用Object旋转射线

时间:2018-05-29 13:59:21

标签: three.js

我有一个可以在我房间内拖动和旋转的物体。

我的物体上有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];
}

1 个答案:

答案 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...

你可以看到模式,并且可以构建一个函数来处理这个重复的代码。