Hey everyone!
I have my data reader for quantized-mesh, but I'm getting weird values for vertex's height
For 0.0.0.terrain data I have (u,v,h):
========= VertexCount (208)
6143,3632,65530
3071,981,65529
0,1339,65534
0,1225,65528
10239,14293,65534
32767,1339,3
8191,6213,2
6143,947,8
4095,1198,8
2047,963,8
0,1213,15
According the documentation, height value should be between 0 and 32767, but I'm getting values higher than that (but not higher than 65534)
Is this right? Is the max value 65534 instead?
Thanks a lot!
Hi,
Heights are deltas from the previous height, and they’re zig-zag encoded. See the code to decode them in CesiumTerrainProvider:
https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Core/CesiumTerrainProvider.js#L350
Kevin
Hi Kevin and thanks for your response
I’m using deltas and zig-zag indeed.
Here is my code:
I don’t know what you mean by void assignments. The loop decodes u,v,h, and then stores them somewhere. Without those lines, the result of decoding would be thrown away.
If your code doesn’t have similar lines, that would explain why the buffer values you showed me originally appear to be the original encoded values.
Hi Jose,
Due to the delta encoding, you should be using int16_t, not uint_16. Some of these deltas are negative.
Alex
Alex, it makes totally sense. It seems to be the root problem
If I understood well, zig-zig produces a signed value from an unsigned input.
And since the output are the signed deltas, I have to accumulate them with the previous
After changing my code (see below), I get negative values for height. And the doc states the height value must be between 0 and 32767
Tile used: http://cesiumjs.org/stk-terrain/tilesets/world/tiles/0/0/0.terrain
Vertex count -> 208
-6 | 11
-7 | 1
-2 | 10
-8 | 11
-2 | 12
The weird thing is the decoded value for the first height is negative, and AFAIK it shouldn't
The code that produces that output is:
uint32_t vertexCount = *(uint32_t *)data;
data += sizeof(uint32_t);
printf("Vertex count -> %d", vertexCount);
uint16_t *horizontalCoords = (uint16_t *)data;
uint16_t *verticalCoords = (uint16_t *)data + (sizeof(uint16_t) * vertexCount);
uint16_t *heights = (uint16_t *)data + (sizeof(uint16_t) * vertexCount * 2);
int16_t u = 0; // horizontal value
int16_t v = 0; // vertical value
int16_t h = 0; // height value
for (int i = 0; i < vertexCount; ++i)
{
u += decodeZigZag(horizontalCoords[i]);
v += decodeZigZag(verticalCoords[i]);
h += decodeZigZag(heights[i]);
printf(" %d | %d", h, heights[i]);
}
decodeZigZag needs to return int16_t, too.
decodeZigZag needs to return int16_t, too.
You're right. I pasted a wrong version.
The good one is
static inline int16_t decodeZigZag(uint16_t encodedValue)
{
return (encodedValue >> 1) ^ (-(encodedValue & 1));
}
BTW, how can I run the JS decoding code to compare against my results?
Still not working then? I thought that would do it.
The easiest way to get the decoding code in Cesium to run is to run Cesium Viewer, then select STK World Terrain from the base layer picker in the top right corner.
Still not working then? I thought that would do it.
Not yet. The log is the same with the correct version of decodeZigZag
I also added some code to make sure the byte ordering is ok, but the height is still < 0. I can send the final code if it helps.
I'm wondering if I can interpolate the values to get an absolute height from the negative value. The final value would be less than header's MinimumHeight but it seems to be wrong according the documentation
The easiest way to get the decoding code in Cesium to run is to run Cesium Viewer, then select STK World Terrain from the base layer picker in the top right corner.
I tried and the Cesium Viewer is quite impressive! but the JS is minimized and I cannot debug that part. A command-line tool that logs the raw data would be quite useful
Hey!
I finally fixed the problem. It was a dumb pointer arithmetic error.
This:
uint16_t *verticalCoords = (uint16_t *)data + (sizeof(uint16_t) * vertexCount);
Should be:
uint16_t *verticalCoords = ((uint16_t *)data) + vertexCount;
I found the error comparing the values read by my code against the values read by JS code.
I wrote this tool for that, maybe it's useful for others:
https://github.com/jmnavarro/cesium-quantized-mesh-terrain-format-logger
Thanks!