diff options
author | Aki <please@ignore.pl> | 2022-04-01 21:23:39 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2022-04-01 21:23:39 +0200 |
commit | 3c487c5cd69c53d6fea948643c0a76df03516605 (patch) | |
tree | 72730c7b8b26a5ef8fc9a987ec4c16129efd5aac /StarsEx/Camera.cpp | |
parent | 8f353abd0bfe18baddd8a8250ab7c4f2d1c83a6e (diff) | |
download | starshatter-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.cpp | 210 |
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; +} + |