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

Quantized mesh loader #729

Merged
merged 28 commits into from
Jun 1, 2020
Merged

Conversation

kylebarron
Copy link
Collaborator

@kylebarron kylebarron commented Apr 28, 2020

Closes #725. Ref visgl/deck.gl#4500

Implements a loader for the quantized mesh format, which is a mesh format defined here by Cesium.

Notes:

  • What should the name/id be? Currently I set the id to be quantized-mesh, but the - means that it can't be set as a key in an options object without quotes.
  • There's a lot of overlap between this getMeshAttributes and the same function in the TerrainLoader.
  • This uses https://github.com/heremaps/quantized-mesh-decoder for decoding, but they didn't push a transpiled bundle to NPM, so I couldn't load it, and thus copied the file locally. I made an issue on their repo to try to publish a transpiled version of their package, because there's no other reason necessitating forking their code.

(Future) Todo:

  • parse the vertex normals extension if provided in the data.

cc @mogmog Is there a Cesium API to access the raw quantized mesh tiles to test this on a wider scale than one tile?

@mogmog
Copy link

mogmog commented Apr 28, 2020

So excited to try this!

I will attempt wiring this up later today with Deck - I am no expert but what I can say is that when you login to Cesium and view this dataset I see network requests following a pattern like this -

https://assets.cesium.com/1/9/495/372.terrain?extensions=octvertexnormals-metadata&v=1.2.0

I guess for now we remove the extension param - interestingly they make reference to water effects.

There is a Bearer token required too - identical to ION assets.

@kylebarron
Copy link
Collaborator Author

Once the loader is working, using it with deck.gl should be straightforward. Basically here, you just call

load(url, QuantizedMeshLoader, {'quantized-mesh': [bounds]}

I'm not sure why CI is failing. Maybe the worker is set up incorrectly.

@ibgreen
Copy link
Collaborator

ibgreen commented Apr 28, 2020

@loshjawrence FYI - We have implemented the quantized mesh format loader that Ceisum uses for terrain.

Are there any demo 3d tilesets that contain terrain tiles using this format that we could test against?

Copy link
Collaborator

@ibgreen ibgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mesh category loader Also update top-level doc that lists links to loaders for each category and the mesh category doc page.

The docs need another pass for correctness.

What should the name/id be? Currently I set the id to be quantized-mesh, but the - means that it can't be set as a key in an options object without quotes.

Yes I am torn on this. I think all lower case is best from a JSON Perspective, but it is not 100% clear cut. But fine for now.

There's a lot of overlap between this getMeshAttributes and the same function in the TerrainLoader.

Yes, it could be time to define a meshes module for common functions for this category of loaders.

This uses https://github.com/heremaps/quantized-mesh-decoder for decoding, but they didn't push a transpiled bundle to NPM, so I couldn't load it, and thus copied the file locally. I made an issue on their repo to try to publish a transpiled version of their package, because there's no other reason necessitating forking their code.

Sounds reasonable. We can also tone down the amount of licenses we include if we don't actually copy their code.

modules/quantized-mesh/docs/README.md Outdated Show resolved Hide resolved
modules/quantized-mesh/README.md Outdated Show resolved Hide resolved
@kylebarron
Copy link
Collaborator Author

Maptiler has a quantized mesh tileset that has a free entry tier, so I can test with their tiles.

@kylebarron
Copy link
Collaborator Author

I'm testing one of the maptiler quantized mesh tiles. One of the outputs from the decoder is triangleIndices. I understand this to be a flat array describing triples that represent triangles of the mesh. But for the maptiler tile specifically, many of the indices are the same:

Uint16Array [
   0,  0,  0,  0,  0,  1,  0,  1,  2,  2,  1,  3,
   2,  3,  4,  4,  3,  5,  4,  5,  6,  6,  5,  5,
   6,  5,  7,  7,  5,  8,  7,  8,  7,  7,  8,  9,
   7,  9,  7,  7,  9, 10,  7, 10,  6,  6, 10, 10,
   6, 10, 11, 11, 10, 12, 11, 12, 13, 13, 12, 12,
  13, 12, 14, 14, 12, 12, 14, 12, 15, 15, 12, 10,
  15, 10, 15, 15, 10, 16, 15, 16, 14, 14, 16, 16,
  14, 16, 17, 17, 16, 16, 17, 16, 18, 18, 16, 10,
  18, 10, 18, 18,
  ... 6134 more items
]

746 out of the 2078 triples have 2 or more indices the same. Which doesn't make sense because you can't make a triangle without three distinct points. But Maptiler has an example rendering with Cesium (might need to sign in). So either:

  • Maptiler's data is invalid, but cesium still renders it correctly
  • I'm misunderstanding the output from the decoder library somehow.

The existing quantized mesh data file in test/fixtures/ comes from Cesium and has no overlapping vertices, so I'm more inclined towards the former possibility.

@loshjawrence
Copy link
Collaborator

loshjawrence commented Apr 29, 2020

I think the only example data we may have lying around would be in the form a sql file. but it sounds like you guys got some data.

many of the indices are the same

I wonder if they are doing something weird with the skirt vertices, like if they are using vertex triplets to indicate that this vertex is a skirt vertex, but probably not if they are using the skirt vertex buffer to flag them. A skirt vertex is a vertex on the edge of the tile, on the client it is duplicated and dropped down some meters to form a skirt around to tile to help hide cracks when there's jump in LOD across the terrain. you generate the skirt on the client to save on payload size.

However, you did mention there were some triangle index triplets where there were only two duplicates. So maybe it's a bug in their generation code where they collapsed edges and updated vertex ids but forgot to clean up their index buffer, idk.

@kylebarron
Copy link
Collaborator Author

This would be work for a future PR, but the 3d tiles docs list

Tile Header - A minimal header describing a tiles bounding volume and a screen space error tolerance (allowing the tile to be culled if it is distant), as well as the URL to load the tile's actual content from

The first 88 bytes of the quantized mesh format describe much of this content.

// The center of the tile in Earth-centered Fixed coordinates.
double CenterX; double CenterY; double CenterZ;

// The minimum and maximum heights in the area covered by this tile.
// The minimum may be lower and the maximum may be higher than
// the height of any vertex in this tile in the case that the min/max vertex
// was removed during mesh simplification, but these are the appropriate
// values to use for analysis or visualization.
float MinimumHeight; float MaximumHeight;

// The tile’s bounding sphere.  The X,Y,Z coordinates are again expressed
// in Earth-centered Fixed coordinates, and the radius is in meters.
double BoundingSphereCenterX; double BoundingSphereCenterY; double BoundingSphereCenterZ; double BoundingSphereRadius;

// The horizon occlusion point, expressed in the ellipsoid-scaled Earth-centered Fixed frame.
// If this point is below the horizon, the entire tile is below the horizon.
// See http://cesiumjs.org/2013/04/25/Horizon-culling/ for more information.
double HorizonOcclusionPointX; double HorizonOcclusionPointY; double HorizonOcclusionPointZ;

In future work it would be possible to more fully integrate quantized mesh tiles into the tileset3d "state of mind", and the QuantizedMeshLoader could be adapted to send an HTTP range request for the first 88 bytes on the remote resource, to more quickly get just the metadata needed.

@kylebarron
Copy link
Collaborator Author

Finally green.

  • Moved the QuantizedMeshLoader to the terrain module
  • Opened a PR in heremaps/quantized-mesh-decoder to support transpiling, so hopefully soon we'll be able to take out the copied code.
  • Updated the docs to reflect loading QuantizedMeshLoader from @loaders.gl/terrain.
  • Added TerrainLoader, QuantizedMeshLoader to the Loader Catalog on the website.
  • Options id is still quantized-mesh

Future work:

  • Skirting. Ref TerrainLoader skirting #712 The Quantized Mesh format includes data on which vertices are on each edge, which should make creating a skirt easier. A couple weeks ago I looked into adding skirts to mesh output from TerrainLoader. I ran into the issue that with the current setup, I don't know how many edge vertices there are until after filling the vertices TypedArray. To make a skirt at that point, I'd need to copy the data into a new, larger TypedArray.

    The better way to prevent an extra copy is to first find the number of edge vertices and then allocate the correct length array from the start. This is simple with quantized mesh since that metadata is always included, but when using the TerrainLoader requires an initial pass over all vertices to get the number of edge vertices.

  • Parse normals extension. There's an optional extension where vertex normals are included in the data.

  • Faster bounding box. Currently getMeshBoundingBox is used for both QuantizedMeshLoader and TerrainLoader, which does an extra pass over all vertices to find min/max values. For QuantizedMeshLoader this information should be accessible from the header.

@xintongxia xintongxia added this to the v2.2.0 milestone May 9, 2020
@kylebarron
Copy link
Collaborator Author

@here/quantized-mesh-decoder v1.2.0 was published a couple days ago, and should now be bundled to ES2015 with rollup, so we should be able to remove the local copy now.

Copy link
Collaborator

@ibgreen ibgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • You have collected some good information here, e.g. in the"future work" section above. You could put some of that in a ## Remarks section in the doc itself.

  • You also probably want to create a clean tracker issue for these things (terrain module tracker)

Are you getting ready to merge this? This PR has been approved for quite a while. If so can you add a blurb to the 2.2 section in the "what's new" doc before merging?

modules/terrain/docs/README.md Outdated Show resolved Hide resolved
modules/terrain/docs/README.md Outdated Show resolved Hide resolved
modules/terrain/docs/README.md Outdated Show resolved Hide resolved
@ibgreen ibgreen merged commit 41cd142 into visgl:master Jun 1, 2020
@kylebarron kylebarron deleted the quantized-mesh-loader branch June 1, 2020 21:45
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

Successfully merging this pull request may close these issues.

Quantized Mesh loader
5 participants