Fermat
MeshStorage.h
1 /*
2  * Fermat
3  *
4  * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the NVIDIA CORPORATION nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include <MeshException.h>
32 #include <MeshView.h>
33 #include <texture_reference.h>
34 #include <buffers.h>
35 #include <string>
36 #include <map>
37 
38 class MeshGroup;
39 class MeshMaterialParams;
40 
44 class SUTILCLASSAPI MeshStorage
45 {
46 public:
47 #if 0
48  static const uint32 VERTEX_TRIANGLE_SIZE = 4;
49  static const uint32 NORMAL_TRIANGLE_SIZE = 3;
50  static const uint32 TEXTURE_TRIANGLE_SIZE = 3;
51  static const uint32 LIGHTMAP_TRIANGLE_SIZE = 3;
52 
53  typedef int4 vertex_triangle;
54  typedef int3 normal_triangle;
55  typedef int3 texture_triangle;
56  typedef int3 lightmap_triangle;
57 
58  static normal_triangle make_normal_triangle(const int32 x, const int32 y, const int32 z) { return make_int3(x,y,z); }
59  static texture_triangle make_texture_triangle(const int32 x, const int32 y, const int32 z) { return make_int3(x,y,z); }
60  static lightmap_triangle make_lightmap_triangle(const int32 x, const int32 y, const int32 z) { return make_int3(x,y,z); }
61 #else
62  static const uint32 VERTEX_TRIANGLE_SIZE = MeshView::VERTEX_TRIANGLE_SIZE;
63  static const uint32 NORMAL_TRIANGLE_SIZE = MeshView::NORMAL_TRIANGLE_SIZE;
64  static const uint32 TEXTURE_TRIANGLE_SIZE = MeshView::TEXTURE_TRIANGLE_SIZE;
65  static const uint32 LIGHTMAP_TRIANGLE_SIZE = MeshView::LIGHTMAP_TRIANGLE_SIZE;
66 
67  typedef MeshView::vertex_triangle vertex_triangle;
68  typedef MeshView::normal_triangle normal_triangle;
69  typedef MeshView::texture_triangle texture_triangle;
70  typedef MeshView::lightmap_triangle lightmap_triangle;
71 
72  static normal_triangle make_normal_triangle(const int32 x, const int32 y, const int32 z) { return make_int4(x,y,z,0); }
73  static texture_triangle make_texture_triangle(const int32 x, const int32 y, const int32 z) { return make_int4(x,y,z,0); }
74  static lightmap_triangle make_lightmap_triangle(const int32 x, const int32 y, const int32 z) { return make_int4(x,y,z,0); }
75 #endif
76 
77  SUTILAPI MeshStorage() :
78  m_num_vertices(0),
79  m_num_normals(0),
80  m_num_texture_coordinates(0),
81  m_num_lightmap_coordinates(0),
82  m_num_triangles(0),
83  m_num_groups(0),
84  m_vertex_stride(sizeof(MeshView::vertex_type) / 4u),
85  m_normal_stride(sizeof(MeshView::normal_type) / 4u),
86  m_texture_stride(sizeof(MeshView::texture_coord_type) / 4u) {}
87 
88  void alloc(
89  const int num_triangles,
90  const int num_vertices,
91  const int num_normals,
92  const int num_texture_coordinates,
93  const int num_groups)
94  {
95  m_num_vertices = num_vertices;
96  m_num_normals = num_normals;
97  m_num_texture_coordinates = num_texture_coordinates;
98  m_num_triangles = num_triangles;
99  m_num_groups = num_groups;
100 
101  m_vertex_stride = sizeof(MeshView::vertex_type) / 4u;
102  m_normal_stride = sizeof(MeshView::normal_type) / 4u;
103  m_texture_stride = sizeof(MeshView::texture_coord_type) / 4u;
104 
105  // alloc per-triangle indices
106  m_vertex_indices.alloc(4 * num_triangles);
107  if (num_normals)
108  {
109  m_normal_indices.alloc(NORMAL_TRIANGLE_SIZE * num_triangles);
110  m_normal_indices.clear(0); // initialize to 0
111  m_normal_indices_comp.alloc(NORMAL_TRIANGLE_SIZE * num_triangles);
112  }
113  if (num_texture_coordinates)
114  {
115  m_texture_indices.alloc(TEXTURE_TRIANGLE_SIZE * num_triangles);
116  m_texture_indices.clear(0); // initialize to 0
117 
118  m_texture_indices_comp.alloc(TEXTURE_TRIANGLE_SIZE * num_triangles);
119  }
120 
121  m_material_indices.alloc(num_triangles);
122  m_material_indices.clear(0xFF); // initialize to undefined|-1
123 
124  m_group_offsets.alloc(num_groups + 1);
125  m_group_names.resize(num_groups);
126 
127  // alloc vertex data
128  m_vertex_data.alloc(m_vertex_stride * num_vertices);
129  m_normal_data.alloc(m_normal_stride * num_normals);
130  m_normal_data_comp.alloc(num_normals);
131  m_texture_data.alloc(m_texture_stride * num_texture_coordinates);
132  }
133 
134  void alloc_lightmap(
135  const int num_lightmap_coordinates)
136  {
137  if (num_lightmap_coordinates)
138  {
139  m_num_lightmap_coordinates = num_lightmap_coordinates;
140  m_lightmap_indices.alloc(LIGHTMAP_TRIANGLE_SIZE * m_num_triangles);
141  m_lightmap_indices_comp.alloc(TEXTURE_TRIANGLE_SIZE * m_num_triangles);
142  m_lightmap_data.alloc(m_texture_stride * num_lightmap_coordinates);
143  }
144  }
145 
146  void compress_normals();
147  void compress_tex();
148 
149  SUTILAPI MeshMaterial* alloc_materials(const size_t n) { m_materials.resize(n); m_material_name_offsets.resize(n); return m_materials.ptr(); }
150  SUTILAPI char* alloc_material_names(const size_t n_chars) { m_material_names.resize(n_chars); return m_material_names.ptr(); }
151 
152  SUTILAPI int getNumVertices() const { return m_num_vertices; }
153  SUTILAPI int getNumNormals() const { return m_num_normals; }
154  SUTILAPI int getNumTextureCoordinates() const { return m_num_texture_coordinates; }
155  SUTILAPI int getNumTriangles() const { return m_num_triangles; }
156  SUTILAPI int getNumGroups() const { return m_num_groups; }
157  SUTILAPI int getNumMaterials() const { return (int)m_materials.count(); }
158  SUTILAPI int getNumTextures() const { return (int)m_textures.size(); }
159 
160  SUTILAPI int getVertexStride() const { return m_vertex_stride; }
161  SUTILAPI int getNormalStride() const { return m_normal_stride; }
162  SUTILAPI int getTextureCoordinateStride() const { return m_texture_stride; }
163 
164  SUTILAPI int* getVertexIndices() { return m_vertex_indices.ptr(); }
165  SUTILAPI const int* getVertexIndices() const { return m_vertex_indices.ptr(); }
166  SUTILAPI int* getNormalIndices() { return m_normal_indices.ptr(); }
167  SUTILAPI const int* getNormalIndices() const { return m_normal_indices.ptr(); }
168  SUTILAPI int* getMaterialIndices() { return m_material_indices.ptr(); }
169  SUTILAPI const int* getMaterialIndices() const { return m_material_indices.ptr(); }
170  SUTILAPI int* getTextureCoordinateIndices() { return m_texture_indices.ptr(); }
171  SUTILAPI const int* getTextureCoordinateIndices() const { return m_texture_indices.ptr(); }
172  SUTILAPI int* getLightmapIndices() { return m_lightmap_indices.ptr(); }
173  SUTILAPI const int* getLightmapIndices() const { return m_lightmap_indices.ptr(); }
174  SUTILAPI int* getGroupOffsets() { return m_group_offsets.ptr(); }
175  SUTILAPI const int* getGroupOffsets() const { return m_group_offsets.ptr(); }
176 
177  SUTILAPI float* getVertexData() { return m_vertex_data.ptr(); }
178  SUTILAPI const float* getVertexData() const { return m_vertex_data.ptr(); }
179 
180  SUTILAPI float* getNormalData() { return m_normal_data.ptr(); }
181  SUTILAPI const float* getNormalData() const { return m_normal_data.ptr(); }
182 
183  SUTILAPI float* getTextureCoordinateData() { return m_texture_data.ptr(); }
184  SUTILAPI const float* getTextureCoordinateData() const { return m_texture_data.ptr(); }
185 
186  SUTILAPI std::string& getGroupName(const uint32 i) { return m_group_names[i]; }
187  SUTILAPI const std::string& getGroupName(const uint32 i) const { return m_group_names[i]; }
188 
189  SUTILAPI const char* getMaterialName(const uint32 i) const { return m_material_names.ptr() + m_material_name_offsets[i]; }
190 
191  SUTILAPI uint32 insert_texture(const std::string& tex_name);
192 
193  SUTILAPI MeshView view()
194  {
195  MeshView mesh;
196  mesh.num_vertices = m_num_vertices;
197  mesh.num_normals = m_num_normals;
198  mesh.num_texture_coordinates = m_num_texture_coordinates;
199  mesh.num_triangles = m_num_triangles;
200  mesh.num_materials = (int)m_materials.count();
201  mesh.vertex_stride = m_vertex_stride;
202  mesh.normal_stride = m_normal_stride;
203  mesh.texture_stride = m_texture_stride;
204  mesh.vertex_indices = m_vertex_indices.ptr();
205  mesh.normal_indices = m_normal_indices.ptr();
206  mesh.normal_indices_comp = m_normal_indices_comp.ptr();
207  mesh.material_indices = m_material_indices.ptr();
208  mesh.texture_indices = m_texture_indices.ptr();
209  mesh.texture_indices_comp = m_texture_indices_comp.ptr();
210  mesh.vertex_data = m_vertex_data.ptr();
211  mesh.normal_data = m_normal_data.ptr();
212  mesh.normal_data_comp = m_normal_data_comp.ptr();
213  mesh.texture_data = m_texture_data.ptr();
214  mesh.lightmap_indices = m_lightmap_indices.ptr();
215  mesh.lightmap_indices_comp = m_lightmap_indices_comp.ptr();
216  mesh.lightmap_data = m_lightmap_data.ptr();
217  mesh.materials = m_materials.ptr();
218 
219  mesh.tex_bias = m_tex_bias;
220  mesh.tex_scale = m_tex_scale;
221  mesh.lm_bias = m_lm_bias;
222  mesh.lm_scale = m_lm_scale;
223  return mesh;
224  }
225 
226  void reorder_triangles(const int* index);
227  void reset_groups(const int num_groups, const int* group_offsets);
228 
229 public:
230  int m_num_vertices;
231  int m_num_normals;
232  int m_num_texture_coordinates;
233  int m_num_lightmap_coordinates;
234  int m_num_triangles;
235  int m_num_groups;
236 
237  int m_vertex_stride;
238  int m_normal_stride;
239  int m_texture_stride;
240 
241  float2 m_tex_bias;
242  float2 m_tex_scale;
243  float2 m_lm_bias;
244  float2 m_lm_scale;
245 
246  std::map<std::string,uint32> m_textures_map;
247  std::vector<std::string> m_textures;
248 
249  std::vector<std::string> m_group_names;
250 
251  Buffer<int> m_vertex_indices;
252  Buffer<int> m_normal_indices;
253  Buffer<int> m_normal_indices_comp;
254  Buffer<int> m_material_indices;
255  Buffer<int> m_texture_indices;
256  Buffer<int> m_texture_indices_comp;
257  Buffer<int> m_lightmap_indices;
258  Buffer<int> m_lightmap_indices_comp;
259  Buffer<int> m_group_offsets;
260  Buffer<float> m_vertex_data;
261  Buffer<float> m_normal_data;
262  Buffer<uint32> m_normal_data_comp;
263  Buffer<float> m_texture_data;
264  Buffer<float> m_lightmap_data;
265  Buffer<MeshMaterial> m_materials;
266  Buffer<char> m_material_names;
267  Buffer<int> m_material_name_offsets;
268 };
269 
273 class SUTILCLASSAPI DeviceMeshStorage
274 {
275 public:
276 
277  SUTILAPI DeviceMeshStorage() : m_num_vertices(0), m_num_normals(0), m_num_texture_coordinates(0), m_num_triangles(0) {}
278 
279  SUTILAPI DeviceMeshStorage& operator= (MeshStorage& mesh)
280  {
281  m_num_vertices = mesh.m_num_vertices;
282  m_num_normals = mesh.m_num_normals;
283  m_num_texture_coordinates = mesh.m_num_texture_coordinates;
284  m_num_lightmap_coordinates = mesh.m_num_lightmap_coordinates;
285  m_num_triangles = mesh.m_num_triangles;
286  m_num_groups = mesh.m_num_groups;
287 
288  m_vertex_stride = mesh.m_vertex_stride;
289  m_normal_stride = mesh.m_normal_stride;
290  m_texture_stride = mesh.m_texture_stride;
291 
292  m_vertex_indices = mesh.m_vertex_indices;
293  m_normal_indices = mesh.m_normal_indices;
294  m_material_indices = mesh.m_material_indices;
295  m_texture_indices = mesh.m_texture_indices;
296  m_lightmap_indices = mesh.m_lightmap_indices;
297  m_group_offsets = mesh.m_group_offsets;
298  m_vertex_data = mesh.m_vertex_data;
299  m_normal_data = mesh.m_normal_data;
300  m_normal_data_comp = mesh.m_normal_data_comp;
301  m_texture_data = mesh.m_texture_data;
302  m_lightmap_data = mesh.m_lightmap_data;
303  m_materials = mesh.m_materials;
304 
305  m_normal_indices_comp = mesh.m_normal_indices_comp;
306  m_texture_indices_comp = mesh.m_texture_indices_comp;
307  m_lightmap_indices_comp = mesh.m_lightmap_indices_comp;
308 
309  m_tex_bias = mesh.m_tex_bias;
310  m_tex_scale = mesh.m_tex_scale;
311  m_lm_bias = mesh.m_lm_bias;
312  m_lm_scale = mesh.m_lm_scale;
313  return *this;
314  }
315 
316  SUTILAPI int getNumVertices() const { return m_num_vertices; }
317  SUTILAPI int getNumNormals() const { return m_num_normals; }
318  SUTILAPI int getNumTextureCoordinates() const { return m_num_texture_coordinates; }
319  SUTILAPI int getNumTriangles() const { return m_num_triangles; }
320  SUTILAPI int getNumMaterials() const { return (int)m_materials.count(); }
321 
322  SUTILAPI int getVertexStride() const { return m_vertex_stride; }
323  SUTILAPI int getNormalStride() const { return m_normal_stride; }
324  SUTILAPI int getTextureCoordinateStride() const { return m_texture_stride; }
325 
326  SUTILAPI int* getVertexIndices() { return m_vertex_indices.ptr(); }
327  SUTILAPI const int* getVertexIndices() const { return m_vertex_indices.ptr(); }
328  SUTILAPI int* getNormalIndices() { return m_normal_indices.ptr(); }
329  SUTILAPI const int* getNormalIndices() const { return m_normal_indices.ptr(); }
330  SUTILAPI int* getMaterialIndices() { return m_material_indices.ptr(); }
331  SUTILAPI const int* getMaterialIndices() const { return m_material_indices.ptr(); }
332  SUTILAPI int* getTextureCoordinateIndices() { return m_texture_indices.ptr(); }
333  SUTILAPI const int* getTextureCoordinateIndices() const { return m_texture_indices.ptr(); }
334  SUTILAPI int* getLightmapIndices() { return m_lightmap_indices.ptr(); }
335  SUTILAPI const int* getLightmapIndices() const { return m_lightmap_indices.ptr(); }
336 
337  SUTILAPI float* getVertexData() { return m_vertex_data.ptr(); }
338  SUTILAPI const float* getVertexData() const { return m_vertex_data.ptr(); }
339 
340  SUTILAPI float* getNormalData() { return m_normal_data.ptr(); }
341  SUTILAPI const float* getNormalData() const { return m_normal_data.ptr(); }
342 
343  SUTILAPI float* getTextureCoordinateData() { return m_texture_data.ptr(); }
344  SUTILAPI const float* getTextureCoordinateData() const { return m_texture_data.ptr(); }
345 
346  SUTILAPI MeshView view()
347  {
348  MeshView mesh;
349  mesh.num_vertices = m_num_vertices;
350  mesh.num_normals = m_num_normals;
351  mesh.num_texture_coordinates = m_num_texture_coordinates;
352  mesh.num_triangles = m_num_triangles;
353  mesh.num_groups = m_num_groups;
354  mesh.num_materials = (int)m_materials.count();
355  mesh.vertex_stride = m_vertex_stride;
356  mesh.normal_stride = m_normal_stride;
357  mesh.texture_stride = m_texture_stride;
358  mesh.vertex_indices = m_vertex_indices.ptr();
359  mesh.normal_indices = m_normal_indices.ptr();
360  mesh.normal_indices_comp = m_normal_indices_comp.ptr();
361  mesh.material_indices = m_material_indices.ptr();
362  mesh.texture_indices = m_texture_indices.ptr();
363  mesh.texture_indices_comp = m_texture_indices_comp.ptr();
364  mesh.group_offsets = m_group_offsets.ptr();
365  mesh.vertex_data = m_vertex_data.ptr();
366  mesh.normal_data = m_normal_data.ptr();
367  mesh.normal_data_comp = m_normal_data_comp.ptr();
368  mesh.texture_data = m_texture_data.ptr();
369  mesh.lightmap_indices = m_lightmap_indices.ptr();
370  mesh.lightmap_indices_comp = m_lightmap_indices_comp.ptr();
371  mesh.lightmap_data = m_lightmap_data.ptr();
372  mesh.materials = m_materials.ptr();
373 
374  mesh.tex_bias = m_tex_bias;
375  mesh.tex_scale = m_tex_scale;
376  mesh.lm_bias = m_lm_bias;
377  mesh.lm_scale = m_lm_scale;
378  return mesh;
379  }
380 
381 public:
382  int m_num_vertices;
383  int m_num_normals;
384  int m_num_texture_coordinates;
385  int m_num_lightmap_coordinates;
386  int m_num_triangles;
387  int m_num_groups;
388 
389  int m_vertex_stride;
390  int m_normal_stride;
391  int m_texture_stride;
392 
393  float2 m_tex_bias;
394  float2 m_tex_scale;
395  float2 m_lm_bias;
396  float2 m_lm_scale;
397 
398  DomainBuffer<CUDA_BUFFER, int> m_vertex_indices;
399  DomainBuffer<CUDA_BUFFER, int> m_normal_indices;
400  DomainBuffer<CUDA_BUFFER, int> m_normal_indices_comp;
401  DomainBuffer<CUDA_BUFFER, int> m_material_indices;
402  DomainBuffer<CUDA_BUFFER, int> m_texture_indices;
403  DomainBuffer<CUDA_BUFFER, int> m_texture_indices_comp;
404  DomainBuffer<CUDA_BUFFER, int> m_lightmap_indices;
405  DomainBuffer<CUDA_BUFFER, int> m_lightmap_indices_comp;
406  DomainBuffer<CUDA_BUFFER, int> m_group_offsets;
407  DomainBuffer<CUDA_BUFFER, float> m_vertex_data;
408  DomainBuffer<CUDA_BUFFER, float> m_normal_data;
409  DomainBuffer<CUDA_BUFFER, uint32> m_normal_data_comp;
410  DomainBuffer<CUDA_BUFFER, float> m_texture_data;
411  DomainBuffer<CUDA_BUFFER, float> m_lightmap_data;
413 };
414 
417 SUTILAPI void loadModel(const std::string& filename, MeshStorage& mesh);
418 
421 SUTILAPI void loadMaterials(const std::string& filename, MeshStorage& mesh);
422 
425 SUTILAPI void apply_material_flags(MeshStorage& mesh);
426 
429 SUTILAPI void translate_group(
430  MeshStorage& mesh,
431  const uint32 group_id,
432  const float3 delta);
433 
436 SUTILAPI void translate_group(
437  DeviceMeshStorage& mesh,
438  const uint32 group_id,
439  const float3 delta);
440 
443 SUTILAPI void merge(MeshStorage& mesh, const MeshStorage& other);
444 
447 SUTILAPI void transform(
448  MeshStorage& mesh,
449  const float mat[4*4]);
450 
453 SUTILAPI void add_per_triangle_normals(MeshStorage& mesh);
454 
457 SUTILAPI void add_per_triangle_texture_coordinates(MeshStorage& mesh);
458 
461 SUTILAPI void unify_vertex_attributes(MeshStorage& mesh);
void transform(const uint32 n, const Iterator in, const Output out, const Functor functor)
Definition: primitives_inl.h:357
Definition: MeshBase.h:106
Definition: MeshView.h:55
Definition: MeshStorage.h:44
Definition: MeshView.h:96
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void merge(input_iterator1 first1, input_iterator1 end1, input_iterator2 first2, input_iterator2 end2, output_iterator output)
Definition: algorithms.h:214
Definition: MeshBase.h:67
Definition: MeshStorage.h:273