Fix applied rotation from moving platforms in move_and_slide
When synchronizing CharacterBody motion with moving the platform using direct body state, only the linear velocity was taken into account. This change exposes velocity at local point in direct body state and uses it in move_and_slide to get the proper velocity that includes rotations.
This commit is contained in:
parent
0cee8831b2
commit
5650c83e4b
|
@ -137,6 +137,13 @@
|
|||
Returns the current state of the space, useful for queries.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_velocity_at_local_position" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<argument index="0" name="local_position" type="Vector2" />
|
||||
<description>
|
||||
Returns the body's velocity at the given relative position, including both translation and rotation.
|
||||
</description>
|
||||
</method>
|
||||
<method name="integrate_forces">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
|
|
@ -138,6 +138,13 @@
|
|||
Returns the current state of the space, useful for queries.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_velocity_at_local_position" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="local_position" type="Vector3" />
|
||||
<description>
|
||||
Returns the body's velocity at the given relative position, including both translation and rotation.
|
||||
</description>
|
||||
</method>
|
||||
<method name="integrate_forces">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
|
|
@ -114,6 +114,16 @@ Transform3D BulletPhysicsDirectBodyState3D::get_transform() const {
|
|||
return body->get_transform();
|
||||
}
|
||||
|
||||
Vector3 BulletPhysicsDirectBodyState3D::get_velocity_at_local_position(const Vector3 &p_position) const {
|
||||
btVector3 local_position;
|
||||
G_TO_B(p_position, local_position);
|
||||
|
||||
Vector3 velocity;
|
||||
B_TO_G(body->btBody->getVelocityInLocalPoint(local_position), velocity);
|
||||
|
||||
return velocity;
|
||||
}
|
||||
|
||||
void BulletPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) {
|
||||
body->apply_central_force(p_force);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,8 @@ public:
|
|||
virtual void set_transform(const Transform3D &p_transform) override;
|
||||
virtual Transform3D get_transform() const override;
|
||||
|
||||
virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const override;
|
||||
|
||||
virtual void add_central_force(const Vector3 &p_force) override;
|
||||
virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
|
||||
virtual void add_torque(const Vector3 &p_torque) override;
|
||||
|
|
|
@ -1062,7 +1062,9 @@ void CharacterBody2D::move_and_slide() {
|
|||
//this approach makes sure there is less delay between the actual body velocity and the one we saved
|
||||
PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(on_floor_body);
|
||||
if (bs) {
|
||||
current_floor_velocity = bs->get_linear_velocity();
|
||||
Transform2D gt = get_global_transform();
|
||||
Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2];
|
||||
current_floor_velocity = bs->get_velocity_at_local_position(local_position);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1101,7 +1101,9 @@ void CharacterBody3D::move_and_slide() {
|
|||
//this approach makes sure there is less delay between the actual body velocity and the one we saved
|
||||
PhysicsDirectBodyState3D *bs = PhysicsServer3D::get_singleton()->body_get_direct_state(on_floor_body);
|
||||
if (bs) {
|
||||
current_floor_velocity = bs->get_linear_velocity();
|
||||
Transform3D gt = get_global_transform();
|
||||
Vector3 local_position = gt.origin - bs->get_transform().origin;
|
||||
current_floor_velocity = bs->get_velocity_at_local_position(local_position);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -266,6 +266,10 @@ public:
|
|||
void integrate_forces(real_t p_step);
|
||||
void integrate_velocities(real_t p_step);
|
||||
|
||||
_FORCE_INLINE_ Vector2 get_velocity_in_local_point(const Vector2 &rel_pos) const {
|
||||
return linear_velocity + Vector2(-angular_velocity * rel_pos.y, angular_velocity * rel_pos.x);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector2 get_motion() const {
|
||||
if (mode > PhysicsServer2D::BODY_MODE_KINEMATIC) {
|
||||
return new_transform.get_origin() - get_transform().get_origin();
|
||||
|
@ -352,6 +356,8 @@ public:
|
|||
virtual void set_transform(const Transform2D &p_transform) override { body->set_state(PhysicsServer2D::BODY_STATE_TRANSFORM, p_transform); }
|
||||
virtual Transform2D get_transform() const override { return body->get_transform(); }
|
||||
|
||||
virtual Vector2 get_velocity_at_local_position(const Vector2 &p_position) const override { return body->get_velocity_in_local_point(p_position); }
|
||||
|
||||
virtual void add_central_force(const Vector2 &p_force) override { body->add_central_force(p_force); }
|
||||
virtual void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) override { body->add_force(p_force, p_position); }
|
||||
virtual void add_torque(real_t p_torque) override { body->add_torque(p_torque); }
|
||||
|
|
|
@ -389,6 +389,8 @@ public:
|
|||
virtual void set_transform(const Transform3D &p_transform) override { body->set_state(PhysicsServer3D::BODY_STATE_TRANSFORM, p_transform); }
|
||||
virtual Transform3D get_transform() const override { return body->get_transform(); }
|
||||
|
||||
virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const override { return body->get_velocity_in_local_point(p_position); }
|
||||
|
||||
virtual void add_central_force(const Vector3 &p_force) override { body->add_central_force(p_force); }
|
||||
virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override {
|
||||
body->add_force(p_force, p_position);
|
||||
|
|
|
@ -89,6 +89,8 @@ void PhysicsDirectBodyState2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &PhysicsDirectBodyState2D::set_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_transform"), &PhysicsDirectBodyState2D::get_transform);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_velocity_at_local_position", "local_position"), &PhysicsDirectBodyState2D::get_velocity_at_local_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_central_force", "force"), &PhysicsDirectBodyState2D::add_central_force);
|
||||
ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState2D::add_force, Vector2());
|
||||
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState2D::add_torque);
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
virtual void set_transform(const Transform2D &p_transform) = 0;
|
||||
virtual Transform2D get_transform() const = 0;
|
||||
|
||||
virtual Vector2 get_velocity_at_local_position(const Vector2 &p_position) const = 0;
|
||||
|
||||
virtual void add_central_force(const Vector2 &p_force) = 0;
|
||||
virtual void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
|
||||
virtual void add_torque(real_t p_torque) = 0;
|
||||
|
|
|
@ -91,6 +91,8 @@ void PhysicsDirectBodyState3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &PhysicsDirectBodyState3D::set_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_transform"), &PhysicsDirectBodyState3D::get_transform);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_velocity_at_local_position", "local_position"), &PhysicsDirectBodyState3D::get_velocity_at_local_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_central_force", "force"), &PhysicsDirectBodyState3D::add_central_force, Vector3());
|
||||
ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState3D::add_force, Vector3());
|
||||
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState3D::add_torque);
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
virtual void set_transform(const Transform3D &p_transform) = 0;
|
||||
virtual Transform3D get_transform() const = 0;
|
||||
|
||||
virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const = 0;
|
||||
|
||||
virtual void add_central_force(const Vector3 &p_force) = 0;
|
||||
virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
|
||||
virtual void add_torque(const Vector3 &p_torque) = 0;
|
||||
|
|
Loading…
Reference in New Issue