Как обнаружить столкновение в three.js? [закрыто]

Я использую three.js.

У меня есть две геометрии сетки в моей сцене.

Если эти геометрии пересекаются (илиwould intersect если переведено) я хочу обнаружить это как столкновение.

Как мне выполнить обнаружение столкновений с three.js? Если Three.js не имеет средств обнаружения столкновений, есть ли другие библиотеки, которые я мог бы использовать в сочетании с three.js?

 LeeGee22 окт. 2014 г., 10:56
Похоже, хороший вопрос для меня. ТАК может быть такой тупой.
 eqiproo13 июл. 2012 г., 17:56
Я искал его в Google, но обнаружил только столкновение лучей.
 Nate13 июл. 2012 г., 17:44
Один вопрос о том, как сделать что-то более широкое, чем обнаружение столкновений, на самом деле не вопрос, а тема обучения. Google твой друг.
 user302423526 июн. 2016 г., 05:18
@Adi Я сделал это в Google. И это первый результат.
 Lee Stemkoski13 июл. 2012 г., 21:14
Я думаю, что лучевая коллизия - это то, что нужно ... файлы CollisionUtils.js и Collisions.js, на которые ссылается Аднан (предположительно), устарели и не являются частью самого последнего (v49 на момент написания) файла Three.js. версия.

Ответы на вопрос(2)

чтобы ее можно было рассмотреть в SO-вопросе, но для того, чтобы немного смазать SEO сайта, вот пара простых отправных точек:

Если вы хотите действительно простое обнаружение столкновений, а не полноценный физический движок, посмотритеThree.js: простое обнаружение столкновений

Если, с другой стороны, вам НЕОБХОДИМО получить какой-либо ответ о столкновении, а не просто "А и В столкнулись?", Взгляните наPhysijs, который является супер простым в использовании оберткой Ammo.js, построенной вокруг Three.js

 eqiproo13 июл. 2012 г., 20:40
Демонстрация, которую вы связали - это столкновение лучей
Решение Вопроса

иваются, и mrdoob (создатель three.js) сам рекомендует обновить его до последней версии three.js и использовать для этого класс Ray. вместо. То, что следует, является одним из способов сделать это.

Идея заключается в следующем: допустим, мы хотим проверить, пересекает ли данная сетка, называемая «Player», любые сетки, содержащиеся в массиве с именем «collidableMeshList». Что мы можем сделать, это создать набор лучей, которые начинаются с координат сетки игрока (Player.position) и простираются в направлении каждой вершины в геометрии сетки игрока. У каждого луча есть метод, называемый «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).) Последний подход, вероятно, приведет к снижению производительности, поэтому я рекомендую использовать его экономно.

Я надеюсь, что другие внесут свой вклад в этот вопрос, решив этот вопрос. Я долго боролся с этим, прежде чем разрабатывать решение, описанное здесь.

 18 нояб. 2013 г., 16:11
Я хотел бы предложить вам избежать создания новогоRaycaster внутри цикла рендеринга. Создайте один и используйте его снова.
 25 авг. 2012 г., 15:13
Спасибо за это подробное объяснение! Я также все еще изо всех сил пытаюсь найти достойное решение для моей игры с ландшафтом и трехмерными объектами, и ваш ответ дал мне несколько новых идей!
 10 авг. 2013 г., 05:59
Хотя этот метод, кажется, проверяет, пересекается ли какая-либо вершина от центра объекта, он будет в два раза медленнее, но с точностью до 100% (?) Для проверки всех ребер (связанных вершин). Поэтому, чтобы уточнить, вам нужно пройтись по каждой грани и взять вершины [n] и вершины [(n + 1)% len], чтобы получить все ребра. Если я обнимаю кого-то, они пересекают центр моей позиции и мою руку, но они не пересекают мою кожу, поскольку проверка края будет проверена.
 20 февр. 2014 г., 16:21
Отличный ответ. Просто для пояснения: collisionResults [0] .distance - это расстояние от источника луча до места, где луч пересекает объект (это не обязательно самое короткое расстояние от источника луча до объекта, особенно для объектов сложной формы)
 10 авг. 2013 г., 22:30
Это хорошая идея! Для 100% (?) Точности, я думаю, вам нужно будет проверить ребра в каждой из двух сеток, и вам нужно будет проверить их движение в обоих направлениях, поскольку столкновения обнаруживаются только в одном направлении, когда луч идет из снаружи внутрь сетки. Конечно, это может быть немного медленнее, но вы можете ускорить его с помощью предварительной проверки радиуса ограничивающей сферы. Но самое главное, я думаю, вы можете быть правы насчет 100% точности ...

Ваш ответ на вопрос