Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: melonjs/melonJS
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: melonjs/melonJS
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: platformer25d-1476
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 6 commits
  • 18 files changed
  • 2 contributors

Commits on Aug 11, 2026

  1. feat(physics): Box3d shape and 3D collision resolution (#1476)

    Adds a `Box3d` body shape so a body can be resolved along Z as well as X
    and Y. Every other built-in shape is planar and goes through the 2D SAT
    narrowphase, whose minimum translation vector is a `Vector2d` — a depth
    gate can filter candidate pairs, but nothing could produce a Z pushback.
    
    - `Box3d` (geometries/box3d.ts): centre + half-extents, with a cached XY
      footprint so every 2D consumer (body bounds, broadphase pre-gate, debug
      draw) needs no 3D awareness. The footprint is floored at a minimum edge
      because `Polygon.recalc` normalizes edges with no zero guard and would
      otherwise emit NaN normals for a zero-size box.
    - `testBox3dBox3d` (physics/builtin/sat3d.js): AABB-vs-AABB MTV, filling
      the new `ResponseObject.overlapZ` / `overlapNZ`.
    - `Body`: `velZ`, `forceZ`, `frictionZ`, `maxVelZ`, and a `hasDepth` flag.
    - `raycast3d`: exact ray-vs-AABB slab test for bodies carrying a `Box3d`,
      replacing a bounding-sphere approximation whose radius came from a 2D
      bounds with no depth — useless for probing floor height.
    
    The 2D path is unchanged. Z arrives as scalars beside `overlapV` /
    `overlapN` / `body.vel` rather than by widening them: `Vector3d` is not a
    subclass of `Vector2d`, so retyping would break every existing consumer.
    The MTV is a single axis, so a planar pair leaves every Z field at 0 and
    the added arithmetic is inert. Mixed pairs treat the planar shape as
    unbounded along Z, so introducing one `Box3d` body into a 2D game leaves
    its world shapes colliding exactly as before.
    
    54 tests, including differential sweeps against a brute-force AABB test
    (seeded LCG, reported as a rate) and a compat suite pinning that 2D-only
    responses are untouched.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
    obiot and claude committed Aug 11, 2026
    Configuration menu
    Copy the full SHA
    7ed6709 View commit details
    Browse the repository at this point in the history
  2. fix(gltf): encode baseColorFactor from linear to sRGB

    `pbrMetallicRoughness.baseColorFactor` is defined by the glTF spec in
    linear space; a melonJS tint is 8-bit sRGB, the same space as a CSS colour
    or a PNG texel. The loader scaled the linear value by 255 and used it as
    the tint, so every untextured glTF material rendered lighter and less
    saturated than authored — a mid-green (linear 0.29) arrived as sRGB 0.58
    and read as pale mint.
    
    Adds `linearToSrgb8` and applies it at both tint sites. The helper clamps
    its domain as well: an exporter emitting a slightly out-of-range factor
    would previously have reached `Math.pow` with a negative base and NaN-ed
    the whole tint.
    
    Tested at both levels — the transfer function itself, and the loader
    wiring (a `GLTFModel` built from a known factor must arrive at the encoded
    tint). The wiring tests are the load-bearing ones: the helper tests alone
    still pass if the loader stops calling it.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
    obiot and claude committed Aug 11, 2026
    Configuration menu
    Copy the full SHA
    2589d00 View commit details
    Browse the repository at this point in the history
  3. fix(gltf): decode images to ImageBitmap, not HTMLImageElement

    An indexed (palette) PNG texture in a glTF asset rendered greyscale on
    Safari: geometry and animation intact, all colour gone (r == g == b).
    
    The glTF parser decoded images to an `HTMLImageElement`, unlike the
    ordinary image loader, which has always produced an `ImageBitmap`. That
    difference is invisible for an RGBA source but not for an indexed one
    (PNG colorType 3): WebKit's `copyExternalImageToTexture` uploads such an
    image as its raw palette indices rather than expanding them through the
    palette. Other browsers normalise the image at decode, and the WebGL
    backend's `texImage2D` is unaffected, so it presented as a WebGPU
    regression in one browser only.
    
    Nothing in the WebGPU API can correct this at upload time — `flipY`,
    `premultipliedAlpha` and `colorSpace` are the only knobs, and expanding a
    palette belongs to the decoder. glTF images therefore now decode to an
    `ImageBitmap`, which is RGBA by definition, bringing the glTF path in line
    with the rest of the loader.
    
    All three sources (embedded bufferView, data: URI, external file) fall
    back to the previous element path on failure: `createImageBitmap` is
    stricter about malformed sources, and a stricter loader would itself be a
    regression — a first cut without the fallback broke 17 existing glTF
    tests.
    
    Regression test builds a real 2x2 indexed PNG (palette: red, blue) inside
    a GLB and asserts both that the decode is an `ImageBitmap` and that the
    palette actually expands.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
    obiot and claude committed Aug 11, 2026
    Configuration menu
    Copy the full SHA
    76d8d23 View commit details
    Browse the repository at this point in the history
  4. docs(changelog): Box3d feature and the glTF colour fixes

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
    obiot and claude committed Aug 11, 2026
    Configuration menu
    Copy the full SHA
    dff29e0 View commit details
    Browse the repository at this point in the history
  5. example(afterBurner): no ground shadows, and enable 4x MSAA

    Two unrelated corrections to the same example.
    
    Ground shadows: this scene has no ground GEOMETRY to receive a blob — the
    "ground" is a screen-space stroked line grid drawn in pixel coords at a
    computed horizon, so a world-space shadow has nothing correct to land on
    and drifts as the camera pitches. It was only casting them because the
    application default ships `true`.
    
    MSAA: the jet, enemies and terrain props are low-poly models with long
    straight edges, which aliased badly as they receded. `antiAlias` was never
    set here, so it defaulted off. The example composites through post
    effects, so this depends on capture targets being multisampled too
    (#1556). Measured on the horizon band: intermediate-coverage pixels along
    the mountain silhouette rise from 8.5% to 27.0%.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
    obiot and claude committed Aug 11, 2026
    Configuration menu
    Copy the full SHA
    2bdce86 View commit details
    Browse the repository at this point in the history
  6. docs(changelog): condense the unreleased section

    Entries had grown into multi-paragraph essays — some single bullets ran to
    4000 characters. Rewritten to one or two sentences each: what changed, why
    it matters, and any migration-critical detail. Measurement tables kept
    where the numbers are the point.
    
    Unreleased section 51KB -> 21KB (58% shorter), average entry ~1000 -> ~450
    characters. No entry removed and no issue link dropped. Released sections
    are untouched.
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01QVjYzf76AEU3wJk766JAQi
    obiot and claude committed Aug 11, 2026
    Configuration menu
    Copy the full SHA
    81ae4c6 View commit details
    Browse the repository at this point in the history
Loading