EnginO
EnginO

Reputation: 206

rotating raycasters with Object

i have a Object that i can drag and rotate in my room.

I have 4 Raycasters on my object that cast to its back,front,left and right to see if it intersects with some walls. Until now i have no problems and everything works.

Now if i rotate my Object for lets say 60 degree the origins of the racasters are at the wrong place of my object. Is there a way to "stick" the raycasters to a object ?

I have a working version when i just rotate in 90 degree steps but everything else doesnt work.

I made some screenshots for better understanding. The arrows are the rays https://i.sstatic.net/JHSid.jpg

My Code for Creating my Casters:

/*** 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];
}

Upvotes: 1

Views: 121

Answers (1)

TheJim01
TheJim01

Reputation: 8876

First, it looks like you're creating a lot of new objects (Vector3s specifically). Try to create them one time and re-use them, if possible. This is especially important for functions that run frequently, because you'll be polluting the heap with new objects until garbage collection decides to run (and you never know when that will be).

Second, you only need one Raycaster. Simply update its ray property with new information for each direction you're checking. For example:

// 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...

You can probably see the pattern, and can build a function to handle this repetitive code.

Upvotes: 2

Related Questions