CoordsysNode.cc 21.5 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  OpenFlipper is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenFlipper is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37
 *   $Revision$                                                       *
Jan Möbius's avatar
Jan Möbius committed
38
39
40
41
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
   
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51
52
53
54




//=============================================================================
//
//  CLASS CoordsysNode - IMPLEMENTATION
//
//=============================================================================

//== INCLUDES =================================================================

#include "CoordsysNode.hh"
55
56
#include <ACG/GL/gl.hh>

Jan Möbius's avatar
   
Jan Möbius committed
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <math.h>


//== NAMESPACES ===============================================================

namespace ACG {
namespace SceneGraph {


//== IMPLEMENTATION ==========================================================


70
71
72
73
74
75
76
77
78
79
80
81
CoordsysNode::CoordsysNode(BaseNode* _parent, std::string _name, CoordsysMode _mode, ProjectionMode _projectionMode) :
        BaseNode(_parent, _name),
        mode_(_mode),
        projectionMode_(_projectionMode)
{
  const double bodyRadius = 0.004;
  const double topRadius = 0.01;
  const int slices = 10;
  const int stacks = 10;

  sphere_   = new ACG::GLSphere(slices,stacks);
  cylinder_ = new ACG::GLCylinder(slices, stacks, bodyRadius,false,false);
Jan Möbius's avatar
Jan Möbius committed
82
  cone_     = new ACG::GLCone(slices, stacks, 0, topRadius , false,true);
83
84
85
}


Jan Möbius's avatar
   
Jan Möbius committed
86
87
void
CoordsysNode::
88
boundingBox(Vec3d& /*_bbMin*/, Vec3d& /*_bbMax*/)
Jan Möbius's avatar
   
Jan Möbius committed
89
90
91
92
93
94
95
96
{
	//_bbMin.minimize( Vect3f  )
}


//----------------------------------------------------------------------------


Jan Möbius's avatar
Jan Möbius committed
97
DrawModes::DrawMode
Jan Möbius's avatar
   
Jan Möbius committed
98
CoordsysNode::
Jan Möbius's avatar
Jan Möbius committed
99
availableDrawModes() const
Jan Möbius's avatar
   
Jan Möbius committed
100
101
102
103
104
105
106
107
108
109
110
111
112
{
  return ( DrawModes::POINTS |
	        DrawModes::POINTS_SHADED |
	        DrawModes::POINTS_COLORED );
}


//----------------------------------------------------------------------------

void
CoordsysNode::
drawCoordsys( GLState&  _state) {

113
114
115
  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;
Jan Möbius's avatar
   
Jan Möbius committed
116

117
118
119

  ACG::Vec4f matCol(0.5f, 0.5f, 0.5f, 1.0f);

Jan Möbius's avatar
   
Jan Möbius committed
120
  // Origin
121
122
123
  glColor4f(0.5, 0.5, 0.5 , 1.0);
  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.5f).data());
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
124
  sphere_->draw(_state,sphereRadius);
125
  
Jan Möbius's avatar
   
Jan Möbius committed
126
  // X-Axis
127
128
129
130
  glColor4f(1.0, 0.0, 0.0, 1.0);
  matCol[0] = 1.0f;  matCol[1] = 0.0f; matCol[2] = 0.0f;
  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.5f).data());
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
131
132
133
  _state.push_modelview_matrix ();
  _state.rotate (-90, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
134
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
135
  _state.translate ( 0, 0, -arrowLength );
136
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
137
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
   
Jan Möbius committed
138
139

  // Y-Axis
140
141
142
143
  glColor4f(0.0, 1.0, 0.0, 1.0);
  matCol[0] = 0.0f;  matCol[1] = 1.0f; matCol[2] = 0.0f;
  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.2f).data());
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
144
145
146
  _state.push_modelview_matrix ();
  _state.rotate (90, 1, 0, 0);
  _state.translate ( 0, 0, -bodyLength );
147
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
148
  _state.translate ( 0, 0, -arrowLength );
149
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
150
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
   
Jan Möbius committed
151
152

  // Z-Axis
153
154
155
156
  glColor4f(0.0, 0.0, 1.0, 1.0);
  matCol[0] = 0.0f;  matCol[1] = 0.0f; matCol[2] = 1.0f;
  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (matCol * 0.5f).data());
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matCol.data());
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
157
158
159
  _state.push_modelview_matrix ();
  _state.rotate (180, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
160
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
161
  _state.translate ( 0, 0, -arrowLength );
162
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
163
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
   
Jan Möbius committed
164
165
166
167
168
169
170
171

}

//============================================================================

void
CoordsysNode::drawCoordsysPick( GLState&  _state) {

172
173
174
  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;
Jan Möbius's avatar
   
Jan Möbius committed
175
176

  // Origin
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
177
  _state.pick_set_name (1);
178
  sphere_->draw(_state,sphereRadius);
Jan Möbius's avatar
   
Jan Möbius committed
179
180

  // X-Axis
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
181
182
183
184
  _state.pick_set_name (2);
  _state.push_modelview_matrix ();
  _state.rotate (-90, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
185
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
186
  _state.translate ( 0, 0, -arrowLength );
187
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
188
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
   
Jan Möbius committed
189

190

Jan Möbius's avatar
   
Jan Möbius committed
191
  // Y-Axis
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
192
193
194
195
  _state.pick_set_name (3);
  _state.push_modelview_matrix ();
  _state.rotate (90, 1, 0, 0);
  _state.translate ( 0, 0, -bodyLength );
196
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
197
  _state.translate ( 0, 0, -arrowLength );
198
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
199
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
   
Jan Möbius committed
200
201

  // Z-Axis
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
202
203
204
205
  _state.pick_set_name (4);
  _state.push_modelview_matrix ();
  _state.rotate (180, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
206
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
207
  _state.translate ( 0, 0, -arrowLength );
208
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
209
210
  _state.pop_modelview_matrix ();

Jan Möbius's avatar
   
Jan Möbius committed
211
212
213
214
215
216
217
218
}


//============================================================================


void
CoordsysNode::
219
draw(GLState&  _state  , const DrawModes::DrawMode& /*_drawMode*/)
Jan Möbius's avatar
   
Jan Möbius committed
220
{
221
222
  GLenum prev_depth = _state.depthFunc();
    
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
223
224
225
  GLboolean colorMask[4];
  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
  
Jan Möbius's avatar
   
Jan Möbius committed
226
227
228
229
230
231
  // Push Modelview-Matrix
  _state.push_modelview_matrix();

  Vec4f lastBaseColor = _state.base_color();

  glPushAttrib( GL_LIGHTING_BIT ); // STACK_ATTRIBUTES <- LIGHTING_ATTRIBUTE
232
  ACG::GLState::enable(GL_LIGHTING);
Jan Möbius's avatar
   
Jan Möbius committed
233
  glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
234
235
  ACG::GLState::enable(GL_COLOR_MATERIAL);
  ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
   
Jan Möbius committed
236

237
238
239
240
  GLfloat zeroVec[4] = {0.0f};
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zeroVec);
  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, zeroVec);

Jan Möbius's avatar
   
Jan Möbius committed
241
242
243
244
245
246
  // Init state - changes when mode_ != POSITION
  Vec3d pos3D(0.0,0.0,0.0);

  if ( mode_ == SCREENPOS ) {

    int left, bottom, width, height;
247
    double aspect = _state.aspect();
248

Jan Möbius's avatar
   
Jan Möbius committed
249
250
251
252
    _state.get_viewport(left, bottom, width, height);

    // Projection reset
    _state.push_projection_matrix();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
253
    _state.reset_projection();
Jan Möbius's avatar
   
Jan Möbius committed
254

255
256
257
    if (projectionMode_ == PERSPECTIVE_PROJECTION)
        _state.perspective(45.0, aspect, 0.8, 20.0);
    else
258
        _state.ortho(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 0.8, 20.0);
Jan Möbius's avatar
   
Jan Möbius committed
259

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
260
261
    _state.push_modelview_matrix();
    _state.reset_modelview();
Jan Möbius's avatar
   
Jan Möbius committed
262

263
264
265
266
267
268
    float rel_size = 50.0;
    float projdist = sqrt ( (width*height) / rel_size );

    float posx = left + width - projdist ;
    float posy = bottom + height - projdist ;

269
    // get our desired coordsys position in scene coordinates
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
270
271
    pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
    _state.pop_modelview_matrix();
Jan Möbius's avatar
   
Jan Möbius committed
272

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
273
    // reset scene translation
274
    // we want only the scene rotation to rotate the coordsys
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
275
    GLMatrixd modelview = _state.modelview();
Jan Möbius's avatar
   
Jan Möbius committed
276

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
277
278
279
    modelview(0,3) = 0.0;
    modelview(1,3) = 0.0;
    modelview(2,3) = 0.0;
Jan Möbius's avatar
   
Jan Möbius committed
280

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
281
    _state.set_modelview (modelview);
282
    _state.translate (pos3D[0], pos3D[1], pos3D[2], MULT_FROM_LEFT);
Jan Möbius's avatar
   
Jan Möbius committed
283

284
285

    // clear the depth buffer behind the coordsys
Jan Möbius's avatar
Jan Möbius committed
286
    ACG::GLState::depthRange (1.0, 1.0);
287
    ACG::GLState::depthFunc (GL_ALWAYS);
288
289

    drawCoordsys(_state);
290

Jan Möbius's avatar
Jan Möbius committed
291
    ACG::GLState::depthRange (0.0, 1.0);
292
    ACG::GLState::depthFunc (GL_LESS);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
293

294
    // draw coordsys
Jan Möbius's avatar
   
Jan Möbius committed
295
296
    drawCoordsys(_state);

297
    // set depth buffer to 0 so that nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
298
    ACG::GLState::depthRange (0.0, 0.0);
299
    ACG::GLState::depthFunc (GL_ALWAYS);
300
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
301

302
303
304
    // Koordinatensystem zeichnen
    drawCoordsys(_state);

Jan Möbius's avatar
Jan Möbius committed
305
    ACG::GLState::depthRange (0.0, 1.0);
306
    ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
307
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
308

Jan Möbius's avatar
   
Jan Möbius committed
309
310
    // Projection reload
    _state.pop_projection_matrix();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
311

Jan Möbius's avatar
   
Jan Möbius committed
312
313
314

  } else if (mode_ == POSITION) { /* mode_ == POSITION */

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
315
316
317
318
319
320
321
    GLMatrixd modelview = _state.modelview();

    modelview(0,3) = 0.0;
    modelview(1,3) = 0.0;
    modelview(2,3) = 0.0;

    _state.set_modelview (modelview);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
322

323
    // clear depth buffer in coordsys region
Jan Möbius's avatar
Jan Möbius committed
324
    ACG::GLState::depthRange (1.0, 1.0);
325
    ACG::GLState::depthFunc (GL_ALWAYS);
326
327
328
329
330

    // Koordinatensystem zeichnen
    drawCoordsys(_state);

    // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
331
    ACG::GLState::depthRange (0.0, 1.0);
332
    ACG::GLState::depthFunc (GL_LESS);
333

334
    // Koordinatensystem zeichnen
Jan Möbius's avatar
   
Jan Möbius committed
335
336
    drawCoordsys(_state);

337
    // set depth buffer to 0 so that nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
338
    ACG::GLState::depthRange (0.0, 0.0);
339
    ACG::GLState::depthFunc (GL_ALWAYS);
340
341
342
343
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

    // Koordinatensystem zeichnen
    drawCoordsys(_state);
344

345
    // reset to default
Jan Möbius's avatar
Jan Möbius committed
346
    ACG::GLState::depthRange (0.0, 1.0);
347
    ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
348
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
Jan Möbius's avatar
   
Jan Möbius committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  }

  glPopAttrib();

  glColor4fv(lastBaseColor.data());

  // Reload old configuration
  _state.pop_modelview_matrix();
}


void
CoordsysNode::
setMode(const CoordsysMode _mode)
{
  mode_ = _mode;
}

367
368
369
370
371
372
373
void
CoordsysNode::
setProjectionMode(const ProjectionMode _mode)
{
  projectionMode_ = _mode;
}

Jan Möbius's avatar
   
Jan Möbius committed
374
375
376
377
378
379
380
381
382
383
384
385
386
387
void
CoordsysNode::
setPosition(const Vec3f& _pos)
{
  pos3f_ = _pos;
}

CoordsysNode::CoordsysMode
CoordsysNode::
getMode() const
{
  return mode_;
}

388
389
390
391
392
393
394
CoordsysNode::ProjectionMode
CoordsysNode::
getProjectionMode() const
{
  return projectionMode_;
}

Jan Möbius's avatar
   
Jan Möbius committed
395
396
397
void
CoordsysNode::pick(GLState& _state, PickTarget _target)
{
398
399
  GLenum prev_depth = _state.depthFunc();  
    
Jan Möbius's avatar
Jan Möbius committed
400
401
  if (_target == PICK_ANYTHING) {

Jan Möbius's avatar
Jan Möbius committed
402
403
    GLdouble mat[16];

Jan Möbius's avatar
   
Jan Möbius committed
404
    // Push Modelview-Matrix
Jan Möbius's avatar
Jan Möbius committed
405
    _state.push_modelview_matrix();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
406
    _state.pick_set_maximum (5);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
407
    _state.pick_set_name (0);
Jan Möbius's avatar
   
Jan Möbius committed
408
409

    // Init state - changes when mode_ != POSITION
Jan Möbius's avatar
Jan Möbius committed
410
    Vec3d pos3D(0.0,0.0,0.0);
Jan Möbius's avatar
   
Jan Möbius committed
411

Jan Möbius's avatar
Jan Möbius committed
412
    if ( mode_ == SCREENPOS ) {
Jan Möbius's avatar
   
Jan Möbius committed
413

Jan Möbius's avatar
Jan Möbius committed
414
      int left, bottom, width, height;
415
      double aspect = _state.aspect();
416

Jan Möbius's avatar
Jan Möbius committed
417
      _state.get_viewport(left, bottom, width, height);
418
      
Jan Möbius's avatar
Jan Möbius committed
419
420
      // Projection reset
      _state.push_projection_matrix();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
421
      _state.reset_projection();
Jan Möbius's avatar
   
Jan Möbius committed
422

423
424
425
      if (projectionMode_ == PERSPECTIVE_PROJECTION)
        _state.perspective(45.0, aspect, 0.8, 20.0);
      else
426
        _state.ortho(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 0.8, 20.0);
Jan Möbius's avatar
   
Jan Möbius committed
427

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
428
429
      _state.push_modelview_matrix();
      _state.reset_modelview();
Jan Möbius's avatar
   
Jan Möbius committed
430

431
432
433
434
435
436
437
      float rel_size = 50.0;
      float projdist = sqrt ( (width*height) / rel_size );

      float posx = left + width - projdist ;
      float posy = bottom + height - projdist ;

      // get our desired coordsys position in scene coordinates
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
438
439
      pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
      _state.pop_modelview_matrix();
Jan Möbius's avatar
   
Jan Möbius committed
440

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
441
442
      // reset scene translation
      GLMatrixd modelview = _state.modelview();
Jan Möbius's avatar
   
Jan Möbius committed
443

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
444
445
446
      modelview(0,3) = 0.0;
      modelview(1,3) = 0.0;
      modelview(2,3) = 0.0;
Jan Möbius's avatar
   
Jan Möbius committed
447

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
448
      _state.set_modelview (modelview);
449
      _state.translate (pos3D[0], pos3D[1], pos3D[2], MULT_FROM_LEFT);
Jan Möbius's avatar
   
Jan Möbius committed
450

451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
      // We don't have access to the pick matrix used during selection buffer picking
      // so we can't draw our pick area circle in this case
      if (_state.color_picking ())
      {
        // clear depth buffer behind coordsys node
        clearPickArea(_state, true, 1.0);

        // Koordinatensystem zeichnen
        drawCoordsysPick(_state);

        // set depth buffer to 0.0 so that nothing can paint above
        clearPickArea(_state, false, 0.0);
      }
      else
      {
        // clear depth buffer in coordsys region
Jan Möbius's avatar
Jan Möbius committed
467
        ACG::GLState::depthRange (1.0, 1.0);
468
        ACG::GLState::depthFunc (GL_ALWAYS);
469
470
471
472
473

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
474
        ACG::GLState::depthRange (0.0, 1.0);
475
        ACG::GLState::depthFunc (GL_LESS);
476
477
478
479
480

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // set depth buffer to 0 so tah nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
481
        ACG::GLState::depthRange (0.0, 0.0);
482
        ACG::GLState::depthFunc (GL_ALWAYS);
483
484
485
486
487
488
        glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // reset to default
Jan Möbius's avatar
Jan Möbius committed
489
        ACG::GLState::depthRange (0.0, 1.0);
490
        ACG::GLState::depthFunc (prev_depth);
491
492
        glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      }
Jan Möbius's avatar
Jan Möbius committed
493

494
495
      // Projection reload
      _state.pop_projection_matrix();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
496

Jan Möbius's avatar
Jan Möbius committed
497
498
    } else if (mode_ == POSITION) { /* mode_ == POSITION */

499
500
501
      // The selection buffer picking method might have set a 
      // pick matrix that has been multiplied with the projection matrix.
      // This is the only way to get the gl pick matrix again
Jan Möbius's avatar
Jan Möbius committed
502
503
504
505
506
507
508
509
510
511
512
513
514
      glMatrixMode(GL_PROJECTION);

      glPushMatrix ();
      glMultMatrixd( _state.inverse_projection().get_raw_data());

      glGetDoublev(GL_PROJECTION_MATRIX, mat);

      glPopMatrix ();

      GLMatrixd pickMat (mat);

      glMatrixMode(GL_MODELVIEW);

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
515
516
517
518
519
520
      GLMatrixd modelview = _state.modelview();

      modelview(0,3) = 0.0;
      modelview(1,3) = 0.0;
      modelview(2,3) = 0.0;

521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
      // We don't have access to the pick matrix used during selection buffer picking
      // so we can't draw our pick area circle in this case
      if (_state.color_picking ())
      {
        // clear depth buffer behind coordsys node
        clearPickArea(_state, true, 1.0);

        // Koordinatensystem zeichnen
        drawCoordsysPick(_state);

        // set depth buffer to 0.0 so that nothing can paint above
        clearPickArea(_state, false, 0.0);
      }
      else
      {
        // clear depth buffer in coordsys region
Jan Möbius's avatar
Jan Möbius committed
537
        ACG::GLState::depthRange (1.0, 1.0);
538
        ACG::GLState::depthFunc (GL_ALWAYS);
539
540
541
542
543

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
544
        ACG::GLState::depthRange (0.0, 1.0);
545
        ACG::GLState::depthFunc (GL_LESS);
546
547
548
549
550

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // set depth buffer to 0 so tah nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
551
        ACG::GLState::depthRange (0.0, 0.0);
552
        ACG::GLState::depthFunc (GL_ALWAYS);
553
554
555
556
557
558
        glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // reset to default
Jan Möbius's avatar
Jan Möbius committed
559
        ACG::GLState::depthRange (0.0, 1.0);
560
        ACG::GLState::depthFunc (prev_depth);
561
562
        glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      }
Jan Möbius's avatar
   
Jan Möbius committed
563
    }
Jan Möbius's avatar
Jan Möbius committed
564
565
566
567
    // Reload old configuration
    _state.pop_modelview_matrix();

  }
Jan Möbius's avatar
   
Jan Möbius committed
568
569
}

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
570
571
//----------------------------------------------------------------------------

572
void CoordsysNode::clearPickArea(GLState&  _state, bool _draw, GLfloat _depth)
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
573
{
574
575
  GLenum prev_depth = _state.depthFunc();
    
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
576
577
578
579
580
581
582
  std::vector<Vec2f> points;
  Vec2f center;
  float radius;

  int left, bottom, width, height;
  _state.get_viewport(left, bottom, width, height);

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
583
584
585
  GLboolean colorMask[4];
  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
  GLUquadricObj *quadric = gluNewQuadric();

  // respect sphere radius
  Vec3d proj = _state.project (Vec3d (-0.01, -0.01, -0.01));
  points.push_back (Vec2f (proj[0], proj[1]));

  proj = _state.project (Vec3d (0.1, 0.0, 0.0));
  points.push_back (Vec2f (proj[0], proj[1]));

  proj = _state.project (Vec3d (0.0, 0.1, 0.0));
  points.push_back (Vec2f (proj[0], proj[1]));

  proj = _state.project (Vec3d (0.0, 0.0, 0.1));
  points.push_back (Vec2f (proj[0], proj[1]));


  // get bounding circle of projected 4 points of the coord node
  boundingCircle(points, center, radius);

  _state.push_projection_matrix();
  _state.reset_projection();
Jan Möbius's avatar
Jan Möbius committed
607

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
608
609
610
611
  _state.ortho (left, left + width, bottom, bottom + height, 0.0, 1.0);

  _state.push_modelview_matrix();
  _state.reset_modelview();
612
  ACG::GLState::depthFunc (GL_ALWAYS);
Jan Möbius's avatar
Jan Möbius committed
613
  ACG::GLState::depthRange (_depth, _depth);
614
  _state.translate (center[0], center[1], -0.5);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
615

616
  if (_draw)
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
617
618
619
620
621
622
623
    _state.pick_set_name (0);
  else
    glColorMask(false, false, false, false);

  // 10% more to ensure everything is in
  gluDisk( quadric, 0, radius * 1.1, 10, 10 );

624
  ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
625
626
627
  _state.pop_modelview_matrix();
  _state.pop_projection_matrix();

Jan Möbius's avatar
Jan Möbius committed
628
  ACG::GLState::depthRange (0.0, 1.0);
629
630

  if (!_draw)
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
631
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
632

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
633
634
635
636
637
638
639
  gluDeleteQuadric(quadric);
}

//----------------------------------------------------------------------------

void CoordsysNode::boundingCircle(std::vector<Vec2f> &_in, Vec2f &_center, float &_radius)
{
Jan Möbius's avatar
Jan Möbius committed
640
  if (_in.empty())
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
    return;
  if (_in.size () < 2)
  {
    _center = _in[0];
    _radius = 0.0f;
    return;
  }
  bool found = false;

  // try all circumcircles of all possible lines
  for (unsigned int i = 0; i < _in.size () - 1; i++)
    for (unsigned int j = i + 1; j < _in.size (); j++)
    {
      Vec2f cen = (_in[i] + _in[j]) * 0.5;
      float rad = (_in[i] - cen).length ();
      bool allin = true;

      for (unsigned int k = 0; k < _in.size (); k++)
        if (k != i && k != j && (_in[k] - cen).length () > rad)
        {
          allin = false;
          break;
        }

      if (!allin)
        continue;

      if (found)
      {
        if (rad < _radius)
        {
          _center = cen;
          _radius = rad;
        }
      }
      else
      {
        found = true;
        _center = cen;
        _radius = rad;
      }
    }

  if (found)
    return;

  // try all circumcircles of all possible triangles
  for (unsigned int i = 0; i < _in.size () - 2; i++)
    for (unsigned int j = i + 1; j < _in.size () - 1; j++)
      for (unsigned int k = j + 1; k < _in.size (); k++)
      {
        float v = ((_in[k][0]-_in[j][0])*((_in[i][0]*_in[i][0])+(_in[i][1]*_in[i][1]))) +
                  ((_in[i][0]-_in[k][0])*((_in[j][0]*_in[j][0])+(_in[j][1]*_in[j][1]))) +
                  ((_in[j][0]-_in[i][0])*((_in[k][0]*_in[k][0])+(_in[k][1]*_in[k][1])));
        float u = ((_in[j][1]-_in[k][1])*((_in[i][0]*_in[i][0])+(_in[i][1]*_in[i][1]))) +
                  ((_in[k][1]-_in[i][1])*((_in[j][0]*_in[j][0])+(_in[j][1]*_in[j][1]))) +
                  ((_in[i][1]-_in[j][1])*((_in[k][0]*_in[k][0])+(_in[k][1]*_in[k][1])));
        float d = (_in[i][0]*_in[j][1])+(_in[j][0]*_in[k][1])+(_in[k][0]*_in[i][1]) -
                  (_in[i][0]*_in[k][1])-(_in[j][0]*_in[i][1])-(_in[k][0]*_in[j][1]);
        Vec2f cen(0.5 * (u/d), 0.5 * (v/d));
        float rad = (_in[i] - cen).length ();
        bool allin = true;

        for (unsigned int l = 0; l < _in.size (); l++)
          if (l != i && l != j && l != k && (_in[l] - cen).length () > rad)
          {
            allin = false;
            break;
          }

        if (!allin)
          continue;

        if (found)
        {
          if (rad < _radius)
          {
            _center = cen;
            _radius = rad;
          }
        }
        else
        {
          found = true;
          _center = cen;
          _radius = rad;
        }
      }
}

Jan Möbius's avatar
   
Jan Möbius committed
731
732
733
734
//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================