Skip to content

Respect up_axis in Collada (.dae) mesh importer#12708

Merged
rerun-sync[bot] merged 11 commits intorerun-io:mainfrom
Abhisheklearn12:abhisheklearn12/12335-dae-up-axis
Apr 22, 2026
Merged

Respect up_axis in Collada (.dae) mesh importer#12708
rerun-sync[bot] merged 11 commits intorerun-io:mainfrom
Abhisheklearn12:abhisheklearn12/12335-dae-up-axis

Conversation

@Abhisheklearn12
Copy link
Copy Markdown
Contributor

Related

What

  • Read up_axis from document.asset.up_axis in the Collada importer
  • Compute a correction matrix and pass it as the initial parent_tf to gather_instances_recursive, baking it into every world_from_mesh instance
    transform
  • Z_UP → identity (no correction needed, already matches Rerun's RFU convention)
  • Y_UP → 90° rotation around X axis (Collada's default, most common case)
  • X_UP → custom rotation matrix mapping X_UP axes to RFU

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for opening this pull request.

Because this is your first time contributing to this repository, make sure you've read our Contributor Guide and Code of Conduct.

@oxkitsune oxkitsune self-requested a review March 26, 2026 09:49
Copy link
Copy Markdown
Member

@oxkitsune oxkitsune left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I think we should handle <child> assets properly as well.

// TODO(#12335): Respect up_axis from DAE file via ViewCoordinates.
// Compute a correction matrix to rotate from the DAE file's coordinate system into Rerun's
// default RFU (X=Right, Y=Forward, Z=Up) convention.
let correction = match document.asset.up_axis {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong, but this only applies the correction for the root document's up_axis right?

However COLLADA allows child <asset> metadata to override parent metadata recursively within the child’s scope, from the COLLADA spec:

In the case of hierarchical <asset> elements, where both the parent and child assets supply a value for the same metadata, such as for <unit>, the child asset’s value supersedes the parent’s value within the scope of the child element. This applies recursively.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've updated the PR to handle child elements at both the <visual_scene> and <node> levels, propagating the effective correction recursively to all descendants as per COLLADA spec requires.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, as Per the COLLADA spec and the dae-parser library, <asset> can appear at the document, <visual_scene>, and <node> levels, each overriding the parent's value within its scope (Document.asset: Asset, VisualScene.asset: Option<Box<Asset>>, Node.asset: Option<Box<Asset>>)

Comment thread crates/viewer/re_renderer/src/importer/dae.rs Outdated
Comment thread crates/viewer/re_renderer/src/importer/dae.rs Outdated
@Abhisheklearn12 Abhisheklearn12 force-pushed the abhisheklearn12/12335-dae-up-axis branch from 372eddd to 5c1ab44 Compare April 3, 2026 06:20
@Abhisheklearn12 Abhisheklearn12 force-pushed the abhisheklearn12/12335-dae-up-axis branch from 5c1ab44 to fe64cdb Compare April 3, 2026 06:41
@Abhisheklearn12
Copy link
Copy Markdown
Contributor Author

Fixed in fe64cdb, correction is now applied before composing with parent_tf:

let world_tf = *parent_tf * *correction * Affine3A::from_mat4(local_mat);

Children without their own override get IDENTITY since world_tf is already in RFU.

@Abhisheklearn12
Copy link
Copy Markdown
Contributor Author

Hey @oxkitsune , would love your review on my changes when you get a chance. Thanks!

@oxkitsune
Copy link
Copy Markdown
Member

Hi @Abhisheklearn12, I pushed a commit.

However since I cannot push LFS artifacts to your fork, please update tests/assets/mesh/box.dae to the following, and update the snapshots:

box.dae
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
    <asset>
        <contributor>
            <authoring_tool>modo 801 [Build 77509], Microsoft Windows 7 Service Pack 1 (6.1.7601 Service Pack 1)</authoring_tool>
            <comments>Plug-in: [Build 77509]; Use Absolute Path: No; Merge Reference Items: No; Save Hidden Items: No; Save Cameras: No; Save Lights: No; Save Locators: Yes; Save Triangles as Triangles: Yes; Order Vertex Maps
                Alphabetically: Yes; Bake Matrices: No; Save Vertex Normals: Yes; Save UV Texture Coordinates: Yes; Save Vertex Colors: No; Save Vertex Weights: No; Save Animation: Yes; Sample Animation: No; Sample Animation
                Start: 0; Sample Animation End: 120; Save modo Profile: No; Save Maya Profile: No; Save 3ds Max Profile: No; Formatted Arrays: No;</comments>
            <source_data>file:///C:/Users/Branden/Creative%20Cloud%20Files/03-2015%20Cesium%20Test%20Models/CesiumBoxTest.lxo</source_data>
        </contributor>
        <created>2015-03-04T16:39:37Z</created>
        <modified>2015-03-04T16:39:37Z</modified>
        <up_axis>Y_UP</up_axis>
    </asset>
    <library_materials>
        <material id="Material-Red" name="Red">
            <instance_effect url="#Effect-Red" />
        </material>
    </library_materials>
    <library_effects>
        <effect id="Effect-Red" name="Red">
            <profile_COMMON>
                <technique sid="common">
                    <phong>
                        <diffuse>
                            <color sid="diffuse_effect_rgb">0.8 0 0 1</color>
                        </diffuse>
                        <specular>
                            <color sid="specular_effect_rgb">0.2 0.2 0.2 1</color>
                        </specular>
                        <shininess>
                            <float sid="specular_effect_rgb">256</float>
                        </shininess>
                    </phong>
                </technique>
            </profile_COMMON>
        </effect>
    </library_effects>
    <library_geometries>
        <geometry id="Geometry-mesh002" name="Mesh">
            <mesh>
                <source id="Geometry-mesh002-positions" name="positions">
                    <float_array id="Geometry-mesh002-positions-array" count="24">-0.25 -0.25 -0.25 -0.25 0.25 -0.25 0.25 0.25 -0.25 0.25 -0.25 -0.25 -0.25 -0.25 0.25 -0.25 0.25 0.25 0.25 0.25 0.25 0.25 -0.25 0.25</float_array>
                    <technique_common>
                        <accessor count="8" source="#Geometry-mesh002-positions-array" stride="3">
                            <param name="X" type="float" />
                            <param name="Y" type="float" />
                            <param name="Z" type="float" />
                        </accessor>
                    </technique_common>
                </source>
                <source id="Geometry-mesh002-normals" name="normals">
                    <float_array id="Geometry-mesh002-normals-array" count="18">0 0 1 0 -1 0 1 0 0 0 1 0 -1 0 0 0 0 -1</float_array>
                    <technique_common>
                        <accessor count="6" source="#Geometry-mesh002-normals-array" stride="3">
                            <param name="X" type="float" />
                            <param name="Y" type="float" />
                            <param name="Z" type="float" />
                        </accessor>
                    </technique_common>
                </source>
                <source id="Geometry-mesh002-Texture" name="Texture">
                    <float_array id="Geometry-mesh002-Texture-array" count="28">0.25 1 0.25 0.666667 0.5 1 0.5 0.666667 0 0.666667 0.25 0.333333 0 0.333333 0.5 0.333333 0.75 0.666667 0.75 0.333333 1 0.666667 1 0.333333 0.25 0
                        0.5 0</float_array>
                    <technique_common>
                        <accessor count="14" source="#Geometry-mesh002-Texture-array" stride="2">
                            <param name="S" type="float" />
                            <param name="T" type="float" />
                        </accessor>
                    </technique_common>
                </source>
                <vertices id="Geometry-mesh002-vertices">
                    <input semantic="POSITION" source="#Geometry-mesh002-positions" />
                </vertices>
                <triangles count="12" material="Material-Red">
                    <input semantic="VERTEX" source="#Geometry-mesh002-vertices" offset="0" />
                    <input semantic="NORMAL" source="#Geometry-mesh002-normals" offset="1" />
                    <input semantic="TEXCOORD" source="#Geometry-mesh002-Texture" offset="2" set="0" />
                    <p>4 0 0 7 0 1 5 0 2 6 0 3 5 0 2 7 0 1 7 1 1 4 1 4 3 1 5 0 1 6 3 1 5 4 1 4 6 2 3 7 2 1 2 2 7 3 2 5 2 2 7 7 2 1 5 3 8 6 3 3 1 3 9 2 3 7 1 3 9 6 3 3 4 4 10 5 4 8 0 4 11 1 4 9 0 4 11 5 4 8 0 5 12 1 5 13 3 5 5
                        2 5 7 3 5 5 1 5 13</p>
                </triangles>
            </mesh>
        </geometry>
    </library_geometries>
    <library_visual_scenes>
        <visual_scene id="DefaultScene">
            <node id="Root" name="Root" type="NODE">
                <translate>0 2 0</translate>
                <node id="Geometry-mesh002Node" name="Mesh" type="NODE">
                    <instance_geometry url="#Geometry-mesh002">
                        <bind_material>
                            <technique_common>
                                <instance_material symbol="Material-Red" target="#Material-Red" />
                            </technique_common>
                        </bind_material>
                    </instance_geometry>
                </node>
            </node>
        </visual_scene>
    </library_visual_scenes>
    <scene>
        <instance_visual_scene url="#DefaultScene" />
    </scene>
</COLLADA>

@Abhisheklearn12
Copy link
Copy Markdown
Contributor Author

Hi @oxkitsune, I updated tests/assets/mesh/box.dae and regenerated the snapshots.

Copy link
Copy Markdown
Member

@oxkitsune oxkitsune left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! I'll get this merged once CI goes green!

@Abhisheklearn12
Copy link
Copy Markdown
Contributor Author

hi @oxkitsune, CI’s green, looks good to merge. thanks for the review

@oxkitsune
Copy link
Copy Markdown
Member

@rerun-bot reality-sync

@rerun-sync
Copy link
Copy Markdown
Contributor

rerun-sync Bot commented Apr 17, 2026

Sync complete. Mirror PR in reality: https://github.com/rerun-io/reality/pull/1637

Triggered by @oxkitsune

@oxkitsune
Copy link
Copy Markdown
Member

@rerun-bot reality-sync

@oxkitsune
Copy link
Copy Markdown
Member

@rerun-bot reality-sync

@oxkitsune
Copy link
Copy Markdown
Member

hey, there's some internal checks failing. I'll try and fix them tonight 🫡

@Abhisheklearn12
Copy link
Copy Markdown
Contributor Author

It's okay @oxkitsune, take your time

@oxkitsune
Copy link
Copy Markdown
Member

@rerun-bot reality-sync

@rerun-sync rerun-sync Bot merged commit a03b2f7 into rerun-io:main Apr 22, 2026
38 of 39 checks passed
bourumir-wyngs pushed a commit to bourumir-wyngs/rerun that referenced this pull request Apr 30, 2026
<!--
Thank you for filing a pull request! We kindly ask you to:

1. Fill out this pull request template below, to make the review smoother.
2. Enable edits to your branch by our maintainers. This helps us to get your branch ready to merge. See here for more details:
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork
-->

### Related

- Closes rerun-io#12335

### What

  - Read `up_axis` from `document.asset.up_axis` in the Collada importer
  - Compute a correction matrix and pass it as the initial `parent_tf` to `gather_instances_recursive`, baking it into every `world_from_mesh` instance
  transform
  - `Z_UP` → identity (no correction needed, already matches Rerun's RFU convention)
  - `Y_UP` → 90° rotation around X axis (Collada's default, most common case)
  - `X_UP` → custom rotation matrix mapping X_UP axes to RFU

Source-Ref: 328bfa817a00bf08e25de1185874ac432a7692e9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Respect up_axis in Collada mesh importer

2 participants