For the complete documentation index, see llms.txt. This page is also available as Markdown.

Splats from Other Tools

Upload a Gaussian Splat trained outside Xgrids: declare its right-handed Y up frame through the REST API, or convert it to Z up yourself, and add a poses.json when you can.

The processing pipeline works in a right-handed, Z up frame, and Xgrids output already matches it. COLMAP and the Gaussian Splat trainers built on it (the reference 3DGS trainer, Nerfstudio Splatfacto and similar tools) write right-handed, Y up instead. There are two ways to bring such a splat in: tell the API which frame the file is in and let the pipeline rotate it, or convert it to Z up yourself before uploading.

Create the map with the Gaussian Splat upload REST call and set source.coordinateSystem to "RHS-Y-UP". Upload the .ply exactly as your trainer wrote it. The pipeline rotates it into its Z up frame on ingest, carrying positions, normals, the per Gaussian rotation quaternions and the spherical harmonic coefficients along, and applies the same rotation to poses.json so the splat and its cameras stay registered.

"source": {
  "provider": "others",
  "fileType": "splat",
  "coordinateSystem": "RHS-Y-UP",
  "metadata": {
    "mode": "indoor",
    "hasPoses": true
  }
}
Field
Value
Notes

coordinateSystem

"RHS-Y-UP"

The frame the .ply and, if present, poses.json are in. Use "RHS-Z-UP" only if you have already converted the file yourself (Option 2).

provider

"others"

Use "others" for a splat trained outside Xgrids. "xgrid" is reserved for Lixel CyberColor exports.

metadata.hasPoses

true | false

true when poses.json is in the zip, false when it is not.

metadata.mode

"indoor" | "outdoor"

Match the capture.

API only. The developer portal's upload flow has no coordinate system option and treats every Gaussian Splat as right-handed Z up. A Y up splat uploaded through the portal is processed in the wrong frame, so create the map through the REST API whenever you need "RHS-Y-UP".

What to put in the zip

A single .zip with everything at the root, packaged the same way as an Xgrids export (see Step 4 of the Xgrids Gaussian Splat Export page):

  • The Gaussian Splat as a standard 3DGS .ply, in the frame your trainer wrote it.

  • poses.json, if you have the training camera poses. It must be in the same frame as the .ply: for a Y up splat the poses stay Y up too, and the pipeline rotates both together.

poses.json is optional, but use it when you can

Poses give the best result. Include poses.json whenever the training camera poses are available. A splat without poses can still be processed, but localization quality will be lower.

If your trainer kept its COLMAP reconstruction, the poses already exist: each training image has a camera centre and a camera to world rotation. Write one entry per training camera:

  • T is the camera position in world coordinates, [x, y, z].

  • R is the camera to world rotation as a quaternion in [w, x, y, z] order, with the camera looking down +Z (OpenCV convention, the same as COLMAP's camera frame).

  • ts is a string timestamp, and RGB can be null.

COLMAP's images.txt stores the world to camera transform. Invert it before writing an entry: the camera position is -Rᵀ t, and the camera to world quaternion is the conjugate of the stored one ([qw, -qx, -qy, -qz]).

See the Gaussian Splat overview for the full JSON shape. A dense list is fine, since poses are subsampled to roughly one per metre during processing. Set metadata.hasPoses to true when the file is in the zip and false when it is not.

Option 2: Convert to Z up yourself

If your tool has an axis convention option on export, or you prefer to ship a Z up file, convert first and upload with source.coordinateSystem set to "RHS-Z-UP".

  1. Rotate the splat into right-handed Z up. Right-handed Y up to right-handed Z up is a 90 degree rotation about X, so (x, y, z) becomes (x, -z, y).

  2. Rotate more than the positions. Every Gaussian also carries a rotation quaternion and a normal that turn with the world, and the spherical harmonic coefficients (f_rest_*, rotated per degree band) have to come along too or view dependent colour will be wrong from some viewpoints. The f_dc_* base colour is rotation invariant, and opacity and scale do not move. An exporter with an axis convention option handles all of this for you and is safer than transforming the .ply by hand.

  3. Apply the identical transform to the camera poses. The splat and its poses have to end up in one shared frame. A Z up splat with Y up poses will not register, even though both files look individually correct.

Once converted, package and upload it exactly like an Xgrids export. The packaging and portal steps are identical, see Step 4 and Step 5 of the Xgrids Gaussian Splat Export page. Because the file is already Z up, the portal upload works for this option.

Keep it metric

Scale requirements do not change with the axis convention or the upload route. Storey detection, grid spacing and pose subsampling all work in metres, so an arbitrary-scale reconstruction does not produce a wrong-looking map, it produces no usable map at all. Scale the reconstruction to real-world metres before training, or rescale the splat and its poses together before uploading.

Last updated

Was this helpful?