Three.js, PointerLock And Collision Detection
collision-detection, three.js
Solution
Finally i discovered!! the solution. i'm not good at math, but at the end i figure it out. After i get direction from pointer-locker controls, depend on which key is pressed, i put the direction into a rotation matrix to get the actual direction vector(thanks for the clue 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);
}
}
Also i made some changes to the PointerLockControls.js to stop moving when camera hit the collider object. I upload my sample here: CameraRayCasting.zip
Update Finally i've found some time to finish my TouchControls project. It uses threejs v0.77.1 and supports touch and hit-testing. check it out here: TouchControls
Problem
I'm working on a 3d virtual home project. everythings works fine except collision detection. I use PointerLockControls for my camera and movement. but i'm not sure how to detec collision in every possible directions. For simplicity i started with just forward and backward collision to a simple cube on (0,0,0): ``` rays = [ new THREE.Vector3(0, 0, 1), new THREE.Vector3(0, 0, -1) ]; ``` Then: ``` 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); } } ``` But when i get close enough to my cube, console shows me both rays hit the cube! so why? Is there any problem with my rays? vector(0,0,1) should be backward and (0,0,-1) should be forward, right? Please help me, before i get lost in 3d! Thanks.