diff --git a/doc/classes/AimModifier3D.xml b/doc/classes/AimModifier3D.xml index c6788bada93..b0fb7d5222a 100644 --- a/doc/classes/AimModifier3D.xml +++ b/doc/classes/AimModifier3D.xml @@ -24,6 +24,13 @@ Returns the axis of the first rotation. It is enabled only if [method is_using_euler] is [code]true[/code]. + + + + + Returns [code]true[/code] if the relative option is enabled in the setting at [param index]. + + @@ -54,6 +61,16 @@ Sets the axis of the first rotation. It is enabled only if [method is_using_euler] is [code]true[/code]. + + + + + + Sets relative option in the setting at [param index] to [param enabled]. + If sets [param enabled] to [code]true[/code], the rotation is applied relative to the pose. + If sets [param enabled] to [code]false[/code], the rotation is applied relative to the rest. It means to replace the current pose with the [AimModifier3D]'s result. + + diff --git a/doc/classes/LookAtModifier3D.xml b/doc/classes/LookAtModifier3D.xml index 22b24097eed..dbdb92709c1 100644 --- a/doc/classes/LookAtModifier3D.xml +++ b/doc/classes/LookAtModifier3D.xml @@ -91,6 +91,9 @@ The axis of the first rotation. This [SkeletonModifier3D] works by compositing the rotation by Euler angles to prevent to rotate the [member forward_axis]. + + The relative option. If [code]true[/code], the rotation is applied relative to the pose. If [code]false[/code], the rotation is applied relative to the rest. It means to replace the current pose with the [LookAtModifier3D]'s result. + The threshold to start damping for [member secondary_limit_angle]. diff --git a/scene/3d/aim_modifier_3d.cpp b/scene/3d/aim_modifier_3d.cpp index 30f9694eb3b..931a0683caf 100644 --- a/scene/3d/aim_modifier_3d.cpp +++ b/scene/3d/aim_modifier_3d.cpp @@ -47,6 +47,8 @@ bool AimModifier3D::_set(const StringName &p_path, const Variant &p_value) { set_primary_rotation_axis(which, static_cast((int)p_value)); } else if (what == "use_secondary_rotation") { set_use_secondary_rotation(which, p_value); + } else if (what == "relative") { + set_relative(which, p_value); } else { return false; } @@ -70,6 +72,8 @@ bool AimModifier3D::_get(const StringName &p_path, Variant &r_ret) const { r_ret = (int)get_primary_rotation_axis(which); } else if (what == "use_secondary_rotation") { r_ret = is_using_secondary_rotation(which); + } else if (what == "relative") { + r_ret = is_relative(which); } else { return false; } @@ -88,6 +92,7 @@ void AimModifier3D::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::BOOL, path + "use_euler")); p_list->push_back(PropertyInfo(Variant::INT, path + "primary_rotation_axis", PROPERTY_HINT_ENUM, "X,Y,Z", rotation_usage)); p_list->push_back(PropertyInfo(Variant::BOOL, path + "use_secondary_rotation", PROPERTY_HINT_NONE, "", rotation_usage)); + p_list->push_back(PropertyInfo(Variant::BOOL, path + "relative")); } } @@ -158,6 +163,18 @@ bool AimModifier3D::is_using_secondary_rotation(int p_index) const { return setting->use_secondary_rotation; } +void AimModifier3D::set_relative(int p_index, bool p_enabled) { + ERR_FAIL_INDEX(p_index, (int)settings.size()); + AimModifier3DSetting *setting = static_cast(settings[p_index]); + setting->relative = p_enabled; +} + +bool AimModifier3D::is_relative(int p_index) const { + ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0); + AimModifier3DSetting *setting = static_cast(settings[p_index]); + return setting->relative; +} + void AimModifier3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_forward_axis", "index", "axis"), &AimModifier3D::set_forward_axis); ClassDB::bind_method(D_METHOD("get_forward_axis", "index"), &AimModifier3D::get_forward_axis); @@ -167,6 +184,8 @@ void AimModifier3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_primary_rotation_axis", "index"), &AimModifier3D::get_primary_rotation_axis); ClassDB::bind_method(D_METHOD("set_use_secondary_rotation", "index", "enabled"), &AimModifier3D::set_use_secondary_rotation); ClassDB::bind_method(D_METHOD("is_using_secondary_rotation", "index"), &AimModifier3D::is_using_secondary_rotation); + ClassDB::bind_method(D_METHOD("set_relative", "index", "enabled"), &AimModifier3D::set_relative); + ClassDB::bind_method(D_METHOD("is_relative", "index"), &AimModifier3D::is_relative); ADD_ARRAY_COUNT("Settings", "setting_count", "set_setting_count", "get_setting_count", "settings/"); } @@ -193,7 +212,7 @@ void AimModifier3D::_process_aim(int p_index, Skeleton3D *p_skeleton, int p_appl AimModifier3DSetting *setting = static_cast(settings[p_index]); // Prepare forward_vector and rest. - Transform3D src_bone_rest = p_skeleton->get_bone_rest(p_apply_bone); + Transform3D src_bone_rest = setting->relative ? p_skeleton->get_bone_pose(p_apply_bone) : p_skeleton->get_bone_rest(p_apply_bone); Transform3D bone_rest_space; int parent_bone = p_skeleton->get_bone_parent(p_apply_bone); if (parent_bone < 0) { diff --git a/scene/3d/aim_modifier_3d.h b/scene/3d/aim_modifier_3d.h index 58019a4b8a9..32f9705d6a2 100644 --- a/scene/3d/aim_modifier_3d.h +++ b/scene/3d/aim_modifier_3d.h @@ -41,6 +41,7 @@ public: bool use_euler = false; Vector3::Axis primary_rotation_axis = Vector3::AXIS_X; bool use_secondary_rotation = true; + bool relative = true; }; protected: @@ -65,6 +66,8 @@ public: Vector3::Axis get_primary_rotation_axis(int p_index) const; void set_use_secondary_rotation(int p_index, bool p_enabled); bool is_using_secondary_rotation(int p_index) const; + void set_relative(int p_index, bool p_enabled); + bool is_relative(int p_index) const; ~AimModifier3D(); }; diff --git a/scene/3d/look_at_modifier_3d.cpp b/scene/3d/look_at_modifier_3d.cpp index 3dbad6aa896..2db0b150b67 100644 --- a/scene/3d/look_at_modifier_3d.cpp +++ b/scene/3d/look_at_modifier_3d.cpp @@ -143,6 +143,14 @@ bool LookAtModifier3D::is_using_secondary_rotation() const { return use_secondary_rotation; } +void LookAtModifier3D::set_relative(bool p_enabled) { + relative = p_enabled; +} + +bool LookAtModifier3D::is_relative() const { + return relative; +} + void LookAtModifier3D::set_target_node(const NodePath &p_target_node) { if (target_node != p_target_node) { init_transition(); @@ -394,9 +402,11 @@ void LookAtModifier3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_primary_rotation_axis"), &LookAtModifier3D::get_primary_rotation_axis); ClassDB::bind_method(D_METHOD("set_use_secondary_rotation", "enabled"), &LookAtModifier3D::set_use_secondary_rotation); ClassDB::bind_method(D_METHOD("is_using_secondary_rotation"), &LookAtModifier3D::is_using_secondary_rotation); + ClassDB::bind_method(D_METHOD("set_relative", "enabled"), &LookAtModifier3D::set_relative); + ClassDB::bind_method(D_METHOD("is_relative"), &LookAtModifier3D::is_relative); + ClassDB::bind_method(D_METHOD("set_origin_safe_margin", "margin"), &LookAtModifier3D::set_origin_safe_margin); ClassDB::bind_method(D_METHOD("get_origin_safe_margin"), &LookAtModifier3D::get_origin_safe_margin); - ClassDB::bind_method(D_METHOD("set_origin_from", "origin_from"), &LookAtModifier3D::set_origin_from); ClassDB::bind_method(D_METHOD("get_origin_from"), &LookAtModifier3D::get_origin_from); ClassDB::bind_method(D_METHOD("set_origin_bone_name", "bone_name"), &LookAtModifier3D::set_origin_bone_name); @@ -460,6 +470,7 @@ void LookAtModifier3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "forward_axis", PROPERTY_HINT_ENUM, SkeletonModifier3D::get_hint_bone_axis()), "set_forward_axis", "get_forward_axis"); ADD_PROPERTY(PropertyInfo(Variant::INT, "primary_rotation_axis", PROPERTY_HINT_ENUM, "X,Y,Z"), "set_primary_rotation_axis", "get_primary_rotation_axis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_secondary_rotation"), "set_use_secondary_rotation", "is_using_secondary_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "relative"), "set_relative", "is_relative"); ADD_GROUP("Origin Settings", "origin_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "origin_from", PROPERTY_HINT_ENUM, "Self,SpecificBone,ExternalNode"), "set_origin_from", "get_origin_from"); @@ -506,14 +517,15 @@ void LookAtModifier3D::_process_modification(double p_delta) { } // Calculate bone rest space in the world. + Transform3D bone_rest = relative ? skeleton->get_bone_pose(bone) : skeleton->get_bone_rest(bone); Transform3D bone_rest_space; int parent_bone = skeleton->get_bone_parent(bone); if (parent_bone < 0) { bone_rest_space = skeleton->get_global_transform_interpolated(); - bone_rest_space.translate_local(skeleton->get_bone_rest(bone).origin); + bone_rest_space.translate_local(bone_rest.origin); } else { bone_rest_space = skeleton->get_global_transform_interpolated() * skeleton->get_bone_global_pose(parent_bone); - bone_rest_space.translate_local(skeleton->get_bone_rest(bone).origin); + bone_rest_space.translate_local(bone_rest.origin); } // Calculate forward_vector and destination. @@ -543,7 +555,7 @@ void LookAtModifier3D::_process_modification(double p_delta) { destination = skeleton->get_bone_pose_rotation(bone); forward_vector = Vector3(0, 0, 0); // The zero-vector to be used for checking in the line immediately below to avoid animation glitch. } else { - destination = look_at_with_axes(skeleton->get_bone_rest(bone)).basis.get_rotation_quaternion(); + destination = look_at_with_axes(bone_rest).basis.get_rotation_quaternion(); } } diff --git a/scene/3d/look_at_modifier_3d.h b/scene/3d/look_at_modifier_3d.h index f75bad47fa8..fea1e99b4ad 100644 --- a/scene/3d/look_at_modifier_3d.h +++ b/scene/3d/look_at_modifier_3d.h @@ -53,6 +53,7 @@ private: Vector3::Axis primary_rotation_axis = Vector3::AXIS_Y; Vector3::Axis secondary_rotation_axis = Vector3::AXIS_X; bool use_secondary_rotation = true; + bool relative = true; OriginFrom origin_from = ORIGIN_FROM_SELF; String origin_bone_name; @@ -123,6 +124,8 @@ public: Vector3::Axis get_primary_rotation_axis() const; void set_use_secondary_rotation(bool p_enabled); bool is_using_secondary_rotation() const; + void set_relative(bool p_enabled); + bool is_relative() const; void set_origin_from(OriginFrom p_origin_from); OriginFrom get_origin_from() const;