summaryrefslogtreecommitdiffhomepage
path: root/StarsEx/Camera.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2022-04-01 21:23:39 +0200
committerAki <please@ignore.pl>2022-04-01 21:23:39 +0200
commit3c487c5cd69c53d6fea948643c0a76df03516605 (patch)
tree72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /StarsEx/Camera.cpp
parent8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff)
downloadstarshatter-3c487c5cd69c53d6fea948643c0a76df03516605.zip
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.gz
starshatter-3c487c5cd69c53d6fea948643c0a76df03516605.tar.bz2
Moved Stars45 to StarsEx
Diffstat (limited to 'StarsEx/Camera.cpp')
-rw-r--r--StarsEx/Camera.cpp210
1 files changed, 210 insertions, 0 deletions
diff --git a/StarsEx/Camera.cpp b/StarsEx/Camera.cpp
new file mode 100644
index 0000000..c8671e1
--- /dev/null
+++ b/StarsEx/Camera.cpp
@@ -0,0 +1,210 @@
+/* Starshatter: The Open Source Project
+ Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors
+ Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
+ Copyright (c) 1997-2006, Destroyer Studios LLC.
+
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+ Camera Class - Position and Point of View
+*/
+
+#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;
+}
+