CoordsysNode.cc 27.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 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/IRenderer.hh>
63

Jan Möbius's avatar
 
Jan Möbius committed
64 65 66 67 68 69 70 71 72 73

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

namespace ACG {
namespace SceneGraph {


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


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

Jan Möbius's avatar
Jan Möbius committed
90 91 92 93 94 95 96 97 98 99 100 101 102
CoordsysNode::~CoordsysNode() {
  if (sphere_)
    delete sphere_;

  if (cylinder_)
    delete cylinder_;

  if (cone_)
    delete cone_;

  if (disk_)
    delete disk_;
}
103

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


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


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


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

void
CoordsysNode::
drawCoordsys( GLState&  _state) {

131 132 133
  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;
Jan Möbius's avatar
 
Jan Möbius committed
134

135 136 137

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

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

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

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

}

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


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


  // Origin
197
  _baseRO->debugName = "coordsys.sphere";
198 199 200 201
  _baseRO->emissive = Vec3f(0.4f, 0.4f, 0.4f);
  _baseRO->diffuse  = Vec3f(0.3f, 0.3f, 0.3f);
  _baseRO->specular = Vec3f(0.2f, 0.2f, 0.2f);
  _baseRO->ambient  = Vec3f(0.1f, 0.1f, 0.1f);
202 203 204 205
  sphere_->addToRenderer(_renderer, _baseRO, sphereRadius);


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


  // Y-Axis
222
  _baseRO->debugName = "coordsys.y.axis";
223 224 225 226
  _baseRO->emissive = Vec3f(0.0f, 0.5f, 0.0f);
  _baseRO->diffuse  = Vec3f(0.0f, 0.3f, 0.0f);
  _baseRO->specular = Vec3f(0.0f, 0.1f, 0.0f);
  _baseRO->ambient  = Vec3f(0.0f, 0.1f, 0.0f);
227 228 229 230 231
  _baseRO->modelview = mModelView;
  _baseRO->modelview.rotate (90, 1, 0, 0);
  _baseRO->modelview.translate ( 0, 0, -bodyLength );
  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);

232
  _baseRO->debugName = "coordsys.y.head";
233 234 235 236 237
  _baseRO->modelview.translate ( 0, 0, -arrowLength );
  cone_->addToRenderer(_renderer, _baseRO, arrowLength);


  // Z-Axis
238
  _baseRO->debugName = "coordsys.z.axis";
239 240 241 242
  _baseRO->emissive = Vec3f(0.0f, 0.0f, 0.5f);
  _baseRO->diffuse  = Vec3f(0.0f, 0.0f, 0.3f);
  _baseRO->specular = Vec3f(0.0f, 0.0f, 0.1f);
  _baseRO->ambient  = Vec3f(0.0f, 0.0f, 0.1f);
243 244 245 246 247
  _baseRO->modelview = mModelView;
  _baseRO->modelview.rotate (180, 0, 1, 0);
  _baseRO->modelview.translate ( 0, 0, -bodyLength );
  cylinder_->addToRenderer(_renderer, _baseRO, bodyLength);

248
  _baseRO->debugName = "coordsys.z.head";
249 250 251 252
  _baseRO->modelview.translate ( 0, 0, -arrowLength );
  cone_->addToRenderer(_renderer, _baseRO, arrowLength);
}

Jan Möbius's avatar
 
Jan Möbius committed
253 254 255 256 257
//============================================================================

void
CoordsysNode::drawCoordsysPick( GLState&  _state) {

258 259 260
  const double arrowLength  = 0.03;
  const double bodyLength   = 0.06;
  const double sphereRadius = 0.01;
Jan Möbius's avatar
 
Jan Möbius committed
261 262

  // Origin
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
263
  _state.pick_set_name (1);
264
  sphere_->draw(_state,sphereRadius);
Jan Möbius's avatar
 
Jan Möbius committed
265 266

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

276

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

  // Z-Axis
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
288 289 290 291
  _state.pick_set_name (4);
  _state.push_modelview_matrix ();
  _state.rotate (180, 0, 1, 0);
  _state.translate ( 0, 0, -bodyLength );
292
  cylinder_->draw(_state,bodyLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
293
  _state.translate ( 0, 0, -arrowLength );
294
  cone_->draw(_state,arrowLength);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
295 296
  _state.pop_modelview_matrix ();

Jan Möbius's avatar
 
Jan Möbius committed
297 298 299 300 301 302 303 304
}


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


void
CoordsysNode::
305
draw(GLState&  _state  , const DrawModes::DrawMode& /*_drawMode*/)
Jan Möbius's avatar
 
Jan Möbius committed
306
{
307 308
  GLenum prev_depth = _state.depthFunc();
    
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
309 310 311
  GLboolean colorMask[4];
  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
  
Jan Möbius's avatar
 
Jan Möbius committed
312 313 314 315 316 317
  // Push Modelview-Matrix
  _state.push_modelview_matrix();

  Vec4f lastBaseColor = _state.base_color();

  glPushAttrib( GL_LIGHTING_BIT ); // STACK_ATTRIBUTES <- LIGHTING_ATTRIBUTE
318
  ACG::GLState::enable(GL_LIGHTING);
Jan Möbius's avatar
 
Jan Möbius committed
319
  glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
320 321
  ACG::GLState::enable(GL_COLOR_MATERIAL);
  ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
 
Jan Möbius committed
322

323 324 325 326
  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
327 328 329 330 331 332
  // Init state - changes when mode_ != POSITION
  Vec3d pos3D(0.0,0.0,0.0);

  if ( mode_ == SCREENPOS ) {

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

Jan Möbius's avatar
 
Jan Möbius committed
335 336 337 338
    _state.get_viewport(left, bottom, width, height);

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

341 342 343
    if (projectionMode_ == PERSPECTIVE_PROJECTION)
        _state.perspective(45.0, aspect, 0.8, 20.0);
    else
344
        _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
345

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
346 347
    _state.push_modelview_matrix();
    _state.reset_modelview();
Jan Möbius's avatar
 
Jan Möbius committed
348

349 350 351 352 353 354
    float rel_size = 50.0;
    float projdist = sqrt ( (width*height) / rel_size );

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

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

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
359
    // reset scene translation
360
    // we want only the scene rotation to rotate the coordsys
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
361
    GLMatrixd modelview = _state.modelview();
Jan Möbius's avatar
 
Jan Möbius committed
362

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
363 364 365
    modelview(0,3) = 0.0;
    modelview(1,3) = 0.0;
    modelview(2,3) = 0.0;
Jan Möbius's avatar
 
Jan Möbius committed
366

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

370 371

    // clear the depth buffer behind the coordsys
Jan Möbius's avatar
Jan Möbius committed
372
    ACG::GLState::depthRange (1.0, 1.0);
373
    ACG::GLState::depthFunc (GL_ALWAYS);
374 375

    drawCoordsys(_state);
376

Jan Möbius's avatar
Jan Möbius committed
377
    ACG::GLState::depthRange (0.0, 1.0);
378
    ACG::GLState::depthFunc (GL_LESS);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
379

380
    // draw coordsys
Jan Möbius's avatar
 
Jan Möbius committed
381 382
    drawCoordsys(_state);

383
    // set depth buffer to 0 so that nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
384
    ACG::GLState::depthRange (0.0, 0.0);
385
    ACG::GLState::depthFunc (GL_ALWAYS);
386
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
387

388 389 390
    // Koordinatensystem zeichnen
    drawCoordsys(_state);

Jan Möbius's avatar
Jan Möbius committed
391
    ACG::GLState::depthRange (0.0, 1.0);
392
    ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
393
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
394

Jan Möbius's avatar
 
Jan Möbius committed
395 396
    // Projection reload
    _state.pop_projection_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
397

Jan Möbius's avatar
 
Jan Möbius committed
398 399 400

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

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
401 402 403 404 405 406 407
    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
408

409
    // clear depth buffer in coordsys region
Jan Möbius's avatar
Jan Möbius committed
410
    ACG::GLState::depthRange (1.0, 1.0);
411
    ACG::GLState::depthFunc (GL_ALWAYS);
412 413 414 415 416

    // Koordinatensystem zeichnen
    drawCoordsys(_state);

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

420
    // Koordinatensystem zeichnen
Jan Möbius's avatar
 
Jan Möbius committed
421 422
    drawCoordsys(_state);

423
    // set depth buffer to 0 so that nothing can paint over cordsys
Jan Möbius's avatar
Jan Möbius committed
424
    ACG::GLState::depthRange (0.0, 0.0);
425
    ACG::GLState::depthFunc (GL_ALWAYS);
426 427 428 429
    glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

    // Koordinatensystem zeichnen
    drawCoordsys(_state);
430

431
    // reset to default
Jan Möbius's avatar
Jan Möbius committed
432
    ACG::GLState::depthRange (0.0, 1.0);
433
    ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
434
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
Jan Möbius's avatar
 
Jan Möbius committed
435 436 437 438 439 440 441 442 443 444 445
  }

  glPopAttrib();

  glColor4fv(lastBaseColor.data());

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


446 447 448 449




450
void CoordsysNode::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
451 452 453 454 455 456 457 458 459 460
{
  // 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);
461
  ro.setMaterial(_mat);
462 463 464 465


  ro.depthTest = true;
  ro.depthWrite = true;
466
  ro.inZPrePass = false;
467
  ro.overlay = true;
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 508 509 510 511 512 513 514

  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
515
    ro.shaderDesc.shadeMode = SG_SHADE_PHONG;
516
    ro.shaderDesc.clearTextures();
517 518 519 520 521 522 523
    ro.shaderDesc.vertexColors = false;



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

524
    ro.priority = 3;
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 566 567 568 569 570 571 572 573
    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
574 575 576 577 578 579 580
void
CoordsysNode::
setMode(const CoordsysMode _mode)
{
  mode_ = _mode;
}

581 582 583 584 585 586 587
void
CoordsysNode::
setProjectionMode(const ProjectionMode _mode)
{
  projectionMode_ = _mode;
}

Jan Möbius's avatar
 
Jan Möbius committed
588 589 590 591 592 593 594 595 596 597 598 599 600 601
void
CoordsysNode::
setPosition(const Vec3f& _pos)
{
  pos3f_ = _pos;
}

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

602 603 604 605 606 607 608
CoordsysNode::ProjectionMode
CoordsysNode::
getProjectionMode() const
{
  return projectionMode_;
}

Jan Möbius's avatar
 
Jan Möbius committed
609 610 611
void
CoordsysNode::pick(GLState& _state, PickTarget _target)
{
612 613
  GLenum prev_depth = _state.depthFunc();  
    
Jan Möbius's avatar
Jan Möbius committed
614 615
  if (_target == PICK_ANYTHING) {

Jan Möbius's avatar
Jan Möbius committed
616 617
    GLdouble mat[16];

Jan Möbius's avatar
 
Jan Möbius committed
618
    // Push Modelview-Matrix
Jan Möbius's avatar
Jan Möbius committed
619
    _state.push_modelview_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
620
    _state.pick_set_maximum (5);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
621
    _state.pick_set_name (0);
Jan Möbius's avatar
 
Jan Möbius committed
622 623

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

Jan Möbius's avatar
Jan Möbius committed
626
    if ( mode_ == SCREENPOS ) {
Jan Möbius's avatar
 
Jan Möbius committed
627

Jan Möbius's avatar
Jan Möbius committed
628
      int left, bottom, width, height;
629
      double aspect = _state.aspect();
630

Jan Möbius's avatar
Jan Möbius committed
631
      _state.get_viewport(left, bottom, width, height);
632
      
Jan Möbius's avatar
Jan Möbius committed
633 634
      // Projection reset
      _state.push_projection_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
635
      _state.reset_projection();
Jan Möbius's avatar
 
Jan Möbius committed
636

637 638 639
      if (projectionMode_ == PERSPECTIVE_PROJECTION)
        _state.perspective(45.0, aspect, 0.8, 20.0);
      else
640
        _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
641

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
642 643
      _state.push_modelview_matrix();
      _state.reset_modelview();
Jan Möbius's avatar
 
Jan Möbius committed
644

645 646 647 648 649 650 651
      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
652 653
      pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
      _state.pop_modelview_matrix();
Jan Möbius's avatar
 
Jan Möbius committed
654

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
655 656
      // reset scene translation
      GLMatrixd modelview = _state.modelview();
Jan Möbius's avatar
 
Jan Möbius committed
657

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
658 659 660
      modelview(0,3) = 0.0;
      modelview(1,3) = 0.0;
      modelview(2,3) = 0.0;
Jan Möbius's avatar
 
Jan Möbius committed
661

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

665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
      // 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
681
        ACG::GLState::depthRange (1.0, 1.0);
682
        ACG::GLState::depthFunc (GL_ALWAYS);
683 684 685 686 687

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
688
        ACG::GLState::depthRange (0.0, 1.0);
689
        ACG::GLState::depthFunc (GL_LESS);
690 691 692 693 694

        // 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
695
        ACG::GLState::depthRange (0.0, 0.0);
696
        ACG::GLState::depthFunc (GL_ALWAYS);
697 698 699 700 701 702
        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
703
        ACG::GLState::depthRange (0.0, 1.0);
704
        ACG::GLState::depthFunc (prev_depth);
705 706
        glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      }
Jan Möbius's avatar
Jan Möbius committed
707

708 709
      // Projection reload
      _state.pop_projection_matrix();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
710

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

713 714 715
      // 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
716 717 718 719 720 721 722 723 724 725 726 727 728
      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
729 730 731 732 733 734
      GLMatrixd modelview = _state.modelview();

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

735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
      // 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
751
        ACG::GLState::depthRange (1.0, 1.0);
752
        ACG::GLState::depthFunc (GL_ALWAYS);
753 754 755 756 757

        // Koordinatensystem zeichnen
        drawCoordsys(_state);

        // draw coordsys in normal mode
Jan Möbius's avatar
Jan Möbius committed
758
        ACG::GLState::depthRange (0.0, 1.0);
759
        ACG::GLState::depthFunc (GL_LESS);
760 761 762 763 764

        // 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
765
        ACG::GLState::depthRange (0.0, 0.0);
766
        ACG::GLState::depthFunc (GL_ALWAYS);
767 768 769 770 771 772
        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
773
        ACG::GLState::depthRange (0.0, 1.0);
774
        ACG::GLState::depthFunc (prev_depth);
775 776
        glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
      }
Jan Möbius's avatar
 
Jan Möbius committed
777
    }
Jan Möbius's avatar
Jan Möbius committed
778 779 780 781
    // Reload old configuration
    _state.pop_modelview_matrix();

  }
Jan Möbius's avatar
 
Jan Möbius committed
782 783
}

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
784 785
//----------------------------------------------------------------------------

786
void CoordsysNode::clearPickArea(GLState&  _state, bool _draw, GLfloat _depth)
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
787
{
788 789
  GLenum prev_depth = _state.depthFunc();
    
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
790 791 792 793 794 795 796
  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
797 798 799
  GLboolean colorMask[4];
  glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818
  // 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
819

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
820 821 822 823
  _state.ortho (left, left + width, bottom, bottom + height, 0.0, 1.0);

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

828
  if (_draw)
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
829 830 831 832 833
    _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
834 835 836
  disk_->setInnerRadius(0.0f);
  disk_->setOuterRadius(radius * 1.1f);
  disk_->draw(_state);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
837

838
  ACG::GLState::depthFunc (prev_depth);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
839 840 841
  _state.pop_modelview_matrix();
  _state.pop_projection_matrix();

Jan Möbius's avatar
Jan Möbius committed
842
  ACG::GLState::depthRange (0.0, 1.0);
843 844

  if (!_draw)
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
845
    glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
846 847 848 849 850 851
}

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

void CoordsysNode::boundingCircle(std::vector<Vec2f> &_in, Vec2f &_center, float &_radius)
{
Jan Möbius's avatar
Jan Möbius committed
852
  if (_in.empty())
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
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 935 936 937 938 939 940 941 942
    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
943 944 945 946
//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================