From: Daniel Karbach Date: Sun, 10 Dec 2017 16:32:24 +0000 (+0100) Subject: fix friction X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=e35e0c2da8e86fc15cde78ab94c7d7273bd185c3 fix friction --- diff --git a/src/app/states.cpp b/src/app/states.cpp index 98add96..5e3642b 100644 --- a/src/app/states.cpp +++ b/src/app/states.cpp @@ -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(); } diff --git a/src/blobs.cpp b/src/blobs.cpp index d032d9d..52d4b57 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -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); diff --git a/src/creature/Situation.hpp b/src/creature/Situation.hpp index a442d44..ea46617 100644 --- a/src/creature/Situation.hpp +++ b/src/creature/Situation.hpp @@ -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; } diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp index 085d70f..9b85eff 100644 --- a/src/creature/creature.cpp +++ b/src/creature/creature.cpp @@ -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; diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp index 2034b8d..f7efc58 100644 --- a/src/world/Planet.hpp +++ b/src/world/Planet.hpp @@ -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; diff --git a/src/world/Sun.hpp b/src/world/Sun.hpp index a47c039..dd84862 100644 --- a/src/world/Sun.hpp +++ b/src/world/Sun.hpp @@ -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; + }; } diff --git a/src/world/world.cpp b/src/world/world.cpp index c22434a..2f0d130 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -694,7 +694,9 @@ void GenerateTest(const Set &tiles, Planet &p) noexcept { Sun::Sun() -: Body() { +: Body() +, color(1.0) +, luminosity(1.0) { } Sun::~Sun() {