From 98770f59a02c76f02de0a46ed36d9cfd52f5071b Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 12 Nov 2017 21:39:15 +0100 Subject: [PATCH] half-assed implementation of "other" body rendering --- src/blobs.cpp | 19 +++++++++++-- src/graphics/viewport.cpp | 5 ++-- src/world/Body.hpp | 18 +++++++++--- src/world/sim.cpp | 1 + src/world/world.cpp | 58 +++++++++++++++++++++++++-------------- 5 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/blobs.cpp b/src/blobs.cpp index 464273b..f96dd0f 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) { sun.Mass(1.0e12); sun.Radius(10.0); sun.SurfaceTilt(glm::dvec2(PI * 0.25, PI * 0.25)); - sun.AngularMomentum(1.0e9); + sun.AngularMomentum(1.0e13); world::Planet planet(11); world::GenerateTest(planet); @@ -40,9 +40,19 @@ int main(int argc, char *argv[]) { moon.Rotation(PI * 0.25); moon.AngularMomentum(1.0e4); + world::Planet second_planet(9); + world::GenerateTest(second_planet); + second_planet.SetParent(sun); + second_planet.Mass(1.0e9); + second_planet.GetOrbit().SemiMajorAxis(350.0); + second_planet.SurfaceTilt(glm::dvec2(PI * 0.125, PI * 0.25)); + second_planet.AxialTilt(glm::dvec2(PI * 0.95, 0.0)); + second_planet.AngularMomentum(1.0e8); + world::Simulation sim(sun); sim.AddSun(sun); sim.AddPlanet(planet); + sim.AddPlanet(second_planet); sim.AddPlanet(moon); std::cout << "length of year: " << planet.OrbitalPeriod() << "s" << std::endl; @@ -61,9 +71,12 @@ int main(int argc, char *argv[]) { //.FirstPerson(3, glm::vec3(0.0f, 0.0f, 0.1f), glm::vec3(1.0f, -0.75f, 0.1f)) // from afar //.MapView(0, glm::vec3(0.0f, 0.0f, 25.0f), 0.0f) - // system view - //.Orbital(glm::vec3(50.0f, 2500.0f, 50.0f)); ; + // system view + //state.GetCamera() + // .Reference(sun) + // .Orbital(glm::vec3(-500.0f, 500.0f, 500.0f)) + //; planet.BuildVAOs(); app::Application app(init.window, init.viewport); diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp index 2d9b469..9e22a26 100644 --- a/src/graphics/viewport.cpp +++ b/src/graphics/viewport.cpp @@ -120,8 +120,9 @@ glm::mat4 Camera::Model(const world::Body &b) const noexcept { ? ref->InverseTransform() * ref->ToParent() * b.LocalTransform() : ref->ToParent() * b.LocalTransform(); } else { - // TODO: model matrices for path distances > 1 - return track_orient ? glm::mat4(1.0f) : glm::mat4(ref->LocalTransform()); + return track_orient + ? ref->InverseTransform() * ref->ToUniverse() * b.FromUniverse() * b.LocalTransform() + : ref->ToUniverse() * b.FromUniverse() * b.LocalTransform(); } } diff --git a/src/world/Body.hpp b/src/world/Body.hpp index 1b9e2e3..5f82be2 100644 --- a/src/world/Body.hpp +++ b/src/world/Body.hpp @@ -70,14 +70,19 @@ public: double OrbitalPeriod() const noexcept; double RotationalPeriod() const noexcept; - glm::dmat4 LocalTransform() const noexcept; - glm::dmat4 InverseTransform() const noexcept; + const glm::dmat4 &LocalTransform() const noexcept { return local; } + const glm::dmat4 &InverseTransform() const noexcept { return inverse_local; } - glm::dmat4 ToParent() const noexcept; - glm::dmat4 FromParent() const noexcept; + const glm::dmat4 &ToParent() const noexcept { return inverse_orbital; } + const glm::dmat4 &FromParent() const noexcept { return orbital; } + + glm::dmat4 ToUniverse() const noexcept; + glm::dmat4 FromUniverse() const noexcept; virtual void Draw(app::Assets &, graphics::Viewport &) { } + void Cache() noexcept; + private: void AddChild(Body &); void RemoveChild(Body &); @@ -94,6 +99,11 @@ private: double rotation; double angular; + glm::dmat4 orbital; + glm::dmat4 inverse_orbital; + glm::dmat4 local; + glm::dmat4 inverse_local; + }; } diff --git a/src/world/sim.cpp b/src/world/sim.cpp index 185046d..8b4c214 100644 --- a/src/world/sim.cpp +++ b/src/world/sim.cpp @@ -41,6 +41,7 @@ void Simulation::Tick() { time += dt; for (auto body : bodies) { body->Rotation(body->Rotation() + dt * body->AngularMomentum() / body->Inertia()); + body->Cache(); } } diff --git a/src/world/world.cpp b/src/world/world.cpp index eb03490..c9a7a32 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -37,7 +37,11 @@ Body::Body() , surface_tilt(0.0, 0.0) , axis_tilt(0.0, 0.0) , rotation(0.0) -, angular(0.0) { +, angular(0.0) +, orbital(1.0) +, inverse_orbital(1.0) +, local(1.0) +, inverse_local(1.0) { } Body::~Body() { @@ -101,32 +105,44 @@ double Body::RotationalPeriod() const noexcept { } } -glm::dmat4 Body::LocalTransform() const noexcept { - glm::dmat4 srf = glm::eulerAngleXY(surface_tilt.x, surface_tilt.y); - glm::dmat4 rot = glm::eulerAngleY(rotation); - glm::dmat4 tilt = glm::eulerAngleXY(axis_tilt.x, axis_tilt.y); - return tilt * rot * srf; -} - -glm::dmat4 Body::InverseTransform() const noexcept { - glm::dmat4 srf = glm::eulerAngleYX(-surface_tilt.y, -surface_tilt.x); - glm::dmat4 rot = glm::eulerAngleY(-rotation); - glm::dmat4 tilt = glm::eulerAngleYX(-axis_tilt.y, -axis_tilt.x); - return srf * rot * tilt; +glm::dmat4 Body::ToUniverse() const noexcept { + glm::dmat4 m(1.0); + const Body *b = this; + while (b->HasParent()) { + m = b->ToParent() * m; + b = &b->Parent(); + } + return m; } -glm::dmat4 Body::ToParent() const noexcept { - if (!parent) { - return glm::dmat4(1.0); +glm::dmat4 Body::FromUniverse() const noexcept { + glm::dmat4 m(1.0); + const Body *b = this; + while (b->HasParent()) { + m *= b->FromParent(); + b = &b->Parent(); } - return orbit.InverseMatrix(PI_2p0 * (GetSimulation().Time() / OrbitalPeriod())); + return m; } -glm::dmat4 Body::FromParent() const noexcept { - if (!parent) { - return glm::dmat4(1.0); +void Body::Cache() noexcept { + if (parent) { + orbital = + orbit.Matrix(PI_2p0 * (GetSimulation().Time() / OrbitalPeriod())) + * glm::eulerAngleXY(axis_tilt.x, axis_tilt.y); + inverse_orbital = + glm::eulerAngleYX(-axis_tilt.y, -axis_tilt.x) + * orbit.InverseMatrix(PI_2p0 * (GetSimulation().Time() / OrbitalPeriod())); + } else { + orbital = glm::eulerAngleXY(axis_tilt.x, axis_tilt.y); + inverse_orbital = glm::eulerAngleYX(-axis_tilt.y, -axis_tilt.x); } - return orbit.Matrix(PI_2p0 * (GetSimulation().Time() / OrbitalPeriod())); + local = + glm::eulerAngleY(rotation) + * glm::eulerAngleXY(surface_tilt.x, surface_tilt.y); + inverse_local = + glm::eulerAngleYX(-surface_tilt.y, -surface_tilt.x) + * glm::eulerAngleY(-rotation); } -- 2.39.2