How to preserve transform when converting GLTF to 3D tiles

Hi, I’m working on a huge model (> 1GB gltf file) so I broken it into multiple smaller GLTFs and converted them to tilesets so I can pick which ones to load on-demand. However, when I test loading them into the same scene, the tilesets do not appear to be positioned at the right offset (transform). It looks like rotation is correct. I verified that the individual GLTFs has the right transform as I can merge them back and all the objects will be rendered at the correct position. Does the pipeline re-center the GLTF when transforming it to tile? Is there a way to preserve the original transform so I can merge them back to the correct position? I want to avoid manual alignment as it would be very tedious.

Adding an example here using a simplified model:

I split the model into 2 GLTFs, one with light color meshes, the other with dark color. When combining them in one scene, it looks like above. The position of the dark color mesh is lost. The original GLTFs should be rendered as below instead, notice the offset of the dark mesh.

Thanks!

Hi, this does seem to be the same issue as OBJ -> 3D Tiles Centering Algorithm.

Have you tried uploading the models to ion as 3D Model (convert to glTF)? That won’t recenter the models. Is using 3D Tiles a requirement?

I haven’t tried convert to GLTF option, is there a document to tell the difference between this option and the convert to 3D Tiles option? In my use case, the 3D model I have is already a GLTF file. I need to render it efficiently in browser, my understanding is tiling the 3D model will enable the HLOD feature so I can progressively load more details on demand. Will the GLTF option provide the same feature?

No, the glTF option will not generate LODs, it will produce a single model. I just wanted to point it out in case you didn’t need LODs.

Could you expand on the offset approach you tried?

With the on-prem tilers you can give the same longitude, latitude parameters to each model they should be positioned correctly.

Based on the previous post, it says that the tiling pipeline will generate a tight fit bounding box and use the bottom center point as the new origin. I calculated the bottom center point of each parts of the GLTF model and put them at that location when merging the tiles.
However it is not very reliable, it can roughly put the tile around the correct position, but there is always some discrepancy, could be caused by precision of calculation (I used javascript to process and calculate the bounding box of GLTF), could be caused that I don’t have the exact algorithm you do in the tiling pipeline to get the bounding box.

I’m decomposing a large building model, say divide the building by floor, for each floor I create a GLTF in which each vertex has the correct offset in the building local coordinate (pick some point in the building model as the origin) and use Cesium Ion to convert them to a Tileset. I don’t have the longitude and latitude for each of the floor unfortunately.

That’s fine. The longitude and latitude apply to the origin of the model so as long as all the models use the same origin they should be positioned correctly relative to each other.

I want to try it. How do I implement that? Do I first do the tiling and then go to the Asset page to manually add the lat, long?

Unfortunately this only applies to the on-prem tilers.

The lat, long on the asset page positions the tileset origin after it has been tiled, which will be the bottom center point.

sounds good. will try it once I got the on-prem tool. Thanks!

Hi, just give an update so if others had the same problem can try this solution. Setting lat, long, height in on-prem tool does work. Thanks!

Glad to hear! Here’s a setup in case anyone else wants to try it out.

Files:

box-center.glb (1.8 KB)
box-offset.glb (1.9 KB)

Commands

./bin/model-tiler -i ~/Desktop/box-center.glb -o ~/Desktop/box-center-tileset -I CAD --longitude 0.0 --latitude 0.0
./bin/model-tiler -i ~/Desktop/box-offset.glb -o ~/Desktop/box-offset-tileset -I CAD --longitude 0.0 --latitude 0.0

Sandcastle code

const viewer = new Cesium.Viewer("cesiumContainer");

const tileset1 = new Cesium.Cesium3DTileset({
  url: "http://localhost:8002/static/Desktop/box-center-tileset/tileset.json",
});

const tileset2 = new Cesium.Cesium3DTileset({
  url: "http://localhost:8002/static/Desktop/box-offset-tileset/tileset.json",
});

viewer.scene.primitives.add(tileset1);
viewer.scene.primitives.add(tileset2);

viewer.zoomTo(tileset1);