GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_3dviewinstance.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 *****************************************************************************/
22 
24 
25 #include "glc_3dviewinstance.h"
26 #include "../shading/glc_selectionmaterial.h"
27 #include "../viewport/glc_viewport.h"
28 #include <QMutexLocker>
29 #include "../glc_state.h"
30 
33 
36 
37 
39 // Construction/Destruction
41 
43 : GLC_Object()
44 , m_3DRep()
45 , m_pBoundingBox(NULL)
46 , m_AbsoluteMatrix()
47 , m_IsBoundingBoxValid(false)
48 , m_RenderProperties()
49 , m_IsVisible(true)
50 , m_DefaultLOD(m_GlobalDefaultLOD)
51 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
52 , m_ViewableGeomFlag()
53 {
54  // Encode Color Id
56 
57 }
58 
60 : GLC_Object()
61 , m_3DRep(pGeom)
62 , m_pBoundingBox(NULL)
63 , m_AbsoluteMatrix()
64 , m_IsBoundingBoxValid(false)
65 , m_RenderProperties()
66 , m_IsVisible(true)
67 , m_DefaultLOD(m_GlobalDefaultLOD)
68 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
69 , m_ViewableGeomFlag()
70 {
71  // Encode Color Id
73 
74  setName(m_3DRep.name());
75 }
76 
78 : GLC_Object(id)
79 , m_3DRep(pGeom)
80 , m_pBoundingBox(NULL)
81 , m_AbsoluteMatrix()
82 , m_IsBoundingBoxValid(false)
83 , m_RenderProperties()
84 , m_IsVisible(true)
85 , m_DefaultLOD(m_GlobalDefaultLOD)
86 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
87 , m_ViewableGeomFlag()
88 {
89  // Encode Color Id
91 
92  setName(m_3DRep.name());
93 }
94 
96 : GLC_Object(rep.name())
97 , m_3DRep(rep)
98 , m_pBoundingBox(NULL)
99 , m_AbsoluteMatrix()
100 , m_IsBoundingBoxValid(false)
101 , m_RenderProperties()
102 , m_IsVisible(true)
103 , m_DefaultLOD(m_GlobalDefaultLOD)
104 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
105 , m_ViewableGeomFlag()
106 {
107  // Encode Color Id
109 
110 }
111 
113 : GLC_Object(id, rep.name())
114 , m_3DRep(rep)
115 , m_pBoundingBox(NULL)
116 , m_AbsoluteMatrix()
117 , m_IsBoundingBoxValid(false)
118 , m_RenderProperties()
119 , m_IsVisible(true)
120 , m_DefaultLOD(m_GlobalDefaultLOD)
121 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
122 , m_ViewableGeomFlag()
123 {
124  // Encode Color Id
126 
127 }
128 
129 // Copy constructor
131 : GLC_Object(inputNode)
132 , m_3DRep(inputNode.m_3DRep)
133 , m_pBoundingBox(NULL)
134 , m_AbsoluteMatrix(inputNode.m_AbsoluteMatrix)
135 , m_IsBoundingBoxValid(inputNode.m_IsBoundingBoxValid)
136 , m_RenderProperties(inputNode.m_RenderProperties)
137 , m_IsVisible(inputNode.m_IsVisible)
138 , m_DefaultLOD(inputNode.m_DefaultLOD)
139 , m_ViewableFlag(inputNode.m_ViewableFlag)
140 , m_ViewableGeomFlag(inputNode.m_ViewableGeomFlag)
141 {
142  // Encode Color Id
144 
145  if (NULL != inputNode.m_pBoundingBox)
146  {
148  }
149 }
150 
151 
152 // Assignement operator
154 {
155  if (this != &inputNode)
156  {
157  // Clear this instance
158  clear();
159  GLC_Object::operator=(inputNode);
160  // Encode Color Id
162 
163  m_3DRep= inputNode.m_3DRep;
164  if (NULL != inputNode.m_pBoundingBox)
165  {
167  }
171  m_IsVisible= inputNode.m_IsVisible;
172  m_DefaultLOD= inputNode.m_DefaultLOD;
173  m_ViewableFlag= inputNode.m_ViewableFlag;
175 
176  //qDebug() << "GLC_3DViewInstance::operator= :ID = " << m_Uid;
177  //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
178  }
179 
180  return *this;
181 }
182 
183 // Destructor
185 {
186  clear();
187 }
188 
190 // Get Functions
192 
193 // Get the bounding box
195 {
196  GLC_BoundingBox resultBox;
197  if (boundingBoxValidity())
198  {
199  resultBox= *m_pBoundingBox;
200  }
201  else if (!m_3DRep.isEmpty())
202  {
204  m_IsBoundingBoxValid= true;
205  resultBox= *m_pBoundingBox;
206  }
207 
208  return resultBox;
209 }
210 
213 {
214  QMutexLocker locker(&m_Mutex);
215  m_GlobalDefaultLOD= lod;
216 }
217 
219 {
220  m_3DRep.setVboUsage(usage);
221 }
222 
223 // Clone the instance
225 {
226 
227  GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(m_3DRep.deepCopy());
228  Q_ASSERT(NULL != pRep);
229  GLC_3DRep newRep(*pRep);
230  delete pRep;
231  GLC_3DViewInstance cloneInstance(newRep);
232 
233  if (NULL != m_pBoundingBox)
234  {
235  cloneInstance.m_pBoundingBox= new GLC_BoundingBox(*m_pBoundingBox);
236  }
237 
238  cloneInstance.m_AbsoluteMatrix= m_AbsoluteMatrix;
240  cloneInstance.m_RenderProperties= m_RenderProperties;
241  cloneInstance.m_IsVisible= m_IsVisible;
242  cloneInstance.m_ViewableFlag= m_ViewableFlag;
243  return cloneInstance;
244 }
245 
246 // Instanciate the instance
248 {
249  GLC_3DViewInstance instance(*this);
250  instance.m_Uid= glc::GLC_GenID();
251  // Encode Color Id
253 
254  return instance;
255 }
256 
258 // Set Functions
260 
261 
262 // Set the instance Geometry
264 {
265  if (m_3DRep.contains(pGeom))
266  {
267  return false;
268  }
269  else
270  {
271  m_3DRep.addGeom(pGeom);
272  return true;
273  }
274 }
275 
276 // Instance translation
277 GLC_3DViewInstance& GLC_3DViewInstance::translate(double Tx, double Ty, double Tz)
278 {
279  multMatrix(GLC_Matrix4x4(Tx, Ty, Tz));
280 
281  return *this;
282 }
283 
284 
285 // Move instance with a 4x4Matrix
287 {
289  m_IsBoundingBoxValid= false;
290 
291  return *this;
292 }
293 
294 // Replace the instance Matrix
296 {
297  m_AbsoluteMatrix= SetMat;
298  m_IsBoundingBoxValid= false;
299 
300  return *this;
301 }
302 
303 // Reset the instance Matrix
305 {
307  m_IsBoundingBoxValid= false;
308 
309  return *this;
310 }
311 
313 // OpenGL Functions
315 
316 // Display the instance
317 void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView)
318 {
319  //qDebug() << "GLC_3DViewInstance::render render properties= " << m_RenderProperties.renderingMode();
320  if (m_3DRep.isEmpty()) return;
321  const int bodyCount= m_3DRep.numberOfBody();
322 
323  if (bodyCount != m_ViewableGeomFlag.size())
324  {
325  m_ViewableGeomFlag.fill(true, bodyCount);
326  }
327 
329 
330  // Save current OpenGL Matrix
333 
334  // Change front face orientation if this instance absolute matrix is indirect
336  {
337  glFrontFace(GL_CW);
338  }
340  {
341  glColor3ubv(m_colorId); // D'ont use Alpha component
342  }
343 
344  if (useLod && (NULL != pView))
345  {
346  for (int i= 0; i < bodyCount; ++i)
347  {
348  if (m_ViewableGeomFlag.at(i))
349  {
350  const int lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod);
351  if (lodValue <= 100)
352  {
353  m_3DRep.geomAt(i)->setCurrentLod(lodValue);
356  }
357  }
358  }
359  }
360  else
361  {
362  for (int i= 0; i < bodyCount; ++i)
363  {
364  if (m_ViewableGeomFlag.at(i))
365  {
366  int lodValue= 0;
367  if (GLC_State::isPixelCullingActivated() && (NULL != pView))
368  {
369  lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod);
370  }
371 
372  if (lodValue <= 100)
373  {
377  }
378  }
379  }
380  }
381  // Restore OpenGL Matrix
383 
384  // Restore front face orientation if this instance absolute matrix is indirect
386  {
387  glFrontFace(GL_CCW);
388  }
389 
390 }
391 
392 // Display the instance in Body selection mode
394 {
395  Q_ASSERT(GLC_State::isInSelectionMode());
396  if (m_3DRep.isEmpty()) return;
397 
398  // Save previous rendering mode and set the rendering mode to BodySelection
399  glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
401 
402  // Save current OpenGL Matrix
405 
406  GLubyte colorId[4];
407  const int size= m_3DRep.numberOfBody();
408  for (int i= 0; i < size; ++i)
409  {
410  GLC_Geometry* pGeom= m_3DRep.geomAt(i);
411  glc::encodeRgbId(pGeom->id(), colorId);
412  glColor3ubv(colorId);
413  pGeom->setCurrentLod(m_DefaultLOD);
415  pGeom->render(m_RenderProperties);
416  }
417 
418  // Restore rendering mode
419  m_RenderProperties.setRenderingMode(previousRenderMode);
420  // Restore OpenGL Matrix
422 }
423 
424 // Display the instance in Primitive selection mode and return the body index
426 {
427  Q_ASSERT(GLC_State::isInSelectionMode());
428  if (m_3DRep.isEmpty()) return -1;
429  // Save previous rendering mode and set the rendering mode to BodySelection
430  glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
432 
433  // Save current OpenGL Matrix
436 
437  const int size= m_3DRep.numberOfBody();
438  int i= 0;
439  bool continu= true;
440  while ((i < size) && continu)
441  {
442  GLC_Geometry* pGeom= m_3DRep.geomAt(i);
443  if (pGeom->id() == bodyId)
444  {
445  pGeom->setCurrentLod(0);
446  pGeom->render(m_RenderProperties);
447  continu= false;
448  }
449  else ++i;
450  }
451 
452  m_RenderProperties.setRenderingMode(previousRenderMode);
453 
454  // Restore OpenGL Matrix
456 
457  return i;
458 }
459 
460 
461 
463 // private services functions
465 
466 
467 // compute the instance bounding box
468 // m_pGeomList should be not null
470 {
471  if (m_3DRep.isEmpty()) return;
472 
473  if (m_pBoundingBox != NULL)
474  {
475  delete m_pBoundingBox;
476  m_pBoundingBox= NULL;
477  }
479  const int size= m_3DRep.numberOfBody();
480  for (int i= 0; i < size; ++i)
481  {
483  }
484 
486 }
487 
488 // Clear current instance
490 {
491 
492  delete m_pBoundingBox;
493  m_pBoundingBox= NULL;
494 
495  // invalidate the bounding box
496  m_IsBoundingBoxValid= false;
497 
498 }
499 
500 // Compute LOD
501 int GLC_3DViewInstance::choseLod(const GLC_BoundingBox& boundingBox, GLC_Viewport* pView, bool useLod)
502 {
503  if (NULL == pView) return 0;
504  double pixelCullingRatio= 0.0;
505  if (useLod)
506  {
507  pixelCullingRatio= pView->minimumDynamicPixelCullingRatio();
508  }
509  else
510  {
511  pixelCullingRatio= pView->minimumStaticPixelCullingRatio();
512  }
513 
514  const double diameter= boundingBox.boundingSphereRadius() * 2.0 * m_AbsoluteMatrix.scalingX();
515  GLC_Vector3d center(m_AbsoluteMatrix * boundingBox.center());
516 
517  const double dist= (center - pView->cameraHandle()->eye()).length();
518  const double cameraCover= dist * pView->viewTangent();
519 
520  double ratio= diameter / cameraCover * 100.0;
521  if (ratio > 100.0) ratio= 100.0;
522  ratio= 100.0 - ratio;
523 
524  if ((ratio > (100.0 - pixelCullingRatio)) && GLC_State::isPixelCullingActivated()) ratio= 110.0;
525  else if(useLod && (ratio > 50.0))
526  {
527  ratio= (ratio - 50.0) / 50.0 * 100.0;
528  if (ratio < static_cast<double>(m_DefaultLOD)) ratio= static_cast<double>(m_DefaultLOD);
529  }
530  else
531  {
532  ratio= static_cast<double>(m_DefaultLOD);
533  }
534 
535  return static_cast<int>(ratio);
536 }
537 
538 

©2005-2013 Laurent Ribon