Conversation
meta.json may hold a `camera` key (rest pose, pinhole intrinsics and a few viewing hints, see playcanvas#319). Until now the SOG writer rebuilt meta.json from scratch, so any re-encode dropped it. The block now lives on ChunkSourceMetadata next to `model`: the SOG and streamed SOG readers keep it, the SOG writer writes it, and the LOD writer writes it once at the top level of lod-meta.json (the per-unit meta.json files don't repeat it). Like the gaussians it is stored raw, so bakeTransform moves the rest pose with the scene and scales its distances; other keys in the block pass through untouched.
`--camera-from cameras.json[:n]` records training camera n (default 0) of the cameras.json that 3DGS trainers write next to the PLY as that input's camera: position and camera-to-world rotation as the rest pose, fx/fy/width/height as the intrinsics (principal point at the image centre). The poses are already in the PLY's coordinates with OpenCV axes, so they are used as-is. Also documents the block in the README.
This was referenced Sep 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the proposal in #319: an optional
camerakey inmeta.jsonthat says how the scene is meant to be opened (one camera: rest pose, pinhole intrinsics, a few viewing hints). It is advisory. Readers that don't use it ignore it, and nothing changes for files without one.What changes
ChunkSourceMetadatagets an optionalcameranext tomodel, and it travels the same waymodeldoes. The SOG reader keepsmeta.camera. The SOG writer writes it to bundled and unbundled output. Before this changewrite-sog.tsbuiltmetaObjfrom scratch, so any.sog → .sogre-encode dropped the block.lod-meta.json(sibling ofasset), and the per-unit and envmeta.jsonfiles don't repeat it. Thelod-meta.jsonreader reads it back.bakeTransformmoves it:-t/-r/-sapply the full transform to the rest pose and the uniform scale to thefocus/stereodistances. Intrinsics and unknown keys pass through untouched. The block is deep-copied on read, so nothing is re-typed or dropped.concatSource(keeps the first input's camera and warns if another input's differs), the DataTable island inprocessSourceBridged, and the CLI's mixed-layout combine.--camera-from cameras.json[:n](per input, default n = 0) sets the block from a training camera in the INRIA-stylecameras.jsonthat 3DGS trainers write next to the PLY. That file storesposition, a camera-to-worldrotationgiven as rows, and pixelfx/fywithwidth/height, all in the PLY's own coordinates with OpenCV axes, so the pose is used as-is (rows → quaternion). The file has no principal point, so it is set to the image centre. If--camera-fromfollows the output file, the CLI rejects it.SogCamera,sogCameraFromCamerasJson,transformSogCamera,withCamera.What doesn't change
versionstays 2, and so does every existing key. A file without a camera writes byte-identicalmeta.json..ply,.spzand the other outputs have nowhere to put the block, so it is dropped silently, which is howmodelis handled.Tests
test/sog-camera.test.mjs(new, 11 tests) covers:transformSogCamerameta.jsonwrite/read.sog → re-encode, where the camera JSON is byte-equalcamerakeylod-meta.jsonand not in the unitmeta.jsonfileslod-meta.jsonread-backI also checked that the rotate test fails with the
bakeTransformchange reverted, and that the lod-meta test fails if the units keep the camera.test/cli.test.mjs:in.ply --camera-from cameras.json:1 out/meta.jsonand… out/lod-meta.jsonboth write the expected block, and--camera-fromafter the output is rejected. To make the CLI tests able to write SOG from source, the test bootstrap now pointsWebPCodec.wasmUrlatlib/webp.wasm, the same way the in-process tests do.npm run lintis clean andnpm run docsbuilds.npm testgives 858 tests, 855 pass. The 3 failures also fail onmainon my machine (Apple M1 Pro): themidandtiny-dofrender goldens, and "should write unbundled HTML viewer with separate files".Spec. The SOG spec page is in
playcanvas/developer-site(docs/user-manual/gaussian-splatting/formats/sog.md, andstreamed-sog.mdforlod-meta.json), not in this repo. I can open a PR there with the matching paragraph once the shape here is settled.Closes #319.