I'm making a game using THREE.JS, and I want my character to walk on the terrain, and collide with static 3D objects (=AABB boxes) that are on that terrain.
The problem is: THREE.JS has only a raycasting class which can be used for collisions.
I figured it would be possible if I casted 8 rays from my character to the points of an imaginary cube around the character (simulating an AABB box). I realize a sphere would be much better, but I wouldn't know how to do that using rays.
var rayDirections = [];
rayDirections.push(new THREE.Vector3(1, 1, 1));
rayDirections.push(new THREE.Vector3(-1, 1, 1));
rayDirections.push(new THREE.Vector3(1, 1, -1));
rayDirections.push(new THREE.Vector3(-1, 1, -1));
rayDirections.push(new THREE.Vector3(1, -1, 1));
rayDirections.push(new THREE.Vector3(-1, -1, 1));
rayDirections.push(new THREE.Vector3(1, -1, -1));
rayDirections.push(new THREE.Vector3(-1, -1, -1));
Then, I simply test the rays against the terrain and possible 3D meshes on the terrain, and check if the ray distance from one of the raycasts is smaller than the AABB box size. This would mean a collision occured.
Rays around the character http://www.ironbane.com/images/colbox.png.
So far so good! I cast a ray from the character's position with every rayDirection and check if one collides with the meshes array (which contains the terrain and other 3D objects on the terrain)
Once I have a collision, what to do now? Should I calculate a reflection vector? If for instance I simply walk on a flat terrain, the four rays at the bottom should trigger a collision. How do I use this reflection vector in my situation?
for(var r in rayDirections) {
// this.position refers to the character's current position
var ray = new THREE.Ray( this.position, rayDirections[r] );
for (var m in meshes) {
var intersects = ray.intersectObject( meshes[m] );
if ( intersects.length > 0 ) {
// Normal vector of the meshes' face we hit
var nV = intersects[0].face.normal;
// Velocity vector (of the character)
var vV = this.velocity.clone();
// And calculate the reflection vector
var rV = n.multiplyScalar(-2 * vV.dot(nV)).addSelf(vV);;
// ... Now what?
}
}
}