Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
CameraNode.cc
1 /* ========================================================================= *
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  * ========================================================================= */
41 
42 /*===========================================================================*\
43  *
44  * $Revision$
45  * $Date$
46  *
47 \*===========================================================================*/
48 
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS GlutPrimitiveNode - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 #define CAMERAVISNODE_C
60 
61 //== INCLUDES =================================================================
62 #include "CameraNode.hh"
63 
64 //== NAMESPACES ===============================================================
65 
66 namespace ACG {
67 namespace SceneGraph {
68 
69 const float axis_length = 0.1f;
70 
71 //== IMPLEMENTATION ==========================================================
72 
74 CameraNode::CameraNode(BaseNode* _parent, std::string _name) :
75  BaseNode(_parent, _name),
76  bbmin_(FLT_MAX,FLT_MAX,FLT_MAX),
77  bbmax_(FLT_MIN,FLT_MIN,FLT_MIN),
78  cylinder_(0),
79  cone_(0),
80  showFrustum_(false) {
81 
82  modelView_.identity();
83 
84  projection_.identity();
85  // Setup a standard projection ( Full fovy 90, aspect 1.0, near 1.0, far 2.0 )
86  projection_.perspective(45 ,1.0,1.0,2.0);
87 
88  far_ = 2.0;
89  near_ = 1.0;
90 
91 
92  width_ = 500;
93  height_ = 500;
94 
95  updateBoundingBoxes(modelView_);
96 
97  cylinder_ = new GLCylinder(8, 4, 1.0f, false, false);
98  cone_ = new GLCone(8, 1, 1.0f, 0.0f, true, false);
99 }
100 
102  if (cylinder_)
103  delete cylinder_;
104 
105  if (cone_)
106  delete cone_;
107 }
108 
109 void CameraNode::boundingBox(Vec3d& _bbMin, Vec3d& _bbMax) {
110  _bbMin.minimize(bbmin_);
111  _bbMax.maximize(bbmax_);
112 }
113 
114 //----------------------------------------------------------------------------
115 
117  return (DrawModes::POINTS |
122 }
123 
124 //----------------------------------------------------------------------------
125 
126 void CameraNode::draw(GLState& _state, const DrawModes::DrawMode& /*_drawMode*/) {
127 
128  glPushAttrib(GL_LIGHTING_BIT);
129  glPushAttrib(GL_ENABLE_BIT);
130  ACG::GLState::shadeModel(GL_SMOOTH);
131  ACG::GLState::enable(GL_LIGHTING); // Turn lighting on
132 
133  // Store modelview matrix
134  _state.push_modelview_matrix();
135 
136  Vec4f lastBaseColor = _state.base_color();
137  Vec4f lastDiffuseColor = _state.diffuse_color();
138  Vec4f lastSpecularColor = _state.specular_color();
139 
140  // Set modelview matrix such that it matches
141  // the remote settings (+ the local transformation).
142  // This is performed by multiplying the local
143  // modelview matrix by the inverse remote
144  // modelview matrix: M_l' = M_l * M^{-1}_r
145  ACG::GLMatrixd modelview = _state.modelview();
146  _state.set_modelview(modelview * modelView_);
147 
148  // Update bounding box data and clipped_ flag
149  updateBoundingBoxes(modelview);
150 
151  _state.set_base_color(ACG::Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
152  _state.set_diffuse_color(ACG::Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
153  _state.set_specular_color(ACG::Vec4f(1.0f, 1.0f, 0.0f, 1.0f));
154 
155  // Draw camera box
156 
157  glPushAttrib(GL_LIGHTING_BIT);
158  ACG::GLState::disable(GL_LIGHTING); // Disable lighting
159  glBegin(GL_LINES);
160  glVertex3f(0.0f, 0.0f, 0.0f);
161  glVertex3f(-half_width_, -half_height_, -near_);
162 
163  glVertex3f(0.0f, 0.0f, 0.0f);
164  glVertex3f(half_width_, -half_height_, -near_);
165 
166  glVertex3f(0.0f, 0.0f, 0.0f);
167  glVertex3f(-half_width_, half_height_, -near_);
168 
169  glVertex3f(0.0f, 0.0f, 0.0f);
170  glVertex3f(half_width_, half_height_, -near_);
171 
172  glVertex3f(-half_width_, -half_height_, -near_);
173  glVertex3f(half_width_, -half_height_, -near_);
174 
175  glVertex3f(-half_width_, -half_height_, -near_);
176  glVertex3f(-half_width_, half_height_, -near_);
177 
178  glVertex3f(half_width_, half_height_, -near_);
179  glVertex3f(half_width_, -half_height_, -near_);
180 
181  glVertex3f(half_width_, half_height_, -near_);
182  glVertex3f(-half_width_, half_height_, -near_);
183  glEnd();
184  glPopAttrib();
185 
186  // Render frustum
187  if(showFrustum_) {
188 
189  // Draw left side of frustum
190  ACG::GLState::enable (GL_BLEND);
191  glPushAttrib(GL_LIGHTING_BIT);
192  ACG::GLState::disable(GL_LIGHTING); // Disable lighting
193 
194  glColor4f(0.0f, 0.5f, 0.0f, 1.0f);
195 
196  glBegin(GL_LINES);
197 
198  // Top plane
199  glVertex3f(0.0f, 0.0f, 0.0f);
200  glVertex3f(-far_half_width_, -far_half_height_, -far_);
201 
202  glVertex3f(-far_half_width_, -far_half_height_, -far_);
203  glVertex3f(-far_half_width_, far_half_height_, -far_);
204 
205  glVertex3f(-far_half_width_, far_half_height_, -far_);
206  glVertex3f(0.0f, 0.0f, 0.0f);
207 
208 
209  // Bottom plane
210  glVertex3f(0.0f, 0.0f, 0.0f);
211  glVertex3f(far_half_width_, -far_half_height_, -far_);
212 
213  glVertex3f(far_half_width_, -far_half_height_, -far_);
214  glVertex3f(far_half_width_, far_half_height_, -far_);
215 
216  glVertex3f(far_half_width_, far_half_height_, -far_);
217  glVertex3f(0.0f, 0.0f, 0.0f);
218 
219  // Left
220  glVertex3f(0.0f, 0.0f, 0.0f);
221  glVertex3f(-far_half_width_, far_half_height_, -far_);
222 
223  glVertex3f(-far_half_width_, far_half_height_, -far_);
224  glVertex3f(far_half_width_, far_half_height_, -far_);
225 
226  glVertex3f(far_half_width_, far_half_height_, -far_);
227  glVertex3f(0.0f, 0.0f, 0.0f);
228 
229  // Right
230  glVertex3f(0.0f, 0.0f, 0.0f);
231  glVertex3f(-far_half_width_, -far_half_height_, -far_);
232 
233  glVertex3f(-far_half_width_, -far_half_height_, -far_);
234  glVertex3f(far_half_width_, -far_half_height_, -far_);
235 
236  glVertex3f(far_half_width_, -far_half_height_, -far_);
237  glVertex3f(0.0f, 0.0f, 0.0f);
238 
239  // Far
240  glVertex3f(-far_half_width_, -far_half_height_, -far_);
241  glVertex3f(far_half_width_, -far_half_height_, -far_);
242 
243  glVertex3f(far_half_width_, -far_half_height_, -far_);
244  glVertex3f(far_half_width_, far_half_height_, -far_);
245 
246  glVertex3f(far_half_width_, far_half_height_, -far_);
247  glVertex3f(-far_half_width_, -far_half_height_, -far_);
248 
249  glEnd();
250 
251  glColor4f(0.0f, 1.0f, 0.0f, 0.01f);
252 
253  glBegin(GL_TRIANGLES);
254 
255  // Top plane
256  glVertex3f(-half_width_, -half_height_, -1.0f);
257  glVertex3f(-far_half_width_, -far_half_height_, -far_);
258  glVertex3f(-far_half_width_, far_half_height_, -far_);
259 
260  glVertex3f(-far_half_width_, far_half_height_, -far_);
261  glVertex3f(-half_width_, half_height_, -1.0f);
262  glVertex3f(-half_width_, -half_height_, -1.0f);
263 
264  // Bottom plane
265  glVertex3f(half_width_, -half_height_, -1.0f);
266  glVertex3f(far_half_width_, -far_half_height_, -far_);
267  glVertex3f(far_half_width_, far_half_height_, -far_);
268 
269  glVertex3f(far_half_width_, far_half_height_, -far_);
270  glVertex3f(half_width_, half_height_, -1.0f);
271  glVertex3f(half_width_, -half_height_, -1.0f);
272 
273  // Left
274  glVertex3f(-half_width_, half_height_, -1.0f);
275  glVertex3f(-far_half_width_, far_half_height_, -far_);
276  glVertex3f(far_half_width_, far_half_height_, -far_);
277 
278  glVertex3f(far_half_width_, far_half_height_, -far_);
279  glVertex3f(half_width_, half_height_, -1.0f);
280  glVertex3f(-half_width_, half_height_, -1.0f);
281 
282  // Right
283  glVertex3f(-half_width_, -half_height_, -1.0f);
284  glVertex3f(-far_half_width_, -far_half_height_, -far_);
285  glVertex3f(far_half_width_, -far_half_height_, -far_);
286 
287  glVertex3f(far_half_width_, -far_half_height_, -far_);
288  glVertex3f(half_width_, -half_height_, -1.0f);
289  glVertex3f(-half_width_, -half_height_, -1.0f);
290 
291  // Far
292  glVertex3f(-far_half_width_, -far_half_height_, -far_);
293  glVertex3f(far_half_width_, -far_half_height_, -far_);
294  glVertex3f(far_half_width_, far_half_height_, -far_);
295 
296  glVertex3f(far_half_width_, far_half_height_, -far_);
297  glVertex3f(-far_half_width_, far_half_height_, -far_);
298  glVertex3f(-far_half_width_, -far_half_height_, -far_);
299 
300  glEnd();
301 
302 
303  glPopAttrib(); // LIGHTING
304  }
305 
306  // Draw right vector
307  _state.rotate(90, 0.0, 1.0, 0.0);
308 
309  _state.set_base_color(ACG::Vec4f(1.0f, 0.0f, 0.0f, 1.0f));
310  _state.set_diffuse_color(ACG::Vec4f(1.0f, 0.0f, 0.0f, 1.0f));
311  _state.set_specular_color(ACG::Vec4f(1.0f, 0.4f, 0.4f, 1.0f));
312 
313  cylinder_->setBottomRadius(axis_length/20.0f);
314  cylinder_->setTopRadius(axis_length/20.0f);
315  cylinder_->draw(_state, axis_length);
316 
317  // Draw top
318  _state.translate(0.0, 0.0, axis_length );
319  cone_->setBottomRadius(axis_length/5.0f);
320  cone_->setTopRadius(0.0f);
321  cone_->draw(_state, axis_length/2.0f);
322  _state.translate(0.0, 0.0, -axis_length );
323 
324  // Draw up vector
325  _state.rotate(-90, 1.0, 0.0, 0.0);
326 
327  _state.set_base_color(ACG::Vec4f(0.0f, 1.0f, 0.0f, 1.0f));
328  _state.set_diffuse_color(ACG::Vec4f(0.0f, 1.0f, 0.0f, 1.0f));
329  _state.set_specular_color(ACG::Vec4f(0.4f, 1.0f, 0.4f, 1.0f));
330 
331  cylinder_->draw(_state, axis_length);
332 
333  // Draw top
334  _state.translate(0.0, 0.0, axis_length );
335  cone_->draw(_state, axis_length/2.0f);
336  _state.translate(0.0, 0.0, -axis_length );
337 
338  // Draw viewing direction vector
339  _state.rotate(90, 0.0, 1.0, 0.0);
340 
341  _state.set_base_color(ACG::Vec4f(0.0f, 0.0f, 1.0f, 1.0f));
342  _state.set_diffuse_color(ACG::Vec4f(0.0f, 0.0f, 1.0f, 1.0f));
343  _state.set_specular_color(ACG::Vec4f(0.4f, 0.4f, 1.0f, 1.0f));
344 
345  cylinder_->draw(_state, axis_length);
346 
347  // Draw top
348  _state.translate(0.0, 0.0, axis_length );
349  cone_->draw(_state, axis_length/2.0f);
350  _state.translate(0.0, 0.0, -axis_length );
351 
352 
353  // Reset to previous modelview
354  _state.pop_modelview_matrix();
355 
356  _state.set_base_color(lastBaseColor);
357  _state.set_diffuse_color(lastDiffuseColor);
358  _state.set_specular_color(lastSpecularColor);
359 
360  glPopAttrib(); // GL_ENABLE_BIT
361  glPopAttrib(); // LIGHTING
362 }
363 
364 //----------------------------------------------------------------------------
365 
366 void CameraNode::pick(GLState& _state, PickTarget /*_target*/) {
367 
368  _state.pick_set_maximum(2);
369 
370  _state.pick_set_name(0);
371 
372  // Store modelview matrix
373  _state.push_modelview_matrix();
374 
375  // Set modelview matrix such that it matches
376  // the remote settings (+ the local transformation).
377  // This is performed by multiplying the local
378  // modelview matrix by the inverse remote
379  // modelview matrix: M_l' = M_l * M^{-1}_r
380  ACG::GLMatrixd modelview = _state.modelview();
381  _state.set_modelview(modelview * modelView_);
382 
383  // Update bounding box data and clipped_ flag
384  updateBoundingBoxes(modelview);
385 
386  // Draw camera box
387  glBegin(GL_LINES);
388  glVertex3f(0.0f, 0.0f, 0.0f);
389  glVertex3f(-half_width_, -half_height_, -near_);
390 
391  glVertex3f(0.0f, 0.0f, 0.0f);
392  glVertex3f(half_width_, -half_height_, -near_);
393 
394  glVertex3f(0.0f, 0.0f, 0.0f);
395  glVertex3f(-half_width_, half_height_, -near_);
396 
397  glVertex3f(0.0f, 0.0f, 0.0f);
398  glVertex3f(half_width_, half_height_, -near_);
399 
400  glVertex3f(-half_width_, -half_height_, -near_);
401  glVertex3f(half_width_, -half_height_, -near_);
402 
403  glVertex3f(-half_width_, -half_height_, -near_);
404  glVertex3f(-half_width_, half_height_, -near_);
405 
406  glVertex3f(half_width_, half_height_, -near_);
407  glVertex3f(half_width_, -half_height_, -near_);
408 
409  glVertex3f(half_width_, half_height_, -near_);
410  glVertex3f(-half_width_, half_height_, -near_);
411  glEnd();
412 
413 
414  _state.pick_set_name(1);
415 
416  // Draw right vector
417  _state.rotate(90, 0.0, 1.0, 0.0);
418 
419  cylinder_->setBottomRadius(axis_length/20.0f);
420  cylinder_->setTopRadius(axis_length/20.0f);
421  cylinder_->draw(_state, axis_length);
422 
423  // Draw top
424  _state.translate(0.0, 0.0, axis_length );
425  cone_->setBottomRadius(axis_length/5.0f);
426  cone_->setTopRadius(0.0f);
427  cone_->draw(_state, axis_length/2.0f);
428  _state.translate(0.0, 0.0, -axis_length );
429 
430  // Draw up vector
431  _state.rotate(-90, 1.0, 0.0, 0.0);
432 
433  cylinder_->draw(_state, axis_length);
434 
435  // Draw top
436  _state.translate(0.0, 0.0, axis_length );
437  cone_->draw(_state, axis_length/2.0f);
438  _state.translate(0.0, 0.0, -axis_length );
439 
440  // Draw viewing direction vector
441  _state.rotate(90, 0.0, 1.0, 0.0);
442 
443  cylinder_->draw(_state, axis_length);
444 
445  // Draw top
446  _state.translate(0.0, 0.0, axis_length );
447  cone_->draw(_state, axis_length/2.0f);
448  _state.translate(0.0, 0.0, -axis_length );
449 
450  // Reset to previous modelview
451  _state.pop_modelview_matrix();
452 }
453 
454 //----------------------------------------------------------------------------
455 
456 void CameraNode::updateBoundingBoxes(GLMatrixd& _modelview) {
457 
458  // Get fovy of remote projection
459  fovy_ = atan(1/projection_(1,1)) * 2;
460 
461  // Set bounding box of camera to be of sufficient
462  // size to cover any camera rotation.
463  // Note: 1.41421 = sqrt(2)
464 
465  aspectRatio_ = (double)width_ / (double)height_;
466 
467  half_height_ = height_/2.0;
468  half_width_ = aspectRatio_ * half_height_;
469 
470  if(showFrustum_) {
471  far_half_height_ = tan(fovy_/2) * far_;
472  far_half_width_ = far_half_height_ * aspectRatio_;
473  }
474 
475  OpenMesh::Vec3d e = OpenMesh::Vec3d(modelView_(0,3), modelView_(1,3), modelView_(2,3));
476 
477  OpenMesh::Vec3d tmp(std::max(1.41421, half_width_), std::max(1.41421, half_height_), 1.41421);
478 
479  bbmin_ = e - tmp;
480  bbmax_ = e + tmp;
481 }
482 
483 
484 
485 //=============================================================================
486 } // namespace SceneGraph
487 } // namespace ACG
488 //=============================================================================
VectorT< double, 3 > Vec3d
Definition: Vector11T.hh:771
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
void pick(GLState &_state, PickTarget _target)
picking
Definition: CameraNode.cc:366
static void enable(GLenum _cap)
replaces glEnable, but supports locking
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
Definition: DrawModes.cc:86
void pick_set_name(unsigned int _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1057
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
static void disable(GLenum _cap)
replaces glDisable, but supports locking
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1047
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:531
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
Definition: GLState.cc:562
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:87
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Definition: DrawModes.cc:88
void set_diffuse_color(const Vec4f &_col)
set diffuse color
Definition: GLState.cc:720
DrawModes::DrawMode availableDrawModes() const
return available draw modes
Definition: CameraNode.cc:116
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1006
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
drawing
Definition: CameraNode.cc:126
4x4 matrix implementing OpenGL commands.
Definition: GLMatrixT.hh:85
const Vec4f & specular_color() const
get specular color
Definition: GLState.hh:944
virtual ~CameraNode()
Destructor.
Definition: CameraNode.cc:101
void identity()
setup an identity matrix
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:79
void perspective(Scalar fovY, Scalar aspect, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
CameraNode(BaseNode *_parent=0, std::string _name="<CameraVis>")
Default constructor.
Definition: CameraNode.cc:74
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1022
void set_base_color(const Vec4f &_col)
set base color (used when lighting is off)
Definition: GLState.cc:675
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:84
void set_specular_color(const Vec4f &_col)
set specular color
Definition: GLState.cc:735
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:731
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:929
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
Definition: CameraNode.cc:109
const Vec4f & diffuse_color() const
get diffuse color
Definition: GLState.hh:939