本文介绍了Three.js,PointerLock和冲突检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究3d虚拟家庭项目。一切正常,除了碰撞检测。
我将PointerLockControls用于相机和移动。但我不确定如何在所有可能的方向上检测碰撞。
为简单起见,我从与(0,0,0)上的简单立方体的向前和向后碰撞开始:

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

然后:

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

但是当我离立方体足够近时,控制台告诉我两条光线都射中了立方体!所以为什么?
我的光线有问题吗? vector(0,0,1)应该向后,而(0,0,-1)应该向后,对吗?
在我迷失3D之前,请帮助我!
谢谢。

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.

推荐答案

最后我发现了!解决方案。我不擅长数学,但最后我弄清楚了。

从指针锁控件获得方向后,取决于所按下的键,我将方向放入旋转矩阵中获取实际的方向矢量(感谢Icemonster的提示):

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

我也对PointerLockControls.js进行了一些更改,相机碰到对撞机对象时停止移动。我在此处上传示例:

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

更新

最后,我找到了一些时间来完成我的TouchControls项目。它使用threejs v0.77.1并支持触摸和命中测试。

在此处查看:

这篇关于Three.js,PointerLock和冲突检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 09:36