EMODnet Quantized Mesh Generator for Cesium
quantized_mesh.h
1 // Copyright (c) 2018 Coronis Computing S.L. (Spain)
2 // All rights reserved.
3 //
4 // This file is part of EMODnet Quantized Mesh Generator for Cesium.
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 //
19 // Author: Ricard Campos (ricardcd@gmail.com)
20 
21 #ifndef EMODNET_QMGC_QUANTIZED_MESH_H
22 #define EMODNET_QMGC_QUANTIZED_MESH_H
23 
24 
25 #include <string>
26 #include <vector>
27 #include "cgal/cgal_utils.h"
28 #include <ctb.hpp>
29 #include "misc_utils.h"
30 
36 
37 public:
38  // --- Various structs as described in the documentation ---
39  // (https://cesiumjs.org/data-and-assets/terrain/formats/quantized-mesh-1.0.html)
40  struct Header
41  {
42  // The center of the tile in Earth-centered Earth-Fixed coordinates
43  double CenterX;
44  double CenterY;
45  double CenterZ;
46 
47  // The minimum and maximum heights in the area covered by this tile.
48  // The minimum may be lower and the maximum may be higher than
49  // the height of any vertex in this tile in the case that the min/max vertex
50  // was removed during mesh simplification, but these are the appropriate
51  // values to use for analysis or visualization.
52  float MinimumHeight;
53  float MaximumHeight;
54 
55  // The tile’s bounding sphere. The X,Y,Z coordinates are again expressed
56  // in Earth-centered Fixed coordinates, and the radius is in meters.
61 
62  // The horizon occlusion point, expressed in the ellipsoid-scaled Earth-centered Fixed frame.
63  // If this point is below the horizon, the entire tile is below the horizon.
64  // See http://cesiumjs.org/2013/04/25/Horizon-culling/ for more information.
68  };
69 
70  struct VertexData
71  {
72  unsigned int vertexCount = 0;
73  std::vector<unsigned short> u;
74  std::vector<unsigned short> v;
75  std::vector<unsigned short> height;
76  };
77 
78  struct IndexData
79  {
80  unsigned int triangleCount ;
81  std::vector< unsigned int > indices ;
82  };
83 
84  struct EdgeIndices
85  {
86  unsigned int westVertexCount;
87  std::vector<unsigned int> westIndices;
88 
89  unsigned int southVertexCount;
90  std::vector<unsigned int> southIndices;
91 
92  unsigned int eastVertexCount;
93  std::vector<unsigned int> eastIndices;
94 
95  unsigned int northVertexCount;
96  std::vector<unsigned int> northIndices;
97  };
98 
100  {
101  std::vector<float> nx;
102  std::vector<float> ny;
103  std::vector<float> nz;
104  };
105 
106  struct WaterMask {
107  std::vector<unsigned char> mask ;
108  };
109 
110  enum ExtensionIds {OCT_VERTEX_NORMALS = 1, WATER_MASK = 2};
111 
112  // --- Functions ---
115  m_header = Header();
116  m_vertexData = VertexData();
117  m_indexData = IndexData();
118  m_edgeIndices = EdgeIndices();
119  m_vertexNormals = VertexNormals();
120  m_waterMask = WaterMask();
121  m_bytesPerIndex = 0;
122  }
123 
125  QuantizedMesh(const std::string &filePath) { readFile(filePath); }
126 
128  bool readFile(const std::string &filePath);
129 
131  bool writeFile(const std::string &filePath);
132 
134  void print();
135 
137  void printHeader();
138 
140  void setHeader(const Header& header) { m_header = header; }
141 
143  void setVertexData(const VertexData& vd) { m_vertexData = vd; }
144 
146  void setIndexData(const IndexData& id) { m_indexData = id; }
147 
149  void setEdgeIndices(const EdgeIndices& ei) { m_edgeIndices = ei; }
150 
152  void setVertexNormals(const VertexNormals& vn) { m_vertexNormals = vn; }
153 
155  Header getHeader() const { return m_header; }
156 
158  VertexData getVertexData() const { return m_vertexData; }
159 
161  IndexData getIndexData() const { return m_indexData; }
162 
164  VertexNormals getVertexNormals() const { return m_vertexNormals; }
165 
167  EdgeIndices getEdgeIndices() const { return m_edgeIndices; }
168 
169  // --- Constants ---
170  const unsigned short int TILE_SIZE = 65;
171  static const unsigned short MAX_VERTEX_DATA = 32767;
172 
173  // --- Convenience static functions ---
181  static unsigned short remapToVertexDataValue(const double& value, const double& minOr, const double& maxOr) {
182  double valueRemap = remap(value, minOr, maxOr, 0, MAX_VERTEX_DATA) ;
183  return static_cast<unsigned short>(valueRemap);
184  }
185 
186  static double remapFromVertexDataValue(const double& value, const double& minOr, const double& maxOr) {
187  return remap(value, 0, MAX_VERTEX_DATA, minOr, maxOr ) ;
188  }
189 
190 
191 
192 private:
193 
194  // --- Attributes ---
195  Header m_header ;
196  VertexData m_vertexData ;
197  IndexData m_indexData ;
198  EdgeIndices m_edgeIndices ;
199  int m_bytesPerIndex ; // Number of bytes used per index
200  VertexNormals m_vertexNormals ;
201  WaterMask m_waterMask ;
202 
203  // --- Functions ---
204 
205  // Decode a zig-zag encoded value
206  unsigned short zigZagDecode( const unsigned short &value ) {
207  return (value >> 1) ^ (-(value & 1)) ;
208  }
209 
211  unsigned short zigZagEncode( const short &value ) {
212  return (value << 1) ^ (value >> 31) ;
213  }
214 
216  void octEncode( const float xyz[3], unsigned char octxy[2] ) {
217  const float invL1Norm = (1.0f) / (fabs(xyz[0]) + fabs(xyz[1]) + fabs(xyz[2]));
218 
219  if (xyz[2] < 0.0f) {
220  octxy[0] = static_cast<unsigned char>((1.0f - float(fabs(xyz[1] * invL1Norm))) * sign(xyz[0]));
221  octxy[1] = static_cast<unsigned char>((1.0f - float(fabs(xyz[0] * invL1Norm))) * sign(xyz[1]));
222  } else {
223  octxy[0] = static_cast<unsigned char>(xyz[0] * invL1Norm);
224  octxy[1] = static_cast<unsigned char>(xyz[1] * invL1Norm);
225  }
226  }
227 
229  void octDecode( const unsigned char octxy[2], float xyz[3] ) {
230 
231  xyz[0] = uchar2float(octxy[0]);
232  xyz[1] = uchar2float(octxy[1]);
233  xyz[2] = 1.0f - (fabs(xyz[0]) + fabs(xyz[1]));
234 
235  if (xyz[2] < 0.0f) {
236  float oldX = xyz[0];
237  xyz[0] = ((1.0f) - fabs(xyz[1])) * sign(oldX);
238  xyz[1] = ((1.0f) - fabs(oldX)) * sign(xyz[1]);
239  }
240  }
241 
243  inline float sign(float v) {
244  return (v < 0.0f) ? -1.0f : 1.0f;
245  }
246 
248  float uchar2float( unsigned char u ) {
249  return float(clamp(int(8) * (1.0f / float((uint64_t(1) << 7) - 1)), -1.0f, 1.0f));
250  }
251 
253  unsigned char float2uchar( float f ) {
254  return (unsigned char)round(clamp(f, -1.0f, 1.0f) * ((uint64_t(1) << 7) - 1));
255  }
256 
258  inline float clamp(float val, float low, float hi) {
259  if (val <= low) {
260  return low;
261  } else if (val >= hi) {
262  return hi;
263  } else {
264  return val;
265  }
266  }
267 
268  // Round a value
269  inline float round(float f) {
270  return floor(f + 0.5f);
271  }
272 
273 };
274 
275 
276 #endif //EMODNET_QMGC_QUANTIZED_MESH_H
double HorizonOcclusionPointZ
Z coordinate of the horizon occlusion point of the tile.
Definition: quantized_mesh.h:67
double HorizonOcclusionPointX
X coordinate of the horizon occlusion point of the tile.
Definition: quantized_mesh.h:65
void setHeader(const Header &header)
Set the header part of the quantized mesh structure.
Definition: quantized_mesh.h:140
std::vector< float > nz
Z coordinate of the normal.
Definition: quantized_mesh.h:103
std::vector< unsigned short > height
height coordinate of the vertex
Definition: quantized_mesh.h:75
EdgeIndices getEdgeIndices() const
Get the edge indices of the quantized mesh structure.
Definition: quantized_mesh.h:167
IndexData getIndexData() const
Get the index data of the quantized mesh structure.
Definition: quantized_mesh.h:161
double BoundingSphereCenterZ
Center of the bounding sphere of the tile in Earth-centered Earth-Fixed, coordinate Z...
Definition: quantized_mesh.h:59
void setIndexData(const IndexData &id)
Set the index data part of the quantized mesh structure.
Definition: quantized_mesh.h:146
float MinimumHeight
Minimum height possible for this tile.
Definition: quantized_mesh.h:52
double BoundingSphereCenterY
Center of the bounding sphere of the tile in Earth-centered Earth-Fixed, coordinate Y...
Definition: quantized_mesh.h:58
QuantizedMesh()
Constructor.
Definition: quantized_mesh.h:114
bool readFile(const std::string &filePath)
Read the tile from a file.
Definition: quantized_mesh.cpp:36
Header getHeader() const
Get the header part of the quantized mesh structure.
Definition: quantized_mesh.h:155
std::vector< unsigned short > u
U coordinate of the vertex.
Definition: quantized_mesh.h:73
double CenterZ
Center of the tile in Earth-centered Earth-Fixed, coordinate Z.
Definition: quantized_mesh.h:45
std::vector< unsigned int > westIndices
The indices of the vertices falling in the western border of the tile.
Definition: quantized_mesh.h:87
static unsigned short remapToVertexDataValue(const double &value, const double &minOr, const double &maxOr)
Remap a value to be between 0 and 32767.
Definition: quantized_mesh.h:181
Definition: quantized_mesh.h:84
void printHeader()
Show the contents of the header of the tile on screen.
Definition: quantized_mesh.cpp:482
double CenterY
Center of the tile in Earth-centered Earth-Fixed, coordinate Y.
Definition: quantized_mesh.h:44
std::vector< unsigned int > southIndices
The indices of the vertices falling in the southern border of the tile.
Definition: quantized_mesh.h:90
std::vector< float > ny
Y coordinate of the normal.
Definition: quantized_mesh.h:102
void setVertexData(const VertexData &vd)
Set the vertex data part of the quantized mesh structure.
Definition: quantized_mesh.h:143
unsigned int northVertexCount
Number of vertices in the northern border of the tile.
Definition: quantized_mesh.h:95
Definition: quantized_mesh.h:70
VertexData getVertexData() const
Get the vertex data part of the quantized mesh structure.
Definition: quantized_mesh.h:158
unsigned int eastVertexCount
Number of vertices in the eastern border of the tile.
Definition: quantized_mesh.h:92
Contains all the data of a Quantized-mesh.
Definition: quantized_mesh.h:35
double HorizonOcclusionPointY
Y coordinate of the horizon occlusion point of the tile.
Definition: quantized_mesh.h:66
std::vector< unsigned int > eastIndices
The indices of the vertices falling in the eastern border of the tile.
Definition: quantized_mesh.h:93
Definition: quantized_mesh.h:40
Definition: quantized_mesh.h:99
void setVertexNormals(const VertexNormals &vn)
Set the vertices normal part of the quantized mesh structure.
Definition: quantized_mesh.h:152
double CenterX
Center of the tile in Earth-centered Earth-Fixed, coordinate X.
Definition: quantized_mesh.h:43
void print()
Show the contents of the tile on screen.
Definition: quantized_mesh.cpp:383
bool writeFile(const std::string &filePath)
Write the tile to a file.
Definition: quantized_mesh.cpp:215
std::vector< unsigned short > v
v coordinate of the vertex
Definition: quantized_mesh.h:74
VertexNormals getVertexNormals() const
Get the vertex normals of the quantized mesh structure.
Definition: quantized_mesh.h:164
Definition: quantized_mesh.h:106
Set of miscellaneous functions extending the functionality of the CGAL library.
unsigned int southVertexCount
Number of vertices in the southern border of the tile.
Definition: quantized_mesh.h:89
float MaximumHeight
Maximum height possible for this tile.
Definition: quantized_mesh.h:53
void setEdgeIndices(const EdgeIndices &ei)
Set the edge indices data part of the quantized mesh structure.
Definition: quantized_mesh.h:149
std::vector< unsigned int > indices
Indices of the triangles in the tile, size triangleCount*3. While they can be ints or shorts...
Definition: quantized_mesh.h:81
unsigned int westVertexCount
Number of vertices in the western border of the tile.
Definition: quantized_mesh.h:86
Definition: quantized_mesh.h:78
unsigned int triangleCount
Number of triangles in the tile.
Definition: quantized_mesh.h:80
std::vector< float > nx
X coordinate of the normal.
Definition: quantized_mesh.h:101
double BoundingSphereCenterX
Center of the bounding sphere of the tile in Earth-centered Earth-Fixed, coordinate X...
Definition: quantized_mesh.h:57
double BoundingSphereRadius
Radius of the bounding sphere of the tile in meters.
Definition: quantized_mesh.h:60
QuantizedMesh(const std::string &filePath)
Constructor from file.
Definition: quantized_mesh.h:125
std::vector< unsigned int > northIndices
The indices of the vertices falling in the northern border of the tile.
Definition: quantized_mesh.h:96
std::vector< unsigned char > mask
Water mask. Can be either a single value or 256x256.
Definition: quantized_mesh.h:107