source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Camera.cpp @ 3213

Revision 3213, 9.8 KB checked in by mattausch, 16 years ago (diff)

lense flare starting to work

RevLine 
[2753]1#include "common.h"
2#include "Camera.h"
[2755]3#include "glInterface.h"
[2911]4#include "Polygon3.h"
5#include "Matrix4x4.h"
6#include "Polyhedron.h"
[2753]7
[2776]8namespace CHCDemoEngine
[2753]9{
10
[2796]11using namespace std;
[2753]12
[2932]13// our coordinate system is left-handed
14// we look into positive y and have the positive z axis pointing up
[2928]15static const Vector3 baseDir = -Vector3::UNIT_Y();
[2796]16
[2887]17
[3062]18
19/**********************************************************/
20/*            class Frustum implementation                */
21/**********************************************************/
22
23
24Frustum::Frustum(const Matrix4x4 &trafo)
[2753]25{
[3062]26        //////////
27        //-- extract the plane equations
[2796]28
[3062]29        for (int i = 0; i < 4; ++ i)
30        {
31                mClipPlanes[Frustum::RIGHT_PLANE][i] = trafo.x[i][3] - trafo.x[i][0];
32                mClipPlanes[Frustum::LEFT_PLANE][i] = trafo.x[i][3] + trafo.x[i][0];
33               
34                mClipPlanes[Frustum::BOTTOM_PLANE][i] = trafo.x[i][3] + trafo.x[i][1];
35                mClipPlanes[Frustum::TOP_PLANE][i] = trafo.x[i][3] - trafo.x[i][1];
[2887]36
[3062]37                mClipPlanes[Frustum::FAR_PLANE][i] = trafo.x[i][3] - trafo.x[i][2];
38                mClipPlanes[Frustum::NEAR_PLANE][i] = trafo.x[i][3] + trafo.x[i][2];
39        }
[2753]40}
41
42
[3062]43void Frustum::EnclosePolyhedron(const Polyhedron &polyhedron)
[2753]44{
[3062]45        VertexArray vertices;
46        polyhedron.CollectVertices(vertices);
[2796]47
[3062]48        for (int i = 0; i < 6; ++ i)
49        {
50                Plane3 &plane = mClipPlanes[i];
[2796]51
[3062]52                VertexArray::const_iterator it, it_end = vertices.end();
53                float minDist = 1e20;
54
55                for (it = vertices.begin(); it != it_end; ++ it)
56                {
57                        float dist = plane.Distance(*it);
58
59                        if (dist < minDist)
60                        {
61                                cout << "minDist: " << dist << endl;
62                                minDist = dist;
63                        }
64                }
65
66                plane.mD += minDist;
67        }
68}
69
70
71void Frustum::ExtractTransformation(Matrix4x4 &m) const
72{
73        for (int i = 0; i < 4; ++ i)
74        {
75                m.x[i][0] = (mClipPlanes[LEFT_PLANE][i] - mClipPlanes[RIGHT_PLANE][i]) * 0.5f;
76                m.x[i][1] = (mClipPlanes[BOTTOM_PLANE][i] - mClipPlanes[TOP_PLANE][i]) * 0.5f;
77                m.x[i][2] = (mClipPlanes[NEAR_PLANE][i] - mClipPlanes[FAR_PLANE][i]) * 0.5f;
78                m.x[i][3] = (mClipPlanes[LEFT_PLANE][i] + mClipPlanes[RIGHT_PLANE][i]) * 0.5f;
79        }
80}
81
82
83
84/*********************************************************/
85/*            class Camera implementation                */
86/*********************************************************/
87
88
89Camera::Camera()
90{
91        SetPosition(Vector3(0, 0, 0));
92
[2796]93        mPitch = mYaw = 0;
[2918]94        Precompute(baseDir);
[2887]95
96        CalculateFromPitchAndYaw();
[2753]97}
98
99
[2928]100void Camera::Precompute(const Vector3 &dir)
[2753]101{
[2928]102        Vector3 up = Vector3::UNIT_Z();
[3061]103       
104        mBaseOrientation = LookAt(Vector3::ZERO(), dir, up);
[2796]105        mViewOrientation = mBaseOrientation;
[2753]106}
107
108
109void Camera::SetPosition(const Vector3 &pos)
110{
111        mPosition = pos;
112}
113
114
[2764]115void Camera::SetNear(float nearDist)
116{
117        mNear = nearDist;
[3063]118        UpdateProjectionMatrix();
[2764]119}
120
121
[2806]122void Camera::SetFar(float farDist)
123{
124        mFar = farDist;
[3063]125        UpdateProjectionMatrix();
[2806]126}
127
128
[2986]129void Camera::GetModelViewMatrix(Matrix4x4 &mat) const
[2755]130{
[2893]131        mat = mViewOrientation;
132
[2932]133        // note: left handed system => we go into positive z
134        mat.x[3][0] = -DotProd(GetRightVector(), mPosition);
135        mat.x[3][1] = -DotProd(GetUpVector(), mPosition);
[3213]136        mat.x[3][2] =  DotProd(GetDirection(), mPosition);
[2755]137}
138
139
[2986]140void Camera::GetViewOrientationMatrix(Matrix4x4 &mat) const
141{
142        mat = mViewOrientation;
143}
144
145
[3061]146void Camera::SetupViewProjection()
147{
148        glMatrixMode(GL_PROJECTION);
149        SetupProjection();
150
151        glMatrixMode(GL_MODELVIEW);
152        // set up the view matrix
153        SetupCameraView();
154}
155
156
157void Camera::SetupProjection()
158{
[3062]159        Matrix4x4 m;
160
161        GetProjectionMatrix(m);
162        glLoadMatrixf((float *)m.x);
[3061]163}
164
165
[2756]166void Camera::SetupCameraView()
167{
[2932]168        Matrix4x4 m;
169        GetModelViewMatrix(m);
[2780]170
[2932]171        glLoadMatrixf((float *)m.x);
[2755]172}
173
[2756]174
[2796]175void Camera::Yaw(float angle)
176{
177        mYaw += angle;
178        CalculateFromPitchAndYaw();
179}
180
181
182void Camera::Pitch(float angle)
183{
184        mPitch += angle;
185        CalculateFromPitchAndYaw();
186}
187
188
[2864]189void Camera::SetDirection(const Vector3 &dir)
[2829]190{
[2927]191        Vector3 ndir = -Normalize(dir);
[2829]192
[2888]193        mPitch = -atan2(ndir.x, ndir.y);
194        mYaw = atan2(ndir.z, sqrt((ndir.x * ndir.x) + (ndir.y * ndir.y)));
[2887]195
[2829]196        CalculateFromPitchAndYaw();
197}
198
199
[2796]200void Camera::CalculateFromPitchAndYaw()
201{
202        mViewOrientation = mBaseOrientation;
203
204        Matrix4x4 roty = RotationYMatrix(mPitch);
205        Matrix4x4 rotx = RotationXMatrix(mYaw);
206
207        mViewOrientation *= roty;
208        mViewOrientation *= rotx;
209}
210
211
212Vector3 Camera::GetDirection() const
213{
[2927]214        return -Vector3(mViewOrientation.x[0][2], mViewOrientation.x[1][2], mViewOrientation.x[2][2]);
[2796]215}
216
217
218Vector3 Camera::GetUpVector() const
219{
220        return Vector3(mViewOrientation.x[0][1], mViewOrientation.x[1][1], mViewOrientation.x[2][1]);
221}
222
223
224Vector3 Camera::GetRightVector() const
225{
[2911]226        return Vector3(mViewOrientation.x[0][0], mViewOrientation.x[1][0], mViewOrientation.x[2][0]);           
[2796]227}
228
229
[2911]230Vector3 Camera::GetBaseDirection() const
231{
[2927]232        return -Vector3(mBaseOrientation.x[0][2], mBaseOrientation.x[1][2], mBaseOrientation.x[2][2]);
[2796]233}
234
[2911]235
236Vector3 Camera::GetBaseUpVector() const
237{
238        return Vector3(mBaseOrientation.x[0][1], mBaseOrientation.x[1][1], mBaseOrientation.x[2][1]);
239}
240
241
242Vector3 Camera::GetBaseRightVector() const
243{
244        return Vector3(mBaseOrientation.x[0][0], mBaseOrientation.x[1][0], mBaseOrientation.x[2][0]);
245}
246
247
[3062]248void Camera::CalcFrustum(Frustum &frustum)
[2911]249{
[3062]250        // we grab the plane equations of the six clipplanes of the viewfrustum
251        Matrix4x4 matViewing, matProjectionView;
[2911]252
[3062]253        GetModelViewMatrix(matViewing);
254        GetProjectionMatrix(matProjectionView);
[2936]255
[3062]256        matProjectionView = matViewing * matProjectionView;
[2911]257
[3062]258        frustum = Frustum(matProjectionView);
[2911]259
260
[3062]261        ////////////
262        //-- normalize the coefficients
263
[2911]264        for (int i = 0; i < 6; ++ i)
265        {
[3062]266                // the clipping planes look outward the frustum,
267                // so distances > 0 mean that a point is outside
268                const float invLength = -1.0f / Magnitude(frustum.mClipPlanes[i].mNormal);
269       
270                frustum.mClipPlanes[i].mD *= invLength;
271                frustum.mClipPlanes[i].mNormal *= invLength;
272        }
273}
[2911]274
275
[3063]276void Camera::GetProjectionMatrix(Matrix4x4 &m)const
277{
[3102]278        //glGetFloatv(GL_PROJECTION_MATRIX, (float *)m.x);
[3063]279        m = mProjection;
280}
281
282
[3102]283
[3062]284/*********************************************************/
[3102]285/*       Class PerspectiveCamera implementation          */
[3062]286/*********************************************************/
[2911]287
288
[3062]289PerspectiveCamera::PerspectiveCamera()
290{
291        mFOVy = 60.0f * M_PI / 180.0f;
[3063]292        mAspect = 1.0f;
293
294        UpdateProjectionMatrix();
[2911]295}
296
297
[3062]298PerspectiveCamera::PerspectiveCamera(float aspect, float fieldOfView)
[2911]299{
[3062]300        mFOVy = fieldOfView * M_PI / 180.0f;
301        mAspect = aspect;
[3063]302
303        UpdateProjectionMatrix();
[2911]304}
305
306
[3062]307Polyhedron *PerspectiveCamera::ComputeFrustum(float farthestVisibleDistance) const
[2931]308{
309        Vector3 ftl, ftr, fbl, fbr;
310        Vector3 ntl, ntr, nbl, nbr;
[2911]311
[2931]312        VertexArray sides[6];
313
[2947]314        ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr, farthestVisibleDistance);
[2931]315
316        for (int i = 0; i < 6; ++ i)
317                sides[i].resize(4);
318       
319        // left, right
320        sides[0][0] = ftl; sides[0][1] = fbl; sides[0][2] = nbl; sides[0][3] = ntl;
321        sides[1][0] = fbr; sides[1][1] = ftr; sides[1][2] = ntr; sides[1][3] = nbr;
322        // bottom, top
323        sides[2][0] = fbl; sides[2][1] = fbr; sides[2][2] = nbr; sides[2][3] = nbl;
324        sides[3][0] = ftr; sides[3][1] = ftl; sides[3][2] = ntl; sides[3][3] = ntr;
325        // near, far
326        sides[4][0] = ntr; sides[4][1] = ntl; sides[4][2] = nbl; sides[4][3] = nbr;
327        sides[5][0] = ftl; sides[5][1] = ftr; sides[5][2] = fbr; sides[5][3] = fbl;
328
329
330        //////////
331        //-- compute polyhedron
332
333        PolygonContainer polygons;
334
335        for (int i = 0; i < 6; ++ i)
336        {
337                Polygon3 *poly = new Polygon3(sides[i]);
338                polygons.push_back(poly);
339        }
340
341        return new Polyhedron(polygons);
[2911]342}
343
[2931]344
[3062]345void PerspectiveCamera::ComputePointsInternal(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
346                                                                                          Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
347                                                                                          const Vector3 &view, const Vector3 &right, const Vector3 &up,
348                                                                                          const Vector3 &pos,
349                                                                                          float farthestVisibleDistance) const
350{
351        const float z_near = mNear;
352        const float z_far = min(mFar, farthestVisibleDistance);
353
354        const float fov = mFOVy;
355
356        const float aspectRatio = GetAspect();
357
358        const float h_near = tan(fov * 0.5f) * z_near;
359        const float w_near = h_near * aspectRatio;
360
361        const float h_far = tan(fov * 0.5f) * z_far;
362        const float w_far = h_far * aspectRatio;
363
364        const Vector3 fc = pos + view * z_far;
365       
366
367        Vector3 t1, t2;
368
369        t1 = h_far * up;
370        t2 = w_far * right;
371
372        ftl = fc + t1 - t2;
373        ftr = fc + t1 + t2;
374        fbl = fc - t1 - t2;
375        fbr = fc - t1 + t2;
376
377        const Vector3 nc = pos + view * z_near;
378       
379        t1 = h_near * up;
380        t2 = w_near * right;
381
382        ntl = nc + t1 - t2;
383        ntr = nc + t1 + t2;
384        nbl = nc - t1 - t2;
385        nbr = nc - t1 + t2;
386}
387
388
[3102]389void PerspectiveCamera::UpdateProjectionMatrix()
390{
391        mProjection = GetPerspective(mFOVy, 1.0f / mAspect, mNear, mFar);
392}
393
394
395
[3062]396void PerspectiveCamera::ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
397                                                                          Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
398                                                                          float farthestVisibleDistance) const
399{
400        ComputePointsInternal(ftl, ftr, fbl, fbr,
401                                  ntl, ntr, nbl, nbr,
402                                                  GetDirection(), GetRightVector(), GetUpVector(),
403                                                  GetPosition(),
404                                                  farthestVisibleDistance);
405}
406
407
[3102]408
409/*********************************************************/
410/*          Class OrthoCamera implementation             */
411/*********************************************************/
412
413
414OrthoCamera::OrthoCamera():
415mLeft(0), mRight(1), mBottom(0), mTop(1)
[3062]416{
[3102]417        mNear = 0; mFar = 1;
418        UpdateProjectionMatrix();
[3062]419}
420
421
[3102]422OrthoCamera::OrthoCamera(float l, float r, float b, float t):
423mLeft(l), mRight(r), mBottom(b), mTop(t)
424{
425        mNear = 0; mFar = 1;
426        UpdateProjectionMatrix();
427}
428
429
430OrthoCamera::OrthoCamera(float l, float r, float b, float t, float n, float f):
431mLeft(l), mRight(r), mBottom(b), mTop(t)
432{
433        mNear = n; mFar = f;
434        UpdateProjectionMatrix();
435}
436
437
438void OrthoCamera::UpdateProjectionMatrix()
439{
440        mProjection = GetOrtho(mLeft, mRight, mBottom, mTop, mNear, mFar);
441}
442
443
[2931]444}
Note: See TracBrowser for help on using the repository browser.