Reputation: 2783
I got a scene with multiple random forms (like triangles, trapezoids, but also more custom designs), and I'm trying to write the code for the collision detection. The shapes are all 2D and are location on Y=0
As the forms are more complicated than just circles and rectangles, I decided to use raycasting to check for collisions.
var raycastCollision = function () {
var originPoint = activeElement.position.clone();
var vertices = activeElement.geometry.vertices;
//loop
for (var vertexIndex = 0; vertexIndex < vertices.length; vertexIndex++) {
var localVertex = vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4(activeElement.matrix);
var directionVector = globalVertex.sub(activeElement.position);
var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize(),true);
ray.ray.direction.y = 0;
var collisionResults = ray.intersectObjects(elements);
debug["ray" + vertexIndex] = ray;
if (collisionResults.length > 0 && collisionResults[0].object != activeElement && collisionResults[0].distance < directionVector.length()) {
debug["raycast detection"] = "HIT";
break;
}
}
}
ActiveElement
is the current selected shape, and elements
is the list of all shapes on scene.
The problem I have is that it only detects "hits" in certain situations, and I've not been able yet to pinpoint in what situations that is. But 1 thing is sure: it more often than not, doesn't detect a hit when it should.
Can anyone detect the error(s) in my code?
Edit: example pictures of a "no hit" and a "hit" situation
Upvotes: 1
Views: 693
Reputation: 392
As my old answer is not correct, I removed it.
I tried your function on a test scene and the following solution works:
https://jsfiddle.net/qzL9L38a/
I guess the problem are the parallel faces in your case.
For spheres the following works:
var raycastCollision = function () {
var originPoint = spheres[0].position.clone();
var vertices = spheres[0].geometry.vertices;
//loop
for (var vertexIndex = 0; vertexIndex < vertices.length; vertexIndex++) {
var localVertex = vertices[vertexIndex]; // no need to clone if applyMatrix4 won'T change localVertex.
var globalVertex = localVertex.applyMatrix4(spheres[0].matrix);
var directionVector = globalVertex.sub(originPoint);
var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize(),true);
var collisionResults = ray.intersectObjects(spheres);
collisionResults = collisionResults.filter(function(element)
{
return element.distance < directionVector.length();
});
if (collisionResults.length > 0 ) {
console.log('HIT: '+collisionResults);
break;
}
}
}
Upvotes: 1