00001 #include "VCamera.h"
00002
00008 VCamera::VCamera() : mFov(45.0f), mNearPlane(0.001f), mPosition(), mOrientation(),
00009 mViewMatrix(), mProjMatrix(), mScreenDistance(3.5f),
00010 mEyeSeparation(0.06f), mMustUpdateProjection(true), mMustUpdateView(true),
00011 mOrthogonalCamera(false), mOrthogonalSize(), mIsShadowCamera(false)
00012 {
00013
00014 mAspectRatio = 1.0f + (1.0f / 3.0f);
00015 mFarPlane = 100.0f;
00016 }
00017
00024 void VCamera::setProjection(int width, int height)
00025 {
00026 if (height == 0)
00027 {
00028 height = 1;
00029 }
00030
00031 mAspectRatio = (float)width / (float)height;
00032
00033 mMustUpdateProjection = true;
00034 updateProjMatrix();
00035 }
00036
00042 void VCamera::updateProjMatrix()
00043 {
00044 if(mMustUpdateProjection)
00045 {
00046 if(mOrthogonalCamera)
00047 {
00048
00049
00050
00051
00052
00053
00054 float right = 1.1f;
00055 float left = -right;
00056 float top = 1.1f;
00057 float bottom = -top;
00058
00059 mProjMatrix.clearMatrix();
00060 mProjMatrix[0] = 2.0f / (right - left);
00061 mProjMatrix[5] = 2.0f / (top - bottom);
00062 mProjMatrix[10] = (-2.0f / (mFarPlane - mNearPlane));
00063 mProjMatrix[12] = - (right + left) / (right - left);
00064 mProjMatrix[13] = - (top + bottom) / (top - bottom);
00065 mProjMatrix[14] = - (mFarPlane + mNearPlane) / (mFarPlane - mNearPlane);
00066 mProjMatrix[15] = 1.0f;
00067
00068 }
00069 else
00070 {
00071 float radian = ( PI/ 180) * (mFov/2);
00072 float tanFov = ::tan(radian);
00073 float right = mAspectRatio * tanFov * mNearPlane;
00074 float left = -right;
00075 float top = tanFov * mNearPlane;
00076 float bottom = -top;
00077
00078 mProjMatrix[0] = (2.0f * mNearPlane) / (right - left);
00079 mProjMatrix[5] = (2.0f * mNearPlane) / (top - bottom);
00080 mProjMatrix[8] = (right + left) / (right - left);
00081 mProjMatrix[9] = (top + bottom) / (top - bottom);
00082 mProjMatrix[10] = (-(mFarPlane + mNearPlane)) / (mFarPlane - mNearPlane);
00083 mProjMatrix[11] = -1.0f;
00084 mProjMatrix[14] = (-(2.0f * mNearPlane * mFarPlane) / (mFarPlane - mNearPlane));
00085 mProjMatrix[15] = 0.0f;
00086 }
00087 mMustUpdateProjection = false;
00088 }
00089 }
00090
00096 void VCamera::updateProjMatrixLeft()
00097 {
00098 if(mMustUpdateProjection)
00099 {
00100 this->updateProjMatrix();
00101 }
00102 VMatrix asymMatrix;
00103 asymMatrix[8] = mEyeSeparation / (2.0f * mScreenDistance);
00104
00105 mLeftProjMatrix = mProjMatrix * asymMatrix;
00106 }
00107
00113 void VCamera::updateProjMatrixRight()
00114 {
00115 if(mMustUpdateProjection)
00116 {
00117 this->updateProjMatrix();
00118 }
00119
00120 VMatrix asymMatrix;
00121 asymMatrix[8] = -mEyeSeparation / (2.0f * mScreenDistance);
00122
00123 mRightProjMatrix = mProjMatrix * asymMatrix;
00124 }
00125
00130 void VCamera::setProjectionToInfinity()
00131 {
00132 mProjMatrix[10] = -1.0f;
00133 mProjMatrix[14] = -2.0f * mNearPlane;
00134 }
00135
00140 void VCamera::setProjectionToNormal()
00141 {
00142 mProjMatrix[10] = (mFarPlane + mNearPlane) / (mNearPlane - mFarPlane);
00143 mProjMatrix[14] = (2 * mNearPlane * mFarPlane) / (mNearPlane - mFarPlane);
00144 }
00145
00150 void VCamera::rotateX(float m_degrees)
00151 {
00152 mOrientation.normalize();
00153 mOrientation.applyRotationX(-m_degrees);
00154 mMustUpdateView = true;
00155 }
00156
00161 void VCamera::rotateY(float m_degrees)
00162 {
00163 mOrientation.normalize();
00164 mOrientation.applyRotationY(-m_degrees);
00165 mMustUpdateView = true;
00166 }
00167
00172 void VCamera::rotateZ(float m_degrees)
00173 {
00174 mOrientation.normalize();
00175 mOrientation.applyRotationZ(-m_degrees);
00176 mMustUpdateView = true;
00177 }
00178
00179 void VCamera::rotate(float m_degrees, float ax, float ay, float az)
00180 {
00181 mOrientation.normalize();
00182
00183 mOrientation.applyRotationZ(-m_degrees);
00184 mMustUpdateView = true;
00185 }
00186
00193 void VCamera::lookInDirection(VVector eye, VVector view, VVector up)
00194 {
00195 VVector side;
00196
00197 mViewMatrix.clearMatrix();
00198
00199 view.normalize();
00200 up.normalize();
00201
00202
00203 side = view.getCross(up);
00204 side.normalize();
00205
00206 up = side.getCross(view);
00207 up.normalize();
00208
00209
00210
00211 mViewMatrix[0] = side.getX();
00212 mViewMatrix[4] = side.getY();
00213 mViewMatrix[8] = side.getZ();
00214
00215 mViewMatrix[1] = up.getX();
00216 mViewMatrix[5] = up.getY();
00217 mViewMatrix[9] = up.getZ();
00218
00219 mViewMatrix[2] = -view.getX();
00220 mViewMatrix[6] = -view.getY();
00221 mViewMatrix[10] = -view.getZ();
00222
00223 mViewMatrix.translate(-eye);
00224
00225 mPosition = eye;
00226
00227 mOrientation = mViewMatrix.getRotation();
00228 mOrientation.normalize();
00229
00230 mMustUpdateView = false;
00231
00232
00233
00234
00235
00236
00237 }
00238
00244 void VCamera::updateViewMatrix()
00245 {
00246 if(mMustUpdateView)
00247 {
00248 mOrientation.normalize();
00249 VQuaternion tmpQ = mOrientation.getInverse();
00250 mViewMatrix.clearMatrix();
00251 mViewMatrix.rotate(tmpQ);
00252 VVector tmpV = - mPosition;
00253 mViewMatrix.translate(tmpV);
00254
00255 mMustUpdateView = false;
00256 }
00257 }
00258
00264 void VCamera::updateViewMatrixLeft()
00265 {
00266 if(mMustUpdateView)
00267 {
00268 updateViewMatrix();
00269 }
00270 VMatrix asymMatrix;
00271 asymMatrix[12] = 0.5f * mEyeSeparation * mScreenDistance;
00272
00273 mLeftViewMatrix = asymMatrix * mViewMatrix;
00274 }
00275
00281 void VCamera::updateViewMatrixRight()
00282 {
00283 if(mMustUpdateView)
00284 {
00285 updateViewMatrix();
00286 }
00287 VMatrix asymMatrix;
00288 asymMatrix[12] = -0.5f * mEyeSeparation * mScreenDistance;
00289
00290 mRightViewMatrix = asymMatrix * mViewMatrix;
00291 }
00292
00300 void VCamera::mouseMove(float x, float y, float z)
00301 {
00302 VQuaternion rot_x(VVector(1.0f, 0.0f, 0.0f), -x);
00303 VQuaternion rot_y(VVector(0.0f, 1.0f, 0.0f), -y);
00304
00305 if(x == 0)
00306 {
00307 rot_x = VQuaternion();
00308 }
00309
00310 if(y == 0)
00311 {
00312 rot_y = VQuaternion();
00313 }
00314
00315 mOrientation = rot_y * mOrientation * rot_x;
00316 mMustUpdateView = true;
00317 }
00318
00324 void VCamera::moveForward(float way)
00325 {
00326 mPosition += mOrientation.getForwardVector() * way;
00327
00328 mMustUpdateView = true;
00329 }
00330
00336 void VCamera::moveSideWards(float way)
00337 {
00338 mPosition += mOrientation.getRightVector() * way;
00339
00340 mMustUpdateView = true;
00341 }
00342
00348 void VCamera::setStereoParameters(float m_ScreenDistance, float m_EyeSeparation)
00349 {
00350 mScreenDistance = m_ScreenDistance;
00351 mEyeSeparation = m_EyeSeparation;
00352 mMustUpdateProjection = true;
00353 }
00354