X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgraphics%2Fviewport.cpp;h=c3727738861648a914b97021f36305b6698a7bdd;hb=a19fdf3d9f0d7ecbf6eeeec817856d85049a8336;hp=499a22772025f64c2edbee3277a67f2a2944c522;hpb=be413456f57da06e918ae7bf4c4f35e5198ff7ce;p=blobs.git diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp index 499a227..c372773 100644 --- a/src/graphics/viewport.cpp +++ b/src/graphics/viewport.cpp @@ -1,54 +1,115 @@ #include "Camera.hpp" #include "Viewport.hpp" -#include "const.hpp" +#include "../creature/Creature.hpp" +#include "../math/const.hpp" +#include "../world/Body.hpp" +#include "../world/Planet.hpp" +#include #include +#include +#include #include namespace blobs { namespace graphics { -Camera::Camera() noexcept -: fov(PI_0p25) +Camera::Camera(const world::Body &r) noexcept +: fov(PI * 0.25) , aspect(1.0f) , near(0.1f) -, far(256.0f) -, projection(glm::perspective(fov, aspect, near, far)) -, view(1.0f) { +, far(12560.0f) +, projection(glm::infinitePerspective(fov, aspect, near)) +, view(1.0f) +, ref(&r) +, track_orient(false) { } Camera::~Camera() noexcept { } -void Camera::FOV(float f) noexcept { +Camera &Camera::FOV(float f) noexcept { fov = f; UpdateProjection(); + return *this; } -void Camera::Aspect(float r) noexcept { +Camera &Camera::Aspect(float r) noexcept { aspect = r; UpdateProjection(); + return *this; } -void Camera::Aspect(float w, float h) noexcept { +Camera &Camera::Aspect(float w, float h) noexcept { Aspect(w / h); + return *this; } -void Camera::Clip(float n, float f) noexcept { +Camera &Camera::Clip(float n, float f) noexcept { near = n; far = f; UpdateProjection(); + return *this; } -void Camera::View(const glm::mat4 &v) noexcept { - view = v; +Camera &Camera::Reference(const world::Body &r) noexcept { + ref = &r; + return *this; +} + +Camera &Camera::Orbital(const glm::vec3 &pos) noexcept { + track_orient = false; + view = glm::lookAt(pos, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + return *this; +} + +Camera &Camera::Radial(const creature::Creature &c, double distance, const glm::dvec3 &angle) { + const creature::Situation &s = c.GetSituation(); + glm::dvec3 pos(s.Position()); + glm::dvec3 up(0.0); + glm::dvec3 dir(0.0, 0.0, -distance); + if (s.OnSurface()) { + Reference(s.GetPlanet()); + track_orient = true; + up = s.GetPlanet().NormalAt(s.Position()); + glm::dvec3 ref(glm::normalize(glm::cross(up, glm::dvec3(up.z, up.x, up.y)))); + dir = + glm::dmat3(ref, up, glm::cross(ref, up)) + * glm::dmat3(glm::eulerAngleYX(-angle.y, -angle.x)) + * dir; + } else { + up.y = 1.0; + dir = glm::dmat3(glm::eulerAngleYX(-angle.y, -angle.x)) * dir; + } + pos += up * (c.Size() * 0.5); + up = glm::rotate(up, angle.z, glm::normalize(-dir)); + view = glm::lookAt(pos - dir, pos, up); + return *this; +} + +glm::mat4 Camera::Model(const world::Body &b) const noexcept { + if (&b == ref) { + return track_orient ? glm::mat4(1.0f) : glm::mat4(ref->LocalTransform()); + } else if (b.HasParent() && &b.Parent() == ref) { + return glm::mat4(track_orient + ? ref->InverseTransform() * b.FromParent() * b.LocalTransform() + : b.FromParent() * b.LocalTransform()); + } else if (ref->HasParent() && &ref->Parent() == &b) { + return glm::mat4(track_orient + ? ref->InverseTransform() * ref->ToParent() * b.LocalTransform() + : ref->ToParent() * b.LocalTransform()); + } else { + return glm::mat4(track_orient + ? ref->InverseTransform() * ref->ToUniverse() * b.FromUniverse() * b.LocalTransform() + : ref->ToUniverse() * b.FromUniverse() * b.LocalTransform()); + } } void Camera::UpdateProjection() noexcept { - projection = glm::perspective(fov, aspect, near, far); + projection = glm::infinitePerspective(fov, aspect, near); } @@ -73,5 +134,9 @@ void Viewport::Clear() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } +void Viewport::ClearDepth() { + glClear(GL_DEPTH_BUFFER_BIT); +} + } }