summaryrefslogtreecommitdiff
path: root/servers/physics_2d/godot_body_2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics_2d/godot_body_2d.cpp')
-rw-r--r--servers/physics_2d/godot_body_2d.cpp86
1 files changed, 48 insertions, 38 deletions
diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp
index 56f191c203..109914d585 100644
--- a/servers/physics_2d/godot_body_2d.cpp
+++ b/servers/physics_2d/godot_body_2d.cpp
@@ -187,6 +187,14 @@ void GodotBody2D::set_param(PhysicsServer2D::BodyParameter p_param, const Varian
case PhysicsServer2D::BODY_PARAM_GRAVITY_SCALE: {
gravity_scale = p_value;
} break;
+ case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP_MODE: {
+ int mode_value = p_value;
+ linear_damp_mode = (PhysicsServer2D::BodyDampMode)mode_value;
+ } break;
+ case PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP_MODE: {
+ int mode_value = p_value;
+ angular_damp_mode = (PhysicsServer2D::BodyDampMode)mode_value;
+ } break;
case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP: {
linear_damp = p_value;
} break;
@@ -218,6 +226,12 @@ Variant GodotBody2D::get_param(PhysicsServer2D::BodyParameter p_param) const {
case PhysicsServer2D::BODY_PARAM_GRAVITY_SCALE: {
return gravity_scale;
}
+ case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP_MODE: {
+ return linear_damp_mode;
+ }
+ case PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP_MODE: {
+ return angular_damp_mode;
+ }
case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP: {
return linear_damp;
}
@@ -401,8 +415,8 @@ void GodotBody2D::_compute_area_gravity_and_damping(const GodotArea2D *p_area) {
p_area->compute_gravity(get_transform().get_origin(), area_gravity);
gravity += area_gravity;
- area_linear_damp += p_area->get_linear_damp();
- area_angular_damp += p_area->get_angular_damp();
+ total_linear_damp += p_area->get_linear_damp();
+ total_angular_damp += p_area->get_angular_damp();
}
void GodotBody2D::_update_transform_dependent() {
@@ -414,19 +428,17 @@ void GodotBody2D::integrate_forces(real_t p_step) {
return;
}
- GodotArea2D *def_area = get_space()->get_default_area();
- // GodotArea2D *damp_area = def_area;
- ERR_FAIL_COND(!def_area);
-
int ac = areas.size();
bool stopped = false;
gravity = Vector2(0, 0);
- area_angular_damp = 0;
- area_linear_damp = 0;
+
+ total_linear_damp = 0.0;
+ total_angular_damp = 0.0;
+
+ // Combine gravity and damping from overlapping areas in priority order.
if (ac) {
areas.sort();
const AreaCMP *aa = &areas[0];
- // damp_area = aa[ac-1].area;
for (int i = ac - 1; i >= 0 && !stopped; i--) {
PhysicsServer2D::AreaSpaceOverrideMode mode = aa[i].area->get_space_override_mode();
switch (mode) {
@@ -438,8 +450,8 @@ void GodotBody2D::integrate_forces(real_t p_step) {
case PhysicsServer2D::AREA_SPACE_OVERRIDE_REPLACE:
case PhysicsServer2D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: {
gravity = Vector2(0, 0);
- area_angular_damp = 0;
- area_linear_damp = 0;
+ total_linear_damp = 0.0;
+ total_angular_damp = 0.0;
_compute_area_gravity_and_damping(aa[i].area);
stopped = mode == PhysicsServer2D::AREA_SPACE_OVERRIDE_REPLACE;
} break;
@@ -448,27 +460,36 @@ void GodotBody2D::integrate_forces(real_t p_step) {
}
}
}
+
+ // Override linear damping with body's value.
if (!stopped) {
+ GodotArea2D *def_area = get_space()->get_default_area();
+ ERR_FAIL_COND(!def_area);
+
_compute_area_gravity_and_damping(def_area);
}
- gravity *= gravity_scale;
- // If less than 0, override dampenings with that of the Body2D
- if (angular_damp >= 0) {
- area_angular_damp = angular_damp;
+ // Override linear damping with body's value.
+ switch (linear_damp_mode) {
+ case PhysicsServer2D::BODY_DAMP_MODE_COMBINE: {
+ total_linear_damp += linear_damp;
+ } break;
+ case PhysicsServer2D::BODY_DAMP_MODE_REPLACE: {
+ total_linear_damp = linear_damp;
+ } break;
}
- /*
- else
- area_angular_damp=damp_area->get_angular_damp();
- */
- if (linear_damp >= 0) {
- area_linear_damp = linear_damp;
+ // Override angular damping with body's value.
+ switch (angular_damp_mode) {
+ case PhysicsServer2D::BODY_DAMP_MODE_COMBINE: {
+ total_angular_damp += angular_damp;
+ } break;
+ case PhysicsServer2D::BODY_DAMP_MODE_REPLACE: {
+ total_angular_damp = angular_damp;
+ } break;
}
- /*
- else
- area_linear_damp=damp_area->get_linear_damp();
- */
+
+ gravity *= gravity_scale;
Vector2 motion;
bool do_motion = false;
@@ -483,13 +504,6 @@ void GodotBody2D::integrate_forces(real_t p_step) {
do_motion = true;
- /*
- for(int i=0;i<get_shape_count();i++) {
- set_shape_kinematic_advance(i,Vector2());
- set_shape_kinematic_retreat(i,0);
- }
- */
-
} else {
if (!omit_force_integration) {
//overridden by direct state query
@@ -498,13 +512,13 @@ void GodotBody2D::integrate_forces(real_t p_step) {
force += applied_force;
real_t torque = applied_torque;
- real_t damp = 1.0 - p_step * area_linear_damp;
+ real_t damp = 1.0 - p_step * total_linear_damp;
if (damp < 0) { // reached zero in the given time
damp = 0;
}
- real_t angular_damp = 1.0 - p_step * area_angular_damp;
+ real_t angular_damp = 1.0 - p_step * total_angular_damp;
if (angular_damp < 0) { // reached zero in the given time
angular_damp = 0;
@@ -523,8 +537,6 @@ void GodotBody2D::integrate_forces(real_t p_step) {
}
}
- //motion=linear_velocity*p_step;
-
biased_angular_velocity = 0;
biased_linear_velocity = Vector2();
@@ -532,8 +544,6 @@ void GodotBody2D::integrate_forces(real_t p_step) {
_update_shapes_with_motion(motion);
}
- // damp_area=nullptr; // clear the area, so it is set in the next frame
- def_area = nullptr; // clear the area, so it is set in the next frame
contact_count = 0;
}