Disappearing I3dm's on map navigation (again)

There is still an issue with disappearing Instanced 3D Tiles (I3dm) on map navigation .

Some previous attempts:

Here a new attempt with some new observations:

1] Issue

Issue occurs with 2 instances of a windmill in 1 I3dm file, implicit tiling is used, no RTC_CENTER is used

See https://bertt.github.io/cesium_issues/i3dm_disappearing2/issue/

GLB model: https://bertt.github.io/cesium_issues/i3dm_disappearing2/issue/windmill.glb

windmill_disappears

2] Workaround

As a workaround Iā€™ve processed the windmill model and now the effect does not occur.

See https://bertt.github.io/cesium_issues/i3dm_disappearing2/workaround/

GLB model: https://bertt.github.io/cesium_issues/i3dm_disappearing2/workaround/windmill.glb

windmill_workaround

Further remarks

  • All GLBā€™s are valid

  • All tilesets are valid

  • When there is only 1 instance the effect does not occur

  • Cesium version: 1.119

So Iā€™ve got the feeling there goes something wrong in CesiumJS visualizing some glTF models. Maybe there is a clue in comparing the two glTFā€™s but itā€™s a time consuming processā€¦

Any pointers?

cc @Marco13

Hi @bertt,

It appears that the one instanced version is getting culled based on the location of the other instance.

This reminds me of a previously reported issue. Would you be able to confirm that the transformation matrix of the glTF node in the I3DM is not the identity matrix?

The task to investigate this is moved slightly up my TODO list each time when it is reported, but itā€™s still struggling to move to the top (Iā€™ll have to familiarize myself with some aspects of the culling first).

But as a first pass here: The original model has this node structure:

  "nodes" : [
    {
      "name" : "SM_Rotor_LOD2",
      "mesh" : 0,
      "scale" : [
        0.01,
        0.01,
        0.01
      ],
      "translation" : [
        0,
        100,
        4.9
      ]
    },
    {
      "name" : "SM_Pillar_LOD2",
      "mesh" : 1,
      "scale" : [
        0.01,
        0.01,
        0.01
      ]
    }
  ],
  "scene" : 0,
  "scenes" : [
    {
      "name" : "Scene",
      "nodes" : [
        0,
        1
      ]
    }
  ]

The workaround model has this

  "nodes" : [
    {
      "mesh" : 0,
      "name" : "Asset3DLoader.sceneRoot"
    }
  ],
  "scenes" : [
    {
      "nodes" : [
        0
      ]
    }
  ],
  "scene" : 0

(Which looks like something like clearNodeTransform | glTF Transform was applied to that)

FYI to ā€˜fixā€™ the problematic windmill model Iā€™ve used Online glTF model repair tool for free, exported obj and converted to glbā€¦ clumsy method, the animation is removed and the model is gray but at least the issue is no longer there.

Iā€™m curious (and this might also be a reason to move this up in my TODO list), but from the description here (and previous threads), it sounds like itā€™s really related to the root transform, because thatā€™s the only difference between those files that Iā€™d consider even possibly relevant. One first step could be to drag-and-drop the original model into https://gltf.report/, apply clearNodeTransform in the script, and see whether that fixes it. (Iā€™ll try to allocate at least a short time slice for that - if it fixes it, then mapping that to the point where something goes wrong in the culling is another task, but it could bring an insight, at least)

Iā€™ve executed the following script on https://gltf.report on the problematic windmill:

import { clearNodeTransform } from ā€˜@gltf-transform/functionsā€™;
document.getRoot()
.listNodes()
.forEach((node) => {
clearNodeTransform(node)
});

Result:

glb : https://bertt.github.io/cesium_issues/i3dm_disappearing2/clearnodetransform/0_0_0.glb

  • Animation windmill is messed up :frowning: (Btw something similar with this animation happens when upgrading this tileset to 1.1 using 3d-tiles-tools might have to check on that)

Conclusion: So it should be something with the node transforms indeed

I think that the way of using clearNodeTransform is not perfectly right. The documentation says

To clear all transforms of a Node, first clear its inherited transforms with clearNodeParent, then clear the local transform with clearNodeTransform.

So the application of this has to take the node hierarchy structure into account. And it might be that when doing that, the animation might work as expected. (I mean, the current result looks funny, but ā€¦). Iā€™ll try to have a closer look at this today.

A very quick test yields some pretty confusing results.

I created some hacky customClearNodeTransform, and applied it in a way so that only the translation part of the animated node is kept (so the scale of the animated node and the other root node are ā€˜clearedā€™). This causes the animation to still work. But the model also still disappears. (I would have thought that the scale of 0.01 in the root nodes might be a hot candidate. But ā€¦ that doesnā€™t seem to be itā€¦)

Another ā€¦ ā€œdata pointā€: I noticed that itā€™s possible to carefully tweak the view so that only parts of the model are disappearing:

Cesium Disappearing Model

This may look like a boring detail, but might actually give a hint about the place in the culling code where the bug is nesting: Whatever is happening there, itā€™s not happening on the granularity of the model, but on the granularity of the ā€œprimitivesā€ (meshes).
(Which is, frankly, even more confusing, because the ā€˜pillarā€™ in this model has an identity transform, and it still disapparsā€¦)

1 Like

Testing with clearNodeParent (before clearNodeTransform) gives the same result: disappearing fixed, animation rotor not good. Hope to find a fix too for the animation.

It is possible to make the root transform the identity matrix, and still have the proper rotation (but also still have the issue of the model disappearing).

The node that contains the ā€˜rotorā€™ must have translation, because that defines what the rotation is all about (i.e. the axis or rather local coordinate space).

Right now, the node structure is

nodes: [
   { rotor (with translation },
   { pillar }
]
scenes: [
  { nodes: [ 0, 1 ] }
]

I.e. both nodes are root nodes.
And I quickly tried out whether changing this to

nodes: [
   { rotor (with translation },
   { pillar, children: [0] }
]
scenes: [
  { nodes: [ 1 ] }
]

makes a difference, but it doesnā€™t.

Iā€™ll try to do one quick debugging pass on this today, but cannot say how deeply I can go into the expected rabbit holes.

1 Like

OK. This is embarassing. Some of my previous statements did not make sense and/or have been plainly wrong. For some reason, I assumed that the I3DM refers to the GLB in the root directory. So I modified that GLB, and was surprised that the model still disappeared. But ā€¦ yeah, that modified GLB was never loaded :roll_eyes:
(I now changed the I3DM to use a URI to refer to the GLB locally, so that I can test changes of the GLB more easily. Fortuntately, some of the pain-in-the-back debugging that I just went through would also have been necessary if the right model had been loadedā€¦)

1 Like

A short heads-up: Some results from the first debugging pass are at i3dm renders incorrectly when model has non-identity matrix Ā· Issue #11176 Ā· CesiumGS/cesium Ā· GitHub .

There are a few things left to investigate - for example, whether an I3DM that refers to a GLB that contains geometry in nodes that have different scaling even renders correctly.

A few levels higher, the question is whether the scaling factor (or more generally, the transform - details TBD) of a glTF node should affect the instancing transforms. When the instancing transforms come from EXT_mesh_gpu_instancing, then the node transform should affect them. When they come from ā€œoutsideā€, via an I3DM, then the node transform should not affect them (or at least, not in the way that it currently does).


Note to myself: Create an I3DM that contains a GLB that contains EXT_mesh_gpu_instancing. From what Iā€™ve read so far in the code, Iā€™m reasonably sure that this will breakā€¦

1 Like

nice debugging :slight_smile:

I did a test with 1 I3dm with a ext_mesh_gpu_instancing glb inside (2 red box.glb points ) : https://bertt.github.io/cesium_issues/i3dm_with_gpu_instancing/issue/

Result: No error message, nothing gets drawn, 3d-tiles validator gives only info messages about not supported EXT_structural_metadata, EXT_mesh_gpu_instancing and EXT_instance_features

Donā€™t know if this scenario is supported or not (can image itā€™s not because I3dm is deprecated), but if it is not supported I expect an error message (in Cesium client and/or validator).

While investigating this issue, I saw that ā€œthe instancingā€ is internally accomplished with the same mechanism/structure, regardless of whether the instancing information comes from EXT_mesh_gpu_instancing or from the I3DM data. Soā€¦ I suspected that they simply cannot be combined. One could argue back and forth here. Yes, I3DM is deprecated, but it is still used (and actually required for things like instanced animated models). And if it is a limitation, it should be clearly pointed out (and probably tracked in an issue, at least).