Three.js, PointerLock and collision detection

I am working on a 3D virtual home project. everything works fine except collision detection. I use PointerLockControls for my camera and movement. but I’m not sure how to deal with the detex in all possible directions. For simplicity, I started with a direct and reverse collision with a simple cube at (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 to my cube, the console shows that both rays hit the cube! So why? Are there any problems with my rays? vector (0,0,1) should be inverse and (0,0, -1) should be forward, right? Please help me before I get lost in 3d! Thanks.

+4
source share
1 answer

Finally, I discovered !! decision. I am not good at math, but in the end I understand that.
After I get the direction from the blocking pointers, it depends on which key is pressed, I put the direction in the rotation matrix to get the actual direction vector (thanks for the Icemonster key):

 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); } } 

I also made some changes to PointerLockControls.js to stop the movement when the camera hit the collider object. I upload my example here: CameraRayCasting.zip

Update
Finally, I took some time to complete the TouchControls project. It uses threejs v0.77.1 and supports touch and hit-testing.
here: TouchControls

+8
source

Source: https://habr.com/ru/post/1499911/


All Articles