]> git.localhorst.tv Git - blobs.git/commitdiff
allow clicking celestial bodies
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 10 Dec 2017 13:07:18 +0000 (14:07 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 10 Dec 2017 13:07:18 +0000 (14:07 +0100)
12 files changed:
src/app/MasterState.hpp
src/app/states.cpp
src/blobs.cpp
src/creature/Creature.hpp
src/creature/creature.cpp
src/math/geometry.cpp
src/math/geometry.hpp
src/ui/BodyPanel.hpp [new file with mode: 0644]
src/ui/string.hpp
src/ui/ui.cpp
src/world/Body.hpp
src/world/world.cpp

index 8290e86886b53d59c246ea36d076c34acadf4dfd..7521d8e4c0eacd1bba0a64aae26c0e87253c15cc 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "Assets.hpp"
 #include "../graphics/Camera.hpp"
+#include "../ui/BodyPanel.hpp"
 #include "../ui/CreaturePanel.hpp"
 #include "../ui/RecordsPanel.hpp"
 #include "../ui/TimePanel.hpp"
@@ -68,6 +69,7 @@ private:
        glm::dvec3 cam_orient;
        bool cam_dragging;
 
+       ui::BodyPanel bp;
        ui::CreaturePanel cp;
        ui::RecordsPanel rp;
        ui::TimePanel tp;
index bec6da1387221b903ff2897e88a31d7ad4a1a8e6..98add9653a5af3e0571b82c6e6fd52435eb135c4 100644 (file)
@@ -11,6 +11,9 @@
 
 #include <glm/gtx/transform.hpp>
 
+#include <iostream>
+#include <glm/gtx/io.hpp>
+
 
 namespace blobs {
 namespace app {
@@ -24,15 +27,17 @@ MasterState::MasterState(Assets &assets, world::Simulation &sim) noexcept
 , cam_tgt_dist(5.0)
 , cam_orient(PI * 0.375, PI * 0.25, 0.0)
 , cam_dragging(false)
+, bp(assets)
 , cp(assets)
 , rp(sim)
 , tp(sim)
 , remain(0)
 , thirds(0)
 , paused(false) {
-       cp.ZIndex(10.0f);
-       rp.ZIndex(20.0f);
-       tp.ZIndex(30.0f);
+       bp.ZIndex(10.0f);
+       cp.ZIndex(20.0f);
+       rp.ZIndex(30.0f);
+       tp.ZIndex(40.0f);
 }
 
 MasterState::~MasterState() noexcept {
@@ -108,21 +113,39 @@ void MasterState::OnMouseUp(const SDL_MouseButtonEvent &e) {
        if (e.button == SDL_BUTTON_LEFT) {
                glm::dmat4 inverse(glm::inverse(cam.Projection() * cam.View()));
                math::Ray ray(inverse * App().GetViewport().ShootPixel(e.x, e.y));
-               creature::Creature *closest = nullptr;
-               double closest_dist = 1.0e24;
+
+               creature::Creature *closest_creature = nullptr;
+               double closest_dist = std::numeric_limits<double>::infinity();
                for (creature::Creature *c : sim.LiveCreatures()) {
                        glm::dvec3 normal(0.0);
                        double dist = 0.0;
-                       if (Intersect(ray, c->CollisionBox(), glm::dmat4(cam.Model(c->GetSituation().GetPlanet())) * c->CollisionTransform(), normal, dist)
+                       if (Intersect(ray, c->CollisionBounds(), glm::dmat4(cam.Model(c->GetSituation().GetPlanet())) * c->CollisionTransform(), normal, dist)
                                && dist < closest_dist) {
-                               closest = c;
+                               closest_creature = c;
+                               closest_dist = dist;
+                       }
+               }
+
+               world::Body *closest_body = nullptr;
+               for (world::Body *b : sim.Bodies()) {
+                       glm::dvec3 normal(0.0);
+                       double dist = 0.0;
+                       if (Intersect(ray, glm::dmat4(cam.Model(*b)) * b->CollisionBounds(), normal, dist) && dist < closest_dist) {
+                               closest_creature = nullptr;
+                               closest_body = b;
                                closest_dist = dist;
                        }
                }
-               if (closest) {
-                       cp.Show(*closest);
+
+               if (closest_creature) {
+                       cp.Show(*closest_creature);
+                       bp.Hide();
+               } else if (closest_body) {
+                       bp.Show(*closest_body);
+                       cp.Hide();
                } else {
                        cp.Hide();
+                       bp.Hide();
                }
        } else if (e.button == SDL_BUTTON_RIGHT) {
                SDL_SetRelativeMouseMode(SDL_FALSE);
@@ -223,6 +246,7 @@ void MasterState::OnRender(graphics::Viewport &viewport) {
        }
 
        viewport.ClearDepth();
+       bp.Draw(viewport);
        cp.Draw(viewport);
        rp.Draw(viewport);
        tp.Draw(viewport);
index 1cd3f9fad69cb6b01c60d67cf34264ab5cdd833f..d032d9de33502e86d4fe9aa6998103bd2ea84c30 100644 (file)
@@ -20,12 +20,14 @@ int main(int argc, char *argv[]) {
        app::Assets assets;
 
        world::Sun sun;
+       sun.Name("Sun");
        sun.Mass(1.0e14);
        sun.Radius(20.0);
        sun.SurfaceTilt(glm::dvec2(PI * 0.25, PI * 0.25));
        sun.AngularMomentum(1.0e13);
 
        world::Planet planet(25);
+       planet.Name("Planet");
        planet.SetParent(sun);
        planet.Mass(1.0e10);
        planet.GetOrbit().SemiMajorAxis(941.7);
@@ -34,6 +36,7 @@ int main(int argc, char *argv[]) {
        planet.AngularMomentum(6.0e10);
 
        world::Planet moon(3);
+       moon.Name("Moon");
        moon.SetParent(planet);
        moon.Mass(1.0e6);
        moon.GetOrbit().SemiMajorAxis(37.0);
@@ -41,6 +44,7 @@ int main(int argc, char *argv[]) {
        moon.AngularMomentum(1.0e4);
 
        world::Planet second_planet(9);
+       second_planet.Name("Second planet");
        second_planet.SetParent(sun);
        second_planet.Mass(1.0e9);
        second_planet.GetOrbit().SemiMajorAxis(350.0);
index 2c0b6b8dabd8198d85c6f6ef9dc9743e5710b7d4..b8171ed73070a8baac5573b8c0d1c561c2427ba7 100644 (file)
@@ -177,7 +177,7 @@ public:
        Steering &GetSteering() noexcept { return steering; }
        const Steering &GetSteering() const noexcept { return steering; }
 
-       math::AABB CollisionBox() const noexcept;
+       math::AABB CollisionBounds() const noexcept;
        glm::dmat4 CollisionTransform() const noexcept;
 
        glm::dmat4 LocalTransform() noexcept;
index b609fe8a169c35462622a65aee816c17b4d8e077..085d70f000554bec57537f0b419b62f474ccb3eb 100644 (file)
@@ -472,14 +472,13 @@ Situation::Derivative Creature::Step(const Situation::Derivative &ds, double dt)
        s.vel += ds.acc * dt;
        glm::dvec3 force(steering.Force(s));
        // gravity = antinormal * mass * Gm / r²
-       double elevation = situation.GetPlanet().DistanceAt(s.pos);
        glm::dvec3 normal(situation.GetPlanet().NormalAt(s.pos));
        force += glm::dvec3(
                -normal
                * Mass() * situation.GetPlanet().GravitationalParameter()
-               / (elevation * elevation));
+               / glm::length2(s.pos));
        // if net force is applied and in contact with surface
-       if (!allzero(force) && std::abs(std::abs(elevation) - situation.GetPlanet().Radius()) < 0.001) {
+       if (!allzero(force) && glm::length2(s.pos) < (situation.GetPlanet().Radius() + 0.01) * (situation.GetPlanet().Radius() + 0.01)) {
                // apply friction = -|normal force| * tangential force * coefficient
                glm::dvec3 fn(normal * glm::dot(force, normal));
                glm::dvec3 ft(force - fn);
@@ -550,7 +549,7 @@ void Creature::TickBrain(double dt) {
        }
 }
 
-math::AABB Creature::CollisionBox() const noexcept {
+math::AABB Creature::CollisionBounds() const noexcept {
        return { glm::dvec3(size * -0.5), glm::dvec3(size * 0.5) };
 }
 
index 58c97ae71e378b98f14ce3cc1917ed8201e23aad..3afa944f479b0fc41905d5de6364ee6ca8068e5b 100644 (file)
@@ -148,5 +148,37 @@ bool Intersect(
        return true;
 }
 
+bool Intersect(
+       const Ray &r,
+       const Sphere &s,
+       glm::dvec3 &normal,
+       double &dist
+) noexcept {
+       const glm::dvec3 diff(s.origin - r.Origin());
+       if (glm::dot(diff, r.Direction()) < 0.0) {
+               if (glm::length2(diff) > s.radius * s.radius) return false;
+               if (std::abs(glm::length2(diff) - s.radius * s.radius) < std::numeric_limits<double>::epsilon() * s.radius) {
+                       normal = glm::normalize(-diff);
+                       dist = 0.0;
+                       return true;
+               }
+               const glm::dvec3 pc(r.Direction() * glm::dot(r.Direction(), diff) + r.Origin());
+               double idist = std::sqrt(s.radius * s.radius - glm::length2(pc - s.origin));
+               dist = idist - glm::length(pc - r.Origin());
+               normal = glm::normalize((r.Origin() + (r.Direction() * dist)) - s.origin);
+               return true;
+       }
+       const glm::dvec3 pc(r.Direction() * glm::dot(r.Direction(), diff) + r.Origin());
+       if (glm::length2(s.origin - pc) > s.radius * s.radius) return false;
+       double idist = std::sqrt(s.radius * s.radius - glm::length2(pc - s.origin));
+       if (glm::length2(diff) > s.radius * s.radius) {
+               dist = glm::length(pc - r.Origin()) - idist;
+       } else {
+               dist = glm::length(pc - r.Origin()) + idist;
+       }
+       normal = glm::normalize((r.Origin() + (r.Direction() * dist)) - s.origin);
+       return true;
+}
+
 }
 }
index 8f062841fe8adf64b05f6c8a0668f3e8a07adf2f..b4a9f50bb43c86c283691a65736f90981b62368a 100644 (file)
@@ -40,6 +40,7 @@ bool Intersect(
        glm::dvec3 &normal,
        double &depth) noexcept;
 
+
 class Ray {
 
 public:
@@ -77,6 +78,32 @@ bool Intersect(
        glm::dvec3 &normal,
        double &dist) noexcept;
 
+
+struct Sphere {
+
+       glm::dvec3 origin;
+       double radius;
+
+};
+
+/// matrix may scale, but only uniformly
+inline Sphere operator *(const glm::dmat4 &m, const Sphere &s) noexcept {
+       glm::dvec4 o(m * glm::dvec4(s.origin, 1.0));
+       glm::dvec4 p(m * glm::dvec4(s.origin + glm::dvec3(s.radius, 0.0, 0.0), 1.0));
+       return Sphere{glm::dvec3(o) / o.w, glm::length((glm::dvec3(p) / p.w) - (glm::dvec3(o) / o.w))};
+}
+
+inline std::ostream &operator <<(std::ostream &out, const Sphere &s) {
+       return out << "Sphere(" << s.origin << ", " << s.radius << ")";
+}
+
+/// oriented ray/sphere intersection test
+bool Intersect(
+       const Ray &,
+       const Sphere &,
+       glm::dvec3 &normal,
+       double &dist) noexcept;
+
 }
 }
 
diff --git a/src/ui/BodyPanel.hpp b/src/ui/BodyPanel.hpp
new file mode 100644 (file)
index 0000000..ef6d51f
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef BLOBS_UI_BODYPANEL_HPP_
+#define BLOBS_UI_BODYPANEL_HPP_
+
+#include "Panel.hpp"
+
+namespace blobs {
+namespace app {
+       struct Assets;
+}
+namespace graphics {
+       class Viewport;
+}
+namespace world {
+       class Body;
+}
+namespace ui {
+
+class Label;
+
+class BodyPanel {
+
+public:
+       explicit BodyPanel(app::Assets &);
+       ~BodyPanel();
+
+       BodyPanel(const BodyPanel &) = delete;
+       BodyPanel &operator =(const BodyPanel &) = delete;
+
+       BodyPanel(BodyPanel &&) = delete;
+       BodyPanel &operator =(BodyPanel &&) = delete;
+
+public:
+       void Show(world::Body &);
+       void Hide() noexcept;
+
+       bool Shown() const noexcept { return body; }
+       const world::Body &GetBody() const noexcept { return *body; }
+
+       void ZIndex(float z) noexcept { panel.ZIndex(z); }
+
+       void Draw(graphics::Viewport &) noexcept;
+
+private:
+       app::Assets &assets;
+       world::Body *body;
+
+       Label *name;
+       Label *mass;
+       Label *radius;
+       Label *soi;
+       Label *operiod;
+       Label *rperiod;
+       Label *atm;
+       Label *sma;
+       Label *ecc;
+       Label *inc;
+       Label *asc;
+       Label *arg;
+       Label *mna;
+       Panel panel;
+
+};
+
+}
+}
+
+#endif
index ff20ec1134d787ae8719aaae086dc05634244be0..5397c800c6fb2746d43f1832d89f7d5c43e237d1 100644 (file)
@@ -8,6 +8,7 @@
 namespace blobs {
 namespace ui {
 
+std::string AngleString(double a);
 std::string DecimalString(double n, int p);
 std::string LengthString(double m);
 std::string MassString(double kg);
index 126e3079b37fac1c9022298f7dd3831ee9bfa56e..35242d339c69c11f48e49e71168e49621779af6d 100644 (file)
@@ -1,3 +1,4 @@
+#include "BodyPanel.hpp"
 #include "CreaturePanel.hpp"
 #include "RecordsPanel.hpp"
 #include "string.hpp"
@@ -8,6 +9,7 @@
 #include "../app/Assets.hpp"
 #include "../creature/Creature.hpp"
 #include "../graphics/Viewport.hpp"
+#include "../math/const.hpp"
 #include "../world/Body.hpp"
 #include "../world/Simulation.hpp"
 
@@ -285,6 +287,127 @@ void CreaturePanel::Draw(graphics::Viewport &viewport) noexcept {
 }
 
 
+BodyPanel::BodyPanel(app::Assets &assets)
+: assets(assets)
+, body(nullptr)
+, name(new Label(assets.fonts.large))
+, mass(new Label(assets.fonts.medium))
+, radius(new Label(assets.fonts.medium))
+, soi(new Label(assets.fonts.medium))
+, operiod(new Label(assets.fonts.medium))
+, rperiod(new Label(assets.fonts.medium))
+, atm(new Label(assets.fonts.medium))
+, sma(new Label(assets.fonts.medium))
+, ecc(new Label(assets.fonts.medium))
+, inc(new Label(assets.fonts.medium))
+, asc(new Label(assets.fonts.medium))
+, arg(new Label(assets.fonts.medium))
+, mna(new Label(assets.fonts.medium))
+, panel() {
+       Label *mass_label = new Label(assets.fonts.medium);
+       mass_label->Text("Mass");
+       Label *radius_label = new Label(assets.fonts.medium);
+       radius_label->Text("Radius");
+       Label *soi_label = new Label(assets.fonts.medium);
+       soi_label->Text("SOI");
+       Label *operiod_label = new Label(assets.fonts.medium);
+       operiod_label->Text("Orb. period");
+       Label *rperiod_label = new Label(assets.fonts.medium);
+       rperiod_label->Text("Rot. period");
+       Label *atm_label = new Label(assets.fonts.medium);
+       atm_label->Text("Atmosphere");
+       Label *sma_label = new Label(assets.fonts.medium);
+       sma_label->Text("SMA");
+       Label *ecc_label = new Label(assets.fonts.medium);
+       ecc_label->Text("Eccentricity");
+       Label *inc_label = new Label(assets.fonts.medium);
+       inc_label->Text("Inclination");
+       Label *asc_label = new Label(assets.fonts.medium);
+       asc_label->Text("Asc. node");
+       Label *arg_label = new Label(assets.fonts.medium);
+       arg_label->Text("Arg. Periapsis");
+       Label *mna_label = new Label(assets.fonts.medium);
+       mna_label->Text("Mean anomaly");
+       Panel *label_panel = new Panel;
+       label_panel
+               ->Direction(Panel::VERTICAL)
+               ->Add(mass_label)
+               ->Add(radius_label)
+               ->Add(soi_label)
+               ->Add(operiod_label)
+               ->Add(rperiod_label)
+               ->Add(atm_label)
+               ->Add(sma_label)
+               ->Add(ecc_label)
+               ->Add(inc_label)
+               ->Add(asc_label)
+               ->Add(arg_label)
+               ->Add(mna_label);
+       Panel *value_panel = new Panel;
+       value_panel
+               ->Direction(Panel::VERTICAL)
+               ->Add(mass)
+               ->Add(radius)
+               ->Add(soi)
+               ->Add(operiod)
+               ->Add(rperiod)
+               ->Add(atm)
+               ->Add(sma)
+               ->Add(ecc)
+               ->Add(inc)
+               ->Add(asc)
+               ->Add(arg)
+               ->Add(mna);
+       Panel *info_panel = new Panel;
+       info_panel
+               ->Direction(Panel::HORIZONTAL)
+               ->Spacing(10.0f)
+               ->Add(label_panel)
+               ->Add(value_panel);
+
+       panel
+               .Add(name)
+               ->Add(info_panel)
+               ->Padding(glm::vec2(10.0f))
+               ->Spacing(10.0f)
+               ->Direction(Panel::VERTICAL)
+               ->Background(glm::vec4(1.0f, 1.0f, 1.0f, 0.7f));
+}
+
+BodyPanel::~BodyPanel() {
+}
+
+void BodyPanel::Show(world::Body &b) {
+       body = &b;
+       name->Text(b.Name());
+       mass->Text(MassString(b.Mass()));
+       radius->Text(LengthString(b.Radius()));
+       soi->Text(LengthString(b.SphereOfInfluence()));
+       operiod->Text(TimeString(b.OrbitalPeriod()));
+       rperiod->Text(TimeString(b.RotationalPeriod()));
+       atm->Text(b.HasAtmosphere() ? assets.data.resources[b.Atmosphere()].label : std::string("none"));
+       sma->Text(LengthString(b.GetOrbit().SemiMajorAxis()));
+       ecc->Text(DecimalString(b.GetOrbit().Eccentricity(), 3));
+       inc->Text(AngleString(b.GetOrbit().Inclination()));
+       asc->Text(AngleString(b.GetOrbit().LongitudeAscending()));
+       arg->Text(AngleString(b.GetOrbit().ArgumentPeriapsis()));
+       mna->Text(AngleString(b.GetOrbit().MeanAnomaly()));
+}
+
+void BodyPanel::Hide() noexcept {
+       body = nullptr;
+}
+
+void BodyPanel::Draw(graphics::Viewport &viewport) noexcept {
+       if (!Shown()) return;
+
+       const glm::vec2 margin(20.0f);
+       panel.Position(glm::vec2(viewport.Width() - margin.x - panel.Size().x, margin.y));
+       panel.Layout();
+       panel.Draw(assets, viewport);
+}
+
+
 RecordsPanel::RecordsPanel(world::Simulation &sim)
 : sim(sim)
 , records()
@@ -434,6 +557,29 @@ void TimePanel::Draw(graphics::Viewport &viewport) noexcept {
 }
 
 
+namespace {
+std::ostream &custom_fixed(std::ostream &out, double n, int d) {
+       double f = n;
+       int p = d;
+       while (f > 1.0 && p > 0) {
+               --p;
+               f *= 0.1;
+       }
+       if (p > 0) {
+               out << std::fixed << std::setprecision(p) << n;
+       } else {
+               out << std::defaultfloat << std::setprecision(d) << n;
+       }
+       return out;
+}
+}
+
+std::string AngleString(double a) {
+       std::stringstream s;
+       s << std::fixed << std::setprecision(2) << std::fmod(a * 180.0 * PI_inv, 360.0) << "°";
+       return s.str();
+}
+
 std::string DecimalString(double n, int p) {
        std::stringstream s;
        s << std::fixed << std::setprecision(p) << n;
@@ -442,28 +588,38 @@ std::string DecimalString(double n, int p) {
 
 std::string LengthString(double m) {
        std::stringstream s;
-       s << std::fixed << std::setprecision(3);
-       if (m > 1500.0) {
-               s << (m * 0.001) << "km";
-       } else if (m < 0.1) {
-               s << (m * 1000.0) << "mm";
+       if (m > 1.5e9) {
+               custom_fixed(s, m * 1.0e-9, 4) << "Gm";
+       } else if (m > 1.5e6) {
+               custom_fixed(s, m * 1.0e-6, 4) << "Mm";
+       } else if (m > 1.5e3) {
+               custom_fixed(s, m * 1.0e-3, 4) << "km";
+       } else if (m < 1.5e-3) {
+               custom_fixed(s, m * 1.0e3, 4) << "mm";
+       } else if (m < 1.5) {
+               custom_fixed(s, m * 1.0e2, 4) << "cm";
        } else {
-               s << m << "m";
+               custom_fixed(s, m, 4) << "m";
        }
        return s.str();
 }
 
 std::string MassString(double kg) {
        std::stringstream s;
-       s << std::fixed << std::setprecision(3);
-       if (kg > 1500.0) {
-               s << (kg * 0.001) << "t";
+       if (kg > 1.5e12) {
+               custom_fixed(s, kg * 1.0e-12, 4) << "Gt";
+       } else if (kg > 1.5e9) {
+               custom_fixed(s, kg * 1.0e-9, 4) << "Mt";
+       } else if (kg > 1.5e6) {
+               custom_fixed(s, kg * 1.0e-6, 4) << "kt";
+       } else if (kg > 1.5e3) {
+               custom_fixed(s, kg * 1.0e-3, 4) << "t";
+       } else if (kg < 1.0e-3) {
+               custom_fixed(s, kg * 1.0e6, 4) << "mg";
        } else if (kg < 1.0) {
-               s << (kg * 1000.0) << "g";
-       } else if (kg < 0.001) {
-               s << (kg * 1.0e6) << "mg";
+               custom_fixed(s, kg * 1.0e3, 4) << "g";
        } else {
-               s << kg << "kg";
+               custom_fixed(s, kg, 4) << "kg";
        }
        return s.str();
 }
@@ -480,16 +636,21 @@ std::string PercentageString(double n) {
 
 std::string TimeString(double s) {
        int is = int(s);
+       int md = 1;
+       int sd = 1;
        std::stringstream ss;
+       ss << std::setfill('0');
        if (is >= 3600) {
                ss << (is / 3600) << "h ";
                is %= 3600;
+               md = 2;
        }
        if (is >= 60) {
-               ss << (is / 60) << "m ";
+               ss << std::setw(md) << (is / 60) << "m ";
                is %= 60;
+               sd = 2;
        }
-       ss << is << 's';
+       ss << std::setw(sd) << is << 's';
        return ss.str();
 }
 
index 165d8483f5cbc6d890b7280ec91d6ed85401e6b1..d90806584b0e43d37f1202d0dcddce7e8afe3d23 100644 (file)
@@ -2,8 +2,10 @@
 #define BLOBS_WORLD_BODY_HPP_
 
 #include "Orbit.hpp"
+#include "../math/geometry.hpp"
 #include "../math/glm.hpp"
 
+#include <string>
 #include <vector>
 
 
@@ -47,6 +49,9 @@ public:
 
        const std::vector<Body *> &Children() const noexcept { return children; }
 
+       const std::string &Name() const noexcept { return name; }
+       void Name(const std::string &n) noexcept { name = n; }
+
        double Mass() const noexcept { return mass; }
        void Mass(double m) noexcept { mass = m; }
 
@@ -73,6 +78,10 @@ public:
        double GravitationalParameter() const noexcept;
        double OrbitalPeriod() const noexcept;
        double RotationalPeriod() const noexcept;
+       double SphereOfInfluence() const noexcept;
+
+       math::Sphere CollisionBounds() const noexcept { return math::Sphere{ glm::dvec3(0.0), Radius() }; }
+       const glm::dmat4 &CollisionTransform() const noexcept { return local; }
 
        const glm::dmat4 &LocalTransform() const noexcept { return local; }
        const glm::dmat4 &InverseTransform() const noexcept { return inverse_local; }
@@ -106,6 +115,7 @@ private:
        Simulation *sim;
        Body *parent;
        std::vector<Body *> children;
+       std::string name;
        double mass;
        double radius;
        Orbit orbit;
index 02c142ac5af08f52ecd42114bc8b6019d556bcad..c22434a47c754b8f3b028bcbabcb8888c04d7671 100644 (file)
@@ -115,6 +115,14 @@ double Body::RotationalPeriod() const noexcept {
        }
 }
 
+double Body::SphereOfInfluence() const noexcept {
+       if (HasParent()) {
+               return orbit.SemiMajorAxis() * std::pow(Mass() / Parent().Mass(), 2.0 / 5.0);
+       } else {
+               return std::numeric_limits<double>::infinity();
+       }
+}
+
 glm::dmat4 Body::ToUniverse() const noexcept {
        glm::dmat4 m(1.0);
        const Body *b = this;
@@ -184,13 +192,13 @@ void Body::CheckCollision() noexcept {
        collisions.clear();
        auto end = Creatures().end();
        for (auto i = Creatures().begin(); i != end; ++i) {
-               math::AABB i_box((*i)->CollisionBox());
+               math::AABB i_box((*i)->CollisionBounds());
                glm::dmat4 i_mat((*i)->CollisionTransform());
                for (auto j = (i + 1); j != end; ++j) {
                        glm::dvec3 diff((*i)->GetSituation().Position() - (*j)->GetSituation().Position());
                        double max_dist = ((*i)->Size() + (*j)->Size()) * 1.74;
                        if (glm::length2(diff) > max_dist * max_dist) continue;
-                       math::AABB j_box((*j)->CollisionBox());
+                       math::AABB j_box((*j)->CollisionBounds());
                        glm::dmat4 j_mat((*j)->CollisionTransform());
                        glm::dvec3 normal;
                        double depth;