three.js中如何根据物体位置和旋转正确旋转raycaster
How to properly rotate the raycaster according to the object position and rotation in three.js
我有 8 个从 Object3D 到不同方向的光线投射器,用于碰撞检测。我想根据对象旋转旋转他们指向的方向。我遵循了 here
的解决方案
光线投射器开始旋转,但旋转方式很奇怪。它开始检测来自不同方向的所有光线的碰撞。
在HTML我有
cube = new THREE.BoxGeometry(1,1,1);
cube_material = new THREE.MeshBasicMaterial({color: 0x00a000});
cube_mesh = new THREE.Mesh(cube, cube_material);
var rays = [
new THREE.Vector3(0, 1, 0), // forward
new THREE.Vector3(0, -1, 0), // backward
new THREE.Vector3(-1, 0, 0), // left
new THREE.Vector3(1, 0, 0), // right
new THREE.Vector3(1, 1, 0), // forward right
new THREE.Vector3(-1, 1, 0), // forward left
new THREE.Vector3(1, -1, 0), // backward right
new THREE.Vector3(-1, -1, 0) // backward left
];
这是我从 animate() 函数调用的 detectCollision 函数:
detectCollision = function( ){
var hit = false;
var dist = 0.8;
var origin = new THREE.Vector3(cube_mesh.position.x, cube_mesh.position.y, cube_mesh.position.z);
var rayHits = [];
for ( var i = 0; i < rays.length; i++){
var matrix = new THREE.Matrix4();
matrix.extractRotation(cube_mesh.matrix);
var dir = rays[i];
dir = dir.applyMatrix4( matrix );
raycaster = new THREE.Raycaster(origin, dir, 0.6, dist);
var intersections = raycaster.intersectObjects(collidable_walls);
if (intersections.length > 0){
// 0 = forward
// 1 = backward
// 2 = left
// 3 = right
// 4 = forward right
// 5 = forward left
// 6 = backward right
// 7 = backward left
switch (i) {
case 0:
console.log("forward: " + i);
cube_mesh.translateY(-0.12);
break;
case 1:
console.log("backward: " + i);
cube_mesh.translateY(0.12);
break;
case 2:
cube_mesh.translateX(0.12);
console.log("left: " + i);
break;
case 3:
cube_mesh.translateX(-0.12);
console.log("right: " + i);
break;
case 4:
console.log("forward right: " + i);
break;
case 5:
console.log("forward left: " + i);
break;
case 6:
console.log("backward right:" + i);
break;
case 7:
console.log("backward left: " + i);
break;
}
}
}
}
任何人都可以告诉我如何正确旋转 raycaster 作为 ArrowHelper(在图像中不起作用,但与 rotation.z 一起工作得很好)
Three.js使用右手坐标系,rays
应该是:
var rays = [
new THREE.Vector3(0, 0, -1), // forward
new THREE.Vector3(0, 0, 1), // backward
new THREE.Vector3(-1, 0, 0), // left
new THREE.Vector3(1, 0, 0), // right
new THREE.Vector3(1, 0, -1), // forward right
new THREE.Vector3(-1, 0, -1), // forward left
new THREE.Vector3(1, 0, 1), // backward right
new THREE.Vector3(-1, 0, 1) // backward left
];
在您的函数 detectCollision
中,您应该将 var dir = rays[i];
更改为 var dir = new THREE.Vector3().copy(rays[i])
,或者当您将矩阵应用于此 dir
时,rays[i]
将更改还有。
您最好确保 cube_mesh.position
是立方体的世界位置。我建议您使用 cube_mesh.getWorldPosition()
和 cube_mesh.matrixWorld
.
我有 8 个从 Object3D 到不同方向的光线投射器,用于碰撞检测。我想根据对象旋转旋转他们指向的方向。我遵循了 here
的解决方案光线投射器开始旋转,但旋转方式很奇怪。它开始检测来自不同方向的所有光线的碰撞。
在HTML我有
cube = new THREE.BoxGeometry(1,1,1);
cube_material = new THREE.MeshBasicMaterial({color: 0x00a000});
cube_mesh = new THREE.Mesh(cube, cube_material);
var rays = [
new THREE.Vector3(0, 1, 0), // forward
new THREE.Vector3(0, -1, 0), // backward
new THREE.Vector3(-1, 0, 0), // left
new THREE.Vector3(1, 0, 0), // right
new THREE.Vector3(1, 1, 0), // forward right
new THREE.Vector3(-1, 1, 0), // forward left
new THREE.Vector3(1, -1, 0), // backward right
new THREE.Vector3(-1, -1, 0) // backward left
];
这是我从 animate() 函数调用的 detectCollision 函数:
detectCollision = function( ){
var hit = false;
var dist = 0.8;
var origin = new THREE.Vector3(cube_mesh.position.x, cube_mesh.position.y, cube_mesh.position.z);
var rayHits = [];
for ( var i = 0; i < rays.length; i++){
var matrix = new THREE.Matrix4();
matrix.extractRotation(cube_mesh.matrix);
var dir = rays[i];
dir = dir.applyMatrix4( matrix );
raycaster = new THREE.Raycaster(origin, dir, 0.6, dist);
var intersections = raycaster.intersectObjects(collidable_walls);
if (intersections.length > 0){
// 0 = forward
// 1 = backward
// 2 = left
// 3 = right
// 4 = forward right
// 5 = forward left
// 6 = backward right
// 7 = backward left
switch (i) {
case 0:
console.log("forward: " + i);
cube_mesh.translateY(-0.12);
break;
case 1:
console.log("backward: " + i);
cube_mesh.translateY(0.12);
break;
case 2:
cube_mesh.translateX(0.12);
console.log("left: " + i);
break;
case 3:
cube_mesh.translateX(-0.12);
console.log("right: " + i);
break;
case 4:
console.log("forward right: " + i);
break;
case 5:
console.log("forward left: " + i);
break;
case 6:
console.log("backward right:" + i);
break;
case 7:
console.log("backward left: " + i);
break;
}
}
}
}
任何人都可以告诉我如何正确旋转 raycaster 作为 ArrowHelper(在图像中不起作用,但与 rotation.z 一起工作得很好)
Three.js使用右手坐标系,rays
应该是:
var rays = [
new THREE.Vector3(0, 0, -1), // forward
new THREE.Vector3(0, 0, 1), // backward
new THREE.Vector3(-1, 0, 0), // left
new THREE.Vector3(1, 0, 0), // right
new THREE.Vector3(1, 0, -1), // forward right
new THREE.Vector3(-1, 0, -1), // forward left
new THREE.Vector3(1, 0, 1), // backward right
new THREE.Vector3(-1, 0, 1) // backward left
];
在您的函数 detectCollision
中,您应该将 var dir = rays[i];
更改为 var dir = new THREE.Vector3().copy(rays[i])
,或者当您将矩阵应用于此 dir
时,rays[i]
将更改还有。
您最好确保 cube_mesh.position
是立方体的世界位置。我建议您使用 cube_mesh.getWorldPosition()
和 cube_mesh.matrixWorld
.