Refinement based on proximity
pjcozzi opened this issue · 2 comments
Instead of relying just on SSE to refine a tile, this would allow, for example, when the viewer enters a bounding volume that the tile gets refined.
A use case is to tile a city with a kd-tree, then when the viewer enters (or comes close to) a building, the building is loaded with an octree, grid, portals, etc.
We might also want to be able to explicitly disable the rest of the scene when inside a building.
CC #15
@lilleyse this will require some experimentation to flush out.
This adds viewerRequestVolume
(with the same sub-properties as boundingVolume
) so the tile's content is not requested until the viewer is inside this volume.
Here's a potential example where the root tile could be a city; the child is a building's interior tile; and the grandchild is an external tileset for a point cloud for an object in the building. For kicks I also added a transform to the children (#98) since the building's interior and point cloud would likely be in their own coordinate systems.
{
"asset" : {
// ...
},
"geometricError": 200, // Error when no buildings are rendered
"root": {
"boundingVolume": { /* ... */ },
"geometricError": 20, // Error because building interior is not rendered
"refine": "replace",
"content": {
"url": "0.b3dm" // Exteriors for entire city
},
"children": [{
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7000000, 0, 0, 1], // transform to WGS84
"boundingVolume": { /* ... */ },
"geometricError": 2, // Error because point cloud is not rendered
"viewerRequestVolume": { /* ... */ },
"content": {
"url": "1.b3dm" // inside of building
},
"children": [{
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1], // transform to Building's coordinate system
"boundingVolume": { /* ... */ },
"geometricError": 2, // Error because point cloud is not rendered, forces external tileset load
"viewerRequestVolume" : { /* ... */ },
"content": {
"url": "points-tileset.json" // New tileset with point cloud
}
}]
}]
}
}
Here's another example where the root tile (a city) has two (grand-)children (each building interiors) in their own tilesets (using additive refinement so, for example, the city is visible outside of the window).
{
"asset" : {
// ...
},
"geometricError": 200, // Error when no buildings are rendered
"root": {
"boundingVolume": { /* ... */ },
"geometricError": 20, // Error because biggest building interior is not rendered
"refine": "add",
"content": {
"url": "0.b3dm" // Exteriors for entire city
},
"children": [{
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7000000, 0, 0, 1], // transform this building to WGS84
"boundingVolume": { /* ... */ }
"geometricError": 20, // Error because biggest building interior is not rendered, forces external tileset load
"viewerRequestVolume": { /* ... */ },
"content": {
"url": "big-building-interior-tileset.json"
}
}, {
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 6000000, 0, 0, 1], // transform this other building to WGS84
"boundingVolume": { /* ... */ },
"geometricError": 10, // Error because smaller building interior is not rendered, forces external tileset load
"viewerRequestVolume": { /* ... */ },
"content": {
"url": "small-building-interior-tileset.json"
}
}]
}
}
Discussion
-
viewerRequestVolume
has the same sub-properties asboundingVolume
. Likewise, it is in the coordinate system defined bytransform
. - To implement this, check if the viewer is inside
viewerRequestVolume
before requesting/rendering a tile's content or refining the tile.- If
viewerRequestVolume
has multiple sub-properties, the viewer needs to be in the union of them? - For replacement refine, I think it is fine to refine the parent and only render the children that pass the new volume test (even if it isn't all of them), but we shouldn't refine the parent until at least one child is ready to render and visible.
- Is "viewer in volume" the right test? Maybe the spec could be worded so that it is more like "near plane in volume?"
- If
- Could be just a roadmap implementation detail: to avoid jarring popping artifacts, it could be useful for a runtime to scale the
viewerRequestVolume
to be slightly larger, and then check thegeometricError
for prefetching (but not rendering until the viewer enters the unscaled volume).
Cesium implementation is in CesiumGS/cesium#4138