cesiumgs / 3d-tiles Goto Github PK
View Code? Open in Web Editor NEWSpecification for streaming massive heterogeneous 3D geospatial datasets :earth_americas:
Specification for streaming massive heterogeneous 3D geospatial datasets :earth_americas:
Lessons learned from CesiumGS/cesium#3237
A tile with content.url
pointing to an external tileset (another tile.json):
children
.root.geometricError === tile.geometricError
and root.box === tile.content.box
(or equals tile.box
if tile.content.box
is undefined
).@e-andersson any other corner cases we should add to the spec?
As we add more tile formats, 3D Tiles needs to stay consistent.
sections
such as header
and body
. Sections are composed of fields
such as magic
and version
.Length
- a Length
suffix on a field name indicates the number of elements in an array.ByteLength
- a ByteLength
suffix indicates the number of bytes, not to be confused with just Length
.magic // uchar[4], indicates the tile format
version // uint32, 1
byteLength // uint32, length, in bytes, of the entire tile.
This is a work-in-progress. There are more guidelines to come.
This will be one of the last things we do so we know the schema is stable.
Like glTF.
This will be an update to tiles.json. It could also impact tile formats since each "sub-title" will need some kind of set of (offset, length)
pointers into the tile content.
What is the best approach for tileset.json when generating tilesets dynamically like in #22 (comment)?
I'm not having any luck getting Cesium to display my own generated 3d-tiles data set, so I pulled down all the Chappes demo data and tried to get that to display like http://cesiumjs.org/Chappes/ does -- but no joy there either. I'm clearly doing something wrong, but don't have a working example I can try to compare against.
It would be very helpful it you could put into the examples directory a very simple test dataset (the json and the actual tiles, plus the couple lines need to include in the HelloWorld sample app). Doesn't have to be the Chappes data, just a few tiles with few hundred points each.
Thanks much.
Is there an advantage to knowing this in tiles.json when it is also defined as the length of the batch table in b3dm
? Or can we remove contents.batchSize
in tiles.json?
Like glTF's copyright property, This could be as simple as:
{
"asset" : {
"credit": "a string"
}
}
However, it would force converters to generate multiple tileset.json files (which could still reference each other to form a tree) to support per-tile credits. So we can move "copyright"
to each tile, e.g.,
{
"root": {
"credit": "a string"
// ...
"children": [{
"credit": "another string or omit to inherit"
// ...
}]
}
}
The "credit"
could inherit from the parent, and its display would be based on the refinement type because refinement impacts which tiles are rendered. This works well for common uses cases:
The following changes to the points README would help reduce potential for misunderstanding:
magic
bytes should be set to pnts
version
should be set to 1
positions
data to be in lat/lon, radians, or..?positions
data to be expressed as XYZXYZXYZ
or XXXYYYZZZ
?colors
data to be expressed as RGBRGBRGB
or RRRGGGBBB
?16 + numpoints * 15
Point clouds use contents.boundingSphere
for the RTC center point. This is not documented yet in README.md. We could put it in the tile itself, but it belongs here instead if 3D Tiles allow bounding spheres as a potential bounding volume, which I suspect we will.
I am currently experimenting with external tilesets and came across a question with relative URLs.
Assume a tileset a.json
with a content.url
pointing to another tileset b.json
. b.json
contains a content.url
to a tile.b3dm
content file. Further assume that a.json
and b.json
are not in the same path.
Now, my assumption was that a relative content.url
to tile.b3dm
must be given relative to b.json
because it is referenced from this tileset. However, I was surprised to learn that it has to be relative to a.json
. Is this the supposed behavior?
Cheers,
Claus
To be more complete and rigorous than just the example in README.md.
We use photoscan to put images together and one of the nices things here is that it nativly support export to potree as a zip file.
The potree project has been under its way for some time and has tools for generating trees.
I am thinking that it would make sense to talk with the author about points and look into if it makes sense to reuse as much as possible, due to the tooling support already. Otherwise leaving all of us to solve one more tooling pipeline :)
Looks good btw. Happy to see the path AGI/Cesium is taking.
Extensions in both tiles.json and the tiles themselves. We'll most likely take the same approach as glTF (for tiles.json) and quantized-mesh (for tiles).
Does tiles.json support both extensions
and extras
like glTF? Perhaps extra
is useful for application-specific per-tile metadata that the app could process with a load event. We need concrete use cases.
Point cloud data is typically more than 3 fields for (x,y,z): LAS classification, salinity and temperature, etc., any of which one might want to represent by mapping it into (r,g,b).
Is there a plan to expand the binary blob in the point tile to include fields beyond (x,y,z) and allow for a colorization function to be plugged in, or is the intent that such colorization be done dynamically on the server side and passed back by the (r,g,b) fields?
First, see the original notes for Instanced 3D Model and Composite tile formats. To help design the Instanced 3D Model tile format, see the Batched 3D Model tile format.
We now have significant work towards instancing in Cesium. See CesiumGS/cesium#3049.
Here's some initial thoughts:
Header
------
magic // uchar[4], "i3dm"
version // uint32, 1
batchTableLength // uint32, can be zero, length of the batch table in bytes
glTFLength // uint32, length of glTF section (after the Batch Table) in bytes
glTFFormat // uint32, 0 = url, 1 = embedded binary glTF
instancesLength // uint32, number of instances, NOT number of bytes, can be zero I guess
Batch Table
-----------
// Same as Batched 3D Model. Optional.
glTF
----
// UTF-8 string or binary blob depending on Header.glTFFormat
// Length in bytes is Header.glTFLength
Instances
---------
There are Header.instancesLength of these:
* x, y, z // doubles in WGS84 coordinates
* x, y, z, w // doubles in WGS84 coordinates (quaternion)
* batchId // uint32, index into batchTable, zero when Header.batchTableLength === 0
instance
field, e.g., positions can be quantized relative to the bounding volume (see EXT_quantized_attributes). Rotation could also be optional (part of the batchTable) and default to Y up (glTF default) in a local frame for the instance's position. Rotation could use fewer fields. RTC. Delta encoding... SOA vs. AOS... Look into point cloud compression...instance.batchId
be omitted when header.batchTableLength === 0
. This will complicate the client, but save memory; however, the case it saves memory for is probably rare in practice.batchTable
be renamed? Something like propertyTable
, metadataTable
, etc. We can also decide this later as we define more tile formats. Consistent terminology is important.batchTable
work more like glTF buffer/bufferView/accessor to avoid arrays of numbers?In order to have different models instanced in the same tile (or more generally, combine any number of tiles, even tiles of different formats), we can use a Composite tile format.
Perhaps:
Header
------
magic // uchar[4], "cmpt"
version // uint32, 1
tilesLength // Number of tiles
Tiles
----
// header.tilesLength (potentially heterogeneous) tiles
We are working on ideas for supporting hierarchies in B3DM.
The background is that we are working with 3D GIS and BIM data (as CityGML or IFC), which are usually more complicated than 3D viz datasets. We want to preserve as much information as possible.
Currently there is a way to group nodes in GLTF. However, we also want to optimzie rendering as much as possible and make use of batches including attribute tables in B3DM.
In our scenarios, we have complex input data with groups, hierarchies and attributes on different levels. For instance,
a building has a unique id and a set of attributes and properties. The parts the building is made of also has a set of attributes, which are usually different. Sometimes we have 3 hierarchy levels and more.
the application we are working on must support selecting and highlighting entities at all available levels and display the attached attributes (as key value pairs).
We want to click on buildings and display building specific attributes and we also want to click on building parts and display component specific (wall, roof, window, door...) attributes without switching
to another data set with different configuration. The behavior of what kind of element is selected is controlled by a toggle button or by other means.
The current design of the batch table is quite simple, it is basically a 2D grid.
Now the question is how we group together batches and attach attributes to these groups.
We found out that the number of columns is flexible and that its not restricted to the number of batches. We can extend the batch table to include additional columns representing abstract features for which we can include attitional attributes.
This is nowhere specified, but it currently happily consumed by Cesium.
@jbo023 has set up a demo application
http://hosting.virtualcitysystems.de/demos/hierarchy/
Use the CityGML Explorer to access attributes and toggle between building selection and part selection using the buttons on the right.
Example B3DM file:
http://hosting.virtualcitysystems.de/demos/hierarchy/examples/data/buildings_semantic/15/35210/6826.b3dm
There is no formal specification of our approach because we see it as workaround taking into account the current limitations of B3DM.
Please let us know in case somebody is working on a similar topic. We are happy to discuss possible solutions.
As to the example file above, you will see batch table with ids, attributes (ignore the strange format for now..) and a row called parentPosition.
The latter is providing the information on how things are grouped together. E.g the first two entries in this row are 1243, which means that these batches are grouped together.
The id of this group can be found in the id array at position 1243. However, there is no batch with this number, its just an abtract group feature.
What do you think of this approach?
Has anybody alternative ideas or suggestions to accomplish this? Our intention is to include this feature in the 3D Tiles specification so that we can base our framework on the master branch. We can try to formally describe our concept in the git repo and create a pull request.
best regards,
Arne
Hi,
What is the best way of generating a .pnts file? Are there any programs or utilities available?
Thank you.
And update the JSON in the spec.
https://groups.google.com/forum/#!topic/cesium-dev/tCCooBxpZFU
From @kring:
I noticed that the spec says, "the bounding volume for child tiles are completely inside the parent's bounding volume." Why? Isn't it sufficient for the child content to be inside the parent's bounding volume?
Such as on/off distance, average/worse-case geometric error, and meters per pixel. In addition to updates to tiles.json, there may also be tile-format-specific metadata.
See Is Screen-Space Error the only metric used to drive refinement?
Cesium now throws an exception when "asset": { "version": 0.0}
is missing from tileset.json
, so if that's the desired behavior it should be reflected in the schema. Judging from the example tileset.json
https://github.com/AnalyticalGraphicsInc/3d-tiles#tilesetjson there may be other updates needed.
Since most 3D Tiles tilesets are generated once and then served as static files, it's good practice to provide an aggressive caching policy in order to avoid unnecessary server hits. This is similar to how we serve Cesium's world terrain, for which we set a cache policy of one year. The problem with this approach is that if I want to update an existing tileset, browsers that already have older versions of the tiles won't request new ones (for a year at least).
This is a common problem in the industry and is solved via query parameters. We can add a property to the root tiles.json file whose value gets appended as a query string to every tile request. tiles.json would then be served with a less aggressive caching policy (1 hour) and the browsers would automatically detect when it changes causing new copies of the previously cached tiles to be fetched as needed.
As an example, in STK Terrain Server's layer.json, there is a version property that indicates the version of the tileset (not the version of the spec). Requests are then made by Cesium with the ?version=<value>
query parameter as I described above. We could use a version
property in tileset.json as well, since it has semantics that allow developers to tell what version of a dataset a client is using, or we could simply add an id
property that require it to be a GUID string so that it's always unique uniquely identify the tileset.
I'm not partial to either approach, as long as the spec enforces one of them. (or optionally determine a complete different way to solve the caching problem).
See When using replacement refinement, can multiple children be combined into one request?.
We may design 3D Tiles to support downloading all children in a single request by allowing tiles.json to point to a subset of a file for a tile's content similiar to glTF buffer and bufferView.
instance
field, e.g., positions can be quantized relative to the bounding volume (see EXT_quantized_attributes). Rotation could also be optional (part of the batchTable) and default to Y up (glTF default) in a local frame for the instance's position. Rotation could use fewer fields. RTC. Delta encoding... SOA vs. AOS... Look into point cloud compression...instance.batchId
be omitted when header.batchTableLength === 0
. This will complicate the client, but save memory; however, the case it saves memory for is probably rare in practice.From #23:
batchTable
be renamed? Something like propertyTable
, metadataTable
, etc.batchTable
work more like glTF buffer/bufferView/accessor to avoid arrays of numbers?BooleanExpression
, NumberExpression
, and friendsCesium3DTileStyle
(and implicitly for Cesium3DTileStyleEngine
)styleEngine
last to constructors (and make it optional?)ColorRampExpression.computeEvenlySpacedIntervals
)JulianDate
datatype to support styling with date/time metadataColor
so why not here?), see #2 (comment)${foo[${memberName}]}
{
"show" : true,
"color" : [255, 255, 255],
"meta" : {
"description" : "Hello, ${FeatureName}"
}
}
var str = style.meta.description.evaluate(feature);
distance
czm_time
, czm_inShadow
, etc.interval
to optimize conditional
when used for intervalscolor : ramp(palette, distance(${thisFeature.location}, ${anotherFeature.location}))
show : (${thisFeature.height} > ${anotherBuilding.height})
Property
system, e.g., evaluate expressions as Property
or vice-versa.Cesium3DTileStyle
and friends for users writing their own styles.replaceVariables
in Expression.js
?Is it redundant with url
if each format defines its extension?
"content": {
"url": "2/0/0.b3dm",
"type": "b3dm",
We need to determine how 3D Tiles are going to support z-indexing. Obviously vector payloads are the biggest use case, but I'm pretty sure it would need to be handled at a higher level in the stack (instead of the payload level).
The 2 primary use cases I have in mind are:
See the originial notes for Vector Data.
Considering only polygons and no styling:
Header
------
magic // uchar[4], "vctr"
version // uint32, 1
byteLength // uint32, length, in bytes, of the entire tile. See #23
batchTableLength // uint32, length, in bytes, of the batch table. Can be zero.
Batch Table
-----------
// Same as Batched 3D Model. Optional.
Polygons
--------
polygonsLength // uint32, number of polygons in the tile
There are polygonsLength of these (each is variable length):
* batchId // uint32, index into batchTable, zero when Header.batchTableLength === 0
* minimumHeight // float, for shadow volume extrusion optimization
* maximumHeight // float, for shadow volume extrusion optimization
* positionsLength // uint32, number of vertex positions in this polygon
* x, y, z ... // doubles in WGS84 coordinates
* indicesLength // uint32, number of triangle indices
* i0, i1, i2, ... // uint16, every three indices form a triangle
This design assumes server-side triangulation and client-side subdivision and shadow volume extrusion. It includes metadata to optimize shadow volume rendering (which makes a huge difference).
Polygons with holes can be represented as multiple polygons (with or without the same batchId
) or as one polygon with disconnected triangles.
The geometry is well behaved: there are no degenerate triangles nor are the duplicate vertex positions.
Cesium should render these tiles with RTC instead of GPU RTE.
Easy Questions
batchId
is the first field here, but the last field in i3dm (#23). Which do we prefer?uint16
or uint32
? When using uint16
, a big polygon could be represented as several polygons with the same batchId
.minimumHeight
and maximumHeight
are for rendering optimization. Most likely, they should be a semantic in the Batch Table instead.minimumHeight
and maximumHeight
just need to be conservative. Is uint16
more appropriate?Less Easy Questions
Change all the examples in this repo and Cesium once the spec stabilizes.
CC #50.
Either a default style or set of styles (#2).
Or is this better served by the app and higher-level formats that combine the tileset and style?
This is probably the right thing to do since it is more precise.
Currently refine
is optional and defaults to "add"
(as opposed to "replace"
).
Instead, if it is omitted, should it inherit its parent's value recursively up the tree?
is there any location from which we can download the OSM model of New York dataset , or its batched file and tileset file togther ? i wanted to work with 3d tile , and use the OSM model of New York as my data source,however i could not find so far the b3dm file of NY and its tileset file online .
I want to create one 3-d tiles b3dm edit Tool.
who can give me the b3dm ascII file which content can't be ??? and I can't understand.
My requirements are below:
1 one complete fileb3dm ascII file in which all content can be read. please notice this webstie sample are not suitable;
2 I am ready for developing it in Java. I want to know how to generate one b3dm file from one gltf in detail?
Cesium's Node.js development server is using application/octet-stream
for now.
Related glTF discussion: KhronosGroup/glTF#412
CC BY 4.0 is probably fine. See Considerations for licensors and licensees.
However, it could be useful to have the same CLA as Cesium for when the community contributes spec fixes, new tile formats, etc.
For example, update here and elsewhere to be glTF 2.0, not glTF 1.0.
glTF 2.0 updates: KhronosGroup/glTF#605
Also consider if there are any other glTF extensions, like unsigned int indices, that we want to include.
When bounding volumes for 3D tiles has been finalized, update the tiles.json specification, examples and descriptions.
These are in at least the following places:
3D Tiles: Tiles.json
3D Tiles: External Tilesets
Example tiles.json
Tiles.json schema
The work on bounding volumes is detailed in Issue #10 Different bounding volumes.
From the spec:
Trees of trees. A content.type of "3dtile" is planned and will allow conversion tools to chunk up a tileset into any number of tiles.json files that reference each other.
The general spatial data structure in tileset.json does not allow for random access, e.g., "give me tile x,y at level z" because the tiling scheme is not fixed; instead the data structure needs to be searched top-down.
If random access is needed, we could allow a tileset to advertise itself as using a particular typing scheme, e.g.,
"tilingScheme" : "quadtree"
Currently, Cesium is storing all of the tile formats gzipped compressed. Should this be part of the core spec, e.g., a .b3dm
file is always gzipped compressed?
One concern is if problem-domain specific compression (mesh compression, point cloud compression, etc.) cancels out any benefit of gzip.
Perhaps we want the flexibility that some tile playloads will be gzipped and others will not so we just leave this out of the spec?
Notes on vector data
minimumHeight
and maximumHeight
?Selection of Cesium geometries:
Looking into getting buildings (and possibly other features), I started toying with the OSM2World project again. Now that OBJ2GLTF exists, it's easy to get OSM into Cesium.
For example: https://github.com/stirringhalo/osm2cesium
This takes OSM extracts and dumps them to obj, which is then converted to gltf, and georeferenced in Cesium based on the original obj
I've heard mention of a gltf to b3dm converter, does such a tool exist now or on the horizon? I'm looking to expand osm2cesium to handle larger areas with streaming.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.