melowntech / vts-tools

VTS tool suite.
BSD 2-Clause "Simplified" License
12 stars 3 forks source link

How to add new format to vts? #7

Open a180285 opened 3 years ago

a180285 commented 3 years ago

Hey, I want to convert new format to vts. Is there any docment for how to do this? Or how the data is store in VTS?

vaclavblazek commented 3 years ago

Hi, there's no document about the low-level data storage in VTS (yet). However, if you want to add new data, you may have a look at existing encoders (programs called like whatever2vts in this repository and in vts-libs/tools). NB: If you'd want to add a on-the fly conversion (like DEM -> VTS surface) you'd have to update vts-mapproxy; in this case the input data need preprocessing and the actual VTS data are not stored anywhere but created on the fly.

If you need to convert (static) hierarchical mesh into VTS surface (which is what majority of the tools in this repo do) is to map input meshes to VTS reference frame, cut it into individual tiles and then to build VTS tileset (which is the actual implementation behind VTS surface).

Each tile has:

There's also a tree of metatiles but it gets complicated.

You can inspect existing tileset via vts tool from this repo.

As a basis of your custom encoder you can use 3dtiles2vts: ( https://github.com/melowntech/vts-tools/blob/master/tools/src/tools/3dtiles2vts.cpp ) It does all the heavy lifting using a "temporary tileset encoder"; the only thing you need is to assign input meshes to parts of tile tree and cut it into indivudual trees. Everything else is handled by the common machinery.

vaclavblazek commented 3 years ago

NB: VTS is resolution-based so things that look alike shoud be at the same level od detail. Our common approach between mapping tile texture resolution (area of 3D mesh divided by texture mesh area in pixels, i.e. m/px) is:

NB: all measurement and cutting is done in the local space division SRS of VTS tile subtree. If used reference frame has multiple subtrees (melown2015 uses webmercator for the main part of the world and appropripate stereographic projections for the two polar caps). If input mesh falls into multiple subtrees the best matching subtree is used and if one mesh spans an area covered by more subtrees the individual parts of given mesh contribute to different subtrees of VTS reference frame. In melown2015 this can realistically happen only in the north parts of the world. In the earth-qsc reference frame (as well as in the mars-qsc) this can happen at more places since the world is mapped to a cube and split into 6 indivudual division/tile sutrees.

a180285 commented 3 years ago

@davion.shi@unity3d.com

a180285 commented 3 years ago

Hi, @vaclavblazek. Thanks very much for your kindly explaining.

We want to add normal FBX file to VTS for streaming. In past 2 weeks, We tried to covert FBX to 3dtiles or lodtree before inporting to VTS. As VTS already support 3dtiles and LODtree. But finally, we failed. (Of course there is no coordinate info in FBX file. We will think about how to add coordinate info too. But I think this should be easy if we already have a way to streaming FBX or OBJ files.)

Do you have any suggestion to streaming FBX or other 3D fomat models, bease on VTS stack. We want to streaming static mesh.

Or otherwise we have to write a encoder for VTS?

a180285 commented 3 years ago

BTW: We have some slpk test files. Is it the same to read slpk2vts.cpp. for the same popurse. Or it's better to read 3dtiles2vts.cpp? If so, do you know where is some 3dtiles file we can use for testing?

vaclavblazek commented 3 years ago

Writng your own VTS streaming would be too hard, tiles would have to be cut on the fly and even vts-mapproxy needs some preprocessing to do it for raster formats (DEM, orthophoto).

If it is static, convert it to VTS. You can go either the your data -> 3D Tiles/SLPK -> VTS way or you can write your own convertor. Using intermediate format would be easier. Or, your can use vef2vts if you have OBJ. Here's the VEF format spec.

However, be aware that any way you use you need to have the input in multiple leves of detail (LODs) available. There's no VTS tool that decimates meshes Also, all the VTS tools expect that the LODs follows (roughly) the power of two rule: e.q. if the original has resolution 1 cm/px then the first LOD should be (around) 2 cm/px, next one (aroun) 4/px cm etc.

We have provided a sample dataset for evaluation, interoperability testing and education purposes at https://cdn.melown.com/pub/example-datasets/benatky-nad-jizerou/ -- there are 3D Tiles, SLPK, VTS and VEF versions of the same dataset available here. Please, consult the LICENSE file for details. The 3D Tiles dataset online visualization is available at https://cdn.melown.com/pub/example-datasets/benatky-nad-jizerou/visualization/3dtiles/benatky-nad-jizerou.html .

vaclavblazek commented 3 years ago

Re SLPK vs 3D Tiles: 3D Tiles is an open format and actually it's an OGC standard. While SLPK is documented you have to use commercial SW (ArgGis Pro) or commercial web service (ArcGis Online) to display it (or use VTS, of course :) ).

I'd go with 3D Tiles.

a180285 commented 3 years ago

Thanks @vaclavblazek , The datasets are very very useful!

a180285 commented 3 years ago

Hi @vaclavblazek , after reading the VEF format spec. I didn't understand that the relation between VEF's lod and VTS's Level info.

For for database vef file. I find that VEF 's LOD start from 0, After converting to vts, the lowest level is 17 or 16. Does this mapping is fixed? If it's dynamic. How it computed.

vaclavblazek commented 3 years ago

Each window's LOD list starts with "original", i.e. the first entry in the lods array is the best mesh version available. Next entry in the same array is first level-of-detail, then the next level-of-detail etc.

When vef2vts encodes such dataset into a VTS tileset it takes each window's best mesh and its texture (from lod[0]), compute's resolutiion and finds best fitting place in the VTS tile tree, i.e. a LOD in VTS tree (*). Then, each consecutive mesh version (lod[1], lod[2], ...) is placed in the same order above each other, i.e. LOD-1, LOD-2, ...

Then, each mesh is converted to spatial division SRS (pseudomercator in melown2015 almost always), cut into tiles in planar grid at given LOD, converted to physical SRS and stored in the tileset.

The input LOD/VTS LOD assignment (for any dataset type, not only VEF) is computed only for original/best mesh, all other input LODs always map linearly above the original (the tree root 0-0-0 is at the top). As a side effect, this introduces the soft constraint that input dataset's quality drop between individual LODs should be around 0.5, if possible.

(*) Just FYI, it's a bit complicated, in the case of a complex reference frame (like melown2015) the best fitting place contains not only LOD but a reference frame subtree (marked by it's division space SRS) and it may happen that one input mesh can be split between multiple subtrees, e.g. a dataset in the Arctics could be split between the main pseudomercator subtree and the north polar cap subtree as well.

vaclavblazek commented 3 years ago

As a sidenote: VTS is visually oriented and the main driving factor behind visualizing data is resolution. Mesh geometry detail is irrelevant, the only important thing that tells VTS encoders where to map data and the VTS browser what to render is data (mesh) resolution. Mesh resolution is computed as sqrt(textureArea / meshArea), textureArea is in pixels^2, meshArea in m^2 in physical SRS.

a180285 commented 3 years ago

Thanks. Got it. And another thing I wondered is that. For your sample VEF files. I found that you already split / cut the vef files by regions.

I want to know the behavior is required or recommended. Because maybe I will try to put a whole city in single one obj file. In VEF format a single window. Is that OK for vef2vts to process. How do you think about the idea of put a city scale objects into a single obj file for vef2vts tool to cut?

vaclavblazek commented 3 years ago

You can have single window. No need to precut. Our own reconstruction software splits input into "reconstruction windows" so our output the format is suited to handle it.

However, if you put single city in one huge mesh the processing time may considerably increase since vef2vts parallelizes work per-window. Single window == single thread.