Merge pull request #4387 from JoshuaGrams/rigidbody2d-torque

Hooked up RigidBody2D torque methods
This commit is contained in:
Rémi Verschelde 2016-04-29 10:29:12 +02:00
commit c97cc362e3
10 changed files with 144 additions and 15 deletions

View File

@ -24661,6 +24661,17 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
<method name="body_add_force">
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="offset" type="Vector2">
</argument>
<argument index="2" name="force" type="Vector2">
</argument>
<description>
Add a positioned force to the applied force and torque. As with [method body_apply_impulse], both the force and the offset from the body origin are in global coordinates.
</description>
</method>
<method name="body_set_axis_velocity">
<argument index="0" name="body" type="RID">
</argument>
@ -24948,13 +24959,15 @@ This method controls whether the position between two cached points is interpola
</constant>
<constant name="BODY_PARAM_MASS" value="2">
</constant>
<constant name="BODY_PARAM_GRAVITY_SCALE" value="3">
<constant name="BODY_PARAM_INERTIA" value="3">
</constant>
<constant name="BODY_PARAM_LINEAR_DAMP" value="4">
<constant name="BODY_PARAM_GRAVITY_SCALE" value="4">
</constant>
<constant name="BODY_PARAM_ANGULAR_DAMP" value="5">
<constant name="BODY_PARAM_LINEAR_DAMP" value="5">
</constant>
<constant name="BODY_PARAM_MAX" value="6">
<constant name="BODY_PARAM_ANGULAR_DAMP" value="6">
</constant>
<constant name="BODY_PARAM_MAX" value="7">
</constant>
<constant name="BODY_STATE_TRANSFORM" value="0">
</constant>
@ -30147,6 +30160,20 @@ This method controls whether the position between two cached points is interpola
Return the body mass.
</description>
</method>
<method name="get_inertia" qualifiers="const">
<return type="float">
</return>
<description>
Return the body's moment of inertia. This is usually automatically computed from the mass and the shapes. Note that this doesn't seem to work in a [code]_ready[/code] function: it apparently has not been auto-computed yet.
</description>
</method>
<method name="set_inertia">
<argument index="0" name="inertia" type="float">
</argument>
<description>
Set the body's moment of inertia. This is like mass, but for rotation: it determines how much torque it takes to rotate the body. The moment of inertia is usually computed automatically from the mass and the shapes, but this function allows you to set a custom value. Set 0 (or negative) inertia to return to automatically computing it.
</description>
</method>
<method name="set_weight">
<argument index="0" name="weight" type="float">
</argument>
@ -30324,12 +30351,12 @@ This method controls whether the position between two cached points is interpola
</description>
</method>
<method name="apply_impulse">
<argument index="0" name="pos" type="Vector2">
<argument index="0" name="offset" type="Vector2">
</argument>
<argument index="1" name="impulse" type="Vector2">
</argument>
<description>
Apply a positioned impulse (which will be affected by the body mass and shape). This is the equivalent of hitting a billiard ball with a cue: a force that is applied once, and only once.
Apply a positioned impulse (which will be affected by the body mass and shape). This is the equivalent of hitting a billiard ball with a cue: a force that is applied once, and only once. Both the impulse and the offset from the body origin are in global coordinates.
</description>
</method>
<method name="set_applied_force">
@ -30346,6 +30373,29 @@ This method controls whether the position between two cached points is interpola
Return the applied force vector.
</description>
</method>
<method name="set_applied_torque">
<argument index="0" name="torque" type="float">
</argument>
<description>
Set a constant torque which will be applied to this body.
</description>
</method>
<method name="get_applied_torque" qualifiers="const">
<return type="float">
</return>
<description>
Return the torque which is being applied to this body.
</description>
</method>
<method name="add_force">
<argument index="0" name="offset" type="Vector2">
</argument>
<argument index="1" name="force" type="Vector2">
</argument>
<description>
Add a positioned force to the applied force and torque. As with [method apply_impulse], both the force and the offset from the body origin are in global coordinates.
</description>
</method>
<method name="set_sleeping">
<argument index="0" name="sleeping" type="bool">
</argument>

View File

@ -602,6 +602,17 @@ real_t RigidBody2D::get_mass() const{
return mass;
}
void RigidBody2D::set_inertia(real_t p_inertia) {
ERR_FAIL_COND(p_inertia<=0);
Physics2DServer::get_singleton()->body_set_param(get_rid(),Physics2DServer::BODY_PARAM_INERTIA,p_inertia);
}
real_t RigidBody2D::get_inertia() const{
return Physics2DServer::get_singleton()->body_get_param(get_rid(),Physics2DServer::BODY_PARAM_INERTIA);
}
void RigidBody2D::set_weight(real_t p_weight){
set_mass(p_weight/9.8);
@ -767,9 +778,9 @@ int RigidBody2D::get_max_contacts_reported() const{
return max_contacts_reported;
}
void RigidBody2D::apply_impulse(const Vector2& p_pos, const Vector2& p_impulse) {
void RigidBody2D::apply_impulse(const Vector2& p_offset, const Vector2& p_impulse) {
Physics2DServer::get_singleton()->body_apply_impulse(get_rid(),p_pos,p_impulse);
Physics2DServer::get_singleton()->body_apply_impulse(get_rid(),p_offset,p_impulse);
}
void RigidBody2D::set_applied_force(const Vector2& p_force) {
@ -782,6 +793,20 @@ Vector2 RigidBody2D::get_applied_force() const {
return Physics2DServer::get_singleton()->body_get_applied_force(get_rid());
};
void RigidBody2D::set_applied_torque(const float p_torque) {
Physics2DServer::get_singleton()->body_set_applied_torque(get_rid(), p_torque);
};
float RigidBody2D::get_applied_torque() const {
return Physics2DServer::get_singleton()->body_get_applied_torque(get_rid());
};
void RigidBody2D::add_force(const Vector2& p_offset, const Vector2& p_force) {
Physics2DServer::get_singleton()->body_add_force(get_rid(),p_offset,p_force);
}
void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) {
@ -858,6 +883,9 @@ void RigidBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_mass","mass"),&RigidBody2D::set_mass);
ObjectTypeDB::bind_method(_MD("get_mass"),&RigidBody2D::get_mass);
ObjectTypeDB::bind_method(_MD("get_inertia"),&RigidBody2D::get_inertia);
ObjectTypeDB::bind_method(_MD("set_inertia","inertia"),&RigidBody2D::set_inertia);
ObjectTypeDB::bind_method(_MD("set_weight","weight"),&RigidBody2D::set_weight);
ObjectTypeDB::bind_method(_MD("get_weight"),&RigidBody2D::get_weight);
@ -895,11 +923,16 @@ void RigidBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_continuous_collision_detection_mode"),&RigidBody2D::get_continuous_collision_detection_mode);
ObjectTypeDB::bind_method(_MD("set_axis_velocity","axis_velocity"),&RigidBody2D::set_axis_velocity);
ObjectTypeDB::bind_method(_MD("apply_impulse","pos","impulse"),&RigidBody2D::apply_impulse);
ObjectTypeDB::bind_method(_MD("apply_impulse","offset","impulse"),&RigidBody2D::apply_impulse);
ObjectTypeDB::bind_method(_MD("set_applied_force","force"),&RigidBody2D::set_applied_force);
ObjectTypeDB::bind_method(_MD("get_applied_force"),&RigidBody2D::get_applied_force);
ObjectTypeDB::bind_method(_MD("set_applied_torque","torque"),&RigidBody2D::set_applied_torque);
ObjectTypeDB::bind_method(_MD("get_applied_torque"),&RigidBody2D::get_applied_torque);
ObjectTypeDB::bind_method(_MD("add_force","offset","force"),&RigidBody2D::add_force);
ObjectTypeDB::bind_method(_MD("set_sleeping","sleeping"),&RigidBody2D::set_sleeping);
ObjectTypeDB::bind_method(_MD("is_sleeping"),&RigidBody2D::is_sleeping);

View File

@ -217,6 +217,9 @@ public:
void set_mass(real_t p_mass);
real_t get_mass() const;
void set_inertia(real_t p_inertia);
real_t get_inertia() const;
void set_weight(real_t p_weight);
real_t get_weight() const;
@ -261,11 +264,16 @@ public:
void set_continuous_collision_detection_mode(CCDMode p_mode);
CCDMode get_continuous_collision_detection_mode() const;
void apply_impulse(const Vector2& p_pos, const Vector2& p_impulse);
void apply_impulse(const Vector2& p_offset, const Vector2& p_impulse);
void set_applied_force(const Vector2& p_force);
Vector2 get_applied_force() const;
void set_applied_torque(const float p_torque);
float get_applied_torque() const;
void add_force(const Vector2& p_offset, const Vector2& p_force);
Array get_colliding_bodies() const; //function for script

View File

@ -33,7 +33,7 @@
void Body2DSW::_update_inertia() {
if (get_space() && !inertia_update_list.in_list())
if (!user_inertia && get_space() && !inertia_update_list.in_list())
get_space()->body_add_to_inertia_update_list(&inertia_update_list);
}
@ -48,6 +48,8 @@ void Body2DSW::update_inertias() {
case Physics2DServer::BODY_MODE_RIGID: {
if(user_inertia) break;
//update tensor for allshapes, not the best way but should be somehow OK. (inspired from bullet)
float total_area=0;
@ -157,6 +159,15 @@ void Body2DSW::set_param(Physics2DServer::BodyParameter p_param, float p_value)
_update_inertia();
} break;
case Physics2DServer::BODY_PARAM_INERTIA: {
if(p_value<=0) {
user_inertia = false;
_update_inertia();
} else {
user_inertia = true;
_inv_inertia = 1.0 / p_value;
}
} break;
case Physics2DServer::BODY_PARAM_GRAVITY_SCALE: {
gravity_scale=p_value;
} break;
@ -186,6 +197,9 @@ float Body2DSW::get_param(Physics2DServer::BodyParameter p_param) const {
case Physics2DServer::BODY_PARAM_MASS: {
return mass;
} break;
case Physics2DServer::BODY_PARAM_INERTIA: {
return _inv_inertia==0 ? 0 : 1.0 / _inv_inertia;
} break;
case Physics2DServer::BODY_PARAM_GRAVITY_SCALE: {
return gravity_scale;
} break;
@ -665,6 +679,7 @@ Body2DSW::Body2DSW() : CollisionObject2DSW(TYPE_BODY), active_list(this), inerti
angular_velocity=0;
biased_angular_velocity=0;
mass=1;
user_inertia=false;
_inv_inertia=0;
_inv_mass=1;
bounce=0;

View File

@ -57,6 +57,7 @@ class Body2DSW : public CollisionObject2DSW {
real_t _inv_mass;
real_t _inv_inertia;
bool user_inertia;
Vector2 gravity;
real_t area_linear_damp;
@ -204,10 +205,10 @@ public:
_FORCE_INLINE_ real_t get_biased_angular_velocity() const { return biased_angular_velocity; }
_FORCE_INLINE_ void apply_impulse(const Vector2& p_pos, const Vector2& p_j) {
_FORCE_INLINE_ void apply_impulse(const Vector2& p_offset, const Vector2& p_impulse) {
linear_velocity += p_j * _inv_mass;
angular_velocity += _inv_inertia * p_pos.cross(p_j);
linear_velocity += p_impulse * _inv_mass;
angular_velocity += _inv_inertia * p_offset.cross(p_impulse);
}
_FORCE_INLINE_ void apply_bias_impulse(const Vector2& p_pos, const Vector2& p_j) {
@ -243,6 +244,11 @@ public:
void set_applied_torque(real_t p_torque) { applied_torque=p_torque; }
real_t get_applied_torque() const { return applied_torque; }
_FORCE_INLINE_ void add_force(const Vector2& p_force, const Vector2& p_offset) {
applied_force += p_force;
applied_torque += p_offset.cross(p_force);
}
_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode=p_mode; }
_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }

View File

@ -860,6 +860,15 @@ void Physics2DServerSW::body_apply_impulse(RID p_body, const Vector2& p_pos, con
body->wakeup();
};
void Physics2DServerSW::body_add_force(RID p_body, const Vector2& p_offset, const Vector2& p_force) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
body->add_force(p_force,p_offset);
body->wakeup();
};
void Physics2DServerSW::body_set_axis_velocity(RID p_body, const Vector2& p_axis_velocity) {
Body2DSW *body = body_owner.get(p_body);

View File

@ -205,6 +205,8 @@ public:
virtual void body_set_applied_torque(RID p_body, float p_torque);
virtual float body_get_applied_torque(RID p_body) const;
virtual void body_add_force(RID p_body, const Vector2& p_offset, const Vector2& p_force);
virtual void body_apply_impulse(RID p_body, const Vector2& p_pos, const Vector2& p_impulse);
virtual void body_set_axis_velocity(RID p_body, const Vector2& p_axis_velocity);

View File

@ -205,6 +205,7 @@ public:
FUNC2(body_set_applied_torque,RID,float);
FUNC1RC(float,body_get_applied_torque,RID);
FUNC3(body_add_force,RID,const Vector2&,const Vector2&);
FUNC3(body_apply_impulse,RID,const Vector2&,const Vector2&);
FUNC2(body_set_axis_velocity,RID,const Vector2&);

View File

@ -597,6 +597,7 @@ void Physics2DServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("body_get_state","body","state"),&Physics2DServer::body_get_state);
ObjectTypeDB::bind_method(_MD("body_apply_impulse","body","pos","impulse"),&Physics2DServer::body_apply_impulse);
ObjectTypeDB::bind_method(_MD("body_add_force","body","offset","force"),&Physics2DServer::body_add_force);
ObjectTypeDB::bind_method(_MD("body_set_axis_velocity","body","axis_velocity"),&Physics2DServer::body_set_axis_velocity);
ObjectTypeDB::bind_method(_MD("body_add_collision_exception","body","excepted_body"),&Physics2DServer::body_add_collision_exception);
@ -677,6 +678,7 @@ void Physics2DServer::_bind_methods() {
BIND_CONSTANT( BODY_PARAM_BOUNCE );
BIND_CONSTANT( BODY_PARAM_FRICTION );
BIND_CONSTANT( BODY_PARAM_MASS );
BIND_CONSTANT( BODY_PARAM_INERTIA );
BIND_CONSTANT( BODY_PARAM_GRAVITY_SCALE );
BIND_CONSTANT( BODY_PARAM_LINEAR_DAMP);
BIND_CONSTANT( BODY_PARAM_ANGULAR_DAMP);

View File

@ -421,6 +421,7 @@ public:
BODY_PARAM_BOUNCE,
BODY_PARAM_FRICTION,
BODY_PARAM_MASS, ///< unused for static, always infinite
BODY_PARAM_INERTIA, // read-only: computed from mass & shapes
BODY_PARAM_GRAVITY_SCALE,
BODY_PARAM_LINEAR_DAMP,
BODY_PARAM_ANGULAR_DAMP,
@ -450,7 +451,9 @@ public:
virtual void body_set_applied_torque(RID p_body, float p_torque)=0;
virtual float body_get_applied_torque(RID p_body) const=0;
virtual void body_apply_impulse(RID p_body, const Vector2& p_pos, const Vector2& p_impulse)=0;
virtual void body_add_force(RID p_body, const Vector2& p_offset, const Vector2& p_force)=0;
virtual void body_apply_impulse(RID p_body, const Vector2& p_offset, const Vector2& p_impulse)=0;
virtual void body_set_axis_velocity(RID p_body, const Vector2& p_axis_velocity)=0;
//fix