CoordsysNode.cc 27.1 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 5 6 7
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
Jan Möbius's avatar
Jan Möbius committed
8 9
 *                                                                           *
 *---------------------------------------------------------------------------*
Jan Möbius's avatar
Jan Möbius committed
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 37 38
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39 40 41 42 43
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
44
 *   $Revision$                                                       *
Jan Möbius's avatar
Jan Möbius committed
45 46 47 48
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
49 50 51 52 53 54 55 56 57 58 59 60 61




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

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

#include "CoordsysNode.hh"
62
#include <ACG/GL/gl.hh>
63
#include <ACG/GL/IRenderer.hh>
64

Jan Möbius's avatar
 
Jan Möbius committed
65
#include <iostream>
66
#include <cmath>
Jan Möbius's avatar
 
Jan Möbius committed
67 68 69 70 71 72 73 74 75 76 77


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

namespace ACG {
namespace SceneGraph {


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


78 79 80 81 82 83 84 85 86 87 88 89
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
90
  cone_     = new ACG::GLCone(slices, stacks, 0, topRadius , false,true);
Jan Möbius's avatar
Jan Möbius committed
91
  disk_     = new ACG::GLDisk(slices, 10, 0.0f, bodyRadius);
92 93
}

Jan Möbius's avatar
Jan Möbius committed
94 95 96 97 98 99 100 101 102 103 104 105 106
CoordsysNode::~CoordsysNode() {
  if (sphere_)
    delete sphere_;

  if (cylinder_)
    delete cylinder_;

  if (cone_)
    delete cone_;

  if (disk_)
    delete disk_;
}
107

Jan Möbius's avatar
 
Jan Möbius committed
108 109
void
CoordsysNode::
110
boundingBox(Vec3d& /*_bbMin*/, Vec3d& /*_bbMax*/)
Jan Möbius's avatar
 
Jan Möbius committed
111 112 113 114 115 116 117 118
{
	//_bbMin.minimize( Vect3f  )
}


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


Jan Möbius's avatar
Jan Möbius committed
119
DrawModes::DrawMode
Jan Möbius's avatar
 
Jan Möbius committed
120
CoordsysNode::
Jan Möbius's avatar
Jan Möbius committed
121
availableDrawModes() const
Jan Möbius's avatar
 
Jan Möbius committed
122 123 124 125 126 127 128 129 130 131 132 133 134
{
  return ( DrawModes::POINTS |
	        DrawModes::POINTS_SHADED |
	        DrawModes::POINTS_COLORED );
}


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

void
CoordsysNode::
drawCoordsys( GLState&  _state) {

135 136 137
  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;
Jan Möbius's avatar
 
Jan Möbius committed
138

139 140 141

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

Jan Möbius's avatar
 
Jan Möbius committed
142
  // Origin
143 144 145
  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());
146
  sphere_->draw(_state,sphereRadius);
147
  
Jan Möbius's avatar
 
Jan Möbius committed
148
  // X-Axis
149 150 151 152
  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
153 154 155
  _state.push_modelview_matrix ();
  _state.rotate (-90, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
156
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
157
  _state.translate ( 0, 0, -arrowLength );
158
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
159
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
 
Jan Möbius committed
160 161

  // Y-Axis
162 163 164 165
  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
166 167 168
  _state.push_modelview_matrix ();
  _state.rotate (90, 1, 0, 0);
  _state.translate ( 0, 0, -bodyLength );
169
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
170
  _state.translate ( 0, 0, -arrowLength );
171
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
172
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
 
Jan Möbius committed
173 174

  // Z-Axis
175 176 177 178
  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
179 180 181
  _state.push_modelview_matrix ();
  _state.rotate (180, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
182
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
183
  _state.translate ( 0, 0, -arrowLength );
184
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
185
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
 
Jan Möbius committed
186 187 188

}

189 190 191
void CoordsysNode::drawCoordsys(IRenderer* _renderer, RenderObject* _baseRO)
{
  // save model view matrix
Jan Möbius's avatar
Jan Möbius committed
192
  const GLMatrixd mModelView = _baseRO->modelview;
193 194 195 196 197 198 199 200


  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;


  // Origin
201
  _baseRO->debugName = "coordsys.sphere";
202 203 204 205 206
  _baseRO->emissive = Vec3f(1.0f, 1.0f, 1.0f);
  sphere_->addToRenderer(_renderer, _baseRO, sphereRadius);


  // X-Axis
207
  _baseRO->debugName = "coordsys.x.axis";
208 209 210 211 212 213
  _baseRO->emissive = Vec3f(1.0f, 0.0f, 0.0f);
  _baseRO->modelview = mModelView;
  _baseRO->modelview.rotate (-90, 0, 1, 0);
  _baseRO->modelview.translate ( 0, 0, -bodyLength );
  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);
  
214
  _baseRO->debugName = "coordsys.x.head";
215 216 217 218 219
  _baseRO->modelview.translate ( 0, 0, -arrowLength );
  cone_->addToRenderer(_renderer, _baseRO, arrowLength);


  // Y-Axis
220
  _baseRO->debugName = "coordsys.y.axis";
221 222 223 224 225 226
  _baseRO->emissive = Vec3f(0.0f, 1.0f, 0.0f);
  _baseRO->modelview = mModelView;
  _baseRO->modelview.rotate (90, 1, 0, 0);
  _baseRO->modelview.translate ( 0, 0, -bodyLength );
  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);

227
  _baseRO->debugName = "coordsys.y.head";
228 229 230 231 232
  _baseRO->modelview.translate ( 0, 0, -arrowLength );
  cone_->addToRenderer(_renderer, _baseRO, arrowLength);


  // Z-Axis
233
  _baseRO->debugName = "coordsys.z.axis";
234 235 236 237 238 239
  _baseRO->emissive = Vec3f(0.0f, 0.0f, 1.0f);
  _baseRO->modelview = mModelView;
  _baseRO->modelview.rotate (180, 0, 1, 0);
  _baseRO->modelview.translate ( 0, 0, -bodyLength );
  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);

240
  _baseRO->debugName = "coordsys.z.head";
241 242 243 244
  _baseRO->modelview.translate ( 0, 0, -arrowLength );
  cone_->addToRenderer(_renderer, _baseRO, arrowLength);
}

Jan Möbius's avatar
 
Jan Möbius committed
245 246 247 248 249
//============================================================================

void
CoordsysNode::drawCoordsysPick( GLState&  _state) {

250 251 252
  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;
Jan Möbius's avatar
 
Jan Möbius committed
253 254

  // Origin
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
255
  _state.pick_set_name (1);
256
  sphere_->draw(_state,sphereRadius);
Jan Möbius's avatar
 
Jan Möbius committed
257 258

  // X-Axis
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
259 260 261 262
  _state.pick_set_name (2);
  _state.push_modelview_matrix ();
  _state.rotate (-90, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
263
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
264
  _state.translate ( 0, 0, -arrowLength );
265
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
266
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
 
Jan Möbius committed
267

268

Jan Möbius's avatar
 
Jan Möbius committed
269
  // Y-Axis
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
270 271 272 273
  _state.pick_set_name (3);
  _state.push_modelview_matrix ();
  _state.rotate (90, 1, 0, 0);
  _state.translate ( 0, 0, -bodyLength );
274
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
275
  _state.translate ( 0, 0, -arrowLength );
276
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
277
  _state.pop_modelview_matrix ();
Jan Möbius's avatar
 
Jan Möbius committed
278 279

  // Z-Axis
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
280 281 282 283
  _state.pick_set_name (4);
  _state.push_modelview_matrix ();
  _state.rotate (180, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
284
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
285
  _state.translate ( 0, 0, -arrowLength );
286
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
287 288
  _state.pop_modelview_matrix ();

Jan Möbius's avatar
 
Jan Möbius committed
289 290 291 292 293 294 295 296
}


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


void
CoordsysNode::
297
draw(GLState&  _state  , const DrawModes::DrawMode& /*_drawMode*/)
Jan Möbius's avatar
 
Jan Möbius committed
298
{
299 300
  GLenum prev_depth = _state.depthFunc();
    
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
301 302 303
  GLboolean colorMask[4];
  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
  
Jan Möbius's avatar
 
Jan Möbius committed
304 305 306 307 308 309
  // Push Modelview-Matrix
  _state.push_modelview_matrix();

  Vec4f lastBaseColor = _state.base_color();

  glPushAttrib( GL_LIGHTING_BIT ); // STACK_ATTRIBUTES <- LIGHTING_ATTRIBUTE
310
  ACG::GLState::enable(GL_LIGHTING);
Jan Möbius's avatar
 
Jan Möbius committed
311
  glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
312 313
  ACG::GLState::enable(GL_COLOR_MATERIAL);
  ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
 
Jan Möbius committed
314

315 316 317 318
  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
319 320 321 322 323 324
  // Init state - changes when mode_ != POSITION
  Vec3d pos3D(0.0,0.0,0.0);

  if ( mode_ == SCREENPOS ) {

    int left, bottom, width, height;
325
    double aspect = _state.aspect();
326

Jan Möbius's avatar
 
Jan Möbius committed
327 328 329 330
    _state.get_viewport(left, bottom, width, height);

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

333 334 335
    if (projectionMode_ == PERSPECTIVE_PROJECTION)
        _state.perspective(45.0, aspect, 0.8, 20.0);
    else
336
        _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
337

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
338 339
    _state.push_modelview_matrix();
    _state.reset_modelview();
Jan Möbius's avatar
 
Jan Möbius committed
340

341 342 343 344 345 346
    float rel_size = 50.0;
    float projdist = sqrt ( (width*height) / rel_size );

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

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

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
351
    // reset scene translation
352
    // we want only the scene rotation to rotate the coordsys
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
353
    GLMatrixd modelview = _state.modelview();
Jan Möbius's avatar
 
Jan Möbius committed
354

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
355 356 357
    modelview(0,3) = 0.0;
    modelview(1,3) = 0.0;
    modelview(2,3) = 0.0;
Jan Möbius's avatar
 
Jan Möbius committed
358

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

362 363

    // clear the depth buffer behind the coordsys
Jan Möbius's avatar
Jan Möbius committed
364
    ACG::GLState::depthRange (1.0, 1.0);
365
    ACG::GLState::depthFunc (GL_ALWAYS);
366 367

    drawCoordsys(_state);
368

Jan Möbius's avatar
Jan Möbius committed
369
    ACG::GLState::depthRange (0.0, 1.0);
370
    ACG::GLState::depthFunc (GL_LESS);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
371

372
    // draw coordsys
Jan Möbius's avatar
 
Jan Möbius committed
373 374
    drawCoordsys(_state);

375
    // set depth buffer to 0 so that nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
376
    ACG::GLState::depthRange (0.0, 0.0);
377
    ACG::GLState::depthFunc (GL_ALWAYS);
378
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
379

380 381 382
    // Koordinatensystem zeichnen
    drawCoordsys(_state);

Jan Möbius's avatar
Jan Möbius committed
383
    ACG::GLState::depthRange (0.0, 1.0);
384
    ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
385
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
386

Jan Möbius's avatar
 
Jan Möbius committed
387 388
    // Projection reload
    _state.pop_projection_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
389

Jan Möbius's avatar
 
Jan Möbius committed
390 391 392

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

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
393 394 395 396 397 398 399
    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
400

401
    // clear depth buffer in coordsys region
Jan Möbius's avatar
Jan Möbius committed
402
    ACG::GLState::depthRange (1.0, 1.0);
403
    ACG::GLState::depthFunc (GL_ALWAYS);
404 405 406 407 408

    // Koordinatensystem zeichnen
    drawCoordsys(_state);

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

412
    // Koordinatensystem zeichnen
Jan Möbius's avatar
 
Jan Möbius committed
413 414
    drawCoordsys(_state);

415
    // set depth buffer to 0 so that nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
416
    ACG::GLState::depthRange (0.0, 0.0);
417
    ACG::GLState::depthFunc (GL_ALWAYS);
418 419 420 421
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

    // Koordinatensystem zeichnen
    drawCoordsys(_state);
422

423
    // reset to default
Jan Möbius's avatar
Jan Möbius committed
424
    ACG::GLState::depthRange (0.0, 1.0);
425
    ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
426
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
Jan Möbius's avatar
 
Jan Möbius committed
427 428 429 430 431 432 433 434 435 436 437
  }

  glPopAttrib();

  glColor4fv(lastBaseColor.data());

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


438 439 440 441




442
void CoordsysNode::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
443 444 445 446 447 448 449 450 451 452
{
  // Init state - changes when mode_ != POSITION
  Vec3d pos3D(0.0,0.0,0.0);

  _state.push_modelview_matrix();


  // init base renderobject
  RenderObject ro;
  ro.initFromState(&_state);
453
  ro.setMaterial(_mat);
454 455 456 457


  ro.depthTest = true;
  ro.depthWrite = true;
458
  ro.inZPrePass = false;
459
  ro.overlay = true;
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507

  if ( mode_ == SCREENPOS ) {

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

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

    // Projection reset
    _state.push_projection_matrix();
    _state.reset_projection();

    if (projectionMode_ == PERSPECTIVE_PROJECTION)
      _state.perspective(45.0, aspect, 0.8, 20.0);
    else
      _state.ortho(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 0.8, 20.0);

    _state.push_modelview_matrix();
    _state.reset_modelview();

    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
    pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
    _state.pop_modelview_matrix();

    // reset scene translation
    // we want only the scene rotation to rotate the coordsys
    GLMatrixd modelview = _state.modelview();

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

    _state.set_modelview (modelview);
    _state.translate (pos3D[0], pos3D[1], pos3D[2], MULT_FROM_LEFT);


    // grab new transforms
    ro.proj = _state.projection();
    ro.modelview = _state.modelview();

    // colored by emission only
    ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
508
    ro.shaderDesc.clearTextures();
509 510 511 512 513 514 515
    ro.shaderDesc.vertexColors = false;



    // regrab of transforms needed, drawCoordsys overwrites this
    ro.modelview = _state.modelview();

516
    ro.priority = 3;
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
    ro.depthRange = Vec2f(0.0f, 1.0f);
    ro.depthFunc = GL_LESS;

    // draw coordsys
    drawCoordsys(_renderer, &ro);


    // Projection reload
    _state.pop_projection_matrix();

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

    GLMatrixd modelview = _state.modelview();

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

    _state.set_modelview (modelview);

    // clear depth buffer in coordsys region
    ACG::GLState::depthRange (1.0, 1.0);
    ACG::GLState::depthFunc (GL_ALWAYS);

    // Koordinatensystem zeichnen
    drawCoordsys(_renderer, &ro);

    // draw coordsys in normal mode
    ACG::GLState::depthRange (0.0, 1.0);
    ACG::GLState::depthFunc (GL_LESS);

    // Koordinatensystem zeichnen
    drawCoordsys(_renderer, &ro);

    // set depth buffer to 0 so that nothing can paint over cordsys
    ACG::GLState::depthRange (0.0, 0.0);
    ACG::GLState::depthFunc (GL_ALWAYS);
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

    // Koordinatensystem zeichnen
    drawCoordsys(_renderer, &ro);
  }


  _state.pop_modelview_matrix();
}



Jan Möbius's avatar
 
Jan Möbius committed
566 567 568 569 570 571 572
void
CoordsysNode::
setMode(const CoordsysMode _mode)
{
  mode_ = _mode;
}

573 574 575 576 577 578 579
void
CoordsysNode::
setProjectionMode(const ProjectionMode _mode)
{
  projectionMode_ = _mode;
}

Jan Möbius's avatar
 
Jan Möbius committed
580 581 582 583 584 585 586 587 588 589 590 591 592 593
void
CoordsysNode::
setPosition(const Vec3f& _pos)
{
  pos3f_ = _pos;
}

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

594 595 596 597 598 599 600
CoordsysNode::ProjectionMode
CoordsysNode::
getProjectionMode() const
{
  return projectionMode_;
}

Jan Möbius's avatar
 
Jan Möbius committed
601 602 603
void
CoordsysNode::pick(GLState& _state, PickTarget _target)
{
604 605
  GLenum prev_depth = _state.depthFunc();  
    
Jan Möbius's avatar
Jan Möbius committed
606 607
  if (_target == PICK_ANYTHING) {

Jan Möbius's avatar
Jan Möbius committed
608 609
    GLdouble mat[16];

Jan Möbius's avatar
 
Jan Möbius committed
610
    // Push Modelview-Matrix
Jan Möbius's avatar
Jan Möbius committed
611
    _state.push_modelview_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
612
    _state.pick_set_maximum (5);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
613
    _state.pick_set_name (0);
Jan Möbius's avatar
 
Jan Möbius committed
614 615

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

Jan Möbius's avatar
Jan Möbius committed
618
    if ( mode_ == SCREENPOS ) {
Jan Möbius's avatar
 
Jan Möbius committed
619

Jan Möbius's avatar
Jan Möbius committed
620
      int left, bottom, width, height;
621
      double aspect = _state.aspect();
622

Jan Möbius's avatar
Jan Möbius committed
623
      _state.get_viewport(left, bottom, width, height);
624
      
Jan Möbius's avatar
Jan Möbius committed
625 626
      // Projection reset
      _state.push_projection_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
627
      _state.reset_projection();
Jan Möbius's avatar
 
Jan Möbius committed
628

629 630 631
      if (projectionMode_ == PERSPECTIVE_PROJECTION)
        _state.perspective(45.0, aspect, 0.8, 20.0);
      else
632
        _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
633

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
634 635
      _state.push_modelview_matrix();
      _state.reset_modelview();
Jan Möbius's avatar
 
Jan Möbius committed
636

637 638 639 640 641 642 643
      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
644 645
      pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
      _state.pop_modelview_matrix();
Jan Möbius's avatar
 
Jan Möbius committed
646

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
647 648
      // reset scene translation
      GLMatrixd modelview = _state.modelview();
Jan Möbius's avatar
 
Jan Möbius committed
649

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
650 651 652
      modelview(0,3) = 0.0;
      modelview(1,3) = 0.0;
      modelview(2,3) = 0.0;
Jan Möbius's avatar
 
Jan Möbius committed
653

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

657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
      // 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
673
        ACG::GLState::depthRange (1.0, 1.0);
674
        ACG::GLState::depthFunc (GL_ALWAYS);
675 676 677 678 679

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
680
        ACG::GLState::depthRange (0.0, 1.0);
681
        ACG::GLState::depthFunc (GL_LESS);
682 683 684 685 686

        // 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
687
        ACG::GLState::depthRange (0.0, 0.0);
688
        ACG::GLState::depthFunc (GL_ALWAYS);
689 690 691 692 693 694
        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
695
        ACG::GLState::depthRange (0.0, 1.0);
696
        ACG::GLState::depthFunc (prev_depth);
697 698
        glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      }
Jan Möbius's avatar
Jan Möbius committed
699

700 701
      // Projection reload
      _state.pop_projection_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
702

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

705 706 707
      // 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
708 709 710 711 712 713 714 715 716 717 718 719 720
      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
721 722 723 724 725 726
      GLMatrixd modelview = _state.modelview();

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

727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
      // 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
743
        ACG::GLState::depthRange (1.0, 1.0);
744
        ACG::GLState::depthFunc (GL_ALWAYS);
745 746 747 748 749

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
750
        ACG::GLState::depthRange (0.0, 1.0);
751
        ACG::GLState::depthFunc (GL_LESS);
752 753 754 755 756

        // 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
757
        ACG::GLState::depthRange (0.0, 0.0);
758
        ACG::GLState::depthFunc (GL_ALWAYS);
759 760 761 762 763 764
        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
765
        ACG::GLState::depthRange (0.0, 1.0);
766
        ACG::GLState::depthFunc (prev_depth);
767 768
        glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      }
Jan Möbius's avatar
 
Jan Möbius committed
769
    }
Jan Möbius's avatar
Jan Möbius committed
770 771 772 773
    // Reload old configuration
    _state.pop_modelview_matrix();

  }
Jan Möbius's avatar
 
Jan Möbius committed
774 775
}

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
776 777
//----------------------------------------------------------------------------

778
void CoordsysNode::clearPickArea(GLState&  _state, bool _draw, GLfloat _depth)
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
779
{
780 781
  GLenum prev_depth = _state.depthFunc();
    
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
782 783 784 785 786 787 788
  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
789 790 791
  GLboolean colorMask[4];
  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
  // 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
811

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
812 813 814 815
  _state.ortho (left, left + width, bottom, bottom + height, 0.0, 1.0);

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

820
  if (_draw)
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
821 822 823 824 825
    _state.pick_set_name (0);
  else
    glColorMask(false, false, false, false);

  // 10% more to ensure everything is in
Jan Möbius's avatar
Jan Möbius committed
826 827 828
  disk_->setInnerRadius(0.0f);
  disk_->setOuterRadius(radius * 1.1f);
  disk_->draw(_state);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
829

830
  ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
831 832 833
  _state.pop_modelview_matrix();
  _state.pop_projection_matrix();

Jan Möbius's avatar
Jan Möbius committed
834
  ACG::GLState::depthRange (0.0, 1.0);
835 836

  if (!_draw)
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
837
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
838 839 840 841 842 843
}

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

void CoordsysNode::boundingCircle(std::vector<Vec2f> &_in, Vec2f &_center, float &_radius)
{
Jan Möbius's avatar
Jan Möbius committed
844
  if (_in.empty())
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
    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
935 936 937 938
//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================