Haxe: Custom Sphere x Box collision, from same size lengths to dynamic w,h,l (Haxe, OpenFL)

24 Views Asked by At

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;
    }
0

There are 0 best solutions below