Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bounding Volume coordinate system clarification #280

Closed
amenzies opened this issue Jan 23, 2018 · 12 comments
Closed

Bounding Volume coordinate system clarification #280

amenzies opened this issue Jan 23, 2018 · 12 comments
Assignees

Comments

@amenzies
Copy link

Hi,

I'm working on a 3D Tiles exporter and renderer. I'm trying to understand the relationship between the 3D Tiles coordinate frame and the glTF coordinate frame, especially in relation to bounding volumes and the gltfUpAxis property.

As an example, lets say we have a box stored in a glTF file with Y as the up axis. Our goal is to create a tileset containing this box. In our tileset, we need to store the bounding volume for the box. My understanding is that the bounding volume needs to be stored in 3D Tiles Frame (z-up) NOT in glTF frame (y-up). So in this case, in our exporter we first compute the glTF files bounds in glTF frame and then apply a glTF to 3D Tiles transform to get it into 3D Tiles frame. In the renderer, we then need to apply the opposite of this transform when we read the glTF file to convert it into 3D Tiles frame at runtime.

I've made the following diagram to illustrate the process of going from glTF Frame to 3d Tiles Frame as I understand it.
image

In the diagram, I assume we want to render the box n the given orientation regardless of how we define the coordinate frame. However, there are many configurations for a right handed coordinate system in which Z is up. I've created two examples (A) and (B). Depending on which of these we choose, our glTF to 3D Tiles transform will be different. This presents a problem because the tileset generator and renderer need to use the same convention. Based on this changeset, it looks like cesium uses (B) but I don't see this documented in the specification anywhere.

I haven't fully worked this out, but it seems like things would only get more confusing once the options for gltfUpAxis get added to the mix.

Please let me know if I've misunderstood how this works.

I think it would be very useful to add some additional text to the README about these transformations and when they should be applied (both during tileset creation and rendering). I'm assuming this should be applied right after loading the glTF file before applying the Tile.transform property.

Overall, I've found it pretty confusing that 3D Tiles uses a different frame then the underlying content storage mechanism. It almost feels like each tile or the tileset could specify a content to tileset matrix to be used when converting the content into tileset frame.

Thanks for the help!

Cheers,
-Alex

@lilleyse
Copy link
Contributor

Hey @amenzies, thanks for the diagrams and notes - this will be really helpful once we bring the spec to completion. I think everything you've stated is correct. I may not get to the spec edits right away so I'll leave this open until then.

However, there are many configurations for a right handed coordinate system in which Z is up. I've created two examples (A) and (B).

I wonder how it can be described clearly in the spec that we are going with option (B). The gltf spec uses the words The front of a glTF asset faces +Z., is there a good analog in 3D Tiles language?

I think it would be very useful to add some additional text to the README about these transformations and when they should be applied (both during tileset creation and rendering). I'm assuming this should be applied right after loading the glTF file before applying the Tile.transform property.

Yup that's correct. The spec text could be clearer about the order of operations.

Overall, I've found it pretty confusing that 3D Tiles uses a different frame then the underlying content storage mechanism. It almost feels like each tile or the tileset could specify a content to tileset matrix to be used when converting the content into tileset frame.

I find this confusing too and I wish the coordinate systems of 3D Tiles and glTF matched. We put some thought into making 3D Tiles y-up but it doesn't translate well to most globe engines (including Cesium) that use z-up coordinate systems such as WGS84. Meanwhile glTF has historically been y-up and so we decided to honor that convention.

My recommendation is to export glTF models using the same z-up coordinate system as 3D Tiles and then setting gltfUpAxis to Z. The renderer may have to handle all the other cases, but to me this is the easiest approach from the content generation side of things.

@caohaoze
Copy link

@amenzies
I have noticed these interesting questions, too. I think it is a good idea to set the Z-axis up in glb in b3dm. The reason is the geo-spatial data(such as shapefile) in 2D Map has a relationship that X-axis represent longitude and Y-axis represent latitude in the GSC(geographical coordinate system). Even though converting the shapefile data from GCS to PCS(projected coordinate system), the direction of longitude is still X-axis, and the latitude is still Y-axis. So (gltfUpAxis to Z) comes true naturally with the right-hand rule.
Actually, I found the truth that the cartesian coordinate system in some softwares is Z-axis up, such as 3Ds Max and SketchUp. And I found that glTF use a matrix which is called Y_UP_Transform to make the model from Z-up to Y-up, whose vertex data still keep Z-up. Moreover, it is easy to get a matrix to put the b3dm to the surface of ellipsoid through 3D Tiles, because I have found that the earth is Z-up in whole cartesian coordinate system.
In one word, Z-up is easier. I prefer Z-up.

@lilleyse
Copy link
Contributor

lilleyse commented May 10, 2018

@amenzies @caohaoze @mlfarrell-convene - would you mind checking out the latest changes to the coordinate system wording? I think we addressed all the points you guys brought up but would like any feedback you have.

The PR is #307.

Specifically check out: Coordinate Reference System.

A couple changes since then:

  • We dropped support for asset.gltfUpAxis since it promotes storing glTF as z-up which is a bit sketchy. This means glTF uses y-up and 3D Tiles uses z-up, which is unfortunate, but is the compromise reached.
  • We are phasing out the CESIUM_RTC glTF extension. It has moved to the RTC_CENTER feature table property, similar to i3dm and pnts.

If you have any thoughts, feel free to leave them here or in the linked PR.

@mlfarrell
Copy link

Still me, I used wrong account before. I wasn't using asset.gltfUpAxis, but the CESIUM_RTC stuff I WAS using quite heavily. That's definitely going to trip up my work. Any chance to keep that around? I'm using the FME 2018 export output, so if they switch over to feature table, I'll have to find a way to support that too.

@lilleyse
Copy link
Contributor

CESIUM_RTC is still a valid glTF 1.0 extension so it will continue to stick around in some form, it just won't be explicitly supported in 3D Tiles which has moved to glTF 2.0.

Cesium will have backwards compatible support for CESIUM_RTC, your project might have to do something similar.

@mlfarrell
Copy link

Okay. Well that works. Thanks!

@ggetz
Copy link
Contributor

ggetz commented May 11, 2018

Resolved in #301

@ggetz ggetz closed this as completed May 11, 2018
@amenzies
Copy link
Author

@lilleyse, little late getting back to you. This looks great to me. I find the new wording a lot clearer and appreciate the order of operations example. Thanks!

@lilleyse
Copy link
Contributor

Great! Thanks for the feedback.

@3a1b2c3
Copy link

3a1b2c3 commented Apr 26, 2022

Stuck at this again trying for a tile reader. Is there any other source of information besides the spec? Somebody has an example maybe? Or can point me to where cesium does it?

So i apply the node transforms in gltf and then rotate to y up and it should work? My tile set doesnt specify a matrix .

@lilleyse
Copy link
Contributor

@3a1b2c3 the order of transformations is:

Final position = final tile transform * y-up-to-z-up matrix * final glTF node transform * vertex

So the glTF needs to be y-up for this to work

Some other resources that might be helpful:

@katSchmid
Copy link

Ok great thats exactly what am doing to get my meshes into WGS84 now. Very helpful

function createBoundingBoxFromGltf(
minX, minY, minZ,
maxX, maxY, maxZ) {

// Take into account the y-up-to-z-up transform:
const tMinX = minX;
const tMinY = -minZ;
const tMinZ = minY;
const tMaxX = maxX;
const tMaxY = -maxZ;
const tMaxZ = maxY;
return createBoundingBox(
tMinX, tMinY, tMinZ,
tMaxX, tMaxY, tMaxZ);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants