// Handles all ball-ball collisions void handleBallBallCollisions() { for (int i = 0; i < _scene.numChildren(); i++) for (int j = 0; j < _scene.numChildren(); j++) { if (i == j) continue; Object3d b1 = _scene.getChildAt(i); Object3d b2 = _scene.getChildAt(j); // if (b1 == _room || b2 == _room) // continue; if (testBallBallCollision(b1, b2)) { // Make the balls reflect off of each other Number3d displacement = Number3d.subtract(b1.position(), b2.position()); displacement.normalize(); float objDot = Number3d.dot(b1.velocity(), displacement); displacement.multiply(objDot); displacement.multiply(2f); b1.velocity().subtract(displacement); displacement = Number3d.subtract(b1.position(), b2.position()); displacement.normalize(); objDot = Number3d.dot(b2.velocity(), displacement); displacement.multiply(objDot); displacement.multiply(2f); b2.velocity().subtract(displacement); } } }
// Returns whether two balls are colliding boolean testBallBallCollision(Object3d obj1, Object3d obj2) { // Check whether the balls are close enough float r = obj1.radius() + obj2.radius(); Number3d obj1Clone = Number3d.subtract(obj1.position(), obj2.position()); obj1Clone.subtract(obj2.position()); if (obj1Clone.magnitudeSquared() < r * r) { // Check whether the balls are moving toward each other Number3d netVelocity = Number3d.subtract(obj1.velocity(), obj2.velocity()); Number3d displacement = Number3d.subtract(obj1.position(), obj2.position()); return Number3d.dot(netVelocity, displacement) < 0; } else return false; }
void checkWallCollision(Object3d obj, Wall wall, double elapsed) { if (testBallWallCollision(obj, wall)) { // Make the ball reflect off of the wall Number3d dir = wallDirection(wall); dir.normalize(); float objDot = Number3d.dot(obj.velocity(), dir); dir.multiply(objDot); dir.multiply(2f); obj.velocity().subtract(dir); Object3d.applyImpactCORSolid(obj); } }
boolean testBallWallCollision(Object3d obj, Wall wall) { Number3d dir = wallDirection(wall); // Check whether the ball is far enough in the "dir" direction, and whether // it is moving toward the wall switch (wall) { case WALL_BOTTOM: return obj.position().y < PERIM_BOTTOM && Number3d.dot(obj.velocity(), dir) > 0; case WALL_TOP: return obj.position().y > PERIM_TOP && Number3d.dot(obj.velocity(), dir) > 0; case WALL_LEFT: return obj.position().x < PERIM_LEFT && Number3d.dot(obj.velocity(), dir) > 0; case WALL_RIGHT: return obj.position().x > PERIM_RIGHT && Number3d.dot(obj.velocity(), dir) > 0; case WALL_NEAR: return obj.position().z > PERIM_NEAR && Number3d.dot(obj.velocity(), dir) > 0; case WALL_FAR: return obj.position().z < PERIM_FAR && Number3d.dot(obj.velocity(), dir) > 0; } return false; }