-
-
Notifications
You must be signed in to change notification settings - Fork 663
Comparing changes
Open a pull request
base repository: melonjs/melonJS
base: master
head repository: melonjs/melonJS
compare: platformer25d-1476
- 6 commits
- 18 files changed
- 2 contributors
Commits on Aug 11, 2026
-
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
Configuration menu - View commit details
-
Copy full SHA for 7ed6709 - Browse repository at this point
Copy the full SHA 7ed6709View commit details -
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
Configuration menu - View commit details
-
Copy full SHA for 2589d00 - Browse repository at this point
Copy the full SHA 2589d00View commit details -
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
Configuration menu - View commit details
-
Copy full SHA for 76d8d23 - Browse repository at this point
Copy the full SHA 76d8d23View commit details -
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
Configuration menu - View commit details
-
Copy full SHA for dff29e0 - Browse repository at this point
Copy the full SHA dff29e0View commit details -
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
Configuration menu - View commit details
-
Copy full SHA for 2bdce86 - Browse repository at this point
Copy the full SHA 2bdce86View commit details -
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
Configuration menu - View commit details
-
Copy full SHA for 81ae4c6 - Browse repository at this point
Copy the full SHA 81ae4c6View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff master...platformer25d-1476