summaryrefslogtreecommitdiff
path: root/scene/3d/physics_body_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/physics_body_3d.cpp')
-rw-r--r--scene/3d/physics_body_3d.cpp206
1 files changed, 168 insertions, 38 deletions
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 4f1003839e..b3192a5bb5 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -174,9 +174,12 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer3D::MotionResult *r = nullptr;
+ PhysicsServer3D::MotionResult temp_result;
if (r_collision.is_valid()) {
// Needs const_cast because method bindings don't support non-const Ref.
r = const_cast<PhysicsServer3D::MotionResult *>(&r_collision->result);
+ } else {
+ r = &temp_result;
}
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
@@ -184,7 +187,14 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear
PhysicsServer3D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
- return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), parameters, r);
+ bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), parameters, r);
+
+ if (colliding) {
+ // Don't report collision when the whole motion is done.
+ return (r->collision_safe_fraction < 1.0);
+ } else {
+ return false;
+ }
}
void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {
@@ -758,8 +768,26 @@ real_t RigidDynamicBody3D::get_gravity_scale() const {
return gravity_scale;
}
+void RigidDynamicBody3D::set_linear_damp_mode(DampMode p_mode) {
+ linear_damp_mode = p_mode;
+ PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE, linear_damp_mode);
+}
+
+RigidDynamicBody3D::DampMode RigidDynamicBody3D::get_linear_damp_mode() const {
+ return linear_damp_mode;
+}
+
+void RigidDynamicBody3D::set_angular_damp_mode(DampMode p_mode) {
+ angular_damp_mode = p_mode;
+ PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE, angular_damp_mode);
+}
+
+RigidDynamicBody3D::DampMode RigidDynamicBody3D::get_angular_damp_mode() const {
+ return angular_damp_mode;
+}
+
void RigidDynamicBody3D::set_linear_damp(real_t p_linear_damp) {
- ERR_FAIL_COND(p_linear_damp < -1);
+ ERR_FAIL_COND(p_linear_damp < 0.0);
linear_damp = p_linear_damp;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp);
}
@@ -769,7 +797,7 @@ real_t RigidDynamicBody3D::get_linear_damp() const {
}
void RigidDynamicBody3D::set_angular_damp(real_t p_angular_damp) {
- ERR_FAIL_COND(p_angular_damp < -1);
+ ERR_FAIL_COND(p_angular_damp < 0.0);
angular_damp = p_angular_damp;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp);
}
@@ -847,30 +875,59 @@ int RigidDynamicBody3D::get_max_contacts_reported() const {
return max_contacts_reported;
}
-void RigidDynamicBody3D::add_central_force(const Vector3 &p_force) {
- PhysicsServer3D::get_singleton()->body_add_central_force(get_rid(), p_force);
+void RigidDynamicBody3D::apply_central_impulse(const Vector3 &p_impulse) {
+ PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
}
-void RigidDynamicBody3D::add_force(const Vector3 &p_force, const Vector3 &p_position) {
+void RigidDynamicBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
PhysicsServer3D *singleton = PhysicsServer3D::get_singleton();
- singleton->body_add_force(get_rid(), p_force, p_position);
+ singleton->body_apply_impulse(get_rid(), p_impulse, p_position);
}
-void RigidDynamicBody3D::add_torque(const Vector3 &p_torque) {
- PhysicsServer3D::get_singleton()->body_add_torque(get_rid(), p_torque);
+void RigidDynamicBody3D::apply_torque_impulse(const Vector3 &p_impulse) {
+ PhysicsServer3D::get_singleton()->body_apply_torque_impulse(get_rid(), p_impulse);
}
-void RigidDynamicBody3D::apply_central_impulse(const Vector3 &p_impulse) {
- PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse);
+void RigidDynamicBody3D::apply_central_force(const Vector3 &p_force) {
+ PhysicsServer3D::get_singleton()->body_apply_central_force(get_rid(), p_force);
}
-void RigidDynamicBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
+void RigidDynamicBody3D::apply_force(const Vector3 &p_force, const Vector3 &p_position) {
PhysicsServer3D *singleton = PhysicsServer3D::get_singleton();
- singleton->body_apply_impulse(get_rid(), p_impulse, p_position);
+ singleton->body_apply_force(get_rid(), p_force, p_position);
}
-void RigidDynamicBody3D::apply_torque_impulse(const Vector3 &p_impulse) {
- PhysicsServer3D::get_singleton()->body_apply_torque_impulse(get_rid(), p_impulse);
+void RigidDynamicBody3D::apply_torque(const Vector3 &p_torque) {
+ PhysicsServer3D::get_singleton()->body_apply_torque(get_rid(), p_torque);
+}
+
+void RigidDynamicBody3D::add_constant_central_force(const Vector3 &p_force) {
+ PhysicsServer3D::get_singleton()->body_add_constant_central_force(get_rid(), p_force);
+}
+
+void RigidDynamicBody3D::add_constant_force(const Vector3 &p_force, const Vector3 &p_position) {
+ PhysicsServer3D *singleton = PhysicsServer3D::get_singleton();
+ singleton->body_add_constant_force(get_rid(), p_force, p_position);
+}
+
+void RigidDynamicBody3D::add_constant_torque(const Vector3 &p_torque) {
+ PhysicsServer3D::get_singleton()->body_add_constant_torque(get_rid(), p_torque);
+}
+
+void RigidDynamicBody3D::set_constant_force(const Vector3 &p_force) {
+ PhysicsServer3D::get_singleton()->body_set_constant_force(get_rid(), p_force);
+}
+
+Vector3 RigidDynamicBody3D::get_constant_force() const {
+ return PhysicsServer3D::get_singleton()->body_get_constant_force(get_rid());
+}
+
+void RigidDynamicBody3D::set_constant_torque(const Vector3 &p_torque) {
+ PhysicsServer3D::get_singleton()->body_set_constant_torque(get_rid(), p_torque);
+}
+
+Vector3 RigidDynamicBody3D::get_constant_torque() const {
+ return PhysicsServer3D::get_singleton()->body_get_constant_torque(get_rid());
}
void RigidDynamicBody3D::set_use_continuous_collision_detection(bool p_enable) {
@@ -970,6 +1027,12 @@ void RigidDynamicBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidDynamicBody3D::set_gravity_scale);
ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidDynamicBody3D::get_gravity_scale);
+ ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &RigidDynamicBody3D::set_linear_damp_mode);
+ ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &RigidDynamicBody3D::get_linear_damp_mode);
+
+ ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &RigidDynamicBody3D::set_angular_damp_mode);
+ ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &RigidDynamicBody3D::get_angular_damp_mode);
+
ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidDynamicBody3D::set_linear_damp);
ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidDynamicBody3D::get_linear_damp);
@@ -990,14 +1053,24 @@ void RigidDynamicBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidDynamicBody3D::set_axis_velocity);
- ClassDB::bind_method(D_METHOD("add_central_force", "force"), &RigidDynamicBody3D::add_central_force);
- ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &RigidDynamicBody3D::add_force, Vector3());
- ClassDB::bind_method(D_METHOD("add_torque", "torque"), &RigidDynamicBody3D::add_torque);
-
ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidDynamicBody3D::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidDynamicBody3D::apply_impulse, Vector3());
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidDynamicBody3D::apply_torque_impulse);
+ ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidDynamicBody3D::apply_central_force);
+ ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidDynamicBody3D::apply_force, Vector3());
+ ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidDynamicBody3D::apply_torque);
+
+ ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidDynamicBody3D::add_constant_central_force);
+ ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidDynamicBody3D::add_constant_force, Vector3());
+ ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidDynamicBody3D::add_constant_torque);
+
+ ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidDynamicBody3D::set_constant_force);
+ ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidDynamicBody3D::get_constant_force);
+
+ ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidDynamicBody3D::set_constant_torque);
+ ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidDynamicBody3D::get_constant_torque);
+
ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidDynamicBody3D::set_sleeping);
ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidDynamicBody3D::is_sleeping);
@@ -1035,10 +1108,15 @@ void RigidDynamicBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "freeze_mode", PROPERTY_HINT_ENUM, "Static,Kinematic"), "set_freeze_mode", "get_freeze_mode");
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_linear_damp_mode", "get_linear_damp_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_GROUP("Constant Forces", "constant_");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_force"), "set_constant_force", "get_constant_force");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_torque"), "set_constant_torque", "get_constant_torque");
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
@@ -1051,12 +1129,15 @@ void RigidDynamicBody3D::_bind_methods() {
BIND_ENUM_CONSTANT(CENTER_OF_MASS_MODE_AUTO);
BIND_ENUM_CONSTANT(CENTER_OF_MASS_MODE_CUSTOM);
+
+ BIND_ENUM_CONSTANT(DAMP_MODE_COMBINE);
+ BIND_ENUM_CONSTANT(DAMP_MODE_REPLACE);
}
void RigidDynamicBody3D::_validate_property(PropertyInfo &property) const {
if (center_of_mass_mode != CENTER_OF_MASS_MODE_CUSTOM) {
if (property.name == "center_of_mass") {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
}
PhysicsBody3D::_validate_property(property);
@@ -1116,6 +1197,10 @@ bool CharacterBody3D::move_and_slide() {
if (bs) {
Vector3 local_position = gt.origin - bs->get_transform().origin;
current_platform_velocity = bs->get_velocity_at_local_position(local_position);
+ } else {
+ // Body is removed or destroyed, invalidate floor.
+ current_platform_velocity = Vector3();
+ platform_rid = RID();
}
} else {
current_platform_velocity = Vector3();
@@ -1256,7 +1341,6 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
// in order to avoid blocking lateral motion along a wall.
if (motion_angle < .5 * Math_PI) {
apply_default_sliding = false;
-
if (p_was_on_floor && !vel_dir_facing_up) {
// Cancel the motion.
Transform3D gt = get_global_transform();
@@ -1264,14 +1348,18 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
real_t cancel_dist_max = MIN(0.1, margin * 20);
if (travel_total <= margin + CMP_EPSILON) {
gt.origin -= result.travel;
+ result.travel = Vector3(); // Cancel for constant speed computation.
} else if (travel_total < cancel_dist_max) { // If the movement is large the body can be prevented from reaching the walls.
gt.origin -= result.travel.slide(up_direction);
// Keep remaining motion in sync with amount canceled.
motion = motion.slide(up_direction);
+ result.travel = Vector3();
+ } else {
+ // Travel is too high to be safely cancelled, we take it into account.
+ result.travel = result.travel.slide(up_direction);
+ motion = motion.normalized() * result.travel.length();
}
set_global_transform(gt);
- result.travel = Vector3(); // Cancel for constant speed computation.
-
// Determines if you are on the ground, and limits the possibility of climbing on the walls because of the approximations.
_snap_on_floor(true, false);
} else {
@@ -1282,8 +1370,15 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo
// Apply slide on forward in order to allow only lateral motion on next step.
Vector3 forward = wall_normal.slide(up_direction).normalized();
motion = motion.slide(forward);
- // Avoid accelerating when you jump on the wall and smooth falling.
- motion_velocity = motion_velocity.slide(forward);
+
+ // Scales the horizontal velocity according to the wall slope.
+ if (vel_dir_facing_up) {
+ Vector3 slide_motion = motion_velocity.slide(result.collisions[0].normal);
+ // Keeps the vertical motion from motion_velocity and add the horizontal motion of the projection.
+ motion_velocity = up_direction * up_direction.dot(motion_velocity) + slide_motion.slide(up_direction);
+ } else {
+ motion_velocity = motion_velocity.slide(forward);
+ }
// Allow only lateral motion along previous floor when already on floor.
// Fixes slowing down when moving in diagonal against an inclined wall.
@@ -1541,6 +1636,7 @@ void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResu
Vector3 prev_wall_normal = wall_normal;
int wall_collision_count = 0;
Vector3 combined_wall_normal;
+ Vector3 tmp_wall_col; // Avoid duplicate on average calculation.
for (int i = p_result.collision_count - 1; i >= 0; i--) {
const PhysicsServer3D::MotionCollision &collision = p_result.collisions[i];
@@ -1587,8 +1683,11 @@ void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResu
}
// Collect normal for calculating average.
- combined_wall_normal += collision.normal;
- wall_collision_count++;
+ if (!collision.normal.is_equal_approx(tmp_wall_col)) {
+ tmp_wall_col = collision.normal;
+ combined_wall_normal += collision.normal;
+ wall_collision_count++;
+ }
}
if (r_state.wall) {
@@ -1904,8 +2003,8 @@ void CharacterBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_motion_velocity", "get_motion_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_slides", "get_max_slides");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_motion_velocity", "get_motion_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_slides", "get_max_slides");
ADD_GROUP("Free Mode", "free_mode_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle");
ADD_GROUP("Floor", "floor_");
@@ -1931,7 +2030,7 @@ void CharacterBody3D::_bind_methods() {
void CharacterBody3D::_validate_property(PropertyInfo &property) const {
if (motion_mode == MOTION_MODE_FREE) {
if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") {
- property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
+ property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL;
}
}
PhysicsBody3D::_validate_property(property);
@@ -2825,6 +2924,12 @@ void PhysicalBone3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale);
ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale);
+ ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &PhysicalBone3D::set_linear_damp_mode);
+ ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &PhysicalBone3D::get_linear_damp_mode);
+
+ ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &PhysicalBone3D::set_angular_damp_mode);
+ ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &PhysicalBone3D::get_angular_damp_mode);
+
ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp);
ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp);
@@ -2845,10 +2950,15 @@ void PhysicalBone3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_linear_damp_mode", "get_linear_damp_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
+ BIND_ENUM_CONSTANT(DAMP_MODE_COMBINE);
+ BIND_ENUM_CONSTANT(DAMP_MODE_REPLACE);
+
BIND_ENUM_CONSTANT(JOINT_TYPE_NONE);
BIND_ENUM_CONSTANT(JOINT_TYPE_PIN);
BIND_ENUM_CONSTANT(JOINT_TYPE_CONE);
@@ -3146,8 +3256,27 @@ real_t PhysicalBone3D::get_gravity_scale() const {
return gravity_scale;
}
+void PhysicalBone3D::set_linear_damp_mode(DampMode p_mode) {
+ linear_damp_mode = p_mode;
+ PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE, linear_damp_mode);
+}
+
+PhysicalBone3D::DampMode PhysicalBone3D::get_linear_damp_mode() const {
+ return linear_damp_mode;
+}
+
+void PhysicalBone3D::set_angular_damp_mode(DampMode p_mode) {
+ angular_damp_mode = p_mode;
+ PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE, angular_damp_mode);
+}
+
+PhysicalBone3D::DampMode PhysicalBone3D::get_angular_damp_mode() const {
+ return angular_damp_mode;
+}
+
void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) {
- ERR_FAIL_COND(p_linear_damp < -1);
+ ERR_FAIL_COND(p_linear_damp < 0);
+
linear_damp = p_linear_damp;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp);
}
@@ -3157,7 +3286,8 @@ real_t PhysicalBone3D::get_linear_damp() const {
}
void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) {
- ERR_FAIL_COND(p_angular_damp < -1);
+ ERR_FAIL_COND(p_angular_damp < 0);
+
angular_damp = p_angular_damp;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp);
}