problme of 3D Tiles ModelMatrix

1. A concise explanation of the problem you're experiencing.
Hi, I have a purpose to put a 3D tiles on a location of cartographic(longitude,latitude), but the 3d tiles is a lit far away the location and also rotated by some angle.


before modelMatrix:

after modelMatrix:

Is there anyone can help me how to solve it?
Thanks

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

    <script>

    var url = ‘http://192.168.0.147:7777/myApps/Batchedbarrel/tileset.json’;

    // var cesiumContainer = 'cesiumContainer';
    var viewer = new Cesium.Viewer('cesiumContainer');

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

    tileset.readyPromise
        .then(function() {
            let inverse = Cesium.Matrix4.inverse(Cesium.Matrix4.fromArray(tileset.root.transform), new Cesium.Matrix4());
            let rotation = Cesium.Matrix4.getRotation(inverse, new Cesium.Matrix3());
            var heightOffset = 0;
            var boundingSphere = tileset.boundingSphere;
            var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
            var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
            var lon = 175.3050519951;
            var lat = -41.1948830262;
            var alt = 0;
            var height = 0;
            var offset = Cesium.Cartesian3.fromDegrees(lon, lat, height);
            var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
            var modelMatrix = Cesium.Matrix4.fromTranslation(translation);
            tileset.modelMatrix = modelMatrix;
            viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0, 0, 0));
        }).otherwise(function(error) {
            console.log(eror);
        });

    </script>

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I am a new cesiumer, I am appreciate someone would like to help me!

4. The Cesium version you're using, your operating system and browser.
Cesium 1.50

If you’re just trying to re-position your tileset on the globe, since your tileset is positioned with a root transform matrix, I think the easiest way is to modify that root transform matrix.

I think the issue here is that, the rotation your tileset has on one part of the globe is not the same you’d need on another part of the globe. For example, if you put your tileset on the opposite side of the globe you’d need to flip it upside down. You can use the eastNorthUpToFixedFrame function to get a consistent rotation on any part of the globe. So this would look something like:

tileset.readyPromise

.then(function() {

// Define a cartographic position

var lon = 175.3050519951;

var lat = -41.1948830262;

var height = 0;

var offset = Cesium.Cartesian3.fromDegrees(lon, lat, height);

// Set the root tile transform

tileset.root.transform = Cesium.Transforms.eastNorthUpToFixedFrame(offset);

// Zoom in

viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0, 0, 0));

}).otherwise(function(error) {

console.log(eror);

});

``

Let me know if that works. What kind of application are you building?

1 Like

Hi Omar,
I tried it worked if I use my 3d tiles, but it looks like faild if I use it in this case of "https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=3D%20Tiles%20Adjust%20Height.html&label=All",
would you please tell me what's the problem?
Thanks a lot!

When you say it doesn’t work, do you mean your tileset is rotated in the same way or that you don’t see it at all or something else?

In that example I believe it’s a special case because that tileset does not have a root transform defined, it’s getting it’s position from the region defined in the bounding volume. When a model matrix is defined it overrides that transform, that’s why it’s necessary in that example to initialize the model matrix with the current location of the tileset, which is what this line does:

var cartographic = Cesium.Cartographic.fromCartesian(tileset.boundingSphere.center);

``

Does that make sense?