From: Daniel Karbach Date: Fri, 2 Dec 2016 11:13:36 +0000 (+0100) Subject: simple physics simulation X-Git-Url: http://git.localhorst.tv/?p=gong.git;a=commitdiff_plain;h=d220b0348951ce210ad4ea18dbe9934dd2999a60 simple physics simulation no collision for now --- diff --git a/src/physics/Derivative.hpp b/src/physics/Derivative.hpp new file mode 100644 index 0000000..ae3d5e5 --- /dev/null +++ b/src/physics/Derivative.hpp @@ -0,0 +1,49 @@ +#ifndef GONG_PHYSICS_DERIVATIVE_HPP_ +#define GONG_PHYSICS_DERIVATIVE_HPP_ + +#include "../graphics/glm.hpp" + +#include + + +namespace gong { +namespace physics { + +struct State; + + +struct Derivative { + + glm::vec3 dpos; + glm::vec3 dlin; + glm::quat dorient; + glm::vec3 dang; + + Derivative() noexcept; + Derivative( + const glm::vec3 &, + const glm::vec3 &, + const glm::quat &, + const glm::vec3 & + ) noexcept; + +}; + + +inline Derivative operator +(const Derivative &a, const Derivative &b) noexcept { + return Derivative(a.dpos + b.dpos, a.dlin + b.dlin, a.dorient * b.dorient, a.dang + b.dang); +} + +inline Derivative operator *(float f, const Derivative &d) noexcept { + return Derivative(f * d.dpos, f * d.dlin, f * d.dorient, f * d.dang); +} +inline Derivative operator *(const Derivative &d, float f) noexcept { + return f * d; +} + +State &operator +=(State &s, const Derivative &d) noexcept; + +} +} + +#endif diff --git a/src/physics/Object.hpp b/src/physics/Object.hpp new file mode 100644 index 0000000..576317c --- /dev/null +++ b/src/physics/Object.hpp @@ -0,0 +1,21 @@ +#ifndef GONG_PHYSICS_OBJECT_HPP_ +#define GONG_PHYSICS_OBJECT_HPP_ + +#include "State.hpp" +#include "../geometry/primitive.hpp" + + +namespace gong { +namespace physics { + +struct Object { + + State state; + geometry::AABB bounds; + +}; + +} +} + +#endif diff --git a/src/physics/Simulation.hpp b/src/physics/Simulation.hpp new file mode 100644 index 0000000..9d41877 --- /dev/null +++ b/src/physics/Simulation.hpp @@ -0,0 +1,34 @@ +#ifndef GONG_PHYSICS_SIMULATION_HPP_ +#define GONG_PHYSICS_SIMULATION_HPP_ + +#include "../graphics/glm.hpp" + +#include + + +namespace gong { +namespace physics { + +struct Derivative; +struct Object; +struct State; + +class Simulation { + +public: + void Update(float dt); + +private: + void Integrate(State &, float dt); + Derivative Evaluate(const State &, float dt, const Derivative &); + +private: + std::vector objects; + glm::vec3 gravity; + +}; + +} +} + +#endif diff --git a/src/physics/State.hpp b/src/physics/State.hpp new file mode 100644 index 0000000..76ff16c --- /dev/null +++ b/src/physics/State.hpp @@ -0,0 +1,37 @@ +#ifndef GONG_PHYSICS_STATE_HPP_ +#define GONG_PHYSICS_STATE_HPP_ + +#include "../graphics/glm.hpp" + +#include + + +namespace gong { +namespace physics { + +struct State { + /// position of center of mass + glm::vec3 pos; + /// linear momentum + glm::vec3 lin; + /// orientation + glm::quat orient; + /// angular momentum + glm::vec3 ang; + /// angular velocity as quat + glm::quat Spin() const noexcept { + return 0.5f * glm::quat(0.0f, ang * inverse_inertia) * orient; + } + float mass; + /// 1/mass + float inverse_mass; + /// rotational inertia + float inertia; + /// 1/inertia + float inverse_inertia; +}; + +} +} + +#endif diff --git a/src/physics/sim.cpp b/src/physics/sim.cpp new file mode 100644 index 0000000..568d28c --- /dev/null +++ b/src/physics/sim.cpp @@ -0,0 +1,73 @@ +#include "Derivative.hpp" +#include "Object.hpp" +#include "Simulation.hpp" +#include "State.hpp" + + +namespace gong { +namespace physics { + +Derivative::Derivative() noexcept +: dpos(0.0f) +, dlin(0.0f) +, dorient(1.0f, 0.0f, 0.0f, 0.0f) +, dang(0.0f) { + +} + +Derivative::Derivative( + const glm::vec3 &p, + const glm::vec3 &l, + const glm::quat &o, + const glm::vec3 &a +) noexcept +: dpos(p) +, dlin(l) +, dorient(o) +, dang(a) { + +} + + +void Simulation::Update(float dt) { + // integrate state + for (Object *o : objects) { + Integrate(o->state, dt); + } + // TODO: detect collisions + // TODO: resolve collisions +} + +void Simulation::Integrate(State &s, float dt) { + Derivative a(Evaluate(s, 0.0f, Derivative())); + Derivative b(Evaluate(s, dt * 0.5f, a)); + Derivative c(Evaluate(s, dt * 0.5f, b)); + Derivative d(Evaluate(s, dt, c)); + constexpr float by_six = 1.0f / 6.0f; + Derivative f((a + (2.0f * (b + c)) + d) * by_six); + s += f * dt; +} + +Derivative Simulation::Evaluate(const State &s, float dt, const Derivative &d) { + // TODO: calculate linear and torque forces from list of raw forces + glm::vec3 force(gravity); + glm::vec3 torque(0.0f); + return Derivative( + s.lin + d.dpos * dt * s.inverse_mass, + force, + glm::normalize(s.Spin() + d.dorient * dt * s.inverse_inertia), + torque + ); +} + + +State &operator +=(State &s, const Derivative &d) noexcept { + s.pos += d.dpos; + s.lin += d.dlin; + s.orient *= d.dorient; + s.ang += d.dang; + return s; +} + +} +}