three stemkoski three.js collision-detection
CameraRayCasting.zip

stemkoski - Three.js, PointerLock y Detección de colisión



three js effects (1)

Estoy trabajando en un proyecto de casa virtual en 3D. todo funciona bien excepto la detección de colisión. Yo uso PointerLockControls para mi cámara y movimiento. pero no estoy seguro de cómo detectar la colisión en todas las direcciones posibles. Para simplificar, comencé con una colisión hacia delante y hacia atrás de un cubo simple en (0,0,0):

rays = [ new THREE.Vector3(0, 0, 1), new THREE.Vector3(0, 0, -1) ];

Entonces:

function detectCollision() { var vector; var projector = new THREE.Projector(); for (var i = 0; i < rays.length; i++) { var vector = rays[i].clone(); projector.unprojectVector(vector, camera); var rayCaster = new THREE.Raycaster(controls.getObject().position, vector.sub(controls.getObject().position).normalize()); var intersects = rayCaster.intersectObject(cube, true); if (intersects.length > 0 && intersects[0].distance < 50) { console.log(vector); console.log(i, intersects); $("#status").text("Collision detected @ " + rays[i].x + "," + rays[i].z + "<br />" + intersects[0].distance); } }

Pero cuando me acerco lo suficiente a mi cubo, ¡la consola me muestra que ambos rayos golpean el cubo! ¿entonces por qué? ¿Hay algún problema con mis rayos? el vector (0,0,1) debe estar hacia atrás y (0,0, -1) debe estar hacia adelante, ¿no? ¡Por favor ayúdame, antes de que me pierda en 3D! Gracias.


¡Finalmente lo descubrí! la solución. No soy bueno en matemáticas, pero al final lo descubro.
Después de obtener la dirección de los controles del puntero-casillero, depende de qué tecla se presione, coloco la dirección en una matriz de rotación para obtener el vector de dirección real (gracias por la pista Icemonster):

function detectCollision() { unlockAllDirection(); var rotationMatrix; var cameraDirection = controls.getDirection(new THREE.Vector3(0, 0, 0)).clone(); if (controls.moveForward()) { // Nothing to do! } else if (controls.moveBackward()) { rotationMatrix = new THREE.Matrix4(); rotationMatrix.makeRotationY(180 * Math.PI / 180); } else if (controls.moveLeft()) { rotationMatrix = new THREE.Matrix4(); rotationMatrix.makeRotationY(90 * Math.PI / 180); } else if (controls.moveRight()) { rotationMatrix = new THREE.Matrix4(); rotationMatrix.makeRotationY((360-90) * Math.PI / 180); } else return; if (rotationMatrix !== undefined){ cameraDirection.applyMatrix4(rotationMatrix); } var rayCaster = new THREE.Raycaster(controls.getObject().position, cameraDirection); var intersects = rayCaster.intersectObject(hitMesh, true); $("#status").html("camera direction x: " + cameraDirection.x + " , z: " + cameraDirection.z); if ((intersects.length > 0 && intersects[0].distance < 25)) { lockDirection(); $("#status").append("<br />Collision detected @ " + intersects[0].distance); var geometry = new THREE.Geometry(); geometry.vertices.push(intersects[0].point); geometry.vertices.push(controls.getObject().position); scene.remove(rayLine); rayLine = new THREE.Line(geometry, new THREE.LineBasicMaterial({color: 0xFF00FF, linewidth: 2})); scene.add(rayLine); } }

También hice algunos cambios en PointerLockControls.js para detener el movimiento cuando la cámara golpea el objeto colisionador. Subo mi muestra aquí: CameraRayCasting.zip

Actualizar
Finalmente, he encontrado algo de tiempo para terminar mi proyecto TouchControls. Utiliza threejs v0.77.1 y admite touch y hit-testing.
échale un vistazo aquí: TouchControls