00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "camera.h"
00022 #include <salt/matrix.h>
00023 #include <zeitgeist/logserver/logserver.h>
00024 #include <zeitgeist/scriptserver/scriptserver.h>
00025
00026 using namespace oxygen;
00027 using namespace salt;
00028
00029 Camera::Camera() : BaseNode()
00030 {
00031 mViewTransform.Identity();
00032 mFOV = 60.0f;
00033 mZNear = 1.0f;
00034 mZFar = 2000.0f;
00035 mX = 0;
00036 mY = 0;
00037 mWidth = 640;
00038 mHeight = 480;
00039
00040 SetName("camera");
00041 }
00042
00043 Camera::~Camera()
00044 {
00045 }
00046
00051 void Camera::DescribeFrustum(Frustum& frustum) const
00052 {
00053
00054 Matrix frustumMatrix = mProjectionTransform * mViewTransform;
00055
00056
00057 float* m = frustumMatrix.m;
00058
00059 Plane *p = &frustum.mPlanes[Frustum::PI_RIGHT];
00060 p->normal.Set(m[3]-m[0], m[7]-m[4], m[11]-m[8]);
00061 p->d = m[15]-m[12];
00062
00063 p = &frustum.mPlanes[Frustum::PI_LEFT];
00064 p->normal.Set(m[3]+m[0], m[7]+m[4], m[11]+m[8]);
00065 p->d = m[15]+m[12];
00066
00067 p = &frustum.mPlanes[Frustum::PI_BOTTOM];
00068 p->normal.Set(m[3]+m[1], m[7]+m[5], m[11]+m[9]);
00069 p->d = m[15]+m[13];
00070
00071 p = &frustum.mPlanes[Frustum::PI_TOP];
00072 p->normal.Set(m[3]-m[1], m[7]-m[5], m[11]-m[9]);
00073 p->d = m[15]-m[13];
00074
00075 p = &frustum.mPlanes[Frustum::PI_NEAR];
00076 p->normal.Set(m[3]-m[2], m[7]-m[6], m[11]-m[10]);
00077 p->d = m[15]-m[14];
00078
00079 p = &frustum.mPlanes[Frustum::PI_FAR];
00080 p->normal.Set(m[3]+m[2], m[7]+m[6], m[11]+m[10]);
00081 p->d = m[15]+m[14];
00082
00083
00084 for(int i=0;i<6;++i)
00085 {
00086 frustum.mPlanes[i].Normalize();
00087 }
00088
00089
00090 frustum.mBasePos = GetWorldTransform().Pos();
00091 }
00092
00093 void Camera::Bind()
00094 {
00095 mViewTransform = GetWorldTransform();
00096 mViewTransform.RotateX(90);
00097 mViewTransform.InvertRotationMatrix();
00098
00099
00100 mProjectionTransform.CalcInfiniteFrustum(
00101 -mHalfWorldWidth,
00102 mHalfWorldWidth,
00103 -mHalfWorldHeight,
00104 mHalfWorldHeight,
00105 mZNear);
00106 }
00107
00108 void Camera::OnLink()
00109 {
00110 bool gotSetup =
00111 (
00112 GetScript()->GetVariable("Viewport.XRes", mWidth) &&
00113 GetScript()->GetVariable("Viewport.YRes", mHeight)
00114 );
00115
00116 if (! gotSetup)
00117 {
00118 GetLog()->Error()
00119 << "(Camera) unable to read setup from ScriptServer\n";
00120 }
00121 }
00122
00123 void Camera::UpdateHierarchyInternal()
00124 {
00125
00126 gClamp(mFOV, 10.0f, 170.0f);
00127
00128 mHalfWorldWidth = mZNear * (float)tan(gDegToRad(mFOV*0.5f));
00129 mHalfWorldHeight = mHalfWorldWidth * (mHeight/(float)mWidth);
00130 }
00131
00132 void Camera::SetViewport(int x, int y, int width, int height)
00133 {
00134 mX = x;
00135 mY = y;
00136 mWidth = width;
00137 mHeight = height;
00138 }
00139
00140 int Camera::GetViewportX()
00141 {
00142 return mX;
00143 }
00144
00145 int Camera::GetViewportY()
00146 {
00147 return mY;
00148 }
00149
00150 int Camera::GetViewportWidth()
00151 {
00152 return mWidth;
00153 }
00154
00155 int Camera::GetViewportHeight()
00156 {
00157 return mHeight;
00158 }
00159
00160 void Camera::SetFOV(const float fov)
00161 {
00162 mFOV = fov;
00163 }
00164
00165 void Camera::SetZNear(const float zNear)
00166 {
00167 mZNear = zNear;
00168 }
00169
00170 void Camera::SetZFar(const float zFar)
00171 {
00172 mZFar = zFar;
00173 }
00174
00175 void Camera::AdjustFOV(const float fov)
00176 {
00177 mFOV+=fov;
00178 }
00179
00180 void Camera::AdjustZNear(const float zNear)
00181 {
00182 mZNear+=zNear;
00183 }
00184
00185 void Camera::AdjustZFar(const float zFar)
00186 {
00187 mZFar+=zFar;
00188 }
00189
00190 float Camera::GetFOV() const
00191 {
00192 return mFOV;
00193 }
00194
00195 float Camera::GetZNear() const
00196 {
00197 return mZNear;
00198 }
00199
00200 float Camera::GetZFar()const
00201 {
00202 return mZFar;
00203 }
00204
00205 const salt::Matrix& Camera::GetViewTransform() const
00206 {
00207 return mViewTransform;
00208 }
00209
00210 const salt::Matrix& Camera::GetProjectionTransform() const
00211 {
00212 return mProjectionTransform;
00213 }