]> git.localhorst.tv Git - gong.git/commitdiff
simple physics simulation
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 2 Dec 2016 11:13:36 +0000 (12:13 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 2 Dec 2016 11:13:36 +0000 (12:13 +0100)
no collision for now

src/physics/Derivative.hpp [new file with mode: 0644]
src/physics/Object.hpp [new file with mode: 0644]
src/physics/Simulation.hpp [new file with mode: 0644]
src/physics/State.hpp [new file with mode: 0644]
src/physics/sim.cpp [new file with mode: 0644]

diff --git a/src/physics/Derivative.hpp b/src/physics/Derivative.hpp
new file mode 100644 (file)
index 0000000..ae3d5e5
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef GONG_PHYSICS_DERIVATIVE_HPP_
+#define GONG_PHYSICS_DERIVATIVE_HPP_
+
+#include "../graphics/glm.hpp"
+
+#include <glm/gtc/quaternion.hpp>
+
+
+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 (file)
index 0000000..576317c
--- /dev/null
@@ -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 (file)
index 0000000..9d41877
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef GONG_PHYSICS_SIMULATION_HPP_
+#define GONG_PHYSICS_SIMULATION_HPP_
+
+#include "../graphics/glm.hpp"
+
+#include <vector>
+
+
+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<Object *> objects;
+       glm::vec3 gravity;
+
+};
+
+}
+}
+
+#endif
diff --git a/src/physics/State.hpp b/src/physics/State.hpp
new file mode 100644 (file)
index 0000000..76ff16c
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef GONG_PHYSICS_STATE_HPP_
+#define GONG_PHYSICS_STATE_HPP_
+
+#include "../graphics/glm.hpp"
+
+#include <glm/gtc/quaternion.hpp>
+
+
+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 (file)
index 0000000..568d28c
--- /dev/null
@@ -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;
+}
+
+}
+}