Open jingyangking opened 4 months ago
this is my tiles file two_ifctileset.zip
This is not really an issue of the 3d-tiles-tools
. The issue tracker should not be used for general support questions. If you want to report a bug in the 3d-tiles-tools
, or request a featue, then you can open an issue here. But if you have a general question, then you could ask at the Cesium Community Forum. There, more people will see your question, and more people will have a chance to answer. And if you ask such a question, then you should include more information. For example: I can see this line scene1.rotate...
in the screenshot. But I don't know which framework/library/application you are actually using for rendering the tileset.
However, I did have a short look at the tileset that you provided. And I have to add a disclaimer here: I have to make a few guesses, due to the lack of technical background information. But the problem is very likely caused by the fact that the tileset has a structure that is ... not ideal for "runtime manipulations".
The tileset consists of a single root node/tile. And it has several child tiles. (Each child tile refers to one B3DM file). The child tiles do have a transform
matrix that contains a huge translation component. This translation component should probably move the tile data to a certain position on the globe. But the problem is that this translation has to be taken into account when you want to rotate the tileset. Depending on the exact renderer that you are using (and depending on what scene1.rotate...
is doing, exactly), the result of applying a rotation may not be what you expect.
I tried to illustrate this here:
The question now is: How can this be solved?
And there is probably no easy, one-fits-all solution. But for the specific tileset that you attached, there may be a way to accomplish the desired goal. Since the structure of the tileset is very simple, you can easily create a new one that has a structure that makes this kind of manipulation easier.
You can use the createTilesetJson
command to create a new tileset JSON file from the given B3DM files. When you run
npx 3d-tiles-tools createTilesetJson -i C:\two_ifctileset -o C:\two_ifctileset\tileset-new.json
then it will generate the tileset-new.json
that is attached here:
This tileset will be located at the origin. This means that it will not include any tile transform
matrices. This means that
The following is a sandcastle that shows how this can be done:
const viewer = new Cesium.Viewer("cesiumContainer");
const tileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromUrl(
"http://localhost:8003/tileset-new.json", {
debugShowBoundingVolume: true,
})
);
// Move the tileset to a certain position on the globe
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.152408, 39.946975, 20)
);
const scale = 1.0;
const modelMatrix = Cesium.Matrix4.multiplyByUniformScale(
transform,
scale,
new Cesium.Matrix4()
);
tileset.modelMatrix = modelMatrix;
// Zoom to the tileset, with a small offset so that
// it is fully visible
const offset = new Cesium.HeadingPitchRange(
Cesium.Math.toRadians(-22.5),
Cesium.Math.toRadians(-22.5),
560.0
);
viewer.zoomTo(tileset, offset);
The result will be the tileset, rendered at the given cartographic position:
Thank you for your reply! I think I will listen carefully to your suggestions. For the issue of correcting the position of tiles, I think the root cause of the problem may be the inconsistency of the coordinate axes applied when creating the tile set. I will study this and would like to know if you have any good suggestions? Thank you!
the inconsistency of the coordinate axes applied
I assume that refers to the question of which axis is the 'up' axis. And yes, this can be confusing. Every tool and every 3D format has its own convention. For example, glTF (which is contained in B3DM) defines the Y-axis as 'up' (at least, in version 2.0). In 3D Tiles, the Z-axis is the 'up' axis. And there are further details of the conventions that may cause confusion. Some of that is summarized at https://github.com/CesiumGS/3d-tiles/tree/main/specification#y-up-to-z-up , but ... regardless of how clearly it is specified, it will always lead to bugs.
However, in the level of the tileset itself, changing the 'rotation' could be simple. In a CesiumJS Sandcastle, you can set the tileset.modelMatrix
(as shown in the example above), and this can contain the required rotation. But in the tileset that you provided, this is more difficult, because it contains the translation components in the child tiles.
Do you happen to know which tool was used for creating this tileset?
Yes, I used the py3dtiles tool to create tiles. Fortunately, I have found the problem of dealing with tiles with incorrect orientation. I added a corresponding matrix to the root node of tiles. json and set the corresponding rotation vector, and the incorrect orientation of tiles actually became correct. Although I am not sure why this operation can solve the problem perfectly, I still want to understand the principle behind it. If you know, I hope you can tell me. Thank you!
The screenshot that you showed already seems to be from the tileset-new.json
that was created with the createTilesetJson
command. And there, none of the tiles contains a transform. So you can insert the transform 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, ...
that applies the rotation for the up-axis conversion. And the important point is: This can be done without affecting the transforms of the child tiles, and without affecting the bounding volumes. If the chilld tiles contained a transform
matrix, then inserting the axis-conversion transform would affect the position of the tile content in the way that I tried to illustrate in the picture above.
Sorry, I didn't use the createTilesetJson command to perform a tileset.json update. I just added a matrix for the root node on top of the original tileset.json, and didn't do anything else. So, I'm curious why adding a matrix allows me to rotate and transform it as a whole. Here is the modified JSON tileset.zip
I see. I was confused by the screenshot: It shows a boundingVolume
for the root that is different from the bounding volume of the root of the tileset that you just posted:
"geometricError": 500.0,
"root": {
"boundingVolume": {
"box": [
486144.9223339863,
3554992.1194912135,
10.550217400223502,
48.79999904060969,
0.0,
0.0,
0.0,
110.17518057441339,
0.0,
0.0,
0.0,
29.849785207338435
]
},
...
In general, you have to be a bit careful when "manually" editing a tileset JSON file: It can easily happen that the tileset becomes "inconsistent" in terms of the bounding volumes and transforms.
In this case, adding a transform
to the root
tile should be "safe" in many ways: It originally did not have a transform
(meaning that the transform defaulted to the identity matrix), and when you assign a new transform only to the root, then no bounding volumes or other transforms have to be updated.
But two things are still raising some questions:
scene1.rotateX...
call that you showed earlier.I assume that you are using https://github.com/NASA-AMMOS/3DTilesRendererJS for rendering the tileset, is that correct? (Maybe I'll have a short look at this, and what rotateX
might be doing different than just applying a rotation to the tileset...)
I'm very sorry, I forgot something. After adding the matrix to tileset.json, I don't need to manipulate the position of the model in the scene. I just need to modify the newly added matrix to change the position of the model at will. Therefore, the previous rotateX is no longer used (if it is necessary to use it, there will still be a problem of position confusion). I do use 3dtilesrenderjs, which makes it easy for me to load tiles in Threejs. Thank you for your reply!
this is the situation where I directly loaded tiles without making any modifications:![image](https://github.com/CesiumGS/3d-tiles-tools/assets/112468121/7c56e7d0-21da-403f-9729-d41437b20f97)
you can see that the position of the building is vertical.Here is a demonstration of my model after making positional changes in the code:
You can see that the positions of some subcomponents have been misplaced,How can I perform the correct position transformation of tiles?Thank you!