I'm trying to implement "bullet and target collision" problem and create an explosion when collision occurs. I managed to do it using aframe-physics-system which was working good: the explosion was rendering at the exact point of the collision and in the exact time. Now I decided to get rid of the physics system as I don't need such overhead - my only goal is to render an explosion.
I tried to use box.containsPoint as well as Raycaster:
tick(time: number, delta: number): void {
// bullet-component
// ...
// Update speed based on acceleration
this.speed = this.currentAcceleration * .01 * delta;
if (this.speed > this.data.maxSpeed) {
this.speed = this.data.maxSpeed;
}
// there is an initial position and direction set in data property.
const newBulletPosition = this.position.add(this.direction.multiplyScalar(this.speed));
// targets is an array of boxes
const found = this._detectCollision(newBulletPosition, this.targets);
if (found) {
console.log("found!");
this.resetBullet();
this.el.emit("collide", {
coordinates: newBulletPosition//found
});
return;
}
this.el.object3D.position.set(newBulletPosition.x, newBulletPosition.y, newBulletPosition.z);
},
_detectCollision(point: THREE.Vector3, obj: THREE.Object3D[]): THREE.Vector3 | null {
const ray = new THREE.Raycaster(point,
this.temps.direction.clone().multiplyScalar(-1).normalize());
const intersects = ray.intersectObjects(obj, true);
return intersects.length % 2 === 1 ? intersects[0].point : null;
},
_box: new THREE.Box3(),
_inverseWorldMatrix: new THREE.Matrix4(),
_detectCollision2(point: THREE.Vector3, obj: THREE.Object3D): THREE.Vector3 | null {
obj.updateMatrixWorld(true);
this._inverseWorldMatrix.copy(obj.matrix).invert();
this._box.setFromObject(obj);
this._inverseBulletPosition.set(point.x, point.y, point.z);
this._inverseBulletPosition.applyMatrix4(this._inverseWorldMatrix);
return this._box.containsPoint(this._inverseBulletPosition);
}
But both approaches have the following flaw:
On frame X the bullet is just in front of a box, but in frame X+1 it is already behind this box. For some reason in this case there might be desirable intersections, but the last bullet position is different than the intersection. Which causes the explosion to be rendered in a wrong position. So, the second approach works only if bullet during it's "jumps" appears inside of a box which is far from being frequent.
The question is how in this case I can repeat the behaviour I had with physics system:
- Bullet is moving relatively fast
- The intersection is being detected instantly once a bullet crosses any face of a box, so there is no "jump" in bullet's movement.
Thanks in advance.