~ubuntu-branches/debian/sid/coin2/sid

« back to all changes in this revision

Viewing changes to src/nodes/SoFrustumCamera.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2008-06-28 02:38:17 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080628023817-lgrh0u677j1gcqgf
Tags: 2.5.0-2
* debian/control: Change suggests from libopenal0 to libopenal0a.
  Closes: #488001.  Change ${Source-Version} to ${binary:Version}.
  Update to standards version 3.8.0.

* debian/rules: Do not ignore errors in clean rule.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************\
 
2
 *
 
3
 *  This file is part of the Coin 3D visualization library.
 
4
 *  Copyright (C) 1998-2007 by Systems in Motion.  All rights reserved.
 
5
 *
 
6
 *  This library is free software; you can redistribute it and/or
 
7
 *  modify it under the terms of the GNU General Public License
 
8
 *  ("GPL") version 2 as published by the Free Software Foundation.
 
9
 *  See the file LICENSE.GPL at the root directory of this source
 
10
 *  distribution for additional information about the GNU GPL.
 
11
 *
 
12
 *  For using Coin with software that can not be combined with the GNU
 
13
 *  GPL, and for taking advantage of the additional benefits of our
 
14
 *  support services, please contact Systems in Motion about acquiring
 
15
 *  a Coin Professional Edition License.
 
16
 *
 
17
 *  See http://www.coin3d.org/ for more information.
 
18
 *
 
19
 *  Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
 
20
 *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
 
21
 *
 
22
\**************************************************************************/
 
23
 
 
24
/*!
 
25
  \class SoFrustumCamera SoFrustumCamera.h Inventor/nodes/SoFrustumCamera.h
 
26
  \brief The SoFrustumCamera class defines a camera with a generic frustum..
 
27
 
 
28
  The SoFrustumCamera class makes it possible to specify a frustum in
 
29
  the same manner as the OpenGL glFrustum() function. It has four new
 
30
  fields (left, right, top, bottom), and will use
 
31
  SoCamera::nearDistance and SoCamera::farDistance for the two last
 
32
  glFrustum() parameters.
 
33
 
 
34
  This camera can be useful in applications that require full control
 
35
  over the view frustum, such as in CAVE or other multipipe
 
36
  applications.
 
37
 
 
38
  \since Coin 2.5
 
39
*/
 
40
 
 
41
/*!
 
42
  \var SoSFFloat SoFrustumCamera::left
 
43
 
 
44
  The left clipping plane position. Default value is -0.5.
 
45
*/
 
46
 
 
47
/*!
 
48
  \var SoSFFloat SoFrustumCamera::right
 
49
 
 
50
  The right clipping plane position. Default value is 0.5
 
51
*/
 
52
 
 
53
/*!
 
54
  \var SoSFFloat SoFrustumCamera::bottom
 
55
 
 
56
  The bottom clipping plane position. Default value is -0.5.
 
57
*/
 
58
 
 
59
/*!
 
60
  \var SoSFFloat SoFrustumCamera::top
 
61
 
 
62
  The top clipping plane position. Default value is 0.5.
 
63
*/
 
64
 
 
65
#include <Inventor/nodes/SoFrustumCamera.h>
 
66
#include <Inventor/nodes/SoSubNodeP.h>
 
67
#include <Inventor/errors/SoDebugError.h>
 
68
#include <Inventor/SbSphere.h>
 
69
#include <math.h>
 
70
 
 
71
SO_NODE_SOURCE(SoFrustumCamera);
 
72
 
 
73
/*!
 
74
  Constructor.
 
75
*/
 
76
SoFrustumCamera::SoFrustumCamera(void)
 
77
{
 
78
  SO_NODE_INTERNAL_CONSTRUCTOR(SoFrustumCamera);
 
79
 
 
80
  SO_NODE_ADD_FIELD(top, (0.5f));
 
81
  SO_NODE_ADD_FIELD(bottom, (-0.5f));
 
82
  SO_NODE_ADD_FIELD(left, (-0.5f));
 
83
  SO_NODE_ADD_FIELD(right, (0.5f));
 
84
}
 
85
 
 
86
/*!
 
87
  Destructor.
 
88
*/
 
89
SoFrustumCamera::~SoFrustumCamera(void)
 
90
{
 
91
}
 
92
 
 
93
// Doc in superclass.
 
94
void
 
95
SoFrustumCamera::initClass(void)
 
96
{
 
97
  SO_NODE_INTERNAL_INIT_CLASS(SoFrustumCamera, SoNode::COIN_2_5);
 
98
}
 
99
 
 
100
// Doc in superclass.
 
101
void
 
102
SoFrustumCamera::scaleHeight(float scalefactor)
 
103
{
 
104
  this->top = this->top.getValue() * scalefactor;
 
105
  this->bottom = this->bottom.getValue() * scalefactor;
 
106
}
 
107
 
 
108
// Doc in superclass.
 
109
SbViewVolume
 
110
SoFrustumCamera::getViewVolume(float useaspectratio) const
 
111
{
 
112
  SbViewVolume vv;
 
113
 
 
114
  if (useaspectratio == 0.0f) { // LEAVE_ALONE viewportMapping
 
115
    vv.frustum(this->left.getValue(),
 
116
               this->right.getValue(),
 
117
               this->bottom.getValue(),
 
118
               this->top.getValue(),
 
119
               this->nearDistance.getValue(),
 
120
               this->farDistance.getValue());
 
121
  }
 
122
  else {
 
123
    // calculate left and right based on height
 
124
    float cx = (this->left.getValue() + this->right.getValue()) * 0.5f;
 
125
    float h_2 = (this->top.getValue() - this->bottom.getValue()) * 0.5f;
 
126
 
 
127
    vv.frustum(cx - h_2 * useaspectratio,
 
128
               cx + h_2 * useaspectratio,
 
129
               this->bottom.getValue(),
 
130
               this->top.getValue(),
 
131
               this->nearDistance.getValue(),
 
132
               this->farDistance.getValue());
 
133
  }
 
134
  vv.rotateCamera(this->orientation.getValue());
 
135
  vv.translateCamera(this->position.getValue());
 
136
  return vv;
 
137
}
 
138
 
 
139
// Doc in superclass.
 
140
void
 
141
SoFrustumCamera::viewBoundingBox(const SbBox3f & box, float aspect, float slack)
 
142
{
 
143
 
 
144
#if COIN_DEBUG
 
145
  // Only check for "flagged" emptiness, and don't use
 
146
  // SbBox3f::hasVolume(), as we *can* handle flat boxes.
 
147
  if (box.isEmpty()) {
 
148
    SoDebugError::postWarning("Frustum::viewBoundingBox",
 
149
                              "bounding box is empty");
 
150
    return;
 
151
  }
 
152
#endif // COIN_DEBUG
 
153
 
 
154
  // First, we want to move the camera in such a way that it is
 
155
  // pointing straight at the center of the scene bounding box -- but
 
156
  // without modifiying the rotation value (so we can't use
 
157
  // SoCamera::pointAt()).
 
158
  SbVec3f cameradirection;
 
159
  this->orientation.getValue().multVec(SbVec3f(0, 0, -1), cameradirection);
 
160
  this->position.setValue(box.getCenter() + -cameradirection);
 
161
 
 
162
  // Get the radius of the bounding sphere.
 
163
  SbSphere bs;
 
164
  bs.circumscribe(box);
 
165
  float radius = bs.getRadius();
 
166
 
 
167
  // Make sure that everything will still be inside the viewing volume
 
168
  // even if the aspect ratio "favorizes" width over height.
 
169
  float aspectradius = radius / (aspect < 1.0f ? aspect : 1.0f);
 
170
 
 
171
  // just calculate a heightangle so that we can reuse code from
 
172
  // SoPerspectiveCamera
 
173
  float nearv = this->nearDistance.getValue();
 
174
  SbVec3f tvec = SbVec3f(0.0f, this->top.getValue(), nearv);
 
175
  SbVec3f bvec = SbVec3f(0.0f, this->bottom.getValue(), nearv);
 
176
 
 
177
  (void) tvec.normalize();
 
178
  (void) bvec.normalize();
 
179
 
 
180
  float heightangle = (float) acos((double)SbClamp(tvec.dot(bvec), 0.0f, 1.0f));
 
181
 
 
182
  // Move the camera to the edge of the bounding sphere, while still
 
183
  // pointing at the scene.
 
184
  SbVec3f direction = this->position.getValue() - box.getCenter();
 
185
  direction.normalize();
 
186
  float movelength =
 
187
    aspectradius + (aspectradius/float(atan(heightangle)));
 
188
  this->position.setValue(box.getCenter() + direction * movelength);
 
189
 
 
190
  // Set up the far clipping plane according to the slack value (a
 
191
  // value of 1.0 will yield a far clipping plane that is tangent to
 
192
  // the bounding sphere of the scene).
 
193
  float distance_to_midpoint =
 
194
    (this->position.getValue() - box.getCenter()).length();
 
195
  this->farDistance = distance_to_midpoint + radius * slack;
 
196
 
 
197
  // The focal distance is simply the distance from the camera to the
 
198
  // scene midpoint. This field is not used in rendering, its just
 
199
  // provided to make it easier for the user to do calculations based
 
200
  // on the distance between the camera and the scene.
 
201
  this->focalDistance = distance_to_midpoint;
 
202
}