Overlaying OBJ file to a 3D Tileset in Cesium

Hello Everyone!

I am trying to overlay an OBJ file to a tileset in Cesium. In order to do this, I used the _root.transform of the tileset, load the OBJ file as a 3D tileset as well and set the modelMatrix to the value of the _root.transform of the tileset, but the position is slightly off on the OBJ file. This is the function I used to display it on the viewer:

let matrix = tileset._root.transform

let modelTileset = this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
    url: url,
    show: true,
    ellipsoid: Cesium.Ellipsoid.WGS84,

modelTileset.readyPromise.then((t) => {
    t.root.transform = Cesium.Matrix4.IDENTITY;
    t.modelMatrix = matrix;

Is there another way to properly position the OBJ file with respect to the position of a specific tileset? Any idea would be much appreciated.

1 Like

Hi @Sarah_Osay - Can you elaborate on the process of how you converted the OBJ to 3D Tileset? The tileset’s root transform should automatically be read and there should be no reason to store it temporarily and then re-assign it after load.

Hello @Shehzan_Mohammed , thanks for the reply. I converted the OBJ file to 3D Tileset by generating the tileset.json using the model-tiler command below:

model-tiler -I 3DSCAN -i Model.obj -o Tileset --verbose 
--longitude 140.51264488968832 --latitude 35.973877838862485 
--height 5.039999900458211

I got the lat, long & height using the code below:

var center = Cesium.Matrix4.multiplyByPoint(
    new Cesium.Cartesian3()
var cartographic = Cesium.Cartographic.fromCartesian(center);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var long = Cesium.Math.toDegrees(cartographic.longitude);
var height = cartographic.height;
console.log(lat, long, height);

But after loading it to cesium and not re-assigning the matrix, it’s position is very far from the tileset. That is the reason why I opt to re-assign the matrix to the modelTileset.

Hi Sarah

The position you are passing to the model-tiler command line is the coordinates for the origin of the OBJ model. If the coordinate you have passed does not align to the OBJ’s center, then it will be offset, like you may be experiencing.

The model tiler creates a 3D Tileset where origin is its “bottom-center”. That is, the model-tiler re-centers the model around its bottom-center. This is why the manual adjustment you are applying is changing the position.

If you have the correct lat/long for the origin of the OBJ 3D Model, then there shouldn’t be a need to re-adjust it.


1 Like

Hi @Shehzan_Mohammed ,
Thanks for the detailed response.
I am colleague of Sarah and I would like to ask some few questions towards what you have taught to us.

  1. In an easy example diagram below, do you mean the bottom-center origin will be (1/3, 1/3, 0) in this case?

  2. In the parameter of the model-tiler, there is no CRS(epsg, wkt). What will happen to the coordinates of the 3D Tileset (in the object coordinate system) created by a point cloud that is georeferenced as ‘UTM zone 54N’ for example?

  3. Do we always need to pass arguments to ‘–longitude’ and ‘–latitude’ in order to display the 3D Tilest(3D model) in the expected location as if it is georeferenced?


Hi Hiroshi

The bottom center refers to the coordinates in 3D - that is, the center is the mid-point of the latitude and longitude, but the vertical axis is originated at the bottom-most coordinate of the 3D model. So on the vertical axis the new 0 is the lowest point in the model, and max is the height point in the model.

For the CRS, thats not supported right now, but we are working on a new pipeline for 3D models that does support CRS coordinate systems out of the box.

Do we always need to pass arguments to ‘–longitude’ and ‘–latitude’ in order to display the 3D Tilest(3D model) in the expected location as if it is georeferenced?

This is not strictly required, but displaying a model tiled this way will place it at (0, 0) latitude, longitude. You can then either upload it to Cesium ion to use the location editor tool or apply transforms manually in CesiumJS (like the original post).



Thank you for your answer.
We will try to solve the issue with your given advice.
We will make sure to let you know if we were able to solve or if we have another questions.