我有一个可以在我房间内拖动和旋转的物体。
我的物体上有4个射线照射器,它向前,向左,向右投射,看它是否与某些墙壁相交。 到现在为止,我没有任何问题,一切正常。
现在,如果我旋转我的对象让我们说60度,那就是我的对象的错误位置。 有没有办法将射线播放器“粘住”到物体上?
当我只是以90度的步幅旋转时,我有一个工作版本,但其他一切都不起作用。
我制作了一些截图以便更好地理解。箭头是光线 https://imgur.com/a/f4n24cZ
我创建脚轮的代码:
/*** Returns 4 Raycasterst as array. Raycasters cast from right,left,front and back of the object */
createCasters(obj: THREE.Object3D, helper: THREE.BoxHelper ) {
let bb = helper.geometry.boundingBox;
let origin = obj.position.clone();
origin.x = bb.getCenter().x;
origin.y = bb.getCenter().y;
origin.z = bb.getCenter().z;
var matrix = new THREE.Matrix4();
matrix.extractRotation(obj.matrix);
let objDirection = obj.getWorldDirection();
let directionRight = new THREE.Vector3(1, 0, 0);
directionRight = directionRight.applyMatrix4(matrix);
let directionLeft = new THREE.Vector3(-1, 0, 0);
directionLeft = directionLeft.applyMatrix4(matrix);
let directionFront = new THREE.Vector3(0, 0, 1);
directionFront = directionFront.applyMatrix4(matrix);
let directionBack = new THREE.Vector3(0, 0, -1);
directionBack = directionBack.applyMatrix4(matrix);
let left: THREE.Vector3, right: THREE.Vector3, front: THREE.Vector3, back: THREE.Vector3;
// Vorne
if (directionLeft.x == -1 || directionRight.x == 1) {
left = new THREE.Vector3( obj.position.x, bb.getCenter().y, obj.position.z + bb.getSize().z / 2 );
right = new THREE.Vector3( obj.position.x + bb.getSize().x , bb.getCenter().y, obj.position.z+ bb.getSize().z / 2 );
front = new THREE.Vector3(obj.position.x + bb.getSize().x/2, bb.getCenter().y, obj.position.z + bb.getSize().z / 2 );
back = new THREE.Vector3( obj.position.x + bb.getSize().x/2, bb.getCenter().y, obj.position.z );
}
// Links
else if (directionLeft.z == 1 || directionRight.z == -1) {
left = new THREE.Vector3( obj.position.x + bb.getSize().x/2 , bb.getCenter().y, obj.position.z );
right = new THREE.Vector3( obj.position.x + bb.getSize().x/2, bb.getCenter().y, obj.position.z - bb.getSize().z );
front = new THREE.Vector3(obj.position.x + bb.getSize().x , bb.getCenter().y, obj.position.z - bb.getSize().z/2 );
back = new THREE.Vector3(obj.position.x , bb.getCenter().y, obj.position.z - bb.getSize().z/2);
}
// Rechts
else if (directionLeft.z == -1 || directionRight.z == 1) {
left = new THREE.Vector3(obj.position.x - bb.getSize().x/2, bb.getCenter().y, obj.position.z);
right = new THREE.Vector3(obj.position.x - bb.getSize().x/2, bb.getCenter().y, obj.position.z + bb.getSize().z);
front = new THREE.Vector3(obj.position.x - bb.getSize().x , bb.getCenter().y, obj.position.z + bb.getSize().z/2 );
back = new THREE.Vector3(obj.position.x , bb.getCenter().y, obj.position.z + bb.getSize().z/2);
}
// Hinten
else if (directionLeft.x == 1 || directionRight.x == -1) {
left = new THREE.Vector3(obj.position.x , bb.getCenter().y, obj.position.z - bb.getSize().z/2);
right = new THREE.Vector3(obj.position.x - bb.getSize().x , bb.getCenter().y, obj.position.z- bb.getSize().z/2);
front = new THREE.Vector3( obj.position.x - bb.getSize().x/2, bb.getCenter().y, obj.position.z - bb.getSize().z);
back = new THREE.Vector3( obj.position.x - bb.getSize().x/2, bb.getCenter().y, obj.position.z );
}
// Schräg
else {
left = new THREE.Vector3( obj.position.x , bb.getCenter().y, bb.getCenter().z);
right = new THREE.Vector3( obj.position.x + bb.getSize().x , bb.getCenter().y, bb.getCenter().z);
front = new THREE.Vector3( obj.position.x, bb.getCenter().y, obj.position.z);
back = new THREE.Vector3( obj.position.x, bb.getCenter().y, obj.position.z);
// #### Schräg nach oben ####
if ( objDirection.z < 1 && objDirection.z > 0 ) {
left = new THREE.Vector3( obj.position.x , bb.getCenter().y, bb.getCenter().z);
right = new THREE.Vector3( obj.position.x + bb.getSize().x , bb.getCenter().y, bb.getCenter().z);
front = new THREE.Vector3( obj.position.x, bb.getCenter().y, obj.position.z);
back = new THREE.Vector3( obj.position.x, bb.getCenter().y, obj.position.z);
}
if (objDirection.z > -1 && objDirection.z < 0) {
}
// ##########################
}
let raycasterLeft = new THREE.Raycaster(left, directionLeft);
let raycasterRight = new THREE.Raycaster(right, directionRight);
let raycasterFront = new THREE.Raycaster(front, directionFront);
let raycasterBack = new THREE.Raycaster(back, directionBack);
return [raycasterLeft, raycasterRight, raycasterFront, raycasterBack];
}
答案 0 :(得分:2)
首先,看起来您正在创建许多新对象(具体为Vector3
)。如果可能的话,尝试创建它们并重复使用它们。这对于频繁运行的函数尤其重要,因为您将使用新对象污染堆,直到垃圾收集决定运行(并且您永远不知道它将在何时运行)。
其次,您只需要一个Raycaster
。只需更新其ray
媒体资源,其中包含您要检查的每个方向的新信息。例如:
// raycaster is a THREE.Raycaster
// direction is a THREE.Vector3
// check +x
direction.set(1, 0, 0);
direction.applyQuaternion(caster.quaternion);
raycaster.ray.origin.copy(caster.boundingBox.getCenter());
raycaster.ray.direction.copy(direction);
results = raycaster.intersectObjects(scene);
if(results){
// handle results
}
// check -x
direction.set(-1, 0, 0);
direction.applyQuaternion(caster.quaternion);
raycaster.ray.origin.copy(caster.boundingBox.getCenter());
raycaster.ray.direction.copy(direction);
results = raycaster.intersectObjects(scene);
if(results){
// handle results
}
// and so on...
你可以看到模式,并且可以构建一个函数来处理这个重复的代码。