-
-
Notifications
You must be signed in to change notification settings - Fork 182
/
quantized-mesh.hexpat
169 lines (130 loc) · 3.61 KB
/
quantized-mesh.hexpat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#pragma author applecuckoo
#pragma description Cesium quantized-mesh terrain
#pragma endian little
// based on https://github.com/CesiumGS/quantized-mesh
// potential improvements: figure out high water mark encoding for indices
import std.math;
import std.io;
u8 extensionCount;
extensionCount = 0; // NOTE: set this to the amount of extensions in your terrain.
// ZigZag decoder based on protobuf.hexpat by WerWolv
struct ZigZag16 {
u16 value;
} [[sealed, format("format_zigzag16")]];
fn format_zigzag16(ZigZag16 zigzag) {
return s16((s16(zigzag.value) << 1) ^ (s16(zigzag.value) >> 15));
};
struct QuantizedMeshHeader {
double CenterX;
double CenterY;
double CenterZ;
float MinimumHeight;
float MaximumHeight;
double BoundingSphereCenterX;
double BoundingSphereCenterY;
double BoundingSphereCenterZ;
double BoundingSphereRadius;
double HorizonOcclusionPointX;
double HorizonOcclusionPointY;
double HorizonOcclusionPointZ;
};
struct VertexData {
u32 vertexCount;
ZigZag16 u[vertexCount];
ZigZag16 v[vertexCount];
ZigZag16 height[vertexCount];
};
struct IndexData16 {
u32 triangleCount;
u16 indices[triangleCount * 3];
};
struct IndexData32 {
u32 triangleCount;
u32 indices[triangleCount * 3];
};
struct EdgeIndices16 {
u32 westVertexCount;
u16 westIndices[westVertexCount];
u32 southVertexCount;
u16 southIndices[southVertexCount];
u32 eastVertexCount;
u16 eastIndices[eastVertexCount];
u32 northVertexCount;
u16 northIndices[northVertexCount];
};
struct EdgeIndices32 {
u32 westVertexCount;
u32 westIndices[westVertexCount];
u32 southVertexCount;
u32 southIndices[southVertexCount];
u32 eastVertexCount;
u32 eastIndices[eastVertexCount];
u32 northVertexCount;
u32 northIndices[northVertexCount];
};
enum ExtensionTypes : u8 {
OctEncodedVertexNormals = 0x1,
WaterMask,
Metadata = 0x4,
};
// Oct16 decode based on https://github.com/loicgasser/quantized-mesh-tile/blob/master/quantized_mesh_tile/utils.py
fn signNotZero(float v) {
if (v < 0.0)
return -1.0;
else
return 1.0;
};
fn fromSnorm(u8 value) {
return float(std::math::clamp(value, 0.0, 255.0) / 255.0 * 2.0 - 1.0);
};
struct Oct16 {
u8 x;
u8 y;
}[[sealed, format("format_oct16")]];
fn format_oct16(Oct16 oct) {
float xOut;
float yOut;
float zOut;
xOut = fromSnorm(oct.x);
yOut = fromSnorm(oct.y);
zOut = 1.0 - (std::math::abs(xOut) + std::math::abs(yOut));
if (zOut < 0.0) {
float oldX;
oldX = xOut;
xOut = (1.0 - std::math::abs(yOut)) * signNotZero(oldX);
yOut = (1.0 - std::math::abs(oldX)) * signNotZero(yOut);
}
return std::format("{}, {}, {}", xOut, yOut, zOut);
};
struct OctEncodedVertexNormals {
Oct16 xy[parent.parent.vertdata.vertexCount];
};
struct WaterMask {
u8 mask[parent.extensionLength];
};
struct Metadata {
u32 jsonLength;
char json[jsonLength];
};
struct ExtensionHeader {
u8 extensionId;
u32 extensionLength;
match (extensionId) {
(ExtensionTypes::OctEncodedVertexNormals): OctEncodedVertexNormals octVertNormals;
(ExtensionTypes::WaterMask): WaterMask maskData;
(ExtensionTypes::Metadata): Metadata metadata;
}
};
struct QuantizedMesh {
QuantizedMeshHeader header;
VertexData vertdata;
if (vertdata.vertexCount > 65536) {
IndexData32 indexdata;
EdgeIndices32 edgeindices;
} else {
IndexData16 indexdata;
EdgeIndices16 edgeindices;
}
ExtensionHeader extensions[extensionCount];
};
QuantizedMesh mesh @ 0x00;