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

Revision 2782, 4.7 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
9
10Camera::Camera()
11{
12        mWidth = 100;
13        mHeight = 100;
14        mFovy = 90.0f * M_PI / 180.0f;
15}
16
17
18Camera::Camera(int width, int height, float fieldOfView)
19{
20        mWidth = width;
21        mHeight = height;
22       
23        mFovy = fieldOfView * M_PI / 180.0f;
24}
25
26
27void Camera::Precompute()
28{
29        mDirection.Normalize();
30
31        //Vector3 side = CrossProd(Vector3(0, 1, 0), mDirection);
32        Vector3 side = CrossProd(Vector3(0, 0, 1), mDirection);
33       
34        mUp = -Normalize(CrossProd(side, mDirection));
35        mRight = -Normalize(CrossProd(mDirection, mUp));
36
37        /*float k = tan(mFovy/2);
38        mUp *= k;
39        mRight *= k*mWidth/mHeight;*/
40}
41
42
43void Camera::SetPosition(const Vector3 &pos)
44{
45        mPosition = pos;
46        Precompute();
47}
48
49
50void Camera::SetDirection(const Vector3 &dir)
51{
52        mDirection = dir;
53        Precompute();
54}
55
56
57void Camera::SetNear(float nearDist)
58{
59        mNear = nearDist;
60}
61
62
63void Camera::LookInBox(const AxisAlignedBox3 &box)
64{
65        //mDirection = Vector3(0, 0, 1);
66        mDirection = Vector3(0, 1, 0);
67        mPosition = box.Center();
68        mPosition.z = box.Min(2) + 0.9f * box.Size(2);
69
70        Precompute();
71}
72
73
74void Camera::LookAtBox(const AxisAlignedBox3 &box)
75{
76        mDirection = Vector3(0, box.Min().y - box.Max().y, 0);
77        mPosition = Vector3(0);//box.Max() - mDirection;
78
79        Precompute();
80}
81
82
83void Camera::GetProjectionMatrix(Matrix4x4 &mat)
84{
85        glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x);
86}
87
88
89void Camera::GetModelViewMatrix(Matrix4x4 &mat)
90{
91        glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mat.x);
92}
93
94
95void Camera::CalcFrustum(Frustum &frustum)
96{
97        // we grab the plane equations of the six clipplanes of the viewfrustum
98        Matrix4x4 matViewing, matProjectionView;
99
100        GetModelViewMatrix(matViewing);
101        GetProjectionMatrix(matProjectionView);
102
103        matProjectionView = matViewing * matProjectionView;
104        //matProjectionView = matProjectionView * matViewing;
105       
106        float planes[6][4];
107
108
109        //////////
110        //-- extract the plane equations
111
112        for (int i = 0; i < 4; ++ i)
113        {
114                planes[0][i] = matProjectionView.x[i][3] - matProjectionView.x[i][0]; // right plane
115                planes[1][i] = matProjectionView.x[i][3] + matProjectionView.x[i][0]; // left plane
116                planes[2][i] = matProjectionView.x[i][3] + matProjectionView.x[i][1]; // bottom plane
117                planes[3][i] = matProjectionView.x[i][3] - matProjectionView.x[i][1]; // top plane
118                planes[4][i] = matProjectionView.x[i][3] - matProjectionView.x[i][2]; // far plane
119                planes[5][i] = matProjectionView.x[i][3] + matProjectionView.x[i][2]; // near plane
120        }
121
122
123        ////////////
124        //-- normalize the coefficients
125
126        for (int i = 0; i < 6; ++ i)
127        {
128                // the clipping planes look outward the frustum,
129                // so distances > 0 mean that a point is outside
130                float fInvLength = -1.0f /
131                        sqrt(planes[i][0] * planes[i][0] +     
132                             planes[i][1] * planes[i][1] +     
133                                 planes[i][2] * planes[i][2]);
134
135                planes[i][0] *= fInvLength;
136                planes[i][1] *= fInvLength;
137                planes[i][2] *= fInvLength;
138                planes[i][3] *= fInvLength;
139
140                frustum.mClipPlanes[i].mNormal = Vector3(planes[i][0], planes[i][1], planes[i][2]);
141                frustum.mClipPlanes[i].mD = planes[i][3];
142        }
143}
144
145
146void Camera::Frustum::CalcNPVertexIndices(int *indices)
147{
148        for (int i = 0; i < 6; ++ i)
149        {
150                // n-vertex
151                indices[i * 2 + 0] = AxisAlignedBox3::GetIndexNearestVertex(mClipPlanes[i].mNormal);
152                // p-vertex
153                indices[i * 2 + 1] = AxisAlignedBox3::GetIndexFarthestVertex(mClipPlanes[i].mNormal);   
154        }
155}
156
157
158void Camera::SetupCameraView()
159{
160        glLoadIdentity();
161        gluLookAt(mPosition.x, mPosition.y, mPosition.z,
162                  mPosition.x + mDirection.x, mPosition.y + mDirection.y, mPosition.z + mDirection.z,
163                          mUp.x, mUp.y, mUp.z);
164
165        //std::cout << "dir: " << mDirection << " pos: " << mPosition << " up: " << mUp << std::endl;
166}
167
168
169
170void Camera::ComputePoints(Vector3 &ftl, Vector3 &ftr, Vector3 &fbl, Vector3 &fbr,
171                                                   Vector3 &ntl, Vector3 &ntr, Vector3 &nbl, Vector3 &nbr)
172{
173        float z_near = 0.1f;
174        float z_far = 300;
175
176        const float h_near = 2.0f * tan(mFovy / 2) * z_near;
177        const float w_near = h_near * GetAspect();
178        const float h_far = 2.0f * tan(mFovy / 2) * z_far;
179        const float w_far = h_far * GetAspect();
180
181        const Vector3 view = mDirection;
182        const Vector3 fc = mPosition + view * z_far;
183       
184        const Vector3 up = mUp;
185
186        const Vector3 right = mRight;
187
188        Vector3 t1, t2;
189
190        t1 = h_far * 0.5f * up;
191        t2 = w_far * 0.5f * right;
192
193        ftl = fc + t1 - t2;
194        ftr = fc + t1 + t2;
195        fbl = fc - t1 - t2;
196        fbr = fc - t1 + t2;
197
198        const Vector3 nc = mPosition + mDirection * z_near;
199       
200        t1 = h_near * 0.5f * up;
201        t2 = w_near * 0.5f * right;
202
203        ntl = nc + t1 - t2;
204        ntr = nc + t1 + t2;
205        nbl = nc - t1 - t2;
206        nbr = nc - t1 + t2;
207}
208
209
210}
211
Note: See TracBrowser for help on using the repository browser.