> For the complete documentation index, see [llms.txt](https://docs.multiset.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.multiset.ai/fundamentals/third-party-scans/gaussian-splat/splats-from-other-tools.md).

# 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.

## Option 1: Declare the frame through the API (recommended)

Create the map with the [Gaussian Splat upload](/fundamentals/rest-api-docs/map-upload/gaussian-splat-upload.md) 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.

```json
"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.                                                                                                                           |

{% hint style="info" %}
**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"`.
{% endhint %}

### 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](/fundamentals/third-party-scans/gaussian-splat/xgrids-gaussian-splat.md) 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`.

{% hint style="info" %}
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]`).
{% endhint %}

See the [Gaussian Splat](/fundamentals/third-party-scans/gaussian-splat.md) 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](/fundamentals/third-party-scans/gaussian-splat/xgrids-gaussian-splat.md) 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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.multiset.ai/fundamentals/third-party-scans/gaussian-splat/splats-from-other-tools.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
