Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a base class SkeletonModifier3D as refactoring for nodes that may modify Skeleton3D #87888

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions doc/classes/AnimationMixer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<param index="0" name="name" type="StringName" />
<description>
Returns the first [AnimationLibrary] with key [param name] or [code]null[/code] if not found.
To get the [AnimationPlayer]'s global animation library, use [code]get_animation_library("")[/code].
To get the [AnimationMixer]'s global animation library, use [code]get_animation_library("")[/code].
</description>
</method>
<method name="get_animation_library_list" qualifiers="const">
Expand Down Expand Up @@ -239,14 +239,14 @@
<return type="bool" />
<param index="0" name="name" type="StringName" />
<description>
Returns [code]true[/code] if the [AnimationPlayer] stores an [Animation] with key [param name].
Returns [code]true[/code] if the [AnimationMixer] stores an [Animation] with key [param name].
</description>
</method>
<method name="has_animation_library" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="StringName" />
<description>
Returns [code]true[/code] if the [AnimationPlayer] stores an [AnimationLibrary] with key [param name].
Returns [code]true[/code] if the [AnimationMixer] stores an [AnimationLibrary] with key [param name].
</description>
</method>
<method name="remove_animation_library">
Expand Down Expand Up @@ -333,9 +333,14 @@
Notifies when the caches have been cleared, either automatically, or manually via [method clear_caches].
</description>
</signal>
<signal name="mixer_applied">
<description>
Notifies when the blending result related have been applied to the target objects.
</description>
</signal>
<signal name="mixer_updated">
<description>
Editor only. Notifies when the property have been updated to update dummy [AnimationPlayer] in animation player editor.
Notifies when the property related process have been updated.
</description>
</signal>
</signals>
Expand Down
1 change: 1 addition & 0 deletions doc/classes/BoneAttachment3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
</member>
<member name="override_pose" type="bool" setter="set_override_pose" getter="get_override_pose" default="false">
Whether the BoneAttachment3D node will override the bone pose of the bone it is attached to. When set to [code]true[/code], the BoneAttachment3D node can change the pose of the bone. When set to [code]false[/code], the BoneAttachment3D will always be set to the bone's transform.
[b]Note:[/b] This override performs interruptively in the skeleton update process using signals due to the old design. It may cause unintended behavior when used at the same time with [SkeletonModifier3D].
</member>
</members>
</class>
49 changes: 49 additions & 0 deletions doc/classes/PhysicalBoneSimulator3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicalBoneSimulator3D" inherits="SkeletonModifier3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
Node that can be the parent of [PhysicalBone3D] and can apply the simulation results to [Skeleton3D].
</brief_description>
<description>
Node that can be the parent of [PhysicalBone3D] and can apply the simulation results to [Skeleton3D].
</description>
<tutorials>
</tutorials>
<methods>
<method name="is_simulating_physics" qualifiers="const">
<return type="bool" />
<description>
Returns a boolean that indicates whether the [PhysicalBoneSimulator3D] is running and simulating.
</description>
</method>
<method name="physical_bones_add_collision_exception">
<return type="void" />
<param index="0" name="exception" type="RID" />
<description>
Adds a collision exception to the physical bone.
Works just like the [RigidBody3D] node.
</description>
</method>
<method name="physical_bones_remove_collision_exception">
<return type="void" />
<param index="0" name="exception" type="RID" />
<description>
Removes a collision exception to the physical bone.
Works just like the [RigidBody3D] node.
</description>
</method>
<method name="physical_bones_start_simulation">
<return type="void" />
<param index="0" name="bones" type="StringName[]" default="[]" />
<description>
Tells the [PhysicalBone3D] nodes in the Skeleton to start simulating and reacting to the physics world.
Optionally, a list of bone names can be passed-in, allowing only the passed-in bones to be simulated.
</description>
</method>
<method name="physical_bones_stop_simulation">
<return type="void" />
<description>
Tells the [PhysicalBone3D] nodes in the Skeleton to stop simulating.
</description>
</method>
</methods>
</class>
60 changes: 51 additions & 9 deletions doc/classes/Skeleton3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
Clear all the bones in this skeleton.
</description>
</method>
<method name="clear_bones_global_pose_override">
<method name="clear_bones_global_pose_override" deprecated="">
<return type="void" />
<description>
Removes the global pose override on all bones in the skeleton.
Expand Down Expand Up @@ -58,6 +58,11 @@
Force updates the bone transform for the bone at [param bone_idx] and all of its children.
</description>
</method>
<method name="get_animate_physical_bones" qualifiers="const" deprecated="">
<return type="bool" />
<description>
</description>
</method>
<method name="get_bone_children" qualifiers="const">
<return type="PackedInt32Array" />
<param index="0" name="bone_idx" type="int" />
Expand All @@ -76,16 +81,17 @@
<param index="0" name="bone_idx" type="int" />
<description>
Returns the overall transform of the specified bone, with respect to the skeleton. Being relative to the skeleton frame, this is not the actual "global" transform of the bone.
[b]Note:[/b] This is the global pose you set to the skeleton in the process, the final global pose can get overridden by modifiers in the deferred process, if you want to access the final global pose, use [signal SkeletonModifier3D.modification_processed].
</description>
</method>
<method name="get_bone_global_pose_no_override" qualifiers="const">
<method name="get_bone_global_pose_no_override" qualifiers="const" deprecated="">
<return type="Transform3D" />
<param index="0" name="bone_idx" type="int" />
<description>
Returns the overall transform of the specified bone, with respect to the skeleton, but without any global pose overrides. Being relative to the skeleton frame, this is not the actual "global" transform of the bone.
</description>
</method>
<method name="get_bone_global_pose_override" qualifiers="const">
<method name="get_bone_global_pose_override" qualifiers="const" deprecated="">
<return type="Transform3D" />
<param index="0" name="bone_idx" type="int" />
<description>
Expand Down Expand Up @@ -119,6 +125,7 @@
<param index="0" name="bone_idx" type="int" />
<description>
Returns the pose transform of the specified bone.
[b]Note:[/b] This is the pose you set to the skeleton in the process, the final pose can get overridden by modifiers in the deferred process, if you want to access the final pose, use [signal SkeletonModifier3D.modification_processed].
</description>
</method>
<method name="get_bone_pose_position" qualifiers="const">
Expand Down Expand Up @@ -176,31 +183,31 @@
Returns all bones in the skeleton to their rest poses.
</description>
</method>
<method name="physical_bones_add_collision_exception">
<method name="physical_bones_add_collision_exception" deprecated="">
<return type="void" />
<param index="0" name="exception" type="RID" />
<description>
Adds a collision exception to the physical bone.
Works just like the [RigidBody3D] node.
</description>
</method>
<method name="physical_bones_remove_collision_exception">
<method name="physical_bones_remove_collision_exception" deprecated="">
<return type="void" />
<param index="0" name="exception" type="RID" />
<description>
Removes a collision exception to the physical bone.
Works just like the [RigidBody3D] node.
</description>
</method>
<method name="physical_bones_start_simulation">
<method name="physical_bones_start_simulation" deprecated="">
<return type="void" />
<param index="0" name="bones" type="StringName[]" default="[]" />
<description>
Tells the [PhysicalBone3D] nodes in the Skeleton to start simulating and reacting to the physics world.
Optionally, a list of bone names can be passed-in, allowing only the passed-in bones to be simulated.
</description>
</method>
<method name="physical_bones_stop_simulation">
<method name="physical_bones_stop_simulation" deprecated="">
<return type="void" />
<description>
Tells the [PhysicalBone3D] nodes in the Skeleton to stop simulating.
Expand All @@ -226,6 +233,12 @@
Sets all bone poses to rests.
</description>
</method>
<method name="set_animate_physical_bones" deprecated="">
<return type="void" />
<param index="0" name="enabled" type="bool" />
<description>
</description>
</method>
<method name="set_bone_enabled">
<return type="void" />
<param index="0" name="bone_idx" type="int" />
Expand All @@ -234,7 +247,16 @@
Disables the pose for the bone at [param bone_idx] if [code]false[/code], enables the bone pose if [code]true[/code].
</description>
</method>
<method name="set_bone_global_pose_override">
<method name="set_bone_global_pose">
<return type="void" />
<param index="0" name="bone_idx" type="int" />
<param index="1" name="pose" type="Transform3D" />
<description>
Sets the global pose transform, [param pose], for the bone at [param bone_idx].
[b]Note:[/b] If other bone poses have been changed, this method executes an update process and will cause performance to deteriorate. If you know that multiple global poses will be applied, consider using [method set_bone_pose] with precalculation.
</description>
</method>
<method name="set_bone_global_pose_override" deprecated="">
<return type="void" />
<param index="0" name="bone_idx" type="int" />
<param index="1" name="pose" type="Transform3D" />
Expand All @@ -251,6 +273,7 @@
<param index="0" name="bone_idx" type="int" />
<param index="1" name="name" type="String" />
<description>
Sets the bone name, [param name], for the bone at [param bone_idx].
</description>
</method>
<method name="set_bone_parent">
Expand All @@ -262,6 +285,14 @@
[b]Note:[/b] [param parent_idx] must be less than [param bone_idx].
</description>
</method>
<method name="set_bone_pose">
<return type="void" />
<param index="0" name="bone_idx" type="int" />
<param index="1" name="pose" type="Transform3D" />
<description>
Sets the pose transform, [param pose], for the bone at [param bone_idx].
</description>
</method>
<method name="set_bone_pose_position">
<return type="void" />
<param index="0" name="bone_idx" type="int" />
Expand Down Expand Up @@ -303,7 +334,8 @@
</method>
</methods>
<members>
<member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true">
<member name="modifier_callback_mode_process" type="int" setter="set_modifier_callback_mode_process" getter="get_modifier_callback_mode_process" enum="Skeleton3D.ModifierCallbackModeProcess" default="1">
Sets the processing timing for the Modifier.
</member>
<member name="motion_scale" type="float" setter="set_motion_scale" getter="get_motion_scale" default="1.0">
Multiplies the 3D position track animation.
Expand All @@ -320,6 +352,10 @@
Emitted when the bone at [param bone_idx] is toggled with [method set_bone_enabled]. Use [method is_bone_enabled] to check the new value.
</description>
</signal>
<signal name="bone_list_changed">
<description>
</description>
</signal>
<signal name="bone_pose_changed">
<param index="0" name="bone_idx" type="int" />
<description>
Expand All @@ -342,5 +378,11 @@
Notification received when this skeleton's pose needs to be updated.
This notification is received [i]before[/i] the related [signal pose_updated] signal.
</constant>
<constant name="MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS" value="0" enum="ModifierCallbackModeProcess">
Set a flag to process modification during physics frames (see [constant Node.NOTIFICATION_INTERNAL_PHYSICS_PROCESS]).
</constant>
<constant name="MODIFIER_CALLBACK_MODE_PROCESS_IDLE" value="1" enum="ModifierCallbackModeProcess">
Set a flag to process modification during process frames (see [constant Node.NOTIFICATION_INTERNAL_PROCESS]).
</constant>
</constants>
</class>
13 changes: 5 additions & 8 deletions doc/classes/SkeletonIK3D.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SkeletonIK3D" inherits="Node" deprecated="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<class name="SkeletonIK3D" inherits="SkeletonModifier3D" deprecated="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A node used to rotate all bones of a [Skeleton3D] bone chain a way that places the end bone at a desired 3D position.
</brief_description>
<description>
SkeletonIK3D is used to rotate all bones of a [Skeleton3D] bone chain a way that places the end bone at a desired 3D position. A typical scenario for IK in games is to place a character's feet on the ground or a character's hands on a currently held object. SkeletonIK uses FabrikInverseKinematic internally to solve the bone chain and applies the results to the [Skeleton3D] [code]bones_global_pose_override[/code] property for all affected bones in the chain. If fully applied, this overwrites any bone transform from [Animation]s or bone custom poses set by users. The applied amount can be controlled with the [member interpolation] property.
SkeletonIK3D is used to rotate all bones of a [Skeleton3D] bone chain a way that places the end bone at a desired 3D position. A typical scenario for IK in games is to place a character's feet on the ground or a character's hands on a currently held object. SkeletonIK uses FabrikInverseKinematic internally to solve the bone chain and applies the results to the [Skeleton3D] [code]bones_global_pose_override[/code] property for all affected bones in the chain. If fully applied, this overwrites any bone transform from [Animation]s or bone custom poses set by users. The applied amount can be controlled with the [member SkeletonModifier3D.influence] property.
[codeblock]
# Apply IK effect automatically on every new frame (not the current)
skeleton_ik_node.start()
Expand All @@ -16,13 +16,13 @@
skeleton_ik_node.stop()

# Apply full IK effect
skeleton_ik_node.set_interpolation(1.0)
skeleton_ik_node.set_influence(1.0)

# Apply half IK effect
skeleton_ik_node.set_interpolation(0.5)
skeleton_ik_node.set_influence(0.5)

# Apply zero IK effect (a value at or below 0.01 also removes bones_global_pose_override on Skeleton)
skeleton_ik_node.set_interpolation(0.0)
skeleton_ik_node.set_influence(0.0)
[/codeblock]
</description>
<tutorials>
Expand Down Expand Up @@ -56,9 +56,6 @@
</method>
</methods>
<members>
<member name="interpolation" type="float" setter="set_interpolation" getter="get_interpolation" default="1.0">
Interpolation value for how much the IK results are applied to the current skeleton bone chain. A value of [code]1.0[/code] will overwrite all skeleton bone transforms completely while a value of [code]0.0[/code] will visually disable the SkeletonIK. A value at or below [code]0.01[/code] also calls [method Skeleton3D.clear_bones_global_pose_override].
</member>
<member name="magnet" type="Vector3" setter="set_magnet_position" getter="get_magnet_position" default="Vector3(0, 0, 0)">
Secondary target position (first is [member target] property or [member target_node]) for the IK chain. Use magnet position (pole target) to control the bending of the IK chain. Only works if the bone chain has more than 2 bones. The middle chain bone position will be linearly interpolated with the magnet position.
</member>
Expand Down
29 changes: 29 additions & 0 deletions doc/classes/SkeletonModifier3D.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SkeletonModifier3D" inherits="Node3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A Node that may modify Skeleton3D's bone.
</brief_description>
<description>
[SkeletonModifier3D] retrieves a target [Skeleton3D] by having a [Skeleton3D] parent.
If there is [AnimationMixer], modification always performs after playback process of the [AnimationMixer].
</description>
<tutorials>
</tutorials>
<members>
<member name="active" type="bool" setter="set_active" getter="is_active" default="true">
If [code]true[/code], the [SkeletonModifier3D] will be processing.
</member>
Comment on lines +13 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is confusing that "Active" and "Visible" are separate properties here.

if SkeletonModifier3D is a child of Node3D, it seems to me that it should use the Node3D visible property instead.

I am unsure why SkeletonModifier3D is a Node3D. If it's a Node, then a custom active property makes more sense, similar to AnimationMixer.

Copy link
Member Author

@TokageItLab TokageItLab Mar 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because XRModifiers inherit Node3D. I believe it make sense for SkeletonModifier3D extending Node3D in order to access the 3D coordinates of the world from within the modifier.

It may indeed be possible to integrate this with visible property since it is Node3D not Node unlike AnimationPlayer, but I am not sure if that is a good idea.

<member name="influence" type="float" setter="set_influence" getter="get_influence" default="1.0">
Sets the influence of the modification.
[b]Note:[/b] This value is used by [Skeleton3D] to blend, so the [SkeletonModifier3D] should always apply only 100% of the result without interpolation.
</member>
</members>
<signals>
<signal name="modification_processed">
<description>
Notifies when the modification have been finished.
[b]Note:[/b] If you want to get the modified bone pose by the modifier, you must use [method Skeleton3D.get_bone_pose] or [method Skeleton3D.get_bone_global_pose] at the moment this signal is fired.
</description>
</signal>
</signals>
</class>
5 changes: 1 addition & 4 deletions doc/classes/XRBodyModifier3D.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="XRBodyModifier3D" inherits="Node3D" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<class name="XRBodyModifier3D" inherits="SkeletonModifier3D" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A node for driving body meshes from [XRBodyTracker] data.
</brief_description>
Expand All @@ -24,9 +24,6 @@
<member name="show_when_tracked" type="bool" setter="set_show_when_tracked" getter="get_show_when_tracked" default="true">
If true then the nodes visibility is determined by whether tracking data is available.
</member>
<member name="target" type="NodePath" setter="set_target" getter="get_target" default="NodePath(&quot;&quot;)">
A [NodePath] to a [Skeleton3D] to animate.
</member>
</members>
<constants>
<constant name="BODY_UPDATE_UPPER_BODY" value="1" enum="BodyUpdate" is_bitfield="true">
Expand Down
5 changes: 1 addition & 4 deletions doc/classes/XRHandModifier3D.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="XRHandModifier3D" inherits="Node3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<class name="XRHandModifier3D" inherits="SkeletonModifier3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A node for driving hand meshes from [XRHandTracker] data.
</brief_description>
Expand All @@ -18,9 +18,6 @@
<member name="hand_tracker" type="StringName" setter="set_hand_tracker" getter="get_hand_tracker" default="&amp;&quot;/user/left&quot;">
The name of the [XRHandTracker] registered with [XRServer] to obtain the hand tracking data from.
</member>
<member name="target" type="NodePath" setter="set_target" getter="get_target" default="NodePath(&quot;&quot;)">
A [NodePath] to a [Skeleton3D] to animate.
</member>
</members>
<constants>
<constant name="BONE_UPDATE_FULL" value="0" enum="BoneUpdate">
Expand Down
Loading
Loading