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

Implemented physics linear and angular lock #14516

Merged
merged 1 commit into from
Dec 10, 2017
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
8 changes: 4 additions & 4 deletions modules/bullet/bullet_physics_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,16 +723,16 @@ void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_ax
body->set_linear_velocity(v);
}

void BulletPhysicsServer::body_set_axis_lock(RID p_body, int axis, bool p_lock) {
void BulletPhysicsServer::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) {
RigidBodyBullet *body = rigid_body_owner.get(p_body);
ERR_FAIL_COND(!body);
body->set_axis_lock(axis, p_lock);
body->set_axis_lock(p_axis, p_lock);
}

bool BulletPhysicsServer::body_get_axis_lock(RID p_body) const {
bool BulletPhysicsServer::body_is_axis_locked(RID p_body, BodyAxis p_axis) const {
const RigidBodyBullet *body = rigid_body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_axis_lock();
return body->is_axis_locked(p_axis);
}

void BulletPhysicsServer::body_add_collision_exception(RID p_body, RID p_body_b) {
Expand Down
4 changes: 2 additions & 2 deletions modules/bullet/bullet_physics_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ class BulletPhysicsServer : public PhysicsServer {
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity);

virtual void body_set_axis_lock(RID p_body, int axis, bool p_lock);
virtual bool body_get_axis_lock(RID p_body) const;
virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock);
virtual bool body_is_axis_locked(RID p_body, BodyAxis p_axis) const;

virtual void body_add_collision_exception(RID p_body, RID p_body_b);
virtual void body_remove_collision_exception(RID p_body, RID p_body_b);
Expand Down
41 changes: 24 additions & 17 deletions modules/bullet/rigid_body_bullet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
RigidBodyBullet::RigidBodyBullet() :
RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY),
kinematic_utilities(NULL),
locked_axis(0),
gravity_scale(1),
mass(1),
linearDamp(0),
Expand All @@ -277,7 +278,7 @@ RigidBodyBullet::RigidBodyBullet() :
setupBulletCollisionObject(btBody);

set_mode(PhysicsServer::BODY_MODE_RIGID);
set_axis_lock(0, locked_axis[0]);
reload_axis_lock();

areasWhereIam.resize(maxAreasWhereIam);
for (int i = areasWhereIam.size() - 1; 0 <= i; --i) {
Expand Down Expand Up @@ -498,25 +499,25 @@ void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) {
switch (p_mode) {
case PhysicsServer::BODY_MODE_KINEMATIC:
mode = PhysicsServer::BODY_MODE_KINEMATIC;
set_axis_lock(0, locked_axis[0]); // Reload axis lock
reload_axis_lock();
_internal_set_mass(0);
init_kinematic_utilities();
break;
case PhysicsServer::BODY_MODE_STATIC:
mode = PhysicsServer::BODY_MODE_STATIC;
set_axis_lock(0, locked_axis[0]); // Reload axis lock
reload_axis_lock();
_internal_set_mass(0);
break;
case PhysicsServer::BODY_MODE_RIGID: {
mode = PhysicsServer::BODY_MODE_RIGID;
set_axis_lock(0, locked_axis[0]); // Reload axis lock
reload_axis_lock();
_internal_set_mass(0 == mass ? 1 : mass);
scratch_space_override_modificator();
break;
}
case PhysicsServer::BODY_MODE_CHARACTER: {
mode = PhysicsServer::BODY_MODE_CHARACTER;
set_axis_lock(0, locked_axis[0]); // Reload axis lock
reload_axis_lock();
_internal_set_mass(0 == mass ? 1 : mass);
scratch_space_override_modificator();
break;
Expand Down Expand Up @@ -655,25 +656,31 @@ Vector3 RigidBodyBullet::get_applied_torque() const {
return gTotTorq;
}

void RigidBodyBullet::set_axis_lock(int axis, bool p_lock) {
locked_axis[axis] = p_lock;
void RigidBodyBullet::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) {
if (lock) {
locked_axis |= p_axis;
} else {
locked_axis &= ~p_axis;
}

btBody->setLinearFactor(btVector3(locked_axis[0] ? 0 : 1., locked_axis[1] ? 0 : 1., locked_axis[2] ? 0 : 1.));
if (locked_axis[0] || locked_axis[1] || locked_axis[2])
btBody->setAngularFactor(btVector3(locked_axis[0] ? 1. : 0, locked_axis[1] ? 1. : 0, locked_axis[2] ? 1. : 0));
else
btBody->setAngularFactor(btVector3(1., 1., 1.));
reload_axis_lock();
}

bool RigidBodyBullet::is_axis_locked(PhysicsServer::BodyAxis p_axis) const {
return locked_axis & p_axis;
}

void RigidBodyBullet::reload_axis_lock() {

btBody->setLinearFactor(btVector3(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_X), !is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Y), !is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Z)));
if (PhysicsServer::BODY_MODE_CHARACTER == mode) {
/// When character lock angular
/// When character angular is always locked
btBody->setAngularFactor(btVector3(0., 0., 0.));
} else {
btBody->setAngularFactor(btVector3(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_X), !is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Y), !is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Z)));
}
}

bool RigidBodyBullet::get_axis_lock() const {
return locked_axis;
}

void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
if (p_enable) {
// This threshold enable CCD if the object moves more than
Expand Down
7 changes: 4 additions & 3 deletions modules/bullet/rigid_body_bullet.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ class RigidBodyBullet : public RigidCollisionObjectBullet {
KinematicUtilities *kinematic_utilities;

PhysicsServer::BodyMode mode;
bool locked_axis[3] = { false, false, false };
GodotMotionState *godotMotionState;
btRigidBody *btBody;
uint16_t locked_axis;
real_t mass;
real_t gravity_scale;
real_t linearDamp;
Expand Down Expand Up @@ -269,8 +269,9 @@ class RigidBodyBullet : public RigidCollisionObjectBullet {
void set_applied_torque(const Vector3 &p_torque);
Vector3 get_applied_torque() const;

void set_axis_lock(int axis, bool p_lock);
bool get_axis_lock() const;
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock);
bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const;
void reload_axis_lock();

/// Doc:
/// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping
Expand Down
96 changes: 28 additions & 68 deletions scene/3d/physics_body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,31 +734,12 @@ bool RigidBody::is_contact_monitor_enabled() const {
return contact_monitor != NULL;
}

void RigidBody::set_axis_lock_x(bool p_lock) {
RigidBody::locked_axis[0] = p_lock;
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]);
void RigidBody::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock) {
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
}

void RigidBody::set_axis_lock_y(bool p_lock) {
RigidBody::locked_axis[1] = p_lock;
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]);
}

void RigidBody::set_axis_lock_z(bool p_lock) {
RigidBody::locked_axis[2] = p_lock;
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]);
}

bool RigidBody::get_axis_lock_x() const {
return RigidBody::locked_axis[0];
}

bool RigidBody::get_axis_lock_y() const {
return RigidBody::locked_axis[1];
}

bool RigidBody::get_axis_lock_z() const {
return RigidBody::locked_axis[2];
bool RigidBody::get_axis_lock(PhysicsServer::BodyAxis p_axis) const {
return PhysicsServer::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
}

Array RigidBody::get_colliding_bodies() const {
Expand Down Expand Up @@ -853,12 +834,8 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree);
ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree);

ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &RigidBody::set_axis_lock_x);
ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &RigidBody::set_axis_lock_y);
ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &RigidBody::set_axis_lock_z);
ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &RigidBody::get_axis_lock_x);
ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &RigidBody::get_axis_lock_y);
ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &RigidBody::get_axis_lock_z);
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody::set_axis_lock);
ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody::get_axis_lock);

ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies);

Expand All @@ -877,9 +854,12 @@ void RigidBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
ADD_GROUP("Axis Lock", "axis_lock_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_X);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_X);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Y);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z);
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
Expand Down Expand Up @@ -969,7 +949,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli
}

for (int i = 0; i < 3; i++) {
if (locked_axis[i]) {
if (locked_axis & (1 << i)) {
result.motion[i] = 0;
}
}
Expand All @@ -985,7 +965,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
Vector3 lv = p_linear_velocity;

for (int i = 0; i < 3; i++) {
if (locked_axis[i]) {
if (locked_axis & (1 << i)) {
lv[i] = 0;
}
}
Expand Down Expand Up @@ -1038,7 +1018,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
lv = lv.slide(n);

for (int i = 0; i < 3; i++) {
if (locked_axis[i]) {
if (locked_axis & (1 << i)) {
lv[i] = 0;
}
}
Expand Down Expand Up @@ -1082,31 +1062,12 @@ bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion)
return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion);
}

void KinematicBody::set_axis_lock_x(bool p_lock) {
KinematicBody::locked_axis[0] = p_lock;
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]);
void KinematicBody::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock) {
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
}

void KinematicBody::set_axis_lock_y(bool p_lock) {
KinematicBody::locked_axis[1] = p_lock;
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]);
}

void KinematicBody::set_axis_lock_z(bool p_lock) {
KinematicBody::locked_axis[2] = p_lock;
PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]);
}

bool KinematicBody::get_axis_lock_x() const {
return KinematicBody::locked_axis[0];
}

bool KinematicBody::get_axis_lock_y() const {
return KinematicBody::locked_axis[1];
}

bool KinematicBody::get_axis_lock_z() const {
return KinematicBody::locked_axis[2];
bool KinematicBody::get_axis_lock(PhysicsServer::BodyAxis p_axis) const {
return PhysicsServer::get_singleton()->body_is_axis_locked(get_rid(), p_axis);
}

void KinematicBody::set_safe_margin(float p_margin) {
Expand Down Expand Up @@ -1157,12 +1118,8 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);

ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &KinematicBody::set_axis_lock_x);
ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &KinematicBody::set_axis_lock_y);
ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &KinematicBody::set_axis_lock_z);
ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &KinematicBody::get_axis_lock_x);
ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &KinematicBody::get_axis_lock_y);
ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &KinematicBody::get_axis_lock_z);
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody::set_axis_lock);
ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody::get_axis_lock);

ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
Expand All @@ -1171,9 +1128,12 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);

ADD_GROUP("Axis Lock", "axis_lock_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_X);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_X);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Y);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z);

ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
Expand All @@ -1182,7 +1142,7 @@ KinematicBody::KinematicBody() :
PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) {

margin = 0.001;

locked_axis = 0;
on_floor = false;
on_ceiling = false;
on_wall = false;
Expand Down
20 changes: 5 additions & 15 deletions scene/3d/physics_body.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,6 @@ class RigidBody : public PhysicsBody {
bool sleeping;
bool ccd;

bool locked_axis[3] = { false, false, false };

int max_contacts_reported;

bool custom_integrator;
Expand Down Expand Up @@ -238,12 +236,8 @@ class RigidBody : public PhysicsBody {
void set_use_continuous_collision_detection(bool p_enable);
bool is_using_continuous_collision_detection() const;

void set_axis_lock_x(bool p_lock);
void set_axis_lock_y(bool p_lock);
void set_axis_lock_z(bool p_lock);
bool get_axis_lock_x() const;
bool get_axis_lock_y() const;
bool get_axis_lock_z() const;
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock);
bool get_axis_lock(PhysicsServer::BodyAxis p_axis) const;

Array get_colliding_bodies() const;

Expand Down Expand Up @@ -277,7 +271,7 @@ class KinematicBody : public PhysicsBody {
};

private:
bool locked_axis[3] = { false, false, false };
uint16_t locked_axis;

float margin;

Expand All @@ -301,12 +295,8 @@ class KinematicBody : public PhysicsBody {
bool move_and_collide(const Vector3 &p_motion, Collision &r_collision);
bool test_move(const Transform &p_from, const Vector3 &p_motion);

void set_axis_lock_x(bool p_lock);
void set_axis_lock_y(bool p_lock);
void set_axis_lock_z(bool p_lock);
bool get_axis_lock_x() const;
bool get_axis_lock_y() const;
bool get_axis_lock_z() const;
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool p_lock);
bool get_axis_lock(PhysicsServer::BodyAxis p_axis) const;

void set_safe_margin(float p_margin);
float get_safe_margin() const;
Expand Down
Loading