GteViewVolume.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
11 using namespace gte;
12 
14 {
15 }
16 
17 ViewVolume::ViewVolume(bool isPerspective, bool isDepthRangeZeroOne)
18  :
19  mIsPerspective(isPerspective),
20  mIsDepthRangeZeroOne(isDepthRangeZeroOne),
22 {
23  // NOTE: SetFrame calls OnFrameChange and SetFrustum calls OnFrustumChange,
24  // and both On*Change functions call UpdatePVMatrix(). OnFrameChange,
25  // OnFrustumChange, and UpdatePVMatrix are virtual, so the calls in this
26  // constructor resolve to those of ViewVolume. Derived classes that
27  // need additional semantics in their constructors must apply those
28  // explicitly.
29  SetFrame({ 0.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, -1.0f, 0.0f },
30  { 0.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 0.0f });
31 
32  if (mIsPerspective)
33  {
34  SetFrustum(90.0f, 1.0f, 1.0f, 10000.0f);
35  }
36  else
37  {
38  SetFrustum(0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
39  }
40 }
41 
43 {
44  mPosition = position;
45  OnFrameChange();
46 }
47 
48 void ViewVolume::SetAxes(Vector4<float> const& dVector,
49  Vector4<float> const& uVector, Vector4<float> const& rVector)
50 {
51  mDVector = dVector;
52  mUVector = uVector;
53  mRVector = rVector;
54 
55  float const epsilon = 0.01f;
56  float det = DotCross(mDVector, mUVector, mRVector);
57  if (fabs(1.0f - det) > epsilon)
58  {
59 #if defined(GTE_VALIDATE_COORDINATE_FRAME_ONCE)
61  {
63 
64  float lenD = Length(mDVector);
65  float lenU = Length(mUVector);
66  float lenR = Length(mRVector);
67  float dotDU = Dot(mDVector, mUVector);
68  float dotDR = Dot(mDVector, mRVector);
69  float dotUR = Dot(mUVector, mRVector);
70  if (fabs(1.0f - lenD) > epsilon
71  || fabs(1.0f - lenU) > epsilon
72  || fabs(1.0f - lenR) > epsilon
73  || fabs(dotDU) > epsilon
74  || fabs(dotDR) > epsilon
75  || fabs(dotUR) > epsilon)
76  {
77  LogError("Coordinate frame is not orthonormal.");
78  }
79  }
80 #endif
81  // The input vectors do not appear to form an orthonormal set. Time
82  // to renormalize.
84  Orthonormalize<4, float>(3, v);
85  mDVector = v[0];
86  mUVector = v[1];
87  mRVector = v[2];
88  }
89 
90  OnFrameChange();
91 }
92 
93 void ViewVolume::SetFrame(Vector4<float> const& position, Vector4<float> const& dVector,
94  Vector4<float> const& uVector, Vector4<float> const& rVector)
95 {
96  mPosition = position;
97  SetAxes(dVector, uVector, rVector);
98 }
99 
101  Vector4<float>& rVector) const
102 {
103  dVector = mDVector;
104  uVector = mUVector;
105  rVector = mRVector;
106 }
107 
109  Vector4<float>& uVector, Vector4<float>& rVector) const
110 {
111  position = mPosition;
112  dVector = mDVector;
113  uVector = mUVector;
114  rVector = mRVector;
115 }
116 
117 void ViewVolume::SetFrustum(float dMin, float dMax, float uMin, float uMax, float rMin, float rMax)
118 {
119  mFrustum[VF_DMIN] = dMin;
120  mFrustum[VF_DMAX] = dMax;
121  mFrustum[VF_UMIN] = uMin;
122  mFrustum[VF_UMAX] = uMax;
123  mFrustum[VF_RMIN] = rMin;
124  mFrustum[VF_RMAX] = rMax;
125  OnFrustumChange();
126 }
127 
128 void ViewVolume::SetFrustum(float const* frustum)
129 {
130  mFrustum[VF_DMIN] = frustum[VF_DMIN];
131  mFrustum[VF_DMAX] = frustum[VF_DMAX];
132  mFrustum[VF_UMIN] = frustum[VF_UMIN];
133  mFrustum[VF_UMAX] = frustum[VF_UMAX];
134  mFrustum[VF_RMIN] = frustum[VF_RMIN];
135  mFrustum[VF_RMAX] = frustum[VF_RMAX];
136  OnFrustumChange();
137 }
138 
139 void ViewVolume::SetFrustum(float upFovDegrees, float aspectRatio, float dMin, float dMax)
140 {
141  float halfAngleRadians = 0.5f * upFovDegrees * (float)GTE_C_DEG_TO_RAD;
142  mFrustum[VF_UMAX] = dMin*tan(halfAngleRadians);
143  mFrustum[VF_RMAX] = aspectRatio*mFrustum[VF_UMAX];
144  mFrustum[VF_UMIN] = -mFrustum[VF_UMAX];
145  mFrustum[VF_RMIN] = -mFrustum[VF_RMAX];
146  mFrustum[VF_DMIN] = dMin;
147  mFrustum[VF_DMAX] = dMax;
148  OnFrustumChange();
149 }
150 
151 void ViewVolume::GetFrustum(float& dMin, float& dMax, float& uMin, float& uMax, float& rMin, float& rMax) const
152 {
153  dMin = mFrustum[VF_DMIN];
154  dMax = mFrustum[VF_DMAX];
155  uMin = mFrustum[VF_UMIN];
156  uMax = mFrustum[VF_UMAX];
157  rMin = mFrustum[VF_RMIN];
158  rMax = mFrustum[VF_RMAX];
159 }
160 
161 bool ViewVolume::GetFrustum(float& upFovDegrees, float& aspectRatio, float& dMin, float& dMax) const
162 {
163  if (mFrustum[VF_RMIN] == -mFrustum[VF_RMAX]
164  && mFrustum[VF_UMIN] == -mFrustum[VF_UMAX])
165  {
166  float tmp = mFrustum[VF_UMAX] / mFrustum[VF_DMIN];
167  upFovDegrees = 2.0f * atan(tmp) * (float)GTE_C_RAD_TO_DEG;
168  aspectRatio = mFrustum[VF_RMAX] / mFrustum[VF_UMAX];
169  dMin = mFrustum[VF_DMIN];
170  dMax = mFrustum[VF_DMAX];
171  return true;
172  }
173  return false;
174 }
175 
177 {
178  // This leads to left-handed coordinates for the camera frame.
179 #if defined(GTE_USE_MAT_VEC)
180  mViewMatrix(0, 0) = mRVector[0];
181  mViewMatrix(0, 1) = mRVector[1];
182  mViewMatrix(0, 2) = mRVector[2];
183  mViewMatrix(0, 3) = -Dot(mPosition, mRVector);
184  mViewMatrix(1, 0) = mUVector[0];
185  mViewMatrix(1, 1) = mUVector[1];
186  mViewMatrix(1, 2) = mUVector[2];
187  mViewMatrix(1, 3) = -Dot(mPosition, mUVector);
188  mViewMatrix(2, 0) = mDVector[0];
189  mViewMatrix(2, 1) = mDVector[1];
190  mViewMatrix(2, 2) = mDVector[2];
191  mViewMatrix(2, 3) = -Dot(mPosition, mDVector);
192  mViewMatrix(3, 0) = 0.0f;
193  mViewMatrix(3, 1) = 0.0f;
194  mViewMatrix(3, 2) = 0.0f;
195  mViewMatrix(3, 3) = 1.0f;
196 
197  mInverseViewMatrix(0, 0) = mRVector[0];
198  mInverseViewMatrix(0, 1) = mUVector[0];
199  mInverseViewMatrix(0, 2) = mDVector[0];
200  mInverseViewMatrix(0, 3) = mPosition[0];
201  mInverseViewMatrix(1, 0) = mRVector[1];
202  mInverseViewMatrix(1, 1) = mUVector[1];
203  mInverseViewMatrix(1, 2) = mDVector[1];
204  mInverseViewMatrix(1, 3) = mPosition[1];
205  mInverseViewMatrix(2, 0) = mRVector[2];
206  mInverseViewMatrix(2, 1) = mUVector[2];
207  mInverseViewMatrix(2, 2) = mDVector[2];
208  mInverseViewMatrix(2, 3) = mPosition[2];
209  mInverseViewMatrix(3, 0) = 0.0f;
210  mInverseViewMatrix(3, 1) = 0.0f;
211  mInverseViewMatrix(3, 2) = 0.0f;
212  mInverseViewMatrix(3, 3) = 1.0f;
213 #else
214  mViewMatrix(0, 0) = mRVector[0];
215  mViewMatrix(1, 0) = mRVector[1];
216  mViewMatrix(2, 0) = mRVector[2];
217  mViewMatrix(3, 0) = -Dot(mPosition, mRVector);
218  mViewMatrix(0, 1) = mUVector[0];
219  mViewMatrix(1, 1) = mUVector[1];
220  mViewMatrix(2, 1) = mUVector[2];
221  mViewMatrix(3, 1) = -Dot(mPosition, mUVector);
222  mViewMatrix(0, 2) = mDVector[0];
223  mViewMatrix(1, 2) = mDVector[1];
224  mViewMatrix(2, 2) = mDVector[2];
225  mViewMatrix(3, 2) = -Dot(mPosition, mDVector);
226  mViewMatrix(0, 3) = 0.0f;
227  mViewMatrix(1, 3) = 0.0f;
228  mViewMatrix(2, 3) = 0.0f;
229  mViewMatrix(3, 3) = 1.0f;
230 
231  mInverseViewMatrix(0, 0) = mRVector[0];
232  mInverseViewMatrix(1, 0) = mUVector[0];
233  mInverseViewMatrix(2, 0) = mDVector[0];
234  mInverseViewMatrix(3, 0) = mPosition[0];
235  mInverseViewMatrix(0, 1) = mRVector[1];
236  mInverseViewMatrix(1, 1) = mUVector[1];
237  mInverseViewMatrix(2, 1) = mDVector[1];
238  mInverseViewMatrix(3, 1) = mPosition[1];
239  mInverseViewMatrix(0, 2) = mRVector[2];
240  mInverseViewMatrix(1, 2) = mUVector[2];
241  mInverseViewMatrix(2, 2) = mDVector[2];
242  mInverseViewMatrix(3, 2) = mPosition[2];
243  mInverseViewMatrix(0, 3) = 0.0f;
244  mInverseViewMatrix(1, 3) = 0.0f;
245  mInverseViewMatrix(2, 3) = 0.0f;
246  mInverseViewMatrix(3, 3) = 1.0f;
247 #endif
248 
249  UpdatePVMatrix();
250 }
251 
253 {
254  // mIsDepthRangeZeroOne true: map (x,y,z) into [-1,1]x[-1,1]x[0,1].
255  // mIsDepthRangeZeroOne false: map (x,y,z) into [-1,1]x[-1,1]x[-1,1].
256  float dMin = mFrustum[VF_DMIN];
257  float dMax = mFrustum[VF_DMAX];
258  float uMin = mFrustum[VF_UMIN];
259  float uMax = mFrustum[VF_UMAX];
260  float rMin = mFrustum[VF_RMIN];
261  float rMax = mFrustum[VF_RMAX];
262  float invDDiff = 1.0f / (dMax - dMin);
263  float invUDiff = 1.0f / (uMax - uMin);
264  float invRDiff = 1.0f / (rMax - rMin);
265 
266  if (mIsPerspective)
267  {
268 #if defined(GTE_USE_MAT_VEC)
270  {
271  mProjectionMatrix(0, 0) = 2.0f * dMin * invRDiff;
272  mProjectionMatrix(0, 1) = 0.0f;
273  mProjectionMatrix(0, 2) = -(rMin + rMax) * invRDiff;
274  mProjectionMatrix(0, 3) = 0.0f;
275  mProjectionMatrix(1, 0) = 0.0f;
276  mProjectionMatrix(1, 1) = 2.0f * dMin * invUDiff;
277  mProjectionMatrix(1, 2) = -(uMin + uMax) * invUDiff;
278  mProjectionMatrix(1, 3) = 0.0f;
279  mProjectionMatrix(2, 0) = 0.0f;
280  mProjectionMatrix(2, 1) = 0.0f;
281  mProjectionMatrix(2, 2) = dMax * invDDiff;
282  mProjectionMatrix(2, 3) = -dMin * dMax * invDDiff;
283  mProjectionMatrix(3, 0) = 0.0f;
284  mProjectionMatrix(3, 1) = 0.0f;
285  mProjectionMatrix(3, 2) = 1.0f;
286  mProjectionMatrix(3, 3) = 0.0f;
287  }
288  else
289  {
290  mProjectionMatrix(0, 0) = 2.0f * dMin * invRDiff;
291  mProjectionMatrix(0, 1) = 0.0f;
292  mProjectionMatrix(0, 2) = -(rMin + rMax) * invRDiff;
293  mProjectionMatrix(0, 3) = 0.0f;
294  mProjectionMatrix(1, 0) = 0.0f;
295  mProjectionMatrix(1, 1) = 2.0f * dMin * invUDiff;
296  mProjectionMatrix(1, 2) = -(uMin + uMax) * invUDiff;
297  mProjectionMatrix(1, 3) = 0.0f;
298  mProjectionMatrix(2, 0) = 0.0f;
299  mProjectionMatrix(2, 1) = 0.0f;
300  mProjectionMatrix(2, 2) = (dMin + dMax) * invDDiff;
301  mProjectionMatrix(2, 3) = -2.0f * dMin * dMax * invDDiff;
302  mProjectionMatrix(3, 0) = 0.0f;
303  mProjectionMatrix(3, 1) = 0.0f;
304  mProjectionMatrix(3, 2) = 1.0f;
305  mProjectionMatrix(3, 3) = 0.0f;
306  }
307 #else
309  {
310  mProjectionMatrix(0, 0) = 2.0f * dMin * invRDiff;
311  mProjectionMatrix(1, 0) = 0.0f;
312  mProjectionMatrix(2, 0) = -(rMin + rMax) * invRDiff;
313  mProjectionMatrix(3, 0) = 0.0f;
314  mProjectionMatrix(0, 1) = 0.0f;
315  mProjectionMatrix(1, 1) = 2.0f * dMin * invUDiff;
316  mProjectionMatrix(2, 1) = -(uMin + uMax) * invUDiff;
317  mProjectionMatrix(3, 1) = 0.0f;
318  mProjectionMatrix(0, 2) = 0.0f;
319  mProjectionMatrix(1, 2) = 0.0f;
320  mProjectionMatrix(2, 2) = dMax * invDDiff;
321  mProjectionMatrix(3, 2) = -dMin * dMax * invDDiff;
322  mProjectionMatrix(0, 3) = 0.0f;
323  mProjectionMatrix(1, 3) = 0.0f;
324  mProjectionMatrix(2, 3) = 1.0f;
325  mProjectionMatrix(3, 3) = 0.0f;
326  }
327  else
328  {
329  mProjectionMatrix(0, 0) = 2.0f * dMin * invRDiff;
330  mProjectionMatrix(1, 0) = 0.0f;
331  mProjectionMatrix(2, 0) = -(rMin + rMax) * invRDiff;
332  mProjectionMatrix(3, 0) = 0.0f;
333  mProjectionMatrix(0, 1) = 0.0f;
334  mProjectionMatrix(1, 1) = 2.0f * dMin * invUDiff;
335  mProjectionMatrix(2, 1) = -(uMin + uMax) * invUDiff;
336  mProjectionMatrix(3, 1) = 0.0f;
337  mProjectionMatrix(0, 2) = 0.0f;
338  mProjectionMatrix(1, 2) = 0.0f;
339  mProjectionMatrix(2, 2) = (dMin + dMax) * invDDiff;
340  mProjectionMatrix(3, 2) = -2.0f * dMin * dMax * invDDiff;
341  mProjectionMatrix(0, 3) = 0.0f;
342  mProjectionMatrix(1, 3) = 0.0f;
343  mProjectionMatrix(2, 3) = 1.0f;
344  mProjectionMatrix(3, 3) = 0.0f;
345  }
346 #endif
347  }
348  else
349  {
350 #if defined (GTE_USE_MAT_VEC)
352  {
353  mProjectionMatrix(0, 0) = 2.0f * invRDiff;
354  mProjectionMatrix(0, 1) = 0.0f;
355  mProjectionMatrix(0, 2) = 0.0f;
356  mProjectionMatrix(0, 3) = -(rMin + rMax) * invRDiff;
357  mProjectionMatrix(1, 0) = 0.0f;
358  mProjectionMatrix(1, 1) = 2.0f * invUDiff;
359  mProjectionMatrix(1, 2) = 0.0f;
360  mProjectionMatrix(1, 3) = -(uMin + uMax) * invUDiff;
361  mProjectionMatrix(2, 0) = 0.0f;
362  mProjectionMatrix(2, 1) = 0.0f;
363  mProjectionMatrix(2, 2) = invDDiff;
364  mProjectionMatrix(2, 3) = -dMin * invDDiff;
365  mProjectionMatrix(3, 0) = 0.0f;
366  mProjectionMatrix(3, 1) = 0.0f;
367  mProjectionMatrix(3, 2) = 0.0f;
368  mProjectionMatrix(3, 3) = 1.0f;
369  }
370  else
371  {
372  mProjectionMatrix(0, 0) = 2.0f * invRDiff;
373  mProjectionMatrix(0, 1) = 0.0f;
374  mProjectionMatrix(0, 2) = 0.0f;
375  mProjectionMatrix(0, 3) = -(rMin + rMax) * invRDiff;
376  mProjectionMatrix(1, 0) = 0.0f;
377  mProjectionMatrix(1, 1) = 2.0f * invUDiff;
378  mProjectionMatrix(1, 2) = 0.0f;
379  mProjectionMatrix(1, 3) = -(uMin + uMax) * invUDiff;
380  mProjectionMatrix(2, 0) = 0.0f;
381  mProjectionMatrix(2, 1) = 0.0f;
382  mProjectionMatrix(2, 2) = 2.0f * invDDiff;
383  mProjectionMatrix(2, 3) = -(dMin + dMax) * invDDiff;
384  mProjectionMatrix(3, 0) = 0.0f;
385  mProjectionMatrix(3, 1) = 0.0f;
386  mProjectionMatrix(3, 2) = 0.0f;
387  mProjectionMatrix(3, 3) = 1.0f;
388  }
389 #else
391  {
392  mProjectionMatrix(0, 0) = 2.0f * invRDiff;
393  mProjectionMatrix(1, 0) = 0.0f;
394  mProjectionMatrix(2, 0) = 0.0f;
395  mProjectionMatrix(3, 0) = -(rMin + rMax) * invRDiff;
396  mProjectionMatrix(0, 1) = 0.0f;
397  mProjectionMatrix(1, 1) = 2.0f * invUDiff;
398  mProjectionMatrix(2, 1) = 0.0f;
399  mProjectionMatrix(3, 1) = -(uMin + uMax) * invUDiff;
400  mProjectionMatrix(0, 2) = 0.0f;
401  mProjectionMatrix(1, 2) = 0.0f;
402  mProjectionMatrix(2, 2) = invDDiff;
403  mProjectionMatrix(3, 2) = -dMin * invDDiff;
404  mProjectionMatrix(0, 3) = 0.0f;
405  mProjectionMatrix(1, 3) = 0.0f;
406  mProjectionMatrix(2, 3) = 0.0f;
407  mProjectionMatrix(3, 3) = 1.0f;
408  }
409  else
410  {
411  mProjectionMatrix(0, 0) = 2.0f * invRDiff;
412  mProjectionMatrix(1, 0) = 0.0f;
413  mProjectionMatrix(2, 0) = 0.0f;
414  mProjectionMatrix(3, 0) = -(rMin + rMax) * invRDiff;
415  mProjectionMatrix(0, 1) = 0.0f;
416  mProjectionMatrix(1, 1) = 2.0f * invUDiff;
417  mProjectionMatrix(2, 1) = 0.0f;
418  mProjectionMatrix(3, 1) = -(uMin + uMax) * invUDiff;
419  mProjectionMatrix(0, 2) = 0.0f;
420  mProjectionMatrix(1, 2) = 0.0f;
421  mProjectionMatrix(2, 2) = invDDiff;
422  mProjectionMatrix(3, 2) = -(dMin + dMax) * invDDiff;
423  mProjectionMatrix(0, 3) = 0.0f;
424  mProjectionMatrix(1, 3) = 0.0f;
425  mProjectionMatrix(2, 3) = 0.0f;
426  mProjectionMatrix(3, 3) = 1.0f;
427  }
428 #endif
429  }
430 
431  UpdatePVMatrix();
432 }
433 
435 {
438 
439 #if defined(GTE_USE_MAT_VEC)
440  pvMatrix = pMatrix * mViewMatrix;
441 #else
442  pvMatrix = mViewMatrix * pMatrix;
443 #endif
444 }
virtual void UpdatePVMatrix()
virtual void OnFrustumChange()
void SetFrame(Vector4< float > const &position, Vector4< float > const &dVector, Vector4< float > const &uVector, Vector4< float > const &rVector)
void SetPosition(Vector4< float > const &position)
Vector4< float > mPosition
void SetAxes(Vector4< float > const &dVector, Vector4< float > const &uVector, Vector4< float > const &rVector)
Matrix4x4< float > mInverseViewMatrix
Matrix4x4< float > mProjectionMatrix
float mFrustum[VF_QUANTITY]
#define GTE_C_RAD_TO_DEG
Definition: GteConstants.h:27
Vector4< float > mUVector
virtual ~ViewVolume()
ViewVolume(bool isPerspective, bool isDepthRangeZeroToOne)
#define LogError(message)
Definition: GteLogger.h:92
Matrix4x4< float > mProjectionViewMatrix
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Vector4< float > mDVector
bool mValidateCoordinateFrame
Real DotCross(Vector< N, Real > const &v0, Vector< N, Real > const &v1, Vector< N, Real > const &v2)
Definition: GteVector3.h:140
void GetFrame(Vector4< float > &position, Vector4< float > &dVector, Vector4< float > &uVector, Vector4< float > &rVector) const
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
Matrix4x4< float > mViewMatrix
#define GTE_C_DEG_TO_RAD
Definition: GteConstants.h:26
const GLdouble * v
Definition: glcorearb.h:832
void GetAxes(Vector4< float > &dVector, Vector4< float > &uVector, Vector4< float > &rVector) const
GLfloat f
Definition: glcorearb.h:1921
Vector4< float > mRVector
float const * GetFrustum() const
virtual void OnFrameChange()
void SetFrustum(float dMin, float dMax, float uMin, float uMax, float rMin, float rMax)


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:02