melonJS
    Preparing search index...

    Interface ShapeCollisionContact

    One overlapping SHAPE pair, passed to the shape-level collision lifecycle hooks (onShapeCollisionStart, onShapeCollisionActive, onShapeCollisionEnd).

    Why this exists alongside CollisionResponse. A body may collide with another through several shapes at once. onCollision and the onCollision* lifecycle report ONE contact per body pair — the one chosen for physical resolution — so a footprint contact can mask a simultaneous hurtbox contact. These hooks report every overlapping pair, without changing which one resolves.

    Opt-in. The detector only enumerates shape pairs when an object declares at least one of these handlers. Declaring none costs nothing.

    Supported on every backend. The builtin detector enumerates shape pairs directly; @melonjs/planck-adapter and @melonjs/matter-adapter map one melonJS shape onto one native collider and their engines already report contacts per collider pair, so both dispatch these natively. The adapters supply normal and depth rather than the full SAT vector set, matching what they already provide to onCollision.

    Receiver-symmetric, exactly like CollisionResponse: a and shapeA are always the side whose handler is firing, b and shapeB the partner.

    Do not retain it. The object is pooled and reused across pairs and frames. Copy anything needed beyond the handler call.

    onShapeCollisionStart(contact, other) {
    // which of MY shapes was hit
    if (contact.indexShapeA === HURTBOX && contact.isTrigger) {
    this.takeHit(other, contact.normal);
    }
    }
    interface ShapeCollisionContact {
        a: Renderable;
        b: Renderable;
        depth: number;
        indexShapeA: number;
        indexShapeB: number;
        isTrigger: boolean;
        normal: { x: number; y: number };
        normalZ: number;
        overlap: number;
        overlapN: { x: number; y: number };
        overlapNZ: number;
        overlapV: { x: number; y: number };
        overlapZ: number;
        shapeA: BodyShape;
        shapeB: BodyShape;
    }
    Index

    the renderable whose handler is firing — always === this.

    the partner renderable — always === other.

    depth: number

    alias of overlap.

    indexShapeA: number

    index of shapeA in the receiver's body.shapes.

    indexShapeB: number

    index of shapeB in the partner's body.shapes.

    isTrigger: boolean

    true when either shape is a trigger, so the pair contributes no push-out.

    normal: { x: number; y: number }

    contact normal oriented for the receiver.

    normalZ: number
    overlap: number

    penetration depth. Zero in onShapeCollisionEnd, where the shapes have separated.

    overlapN: { x: number; y: number }

    contact normal in the legacy overlapN convention.

    overlapNZ: number
    overlapV: { x: number; y: number }

    minimum translation vector for the receiver.

    overlapZ: number

    Z components, non-zero only for a Box3d pair that resolved along Z.

    shapeA: BodyShape

    the receiver's own shape in this contact.

    shapeB: BodyShape

    the partner's shape in this contact.