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

Revision 2893, 6.0 KB checked in by mattausch, 16 years ago (diff)

shadowing partly working

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