]> git.localhorst.tv Git - blobs.git/commitdiff
fix friction
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 10 Dec 2017 16:32:24 +0000 (17:32 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 10 Dec 2017 16:32:24 +0000 (17:32 +0100)
src/app/states.cpp
src/blobs.cpp
src/creature/Situation.hpp
src/creature/creature.cpp
src/world/Planet.hpp
src/world/Sun.hpp
src/world/world.cpp

index 98add9653a5af3e0571b82c6e6fd52435eb135c4..5e3642b6bb4433cd7073df99daa22c9f163641d9 100644 (file)
@@ -189,12 +189,10 @@ void MasterState::OnRender(graphics::Viewport &viewport) {
        for (auto sun : sim.Suns()) {
                // TODO: source sun's light color and strength
                glm::vec3 pos(cam.View() * cam.Model(*sun)[3]);
-               glm::vec3 col(1.0f, 1.0f, 1.0f);
-               float str = 1.0e6f;
                assets.shaders.planet_surface.Activate();
-               assets.shaders.planet_surface.SetLight(num_lights, pos, col, str);
+               assets.shaders.planet_surface.SetLight(num_lights, pos, sun->Color(), sun->Luminosity());
                assets.shaders.creature_skin.Activate();
-               assets.shaders.creature_skin.SetLight(num_lights, pos, col, str);
+               assets.shaders.creature_skin.SetLight(num_lights, pos, sun->Color(), sun->Luminosity());
                ++num_lights;
                if (num_lights >= graphics::PlanetSurface::MAX_LIGHTS || num_lights >= graphics::CreatureSkin::MAX_LIGHTS) {
                        break;
@@ -231,7 +229,7 @@ void MasterState::OnRender(graphics::Viewport &viewport) {
                double sun_radius = sun->Radius();
                assets.shaders.sun_surface.SetM(
                        cam.Model(*sun) * glm::scale(glm::vec3(sun_radius, sun_radius, sun_radius)));
-               assets.shaders.sun_surface.SetLight(glm::vec3(1.0f, 1.0f, 1.0f), 1.0e6f);
+               assets.shaders.sun_surface.SetLight(sun->Color(), sun->Luminosity());
                assets.shaders.sun_surface.Draw();
        }
 
index d032d9de33502e86d4fe9aa6998103bd2ea84c30..52d4b578b554e0dfe019f4641902f19b3495e89b 100644 (file)
@@ -21,36 +21,38 @@ int main(int argc, char *argv[]) {
 
        world::Sun sun;
        sun.Name("Sun");
-       sun.Mass(1.0e14);
-       sun.Radius(20.0);
+       sun.Mass(1.0e17);
+       sun.Radius(200.0);
+       sun.Color(glm::dvec3(1.0));
+       sun.Luminosity(1.0e8);
        sun.SurfaceTilt(glm::dvec2(PI * 0.25, PI * 0.25));
-       sun.AngularMomentum(1.0e13);
+       sun.AngularMomentum(1.0e18);
 
        world::Planet planet(25);
        planet.Name("Planet");
        planet.SetParent(sun);
-       planet.Mass(1.0e10);
-       planet.GetOrbit().SemiMajorAxis(941.7);
+       planet.Mass(1.0e13);
+       planet.GetOrbit().SemiMajorAxis(8184.0);
        planet.SurfaceTilt(glm::dvec2(PI * 0.25, PI * 0.25));
        planet.AxialTilt(glm::dvec2(PI * 0.127, 0.0));
-       planet.AngularMomentum(6.0e10);
+       planet.AngularMomentum(6.5e13);
 
-       world::Planet moon(3);
+       world::Planet moon(5);
        moon.Name("Moon");
        moon.SetParent(planet);
-       moon.Mass(1.0e6);
-       moon.GetOrbit().SemiMajorAxis(37.0);
+       moon.Mass(1.0e7);
+       moon.GetOrbit().SemiMajorAxis(72.5);
        moon.Rotation(PI * 0.25);
-       moon.AngularMomentum(1.0e4);
+       moon.AngularMomentum(5.22e5);
 
-       world::Planet second_planet(9);
+       world::Planet second_planet(14);
        second_planet.Name("Second planet");
        second_planet.SetParent(sun);
-       second_planet.Mass(1.0e9);
-       second_planet.GetOrbit().SemiMajorAxis(350.0);
+       second_planet.Mass(1.0e12);
+       second_planet.GetOrbit().SemiMajorAxis(4350.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);
+       second_planet.AngularMomentum(1.0e12);
 
        world::Simulation sim(sun, assets);
        sim.AddSun(sun);
index a442d4473e7b5dca314025d4538db1e97ef539ab..ea466177f085ce270d0b0ca67d3389091c67c89f 100644 (file)
@@ -66,7 +66,7 @@ public:
        bool Moving() const noexcept { return glm::length2(state.vel) > 0.00001; }
        void Move(const glm::dvec3 &dp) noexcept;
        void Accelerate(const glm::dvec3 &dv) noexcept;
-       void EnforceConstraints(State &) noexcept;
+       void EnforceConstraints(State &) const noexcept;
 
        void Heading(const glm::dvec3 &h) noexcept { state.dir = h; }
        const glm::dvec3 &Heading() const noexcept { return state.dir; }
index 085d70f000554bec57537f0b419b62f474ccb3eb..9b85eff73a81d68d98bc308d3bbc3b146f257d04 100644 (file)
@@ -463,27 +463,31 @@ void Creature::TickState(double dt) {
        }
        situation.SetState(state);
        // work is force times distance
-       DoWork(glm::length(f.acc) * Mass() * glm::length(f.vel) * dt);
+       // exclude gravity for no apparent reason
+       // actually, this should solely be based on steering force
+       DoWork(glm::length(f.acc - situation.GetPlanet().GravityAt(state.pos)) * Mass() * glm::length(f.vel) * dt);
 }
 
 Situation::Derivative Creature::Step(const Situation::Derivative &ds, double dt) const noexcept {
        Situation::State s = situation.GetState();
        s.pos += ds.vel * dt;
        s.vel += ds.acc * dt;
+       situation.EnforceConstraints(s);
        glm::dvec3 force(steering.Force(s));
        // gravity = antinormal * mass * Gm / r²
        glm::dvec3 normal(situation.GetPlanet().NormalAt(s.pos));
        force += glm::dvec3(
                -normal
-               * Mass() * situation.GetPlanet().GravitationalParameter()
-               / glm::length2(s.pos));
+               * (Mass() * situation.GetPlanet().GravitationalParameter()
+               / glm::length2(s.pos)));
        // if net force is applied and in contact with surface
-       if (!allzero(force) && glm::length2(s.pos) < (situation.GetPlanet().Radius() + 0.01) * (situation.GetPlanet().Radius() + 0.01)) {
-               // apply friction = -|normal force| * tangential force * coefficient
+       if (!allzero(force) && !allzero(s.vel) && glm::length2(s.pos) < (situation.GetPlanet().Radius() + 0.01) * (situation.GetPlanet().Radius() + 0.01)) {
+               // apply friction
                glm::dvec3 fn(normal * glm::dot(force, normal));
+               // TODO: friction somehow bigger than force?
                glm::dvec3 ft(force - fn);
                double u = 0.4;
-               glm::dvec3 friction(-glm::length(fn) * ft * u);
+               glm::dvec3 friction(-glm::clamp(glm::length(ft), 0.0, glm::length(fn) * u) * glm::normalize(s.vel));
                force += friction;
        }
        return {
@@ -847,7 +851,7 @@ bool Memory::RememberLocation(const Composition &accept, glm::dvec3 &pos) const
                        c.GetSimulation().Assets().random.SNorm(),
                        c.GetSimulation().Assets().random.SNorm(),
                        c.GetSimulation().Assets().random.SNorm());
-               pos += error * (2.0 * (1.0 - c.IntelligenceFactor()));
+               pos += error * (4.0 * (1.0 - c.IntelligenceFactor()));
                pos = glm::normalize(pos) * c.GetSituation().GetPlanet().Radius();
                return true;
        } else {
@@ -952,11 +956,13 @@ void Situation::Accelerate(const glm::dvec3 &dv) noexcept {
        EnforceConstraints(state);
 }
 
-void Situation::EnforceConstraints(State &s) noexcept {
+void Situation::EnforceConstraints(State &s) const noexcept {
        if (OnSurface()) {
                double r = GetPlanet().Radius();
                if (glm::length2(s.pos) < r * r) {
-                       s.pos = glm::normalize(s.pos) * r;
+                       const glm::dvec3 normal(GetPlanet().NormalAt(s.pos));
+                       s.pos = normal * r;
+                       s.vel -= normal * glm::dot(normal, s.vel);
                }
        }
 }
@@ -1064,7 +1070,7 @@ glm::dvec3 Steering::Force(const Situation::State &s) const noexcept {
        }
        // remove vertical component, if any
        const glm::dvec3 normal(c.GetSituation().GetPlanet().NormalAt(s.pos));
-       result += normal * glm::dot(normal, result);
+       result -= normal * glm::dot(normal, result);
        // clamp to max
        if (glm::length2(result) > max_force * max_force) {
                result = glm::normalize(result) * max_force;
index 2034b8dc4c787b4f30e6a52eb87389402e1c1f95..f7efc585d6dbac8f58bf6ca0b3ae2cbddbcfedc2 100644 (file)
@@ -41,6 +41,8 @@ public:
        double ElevationAt(const glm::dvec3 &p) const noexcept { return glm::length(p) - Radius(); }
        /// distance to planet center
        double DistanceAt(const glm::dvec3 &p) const noexcept { return glm::length(p); }
+       /// acceleration due to gravity at given point
+       glm::dvec3 GravityAt(const glm::dvec3 &p) const noexcept { return NormalAt(p) * (-GravitationalParameter() / glm::length2(p)); }
 
        /// get ground tile
        Tile &TileAt(const glm::dvec3 &) noexcept;
index a47c039c7721bb0047be671ec00f459d426ca3e8..dd848623ef9e5ee74e9b1c93e8dd21161933eb7b 100644 (file)
@@ -20,6 +20,17 @@ public:
        Sun(Sun &&) = delete;
        Sun &operator =(Sun &&) = delete;
 
+public:
+       void Color(const glm::dvec3 &c) noexcept { color = c; }
+       const glm::dvec3 &Color() const noexcept { return color; }
+
+       void Luminosity(double l) noexcept { luminosity = l; }
+       double Luminosity() const noexcept { return luminosity; }
+
+private:
+       glm::dvec3 color;
+       double luminosity;
+
 };
 
 }
index c22434a47c754b8f3b028bcbabcb8888c04d7671..2f0d130312916bd6a289ae9bcc2ca50c7f9cce2b 100644 (file)
@@ -694,7 +694,9 @@ void GenerateTest(const Set<TileType> &tiles, Planet &p) noexcept {
 
 
 Sun::Sun()
-: Body() {
+: Body()
+, color(1.0)
+, luminosity(1.0) {
 }
 
 Sun::~Sun() {