absence_thelab

annotate src/3deng/camera.cpp @ 1:4d5933c261c3

todo and .hgignore
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Oct 2014 02:18:43 +0300
parents
children
rev   line source
nuclear@0 1 #include "camera.h"
nuclear@0 2
nuclear@0 3 // camera constructor
nuclear@0 4 Camera::Camera() {
nuclear@0 5 Pos = Vector3(0.0f, 0.0f, 0.0f);
nuclear@0 6 LookAt = Vector3(0.0f, 0.0f, 5.0f);
nuclear@0 7 Up = Vector3(0.0f, 1.0f, 0.0f);
nuclear@0 8 FOV = QuarterPi; // 45 deg
nuclear@0 9 CreateCameraMatrix();
nuclear@0 10
nuclear@0 11 FlipRight = false;
nuclear@0 12
nuclear@0 13 path = 0;
nuclear@0 14 targpath = 0;
nuclear@0 15
nuclear@0 16 NearClip = 1.0f;
nuclear@0 17 FarClip = 10000.0f;
nuclear@0 18 }
nuclear@0 19
nuclear@0 20 void Camera::SetCamera(const Vector3 &pos, const Vector3 &lookat, const Vector3 &up) {
nuclear@0 21 Pos = pos;
nuclear@0 22 LookAt = lookat;
nuclear@0 23 Up = up;
nuclear@0 24 }
nuclear@0 25
nuclear@0 26 void Camera::SetClippingPlanes(float NearClip, float FarClip) {
nuclear@0 27 this->NearClip = NearClip;
nuclear@0 28 this->FarClip = FarClip;
nuclear@0 29 }
nuclear@0 30
nuclear@0 31 void Camera::GetClippingPlanes(float *NearClip, float *FarClip) const {
nuclear@0 32 *NearClip = this->NearClip;
nuclear@0 33 *FarClip = this->FarClip;
nuclear@0 34 }
nuclear@0 35
nuclear@0 36 Matrix4x4 &Camera::GetCameraMatrix() {
nuclear@0 37 return CCSmat;
nuclear@0 38 }
nuclear@0 39
nuclear@0 40 Vector3 Camera::GetViewVector() const {
nuclear@0 41 return LookAt - Pos;
nuclear@0 42 }
nuclear@0 43
nuclear@0 44 Vector3 Camera::GetPosition() const {
nuclear@0 45 return Pos;
nuclear@0 46 }
nuclear@0 47
nuclear@0 48 Vector3 Camera::GetUpVector() const {
nuclear@0 49 return Up;
nuclear@0 50 }
nuclear@0 51
nuclear@0 52 Vector3 Camera::GetTargetPosition() const {
nuclear@0 53 return LookAt;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 Base Camera::GetCameraBase() const {
nuclear@0 57 Base base;
nuclear@0 58 base.k = (LookAt - Pos).Normalized();
nuclear@0 59 base.j = Up.Normalized();
nuclear@0 60 base.i = CrossProduct(base.j, base.k);
nuclear@0 61 base.j = CrossProduct(base.i, base.k);
nuclear@0 62
nuclear@0 63 return base;
nuclear@0 64 }
nuclear@0 65
nuclear@0 66 //////////////////////////////////////////////////////////////
nuclear@0 67 // Create a camera matrix from 3 vectors position/lookat/up //
nuclear@0 68 //////////////////////////////////////////////////////////////
nuclear@0 69 void Camera::CreateCameraMatrix(Matrix4x4 *matrix, const Vector3 &Pos, const Vector3 &LookAt, const Vector3 &Up) const {
nuclear@0 70
nuclear@0 71 Vector3 n = LookAt - Pos;
nuclear@0 72 n.Normalize();
nuclear@0 73 Vector3 u = Up.CrossProduct(n);
nuclear@0 74 u.Normalize();
nuclear@0 75 Vector3 v = n.CrossProduct(u);
nuclear@0 76 float Tx = -(u.DotProduct(Pos));
nuclear@0 77 float Ty = -(v.DotProduct(Pos));
nuclear@0 78 float Tz = -(n.DotProduct(Pos));
nuclear@0 79
nuclear@0 80 matrix->ResetIdentity();
nuclear@0 81 matrix->m[0][0] = u.x; matrix->m[0][1] = v.x; matrix->m[0][2] = n.x;
nuclear@0 82 matrix->m[1][0] = u.y; matrix->m[1][1] = v.y; matrix->m[1][2] = n.y;
nuclear@0 83 matrix->m[2][0] = u.z; matrix->m[2][1] = v.z; matrix->m[2][2] = n.z;
nuclear@0 84 matrix->m[3][0] = Tx; matrix->m[3][1] = Ty; matrix->m[3][2] = Tz;
nuclear@0 85 }
nuclear@0 86
nuclear@0 87 void Camera::CreateCameraMatrix() {
nuclear@0 88 CreateCameraMatrix(&CCSmat, Pos, LookAt, Up);
nuclear@0 89 }
nuclear@0 90
nuclear@0 91 ///////////////////////////////////////////////////////
nuclear@0 92 // controling the camera
nuclear@0 93
nuclear@0 94 // moves the camera x/y/z units
nuclear@0 95 void Camera::Move(float x, float y, float z) {
nuclear@0 96 PosTranslate.Translate(x,y,z);
nuclear@0 97 LookTranslate.Translate(x,y,z);
nuclear@0 98 UpTranslate.Translate(x,y,z);
nuclear@0 99 }
nuclear@0 100
nuclear@0 101 // moves the camera TO the new coords
nuclear@0 102 void Camera::MoveTo(float x, float y, float z) {
nuclear@0 103 Vector3 newpos = Vector3(x,y,z);
nuclear@0 104 // find the difference between the old and new position
nuclear@0 105 Vector3 translation = newpos - Pos;
nuclear@0 106 PosTranslate.Translate(translation.x, translation.y, translation.z);
nuclear@0 107 LookTranslate.Translate(translation.x, translation.y, translation.z);
nuclear@0 108 UpTranslate.Translate(translation.x, translation.y, translation.z);
nuclear@0 109 }
nuclear@0 110
nuclear@0 111 void Camera::Rotate(float x, float y, float z) {
nuclear@0 112 // find the inverted lookat vector
nuclear@0 113 Vector3 ilook = Pos - LookAt;
nuclear@0 114 Vector3 newilook = ilook;
nuclear@0 115 // rotate it
nuclear@0 116 Matrix4x4 rot;
nuclear@0 117 rot.ResetIdentity();
nuclear@0 118 rot.Rotate(x,y,z);
nuclear@0 119 newilook.Transform(rot);
nuclear@0 120 // find the translation difference between the two vectors
nuclear@0 121 Vector3 transl = newilook - ilook;
nuclear@0 122 //do it
nuclear@0 123 PosTranslate.ResetIdentity();
nuclear@0 124 PosTranslate.Translate(transl.x, transl.y, transl.z);
nuclear@0 125 UpRotate.ResetIdentity();
nuclear@0 126 UpRotate.Rotate(x, y, z);
nuclear@0 127
nuclear@0 128 // apply the transformation
nuclear@0 129 Pos.Transform(PosTranslate);
nuclear@0 130 Up.Transform(UpRotate);
nuclear@0 131 }
nuclear@0 132
nuclear@0 133
nuclear@0 134 ////////////////// rotates the camera around the target ///////////////
nuclear@0 135
nuclear@0 136 inline void Camera::RotateTarget(float x, float y, float z) {
nuclear@0 137 LookRotate.Rotate(x, y, z);
nuclear@0 138 }
nuclear@0 139
nuclear@0 140 inline void Camera::MoveTarget(float x, float y, float z) {
nuclear@0 141 LookTranslate.Translate(x,y,z);
nuclear@0 142 }
nuclear@0 143
nuclear@0 144 // moves the look at point at the point specified
nuclear@0 145 inline void Camera::MoveTargetTo(float x, float y, float z) {
nuclear@0 146 Vector3 translation = Vector3(x,y,z) - LookAt;
nuclear@0 147 LookTranslate.Translate(translation.x, translation.y, translation.z);
nuclear@0 148 }
nuclear@0 149
nuclear@0 150 void Camera::Zoom(float factor) {
nuclear@0 151 // find the new vector between the camera and the target
nuclear@0 152 Vector3 offset = (LookAt - Pos) * factor;
nuclear@0 153 Vector3 diff = offset - LookAt;
nuclear@0 154 Pos += offset;
nuclear@0 155
nuclear@0 156 //PosTranslate.ResetIdentity();
nuclear@0 157 //PosTranslate.Translate(diff.x, diff.y, diff.z);
nuclear@0 158 //Pos.Transform(PosTranslate);
nuclear@0 159 }
nuclear@0 160
nuclear@0 161 void Camera::Spin(float rads) {
nuclear@0 162 Up.Rotate((LookAt - Pos).Normalized(), rads);
nuclear@0 163 }
nuclear@0 164
nuclear@0 165 void Camera::SetRightFlipping(bool enable) {
nuclear@0 166 FlipRight = enable;
nuclear@0 167 }
nuclear@0 168 void Camera::SetPosition(const Vector3 &pos) {
nuclear@0 169 this->Pos = pos;
nuclear@0 170 }
nuclear@0 171
nuclear@0 172 void Camera::SetUpVector(const Vector3 &up) {
nuclear@0 173 Up = up;
nuclear@0 174 }
nuclear@0 175
nuclear@0 176 void Camera::SetTarget(const Vector3 &targ) {
nuclear@0 177 this->LookAt = targ;
nuclear@0 178 }
nuclear@0 179
nuclear@0 180
nuclear@0 181 void Camera::ResetRotation() {
nuclear@0 182 PosRotate.ResetIdentity();
nuclear@0 183 }
nuclear@0 184
nuclear@0 185
nuclear@0 186 void Camera::SetCameraPath(const Curve *path, const Curve *tpath, dword StartTime, dword EndTime) {
nuclear@0 187 this->path = path;
nuclear@0 188 this->targpath = tpath;
nuclear@0 189 this->StartTime = StartTime;
nuclear@0 190 this->EndTime = EndTime;
nuclear@0 191 }
nuclear@0 192
nuclear@0 193 void Camera::FollowPath(dword time, bool Cycle) {
nuclear@0 194 if(Cycle || (!Cycle && time >= StartTime && time < EndTime)) {
nuclear@0 195 float t = (float)(time - StartTime) / (float)(EndTime - StartTime);
nuclear@0 196 if(Cycle) {
nuclear@0 197 t = (float)fmod(t, 1.0f);
nuclear@0 198 } else {
nuclear@0 199 if(t < 0.0f) t = 0.0f;
nuclear@0 200 if(t > 1.0f) t = 1.0f;
nuclear@0 201 }
nuclear@0 202 if(path) {
nuclear@0 203 SetPosition(const_cast<Curve*>(path)->Interpolate(t));
nuclear@0 204 }
nuclear@0 205 if(targpath) {
nuclear@0 206 SetTarget(const_cast<Curve*>(targpath)->Interpolate(t));
nuclear@0 207 }
nuclear@0 208 }
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 void Camera::FollowPath(float t) {
nuclear@0 212 if(t < 0.0f) t = 0.0f;
nuclear@0 213 if(t > 1.0f) t = 1.0f;
nuclear@0 214 if(path) {
nuclear@0 215 SetPosition(const_cast<Curve*>(path)->Interpolate(t));
nuclear@0 216 }
nuclear@0 217 if(targpath) {
nuclear@0 218 SetTarget(const_cast<Curve*>(targpath)->Interpolate(t));
nuclear@0 219 }
nuclear@0 220 }
nuclear@0 221
nuclear@0 222 dword Camera::GetStartTime() const {
nuclear@0 223 return StartTime;
nuclear@0 224 }
nuclear@0 225
nuclear@0 226 dword Camera::GetEndTime() const {
nuclear@0 227 return EndTime;
nuclear@0 228 }