I recently wrote some custom physics code to practice my math and to learn how physics work. Here is the code I wrote in order to test collisions between a equal length (ie 2x2x2,5x5x5,32x32x32, etc.) box and a sphere. How can I adapt my code to test collisions between a sphere and a box with different width,height,length (ie 2x5x32, 8x15x32, etc.)
Here is the code
public static function TestCollisionBetweenSphereBox(a:PhysicsCollider, ta:PhysicsTransform, b:PhysicsCollider, tb:PhysicsTransform):PhysicsCollisionPoints {
final sphere:PhysicsSphereCollider = cast(a, PhysicsSphereCollider);
final sphereTransform = ta;
final box:PhysicsBoxCollider = cast(b, PhysicsBoxCollider);
final boxTransform = tb;
trace("testing collision between sphere", sphere, "and box", box);
trace("transform", ta, tb);
// Transform to World Space
final sphereCenter:Vector3D = new Vector3D(
sphere.center.x + ta.position.x,
sphere.center.y + ta.position.y,
sphere.center.z + ta.position.z
);
final boxCenter:Vector3D = new Vector3D(
box.center.x + tb.position.x,
box.center.y + tb.position.y,
box.center.z + tb.position.z
);
trace("sphereCenter", sphereCenter);
trace("boxCenter", boxCenter);
// Calculate boxMin and boxMax
final boxMin:Vector3D = new Vector3D(
boxCenter.x - (box.size.x * 0.5),
boxCenter.y - (box.size.y * 0.5),
boxCenter.z - (box.size.z * 0.5)
);
final boxMax:Vector3D = new Vector3D(
boxCenter.x + (box.size.x * 0.5),
boxCenter.y + (box.size.y * 0.5),
boxCenter.z + (box.size.z * 0.5)
);
trace("min/max", boxMin, boxMax);
// Closest Point on the Box to Sphere
final closestPointOnBox:Vector3D = new Vector3D(
MathUtils.clamp(sphereCenter.x, boxMin.x, boxMax.x),
MathUtils.clamp(sphereCenter.y, boxMin.y, boxMax.y),
MathUtils.clamp(sphereCenter.z, boxMin.z, boxMax.z)
);
trace("closest point", closestPointOnBox);
// Check for Intersection
final sphereToBox:Vector3D = closestPointOnBox.subtract(sphereCenter);
final distanceSquared:Float = sphereToBox.lengthSquared;
final combinedRadius:Float = (sphere.radius * sphereTransform.scale) + MathUtils.max(box.size.x * 0.5, box.size.y * 0.5, box.size.z * 0.5) * boxTransform.scale;
//trace("intersection", sphereToBox,distanceSquared,combinedRadius);
trace("sphereToBox",sphereToBox);
trace("distanceSquared", distanceSquared);
trace("combinedRadius",combinedRadius);
trace("combinedRadius^2", combinedRadius * combinedRadius);
if (distanceSquared > combinedRadius * combinedRadius) {
// No collision
// trace("NO COLLISION");
return new PhysicsCollisionPoints(null, null, null, 0, false);
}
// Calculate Collision Points
final distance:Float = Math.sqrt(distanceSquared);
final normal:Vector3D = MathUtils.normalizeVector(sphereToBox);
final collisionDepth:Float = combinedRadius - distance;
final aDeep:Vector3D = new Vector3D(
sphereCenter.x + (normal.x * sphere.radius * sphereTransform.scale),
sphereCenter.y + (normal.y * sphere.radius * sphereTransform.scale),
sphereCenter.z + (normal.z * sphere.radius * sphereTransform.scale)
);
final bDeep:Vector3D = new Vector3D(
closestPointOnBox.x - (normal.x * box.size.x * boxTransform.scale),
closestPointOnBox.y - (normal.y * box.size.y * boxTransform.scale),
closestPointOnBox.z - (normal.z * box.size.z * boxTransform.scale)
);
final ret = new PhysicsCollisionPoints(aDeep, bDeep, normal, collisionDepth, true);
trace("distance", distance);
trace("normal", normal);
trace("collisionDepth", collisionDepth);
trace("aDeep", aDeep);
trace("bDeep", bDeep);
return ret;
}