As a newcomer to 3D programming and THREE.js, I am in need of assistance with proper collision detection.
I have been using a method to detect collisions 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 approach works successfully when source elements have Geometry. However, the issue arises when importing larger Gltf models that utilize BufferGeometry for performance reasons. BufferGeometry does not contain vertices but instead has attributes.position.array with coordinates.
To address this change, I attempted to generate vertices based on this attribute 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 BufferGeometry is present, generate vertices based on positions
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);
}
}
}
Although the above code executes without errors and produces an array of Vector3 objects for raycasting, collisions are unfortunately never detected.
What modifications should I make to my code to establish a universal collision detection method regardless of the type of Geometry utilized by objects?
Thank you for your anticipated help.