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 640 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
  gluDeleteQuadric(quadric);
}

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

void CoordsysNode::boundingCircle(std::vector<Vec2f> &_in, Vec2f &_center, float &_radius)
{
  if (_in.size () == 0)
    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
//=============================================================================