Developer Documentation
Loading...
Searching...
No Matches
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
61namespace ACG {
62namespace SceneGraph {
63
64
65//== IMPLEMENTATION ==========================================================
66
67
68CoordsysNode::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
84CoordsysNode::~CoordsysNode() {
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
98void
100boundingBox(Vec3d& /*_bbMin*/, Vec3d& /*_bbMax*/)
101{
102 //_bbMin.minimize( Vect3f )
103}
104
105
106//----------------------------------------------------------------------------
107
108
117
118
119//----------------------------------------------------------------------------
120
121void
122CoordsysNode::
123drawCoordsys( 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
179void 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
249void
250CoordsysNode::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
378void
380draw(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
525void 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
649void
650CoordsysNode::
651setMode(const CoordsysMode _mode)
652{
653 mode_ = _mode;
654}
655
656void
657CoordsysNode::
658setProjectionMode(const ProjectionMode _mode)
659{
660 projectionMode_ = _mode;
661}
662
663void
664CoordsysNode::
665setPosition(const Vec3f& _pos)
666{
667 pos3f_ = _pos;
668}
669
670CoordsysNode::CoordsysMode
671CoordsysNode::
672getMode() const
673{
674 return mode_;
675}
676
677CoordsysNode::ProjectionMode
678CoordsysNode::
679getProjectionMode() const
680{
681 return projectionMode_;
682}
683
684void
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
890void 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
973void 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)
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition GLState.cc:402
Vec4f pick_get_name_color_norm(unsigned int _idx)
same as pick_get_name_color, but the resulting color channels are normalized in [0....
Definition GLState.cc:1077
void pop_modelview_matrix()
pop modelview matrix
Definition GLState.cc:1026
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition GLState.cc:1507
void pop_projection_matrix()
pop projection matrix
Definition GLState.cc:989
const GLMatrixd & modelview() const
get modelview matrix
Definition GLState.hh:816
bool color_picking() const
Is color picking active?
Definition GLState.cc:1141
void push_projection_matrix()
push projection matrix
Definition GLState.cc:971
void reset_modelview()
reset modelview matrix (load identity)
Definition GLState.cc:370
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition GLState.cc:1061
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition GLState.hh:951
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition GLState.cc:1051
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition GLState.cc:533
void reset_projection()
reset projection matrix (load identity)
Definition GLState.cc:334
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition GLState.cc:448
const GLMatrixd & projection() const
get projection matrix
Definition GLState.hh:811
void set_modelview(const GLMatrixd &_m)
set modelview
Definition GLState.hh:753
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition GLState.cc:651
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition GLState.cc:640
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition GLState.cc:1757
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
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition GLState.hh:841
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition GLState.cc:1729
double aspect() const
get aspect ratio
Definition GLState.cc:877
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition GLState.cc:941
void push_modelview_matrix()
push modelview matrix
Definition GLState.cc:1010
const GLMatrixd & inverse_projection() const
get inverse projection matrix
Definition GLState.hh:831
const Scalar * get_raw_data() const
virtual void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
Deferred draw call with shader based renderer.
Definition BaseNode.hh:210
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw Coordsys
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
ACG::SceneGraph::DrawModes::DrawMode availableDrawModes() const override
return available draw modes
void pick(GLState &_state, PickTarget _target) override
draw Coordsys for object picking
@ SCREENPOS
Draws the Coordsys at the upper right position on the screen.
@ POSITION
Draws the Coordsys at the coordsys origin.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
void clearTextures()
disables texture support and removes all texture types
GLSL program class.
void disable()
Resets to standard rendering pipeline.
void use()
Enables the program object for using.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Scalar * data()
access to Scalar array
Definition Vector11T.hh:201
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
Definition DrawModes.cc:74
DrawMode POINTS
draw unlighted points using the default base color
Definition DrawModes.cc:73
DrawMode POINTS_SHADED
draw shaded points (requires point normals)
Definition DrawModes.cc:75
PickTarget
What target to use for picking.
Definition PickTarget.hh:74
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition PickTarget.hh:84
Namespace providing different geometric functions concerning angles.
GLMatrixT< float > GLMatrixf
typedef
Definition GLMatrixT.hh:322
VectorT< float, 3 > Vec3f
Definition VectorT.hh:119
VectorT< float, 2 > Vec2f
Definition VectorT.hh:102
Interface class between scenegraph and renderer.
Vec3f diffuse
material definitions
ShaderGenDesc shaderDesc
Drawmode and other shader params.
int priority
Priority to allow sorting of objects.
GLMatrixd modelview
Modelview transform.
GLMatrixd proj
Projection transform.
bool inZPrePass
Specify whether this object should be rendered in a z-prepass.
bool overlay
Layer based rendering.
Vec2f depthRange
glDepthRange: (znear, zmax)
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..