{
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); });
}
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);
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>;
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