KiCad PCB EDA Suite
3d_model.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Oleg Endo <[email protected]>
5  * Copyright (C) 2015-2020 Mario Luzeiro <[email protected]>
6  * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
30 #include <stdexcept>
31 #include <gal/opengl/kiglew.h> // Must be included first
32 
33 #include "3d_model.h"
34 #include "opengl_utils.h"
35 #include "../common_ogl/ogl_utils.h"
36 #include "../3d_math.h"
37 #include <wx/debug.h>
38 #include <wx/log.h>
39 #include <chrono>
40 #include <memory>
41 
42 
43 /*
44  * Flag to enable connectivity profiling.
45  *
46  * @ingroup trace_env_vars
47  */
48 const wxChar* MODEL_3D::m_logTrace = wxT( "KI_TRACE_EDA_OGL_3DMODEL" );
49 
50 
51 void MODEL_3D::MakeBbox( const BBOX_3D& aBox, unsigned int aIdxOffset, VERTEX* aVtxOut,
52  GLuint* aIdxOut, const glm::vec4& aColor )
53 {
54  aVtxOut[0].m_pos = { aBox.Min().x, aBox.Min().y, aBox.Min().z };
55  aVtxOut[1].m_pos = { aBox.Max().x, aBox.Min().y, aBox.Min().z };
56  aVtxOut[2].m_pos = { aBox.Max().x, aBox.Max().y, aBox.Min().z };
57  aVtxOut[3].m_pos = { aBox.Min().x, aBox.Max().y, aBox.Min().z };
58 
59  aVtxOut[4].m_pos = { aBox.Min().x, aBox.Min().y, aBox.Max().z };
60  aVtxOut[5].m_pos = { aBox.Max().x, aBox.Min().y, aBox.Max().z };
61  aVtxOut[6].m_pos = { aBox.Max().x, aBox.Max().y, aBox.Max().z };
62  aVtxOut[7].m_pos = { aBox.Min().x, aBox.Max().y, aBox.Max().z };
63 
64  for( unsigned int i = 0; i < 8; ++i )
65  aVtxOut[i].m_color = aVtxOut[i].m_cad_color = glm::clamp( aColor * 255.0f, 0.0f, 255.0f );
66 
67  #define bbox_line( vtx_a, vtx_b )\
68  do { *aIdxOut++ = vtx_a + aIdxOffset; \
69  *aIdxOut++ = vtx_b + aIdxOffset; } while( 0 )
70 
71  bbox_line( 0, 1 );
72  bbox_line( 1, 2 );
73  bbox_line( 2, 3 );
74  bbox_line( 3, 0 );
75 
76  bbox_line( 4, 5 );
77  bbox_line( 5, 6 );
78  bbox_line( 6, 7 );
79  bbox_line( 7, 4 );
80 
81  bbox_line( 0, 4 );
82  bbox_line( 1, 5 );
83  bbox_line( 2, 6 );
84  bbox_line( 3, 7 );
85 
86  #undef bbox_line
87 }
88 
89 
90 MODEL_3D::MODEL_3D( const S3DMODEL& a3DModel, MATERIAL_MODE aMaterialMode )
91 {
92  wxLogTrace( m_logTrace, wxT( "MODEL_3D::MODEL_3D %u meshes %u materials" ),
93  static_cast<unsigned int>( a3DModel.m_MeshesSize ),
94  static_cast<unsigned int>( a3DModel.m_MaterialsSize ) );
95 
96  auto start_time = std::chrono::high_resolution_clock::now();
97  GLuint buffers[8];
98 
106  glGenBuffers( 6, buffers );
107  m_bbox_vertex_buffer = buffers[2];
108  m_bbox_index_buffer = buffers[3];
109  m_vertex_buffer = buffers[4];
110  m_index_buffer = buffers[5];
111 
112  // Validate a3DModel pointers
113  wxASSERT( a3DModel.m_Materials != nullptr );
114  wxASSERT( a3DModel.m_Meshes != nullptr );
115  wxASSERT( a3DModel.m_MaterialsSize > 0 );
116  wxASSERT( a3DModel.m_MeshesSize > 0 );
117 
118  m_materialMode = aMaterialMode;
119 
120  if( a3DModel.m_Materials == nullptr || a3DModel.m_Meshes == nullptr
121  || a3DModel.m_MaterialsSize == 0 || a3DModel.m_MeshesSize == 0 )
122  return;
123 
124  // create empty bbox for each mesh. it will be updated when the vertices are copied.
125  m_meshes_bbox.resize( a3DModel.m_MeshesSize );
126 
127  // copy materials for later use during rendering.
128  m_materials.reserve( a3DModel.m_MaterialsSize );
129 
130  for( unsigned int i = 0; i < a3DModel.m_MaterialsSize; ++i )
131  m_materials.emplace_back( a3DModel.m_Materials[i] );
132 
133  // build temporary vertex and index buffers for bounding boxes.
134  // the first box is the outer box.
135  std::vector<VERTEX> bbox_tmp_vertices( ( m_meshes_bbox.size() + 1 ) * bbox_vtx_count );
136  std::vector<GLuint> bbox_tmp_indices( ( m_meshes_bbox.size() + 1 ) * bbox_idx_count );
137 
138  // group all meshes by material.
139  // for each material create a combined vertex and index buffer.
140  // some models might have many sub-meshes. so iterate over the
141  // input meshes only once.
142  struct MESH_GROUP
143  {
144  std::vector<VERTEX> m_vertices;
145  std::vector<GLuint> m_indices;
146  };
147 
148  std::vector<MESH_GROUP> mesh_groups( m_materials.size() );
149 
150  for( unsigned int mesh_i = 0; mesh_i < a3DModel.m_MeshesSize; ++mesh_i )
151  {
152  const auto& mesh = a3DModel.m_Meshes[mesh_i];
153 
154  // silently ignore meshes that have invalid material references or invalid geometry.
155  if( mesh.m_MaterialIdx >= m_materials.size()
156  || mesh.m_Positions == nullptr
157  || mesh.m_FaceIdx == nullptr
158  || mesh.m_Normals == nullptr
159  || mesh.m_FaceIdxSize == 0
160  || mesh.m_VertexSize == 0 )
161  continue;
162 
163  auto& mesh_group = mesh_groups[mesh.m_MaterialIdx];
164  auto& material = m_materials[mesh.m_MaterialIdx];
165 
166  if( material.IsTransparent()
169  else
170  m_have_opaque_meshes = true;
171 
172  const unsigned int vtx_offset = mesh_group.m_vertices.size();
173  mesh_group.m_vertices.resize( mesh_group.m_vertices.size() + mesh.m_VertexSize );
174 
175  // copy vertex data and update the bounding box.
176  // use material color for mesh bounding box or some sort of average vertex color.
177  glm::vec3 avg_color = material.m_Diffuse;
178 
179  for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
180  {
181  m_meshes_bbox[mesh_i].Union( mesh.m_Positions[vtx_i] );
182 
183  auto& vtx_out = mesh_group.m_vertices[vtx_offset + vtx_i];
184 
185  vtx_out.m_pos = mesh.m_Positions[vtx_i];
186  vtx_out.m_nrm = glm::clamp( glm::vec4( mesh.m_Normals[vtx_i], 1.0f ) * 127.0f,
187  -127.0f, 127.0f );
188 
189  vtx_out.m_tex_uv = mesh.m_Texcoords != nullptr
190  ? mesh.m_Texcoords[vtx_i]
191  : glm::vec2 (0);
192 
193  if( mesh.m_Color != nullptr )
194  {
195  avg_color = ( avg_color + mesh.m_Color[vtx_i] ) * 0.5f;
196 
197  vtx_out.m_color =
198  glm::clamp( glm::vec4( mesh.m_Color[vtx_i],
199  1 - material.m_Transparency ) * 255.0f,
200  0.0f, 255.0f );
201 
202  vtx_out.m_cad_color =
203  glm::clamp( glm::vec4( MaterialDiffuseToColorCAD( mesh.m_Color[vtx_i] ),
204  1 ) * 255.0f, 0.0f, 255.0f );
205  }
206  else
207  {
208  // the mesh will be rendered with other meshes that might have
209  // vertex colors. thus, we can't enable/disable vertex colors
210  // for individual meshes during rendering.
211 
212  // if there are no vertex colors, use material color instead.
213  vtx_out.m_color =
214  glm::clamp( glm::vec4( material.m_Diffuse,
215  1 - material.m_Transparency ) * 255.0f,
216  0.0f, 255.0f );
217 
218  vtx_out.m_cad_color =
219  glm::clamp( glm::vec4 ( MaterialDiffuseToColorCAD( material.m_Diffuse ),
220  1 ) * 255.0f,
221  0.0f, 255.0f );
222  }
223  }
224 
225  if( m_meshes_bbox[mesh_i].IsInitialized() )
226  {
227  // generate geometry for the bounding box
228  MakeBbox( m_meshes_bbox[mesh_i], ( mesh_i + 1 ) * bbox_vtx_count,
229  &bbox_tmp_vertices[( mesh_i + 1 ) * bbox_vtx_count],
230  &bbox_tmp_indices[( mesh_i + 1 ) * bbox_idx_count],
231  { avg_color, 1.0f } );
232 
233  // bump the outer bounding box
234  m_model_bbox.Union( m_meshes_bbox[mesh_i] );
235  }
236 
237 
238  // append indices of this mesh to the mesh group.
239  const unsigned int idx_offset = mesh_group.m_indices.size();
240  unsigned int use_idx_count = mesh.m_FaceIdxSize;
241 
242  if( use_idx_count % 3 != 0 )
243  {
244  wxLogTrace( m_logTrace, wxT( " index count %u not multiple of 3, truncating" ),
245  static_cast<unsigned int>( use_idx_count ) );
246  use_idx_count = ( use_idx_count / 3 ) * 3;
247  }
248 
249  mesh_group.m_indices.resize( mesh_group.m_indices.size() + use_idx_count );
250 
251  for( unsigned int idx_i = 0; idx_i < use_idx_count; ++idx_i )
252  {
253  if( mesh.m_FaceIdx[idx_i] >= mesh.m_VertexSize )
254  {
255  wxLogTrace( m_logTrace, wxT( " index %u out of range (%u)" ),
256  static_cast<unsigned int>( mesh.m_FaceIdx[idx_i] ),
257  static_cast<unsigned int>( mesh.m_VertexSize ) );
258 
259  // FIXME: should skip this triangle
260  }
261 
262  mesh_group.m_indices[idx_offset + idx_i] = mesh.m_FaceIdx[idx_i] + vtx_offset;
263  }
264  }
265 
266  // generate geometry for the outer bounding box
268  MakeBbox( m_model_bbox, 0, &bbox_tmp_vertices[0], &bbox_tmp_indices[0],
269  { 0.0f, 1.0f, 0.0f, 1.0f } );
270 
271  // create bounding box buffers
272  glGenBuffers( 1, &m_bbox_vertex_buffer );
273  glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
274  glBufferData( GL_ARRAY_BUFFER, sizeof( VERTEX ) * bbox_tmp_vertices.size(),
275  bbox_tmp_vertices.data(), GL_STATIC_DRAW );
276 
277  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
278 
279  if( bbox_tmp_vertices.size() <= std::numeric_limits<GLushort>::max() )
280  {
281  m_bbox_index_buffer_type = GL_UNSIGNED_SHORT;
282 
283  auto u16buf = std::make_unique<GLushort[]>( bbox_tmp_indices.size() );
284 
285  for( unsigned int i = 0; i < bbox_tmp_indices.size(); ++i )
286  u16buf[i] = static_cast<GLushort>( bbox_tmp_indices[i] );
287 
288  glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( GLushort ) * bbox_tmp_indices.size(),
289  u16buf.get(), GL_STATIC_DRAW );
290  }
291  else
292  {
293  m_bbox_index_buffer_type = GL_UNSIGNED_INT;
294  glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( GLuint ) * bbox_tmp_indices.size(),
295  bbox_tmp_indices.data(), GL_STATIC_DRAW );
296  }
297 
298  // merge the mesh group geometry data.
299  unsigned int total_vertex_count = 0;
300  unsigned int total_index_count = 0;
301 
302  for( auto& mg : mesh_groups )
303  {
304  total_vertex_count += mg.m_vertices.size();
305  total_index_count += mg.m_indices.size();
306  }
307 
308  wxLogTrace( m_logTrace, wxT( " total %u vertices, %u indices" ),
309  total_vertex_count, total_index_count );
310 
311  glBindBuffer( GL_ARRAY_BUFFER, m_vertex_buffer );
312  glBufferData( GL_ARRAY_BUFFER, sizeof( VERTEX ) * total_vertex_count,
313  nullptr, GL_STATIC_DRAW );
314 
315  unsigned int idx_size = 0;
316 
317  if( total_vertex_count <= std::numeric_limits<GLushort>::max() )
318  {
319  m_index_buffer_type = GL_UNSIGNED_SHORT;
320  idx_size = sizeof( GLushort );
321  }
322  else
323  {
324  m_index_buffer_type = GL_UNSIGNED_INT;
325  idx_size = sizeof( GLuint );
326  }
327 
328  // temporary index buffer which will contain either GLushort or GLuint
329  // type indices. allocate with a bit of meadow at the end.
330  auto tmp_idx = std::make_unique<GLuint[]>(
331  ( idx_size * total_index_count + 8 ) / sizeof( GLuint ) );
332 
333  unsigned int prev_vtx_count = 0;
334  unsigned int idx_offset = 0;
335  unsigned int vtx_offset = 0;
336 
337  for( unsigned int mg_i = 0; mg_i < mesh_groups.size (); ++mg_i )
338  {
339  auto& mg = mesh_groups[mg_i];
340  auto& mat = m_materials[mg_i];
341 
342  if( m_index_buffer_type == GL_UNSIGNED_SHORT )
343  {
344  auto idx_out = reinterpret_cast<GLushort*>(
345  reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
346 
347  for( auto idx : mg.m_indices )
348  *idx_out++ = static_cast<GLushort>( idx + prev_vtx_count );
349  }
350  else if( m_index_buffer_type == GL_UNSIGNED_INT )
351  {
352  auto idx_out = reinterpret_cast<GLuint*>(
353  reinterpret_cast<uintptr_t>( tmp_idx.get() ) + idx_offset );
354 
355  for( auto idx : mg.m_indices )
356  *idx_out++ = static_cast<GLuint>( idx + prev_vtx_count );
357  }
358 
359  glBufferSubData( GL_ARRAY_BUFFER, vtx_offset, mg.m_vertices.size() * sizeof( VERTEX ),
360  mg.m_vertices.data() );
361 
362  mat.m_render_idx_buffer_offset = idx_offset;
363  mat.m_render_idx_count = mg.m_indices.size();
364 
365  prev_vtx_count += mg.m_vertices.size();
366  idx_offset += mg.m_indices.size() * idx_size;
367  vtx_offset += mg.m_vertices.size() * sizeof( VERTEX );
368  }
369 
370  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
371  glBufferData( GL_ELEMENT_ARRAY_BUFFER, idx_size * total_index_count, tmp_idx.get(),
372  GL_STATIC_DRAW );
373 
374  glBindBuffer( GL_ARRAY_BUFFER, 0 );
375  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
376 
377  auto end_time = std::chrono::high_resolution_clock::now();
378 
379  wxLogTrace( m_logTrace, wxT( " loaded in %u ms\n" ),
380  (unsigned int)std::chrono::duration_cast<std::chrono::milliseconds> (
381  end_time - start_time).count() );
382 }
383 
384 
385 void MODEL_3D::BeginDrawMulti( bool aUseColorInformation )
386 {
387  glEnableClientState( GL_VERTEX_ARRAY );
388  glEnableClientState( GL_NORMAL_ARRAY );
389 
390  if( aUseColorInformation )
391  {
392  glEnableClientState( GL_COLOR_ARRAY );
393  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
394  glEnable( GL_COLOR_MATERIAL );
395  }
396 
397  glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
398 }
399 
400 
402 {
403  glDisable( GL_COLOR_MATERIAL );
404  glDisableClientState( GL_VERTEX_ARRAY );
405  glDisableClientState( GL_NORMAL_ARRAY );
406  glDisableClientState( GL_COLOR_ARRAY );
407  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
408 
409  glBindBuffer( GL_ARRAY_BUFFER, 0 );
410  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
411 }
412 
413 
414 void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
415  SFVEC3F& aSelectionColor ) const
416 {
417  if( aOpacity <= FLT_EPSILON )
418  return;
419 
420  if( !glBindBuffer )
421  throw std::runtime_error( "The OpenGL context no longer exists: unable to draw" );
422 
423  glBindBuffer( GL_ARRAY_BUFFER, m_vertex_buffer );
424  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
425 
426  glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
427  reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
428 
429  glNormalPointer( GL_BYTE, sizeof( VERTEX ),
430  reinterpret_cast<const void*>( offsetof( VERTEX, m_nrm ) ) );
431 
432  glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
433  reinterpret_cast<const void*>( m_materialMode == MATERIAL_MODE::CAD_MODE
434  ? offsetof( VERTEX, m_cad_color )
435  : offsetof( VERTEX, m_color ) ) );
436 
437  glTexCoordPointer( 2, GL_FLOAT, sizeof( VERTEX ),
438  reinterpret_cast<const void*>( offsetof( VERTEX, m_tex_uv ) ) );
439 
440  const SFVEC4F param = SFVEC4F( 1.0f, 1.0f, 1.0f, aOpacity );
441 
442  glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)&param.x );
443 
444  // BeginDrawMulti();
445  for( const MODEL_3D::MATERIAL& mat : m_materials )
446  {
447  if( ( mat.IsTransparent() != aTransparent )
448  && ( aOpacity >= 1.0f )
450  {
451  continue;
452  }
453 
454  switch( m_materialMode )
455  {
457  OglSetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
458  break;
459 
461  OglSetDiffuseMaterial( mat.m_Diffuse, aOpacity, aUseSelectedMaterial, aSelectionColor );
462  break;
463 
465  OglSetDiffuseMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity,
466  aUseSelectedMaterial, aSelectionColor );
467  break;
468 
469  default:
470  break;
471  }
472 
473  glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
474  reinterpret_cast<const void*>(
475  static_cast<uintptr_t>( mat.m_render_idx_buffer_offset ) ) );
476  }
477 }
478 
479 
481 {
482  if( glDeleteBuffers )
483  {
484  glDeleteBuffers( 1, &m_vertex_buffer );
485  glDeleteBuffers( 1, &m_index_buffer );
486  glDeleteBuffers( 1, &m_bbox_vertex_buffer );
487  glDeleteBuffers( 1, &m_bbox_index_buffer );
488  }
489 }
490 
491 
492 void MODEL_3D::DrawBbox() const
493 {
494  if( !glBindBuffer )
495  throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bbox" );
496 
497  glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
498  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
499 
500  glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
501  reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
502 
503  glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
504  reinterpret_cast<const void*>( offsetof( VERTEX, m_color ) ) );
505 
506  glDrawElements( GL_LINES, bbox_idx_count, m_bbox_index_buffer_type,
507  reinterpret_cast<const void*>( 0 ) );
508 }
509 
510 
512 {
513  if( !glBindBuffer )
514  throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bboxes" );
515 
516  glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
517  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
518 
519  glVertexPointer( 3, GL_FLOAT, sizeof( VERTEX ),
520  reinterpret_cast<const void*>( offsetof( VERTEX, m_pos ) ) );
521 
522  glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( VERTEX ),
523  reinterpret_cast<const void*>( offsetof( VERTEX, m_color ) ) );
524 
525  unsigned int idx_size = m_bbox_index_buffer_type == GL_UNSIGNED_SHORT ? sizeof( GLushort )
526  : sizeof( GLuint );
527 
528  glDrawElements( GL_LINES, bbox_idx_count * m_meshes_bbox.size(), m_bbox_index_buffer_type,
529  reinterpret_cast<const void*>(
530  static_cast<uintptr_t>( bbox_idx_count * idx_size ) ) );
531 }
532 
Use a gray shading based on diffuse material.
void OglSetDiffuseMaterial(const SFVEC3F &aMaterialDiffuse, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Sets only the diffuse color and keep other parameters with default values.
Definition: ogl_utils.cpp:143
const SFVEC3F & Max() const
Return the maximum vertex pointer.
Definition: bbox_3d.h:198
void OglSetMaterial(const SMATERIAL &aMaterial, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Set OpenGL materials.
Definition: ogl_utils.cpp:119
Manage a bounding box defined by two SFVEC3F min max points.
Definition: bbox_3d.h:41
glm::vec4 SFVEC4F
Definition: xv3d_types.h:46
static void MakeBbox(const BBOX_3D &aBox, unsigned int aIdxOffset, VERTEX *aVtxOut, GLuint *aIdxOut, const glm::vec4 &aColor)
Definition: 3d_model.cpp:51
GLuint m_bbox_index_buffer
Definition: 3d_model.h:157
GLuint m_bbox_vertex_buffer
Definition: 3d_model.h:156
SMESH * m_Meshes
The meshes list of this model.
Definition: c3dmodel.h:93
void Union(const SFVEC3F &aPoint)
Recalculate the bounding box adding a point.
Definition: bbox_3d.cpp:102
const SFVEC3F & Min() const
Return the minimum vertex pointer.
Definition: bbox_3d.h:191
Use only diffuse material properties.
static constexpr unsigned int bbox_vtx_count
Definition: 3d_model.h:153
GLuint m_vertex_buffer
Definition: 3d_model.h:128
static constexpr unsigned int bbox_idx_count
Definition: 3d_model.h:154
bool m_have_transparent_meshes
Definition: 3d_model.h:149
#define bbox_line(vtx_a, vtx_b)
GLuint m_index_buffer
Definition: 3d_model.h:129
Use all material properties from model file.
void DrawBbox() const
Draw main bounding box of the model.
Definition: 3d_model.cpp:492
glm::vec3 m_pos
Definition: 3d_model.h:119
std::vector< MATERIAL > m_materials
Definition: 3d_model.h:143
static const wxChar * m_logTrace
Definition: 3d_model.h:106
MATERIAL_MODE
Render 3d model shape materials mode.
Definition: 3d_enums.h:118
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
bool IsInitialized() const
Check if this bounding box is already initialized.
Definition: bbox_3d.cpp:88
bool m_have_opaque_meshes
Definition: 3d_model.h:148
void DrawBboxes() const
Draw individual bounding boxes of each mesh.
Definition: 3d_model.cpp:511
MATERIAL_MODE m_materialMode
Definition: 3d_model.h:111
GLenum m_index_buffer_type
Definition: 3d_model.h:130
static void EndDrawMulti()
Cleanup render states after drawing multiple models.
Definition: 3d_model.cpp:401
MODEL_3D(const S3DMODEL &a3DModel, MATERIAL_MODE aMaterialMode)
Load a 3D model.
Definition: 3d_model.cpp:90
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:147
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
std::vector< BBOX_3D > m_meshes_bbox
individual bbox for each mesh
Definition: 3d_model.h:114
SMATERIAL * m_Materials
The materials list of this model.
Definition: c3dmodel.h:96
void Draw(bool aTransparent, float aOpacity, bool aUseSelectedMaterial, SFVEC3F &aSelectionColor) const
Definition: 3d_model.cpp:414
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90
GLenum m_bbox_index_buffer_type
Definition: 3d_model.h:158
static void BeginDrawMulti(bool aUseColorInformation)
Set some basic render states before drawing multiple models.
Definition: 3d_model.cpp:385
unsigned int m_MeshesSize
Number of meshes in the array.
Definition: c3dmodel.h:92
BBOX_3D m_model_bbox
global bounding box for this model
Definition: 3d_model.h:113