Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Fix applied rotation from moving platforms in move_and_slide #51447

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/classes/Physics2DDirectBodyState.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
7 changes: 7 additions & 0 deletions doc/classes/PhysicsDirectBodyState.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
10 changes: 10 additions & 0 deletions modules/bullet/rigid_body_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ Transform BulletPhysicsDirectBodyState::get_transform() const {
return body->get_transform();
}

Vector3 BulletPhysicsDirectBodyState::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 BulletPhysicsDirectBodyState::add_central_force(const Vector3 &p_force) {
body->apply_central_force(p_force);
}
Expand Down
2 changes: 2 additions & 0 deletions modules/bullet/rigid_body_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class BulletPhysicsDirectBodyState : public PhysicsDirectBodyState {
virtual void set_transform(const Transform &p_transform);
virtual Transform get_transform() const;

virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const;

virtual void add_central_force(const Vector3 &p_force);
virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos);
virtual void add_torque(const Vector3 &p_torque);
Expand Down
4 changes: 3 additions & 1 deletion scene/2d/physics_body_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,9 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
//this approach makes sure there is less delay between the actual body velocity and the one we saved
Physics2DDirectBodyState *bs = Physics2DServer::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);
}
}

Expand Down
4 changes: 3 additions & 1 deletion scene/3d/physics_body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,9 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
// This approach makes sure there is less delay between the actual body velocity and the one we saved.
PhysicsDirectBodyState *bs = PhysicsServer::get_singleton()->body_get_direct_state(on_floor_body);
if (bs) {
current_floor_velocity = bs->get_linear_velocity();
Transform gt = get_global_transform();
Vector3 local_position = gt.origin - bs->get_transform().origin;
current_floor_velocity = bs->get_velocity_at_local_position(local_position);
}
}

Expand Down
2 changes: 2 additions & 0 deletions servers/physics/body_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ class PhysicsDirectBodyStateSW : public PhysicsDirectBodyState {
virtual void set_transform(const Transform &p_transform) { body->set_state(PhysicsServer::BODY_STATE_TRANSFORM, p_transform); }
virtual Transform get_transform() const { return body->get_transform(); }

virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const { return body->get_velocity_in_local_point(p_position); }

virtual void add_central_force(const Vector3 &p_force) { body->add_central_force(p_force); }
virtual void add_force(const Vector3 &p_force, const Vector3 &p_pos) { body->add_force(p_force, p_pos); }
virtual void add_torque(const Vector3 &p_torque) { body->add_torque(p_torque); }
Expand Down
6 changes: 6 additions & 0 deletions servers/physics_2d/body_2d_sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ class Body2DSW : public CollisionObject2DSW {
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 > Physics2DServer::BODY_MODE_KINEMATIC) {
return new_transform.get_origin() - get_transform().get_origin();
Expand Down Expand Up @@ -359,6 +363,8 @@ class Physics2DDirectBodyStateSW : public Physics2DDirectBodyState {
virtual void set_transform(const Transform2D &p_transform) { body->set_state(Physics2DServer::BODY_STATE_TRANSFORM, p_transform); }
virtual Transform2D get_transform() const { return body->get_transform(); }

virtual Vector2 get_velocity_at_local_position(const Vector2 &p_position) const { return body->get_velocity_in_local_point(p_position); }

virtual void add_central_force(const Vector2 &p_force) { body->add_central_force(p_force); }
virtual void add_force(const Vector2 &p_offset, const Vector2 &p_force) { body->add_force(p_offset, p_force); }
virtual void add_torque(real_t p_torque) { body->add_torque(p_torque); }
Expand Down
2 changes: 2 additions & 0 deletions servers/physics_2d_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ void Physics2DDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &Physics2DDirectBodyState::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &Physics2DDirectBodyState::get_transform);

ClassDB::bind_method(D_METHOD("get_velocity_at_local_position", "local_position"), &Physics2DDirectBodyState::get_velocity_at_local_position);

ClassDB::bind_method(D_METHOD("add_central_force", "force"), &Physics2DDirectBodyState::add_central_force);
ClassDB::bind_method(D_METHOD("add_force", "offset", "force"), &Physics2DDirectBodyState::add_force);
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &Physics2DDirectBodyState::add_torque);
Expand Down
2 changes: 2 additions & 0 deletions servers/physics_2d_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class Physics2DDirectBodyState : public Object {
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_offset, const Vector2 &p_force) = 0;
virtual void add_torque(real_t p_torque) = 0;
Expand Down
2 changes: 2 additions & 0 deletions servers/physics_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ void PhysicsDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &PhysicsDirectBodyState::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &PhysicsDirectBodyState::get_transform);

ClassDB::bind_method(D_METHOD("get_velocity_at_local_position", "local_position"), &PhysicsDirectBodyState::get_velocity_at_local_position);

ClassDB::bind_method(D_METHOD("add_central_force", "force"), &PhysicsDirectBodyState::add_central_force);
ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState::add_force);
ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState::add_torque);
Expand Down
2 changes: 2 additions & 0 deletions servers/physics_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class PhysicsDirectBodyState : public Object {
virtual void set_transform(const Transform &p_transform) = 0;
virtual Transform 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_pos) = 0;
virtual void add_torque(const Vector3 &p_torque) = 0;
Expand Down