GlutPrimitiveNode.cc 10.1 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
4
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
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
 *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  OpenFlipper is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenFlipper is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37
 *   $Revision$                                                       *
Jan Möbius's avatar
Jan Möbius committed
38
39
40
41
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66




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


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

#include "GlutPrimitiveNode.hh"
#include "../GL/gl.hh"


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

namespace ACG {
namespace SceneGraph {


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

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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);
}

//----------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
88
89
90

void
GlutPrimitiveNode::
91
set_size(double _s, int _idx) 
Jan Möbius's avatar
 
Jan Möbius committed
92
{
93
94
  if (_idx > -1 && _idx < (int)primitives_.size())
    primitives_[_idx].size = _s; 
Jan Möbius's avatar
 
Jan Möbius committed
95
96
}

97
98
99
100
101
102
103
104
105
106
//----------------------------------------------------------------------------

double
GlutPrimitiveNode::
get_size(int _idx) const
{
  if (_idx > -1 && _idx < (int)primitives_.size())
    return primitives_[_idx].size; 
  return -1;
}
Jan Möbius's avatar
 
Jan Möbius committed
107
108
109

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

110
111
112
113
114
115
116
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);
117
118
    _bbMax.maximize(primitives_[i].position + sizeVec);
    _bbMin.minimize(primitives_[i].position - sizeVec);
119
120
121
122
  }
}

//----------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
123
  
Jan Möbius's avatar
Jan Möbius committed
124
DrawModes::DrawMode
Jan Möbius's avatar
 
Jan Möbius committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
GlutPrimitiveNode::
availableDrawModes() const
{
  return ( DrawModes::POINTS              |
	   DrawModes::WIREFRAME           |
	   DrawModes::HIDDENLINE          |
	   DrawModes::SOLID_FLAT_SHADED   |
	   DrawModes::SOLID_SMOOTH_SHADED );
}

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

void
GlutPrimitiveNode::
Jan Möbius's avatar
Jan Möbius committed
139
draw(GLState& _state, DrawModes::DrawMode _drawMode)
Jan Möbius's avatar
 
Jan Möbius committed
140
141
{
  glDepthFunc(depthFunc());
142
143
144
145
146
147
  
  for (int i = 0; i < (int)primitives_.size(); ++i)
  {
  
    glPushMatrix();
    glTranslatef(primitives_[i].position[0], primitives_[i].position[1], primitives_[i].position[2]);
Jan Möbius's avatar
 
Jan Möbius committed
148
149


150
151
152
153
154
155
156
157
    if (_drawMode & DrawModes::POINTS)
    {
      glDisable(GL_LIGHTING);
      glShadeModel(GL_FLAT);
      glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
      draw_obj(i);
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
Jan Möbius's avatar
 
Jan Möbius committed
158
159


160
161
162
163
164
165
166
167
    if (_drawMode & DrawModes::WIREFRAME)
    {
      glDisable(GL_LIGHTING);
      glShadeModel(GL_FLAT);
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      draw_obj(i);
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
Jan Möbius's avatar
 
Jan Möbius committed
168
169


170
171
172
    if (_drawMode & DrawModes::HIDDENLINE)
    {
      Vec4f base_color_backup = _state.base_color();
Jan Möbius's avatar
 
Jan Möbius committed
173

174
175
      glDisable(GL_LIGHTING);
      glShadeModel(GL_FLAT);
Jan Möbius's avatar
 
Jan Möbius committed
176

177
178
179
180
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      glColor(_state.clear_color());
      glDepthRange(0.01, 1.0);
      draw_obj(i);
Jan Möbius's avatar
 
Jan Möbius committed
181

182
183
184
185
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glColor(base_color_backup);
      glDepthRange(0.0, 1.0);
      draw_obj(i);
Jan Möbius's avatar
 
Jan Möbius committed
186

187
188
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
Jan Möbius's avatar
 
Jan Möbius committed
189
190


191
192
193
194
195
196
197
198
199
200
201
    if (_drawMode & DrawModes::SOLID_FLAT_SHADED)
    {
      glEnable( GL_COLOR_MATERIAL );
      glEnable(GL_LIGHTING);
      glShadeModel(GL_FLAT);
      
      glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
      glColor(primitives_[i].color);
      
      draw_obj(i);
    }
Jan Möbius's avatar
 
Jan Möbius committed
202
203


204
205
206
207
208
209
210
211
    if (_drawMode & DrawModes::SOLID_SMOOTH_SHADED)
    {
      glEnable( GL_COLOR_MATERIAL );
      glEnable(GL_LIGHTING);
      glShadeModel(GL_SMOOTH);
      
      glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
      glColor(primitives_[i].color);
Jan Möbius's avatar
 
Jan Möbius committed
212

213
214
      draw_obj(i);
    }
Jan Möbius's avatar
 
Jan Möbius committed
215

216
217
218
    glPopMatrix();
  } // end of primitives iter
  
Jan Möbius's avatar
 
Jan Möbius committed
219
220
221
222
223
  glDepthFunc(GL_LESS);
}

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

224
225
226
227
228
229
230
231
232
void 
GlutPrimitiveNode::
add_primitive(GlutPrimitiveType _type, Vec3d _pos, Vec3d _axis, ACG::Vec3uc _color)
{
  Primitive p(_type, _pos, _axis, _color);
  primitives_.push_back(p);
}

//----------------------------------------------------------------------------
Jan Möbius's avatar
 
Jan Möbius committed
233
234

void
235
GlutPrimitiveNode::draw_obj(int _idx) const
Jan Möbius's avatar
 
Jan Möbius committed
236
{
237
238
  if (_idx < 0 || _idx >= (int)primitives_.size()) // range check
    return;
239
240
241
242
243

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

  if (size > 1e-10)
Jan Möbius's avatar
 
Jan Möbius committed
244
  {
245
    glPushMatrix();
246

247
248
249
250
    Vec3d direction = axis;
    Vec3d z_axis(0,0,1);
    Vec3d rot_normal;
    double rot_angle;
Jan Möbius's avatar
 
Jan Möbius committed
251

252
253
254
255
    direction.normalize();
    rot_angle  = acos((z_axis | direction)) * 180 / M_PI;
    rot_normal = ((z_axis % direction).normalize());
  
Jan Möbius's avatar
 
Jan Möbius committed
256

257
258
259
260
    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);
Jan Möbius's avatar
 
Jan Möbius committed
261

262
263
264
265
266
267
    
    switch (primitives_[_idx].type)
    {
      case CONE: 
        glutSolidCone(primitives_[_idx].size, primitives_[_idx].innersize, primitives_[_idx].slices, primitives_[_idx].stacks);
        break;
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
      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();
  }
Jan Möbius's avatar
 
Jan Möbius committed
304
305
306
307
308
309
}

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

void
GlutPrimitiveNode::
David Bommes's avatar
   
David Bommes committed
310
pick(GLState& _state , PickTarget _target)
Jan Möbius's avatar
 
Jan Möbius committed
311
{
David Bommes's avatar
   
David Bommes committed
312
  // initialize picking stack
313
  if (!_state.pick_set_maximum (primitives_.size()))
David Bommes's avatar
   
David Bommes committed
314
  {
315
    std::cerr << "Strange pickSetMaximum failed for index " << primitives_.size() << " in GlutPrimitiveNode\n";
David Bommes's avatar
   
David Bommes committed
316
317
318
    return;
  }

Jan Möbius's avatar
 
Jan Möbius committed
319
320
321
322
323
  switch (_target)
  {
    case PICK_ANYTHING:
    case PICK_FACE: 
    { 
324
325
326
327
328
329
330
331
      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();
      }
Jan Möbius's avatar
 
Jan Möbius committed
332
333
334
335
336
337
338
339
340
341
342
343
344
      break; 
    }

    default:
      break;
  }      
}


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