summaryrefslogtreecommitdiffhomepage
path: root/nGenEx/Camera.cpp
diff options
context:
space:
mode:
authorFWoltermann@gmail.com <FWoltermann@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544>2011-12-08 14:53:40 +0000
committerFWoltermann@gmail.com <FWoltermann@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544>2011-12-08 14:53:40 +0000
commite33e19d0587146859d48a134ec9fd94e7b7ba5cd (patch)
tree69d048c8801858d2756ab3a487090a7a1b74bf14 /nGenEx/Camera.cpp
downloadstarshatter-e33e19d0587146859d48a134ec9fd94e7b7ba5cd.zip
starshatter-e33e19d0587146859d48a134ec9fd94e7b7ba5cd.tar.gz
starshatter-e33e19d0587146859d48a134ec9fd94e7b7ba5cd.tar.bz2
Initial upload
Diffstat (limited to 'nGenEx/Camera.cpp')
-rw-r--r--nGenEx/Camera.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/nGenEx/Camera.cpp b/nGenEx/Camera.cpp
new file mode 100644
index 0000000..bbc72dd
--- /dev/null
+++ b/nGenEx/Camera.cpp
@@ -0,0 +1,212 @@
+/* Project nGenEx
+ Destroyer Studios LLC
+ Copyright © 1997-2004. All Rights Reserved.
+
+ SUBSYSTEM: nGenEx.lib
+ FILE: Camera.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Camera Class - Position and Point of View
+*/
+
+#include "MemDebug.h"
+#include "Camera.h"
+
+// +--------------------------------------------------------------------+
+
+Camera::Camera(double x, double y, double z)
+ : pos(x,y,z)
+{ }
+
+Camera::~Camera()
+{ }
+
+// +--------------------------------------------------------------------+
+
+void
+Camera::MoveTo(double x, double y, double z)
+{
+ pos.x = x;
+ pos.y = y;
+ pos.z = z;
+}
+
+void
+Camera::MoveTo(const Point& p)
+{
+ pos.x = p.x;
+ pos.y = p.y;
+ pos.z = p.z;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Camera::MoveBy(double dx, double dy, double dz)
+{
+ pos.x += dx;
+ pos.y += dz;
+ pos.z += dy;
+}
+
+void
+Camera::MoveBy(const Point& p)
+{
+ pos.x += p.x;
+ pos.y += p.y;
+ pos.z += p.z;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Camera::Clone(const Camera& cam)
+{
+ pos = cam.pos;
+ orientation = cam.orientation;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Camera::LookAt(const Point& target, const Point& eye, const Point& up)
+{
+ Point zaxis = target - eye; zaxis.Normalize();
+ Point xaxis = up.cross(zaxis); xaxis.Normalize();
+ Point yaxis = zaxis.cross(xaxis); yaxis.Normalize();
+
+ orientation(0,0) = xaxis.x;
+ orientation(0,1) = xaxis.y;
+ orientation(0,2) = xaxis.z;
+
+ orientation(1,0) = yaxis.x;
+ orientation(1,1) = yaxis.y;
+ orientation(1,2) = yaxis.z;
+
+ orientation(2,0) = zaxis.x;
+ orientation(2,1) = zaxis.y;
+ orientation(2,2) = zaxis.z;
+
+ pos = eye;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+Camera::LookAt(const Point& target)
+{
+ // No navel gazing:
+ if (target == Pos())
+ return;
+
+ Point tgt, tmp = target - Pos();
+
+ // Rotate into the view orientation:
+ tgt.x = (tmp * vrt());
+ tgt.y = (tmp * vup());
+ tgt.z = (tmp * vpn());
+
+ if (tgt.z == 0) {
+ Pitch(0.5);
+ Yaw(0.5);
+ LookAt(target);
+ return;
+ }
+
+ double az = atan(tgt.x/tgt.z);
+ double el = atan(tgt.y/tgt.z);
+
+ // if target is behind, offset by 180 degrees:
+ if (tgt.z < 0)
+ az -= PI;
+
+ Pitch(-el);
+ Yaw(az);
+
+ // roll to upright position:
+ double deflection = vrt().y;
+ while (fabs(deflection) > 0.001) {
+ double theta = asin(deflection/vrt().length());
+ Roll(-theta);
+
+ deflection = vrt().y;
+ }
+}
+
+
+// +--------------------------------------------------------------------+
+
+bool
+Camera::Padlock(const Point& target, double alimit, double e_lo, double e_hi)
+{
+ // No navel gazing:
+ if (target == Pos())
+ return false;
+
+ Point tgt, tmp = target - Pos();
+
+ // Rotate into the view orientation:
+ tgt.x = (tmp * vrt());
+ tgt.y = (tmp * vup());
+ tgt.z = (tmp * vpn());
+
+ if (tgt.z == 0) {
+ Yaw(0.1);
+
+ tgt.x = (tmp * vrt());
+ tgt.y = (tmp * vup());
+ tgt.z = (tmp * vpn());
+
+ if (tgt.z == 0)
+ return false;
+ }
+
+ bool locked = true;
+ double az = atan(tgt.x/tgt.z);
+ double orig = az;
+
+ // if target is behind, offset by 180 degrees:
+ if (tgt.z < 0)
+ az -= PI;
+
+ while (az > PI) az -= 2*PI;
+ while (az < -PI) az += 2*PI;
+
+ if (alimit > 0) {
+ if (az < -alimit) {
+ az = -alimit;
+ locked = false;
+ }
+ else if (az > alimit) {
+ az = alimit;
+ locked = false;
+ }
+ }
+
+ Yaw(az);
+
+ // Rotate into the new view orientation:
+ tgt.x = (tmp * vrt());
+ tgt.y = (tmp * vup());
+ tgt.z = (tmp * vpn());
+
+ double el = atan(tgt.y/tgt.z);
+
+ if (e_lo > 0 && el < -e_lo) {
+ el = -e_lo;
+ locked = false;
+ }
+
+ else if (e_hi > 0 && el > e_hi) {
+ el = e_hi;
+ locked = false;
+ }
+
+ Pitch(-el);
+
+ return locked;
+}
+