Ответ 1
В файле Three.js утилиты CollisionUtils.js и Collisions.js больше не поддерживаются, и mrdoob (создатель three.js) сам рекомендует обновить до последней версии three.js и использовать класс Ray вместо этого. Ниже следует один способ сделать это.
Идея такова: пусть говорят, что мы хотим проверить, пересекает ли какой-либо сет, называемый "Player", какие-либо сетки, содержащиеся в массиве, называемом "collidableMeshList". Мы можем создать набор лучей, которые начинаются с координат сетки Player (Player.position) и распространяются по каждой вершине в геометрии сетки Player. Каждый луч имеет метод под названием "intersectObjects", который возвращает массив объектов, с которыми пересекался луч, и расстояние до каждого из этих объектов (измеренное от начала луча). Если расстояние до пересечения меньше расстояния между позицией игрока и вершиной геометрии, то столкновение происходит во внутренней части игровой сетки - что мы, вероятно, будем называть "фактическим" столкновением.
Я опубликовал рабочий пример:
http://stemkoski.github.io/Three.js/Collision-Detection.html
Вы можете переместить красный кубик каркаса с помощью клавиш со стрелками и повернуть его с помощью W/A/S/D. Когда он пересекает один из синих кубов, слово "Хит" будет отображаться в верхней части экрана один раз для каждого пересечения, как описано выше. Важная часть кода приведена ниже.
for (var vertexIndex = 0; vertexIndex < Player.geometry.vertices.length; vertexIndex++)
{
var localVertex = Player.geometry.vertices[vertexIndex].clone();
var globalVertex = Player.matrix.multiplyVector3(localVertex);
var directionVector = globalVertex.subSelf( Player.position );
var ray = new THREE.Ray( Player.position, directionVector.clone().normalize() );
var collisionResults = ray.intersectObjects( collidableMeshList );
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
{
// a collision occurred... do something...
}
}
Есть две потенциальные проблемы с этим конкретным подходом.
(1) Когда начало луча находится внутри сетки M, результаты столкновения между лучом и M не будут возвращены.
(2) Возможно, что маленький объект (по отношению к сетке Игрока) может "скользить" между различными лучами, и, таким образом, никакое столкновение не будет зарегистрировано. Два возможных подхода, чтобы уменьшить вероятность этой проблемы, - это написать код, чтобы мелкие объекты создавали лучи и выполняли усилия по обнаружению столкновения с их точки зрения или включали больше вершин в сетке (например, используя CubeGeometry (100, 100, 100, 20, 20, 20), а не CubeGeometry (100, 100, 100, 1, 1, 1).) Последний подход, вероятно, приведет к поражению производительности, поэтому я рекомендую использовать его экономно.
Я надеюсь, что другие будут способствовать этому вопросу своими решениями по этому вопросу. Я боролся с этим довольно долго, прежде чем разрабатывать описанное здесь решение.