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

Revision 2986, 8.4 KB checked in by mattausch, 16 years ago (diff)

debug version trying to retrieve position from linear eye space depth

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
[2753]18Camera::Camera()
19{
20        mWidth = 100;
21        mHeight = 100;
[2796]22        mFovy = 60.0f * M_PI / 180.0f;
23        mIsOrtho = false;
24       
25        SetPosition(Vector3(0, 0, 0));
26
27        mPitch = mYaw = 0;
[2917]28        Precompute(baseDir);
[2887]29
30        CalculateFromPitchAndYaw();
[2753]31}
32
33
34Camera::Camera(int width, int height, float fieldOfView)
35{
36        mWidth = width;
37        mHeight = height;
38       
[2760]39        mFovy = fieldOfView * M_PI / 180.0f;
[2796]40
41        mIsOrtho = false;
42
[2942]43        SetPosition(Vector3::ZERO());
[2796]44
45        mPitch = mYaw = 0;
[2918]46        Precompute(baseDir);
[2887]47
48        CalculateFromPitchAndYaw();
[2753]49}
50
51
[2928]52void Camera::Precompute(const Vector3 &dir)
[2753]53{
[2928]54        Vector3 up = Vector3::UNIT_Z();
[2941]55        //Vector3 right = Normalize(CrossProd(dir, up));
56        //up = Normalize(CrossProd(right, dir));
[2753]57
[2941]58        //mBaseOrientation = Matrix4x4(right, up, -dir);
[2944]59        mBaseOrientation = LookAt(Vector3::ZERO(), dir, up);//Matrix4x4(right, up, -dir);
[2796]60        mViewOrientation = mBaseOrientation;
[2753]61}
62
63
64void Camera::SetPosition(const Vector3 &pos)
65{
66        mPosition = pos;
67}
68
69
[2764]70void Camera::SetNear(float nearDist)
71{
72        mNear = nearDist;
73}
74
75
[2806]76void Camera::SetFar(float farDist)
77{
78        mFar = farDist;
79}
80
81
[2986]82void Camera::GetProjectionMatrix(Matrix4x4 &mat) const
[2755]83{
84        glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x);
[2753]85}
86
[2755]87
[2986]88void Camera::GetModelViewMatrix(Matrix4x4 &mat) const
[2755]89{
[2893]90        mat = mViewOrientation;
91
[2932]92        // note: left handed system => we go into positive z
93        mat.x[3][0] = -DotProd(GetRightVector(), mPosition);
94        mat.x[3][1] = -DotProd(GetUpVector(), mPosition);
95        mat.x[3][2] = DotProd(GetDirection(), mPosition);
[2755]96}
97
98
[2986]99void Camera::GetViewOrientationMatrix(Matrix4x4 &mat) const
100{
101        mat = mViewOrientation;
102}
103
104
[2755]105void Camera::CalcFrustum(Frustum &frustum)
106{
107        // we grab the plane equations of the six clipplanes of the viewfrustum
108        Matrix4x4 matViewing, matProjectionView;
109
110        GetModelViewMatrix(matViewing);
111        GetProjectionMatrix(matProjectionView);
112
[2762]113        matProjectionView = matViewing * matProjectionView;
[2755]114
[2911]115        frustum = Frustum(matProjectionView);
[2762]116
[2944]117
[2755]118        ////////////
119        //-- normalize the coefficients
120
121        for (int i = 0; i < 6; ++ i)
122        {
123                // the clipping planes look outward the frustum,
124                // so distances > 0 mean that a point is outside
[2911]125                const float invLength = -1.0f / Magnitude(frustum.mClipPlanes[i].mNormal);
126       
127                frustum.mClipPlanes[i].mD *= invLength;
128                frustum.mClipPlanes[i].mNormal *= invLength;
[2755]129        }
130}
131
132
[2756]133void Camera::SetupCameraView()
134{
[2932]135        Matrix4x4 m;
136        GetModelViewMatrix(m);
[2780]137
[2932]138        glLoadMatrixf((float *)m.x);
[2755]139}
140
[2756]141
[2986]142
[2911]143void Camera::ComputePointsInternal(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
144                                                                   Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
145                                                                   const Vector3 &view, const Vector3 &right, const Vector3 &up,
[2947]146                                                                   const Vector3 &pos,
147                                                                   float farthestVisibleDistance) const
[2762]148{
[2806]149        float z_near = mNear;
[2947]150        float z_far = min(mFar, farthestVisibleDistance);
[2762]151
[2891]152        float fov = mFovy;
[2889]153
[2913]154        const float aspectRatio = GetAspect();
155
[2914]156        const float h_near = tan(fov * 0.5f) * z_near;
157        const float w_near = h_near * aspectRatio;
[2889]158
[2914]159        const float h_far = tan(fov * 0.5f) * z_far;
160        const float w_far = h_far * aspectRatio;
[2762]161
[2911]162        const Vector3 fc = pos + view * z_far;
[2762]163       
[2986]164        cout << "fovx: " << 0.5f * mFovy * aspectRatio << " " << mFovy * 0.5f << endl;
165
[2762]166        Vector3 t1, t2;
167
[2914]168        t1 = h_far * up;
169        t2 = w_far * right;
[2762]170
171        ftl = fc + t1 - t2;
172        ftr = fc + t1 + t2;
173        fbl = fc - t1 - t2;
174        fbr = fc - t1 + t2;
175
[2911]176        const Vector3 nc = pos + view * z_near;
[2762]177       
[2914]178        t1 = h_near * up;
179        t2 = w_near * right;
[2762]180
181        ntl = nc + t1 - t2;
182        ntr = nc + t1 + t2;
183        nbl = nc - t1 - t2;
184        nbr = nc - t1 + t2;
[2756]185}
186
[2762]187
[2911]188void Camera::ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
[2947]189                                                   Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr,
190                                                   float farthestVisibleDistance) const
[2911]191{
192        ComputePointsInternal(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr,
[2947]193                                                  GetDirection(), GetRightVector(), GetUpVector(), GetPosition(),
194                                                  farthestVisibleDistance);
[2911]195}
196
197
[2796]198void Camera::SetOrtho(bool ortho)
199{
200        mIsOrtho = true;
[2762]201}
202
[2796]203
204void Camera::Yaw(float angle)
205{
206        mYaw += angle;
207        CalculateFromPitchAndYaw();
208}
209
210
211void Camera::Pitch(float angle)
212{
213        mPitch += angle;
214        CalculateFromPitchAndYaw();
215}
216
217
[2864]218void Camera::SetDirection(const Vector3 &dir)
[2829]219{
[2927]220        Vector3 ndir = -Normalize(dir);
[2829]221
[2888]222        mPitch = -atan2(ndir.x, ndir.y);
223        mYaw = atan2(ndir.z, sqrt((ndir.x * ndir.x) + (ndir.y * ndir.y)));
[2887]224
[2829]225        CalculateFromPitchAndYaw();
226}
227
228
[2796]229void Camera::CalculateFromPitchAndYaw()
230{
231        mViewOrientation = mBaseOrientation;
232
233        Matrix4x4 roty = RotationYMatrix(mPitch);
234        Matrix4x4 rotx = RotationXMatrix(mYaw);
235
236        mViewOrientation *= roty;
237        mViewOrientation *= rotx;
238}
239
240
241Vector3 Camera::GetDirection() const
242{
[2927]243        return -Vector3(mViewOrientation.x[0][2], mViewOrientation.x[1][2], mViewOrientation.x[2][2]);
[2796]244}
245
246
247Vector3 Camera::GetUpVector() const
248{
249        return Vector3(mViewOrientation.x[0][1], mViewOrientation.x[1][1], mViewOrientation.x[2][1]);
250}
251
252
253Vector3 Camera::GetRightVector() const
254{
[2911]255        return Vector3(mViewOrientation.x[0][0], mViewOrientation.x[1][0], mViewOrientation.x[2][0]);           
[2796]256}
257
258
[2911]259Vector3 Camera::GetBaseDirection() const
260{
[2927]261        return -Vector3(mBaseOrientation.x[0][2], mBaseOrientation.x[1][2], mBaseOrientation.x[2][2]);
[2796]262}
263
[2911]264
265Vector3 Camera::GetBaseUpVector() const
266{
267        return Vector3(mBaseOrientation.x[0][1], mBaseOrientation.x[1][1], mBaseOrientation.x[2][1]);
268}
269
270
271Vector3 Camera::GetBaseRightVector() const
272{
273        return Vector3(mBaseOrientation.x[0][0], mBaseOrientation.x[1][0], mBaseOrientation.x[2][0]);
274}
275
276
277Frustum::Frustum(const Matrix4x4 &trafo)
278{
279        //////////
280        //-- extract the plane equations
281
282        for (int i = 0; i < 4; ++ i)
283        {
284                mClipPlanes[Frustum::RIGHT_PLANE][i] = trafo.x[i][3] - trafo.x[i][0];
285                mClipPlanes[Frustum::LEFT_PLANE][i] = trafo.x[i][3] + trafo.x[i][0];
[2936]286               
[2911]287                mClipPlanes[Frustum::BOTTOM_PLANE][i] = trafo.x[i][3] + trafo.x[i][1];
288                mClipPlanes[Frustum::TOP_PLANE][i] = trafo.x[i][3] - trafo.x[i][1];
[2936]289
[2911]290                mClipPlanes[Frustum::FAR_PLANE][i] = trafo.x[i][3] - trafo.x[i][2];
291                mClipPlanes[Frustum::NEAR_PLANE][i] = trafo.x[i][3] + trafo.x[i][2];
292        }
293}
294
295
296void Frustum::EnclosePolyhedron(const Polyhedron &polyhedron)
297{
298        VertexArray vertices;
299        polyhedron.CollectVertices(vertices);
300
301        for (int i = 0; i < 6; ++ i)
302        {
303                Plane3 &plane = mClipPlanes[i];
304
305                //cout << "p" << i << " " << plane.mD  << endl;
306
307                VertexArray::const_iterator it, it_end = vertices.end();
308
309                float minDist = 1e20;
310
311                for (it = vertices.begin(); it != it_end; ++ it)
312                {
313                        float dist = plane.Distance(*it);
314
315                        if (dist < minDist)
316                        {
317                                cout << "minDist: " << dist << endl;
318                                minDist = dist;
319                        }
320                }
321
322                plane.mD += minDist;
323        }
324}
325
326
327void Frustum::ExtractTransformation(Matrix4x4 &m) const
328{
329        for (int i = 0; i < 4; ++ i)
330        {
331                m.x[i][0] = (mClipPlanes[LEFT_PLANE][i] - mClipPlanes[RIGHT_PLANE][i]) * 0.5f;
332                m.x[i][1] = (mClipPlanes[BOTTOM_PLANE][i] - mClipPlanes[TOP_PLANE][i]) * 0.5f;
333                m.x[i][2] = (mClipPlanes[NEAR_PLANE][i] - mClipPlanes[FAR_PLANE][i]) * 0.5f;
334                m.x[i][3] = (mClipPlanes[LEFT_PLANE][i] + mClipPlanes[RIGHT_PLANE][i]) * 0.5f;
335        }
336}
337
338
[2947]339Polyhedron *Camera::ComputeFrustum(float farthestVisibleDistance) const
[2931]340{
341        Vector3 ftl, ftr, fbl, fbr;
342        Vector3 ntl, ntr, nbl, nbr;
[2911]343
[2931]344        VertexArray sides[6];
345
[2947]346        ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr, farthestVisibleDistance);
[2931]347
348        for (int i = 0; i < 6; ++ i)
349                sides[i].resize(4);
350       
351        // left, right
352        sides[0][0] = ftl; sides[0][1] = fbl; sides[0][2] = nbl; sides[0][3] = ntl;
353        sides[1][0] = fbr; sides[1][1] = ftr; sides[1][2] = ntr; sides[1][3] = nbr;
354        // bottom, top
355        sides[2][0] = fbl; sides[2][1] = fbr; sides[2][2] = nbr; sides[2][3] = nbl;
356        sides[3][0] = ftr; sides[3][1] = ftl; sides[3][2] = ntl; sides[3][3] = ntr;
357        // near, far
358        sides[4][0] = ntr; sides[4][1] = ntl; sides[4][2] = nbl; sides[4][3] = nbr;
359        sides[5][0] = ftl; sides[5][1] = ftr; sides[5][2] = fbr; sides[5][3] = fbl;
360
361
362        //////////
363        //-- compute polyhedron
364
365        PolygonContainer polygons;
366
367        for (int i = 0; i < 6; ++ i)
368        {
369                Polygon3 *poly = new Polygon3(sides[i]);
370                polygons.push_back(poly);
371        }
372
373        return new Polyhedron(polygons);
[2911]374}
375
[2931]376
377}
Note: See TracBrowser for help on using the repository browser.