GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
gltf.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef GLVIS_GLTF_HPP
13 #define GLVIS_GLTF_HPP
14 
15 #include <string>
16 #include <vector>
17 #include <array>
18 #include <tuple>
19 #include <fstream>
20 #include <limits>
21 #include <memory>
22 
23 
25 {
26 public:
27  typedef std::array<float,2> vec2f;
28  typedef std::array<float,3> vec3f;
29  typedef std::array<float,4> color4f;
30  typedef std::vector<float> vecnf;
31 
32 protected:
33  template <typename T>
34  struct node_type
35  {
36  bool valid;
37  std::string key;
38  T value;
39  };
40 
48 
50  {
51  node_string uri = { false, "uri", "" };
52  node_unsigned byteLength = { false, "byteLength", 0 };
53 
54  std::unique_ptr<std::ofstream> file;
55  };
57  {
58  node_unsigned buffer = { false, "buffer", 0 };
59  node_unsigned byteOffset = { false, "byteOffset", 0 };
60  node_unsigned byteLength = { false, "byteLength", 0 };
61  node_unsigned byteStride = { false, "byteStride", 0};
62  node_unsigned target = { false, "target", 0 };
63  };
65  {
66  node_unsigned bufferView = { false, "bufferView", 0 };
67  node_unsigned byteOffset = { false, "byteOffset", 0 };
68  node_unsigned componentType = { false, "componentType", 0 };
69  node_unsigned count = { false, "count", 0 };
70  node_string type = { false, "type", "" };
71  node_vecnf min = { false, "min", {} };
72  node_vecnf max = { false, "max", {} };
73  node_bool normalized = { false, "normalized", false };
74  };
75  struct struct_image
76  {
77  node_string uri = { false, "uri", "" };
78  node_string name = { false, "name", "" };
79  };
81  {
82  node_unsigned magFilter = { false, "magFilter", 0 };
83  node_unsigned minFilter = { false, "minFilter", 0 };
84  node_unsigned wrapS = { false, "wrapS", 0 };
85  node_unsigned wrapT = { false, "wrapT", 0 };
86  };
88  {
89  node_unsigned sampler = { false, "sampler", 0 };
90  node_unsigned source = { false, "source", 0 };
91  };
93  {
94  node_unsigned index = { false, "index", 0 };
95  node_unsigned texCoord = { false, "texCoord", 0 };
96  };
98  {
100  { false, "baseColorFactor", {{0.f, 0.f, 0.f, 0.f}} };
102  { false, "baseColorTexture", {} };
103  node_float metallicFactor = { false, "metallicFactor", 0.f };
104  node_float roughnessFactor = { false, "roughnessFactor", 0.f };
105  };
107  {
109  { false, "pbrMetallicRoughness", {} };
110  node_bool doubleSided = { false, "doubleSided", false };
111  node_string name = { false, "name", "" };
112  };
114  {
115  node_unsigned POSITION = { false, "POSITION", 0 };
116  node_unsigned NORMAL = { false, "NORMAL", 0 };
117  node_unsigned TEXCOORD_0 = { false, "TEXCOORD_0", 0 };
118  node_unsigned COLOR_0 = { false, "COLOR_0", 0 };
119 
120  };
122  {
123  node_type<struct_attributes> attributes = { false, "attributes", {} };
124  node_unsigned indices = { false, "indices", 0 };
125  node_unsigned material = { false, "material", 0 };
126  node_unsigned mode = { false, "mode", 0 };
127  };
128  struct struct_mesh
129  {
130  std::vector<struct_primitive> primitives;
131  node_string name = { false, "name", "" };
132  };
133  struct struct_node
134  {
135  node_unsigned mesh = { false, "mesh", 0 };
136  node_vec3f scale = { false, "scale", {{0.f, 0.f, 0.f}} };
137  node_vec3f translation = { false, "translation", {{0.f, 0.f, 0.f}} };
138  node_string name = { false, "name", "" };
139  };
140 
141  // begin: printing functions
142  static const char *sep(size_t i) { return (i==0) ? "" : ","; }
143  template <typename T>
144  static void print_node(std::ostream &out,
145  int &pfx_counter,
146  const std::string &pfx,
147  const node_type<T> &n)
148  {
149  if (n.valid)
150  {
151  out << sep(pfx_counter++) << pfx << '"' << n.key << "\" : ";
152  print(out, n.value);
153  }
154  }
155 
156  static void print(std::ostream &out, const bool &v) { out << v; }
157  static void print(std::ostream &out, const unsigned &v) { out << v; }
158  static void print(std::ostream &out, const float &v) { out << v; }
159  static void print(std::ostream &out, const std::string &v)
160  { out << '"' << v << '"'; }
161  template <typename T, size_t s>
162  static void print(std::ostream &out, const std::array<T,s> &v)
163  {
164  out << '[';
165  for (size_t i = 0; i != s; ++i) { out << sep(i) << ' ' << v[i]; }
166  out << " ]";
167  }
168  template <typename T>
169  static void print(std::ostream &out, const std::vector<T> &v)
170  {
171  out << '[';
172  for (size_t i = 0; i != v.size(); ++i) { out << sep(i) << ' ' << v[i]; }
173  out << " ]";
174  }
175  static void print(std::ostream &out, const struct_attributes &a)
176  {
177  out << '{';
178  int pos = 0;
179  print_node(out, pos, "\n ", a.POSITION);
180  print_node(out, pos, "\n ", a.NORMAL);
181  print_node(out, pos, "\n ", a.TEXCOORD_0);
182  print_node(out, pos, "\n ", a.COLOR_0);
183  out << "\n }";
184  }
185  static void print(std::ostream &out, const struct_texture_info &ti)
186  {
187  out << '{';
188  int pos = 0;
189  print_node(out, pos, "\n ", ti.index);
190  print_node(out, pos, "\n ", ti.texCoord);
191  out << "\n }";
192  }
193  static void print(std::ostream &out, const struct_pbrMetallicRoughness &pbr)
194  {
195  out << '{';
196  int pos = 0;
197  print_node(out, pos, "\n ", pbr.baseColorFactor);
198  print_node(out, pos, "\n ", pbr.baseColorTexture);
199  print_node(out, pos, "\n ", pbr.metallicFactor);
200  print_node(out, pos, "\n ", pbr.roughnessFactor);
201  out << "\n }";
202  }
203  // end: printing functions
204 
205  const std::string file_prefix;
206 
207  std::vector<struct_buffer> buffers;
208  std::vector<struct_buffer_view> buffer_views;
209  std::vector<struct_accessor> accessors;
210  std::vector<struct_image> images;
211  std::vector<struct_sampler> samplers;
212  std::vector<struct_texture> textures;
213  std::vector<struct_material> materials;
214  std::vector<struct_mesh> meshes;
215  std::vector<struct_node> nodes;
216 
217 public:
218  static constexpr unsigned INVALID_ID = std::numeric_limits<unsigned>::max();
219  typedef struct { unsigned id; } buffer_id;
220  typedef struct { unsigned id; } buffer_view_id;
221  typedef struct { unsigned id; } accessor_id;
222  typedef struct { unsigned id; } image_id;
223  typedef struct { unsigned id; } sampler_id;
224  typedef struct { unsigned id; } texture_id;
225  typedef struct { unsigned id; } material_id;
226  typedef struct { unsigned id; } mesh_id;
227  typedef struct { unsigned id; } node_id;
228 
229  // buffer view option
230  enum struct target_type
231  {
232  ARRAY_BUFFER = 34962,
233  ELEMENT_ARRAY_BUFFER = 34963
234  };
235 
236  // accessor option
237  enum struct component_type
238  {
239  BYTE = 5120,
240  UNSIGNED_BYTE = 5121,
241  SHORT = 5122,
242  UNSIGNED_SHORT = 5123,
243  UNSIGNED_INT = 5125,
244  FLOAT = 5126
245  };
246  // accessor option
247  enum struct tensor_type
248  {
249  SCALAR = 0, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4
250  };
251  // string constants corresponding to the tensor_type constants
252  static const char *tensorTypes[];
253 
254  // sampler option: magnification filter
255  enum struct mag_filter { NEAREST = 9728, LINEAR = 9729 };
256  // sampler option: minification filter
257  enum struct min_filter
258  {
259  NEAREST = 9728, LINEAR = 9729, NEAREST_MIPMAP_NEAREST = 9984,
261  LINEAR_MIPMAP_LINEAR = 9987
262  };
263  // sampler option: S/T (or U/V) wrapping mode
264  enum struct wrap_type
265  {
266  CLAMP_TO_EDGE = 33071, MIRRORED_REPEAT = 33648, REPEAT = 10497
267  };
268 
270  {
271  bool haveTexture; // if true, baseColorTexture must be defined
276  };
277 
278 
279  glTF_Builder(const std::string &filePrefix)
280  : file_prefix(filePrefix)
281  { }
282 
283  buffer_id addBuffer(const std::string &bufferName);
284 
285  buffer_view_id addBufferView(buffer_id buffer,
286  const void *data,
287  size_t byteLength,
288  size_t byteStride,
289  size_t byteAlign,
290  target_type target);
291 
292  // can be called after the call to addBufferView() that created the given
293  // bufferView but only before the next call to addBufferView()
294  void appendToBufferView(buffer_view_id bufferView,
295  const void *data,
296  size_t byteLength);
297 
298  // count must be >= 1
299  accessor_id addAccessor(buffer_view_id bufferView,
300  size_t byteOffset,
301  component_type componentType,
302  size_t count,
303  tensor_type tensorType);
304 
305  // count must be >= 1
306  accessor_id addAccessorVec2f(buffer_view_id bufferView,
307  size_t byteOffset,
308  size_t count,
309  vec2f min,
310  vec2f max);
311 
312  // count must be >= 1
313  accessor_id addAccessorVec3f(buffer_view_id bufferView,
314  size_t byteOffset,
315  size_t count,
316  vec3f min,
317  vec3f max);
318 
319  image_id addImage(const std::string &imageName,
320  int width,
321  int height,
322  const color4f *pixels);
323 
324  sampler_id addSampler(mag_filter magFilter = mag_filter::NEAREST,
325  min_filter minFilter = min_filter::NEAREST,
328 
329  texture_id addTexture(sampler_id sampler, image_id source);
330 
331  material_id addMaterial(const std::string &materialName,
332  const pbr_matallic_roughness &pbrMetallicRoughness,
333  bool doubleSided = false);
334 
335  mesh_id addMesh(const std::string &meshName);
336 
337  void addMeshTriangles(mesh_id mesh,
338  accessor_id vertexPositions,
339  accessor_id vertexNormals,
340  accessor_id vertexTexCoords0,
341  accessor_id vertexIndices,
342  material_id material);
343 
344  void addMeshLines(mesh_id mesh,
345  accessor_id vertexPositions,
346  accessor_id vertexTexcoords0,
347  accessor_id vertexColors0,
348  material_id material);
349 
350  node_id addNode(const std::string &nodeName);
351 
352  void addNodeMesh(node_id node, mesh_id mesh);
353 
354  void addNodeScale(node_id node, vec3f scale);
355 
356  void addNodeTranslation(node_id node, vec3f translation);
357 
358  void getMaterialPBRMR(material_id material,
359  pbr_matallic_roughness &pbr_mr_copy);
360 
361  int writeFile();
362 };
363 
364 #endif // GLVIS_GLTF_HPP
node_unsigned componentType
Definition: gltf.hpp:68
node_type< std::string > node_string
Definition: gltf.hpp:44
static void print_node(std::ostream &out, int &pfx_counter, const std::string &pfx, const node_type< T > &n)
Definition: gltf.hpp:144
material_id addMaterial(const std::string &materialName, const pbr_matallic_roughness &pbrMetallicRoughness, bool doubleSided=false)
Definition: gltf.cpp:276
std::vector< struct_buffer > buffers
Definition: gltf.hpp:207
void addNodeScale(node_id node, vec3f scale)
Definition: gltf.cpp:441
node_type< unsigned > node_unsigned
Definition: gltf.hpp:42
node_unsigned minFilter
Definition: gltf.hpp:83
accessor_id addAccessorVec3f(buffer_view_id bufferView, size_t byteOffset, size_t count, vec3f min, vec3f max)
Definition: gltf.cpp:165
buffer_view_id addBufferView(buffer_id buffer, const void *data, size_t byteLength, size_t byteStride, size_t byteAlign, target_type target)
Definition: gltf.cpp:38
std::string key
Definition: gltf.hpp:37
sampler_id addSampler(mag_filter magFilter=mag_filter::NEAREST, min_filter minFilter=min_filter::NEAREST, wrap_type wrapS=wrap_type::CLAMP_TO_EDGE, wrap_type wrapT=wrap_type::CLAMP_TO_EDGE)
Definition: gltf.cpp:232
std::vector< float > vecnf
Definition: gltf.hpp:30
node_unsigned bufferView
Definition: gltf.hpp:66
node_vec3f translation
Definition: gltf.hpp:137
node_type< bool > node_bool
Definition: gltf.hpp:41
std::vector< struct_material > materials
Definition: gltf.hpp:213
glTF_Builder(const std::string &filePrefix)
Definition: gltf.hpp:279
void appendToBufferView(buffer_view_id bufferView, const void *data, size_t byteLength)
Definition: gltf.cpp:81
void addMeshLines(mesh_id mesh, accessor_id vertexPositions, accessor_id vertexTexcoords0, accessor_id vertexColors0, material_id material)
Definition: gltf.cpp:379
node_unsigned source
Definition: gltf.hpp:90
void addNodeTranslation(node_id node, vec3f translation)
Definition: gltf.cpp:449
static void print(std::ostream &out, const struct_pbrMetallicRoughness &pbr)
Definition: gltf.hpp:193
void addMeshTriangles(mesh_id mesh, accessor_id vertexPositions, accessor_id vertexNormals, accessor_id vertexTexCoords0, accessor_id vertexIndices, material_id material)
Definition: gltf.cpp:333
buffer_id addBuffer(const std::string &bufferName)
Definition: gltf.cpp:24
std::array< float, 3 > vec3f
Definition: gltf.hpp:28
std::vector< struct_mesh > meshes
Definition: gltf.hpp:214
node_type< struct_pbrMetallicRoughness > pbrMetallicRoughness
Definition: gltf.hpp:108
static void print(std::ostream &out, const std::vector< T > &v)
Definition: gltf.hpp:169
node_type< float > node_float
Definition: gltf.hpp:43
texture_id addTexture(sampler_id sampler, image_id source)
Definition: gltf.cpp:256
const std::string file_prefix
Definition: gltf.hpp:205
static const char * sep(size_t i)
Definition: gltf.hpp:142
node_unsigned wrapS
Definition: gltf.hpp:84
node_unsigned wrapT
Definition: gltf.hpp:85
node_unsigned byteLength
Definition: gltf.hpp:52
static void print(std::ostream &out, const unsigned &v)
Definition: gltf.hpp:157
node_unsigned magFilter
Definition: gltf.hpp:82
std::vector< struct_node > nodes
Definition: gltf.hpp:215
mesh_id addMesh(const std::string &meshName)
Definition: gltf.cpp:322
static void print(std::ostream &out, const struct_texture_info &ti)
Definition: gltf.hpp:185
std::vector< struct_image > images
Definition: gltf.hpp:210
static void print(std::ostream &out, const float &v)
Definition: gltf.hpp:158
std::vector< struct_accessor > accessors
Definition: gltf.hpp:209
node_id addNode(const std::string &nodeName)
Definition: gltf.cpp:422
static void print(std::ostream &out, const bool &v)
Definition: gltf.hpp:156
image_id addImage(const std::string &imageName, int width, int height, const color4f *pixels)
Definition: gltf.cpp:190
node_unsigned mesh
Definition: gltf.hpp:135
accessor_id addAccessor(buffer_view_id bufferView, size_t byteOffset, component_type componentType, size_t count, tensor_type tensorType)
Definition: gltf.cpp:97
node_type< struct_texture_info > baseColorTexture
Definition: gltf.hpp:101
int writeFile()
Definition: gltf.cpp:472
std::array< float, 4 > color4f
Definition: gltf.hpp:29
void getMaterialPBRMR(material_id material, pbr_matallic_roughness &pbr_mr_copy)
Definition: gltf.cpp:457
static constexpr unsigned INVALID_ID
Definition: gltf.hpp:218
void addNodeMesh(node_id node, mesh_id mesh)
Definition: gltf.cpp:433
static void print(std::ostream &out, const std::array< T, s > &v)
Definition: gltf.hpp:162
node_type< struct_attributes > attributes
Definition: gltf.hpp:123
std::unique_ptr< std::ofstream > file
Definition: gltf.hpp:54
node_unsigned sampler
Definition: gltf.hpp:89
node_type< vecnf > node_vecnf
Definition: gltf.hpp:47
std::array< float, 2 > vec2f
Definition: gltf.hpp:27
node_unsigned byteOffset
Definition: gltf.hpp:67
std::vector< struct_buffer_view > buffer_views
Definition: gltf.hpp:208
static const char * tensorTypes[]
Definition: gltf.hpp:252
node_type< color4f > node_color4f
Definition: gltf.hpp:46
accessor_id addAccessorVec2f(buffer_view_id bufferView, size_t byteOffset, size_t count, vec2f min, vec2f max)
Definition: gltf.cpp:140
std::vector< struct_primitive > primitives
Definition: gltf.hpp:130
std::vector< struct_sampler > samplers
Definition: gltf.hpp:211
static void print(std::ostream &out, const std::string &v)
Definition: gltf.hpp:159
std::vector< struct_texture > textures
Definition: gltf.hpp:212
node_type< vec3f > node_vec3f
Definition: gltf.hpp:45
static void print(std::ostream &out, const struct_attributes &a)
Definition: gltf.hpp:175