Developer Documentation
SplatCloudNode.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 //================================================================
51 //
52 // CLASS SplatCloudNode - IMPLEMENTATION
53 //
54 //================================================================
55 
56 
57 //== INCLUDES ====================================================
58 
59 #include <ACG/GL/acg_glew.hh>
60 
61 #include "SplatCloudNode.hh"
62 
63 
64 //== DEFINES =====================================================
65 
66 
67 //#define REPORT_VBO_UPDATES
68 
69 
70 //== NAMESPACES ==================================================
71 
72 
73 namespace ACG {
74 namespace SceneGraph {
75 
76 //== STATIC MEMBER VARIABLES =====================================
77 
78 
79 const SplatCloudNode::Position SplatCloudNode::DEFAULT_POSITION (0,0,0);
80 const SplatCloudNode::Index SplatCloudNode::DEFAULT_INDEX ( -1);
81 const SplatCloudNode::Viewlist SplatCloudNode::DEFAULT_VIEWLIST ( 0.0);
82 const SplatCloudNode::Selection SplatCloudNode::DEFAULT_SELECTION(false);
83 
84 
85 //== IMPLEMENTATION ==============================================
86 
87 
88 SplatCloudNode::SplatCloudNode( const SplatCloud &_splatCloud, BaseNode *_parent, std::string _name ) :
89  BaseNode ( _parent, _name ),
90  splatCloud_ ( _splatCloud ),
91  positionsModified_ ( false ),
92  colorsModified_ ( false ),
93  normalsModified_ ( false ),
94  pointsizesModified_ ( false ),
95  selectionsModified_ ( false ),
96  pickColorsModified_ ( false ),
97  defaultColor_ ( Color (0,0,0) ),
98  defaultNormal_ ( Normal (0,0,0) ),
99  defaultPointsize_ ( Pointsize( 0.0) ),
100  splatsDrawMode_ ( DrawModes::NONE ),
101  dotsDrawMode_ ( DrawModes::NONE ),
102  pointsDrawMode_ ( DrawModes::NONE ),
103  pickingBaseIndex_ ( 0 ),
104  pickDrawMode_ ( DrawModes::NONE ), // TODO: hack, see enterPick()
105  vboGlId_ ( 0 ),
106  vboNumSplats_ ( 0 ),
107  vboData_ ( 0 ),
108  vboPositionsOffset_ ( -1 ),
109  vboColorsOffset_ ( -1 ),
110  vboNormalsOffset_ ( -1 ),
111  vboPointsizesOffset_( -1 ),
112  vboSelectionsOffset_( -1 ),
113  vboPickColorsOffset_( -1 )
114 {
115  // add (possibly) new drawmodes
116  pointsDrawMode_ = DrawModes::addDrawMode( "Points" );
117  dotsDrawMode_ = DrawModes::addDrawMode( "Dots" );
118  splatsDrawMode_ = DrawModes::addDrawMode( "Splats" );
119 
120  // create a new VBO (will be invalid and rebuilt the next time drawn (or picked))
121  createVBO();
122 }
123 
124 
125 //----------------------------------------------------------------
126 
127 
129 {
130  destroyVBO();
131 }
132 
133 
134 //----------------------------------------------------------------
135 
136 
138 {
139  ACG::Vec3f bbMin( FLT_MAX, FLT_MAX, FLT_MAX );
140  ACG::Vec3f bbMax(-FLT_MAX,-FLT_MAX,-FLT_MAX );
141 
142  if( splatCloud_.hasPositions() )
143  {
144  unsigned int i, num = splatCloud_.numSplats();
145  for( i=0; i<num; ++i )
146  {
147  const Position &p = splatCloud_.positions( i );
148 
149  ACG::Vec3f acgp( p[0], p[1], p[2] );
150 
151  bbMin.minimize( acgp );
152  bbMax.maximize( acgp );
153  }
154  }
155 
156  _bbMin.minimize( ACG::Vec3d( bbMin ) );
157  _bbMax.maximize( ACG::Vec3d( bbMax ) );
158 }
159 
160 
161 //----------------------------------------------------------------
162 
163 
164 void SplatCloudNode::draw( GLState &_state, const DrawModes::DrawMode &_drawMode )
165 {
166 
167  static const int RENDERMODE_DOTS = 1;
168  static const int RENDERMODE_SPLATS = 2;
169 
170  // check if drawmode is valid
171  int rendermode;
172  if( _drawMode.containsAtomicDrawMode( splatsDrawMode_ ) )
173  rendermode = RENDERMODE_SPLATS;
174  else if( _drawMode.containsAtomicDrawMode( dotsDrawMode_ ) )
175  rendermode = RENDERMODE_DOTS;
176  else if( _drawMode.containsAtomicDrawMode( pointsDrawMode_ ) ) {
177  static const int RENDERMODE_POINTS = 0;
178  rendermode = RENDERMODE_POINTS;
179  } else
180  return;
181 
182  // set desired depth function
184 
185  // if VBO is invalid or was (partially) modified, then rebuild
186  if( (vboData_ == 0) || vboModified() )
187  rebuildVBO( _state );
188 
189  // if VBO is valid...
190  if( vboData_ != 0 )
191  {
192  // activate VBO
193  ACG::GLState::bindBufferARB( GL_ARRAY_BUFFER_ARB, vboGlId_ );
194 
195  // enable arrays:
196  // --------------
197 
198  // positions
199  if( vboPositionsOffset_ != -1 )
200  {
201  ACG::GLState::enableClientState( GL_VERTEX_ARRAY );
202  ACG::GLState::vertexPointer( 3, GL_FLOAT, 0, (unsigned char *) 0 + vboPositionsOffset_ );
203  }
204  else
205  {
206  ACG::GLState::disableClientState( GL_VERTEX_ARRAY );
207  }
208 
209  // colors
210  if( vboColorsOffset_ != -1 )
211  {
212  ACG::GLState::enableClientState( GL_SECONDARY_COLOR_ARRAY );
213  glSecondaryColorPointer( 3, GL_UNSIGNED_BYTE, 0, (unsigned char *) 0 + vboColorsOffset_ ); // TODO: use ACG::GLState::secondaryColorPointer() when implemented
214  }
215  else
216  {
217  ACG::GLState::disableClientState( GL_SECONDARY_COLOR_ARRAY );
218  glSecondaryColor3ub( defaultColor_[0], defaultColor_[1], defaultColor_[2] );
219  }
220 
221  // normals
222  if( vboNormalsOffset_ != -1 )
223  {
224  ACG::GLState::enableClientState( GL_NORMAL_ARRAY );
225  ACG::GLState::normalPointer( GL_FLOAT, 0, (unsigned char *) 0 + vboNormalsOffset_ );
226  }
227  else
228  {
229  ACG::GLState::disableClientState( GL_NORMAL_ARRAY );
230  glNormal3f( defaultNormal_[0], defaultNormal_[1], defaultNormal_[2] );
231  }
232 
233  // pointsizes
234  if( vboPointsizesOffset_ != -1 )
235  {
236  glClientActiveTexture( GL_TEXTURE0 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
237  ACG::GLState::enableClientState( GL_TEXTURE_COORD_ARRAY );
238  ACG::GLState::texcoordPointer( 1, GL_FLOAT, 0, (unsigned char *) 0 + vboPointsizesOffset_ );
239  }
240  else
241  {
242  glClientActiveTexture( GL_TEXTURE0 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
243  ACG::GLState::disableClientState( GL_TEXTURE_COORD_ARRAY );
244  glMultiTexCoord1f( GL_TEXTURE0, defaultPointsize_ );
245  }
246 
247  // selections
248  if( vboSelectionsOffset_ != -1 )
249  {
250  glClientActiveTexture( GL_TEXTURE1 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
251  ACG::GLState::enableClientState( GL_TEXTURE_COORD_ARRAY );
252  ACG::GLState::texcoordPointer( 1, GL_FLOAT, 0, (unsigned char *) 0 + vboSelectionsOffset_ );
253  }
254  else
255  {
256  glClientActiveTexture( GL_TEXTURE1 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
257  ACG::GLState::disableClientState( GL_TEXTURE_COORD_ARRAY );
258  glMultiTexCoord1f( GL_TEXTURE1, 0.0f );
259  }
260 
261  // pick colors
262  if( vboPickColorsOffset_ != -1 )
263  {
264  ACG::GLState::enableClientState( GL_COLOR_ARRAY );
265  ACG::GLState::colorPointer( 4, GL_UNSIGNED_BYTE, 0, (unsigned char *) 0 + vboPickColorsOffset_ );
266  }
267  else
268  {
269  ACG::GLState::disableClientState( GL_COLOR_ARRAY );
270  glColor4ub( 255, 255, 255, 255 );
271  }
272 
273  // render:
274  // -------
275 
276  // enable "pointsize by program" depending on current rendermode
277  if( rendermode == RENDERMODE_SPLATS || rendermode == RENDERMODE_DOTS )
278  ACG::GLState::enable( GL_VERTEX_PROGRAM_POINT_SIZE );
279  else
280  ACG::GLState::disable( GL_VERTEX_PROGRAM_POINT_SIZE );
281 
282  // draw as GLpoints
283  glDrawArrays( GL_POINTS, 0, vboNumSplats_ );
284 
285  // disable arrays:
286  // ---------------
287 
288  // positions
289  ACG::GLState::disableClientState( GL_VERTEX_ARRAY );
290 
291  // colors
292  ACG::GLState::disableClientState( GL_SECONDARY_COLOR_ARRAY );
293 
294  // normals
295  ACG::GLState::disableClientState( GL_NORMAL_ARRAY );
296 
297  // pointsizes
298  glClientActiveTexture( GL_TEXTURE0 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
299  ACG::GLState::disableClientState( GL_TEXTURE_COORD_ARRAY );
300 
301  // selections
302  glClientActiveTexture( GL_TEXTURE1 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
303  ACG::GLState::disableClientState( GL_TEXTURE_COORD_ARRAY );
304 
305  // pick colors
306  ACG::GLState::disableClientState( GL_COLOR_ARRAY );
307 
308  // reset states:
309  // -------------
310 
311  // disable "pointsize by program"
312  ACG::GLState::disable( GL_VERTEX_PROGRAM_POINT_SIZE );
313 
314  // make defaults current again
315  glClientActiveTexture( GL_TEXTURE0 ); // TODO: use ACG::GLState::clientActiveTexture() when implemented
316  glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f );
317  glSecondaryColor3f( 1.0f, 1.0f, 1.0f );
318 
319  // deactivate VBO
320  ACG::GLState::bindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
321  }
322 }
323 
324 
325 //----------------------------------------------------------------
326 
327 
328 void SplatCloudNode::pick( GLState &_state, PickTarget _target )
329 {
330  // if pick target is valid...
331  if( _target == PICK_ANYTHING || _target == PICK_VERTEX )
332  {
333  // set number of pick colors used (each splats gets a unique pick color)
334  if( !_state.pick_set_maximum( splatCloud_.numSplats() ) ) // number of splats could have changed, so use new number of splats (*not* the one in VBO memory!)
335  {
336  std::cerr << "SplatCloudNode::pick() : Color range too small, picking failed." << std::endl;
337  return;
338  }
339 
340  // if in color picking mode...
341  if( _state.color_picking() )
342  {
343  // if picking base index has changed, rebuild pick colors block in VBO so new pick colors will be used
344  if( pickingBaseIndex_ != _state.pick_current_index() )
345  {
346  pickColorsModified_ = true;
347  }
348 
349  // TODO: hack, see enterPick()
350  draw( _state, pickDrawMode_ );
351  }
352  }
353 }
354 
355 
356 //----------------------------------------------------------------
357 
358 
359 void SplatCloudNode::createVBO()
360 {
361  // create new VBO (if *not* already existing)
362  if( vboGlId_ == 0 )
363  {
364  glGenBuffersARB( 1, &vboGlId_ );
365  vboNumSplats_ = 0;
366  vboData_ = 0;
367 
368  modifiedAll(); // (re-)build all data block in VBO memory the first time
369  }
370 }
371 
372 
373 //----------------------------------------------------------------
374 
375 
376 void SplatCloudNode::destroyVBO()
377 {
378  // delete VBO (if existing)
379  if( vboGlId_ != 0 )
380  {
381  glDeleteBuffersARB( 1, &vboGlId_ );
382  vboGlId_ = 0;
383  vboNumSplats_ = 0;
384  vboData_ = 0;
385  }
386 }
387 
388 
389 //----------------------------------------------------------------
390 
391 
392 void SplatCloudNode::rebuildVBO( GLState &_state )
393 {
394  // if something went wrong in the initialization, make VBO invalid and abort
395  if( vboGlId_ == 0 )
396  {
397  vboData_ = 0;
398  return;
399  }
400 
401  // activate VBO
402  ACG::GLState::bindBufferARB( GL_ARRAY_BUFFER_ARB, vboGlId_ );
403 
404  // calculate size of data and offsets
405  unsigned int numSplats = splatCloud_.numSplats();
406  unsigned int size = 0;
407 
408  int positionsOffset = -1;
409  int colorsOffset = -1;
410  int normalsOffset = -1;
411  int pointsizesOffset = -1;
412  int selectionsOffset = -1;
413  int pickColorsOffset = -1;
414 
415  if( splatCloud_.hasPositions() ) { positionsOffset = size; size += numSplats * 12; }
416  if( splatCloud_.hasColors() ) { colorsOffset = size; size += numSplats * 3; }
417  if( splatCloud_.hasNormals() ) { normalsOffset = size; size += numSplats * 12; }
418  if( splatCloud_.hasPointsizes() ) { pointsizesOffset = size; size += numSplats * 4; }
419  if( splatCloud_.hasSelections() ) { selectionsOffset = size; size += numSplats * 4; }
420  /* has pick colors is true */ { pickColorsOffset = size; size += numSplats * 4; }
421 
422  // tell GL that we are seldomly updating the VBO but are often drawing it
423  glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, 0, GL_STATIC_DRAW_ARB );
424 
425  // get pointer to VBO memory
426  unsigned char *data = (unsigned char *) glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB );
427 
428  // check if something went wrong during VBO mapping
429  if( data == 0 )
430  {
431  std::cout << "SplatCloudNode::rebuildVBO() : glMapBufferARB() failed." << std::endl;
432  vboData_ = 0;
433  }
434  else
435  {
436  // if VBO memory block was moved or the internal block structure has to be changed, rebuild entire VBO
437  if( (vboData_ != data) || vboStructureModified() )
438  {
439  vboNumSplats_ = numSplats;
440  vboData_ = data;
441 
442  vboPositionsOffset_ = positionsOffset;
443  vboColorsOffset_ = colorsOffset;
444  vboNormalsOffset_ = normalsOffset;
445  vboPointsizesOffset_ = pointsizesOffset;
446  vboSelectionsOffset_ = selectionsOffset;
447  vboPickColorsOffset_ = pickColorsOffset;
448 
449  // mark all data blocks to rebuild them lateron
450  modifiedAll();
451  }
452 
453  // if in color picking mode...
454  if( _state.color_picking() )
455  {
456  // store picking base index
457  pickingBaseIndex_ = _state.pick_current_index();
458  }
459 
460  // rebuild data blocks if needed
461  if( positionsModified_ ) rebuildVBOPositions();
462  if( colorsModified_ ) rebuildVBOColors();
463  if( normalsModified_ ) rebuildVBONormals();
464  if( pointsizesModified_ ) rebuildVBOPointsizes();
465  if( selectionsModified_ ) rebuildVBOSelections();
466  if( pickColorsModified_ ) rebuildVBOPickColors( _state );
467 
468 # ifdef REPORT_VBO_UPDATES
469  std::cout << std::endl;
470 # endif
471 
472  // every block in VBO memory has been updated
473  positionsModified_ = false;
474  colorsModified_ = false;
475  normalsModified_ = false;
476  pointsizesModified_ = false;
477  selectionsModified_ = false;
478  pickColorsModified_ = false;
479 
480  // release pointer to VBO memory. if something went wrong, make VBO invalid and abort
481  if( !glUnmapBufferARB( GL_ARRAY_BUFFER_ARB ) )
482  {
483  std::cout << "SplatCloudNode::rebuildVBO() : glUnmapBufferARB() failed." << std::endl;
484  vboData_ = 0;
485  }
486  }
487 
488  // deactivate VBO
489  ACG::GLState::bindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
490 }
491 
492 
493 //----------------------------------------------------------------
494 
495 
496 static void addFloatToBuffer( float _value, unsigned char *&_buffer )
497 {
498  // get pointer
499  unsigned char *v = (unsigned char *) &_value;
500 
501  // copy over 4 bytes
502  *_buffer++ = *v++;
503  *_buffer++ = *v++;
504  *_buffer++ = *v++;
505  *_buffer++ = *v;
506 }
507 
508 
509 //----------------------------------------------------------------
510 
511 
512 static void addIntToBuffer( int _value, unsigned char *&_buffer )
513 {
514  // get pointer
515  unsigned char *v = (unsigned char *) &_value;
516 
517  // copy over 4 bytes
518  *_buffer++ = *v++;
519  *_buffer++ = *v++;
520  *_buffer++ = *v++;
521  *_buffer++ = *v;
522 }
523 
524 
525 //----------------------------------------------------------------
526 
527 
528 static void addUCharToBuffer( unsigned char _value, unsigned char *&_buffer )
529 {
530  // get pointer
531  unsigned char *v = (unsigned char *) &_value;
532 
533  // copy over 1 byte
534  *_buffer++ = *v;
535 }
536 
537 
538 //----------------------------------------------------------------
539 
540 
541 void SplatCloudNode::rebuildVBOPositions()
542 {
543  if( (vboPositionsOffset_ == -1) || !splatCloud_.hasPositions() )
544  return;
545 
546 # ifdef REPORT_VBO_UPDATES
547  std::cout << "SplatCloudNode::rebuildVBOPositions()" << std::endl;
548 # endif
549 
550  // get pointer to buffer
551  unsigned char *buffer = vboData_ + vboPositionsOffset_;
552 
553  // for all positions...
554  unsigned int i, num = splatCloud_.numSplats();
555  for( i=0; i<num; ++i )
556  {
557  // add position
558  const Position &p = getPosition( i );
559  addFloatToBuffer( p[0], buffer );
560  addFloatToBuffer( p[1], buffer );
561  addFloatToBuffer( p[2], buffer );
562  }
563 }
564 
565 
566 //----------------------------------------------------------------
567 
568 
569 void SplatCloudNode::rebuildVBOColors()
570 {
571  if( (vboColorsOffset_ == -1) || !splatCloud_.hasColors() )
572  return;
573 
574 # ifdef REPORT_VBO_UPDATES
575  std::cout << "SplatCloudNode::rebuildVBOColors()" << std::endl;
576 # endif
577 
578  // get pointer to buffer
579  unsigned char *buffer = vboData_ + vboColorsOffset_;
580 
581  // for all colors...
582  unsigned int i, num = splatCloud_.numSplats();
583  for( i=0; i<num; ++i )
584  {
585  // add color
586  const Color &c = getColor( i );
587  addUCharToBuffer( c[0], buffer );
588  addUCharToBuffer( c[1], buffer );
589  addUCharToBuffer( c[2], buffer );
590  }
591 }
592 
593 
594 //----------------------------------------------------------------
595 
596 
597 void SplatCloudNode::rebuildVBONormals()
598 {
599  if( (vboNormalsOffset_ == -1) || !splatCloud_.hasNormals() )
600  return;
601 
602 # ifdef REPORT_VBO_UPDATES
603  std::cout << "SplatCloudNode::rebuildVBONormals()" << std::endl;
604 # endif
605 
606  // get pointer to buffer
607  unsigned char *buffer = vboData_ + vboNormalsOffset_;
608 
609  // for all normals...
610  unsigned int i, num = splatCloud_.numSplats();
611  for( i=0; i<num; ++i )
612  {
613  // add normal
614  const Normal &n = getNormal( i );
615  addFloatToBuffer( n[0], buffer );
616  addFloatToBuffer( n[1], buffer );
617  addFloatToBuffer( n[2], buffer );
618  }
619 }
620 
621 
622 //----------------------------------------------------------------
623 
624 
625 void SplatCloudNode::rebuildVBOPointsizes()
626 {
627  if( (vboPointsizesOffset_ == -1) || !splatCloud_.hasPointsizes() )
628  return;
629 
630 # ifdef REPORT_VBO_UPDATES
631  std::cout << "SplatCloudNode::rebuildVBOPointsizes()" << std::endl;
632 # endif
633 
634  // get pointer to buffer
635  unsigned char *buffer = vboData_ + vboPointsizesOffset_;
636 
637  // for all pointsizes...
638  unsigned int i, num = splatCloud_.numSplats();
639  for( i=0; i<num; ++i )
640  {
641  // add pointsize
642  const Pointsize &ps = getPointsize( i );
643  addFloatToBuffer( ps, buffer );
644  }
645 }
646 
647 
648 //----------------------------------------------------------------
649 
650 
651 void SplatCloudNode::rebuildVBOSelections()
652 {
653  if( (vboSelectionsOffset_ == -1) || !splatCloud_.hasSelections() )
654  return;
655 
656 # ifdef REPORT_VBO_UPDATES
657  std::cout << "SplatCloudNode::rebuildVBOSelections()" << std::endl;
658 # endif
659 
660  // get pointer to buffer
661  unsigned char *buffer = vboData_ + vboSelectionsOffset_;
662 
663  // for all selections...
664  unsigned int i, num = splatCloud_.numSplats();
665  for( i=0; i<num; ++i )
666  {
667  const bool &s = getSelection( i );
668  addFloatToBuffer( (s ? 1.0f : 0.0f), buffer );
669  }
670 }
671 
672 
673 //----------------------------------------------------------------
674 
675 
676 void SplatCloudNode::rebuildVBOPickColors( GLState &_state )
677 {
678  if( (vboPickColorsOffset_ == -1) || !splatCloud_.hasPositions() )
679  return;
680 
681 # ifdef REPORT_VBO_UPDATES
682  std::cout << "SplatCloudNode::rebuildVBOPickColors()" << std::endl;
683 # endif
684 
685  // get pointer to buffer
686  unsigned char *buffer = vboData_ + vboPickColorsOffset_;
687 
688  // for all pick colors...
689  unsigned int i, num = splatCloud_.numSplats();
690  for( i=0; i<num; ++i )
691  {
692  // add pick color
693  const Vec4uc &pc = _state.pick_get_name_color( i );
694  addUCharToBuffer( pc[0], buffer );
695  addUCharToBuffer( pc[1], buffer );
696  addUCharToBuffer( pc[2], buffer );
697  addUCharToBuffer( pc[3], buffer );
698  }
699 }
700 
701 
702 //================================================================
703 
704 
705 } // namespace SceneGraph
706 } // namespace ACG
unsigned int pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1114
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
const DrawMode & addDrawMode(const std::string &_name, bool _propertyBased)
Add a custom DrawMode.
Definition: DrawModes.cc:771
bool hasSelections() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:619
bool hasPointsizes() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:616
bool hasColors() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:614
bool color_picking() const
Is color picking active?
Definition: GLState.cc:1124
bool vboStructureModified() const
returns true iff the internal block structure of the VBO has to be changed
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Vec4uc pick_get_name_color(unsigned int _idx)
Definition: GLState.cc:1064
int vboPositionsOffset_
offsets relative to vboData_ or -1 if not present in VBO
bool positionsModified_
marks if parts of the data has been modified
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:562
static void enable(GLenum _cap)
replaces glEnable, but supports locking
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:937
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1047
unsigned int numSplats() const
Get the number of splats.
Definition: SplatCloud.hh:185
SplatCloudNode(const SplatCloud &_splatCloud, BaseNode *_parent=0, std::string _name="<SplatCloudNode>")
constructor
Position & positions(int _idx)
Get a reference of the predefined property&#39;s value.
Definition: SplatCloud.hh:637
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
Definition: MeshNode2T.cc:576
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
picks verices (may not be implemented for all nodes)
Definition: BaseNode.hh:108
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
const SplatCloud & splatCloud_
reference to class containing all the data
bool hasNormals() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:615
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
bool containsAtomicDrawMode(DrawMode _atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
bool vboModified() const
return true iff any of the data values in the VBO has to be changed
void pick(GLState &_state, PickTarget _target)
picking
bool hasPositions() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:613
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:534
void boundingBox(ACG::Vec3d &_bbMin, ACG::Vec3d &_bbMax)
update bounding box
const Position & getPosition(int _idx) const
if the data array exists, the entry with the given index is returned, otherwise the default value is ...
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
draw the SplatCloud
Color defaultColor_
the default values will be used when the specific array is not present
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active