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

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