I'm quite new if it comes to 3d programming and THREE.js and needs some help with proper collision detection.
I'm using the following method to detect collision between sourceElements and targetElements
detect(): void {
if (!this.sourceElements.length || !this.targetElements.length) {
return;
}
for (let i = 0; i < this.sourceElements.length; i+= 1) {
const originPoint = this.sourceElements[i].position.clone();
for (let vertexIndex = 0; vertexIndex < (<Geometry>this.sourceElements[i].geometry).vertices.length; vertexIndex++) {
let localVertex = (<Geometry>this.sourceElements[i].geometry).vertices[vertexIndex].clone();
let globalVertex = localVertex.applyMatrix4(this.sourceElements[i].matrix);
let directionVector = globalVertex.sub(this.sourceElements[i].position);
let ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
let collisionResults = ray.intersectObjects(this.targetElements, false); // @TODO create method
if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
console.log('<<<<HIT>>>>>', collisionResults[0].object.name);
// if hit was detected there's no need to analyze more
return;
}
}
}
}
This code works well if source elements have Geometry. The problem is that recently I started to import larger Gltf models that have BufferGeometry for performance reasons. BufferGeometry has no vertices but instead of this has attributes.position.array with coordicates.
So I tried to generate vertices based on this data
let v: Vector3 = new THREE.Vector3();
// iterate over source elements
for (let i = 0; i < sourceElements.length; i += 1) {
let geometry = sourceElements[i].geometry;
// if there's any with BufferGeometry generate vertices based on
if ( geometry instanceof THREE.BufferGeometry ) {
const vertices: Array<Vector3> = [];
const positions = geometry.attributes.position.array;
console.log('CollisionDetector BufferGeometry detected', geometry);
for ( let k = 0; k < positions.length; k += 3 ) {
v.set(positions[ k ],positions[ k + 1 ], positions[ k + 2 ]);
vertices.push(v);
}
}
}
The above code don't fail and generates an array of Vector3 objects that I then use for raycasting but unfortunately, collision is never detected.
What should I change in my code to have a universal method for collision detection no matter which kind of Geometry has objects?
Thanks in advance
.intersectObjects()
like this.intersectObjects(this.targetElements, true)
. – prisoner849