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

Revision 2838, 6.0 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "common.h"
2#include "Camera.h"
3#include "glInterface.h"
4
5
6namespace CHCDemoEngine
7{
8
9using namespace std;
10
11
12Camera::Camera()
13{
14        mWidth = 100;
15        mHeight = 100;
16        mFovy = 60.0f * M_PI / 180.0f;
17        mIsOrtho = false;
18       
19        SetPosition(Vector3(0, 0, 0));
20
21        mPitch = mYaw = 0;
22        Precompute(Vector3(0, 1, 0));
23}
24
25
26Camera::Camera(int width, int height, float fieldOfView)
27{
28        mWidth = width;
29        mHeight = height;
30       
31        mFovy = fieldOfView * M_PI / 180.0f;
32
33        mIsOrtho = false;
34
35        SetPosition(Vector3(0, 0, 0));
36
37        mPitch = mYaw = 0;
38        Precompute(Vector3(0, 1, 0));
39}
40
41
42void Camera::Precompute(const Vector3 &direction)
43{
44        /*
45        Vector3 side = CrossProd(Vector3(1, 0, 0), direction);
46        Vector3 up = -Normalize(CrossProd(side, direction));
47        Vector3 right = -Normalize(CrossProd(direction, up));
48        */
49        Vector3 up = Vector3(0, 0, 1);
50        Vector3 right = Normalize(CrossProd(up, direction));
51        up = Normalize(CrossProd(direction, right));
52
53        mBaseOrientation = Matrix4x4(right, up, direction);
54        mViewOrientation = mBaseOrientation;
55
56        cout << "right: " << right << endl;
57        cout << "up:    " << up << endl;
58        cout << "dir:   " << direction << endl;
59}
60
61
62
63void Camera::SetPosition(const Vector3 &pos)
64{
65        mPosition = pos;
66}
67
68
69void Camera::SetNear(float nearDist)
70{
71        mNear = nearDist;
72}
73
74
75void Camera::SetFar(float farDist)
76{
77        mFar = farDist;
78}
79
80
81void Camera::GetProjectionMatrix(Matrix4x4 &mat)
82{
83        glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x);
84}
85
86
87void Camera::GetModelViewMatrix(Matrix4x4 &mat)
88{
89        glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mat.x);
90}
91
92
93void Camera::CalcFrustum(Frustum &frustum)
94{
95        // we grab the plane equations of the six clipplanes of the viewfrustum
96        Matrix4x4 matViewing, matProjectionView;
97
98        GetModelViewMatrix(matViewing);
99        GetProjectionMatrix(matProjectionView);
100
101        matProjectionView = matViewing * matProjectionView;
102               
103        float planes[6][4];
104
105
106        //////////
107        //-- extract the plane equations
108
109        for (int i = 0; i < 4; ++ i)
110        {
111                planes[0][i] = matProjectionView.x[i][3] - matProjectionView.x[i][0]; // right plane
112                planes[1][i] = matProjectionView.x[i][3] + matProjectionView.x[i][0]; // left plane
113                planes[2][i] = matProjectionView.x[i][3] + matProjectionView.x[i][1]; // bottom plane
114                planes[3][i] = matProjectionView.x[i][3] - matProjectionView.x[i][1]; // top plane
115                planes[4][i] = matProjectionView.x[i][3] - matProjectionView.x[i][2]; // far plane
116                planes[5][i] = matProjectionView.x[i][3] + matProjectionView.x[i][2]; // near plane
117        }
118
119
120        ////////////
121        //-- normalize the coefficients
122
123        for (int i = 0; i < 6; ++ i)
124        {
125                // the clipping planes look outward the frustum,
126                // so distances > 0 mean that a point is outside
127                float fInvLength = -1.0f /
128                        sqrt(planes[i][0] * planes[i][0] +     
129                             planes[i][1] * planes[i][1] +     
130                                 planes[i][2] * planes[i][2]);
131
132                planes[i][0] *= fInvLength;
133                planes[i][1] *= fInvLength;
134                planes[i][2] *= fInvLength;
135                planes[i][3] *= fInvLength;
136
137                frustum.mClipPlanes[i].mNormal = Vector3(planes[i][0], planes[i][1], planes[i][2]);
138                frustum.mClipPlanes[i].mD = planes[i][3];
139        }
140}
141
142
143void Camera::Frustum::CalcNPVertexIndices(int *indices)
144{
145        for (int i = 0; i < 6; ++ i)
146        {
147                // n-vertex
148                indices[i * 2 + 0] = AxisAlignedBox3::GetIndexNearestVertex(mClipPlanes[i].mNormal);
149                // p-vertex
150                indices[i * 2 + 1] = AxisAlignedBox3::GetIndexFarthestVertex(mClipPlanes[i].mNormal);   
151        }
152}
153
154
155void Camera::SetupCameraView()
156{
157        Matrix4x4 tview = mViewOrientation;
158
159        Vector3 pos = -mPosition;
160        pos = tview * pos;
161
162        Matrix4x4 viewOrientation = mViewOrientation;
163
164        viewOrientation.x[3][0] = pos.x;
165        viewOrientation.x[3][1] = pos.y;
166        viewOrientation.x[3][2] = pos.z;
167
168        glLoadMatrixf((float *)viewOrientation.x);
169}
170
171
172
173void Camera::ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
174                                                   Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr)
175{
176        float z_near = mNear;
177        float z_far = mFar;
178
179        const float w_near = 2.0f * tan(mFovy / 2) * z_near;
180        const float h_near = w_near / GetAspect();
181        const float w_far = 2.0f * tan(mFovy / 2) * z_far;
182        const float h_far = w_far / GetAspect();
183
184        const Vector3 view = GetDirection();
185        const Vector3 fc = mPosition + view * z_far;
186       
187        const Vector3 up = GetUpVector();
188        const Vector3 right = GetRightVector();
189
190        Vector3 t1, t2;
191
192        t1 = h_far * 0.5f * up;
193        t2 = w_far * 0.5f * right;
194
195        ftl = fc + t1 - t2;
196        ftr = fc + t1 + t2;
197        fbl = fc - t1 - t2;
198        fbr = fc - t1 + t2;
199
200        const Vector3 nc = mPosition + view * z_near;
201       
202        t1 = h_near * 0.5f * up;
203        t2 = w_near * 0.5f * right;
204
205        ntl = nc + t1 - t2;
206        ntr = nc + t1 + t2;
207        nbl = nc - t1 - t2;
208        nbr = nc - t1 + t2;
209}
210
211
212void Camera::SetOrtho(bool ortho)
213{
214        mIsOrtho = true;
215}
216
217
218void Camera::Yaw(float angle)
219{
220        mYaw += angle;
221        CalculateFromPitchAndYaw();
222}
223
224
225void Camera::Pitch(float angle)
226{
227        mPitch += angle;
228        CalculateFromPitchAndYaw();
229}
230
231
232void Camera::SetDirection(const Vector3 &direction)
233{
234        Vector3 h1 = direction; h1.z = 0;
235       
236        if (SqrMagnitude(h1) > 0)
237        {
238                h1.Normalize();
239                mPitch = acos(DotProd(h1, Vector3(0, 1, 0)));
240        }
241
242        Vector3 h2 = direction;// h2.x = 0;
243       
244        if (SqrMagnitude(h2) > 0)
245        {
246                h2.Normalize();
247                mYaw = -acos(DotProd(h2, h1));//Vector3(0, 1, 0)));
248        }
249
250        cout<<"here2 " << DotProd(h1, Vector3(0, 1, 0)) << " " << mPitch << endl;
251        CalculateFromPitchAndYaw();
252}
253
254
255void Camera::CalculateFromPitchAndYaw()
256{
257        mViewOrientation = mBaseOrientation;
258
259        Matrix4x4 roty = RotationYMatrix(mPitch);
260        Matrix4x4 rotx = RotationXMatrix(mYaw);
261
262        mViewOrientation *= roty;
263        mViewOrientation *= rotx;
264}
265
266
267Vector3 Camera::GetDirection() const
268{
269        return -Vector3(mViewOrientation.x[0][2], mViewOrientation.x[1][2], mViewOrientation.x[2][2]);
270}
271
272
273Vector3 Camera::GetUpVector() const
274{
275        return Vector3(mViewOrientation.x[0][1], mViewOrientation.x[1][1], mViewOrientation.x[2][1]);
276}
277
278
279Vector3 Camera::GetRightVector() const
280{
281        return Vector3(mViewOrientation.x[0][0], mViewOrientation.x[1][0], mViewOrientation.x[2][0]);
282               
283}
284
285
286}
287
Note: See TracBrowser for help on using the repository browser.