javascript three.js webgl collision-detection

javascript - ¿Cómo detectar colisión en three.js?



webgl collision-detection (2)

En Three.js, las utilidades CollisionUtils.js y Collisions.js ya no parecen ser compatibles, y mrdoob (creador de three.js) mismo recomienda actualizar a la versión más reciente de three.js y usar la clase Ray para este propósito en lugar. Lo que sigue es una forma de hacerlo.

La idea es la siguiente: supongamos que queremos comprobar si una malla determinada, llamada "Reproductor", interseca las mallas contenidas en una matriz llamada "ColLidableMeshList". Lo que podemos hacer es crear un conjunto de rayos que empiecen en las coordenadas de la malla del jugador (Player.position), y se extiendan hacia cada vértice en la geometría de la malla del jugador. Cada rayo tiene un método llamado "intersectObjetos" que devuelve una matriz de objetos con los que se cruzó el rayo, y la distancia a cada uno de estos objetos (medida desde el origen del rayo). Si la distancia a una intersección es menor que la distancia entre la posición del jugador y el vértice de la geometría, entonces la colisión ocurrió en el interior de la malla del jugador, lo que probablemente llamaríamos una colisión "real".

He publicado un ejemplo de trabajo en:

http://stemkoski.github.io/Three.js/Collision-Detection.html

Puede mover el cubo de alambre rojo con las teclas de flecha y rotarlo con W / A / S / D. Cuando se cruza con uno de los cubos azules, la palabra "Hit" aparecerá en la parte superior de la pantalla una vez para cada intersección como se describe arriba. La parte importante del código está debajo.

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... } }

Hay dos problemas potenciales con este enfoque particular.

(1) Cuando el origen del rayo está dentro de una malla M, no se generarán resultados de colisión entre el rayo y M.

(2) Es posible que un objeto que es pequeño (en relación con la malla del jugador) se "deslice" entre los diversos rayos y, por lo tanto, no se registrará ninguna colisión. Dos posibles enfoques para reducir las posibilidades de este problema son escribir código para que los objetos pequeños creen los rayos y realizar el esfuerzo de detección de colisiones desde su perspectiva, o incluir más vértices en la malla (por ejemplo, utilizando CubeGeometry (100, 100, 100, 20, 20, 20) en lugar de CubeGeometry (100, 100, 100, 1, 1, 1).) El último enfoque probablemente causará un golpe de rendimiento, por lo que recomiendo usarlo con moderación.

Espero que otros contribuyan a esta pregunta con sus soluciones a esta pregunta. Luché con él durante bastante tiempo antes de desarrollar la solución que se describe aquí.

Estoy usando three.js.

Tengo dos geometrías de malla en mi escena.

Si estas geometrías se intersecan (o se intersecarían si se traducen), quiero detectar esto como una colisión.

¿Cómo realizo la detección de colisión con three.js? Si three.js no tiene instalaciones de detección de colisiones, ¿hay otras bibliotecas que pueda utilizar en conjunción con three.js?


Este es un tema demasiado amplio para cubrir en una pregunta de SO, pero con el objetivo de engrasar un poco el SEO del sitio, aquí hay un par de puntos de partida simples:

Si desea una detección de colisión realmente simple y no un motor de física completo, consulte Three.js: detección simple de colisión

Si, por otro lado, QUIERES una respuesta de colisión, no solo "A y B toparon?", Physijs un vistazo a Physijs , que es un envoltorio Ammo.js súper fácil de usar construido alrededor de Three.js