diff options
Diffstat (limited to 'scene/3d/skeleton_ik_3d.cpp')
-rw-r--r-- | scene/3d/skeleton_ik_3d.cpp | 116 |
1 files changed, 42 insertions, 74 deletions
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 286268b4a2..78a21ba9e1 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -30,8 +30,6 @@ #include "skeleton_ik_3d.h" -#ifndef _3D_DISABLED - FabrikInverseKinematic::ChainItem *FabrikInverseKinematic::ChainItem::find_child(const BoneId p_bone_id) { for (int i = children.size() - 1; 0 <= i; --i) { if (p_bone_id == children[i].bone) { @@ -236,46 +234,21 @@ void FabrikInverseKinematic::set_goal(Task *p_task, const Transform3D &p_goal) { p_task->goal_global_transform = p_goal; } -void FabrikInverseKinematic::make_goal(Task *p_task, const Transform3D &p_inverse_transf, real_t blending_delta) { - if (blending_delta >= 0.99f) { - // Update the end_effector (local transform) without blending - p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform; - } else { - // End effector in local transform - const Transform3D end_effector_pose(p_task->skeleton->get_bone_global_pose_no_override(p_task->end_effectors[0].tip_bone)); - - // Update the end_effector (local transform) by blending with current pose - p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta); - } +void FabrikInverseKinematic::make_goal(Task *p_task, const Transform3D &p_inverse_transf) { + // Update the end_effector (local transform) by blending with current pose + p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform; } -void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) { - if (blending_delta <= 0.01f) { - // Before skipping, make sure we undo the global pose overrides - ChainItem *ci(&p_task->chain.chain_root); - while (ci) { - p_task->skeleton->set_bone_global_pose_override(ci->bone, ci->initial_transform, 0.0, false); - - if (!ci->children.is_empty()) { - ci = &ci->children.write[0]; - } else { - ci = nullptr; - } - } - - return; // Skip solving - } - +void FabrikInverseKinematic::solve(Task *p_task, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) { // Update the initial root transform so its synced with any animation changes _update_chain(p_task->skeleton, &p_task->chain.chain_root); - p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform3D(), 0.0, false); Vector3 origin_pos = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone).origin; - make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta); + make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse()); if (p_use_magnet && p_task->chain.middle_chain_item) { - p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); + p_task->chain.magnet_position = p_magnet_position; solve_simple(p_task, true, origin_pos); } solve_simple(p_task, false, origin_pos); @@ -303,8 +276,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // IK should not affect scale, so undo any scaling new_bone_pose.basis.orthonormalize(); new_bone_pose.basis.scale(p_task->skeleton->get_bone_global_pose(ci->bone).basis.get_scale()); - - p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true); + p_task->skeleton->set_bone_global_pose(ci->bone, Transform3D(new_bone_pose.basis, p_task->skeleton->get_bone_global_pose(ci->bone).origin)); if (!ci->children.is_empty()) { ci = &ci->children.write[0]; @@ -319,7 +291,7 @@ void FabrikInverseKinematic::_update_chain(const Skeleton3D *p_sk, ChainItem *p_ return; } - p_chain_item->initial_transform = p_sk->get_bone_global_pose_no_override(p_chain_item->bone); + p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone); p_chain_item->current_pos = p_chain_item->initial_transform.origin; ChainItem *items = p_chain_item->children.ptrw(); @@ -329,8 +301,10 @@ void FabrikInverseKinematic::_update_chain(const Skeleton3D *p_sk, ChainItem *p_ } void SkeletonIK3D::_validate_property(PropertyInfo &p_property) const { + SkeletonModifier3D::_validate_property(p_property); + if (p_property.name == "root_bone" || p_property.name == "tip_bone") { - Skeleton3D *skeleton = get_parent_skeleton(); + Skeleton3D *skeleton = get_skeleton(); if (skeleton) { String names("--,"); for (int i = 0; i < skeleton->get_bone_count(); i++) { @@ -356,9 +330,6 @@ void SkeletonIK3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tip_bone", "tip_bone"), &SkeletonIK3D::set_tip_bone); ClassDB::bind_method(D_METHOD("get_tip_bone"), &SkeletonIK3D::get_tip_bone); - ClassDB::bind_method(D_METHOD("set_interpolation", "interpolation"), &SkeletonIK3D::set_interpolation); - ClassDB::bind_method(D_METHOD("get_interpolation"), &SkeletonIK3D::get_interpolation); - ClassDB::bind_method(D_METHOD("set_target_transform", "target"), &SkeletonIK3D::set_target_transform); ClassDB::bind_method(D_METHOD("get_target_transform"), &SkeletonIK3D::get_target_transform); @@ -388,7 +359,6 @@ void SkeletonIK3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone"), "set_root_bone", "get_root_bone"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "tip_bone"), "set_tip_bone", "get_tip_bone"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "target", PROPERTY_HINT_NONE, "suffix:m"), "set_target_transform", "get_target_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet"); @@ -396,23 +366,29 @@ void SkeletonIK3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node"), "set_target_node", "get_target_node"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_min_distance", "get_min_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_iterations"), "set_max_iterations", "get_max_iterations"); + +#ifndef DISABLE_DEPRECATED + ClassDB::bind_method(D_METHOD("set_interpolation", "interpolation"), &SkeletonIK3D::_set_interpolation); + ClassDB::bind_method(D_METHOD("get_interpolation"), &SkeletonIK3D::_get_interpolation); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001", PROPERTY_USAGE_NONE), "set_interpolation", "get_interpolation"); +#endif +} + +void SkeletonIK3D::_process_modification() { + if (!internal_active) { + return; + } + if (target_node_override_ref) { + reload_goal(); + } + _solve_chain(); } void SkeletonIK3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - skeleton_ref = Object::cast_to<Skeleton3D>(get_parent()); - set_process_priority(1); reload_chain(); } break; - - case NOTIFICATION_INTERNAL_PROCESS: { - if (target_node_override_ref) { - reload_goal(); - } - _solve_chain(); - } break; - case NOTIFICATION_EXIT_TREE: { stop(); } break; @@ -445,13 +421,15 @@ StringName SkeletonIK3D::get_tip_bone() const { return tip_bone; } -void SkeletonIK3D::set_interpolation(real_t p_interpolation) { - interpolation = p_interpolation; +#ifndef DISABLE_DEPRECATED +void SkeletonIK3D::_set_interpolation(real_t p_interpolation) { + set_influence(p_interpolation); } -real_t SkeletonIK3D::get_interpolation() const { - return interpolation; +real_t SkeletonIK3D::_get_interpolation() const { + return get_influence(); } +#endif void SkeletonIK3D::set_target_transform(const Transform3D &p_target) { target = p_target; @@ -505,33 +483,25 @@ void SkeletonIK3D::set_max_iterations(int p_iterations) { } Skeleton3D *SkeletonIK3D::get_parent_skeleton() const { - return cast_to<Skeleton3D>(skeleton_ref.get_validated_object()); + return get_skeleton(); } bool SkeletonIK3D::is_running() { - return is_processing_internal(); + return internal_active; } void SkeletonIK3D::start(bool p_one_time) { if (p_one_time) { - set_process_internal(false); - - if (target_node_override_ref) { - reload_goal(); - } - - _solve_chain(); + internal_active = true; + SkeletonModifier3D::process_modification(); + internal_active = false; } else { - set_process_internal(true); + internal_active = true; } } void SkeletonIK3D::stop() { - set_process_internal(false); - Skeleton3D *skeleton = get_parent_skeleton(); - if (skeleton) { - skeleton->clear_bones_global_pose_override(); - } + internal_active = false; } Transform3D SkeletonIK3D::_get_target_transform() { @@ -551,7 +521,7 @@ void SkeletonIK3D::reload_chain() { FabrikInverseKinematic::free_task(task); task = nullptr; - Skeleton3D *skeleton = get_parent_skeleton(); + Skeleton3D *skeleton = get_skeleton(); if (!skeleton) { return; } @@ -575,7 +545,5 @@ void SkeletonIK3D::_solve_chain() { if (!task) { return; } - FabrikInverseKinematic::solve(task, interpolation, override_tip_basis, use_magnet, magnet_position); + FabrikInverseKinematic::solve(task, override_tip_basis, use_magnet, magnet_position); } - -#endif // _3D_DISABLED |