Developer Documentation
CoordsysNode.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 
45 
46 
47 //=============================================================================
48 //
49 // CLASS CoordsysNode - IMPLEMENTATION
50 //
51 //=============================================================================
52 
53 //== INCLUDES =================================================================
54 
55 #include "CoordsysNode.hh"
56 #include <ACG/GL/IRenderer.hh>
57 #include <ACG/GL/ShaderCache.hh>
58 
59 //== NAMESPACES ===============================================================
60 
61 namespace ACG {
62 namespace SceneGraph {
63 
64 
65 //== IMPLEMENTATION ==========================================================
66 
67 
68 CoordsysNode::CoordsysNode(BaseNode* _parent, std::string _name, CoordsysMode _mode, ProjectionMode _projectionMode) :
69  BaseNode(_parent, _name),
70  mode_(_mode),
71  projectionMode_(_projectionMode)
72 {
73  const double bodyRadius = 0.004;
74  const double topRadius = 0.01;
75  const int slices = 10;
76  const int stacks = 10;
77 
78  sphere_ = new ACG::GLSphere(slices,stacks);
79  cylinder_ = new ACG::GLCylinder(slices, stacks, bodyRadius,false,false);
80  cone_ = new ACG::GLCone(slices, stacks, 0, topRadius , false,true);
81  disk_ = new ACG::GLDisk(slices, 10, 0.0f, bodyRadius);
82 }
83 
85  if (sphere_)
86  delete sphere_;
87 
88  if (cylinder_)
89  delete cylinder_;
90 
91  if (cone_)
92  delete cone_;
93 
94  if (disk_)
95  delete disk_;
96 }
97 
98 void
100 boundingBox(Vec3d& /*_bbMin*/, Vec3d& /*_bbMax*/)
101 {
102  //_bbMin.minimize( Vect3f )
103 }
104 
105 
106 //----------------------------------------------------------------------------
107 
108 
112 {
113  return ( DrawModes::POINTS |
116 }
117 
118 
119 //----------------------------------------------------------------------------
120 
121 void
122 CoordsysNode::
123 drawCoordsys( GLState& _state) {
124 
125  const double arrowLength = 0.03;
126  const double bodyLength = 0.06;
127  const double sphereRadius = 0.01;
128 
129 
130  ACG::Vec4f matCol(0.5f, 0.5f, 0.5f, 1.0f);
131 
132  // Origin
133  glColor4f(0.5, 0.5, 0.5 , 1.0);
134  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.5f).data());
135  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
136  sphere_->draw(_state,sphereRadius);
137 
138  // X-Axis
139  glColor4f(1.0, 0.0, 0.0, 1.0);
140  matCol[0] = 1.0f; matCol[1] = 0.0f; matCol[2] = 0.0f;
141  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.5f).data());
142  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
143  _state.push_modelview_matrix ();
144  _state.rotate (-90, 0, 1, 0);
145  _state.translate ( 0, 0, -bodyLength );
146  cylinder_->draw(_state,bodyLength);
147  _state.translate ( 0, 0, -arrowLength );
148  cone_->draw(_state,arrowLength);
149  _state.pop_modelview_matrix ();
150 
151  // Y-Axis
152  glColor4f(0.0, 1.0, 0.0, 1.0);
153  matCol[0] = 0.0f; matCol[1] = 1.0f; matCol[2] = 0.0f;
154  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.2f).data());
155  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
156  _state.push_modelview_matrix ();
157  _state.rotate (90, 1, 0, 0);
158  _state.translate ( 0, 0, -bodyLength );
159  cylinder_->draw(_state,bodyLength);
160  _state.translate ( 0, 0, -arrowLength );
161  cone_->draw(_state,arrowLength);
162  _state.pop_modelview_matrix ();
163 
164  // Z-Axis
165  glColor4f(0.0, 0.0, 1.0, 1.0);
166  matCol[0] = 0.0f; matCol[1] = 0.0f; matCol[2] = 1.0f;
167  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.5f).data());
168  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
169  _state.push_modelview_matrix ();
170  _state.rotate (180, 0, 1, 0);
171  _state.translate ( 0, 0, -bodyLength );
172  cylinder_->draw(_state,bodyLength);
173  _state.translate ( 0, 0, -arrowLength );
174  cone_->draw(_state,arrowLength);
175  _state.pop_modelview_matrix ();
176 
177 }
178 
179 void CoordsysNode::drawCoordsys(IRenderer* _renderer, RenderObject* _baseRO)
180 {
181  // save model view matrix
182  const GLMatrixd mModelView = _baseRO->modelview;
183 
184 
185  const double arrowLength = 0.03;
186  const double bodyLength = 0.06;
187  const double sphereRadius = 0.01;
188 
189 
190  // Origin
191  _baseRO->debugName = "coordsys.sphere";
192  _baseRO->emissive = Vec3f(0.4f, 0.4f, 0.4f);
193  _baseRO->diffuse = Vec3f(0.3f, 0.3f, 0.3f);
194  _baseRO->specular = Vec3f(0.2f, 0.2f, 0.2f);
195  _baseRO->ambient = Vec3f(0.1f, 0.1f, 0.1f);
196  sphere_->addToRenderer(_renderer, _baseRO, sphereRadius);
197 
198 
199  // X-Axis
200  _baseRO->debugName = "coordsys.x.axis";
201  _baseRO->emissive = Vec3f(0.5f, 0.0f, 0.0f);
202  _baseRO->diffuse = Vec3f(0.3f, 0.0f, 0.0f);
203  _baseRO->specular = Vec3f(0.1f, 0.0f, 0.0f);
204  _baseRO->ambient = Vec3f(0.1f, 0.0f, 0.0f);
205  _baseRO->modelview = mModelView;
206  _baseRO->modelview.rotate (-90, 0, 1, 0);
207  _baseRO->modelview.translate ( 0, 0, -bodyLength );
208  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);
209 
210  _baseRO->debugName = "coordsys.x.head";
211  _baseRO->modelview.translate ( 0, 0, -arrowLength );
212  cone_->addToRenderer(_renderer, _baseRO, arrowLength);
213 
214 
215  // Y-Axis
216  _baseRO->debugName = "coordsys.y.axis";
217  _baseRO->emissive = Vec3f(0.0f, 0.5f, 0.0f);
218  _baseRO->diffuse = Vec3f(0.0f, 0.3f, 0.0f);
219  _baseRO->specular = Vec3f(0.0f, 0.1f, 0.0f);
220  _baseRO->ambient = Vec3f(0.0f, 0.1f, 0.0f);
221  _baseRO->modelview = mModelView;
222  _baseRO->modelview.rotate (90, 1, 0, 0);
223  _baseRO->modelview.translate ( 0, 0, -bodyLength );
224  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);
225 
226  _baseRO->debugName = "coordsys.y.head";
227  _baseRO->modelview.translate ( 0, 0, -arrowLength );
228  cone_->addToRenderer(_renderer, _baseRO, arrowLength);
229 
230 
231  // Z-Axis
232  _baseRO->debugName = "coordsys.z.axis";
233  _baseRO->emissive = Vec3f(0.0f, 0.0f, 0.5f);
234  _baseRO->diffuse = Vec3f(0.0f, 0.0f, 0.3f);
235  _baseRO->specular = Vec3f(0.0f, 0.0f, 0.1f);
236  _baseRO->ambient = Vec3f(0.0f, 0.0f, 0.1f);
237  _baseRO->modelview = mModelView;
238  _baseRO->modelview.rotate (180, 0, 1, 0);
239  _baseRO->modelview.translate ( 0, 0, -bodyLength );
240  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);
241 
242  _baseRO->debugName = "coordsys.z.head";
243  _baseRO->modelview.translate ( 0, 0, -arrowLength );
244  cone_->addToRenderer(_renderer, _baseRO, arrowLength);
245 }
246 
247 //============================================================================
248 
249 void
250 CoordsysNode::drawCoordsysPick( GLState& _state, GLSL::Program* _pickShader) {
251 
252  const double arrowLength = 0.03;
253  const double bodyLength = 0.06;
254  const double sphereRadius = 0.01;
255 
256  // Origin
257  if (_pickShader)
258  {
259  _pickShader->setUniform("color", _state.pick_get_name_color_norm(1));
260 
261  GLMatrixf mWVP = _state.projection() * _state.modelview();
262  mWVP.scale(sphereRadius, sphereRadius, sphereRadius);
263  _pickShader->setUniform("mWVP", mWVP);
264  sphere_->draw_primitive(_pickShader);
265  }
266  else
267  {
268  _state.pick_set_name (1);
269  sphere_->draw(_state,sphereRadius);
270  }
271 
272  // X-Axis
273  if (_pickShader)
274  _pickShader->setUniform("color", _state.pick_get_name_color_norm(2));
275  else
276  _state.pick_set_name(2);
277  _state.push_modelview_matrix ();
278  _state.rotate (-90, 0, 1, 0);
279  _state.translate ( 0, 0, -bodyLength );
280  _state.push_modelview_matrix();
281  _state.scale(1.0, 1.0, bodyLength);
282  if (_pickShader)
283  {
284  // set transform matrix
285  GLMatrixf mWVP = _state.projection() * _state.modelview();
286  _pickShader->setUniform("mWVP", mWVP);
287  cylinder_->draw_primitive(_pickShader);
288  }
289  else
290  cylinder_->draw_primitive();
291  _state.pop_modelview_matrix();
292  _state.translate ( 0, 0, -arrowLength );
293  _state.scale(1.0, 1.0, arrowLength);
294  if (_pickShader)
295  {
296  // set transform matrix
297  GLMatrixf mWVP = _state.projection() * _state.modelview();
298  _pickShader->setUniform("mWVP", mWVP);
299  cone_->draw_primitive(_pickShader);
300  }
301  else
302  cone_->draw_primitive();
303  _state.pop_modelview_matrix ();
304 
305 
306  // Y-Axis
307  if (_pickShader)
308  _pickShader->setUniform("color", _state.pick_get_name_color_norm(3));
309  else
310  _state.pick_set_name(3);
311  _state.push_modelview_matrix ();
312  _state.rotate (90, 1, 0, 0);
313  _state.translate ( 0, 0, -bodyLength );
314  _state.push_modelview_matrix();
315  _state.scale(1.0, 1.0, bodyLength);
316  if (_pickShader)
317  {
318  // set transform matrix
319  GLMatrixf mWVP = _state.projection() * _state.modelview();
320  _pickShader->setUniform("mWVP", mWVP);
321  cylinder_->draw_primitive(_pickShader);
322  }
323  else
324  cylinder_->draw_primitive();
325  _state.pop_modelview_matrix();
326  _state.translate(0, 0, -arrowLength);
327  _state.scale(1.0, 1.0, arrowLength);
328  if (_pickShader)
329  {
330  // set transform matrix
331  GLMatrixf mWVP = _state.projection() * _state.modelview();
332  _pickShader->setUniform("mWVP", mWVP);
333  cone_->draw_primitive(_pickShader);
334  }
335  else
336  cone_->draw_primitive();
337  _state.pop_modelview_matrix ();
338 
339  // Z-Axis
340  if (_pickShader)
341  _pickShader->setUniform("color", _state.pick_get_name_color_norm(4));
342  else
343  _state.pick_set_name(4);
344  _state.push_modelview_matrix ();
345  _state.rotate (180, 0, 1, 0);
346  _state.translate ( 0, 0, -bodyLength );
347  _state.push_modelview_matrix();
348  _state.scale(1.0, 1.0, bodyLength);
349  if (_pickShader)
350  {
351  // set transform matrix
352  GLMatrixf mWVP = _state.projection() * _state.modelview();
353  _pickShader->setUniform("mWVP", mWVP);
354  cylinder_->draw_primitive(_pickShader);
355  }
356  else
357  cylinder_->draw_primitive();
358  _state.pop_modelview_matrix();
359  _state.translate(0, 0, -arrowLength);
360  _state.scale(1.0, 1.0, arrowLength);
361  if (_pickShader)
362  {
363  // set transform matrix
364  GLMatrixf mWVP = _state.projection() * _state.modelview();
365  _pickShader->setUniform("mWVP", mWVP);
366  cone_->draw_primitive(_pickShader);
367  }
368  else
369  cone_->draw_primitive();
370  _state.pop_modelview_matrix ();
371 
372 }
373 
374 
375 //============================================================================
376 
377 
378 void
380 draw(GLState& _state , const DrawModes::DrawMode& /*_drawMode*/)
381 {
382  GLenum prev_depth = _state.depthFunc();
383 
384  GLboolean colorMask[4];
385  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
386 
387  // Push Modelview-Matrix
388  _state.push_modelview_matrix();
389 
390  Vec4f lastBaseColor = _state.base_color();
391 
392  glPushAttrib( GL_LIGHTING_BIT ); // STACK_ATTRIBUTES <- LIGHTING_ATTRIBUTE
393  ACG::GLState::enable(GL_LIGHTING);
394  glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
395  ACG::GLState::enable(GL_COLOR_MATERIAL);
396  ACG::GLState::shadeModel(GL_SMOOTH);
397 
398  GLfloat zeroVec[4] = {0.0f};
399  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zeroVec);
400  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, zeroVec);
401 
402  // Init state - changes when mode_ != POSITION
403  Vec3d pos3D(0.0,0.0,0.0);
404 
405  if ( mode_ == SCREENPOS ) {
406 
407  int left, bottom, width, height;
408  double aspect = _state.aspect();
409 
410  _state.get_viewport(left, bottom, width, height);
411 
412  // Projection reset
413  _state.push_projection_matrix();
414  _state.reset_projection();
415 
416  if (projectionMode_ == PERSPECTIVE_PROJECTION)
417  _state.perspective(45.0, aspect, 0.8, 20.0);
418  else
419  _state.ortho(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 0.8, 20.0);
420 
421  _state.push_modelview_matrix();
422  _state.reset_modelview();
423 
424  float rel_size = 50.0;
425  float projdist = sqrt ( (width*height) / rel_size );
426 
427  float posx = left + width - projdist ;
428  float posy = bottom + height - projdist ;
429 
430  // get our desired coordsys position in scene coordinates
431  pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
432  _state.pop_modelview_matrix();
433 
434  // reset scene translation
435  // we want only the scene rotation to rotate the coordsys
436  GLMatrixd modelview = _state.modelview();
437 
438  modelview(0,3) = 0.0;
439  modelview(1,3) = 0.0;
440  modelview(2,3) = 0.0;
441 
442  _state.set_modelview (modelview);
443  _state.translate (pos3D[0], pos3D[1], pos3D[2], MULT_FROM_LEFT);
444 
445 
446  // clear the depth buffer behind the coordsys
447  ACG::GLState::depthRange (1.0, 1.0);
448  ACG::GLState::depthFunc (GL_ALWAYS);
449 
450  drawCoordsys(_state);
451 
452  ACG::GLState::depthRange (0.0, 1.0);
453  ACG::GLState::depthFunc (GL_LESS);
454 
455  // draw coordsys
456  drawCoordsys(_state);
457 
458  // set depth buffer to 0 so that nothing can paint over cordsys
459  ACG::GLState::depthRange (0.0, 0.0);
460  ACG::GLState::depthFunc (GL_ALWAYS);
461  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
462 
463  // Koordinatensystem zeichnen
464  drawCoordsys(_state);
465 
466  ACG::GLState::depthRange (0.0, 1.0);
467  ACG::GLState::depthFunc (prev_depth);
468  glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
469 
470  // Projection reload
471  _state.pop_projection_matrix();
472 
473 
474  } else if (mode_ == POSITION) { /* mode_ == POSITION */
475 
476  GLMatrixd modelview = _state.modelview();
477 
478  modelview(0,3) = 0.0;
479  modelview(1,3) = 0.0;
480  modelview(2,3) = 0.0;
481 
482  _state.set_modelview (modelview);
483 
484  // clear depth buffer in coordsys region
485  ACG::GLState::depthRange (1.0, 1.0);
486  ACG::GLState::depthFunc (GL_ALWAYS);
487 
488  // Koordinatensystem zeichnen
489  drawCoordsys(_state);
490 
491  // draw coordsys in normal mode
492  ACG::GLState::depthRange (0.0, 1.0);
493  ACG::GLState::depthFunc (GL_LESS);
494 
495  // Koordinatensystem zeichnen
496  drawCoordsys(_state);
497 
498  // set depth buffer to 0 so that nothing can paint over cordsys
499  ACG::GLState::depthRange (0.0, 0.0);
500  ACG::GLState::depthFunc (GL_ALWAYS);
501  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
502 
503  // Koordinatensystem zeichnen
504  drawCoordsys(_state);
505 
506  // reset to default
507  ACG::GLState::depthRange (0.0, 1.0);
508  ACG::GLState::depthFunc (prev_depth);
509  glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
510  }
511 
512  glPopAttrib();
513 
514  glColor4fv(lastBaseColor.data());
515 
516  // Reload old configuration
517  _state.pop_modelview_matrix();
518 }
519 
520 
521 
522 
523 
524 
525 void CoordsysNode::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
526 {
527  // Init state - changes when mode_ != POSITION
528  Vec3d pos3D(0.0,0.0,0.0);
529 
530  _state.push_modelview_matrix();
531 
532 
533  // init base renderobject
534  RenderObject ro;
535  ro.initFromState(&_state);
536  ro.setMaterial(_mat);
537 
538 
539  ro.depthTest = true;
540  ro.depthWrite = true;
541  ro.inZPrePass = false;
542  ro.overlay = true;
543 
544  if ( mode_ == SCREENPOS ) {
545 
546  int left, bottom, width, height;
547  double aspect = _state.aspect();
548 
549  _state.get_viewport(left, bottom, width, height);
550 
551  // Projection reset
552  _state.push_projection_matrix();
553  _state.reset_projection();
554 
555  if (projectionMode_ == PERSPECTIVE_PROJECTION)
556  _state.perspective(45.0, aspect, 0.8, 20.0);
557  else
558  _state.ortho(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 0.8, 20.0);
559 
560  _state.push_modelview_matrix();
561  _state.reset_modelview();
562 
563  float rel_size = 50.0;
564  float projdist = sqrt ( (width*height) / rel_size );
565 
566  float posx = left + width - projdist ;
567  float posy = bottom + height - projdist ;
568 
569  // get our desired coordsys position in scene coordinates
570  pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
571  _state.pop_modelview_matrix();
572 
573  // reset scene translation
574  // we want only the scene rotation to rotate the coordsys
575  GLMatrixd modelview = _state.modelview();
576 
577  modelview(0,3) = 0.0;
578  modelview(1,3) = 0.0;
579  modelview(2,3) = 0.0;
580 
581  _state.set_modelview (modelview);
582  _state.translate (pos3D[0], pos3D[1], pos3D[2], MULT_FROM_LEFT);
583 
584 
585  // grab new transforms
586  ro.proj = _state.projection();
587  ro.modelview = _state.modelview();
588 
589  // colored by emission only
590  ro.shaderDesc.shadeMode = SG_SHADE_PHONG;
592  ro.shaderDesc.vertexColors = false;
593 
594 
595 
596  // regrab of transforms needed, drawCoordsys overwrites this
597  ro.modelview = _state.modelview();
598 
599  ro.priority = 3;
600  ro.depthRange = Vec2f(0.0f, 1.0f);
601  ro.depthFunc = GL_LESS;
602 
603  // draw coordsys
604  drawCoordsys(_renderer, &ro);
605 
606 
607  // Projection reload
608  _state.pop_projection_matrix();
609 
610  } else if (mode_ == POSITION) { /* mode_ == POSITION */
611 
612  GLMatrixd modelview = _state.modelview();
613 
614  modelview(0,3) = 0.0;
615  modelview(1,3) = 0.0;
616  modelview(2,3) = 0.0;
617 
618  _state.set_modelview (modelview);
619 
620  // clear depth buffer in coordsys region
621  ACG::GLState::depthRange (1.0, 1.0);
622  ACG::GLState::depthFunc (GL_ALWAYS);
623 
624  // Koordinatensystem zeichnen
625  drawCoordsys(_renderer, &ro);
626 
627  // draw coordsys in normal mode
628  ACG::GLState::depthRange (0.0, 1.0);
629  ACG::GLState::depthFunc (GL_LESS);
630 
631  // Koordinatensystem zeichnen
632  drawCoordsys(_renderer, &ro);
633 
634  // set depth buffer to 0 so that nothing can paint over cordsys
635  ACG::GLState::depthRange (0.0, 0.0);
636  ACG::GLState::depthFunc (GL_ALWAYS);
637  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
638 
639  // Koordinatensystem zeichnen
640  drawCoordsys(_renderer, &ro);
641  }
642 
643 
644  _state.pop_modelview_matrix();
645 }
646 
647 
648 
649 void
651 setMode(const CoordsysMode _mode)
652 {
653  mode_ = _mode;
654 }
655 
656 void
659 {
660  projectionMode_ = _mode;
661 }
662 
663 void
665 setPosition(const Vec3f& _pos)
666 {
667  pos3f_ = _pos;
668 }
669 
672 getMode() const
673 {
674  return mode_;
675 }
676 
680 {
681  return projectionMode_;
682 }
683 
684 void
686 {
687  // use fixed function or shaders to draw pick geometry
688  const bool fixedFunctionGL = _state.compatibilityProfile();
689 
690  // load picking shader from cache
691  GLSL::Program* pickShader = 0;
692  if (!fixedFunctionGL)
693  {
694  static ShaderGenDesc desc;
695  desc.fragmentTemplateFile = "Picking/single_color_fs.glsl";
696  desc.vertexTemplateFile = "Picking/vertex.glsl";
697  pickShader = ShaderCache::getInstance()->getProgram(&desc, nullptr);
698  if (!pickShader)
699  return;
700 
701  pickShader->use();
702  }
703 
704  GLenum prev_depth = _state.depthFunc();
705 
706  if (_target == PICK_ANYTHING) {
707 
708  GLdouble mat[16];
709 
710  // Push Modelview-Matrix
711  _state.push_modelview_matrix();
712  _state.pick_set_maximum (5);
713  _state.pick_set_name (0);
714 
715  // Init state - changes when mode_ != POSITION
716  Vec3d pos3D(0.0,0.0,0.0);
717 
718  if ( mode_ == SCREENPOS ) {
719 
720  int left, bottom, width, height;
721  double aspect = _state.aspect();
722 
723  _state.get_viewport(left, bottom, width, height);
724 
725  // Projection reset
726  _state.push_projection_matrix();
727  _state.reset_projection();
728 
729  if (projectionMode_ == PERSPECTIVE_PROJECTION)
730  _state.perspective(45.0, aspect, 0.8, 20.0);
731  else
732  _state.ortho(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 0.8, 20.0);
733 
734  _state.push_modelview_matrix();
735  _state.reset_modelview();
736 
737  float rel_size = 50.0;
738  float projdist = sqrt ( (width*height) / rel_size );
739 
740  float posx = left + width - projdist ;
741  float posy = bottom + height - projdist ;
742 
743  // get our desired coordsys position in scene coordinates
744  pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
745  _state.pop_modelview_matrix();
746 
747  // reset scene translation
748  GLMatrixd modelview = _state.modelview();
749 
750  modelview(0,3) = 0.0;
751  modelview(1,3) = 0.0;
752  modelview(2,3) = 0.0;
753 
754  _state.set_modelview (modelview);
755  _state.translate (pos3D[0], pos3D[1], pos3D[2], MULT_FROM_LEFT);
756 
757  // We don't have access to the pick matrix used during selection buffer picking
758  // so we can't draw our pick area circle in this case
759  if (_state.color_picking ())
760  {
761  // clear depth buffer behind coordsys node
762  clearPickArea(_state, true, 1.0, pickShader);
763 
764  // Koordinatensystem zeichnen
765  drawCoordsysPick(_state, pickShader);
766 
767  // set depth buffer to 0.0 so that nothing can paint above
768  clearPickArea(_state, false, 0.0, pickShader);
769  }
770  else
771  {
772  // clear depth buffer in coordsys region
773  ACG::GLState::depthRange (1.0, 1.0);
774  ACG::GLState::depthFunc (GL_ALWAYS);
775 
776  // Koordinatensystem zeichnen
777  drawCoordsys(_state);
778 
779  // draw coordsys in normal mode
780  ACG::GLState::depthRange (0.0, 1.0);
781  ACG::GLState::depthFunc (GL_LESS);
782 
783  // Koordinatensystem zeichnen
784  drawCoordsys(_state);
785 
786  // set depth buffer to 0 so tah nothing can paint over cordsys
787  ACG::GLState::depthRange (0.0, 0.0);
788  ACG::GLState::depthFunc (GL_ALWAYS);
789  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
790 
791  // Koordinatensystem zeichnen
792  drawCoordsys(_state);
793 
794  // reset to default
795  ACG::GLState::depthRange (0.0, 1.0);
796  ACG::GLState::depthFunc (prev_depth);
797  glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
798  }
799 
800  // Projection reload
801  _state.pop_projection_matrix();
802 
803  } else if (mode_ == POSITION) { /* mode_ == POSITION */
804 
805  // The selection buffer picking method might have set a
806  // pick matrix that has been multiplied with the projection matrix.
807  // This is the only way to get the gl pick matrix again
808 
809  if (_state.compatibilityProfile())
810  {
811  // todo: check if the pick matrix is really needed here
812  glMatrixMode(GL_PROJECTION);
813 
814  glPushMatrix();
815  glMultMatrixd(_state.inverse_projection().get_raw_data());
816 
817  glGetDoublev(GL_PROJECTION_MATRIX, mat);
818 
819  glPopMatrix();
820 
821  GLMatrixd pickMat(mat);
822 
823  glMatrixMode(GL_MODELVIEW);
824 
825  GLMatrixd modelview = _state.modelview();
826 
827  modelview(0,3) = 0.0;
828  modelview(1,3) = 0.0;
829  modelview(2,3) = 0.0;
830 
831  // glMatrix functions are not available in core profile
832  // so maybe remove this if-branch altogether?
833  }
834 
835 
836  // We don't have access to the pick matrix used during selection buffer picking
837  // so we can't draw our pick area circle in this case
838  if (_state.color_picking ())
839  {
840  // clear depth buffer behind coordsys node
841  clearPickArea(_state, true, 1.0, pickShader);
842 
843  // Koordinatensystem zeichnen
844  drawCoordsysPick(_state, pickShader);
845 
846  // set depth buffer to 0.0 so that nothing can paint above
847  clearPickArea(_state, false, 0.0, pickShader);
848  }
849  else
850  {
851  // clear depth buffer in coordsys region
852  ACG::GLState::depthRange (1.0, 1.0);
853  ACG::GLState::depthFunc (GL_ALWAYS);
854 
855  // Koordinatensystem zeichnen
856  drawCoordsys(_state);
857 
858  // draw coordsys in normal mode
859  ACG::GLState::depthRange (0.0, 1.0);
860  ACG::GLState::depthFunc (GL_LESS);
861 
862  // Koordinatensystem zeichnen
863  drawCoordsys(_state);
864 
865  // set depth buffer to 0 so tah nothing can paint over cordsys
866  ACG::GLState::depthRange (0.0, 0.0);
867  ACG::GLState::depthFunc (GL_ALWAYS);
868  glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
869 
870  // Koordinatensystem zeichnen
871  drawCoordsys(_state);
872 
873  // reset to default
874  ACG::GLState::depthRange (0.0, 1.0);
875  ACG::GLState::depthFunc (prev_depth);
876  glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
877  }
878  }
879  // Reload old configuration
880  _state.pop_modelview_matrix();
881 
882  }
883 
884  if (pickShader)
885  pickShader->disable();
886 }
887 
888 //----------------------------------------------------------------------------
889 
890 void CoordsysNode::clearPickArea(GLState& _state, bool _draw, GLfloat _depth, GLSL::Program* _pickShader)
891 {
892  GLenum prev_depth = _state.depthFunc();
893 
894  std::vector<Vec2f> points;
895  Vec2f center;
896  float radius;
897 
898  int left, bottom, width, height;
899  _state.get_viewport(left, bottom, width, height);
900 
901  GLboolean colorMask[4];
902  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
903 
904  // respect sphere radius
905  Vec3d proj = _state.project (Vec3d (-0.01, -0.01, -0.01));
906  points.push_back (Vec2f (proj[0], proj[1]));
907 
908  proj = _state.project (Vec3d (0.1, 0.0, 0.0));
909  points.push_back (Vec2f (proj[0], proj[1]));
910 
911  proj = _state.project (Vec3d (0.0, 0.1, 0.0));
912  points.push_back (Vec2f (proj[0], proj[1]));
913 
914  proj = _state.project (Vec3d (0.0, 0.0, 0.1));
915  points.push_back (Vec2f (proj[0], proj[1]));
916 
917 
918  // get bounding circle of projected 4 points of the coord node
919  boundingCircle(points, center, radius);
920 
921  _state.push_projection_matrix();
922  _state.reset_projection();
923 
924  _state.ortho (left, left + width, bottom, bottom + height, 0.0, 1.0);
925 
926  _state.push_modelview_matrix();
927  _state.reset_modelview();
928  ACG::GLState::depthFunc (GL_ALWAYS);
929  ACG::GLState::depthRange (_depth, _depth);
930  _state.translate (center[0], center[1], -0.5);
931 
932  if (_draw)
933  {
934  if (_pickShader)
935  _pickShader->setUniform("color", _state.pick_get_name_color_norm(0));
936  else
937  _state.pick_set_name(0);
938  }
939  else
940  glColorMask(false, false, false, false);
941 
942 
943  if (_pickShader)
944  {
945  // set transform matrix
946  GLMatrixf mWVP = _state.projection() * _state.modelview();
947  _pickShader->setUniform("mWVP", mWVP);
948  // 10% more to ensure everything is in
949  disk_->setInnerRadius(0.0f);
950  disk_->setOuterRadius(radius * 1.1f);
951  disk_->draw_primitive(_pickShader);
952  }
953  else {
954  // 10% more to ensure everything is in
955  disk_->setInnerRadius(0.0f);
956  disk_->setOuterRadius(radius * 1.1f);
957  disk_->draw_primitive();
958  }
959 
960 
961  ACG::GLState::depthFunc (prev_depth);
962  _state.pop_modelview_matrix();
963  _state.pop_projection_matrix();
964 
965  ACG::GLState::depthRange (0.0, 1.0);
966 
967  if (!_draw)
968  glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
969 }
970 
971 //----------------------------------------------------------------------------
972 
973 void CoordsysNode::boundingCircle(std::vector<Vec2f> &_in, Vec2f &_center, float &_radius)
974 {
975  if (_in.empty())
976  return;
977  if (_in.size () < 2)
978  {
979  _center = _in[0];
980  _radius = 0.0f;
981  return;
982  }
983  bool found = false;
984 
985  // try all circumcircles of all possible lines
986  for (unsigned int i = 0; i < _in.size () - 1; i++)
987  for (unsigned int j = i + 1; j < _in.size (); j++)
988  {
989  Vec2f cen = (_in[i] + _in[j]) * 0.5f;
990  float rad = (_in[i] - cen).length ();
991  bool allin = true;
992 
993  for (unsigned int k = 0; k < _in.size (); k++)
994  if (k != i && k != j && (_in[k] - cen).length () > rad)
995  {
996  allin = false;
997  break;
998  }
999 
1000  if (!allin)
1001  continue;
1002 
1003  if (found)
1004  {
1005  if (rad < _radius)
1006  {
1007  _center = cen;
1008  _radius = rad;
1009  }
1010  }
1011  else
1012  {
1013  found = true;
1014  _center = cen;
1015  _radius = rad;
1016  }
1017  }
1018 
1019  if (found)
1020  return;
1021 
1022  // try all circumcircles of all possible triangles
1023  for (unsigned int i = 0; i < _in.size () - 2; i++)
1024  for (unsigned int j = i + 1; j < _in.size () - 1; j++)
1025  for (unsigned int k = j + 1; k < _in.size (); k++)
1026  {
1027  float v = ((_in[k][0]-_in[j][0])*((_in[i][0]*_in[i][0])+(_in[i][1]*_in[i][1]))) +
1028  ((_in[i][0]-_in[k][0])*((_in[j][0]*_in[j][0])+(_in[j][1]*_in[j][1]))) +
1029  ((_in[j][0]-_in[i][0])*((_in[k][0]*_in[k][0])+(_in[k][1]*_in[k][1])));
1030  float u = ((_in[j][1]-_in[k][1])*((_in[i][0]*_in[i][0])+(_in[i][1]*_in[i][1]))) +
1031  ((_in[k][1]-_in[i][1])*((_in[j][0]*_in[j][0])+(_in[j][1]*_in[j][1]))) +
1032  ((_in[i][1]-_in[j][1])*((_in[k][0]*_in[k][0])+(_in[k][1]*_in[k][1])));
1033  float d = (_in[i][0]*_in[j][1])+(_in[j][0]*_in[k][1])+(_in[k][0]*_in[i][1]) -
1034  (_in[i][0]*_in[k][1])-(_in[j][0]*_in[i][1])-(_in[k][0]*_in[j][1]);
1035  Vec2f cen(0.5 * (u/d), 0.5 * (v/d));
1036  float rad = (_in[i] - cen).length ();
1037  bool allin = true;
1038 
1039  for (unsigned int l = 0; l < _in.size (); l++)
1040  if (l != i && l != j && l != k && (_in[l] - cen).length () > rad)
1041  {
1042  allin = false;
1043  break;
1044  }
1045 
1046  if (!allin)
1047  continue;
1048 
1049  if (found)
1050  {
1051  if (rad < _radius)
1052  {
1053  _center = cen;
1054  _radius = rad;
1055  }
1056  }
1057  else
1058  {
1059  found = true;
1060  _center = cen;
1061  _radius = rad;
1062  }
1063  }
1064 }
1065 
1066 //=============================================================================
1067 } // namespace SceneGraph
1068 } // namespace ACG
1069 //=============================================================================
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
bool color_picking() const
Is color picking active?
Definition: GLState.cc:1141
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:61
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:370
double aspect() const
get aspect ratio
Definition: GLState.cc:877
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1026
bool inZPrePass
Specify whether this object should be rendered in a z-prepass.
void use()
Enables the program object for using.
Definition: GLSLShader.cc:345
ProjectionMode
projection mode
Definition: CoordsysNode.hh:88
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:102
Namespace providing different geometric functions concerning angles.
void push_projection_matrix()
push projection matrix
Definition: GLState.cc:971
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:926
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw Coordsys
void setProjectionMode(const ProjectionMode _mode)
set mode to either ORTHOGRAPHIC_PROJECTION or PERSPECTIVE_PROJECTION
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:816
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
void clearTextures()
disables texture support and removes all texture types
void scale(double _s)
scale by (_s, _s, _s)
Definition: GLState.hh:750
Vec4f pick_get_name_color_norm(unsigned int _idx)
same as pick_get_name_color, but the resulting color channels are normalized in [0.0, 1.0] range
Definition: GLState.cc:1077
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:941
GLMatrixd proj
Projection transform.
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
bool overlay
Layer based rendering.
Scalar * data()
access to Scalar array
Definition: Vector11T.hh:200
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:334
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
Vec2f depthRange
glDepthRange: (znear, zmax)
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:651
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1010
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:728
CoordsysNode(BaseNode *_parent=0, std::string _name="<TextNode>", CoordsysMode _mode=SCREENPOS, ProjectionMode _projectionMode=PERSPECTIVE_PROJECTION)
Definition: CoordsysNode.cc:68
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:448
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:119
GLSL program class.
Definition: GLSLShader.hh:211
const GLMatrixd & inverse_projection() const
get inverse projection matrix
Definition: GLState.hh:806
Draws the Coordsys at the coordsys origin.
Definition: CoordsysNode.hh:95
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
Definition: ShaderCache.cc:84
Vec3f diffuse
material definitions
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:402
ACG::SceneGraph::DrawModes::DrawMode availableDrawModes() const override
return available draw modes
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat) override
add renderobjects for shader pipeline renderer
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
Definition: ShaderCache.cc:102
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:385
void disable()
Resets to standard rendering pipeline.
Definition: GLSLShader.cc:355
void pop_projection_matrix()
pop projection matrix
Definition: GLState.cc:989
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:73
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
Definition: GLState.cc:564
int priority
Priority to allow sorting of objects.
CoordsysMode getMode() const
get current mode
void setPosition(const Vec3f &_pos)
set position of the coordsys
Draws the Coordsys at the upper right position on the screen.
Definition: CoordsysNode.hh:96
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
Definition: DrawModes.cc:74
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1061
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:791
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:786
DrawMode POINTS_SHADED
draw shaded points (requires point normals)
Definition: DrawModes.cc:75
const Scalar * get_raw_data() const
Definition: Matrix4x4T.hh:256
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
ProjectionMode getProjectionMode() const
get current projection mode
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
void pick(GLState &_state, PickTarget _target) override
draw Coordsys for object picking
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:533
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
void setMode(const CoordsysMode _mode)
set mode to either POSITION or SCREENPOS
GLMatrixd modelview
Modelview transform.