GlutPrimitiveNode.cc 13 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$                   *
 *                                                                           *
\*===========================================================================*/
42 43 44 45 46 47 48 49 50 51 52 53 54 55




//=============================================================================
//
//  CLASS GlutPrimitiveNode - IMPLEMENTATION
//
//=============================================================================


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

#include "GlutPrimitiveNode.hh"
56 57 58 59 60
#include <ACG/GL/gl.hh>

#include <ACG/GL/IRenderer.hh>

#include <ACG/Scenegraph/MaterialNode.hh>
61 62 63 64 65 66 67 68 69 70


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

namespace ACG {
namespace SceneGraph {


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

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
GlutPrimitiveNode::GlutPrimitiveNode( BaseNode*         _parent,
                                      std::string       _name )
  : BaseNode(_parent, _name),
    setColor_(true)
{
  const int slices = 20;
  const int stacks = 20;

  sphere_   = new ACG::GLSphere(slices,stacks);
};

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

GlutPrimitiveNode::GlutPrimitiveNode(GlutPrimitiveType _type,
                                     BaseNode* _parent,
                                     std::string _name) :
        BaseNode(_parent, _name),
        setColor_(true)
{
  const int slices = 20;
  const int stacks = 20;

  // add a single primitive of the given type
  Primitive p(_type);
  primitives_.push_back(p);

  sphere_ = new ACG::GLSphere(slices, stacks);
}

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
void 
GlutPrimitiveNode::
set_position(const Vec3d& _p, int _idx)
{
  if (_idx > -1 && _idx < (int)primitives_.size())
    primitives_[_idx].position = _p; 
}

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

const Vec3d
GlutPrimitiveNode::
get_position(int _idx) const 
{
  if (_idx > -1 && _idx < (int)primitives_.size())
    return primitives_[_idx].position; 
  
  return Vec3d(-1,-1,-1);
}

//----------------------------------------------------------------------------
121 122 123

void
GlutPrimitiveNode::
124
set_size(double _s, int _idx) 
125
{
126 127
  if (_idx > -1 && _idx < (int)primitives_.size())
    primitives_[_idx].size = _s; 
128 129
}

130 131 132 133 134 135 136 137 138 139
//----------------------------------------------------------------------------

double
GlutPrimitiveNode::
get_size(int _idx) const
{
  if (_idx > -1 && _idx < (int)primitives_.size())
    return primitives_[_idx].size; 
  return -1;
}
140 141 142

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

143 144 145 146 147 148 149
void
GlutPrimitiveNode::
boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
{
  for (int i = 0; i < (int)primitives_.size(); ++i)
  {
    Vec3d sizeVec(primitives_[i].size, primitives_[i].size, primitives_[i].size);
150 151
    _bbMax.maximize(primitives_[i].position + sizeVec);
    _bbMin.minimize(primitives_[i].position - sizeVec);
152 153 154 155
  }
}

//----------------------------------------------------------------------------
156
  
Jan Möbius's avatar
Jan Möbius committed
157
DrawModes::DrawMode
158
GlutPrimitiveNode::
159
availableDrawModes() const
160 161 162 163 164
{
  return ( DrawModes::POINTS              |
	   DrawModes::WIREFRAME           |
	   DrawModes::HIDDENLINE          |
	   DrawModes::SOLID_FLAT_SHADED   |
165 166
	   DrawModes::SOLID_SMOOTH_SHADED |
	   DrawModes::SOLID_FACES_COLORED );
167 168 169 170 171 172
}

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

void
GlutPrimitiveNode::
173
draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
174
{  
175 176 177 178 179
  for (int i = 0; i < (int)primitives_.size(); ++i)
  {
  
    glPushMatrix();
    glTranslatef(primitives_[i].position[0], primitives_[i].position[1], primitives_[i].position[2]);
180 181


182 183
    if (_drawMode & DrawModes::POINTS)
    {
184 185
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::shadeModel(GL_FLAT);
186 187 188 189
      glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
      draw_obj(i);
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
190 191


192 193
    if (_drawMode & DrawModes::WIREFRAME)
    {
194 195
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::shadeModel(GL_FLAT);
196 197 198 199
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      draw_obj(i);
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
200

201 202
    if (_drawMode & DrawModes::SOLID_FACES_COLORED)
    {
203 204
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::shadeModel(GL_FLAT);
205 206
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      
207 208 209 210
      if ( setColor_ ) {
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glColor(primitives_[i].color);
      }
211 212 213 214 215

      draw_obj(i);
      
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
216

217 218 219
    if (_drawMode & DrawModes::HIDDENLINE)
    {
      Vec4f base_color_backup = _state.base_color();
220

221 222
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::shadeModel(GL_FLAT);
223

224 225
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      glColor(_state.clear_color());
226
      ACG::GLState::depthRange(0.01, 1.0);
227
      draw_obj(i);
228

229 230
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glColor(base_color_backup);
231
      ACG::GLState::depthRange(0.0, 1.0);
232
      draw_obj(i);
233

234 235
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
236 237


238 239
    if (_drawMode & DrawModes::SOLID_FLAT_SHADED)
    {
240 241 242
      ACG::GLState::enable( GL_COLOR_MATERIAL );
      ACG::GLState::enable(GL_LIGHTING);
      ACG::GLState::shadeModel(GL_FLAT);
243
      
244 245 246 247
      if ( setColor_ ) {
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glColor(primitives_[i].color);
      }
248 249 250
      
      draw_obj(i);
    }
251 252


253 254
    if (_drawMode & DrawModes::SOLID_SMOOTH_SHADED)
    {
255 256 257
      ACG::GLState::enable( GL_COLOR_MATERIAL );
      ACG::GLState::enable(GL_LIGHTING);
      ACG::GLState::shadeModel(GL_SMOOTH);
258
      
259 260 261 262
      if ( setColor_ ) {
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glColor(primitives_[i].color);
      }
263

264 265
      draw_obj(i);
    }
266

267 268
    glPopMatrix();
  } // end of primitives iter
269 270 271 272
}

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

273 274
void 
GlutPrimitiveNode::
275
add_primitive(GlutPrimitiveType _type, Vec3d _pos, Vec3d _axis, ACG::Vec4f _color)
276 277 278 279 280 281
{
  Primitive p(_type, _pos, _axis, _color);
  primitives_.push_back(p);
}

//----------------------------------------------------------------------------
282 283

void
284
GlutPrimitiveNode::draw_obj(int _idx) const
285
{
286 287
  if (_idx < 0 || _idx >= (int)primitives_.size()) // range check
    return;
288 289 290 291 292

  Vec3d axis  = primitives_[_idx].axis;
  double size = axis.norm();

  if (size > 1e-10)
293
  {
294
    glPushMatrix();
295

296 297 298 299
    Vec3d direction = axis;
    Vec3d z_axis(0,0,1);
    Vec3d rot_normal;
    double rot_angle;
300

301 302 303 304
    direction.normalize();
    rot_angle  = acos((z_axis | direction)) * 180 / M_PI;
    rot_normal = ((z_axis % direction).normalize());
  
305

306 307 308 309
    if (fabs(rot_angle) > 0.0001 && fabs(180 - rot_angle) > 0.0001)
      glRotatef(rot_angle,rot_normal[0], rot_normal[1], rot_normal[2]);
    else
      glRotatef(rot_angle,1,0,0);
310

311 312 313 314 315 316
    
    switch (primitives_[_idx].type)
    {
      case CONE: 
        glutSolidCone(primitives_[_idx].size, primitives_[_idx].innersize, primitives_[_idx].slices, primitives_[_idx].stacks);
        break;
317

318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
      case CUBE: 
        glutSolidCube(primitives_[_idx].size);
        break;
      
      case DODECAHEDRON: 
        glutSolidDodecahedron();
        break;
      
      case ICOSAHEDRON: 
        glutSolidIcosahedron();
        break;

      case OCTAHEDRON:
        glutSolidOctahedron();
        break;

      case  SPHERE: 
        glutSolidSphere(primitives_[_idx].size, primitives_[_idx].slices, primitives_[_idx].stacks);
        break;
        
      case TEAPOT: 
        glutSolidTeapot(primitives_[_idx].size);
        break;

      case TETRAHEDRON: 
        glutSolidTetrahedron();
        break;

      case TORUS: 
        glutSolidTorus(primitives_[_idx].innersize, primitives_[_idx].size, primitives_[_idx].slices, primitives_[_idx].stacks);
        break;
    }

    glPopMatrix();
  }
353 354 355 356 357 358
}

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

void
GlutPrimitiveNode::
359
pick(GLState& _state , PickTarget _target)
360
{
361
  // initialize picking stack
362
  if (!_state.pick_set_maximum (primitives_.size()))
363
  {
364
    std::cerr << "Strange pickSetMaximum failed for index " << primitives_.size() << " in GlutPrimitiveNode\n";
365 366 367
    return;
  }

368 369 370 371 372
  switch (_target)
  {
    case PICK_ANYTHING:
    case PICK_FACE: 
    { 
373 374 375 376 377 378 379 380
      for (int i = 0; i < (int)primitives_.size(); ++i)
      {
        _state.pick_set_name(i);
        glPushMatrix();
        glTranslatef(primitives_[i].position[0], primitives_[i].position[1], primitives_[i].position[2]);
        draw_obj(i);
        glPopMatrix();
      }
381 382 383 384 385 386 387 388
      break; 
    }

    default:
      break;
  }      
}

389 390 391 392 393 394 395 396 397 398
//----------------------------------------------------------------------------

void
GlutPrimitiveNode::
getRenderObjects(IRenderer* _renderer, GLState&  _state , const DrawModes::DrawMode&  _drawMode , const Material* _mat) {

  // init base render object
  RenderObject ro;
  ro.initFromState(&_state);

399 400 401 402 403 404 405
  // the selection sphere uses alpha blending against scene meshes
  //  set priority-order > 0 to draw this after meshes
  ro.priority = 1;

  // enable depth-test
  ro.depthTest = true;

406 407 408
  for (int i = 0; i < (int)primitives_.size(); ++i)
  {

Jan Möbius's avatar
Jan Möbius committed
409 410 411 412 413
    // Set the right position
    _state.push_modelview_matrix();
    _state.translate(primitives_[i].position);
    ro.modelview = _state.modelview();
    _state.pop_modelview_matrix();
414

Jan Möbius's avatar
Jan Möbius committed
415 416 417 418 419
    Material localMaterial = *_mat;
    localMaterial.color(primitives_[i].color);
    localMaterial.ambientColor(primitives_[i].color);
    localMaterial.diffuseColor(primitives_[i].color);
    localMaterial.baseColor(primitives_[i].color);
420

Jan Möbius's avatar
Jan Möbius committed
421
    ro.setMaterial(&localMaterial);
422 423 424

    switch (primitives_[i].type) {
      case SPHERE:
425

426 427 428 429 430 431 432 433 434
        // Sphere
        ro.debugName = "glutprimitive.sphere";

        sphere_->addToRenderer(_renderer, &ro, primitives_[i].size);

        break;

      default:
        // TODO: The other glut primitives are not yet supported by the advanced renderers
435
        std::cerr << "Sorry, but the glut renderer objects are not available for this renderer yet!" << std::endl;
436 437 438 439 440 441 442 443
        break;
    }


  }

}

444 445 446 447 448

//=============================================================================
} // namespace SceneGraph
} // namespace ACG
//=============================================================================