B3DM models not showing up in 3D tiles although debug bounding box is in the correct location

I have created a tileset.json file with three levels of discrete LOD.
I use the BoundingVolume "region" type to specify model location.
Using the debugShowBoundingVolume I can see the volume is oriented in the proper location on the globe, but the model is either not inside it, or not inside the bounding box. I've tried removing the mean from the model vertex values and I've tried keeping the values non mean-offset.

Here are the important steps taken to create and display the tileset.json file

For 3 levels of decimation:
-Create OBJ file
-use obj2gltf converter to create glb file
-use gltf-pipeline with draco compression to compress glb file
-3d-tiles-tools.js glbToB3dm to convert glb to b3dm

The inside of the tileset.json looks like this:

{
  "asset": {
    "version": "1.0"
  },
  "geometricError": 500,
  "root": {
    "boundingVolume": {
      "region": [west, south, east, north, z_min, z_max]
    },
    "geometricError": 10,
    "refine": "REPLACE",
    "content": {
      "uri": texture_mesh_level_2.b3dm
    },
    "children": [
      {
        "boundingVolume": {
          "region": [west, south, east, north, z_min, z_max]
        },
        "geometricError": 5,
        "content": {
            "uri": texture_mesh_level_2.b3dm
        },
        "children": [
          {
            "boundingVolume": {
              "region": [west, south, east, north, z_min, z_max]
            },
            "geometricError": 0,
            "content": {
                "uri": texture_mesh_level_2.b3dm
            }
          }
        ]
      }
    ]
  }
}

west, south, east, north are in EPSG:4326 (in radians)
z_min, z_max are in meters above the WGS84 ellipsoid

The frontend code looks like this (abbreviated):

tileset = $scope.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
     url : url,
   debugShowBoundingVolume: true,
   debugShowGeometricError: true,
   debugShowUrl: true,
   debugWireframe: true
}));

tileset.readyPromise.then(function(loaded_tileset) {
  $scope.viewer.zoomTo(loaded_tileset);
});

It zooms to the red bounding volume at the correct location on the globe, but that's it. Checking the network it shows that the b3dm models are loading in and the objects are all there in the console. They just don't display on the viewer.

(Note that I was able to get a plain glb model to display in the browser just fine. It's just getting the 3D tiles that is giving me all sorts of problems)

I am using Cesium 1.48. Neither Chrome nor Firefox work. Ubuntu 16.04 OS.

Any help would be greatly appreciated!

Sorry for the late reply! Just to confirm there’s no issue loading this tileset, can you change:

tileset.readyPromise.then(function(loaded_tileset) {
$scope.viewer.zoomTo(loaded_tileset);
});

``

To:

tileset.readyPromise.then(function(loaded_tileset) {
$scope.viewer.zoomTo(loaded_tileset);
}).otherwise(function(error) {

``
console.log(error)

});

And make sure there’s no error.

If there’s no error, I’m guessing the problem is that the model itself isn’t in the bounding volume. If it’s origin is (0,0,0) then the model is going to be at the center of the earth. The region defined does not actually move or transform the model. You would need to either move the model itself (in the OBJ before exporting it) or by defining a transform to move it to the right location. So you can see how the tileset.json in this tileset defines a transform to move the model to the right location:

https://github.com/AnalyticalGraphicsInc/3d-tiles-samples/tree/master/tilesets/TilesetWithDiscreteLOD

Let me know if that turns out to be the case!

Hi Omar, thank you for the response.
I actually figured this out on my own after completely abandoning the "region" approach in BoundingVolume. I mean-offset my model (centered it at 0,0,0) and switched to using a "sphere" centered at [0,0,0,radius] and doing the transform to the center lat, lng, elevation in the javascript like this for anyone who stumbles across this in the future. Though it sounds like I just needed to do the same thing when using region (maybe?).

var cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude, elevation);
var cartesian = Cesium.Cartographic.toCartesian(cartographic);
var transform = Cesium.Transforms.headingPitchRollToFixedFrame(cartesian, new Cesium.HeadingPitchRoll());

tileset = $scope.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
     url : url,
}));

tileset.readyPromise.then(function(loaded_tileset) {
  loaded_tileset._root.transform = transform;
  $scope.viewer.zoomTo(loaded_tileset);
});

Anyway, thanks again for the response!

Awesome, I’m glad you figured it out, and thanks for posting your solution!