Reputation: 206
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
Reputation: 8876
First, it looks like you're creating a lot of new objects (Vector3
s 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