]> git.tdb.fi Git - libs/game.git/commitdiff
Add support for kinematic motion of rigid bodies
authorMikko Rasa <tdb@tdb.fi>
Mon, 31 Mar 2025 12:03:31 +0000 (15:03 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 31 Mar 2025 12:03:31 +0000 (15:03 +0300)
source/game/physicssystem.cpp
source/game/physicssystem.h
source/game/rigidbody.cpp [new file with mode: 0644]
source/game/rigidbody.h

index 32f71e2da0c3a318a18a34956fa5c1c23f77144d..3d2c85caafc2c1249054fe6e2efbbb1b70347c21 100644 (file)
@@ -30,6 +30,7 @@ PhysicsSystem::PhysicsSystem(Stage &s):
 {
        declare_dependency<Transform>(CHAINED_UPDATE);
        declare_dependency<Motion>(CHAINED_UPDATE);
+       declare_dependency<RigidBody>(READ_FRESH);
 
        monitor.set_changed_callback([this](auto &b){ simulated_rigid_body_changed(b); });
 }
@@ -93,12 +94,23 @@ void PhysicsSystem::tick(Time::TimeDelta dt)
        for(SimulatedRigidBody &b: rigid_bodies)
        {
                Handle<Transform> transform = b.entity->get_transform();
-               if(transform->get_read_generation()!=b.transform_generation)
+               bool transform_changed = (transform->get_read_generation()!=b.transform_generation);
+               bool motion_changed = (b.motion && b.motion->get_read_generation()!=b.motion_generation);
+               bool kinematic = b.body->is_kinematic();
+
+               if(b.motion && b.body->get_read_generation()!=b.body_generation)
+                       b.physics_body->set_motion_type(kinematic ? Physics::KINEMATIC : Physics::DYNAMIC);
+
+               if(transform_changed)
                {
                        const TransformValues &tv = transform->get_values();
-                       b.physics_body->set_transform(tv.position, tv.rotation);
+                       if(b.body->is_kinematic() && !motion_changed)
+                               b.physics_body->move_kinematic(tv.position, tv.rotation, dt);
+                       else
+                               b.physics_body->set_transform(tv.position, tv.rotation);
                }
-               if(b.motion && b.motion->get_read_generation()!=b.motion_generation)
+
+               if(motion_changed)
                {
                        const MotionValues &mv = b.motion->get_values();
                        b.physics_body->set_velocities(mv.linear_velocity, mv.angular_velocity);
index 5c342082e7e3d5ca60c87b1d99520fb70ba56bf1..e56b3541ffcd7d1dfa5674834ba97074dbbaeb6c 100644 (file)
@@ -35,6 +35,7 @@ private:
                std::unique_ptr<Physics::RigidBody> physics_body;
                uint8_t transform_generation = 0;
                uint8_t motion_generation = 0;
+               uint8_t body_generation = 0;
 
                using Components = ArchetypeComponents<&SimulatedRigidBody::body, &SimulatedRigidBody::shape, &SimulatedRigidBody::motion>;
 
diff --git a/source/game/rigidbody.cpp b/source/game/rigidbody.cpp
new file mode 100644 (file)
index 0000000..c572d82
--- /dev/null
@@ -0,0 +1,10 @@
+#include "rigidbody.h"
+
+namespace Msp::Game {
+
+void RigidBody::set_kinematic(bool k)
+{
+       write().kinematic = k;
+}
+
+} // namespace Msp::Game
index 4de67384e8212c592ed96a987b909cfd6197c5a1..1d1a19d203c9e4935ab5ab7169bad89714a21d2e 100644 (file)
@@ -6,10 +6,18 @@
 
 namespace Msp::Game {
 
-class MSPGAME_API RigidBody: public Component
+struct RigidBodyData
+{
+       bool kinematic = false;
+};
+
+class MSPGAME_API RigidBody: public BufferedComponent<RigidBodyData>
 {
 public:
-       RigidBody(Handle<Entity> e): Component(e) { }
+       RigidBody(Handle<Entity> e): BufferedComponent(e) { }
+
+       void set_kinematic(bool);
+       bool is_kinematic() const { return read().kinematic; }
 };
 
 } // namespace Msp::Game