diff options
Diffstat (limited to 'scene/3d/physics_body_3d.cpp')
-rw-r--r-- | scene/3d/physics_body_3d.cpp | 693 |
1 files changed, 399 insertions, 294 deletions
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index c0c3419efe..3496ed1a56 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -43,16 +43,35 @@ #include "editor/plugins/node_3d_editor_plugin.h" #endif -Vector3 PhysicsBody3D::get_linear_velocity() const { - return Vector3(); +void PhysicsBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only", "safe_margin"), &PhysicsBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(0.001)); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "collision", "safe_margin"), &PhysicsBody3D::test_move, DEFVAL(true), DEFVAL(true), DEFVAL(Variant()), DEFVAL(0.001)); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicsBody3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicsBody3D::get_axis_lock); + + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody3D::get_collision_exceptions); + ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody3D::add_collision_exception_with); + ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody3D::remove_collision_exception_with); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); } -Vector3 PhysicsBody3D::get_angular_velocity() const { - return Vector3(); +PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : + CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); } -real_t PhysicsBody3D::get_inverse_mass() const { - return 0; +PhysicsBody3D::~PhysicsBody3D() { + if (motion_cache.is_valid()) { + motion_cache->owner = nullptr; + } } TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { @@ -83,11 +102,75 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) { PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid()); } -void PhysicsBody3D::_bind_methods() {} +Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only, real_t p_margin) { + PhysicsServer3D::MotionResult result; + if (move_and_collide(p_motion, p_infinite_inertia, result, p_margin, p_exclude_raycast_shapes, p_test_only)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; + } + + motion_cache->result = result; -PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : - CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); + return motion_cache; + } + + return Ref<KinematicCollision3D>(); +} + +bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) { + Transform3D gt = get_global_transform(); + bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes); + + for (int i = 0; i < 3; i++) { + if (locked_axis & (1 << i)) { + r_result.motion[i] = 0; + } + } + + if (!p_test_only) { + gt.origin += r_result.motion; + set_global_transform(gt); + } + + return colliding; +} + +bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, const Ref<KinematicCollision3D> &r_collision, real_t p_margin) { + ERR_FAIL_COND_V(!is_inside_tree(), false); + + PhysicsServer3D::MotionResult *r = nullptr; + 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); + } + + return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes); +} + +void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + if (p_lock) { + locked_axis |= p_axis; + } else { + locked_axis &= (~p_axis); + } + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicsBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return (locked_axis & p_axis); +} + +Vector3 PhysicsBody3D::get_linear_velocity() const { + return Vector3(); +} + +Vector3 PhysicsBody3D::get_angular_velocity() const { + return Vector3(); +} + +real_t PhysicsBody3D::get_inverse_mass() const { + return 0; } void StaticBody3D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { @@ -109,14 +192,44 @@ Ref<PhysicsMaterial> StaticBody3D::get_physics_material_override() const { return physics_material_override; } +void StaticBody3D::set_kinematic_motion_enabled(bool p_enabled) { + if (p_enabled == kinematic_motion) { + return; + } + + kinematic_motion = p_enabled; + + if (kinematic_motion) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC); + } else { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); + } + + _update_kinematic_motion(); +} + +bool StaticBody3D::is_kinematic_motion_enabled() const { + return kinematic_motion; +} + void StaticBody3D::set_constant_linear_velocity(const Vector3 &p_vel) { constant_linear_velocity = p_vel; - PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + } } void StaticBody3D::set_constant_angular_velocity(const Vector3 &p_vel) { constant_angular_velocity = p_vel; - PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + } } Vector3 StaticBody3D::get_constant_linear_velocity() const { @@ -127,30 +240,81 @@ Vector3 StaticBody3D::get_constant_angular_velocity() const { return constant_angular_velocity; } +Vector3 StaticBody3D::get_linear_velocity() const { + return linear_velocity; +} + +Vector3 StaticBody3D::get_angular_velocity() const { + return angular_velocity; +} + +void StaticBody3D::_notification(int p_what) { + if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + ERR_FAIL_COND(!kinematic_motion); + + real_t delta_time = get_physics_process_delta_time(); + + Transform3D new_transform = get_global_transform(); + new_transform.origin += constant_linear_velocity * delta_time; + + real_t ang_vel = constant_angular_velocity.length(); + if (!Math::is_zero_approx(ang_vel)) { + Vector3 ang_vel_axis = constant_angular_velocity / ang_vel; + Basis rot(ang_vel_axis, ang_vel * delta_time); + new_transform.basis = rot * new_transform.basis; + new_transform.orthonormalize(); + } + + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_TRANSFORM, new_transform); + + // Propagate transform change to node. + set_ignore_transform_notification(true); + set_global_transform(new_transform); + set_ignore_transform_notification(false); + _on_transform_changed(); + } +} + void StaticBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody3D::set_constant_linear_velocity); ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody3D::set_constant_angular_velocity); ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody3D::get_constant_linear_velocity); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody3D::get_constant_angular_velocity); + ClassDB::bind_method(D_METHOD("set_kinematic_motion_enabled", "enabled"), &StaticBody3D::set_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("is_kinematic_motion_enabled"), &StaticBody3D::is_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody3D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody3D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody3D::get_collision_exceptions); - ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody3D::add_collision_exception_with); - ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody3D::remove_collision_exception_with); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "kinematic_motion"), "set_kinematic_motion_enabled", "is_kinematic_motion_enabled"); +} + +void StaticBody3D::_direct_state_changed(Object *p_state) { +#ifdef DEBUG_ENABLED + PhysicsDirectBodyState3D *state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); + ERR_FAIL_NULL_MSG(state, "Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument"); +#else + PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; //trust it +#endif + + linear_velocity = state->get_linear_velocity(); + angular_velocity = state->get_angular_velocity(); } StaticBody3D::StaticBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { } -StaticBody3D::~StaticBody3D() {} - void StaticBody3D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_BOUNCE, 0); @@ -161,6 +325,27 @@ void StaticBody3D::_reload_physics_characteristics() { } } +void StaticBody3D::_update_kinematic_motion() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + if (kinematic_motion) { + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &StaticBody3D::_direct_state_changed)); + + if (!constant_angular_velocity.is_equal_approx(Vector3()) || !constant_linear_velocity.is_equal_approx(Vector3())) { + set_physics_process_internal(true); + return; + } + } else { + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), Callable()); + } + + set_physics_process_internal(false); +} + void RigidBody3D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); @@ -398,15 +583,15 @@ void RigidBody3D::_notification(int p_what) { void RigidBody3D::set_mode(Mode p_mode) { mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); + case MODE_DYNAMIC: { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC); } break; case MODE_STATIC: { PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); } break; - case MODE_CHARACTER: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_CHARACTER); + case MODE_DYNAMIC_LOCKED: { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED); } break; case MODE_KINEMATIC: { @@ -627,14 +812,6 @@ bool RigidBody3D::is_contact_monitor_enabled() const { return contact_monitor != nullptr; } -void RigidBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); -} - -bool RigidBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); -} - Array RigidBody3D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); @@ -658,8 +835,8 @@ TypedArray<String> RigidBody3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); - if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { - warnings.push_back(TTR("Size changes to RigidBody3D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + if ((get_mode() == MODE_DYNAMIC || get_mode() == MODE_DYNAMIC_LOCKED) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { + warnings.push_back(TTR("Size changes to RigidBody3D (in dynamic modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; @@ -720,14 +897,11 @@ void RigidBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody3D::get_axis_lock); - ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody3D::get_colliding_bodies); BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState3D"))); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -737,13 +911,6 @@ void RigidBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); 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_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::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::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); @@ -757,14 +924,14 @@ void RigidBody3D::_bind_methods() { ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); - BIND_ENUM_CONSTANT(MODE_RIGID); + BIND_ENUM_CONSTANT(MODE_DYNAMIC); BIND_ENUM_CONSTANT(MODE_STATIC); - BIND_ENUM_CONSTANT(MODE_CHARACTER); + BIND_ENUM_CONSTANT(MODE_DYNAMIC_LOCKED); BIND_ENUM_CONSTANT(MODE_KINEMATIC); } RigidBody3D::RigidBody3D() : - PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { + PhysicsBody3D(PhysicsServer3D::BODY_MODE_DYNAMIC) { PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &RigidBody3D::_direct_state_changed)); } @@ -784,147 +951,92 @@ void RigidBody3D::_reload_physics_characteristics() { } } -////////////////////////////////////////////////////// -////////////////////////// - -Ref<KinematicCollision3D> KinematicBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { - Collision col; - if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { - if (motion_cache.is_null()) { - motion_cache.instance(); - motion_cache->owner = this; - } - - motion_cache->collision = col; - - return motion_cache; - } - - return Ref<KinematicCollision3D>(); -} - -Vector3 KinematicBody3D::get_linear_velocity() const { - return linear_velocity; -} - -Vector3 KinematicBody3D::get_angular_velocity() const { - return angular_velocity; -} - -bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { - Transform3D gt = get_global_transform(); - PhysicsServer3D::MotionResult result; - bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes); - - if (colliding) { - r_collision.collider_metadata = result.collider_metadata; - r_collision.collider_shape = result.collider_shape; - r_collision.collider_vel = result.collider_velocity; - r_collision.collision = result.collision_point; - r_collision.normal = result.collision_normal; - r_collision.collider = result.collider_id; - r_collision.collider_rid = result.collider; - r_collision.travel = result.motion; - r_collision.remainder = result.remainder; - r_collision.local_shape = result.collision_local_shape; - } - - for (int i = 0; i < 3; i++) { - if (locked_axis & (1 << i)) { - result.motion[i] = 0; - } - } - - if (!p_test_only) { - gt.origin += result.motion; - set_global_transform(gt); - } - - return colliding; -} +/////////////////////////////////////// //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector3 body_velocity = p_linear_velocity; - Vector3 body_velocity_normal = body_velocity.normalized(); - Vector3 up_direction = p_up_direction.normalized(); +void CharacterBody3D::move_and_slide() { + Vector3 body_velocity_normal = linear_velocity.normalized(); + + bool was_on_floor = on_floor; for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { - body_velocity[i] = 0; + linear_velocity[i] = 0.0; } } // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - Vector3 motion = (floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); + Vector3 motion = (floor_velocity + linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_normal = Vector3(); floor_velocity = Vector3(); - while (p_max_slides) { - Collision collision; + int slide_count = max_slides; + while (slide_count) { + PhysicsServer3D::MotionResult result; bool found_collision = false; for (int i = 0; i < 2; ++i) { bool collided; if (i == 0) { //collide - collided = move_and_collide(motion, p_infinite_inertia, collision); + collided = move_and_collide(motion, infinite_inertia, result, margin); if (!collided) { motion = Vector3(); //clear because no collision happened and motion completed } } else { //separate raycasts (if any) - collided = separate_raycast_shapes(p_infinite_inertia, collision); + collided = separate_raycast_shapes(result); if (collided) { - collision.remainder = motion; //keep - collision.travel = Vector3(); + result.remainder = motion; //keep + result.motion = Vector3(); } } if (collided) { found_collision = true; - colliders.push_back(collision); - motion = collision.remainder; + motion_results.push_back(result); + motion = result.remainder; if (up_direction == Vector3()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; - floor_normal = collision.normal; - on_floor_body = collision.collider_rid; - floor_velocity = collision.collider_vel; + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; - if (p_stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) { + if (stop_on_slope) { + if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) { Transform3D gt = get_global_transform(); - gt.origin -= collision.travel.slide(up_direction); + gt.origin -= result.motion.slide(up_direction); set_global_transform(gt); - return Vector3(); + linear_velocity = Vector3(); + return; } } - } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; } } - motion = motion.slide(collision.normal); - body_velocity = body_velocity.slide(collision.normal); + motion = motion.slide(result.collision_normal); + linear_velocity = linear_velocity.slide(result.collision_normal); for (int j = 0; j < 3; j++) { if (locked_axis & (1 << j)) { - body_velocity[j] = 0; + linear_velocity[j] = 0.0; } } } @@ -934,83 +1046,47 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const break; } - --p_max_slides; + --slide_count; } - return body_velocity; -} - -Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector3 up_direction = p_up_direction.normalized(); - bool was_on_floor = on_floor; - - Vector3 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); - if (!was_on_floor || p_snap == Vector3()) { - return ret; + if (!was_on_floor || snap == Vector3()) { + return; } - Collision col; + // Apply snap. Transform3D gt = get_global_transform(); - - if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { + PhysicsServer3D::MotionResult result; + if (move_and_collide(snap, infinite_inertia, result, margin, false, true)) { bool apply = true; if (up_direction != Vector3()) { - if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { on_floor = true; - floor_normal = col.normal; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; - if (p_stop_on_slope) { + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; + if (stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = col.travel.project(up_direction); + result.motion = result.motion.project(up_direction); } } else { apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. } } if (apply) { - gt.origin += col.travel; + gt.origin += result.motion; set_global_transform(gt); } } - - return ret; -} - -bool KinematicBody3D::is_on_floor() const { - return on_floor; } -bool KinematicBody3D::is_on_wall() const { - return on_wall; -} - -bool KinematicBody3D::is_on_ceiling() const { - return on_ceiling; -} - -Vector3 KinematicBody3D::get_floor_normal() const { - return floor_normal; -} - -Vector3 KinematicBody3D::get_floor_velocity() const { - return floor_velocity; -} - -bool KinematicBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia) { - ERR_FAIL_COND_V(!is_inside_tree(), false); - - return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia); -} - -bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { +bool CharacterBody3D::separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result) { PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays Transform3D gt = get_global_transform(); Vector3 recover; - int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); + int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; real_t deepest_depth; for (int i = 0; i < hits; i++) { @@ -1024,15 +1100,15 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision set_global_transform(gt); if (deepest != -1) { - r_collision.collider = sep_res[deepest].collider_id; - r_collision.collider_metadata = sep_res[deepest].collider_metadata; - r_collision.collider_shape = sep_res[deepest].collider_shape; - r_collision.collider_vel = sep_res[deepest].collider_velocity; - r_collision.collision = sep_res[deepest].collision_point; - r_collision.normal = sep_res[deepest].collision_normal; - r_collision.local_shape = sep_res[deepest].collision_local_shape; - r_collision.travel = recover; - r_collision.remainder = Vector3(); + r_result.collider_id = sep_res[deepest].collider_id; + r_result.collider_metadata = sep_res[deepest].collider_metadata; + r_result.collider_shape = sep_res[deepest].collider_shape; + r_result.collider_velocity = sep_res[deepest].collider_velocity; + r_result.collision_point = sep_res[deepest].collision_point; + r_result.collision_normal = sep_res[deepest].collision_normal; + r_result.collision_local_shape = sep_res[deepest].collision_local_shape; + r_result.motion = recover; + r_result.remainder = Vector3(); return true; } else { @@ -1040,39 +1116,53 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision } } -void KinematicBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - if (p_lock) { - locked_axis |= p_axis; - } else { - locked_axis &= (~p_axis); - } - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +void CharacterBody3D::set_safe_margin(real_t p_margin) { + margin = p_margin; } -bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +real_t CharacterBody3D::get_safe_margin() const { + return margin; } -void KinematicBody3D::set_safe_margin(real_t p_margin) { - margin = p_margin; - PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); +Vector3 CharacterBody3D::get_linear_velocity() const { + return linear_velocity; } -real_t KinematicBody3D::get_safe_margin() const { - return margin; +void CharacterBody3D::set_linear_velocity(const Vector3 &p_velocity) { + linear_velocity = p_velocity; +} + +bool CharacterBody3D::is_on_floor() const { + return on_floor; +} + +bool CharacterBody3D::is_on_wall() const { + return on_wall; +} + +bool CharacterBody3D::is_on_ceiling() const { + return on_ceiling; +} + +Vector3 CharacterBody3D::get_floor_normal() const { + return floor_normal; +} + +Vector3 CharacterBody3D::get_floor_velocity() const { + return floor_velocity; } -int KinematicBody3D::get_slide_count() const { - return colliders.size(); +int CharacterBody3D::get_slide_count() const { + return motion_results.size(); } -KinematicBody3D::Collision KinematicBody3D::get_slide_collision(int p_bounce) const { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); - return colliders[p_bounce]; +PhysicsServer3D::MotionResult CharacterBody3D::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), PhysicsServer3D::MotionResult()); + return motion_results[p_bounce]; } -Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision3D>()); +Ref<KinematicCollision3D> CharacterBody3D::_get_slide_collision(int p_bounce) { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), Ref<KinematicCollision3D>()); if (p_bounce >= slide_colliders.size()) { slide_colliders.resize(p_bounce + 1); } @@ -1082,75 +1172,115 @@ Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { slide_colliders.write[p_bounce]->owner = this; } - slide_colliders.write[p_bounce]->collision = colliders[p_bounce]; + slide_colliders.write[p_bounce]->result = motion_results[p_bounce]; return slide_colliders[p_bounce]; } -void KinematicBody3D::_notification(int p_what) { +bool CharacterBody3D::is_stop_on_slope_enabled() const { + return stop_on_slope; +} + +void CharacterBody3D::set_stop_on_slope_enabled(bool p_enabled) { + stop_on_slope = p_enabled; +} + +bool CharacterBody3D::is_infinite_inertia_enabled() const { + return infinite_inertia; +} +void CharacterBody3D::set_infinite_inertia_enabled(bool p_enabled) { + infinite_inertia = p_enabled; +} + +int CharacterBody3D::get_max_slides() const { + return max_slides; +} + +void CharacterBody3D::set_max_slides(int p_max_slides) { + ERR_FAIL_COND(p_max_slides > 0); + max_slides = p_max_slides; +} + +real_t CharacterBody3D::get_floor_max_angle() const { + return floor_max_angle; +} + +void CharacterBody3D::set_floor_max_angle(real_t p_floor_max_angle) { + floor_max_angle = p_floor_max_angle; +} + +const Vector3 &CharacterBody3D::get_snap() const { + return snap; +} + +void CharacterBody3D::set_snap(const Vector3 &p_snap) { + snap = p_snap; +} + +const Vector3 &CharacterBody3D::get_up_direction() const { + return up_direction; +} + +void CharacterBody3D::set_up_direction(const Vector3 &p_up_direction) { + up_direction = p_up_direction.normalized(); +} + +void CharacterBody3D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { // Reset move_and_slide() data. on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_velocity = Vector3(); } } -void KinematicBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true)); +void CharacterBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide); - ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody3D::is_on_floor); - ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody3D::is_on_ceiling); - ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody3D::is_on_wall); - ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody3D::get_floor_normal); - ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody3D::get_floor_velocity); + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody3D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody3D::get_linear_velocity); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &KinematicBody3D::get_axis_lock); + ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody3D::set_safe_margin); + ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin); + ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody3D::is_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody3D::set_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody3D::is_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody3D::set_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody3D::get_max_slides); + ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody3D::set_max_slides); + ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody3D::get_floor_max_angle); + ClassDB::bind_method(D_METHOD("set_floor_max_angle", "floor_max_angle"), &CharacterBody3D::set_floor_max_angle); + ClassDB::bind_method(D_METHOD("get_snap"), &CharacterBody3D::get_snap); + ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CharacterBody3D::set_snap); + ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody3D::get_up_direction); + ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody3D::set_up_direction); - ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody3D::set_safe_margin); - ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody3D::get_safe_margin); + ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody3D::is_on_floor); + ClassDB::bind_method(D_METHOD("is_on_ceiling"), &CharacterBody3D::is_on_ceiling); + ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody3D::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody3D::get_floor_normal); + ClassDB::bind_method(D_METHOD("get_floor_velocity"), &CharacterBody3D::get_floor_velocity); - ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody3D::get_slide_count); - ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody3D::_get_slide_collision); - - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ClassDB::bind_method(D_METHOD("get_slide_count"), &CharacterBody3D::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody3D::_get_slide_collision); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides"), "set_max_slides", "get_max_slides"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle"), "set_floor_max_angle", "get_floor_max_angle"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap"), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } -void KinematicBody3D::_direct_state_changed(Object *p_state) { -#ifdef DEBUG_ENABLED - PhysicsDirectBodyState3D *state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); - ERR_FAIL_NULL_MSG(state, "Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument"); -#else - PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; //trust it -#endif - - linear_velocity = state->get_linear_velocity(); - angular_velocity = state->get_angular_velocity(); -} - -KinematicBody3D::KinematicBody3D() : +CharacterBody3D::CharacterBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { - set_safe_margin(0.001); - PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &KinematicBody3D::_direct_state_changed)); } -KinematicBody3D::~KinematicBody3D() { - if (motion_cache.is_valid()) { - motion_cache->owner = nullptr; - } - +CharacterBody3D::~CharacterBody3D() { for (int i = 0; i < slide_colliders.size(); i++) { if (slide_colliders[i].is_valid()) { slide_colliders.write[i]->owner = nullptr; @@ -1161,39 +1291,39 @@ KinematicBody3D::~KinematicBody3D() { /////////////////////////////////////// Vector3 KinematicCollision3D::get_position() const { - return collision.collision; + return result.collision_point; } Vector3 KinematicCollision3D::get_normal() const { - return collision.normal; + return result.collision_normal; } Vector3 KinematicCollision3D::get_travel() const { - return collision.travel; + return result.motion; } Vector3 KinematicCollision3D::get_remainder() const { - return collision.remainder; + return result.remainder; } Object *KinematicCollision3D::get_local_shape() const { if (!owner) { return nullptr; } - uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + uint32_t ownerid = owner->shape_find_owner(result.collision_local_shape); return owner->shape_owner_get_owner(ownerid); } Object *KinematicCollision3D::get_collider() const { - if (collision.collider.is_valid()) { - return ObjectDB::get_instance(collision.collider); + if (result.collider_id.is_valid()) { + return ObjectDB::get_instance(result.collider_id); } return nullptr; } ObjectID KinematicCollision3D::get_collider_id() const { - return collision.collider; + return result.collider_id; } Object *KinematicCollision3D::get_collider_shape() const { @@ -1201,7 +1331,7 @@ Object *KinematicCollision3D::get_collider_shape() const { if (collider) { CollisionObject3D *obj2d = Object::cast_to<CollisionObject3D>(collider); if (obj2d) { - uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + uint32_t ownerid = obj2d->shape_find_owner(result.collider_shape); return obj2d->shape_owner_get_owner(ownerid); } } @@ -1210,11 +1340,11 @@ Object *KinematicCollision3D::get_collider_shape() const { } int KinematicCollision3D::get_collider_shape_index() const { - return collision.collider_shape; + return result.collider_shape; } Vector3 KinematicCollision3D::get_collider_velocity() const { - return collision.collider_vel; + return result.collider_velocity; } Variant KinematicCollision3D::get_collider_metadata() const { @@ -1247,12 +1377,6 @@ void KinematicCollision3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); } -KinematicCollision3D::KinematicCollision3D() { - collision.collider_shape = 0; - collision.local_shape = 0; - owner = nullptr; -} - /////////////////////////////////////// bool PhysicalBone3D::JointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -2048,9 +2172,6 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); - ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset"), "set_joint_offset", "get_joint_offset"); @@ -2067,14 +2188,6 @@ void PhysicalBone3D::_bind_methods() { 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::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); - BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); BIND_ENUM_CONSTANT(JOINT_TYPE_CONE); @@ -2416,14 +2529,6 @@ bool PhysicalBone3D::is_able_to_sleep() const { return can_sleep; } -void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); -} - -bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); -} - PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { joint = PhysicsServer3D::get_singleton()->joint_create(); @@ -2483,7 +2588,7 @@ void PhysicalBone3D::_start_physics_simulation() { return; } reset_to_rest_position(); - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &PhysicalBone3D::_direct_state_changed)); |