Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Clay John <[email protected]>
  • Loading branch information
TokageItLab and clayjohn authored Aug 8, 2024
1 parent 2472b8b commit 7babe5e
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions collections/_article/design-of-the-skeleton-modifier-3d.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Design of the Skeleton Modifier 3D"
excerpt: "Skeleton bone update process is reworked to add SkeletonModifier3D for modifying the Skeleton."
excerpt: "We have reworked the skeleton bone update process to add SkeletonModifier3D for modifying the Skeleton."
categories: ["progress-report"]
author: Silc Renew
image: /storage/blog/covers/design-of-the-skeleton-modifier-3d.webp
Expand All @@ -9,9 +9,9 @@ date: 2024-06-01 00:00:00

<style>article .content img { background-color: initial; }</style>

A new node called `SkeletonModifier3D` will be added in Godot 4.3. It is to animate `Skeleton3D` outside of `AnimationMixer` and is the base class for several existing nodes.
In Godot 4.3 we are adding a new node called `SkeletonModifier3D`. It is used to animate `Skeleton3D`s outside of `AnimationMixer` and is now the base class for several existing nodes.

Thus, we add the deprecated flag on some old properties with "override" in `Skeleton3D`.
As part of this we have deprecated (but not removed) some of the pose override functionality in `Skeleton3D` including:

- `set_bone_global_pose_override()`
- `get_bone_global_pose_override()`
Expand All @@ -30,9 +30,9 @@ The main problem is the fact that "the processing order between `Skeleton3D` and

![different process orders](/storage/blog/design-of-the-skeleton-modifier-3d/different_process_orders.webp)

If there is modifier such as IK or physical bone, in most of cases, it needs to be applied to the result of the played animation. So they need to be processed after the `AnimationMixer`.
If there is a modifier such as IK or physical bone, in most cases, it needs to be applied to the result of the played animation. So they need to be processed after the `AnimationMixer`.

In old skeleton modifier design with bone pose override you must place those modifiers below the `AnimationMixer`. However as scene trees become more complex, it becomes difficult to keep track of the processing order. Also the scene might be imported from glTF and cannot edit without localization, so managing node order becomes tedious.
In the old skeleton modifier design with bone pose override you must place those modifiers below the `AnimationMixer`. However as scene trees become more complex, it becomes difficult to keep track of the processing order. Also the scene might be imported from glTF which cannot be edited without localization, so managing node order becomes tedious.

Moreover, if multiple nodes use bone pose override, it breaks the modified result.

Expand All @@ -44,7 +44,7 @@ AnimationMixer -> ModifierA -> ModifierB

Keep in mind that both `ModifierA` and `ModifierB` need to get the bone pose that was processed immediately before.

The `AnimationMixer` does not use `set_bone_global_pose_override()`, so it transforms the original pose as `set_bone_pose_rotation()`. This means that the input to `ModifierA` must be get from the original pose with `get_bone_global_pose_no_override()` and the output must be get from override with `get_bone_global_pose_override()`. In this case, if `ModiferB` wants to consider the output of `ModiferA`, both the input and output of `ModifierB` must be override with `get_bone_global_pose_override()`.
The `AnimationMixer` does not use `set_bone_global_pose_override()`, so it transforms the original pose as `set_bone_pose_rotation()`. This means that the input to `ModifierA` must be retrieved from the original pose with `get_bone_global_pose_no_override()` and the output must be retreived from the override with `get_bone_global_pose_override()`. In this case, if `ModiferB` wants to consider the output of `ModiferA`, both the input and output of `ModifierB` must be the override with `get_bone_global_pose_override()`.

Then, can the order of `ModifierA` and `ModifierB` be interchanged?

Expand All @@ -54,11 +54,11 @@ Because `ModifierB`'s input is now `get_bone_global_pose_override()` which is di

As I described above, the override design was very weak in terms of process ordering.

# How the new skeleton design to work with SkeletonModifier3D?
# How does the new skeleton design work with SkeletonModifier3D?

`SkeletonModifier3D` is designed to modify bones in the `_process_modification()` as virtual method. This means that if you want to develop a custom `SkeletonModifier3D`, you will need to modify the bones within that method.
`SkeletonModifier3D` is designed to modify bones in the `_process_modification()` virtual method. This means that if you want to develop a custom `SkeletonModifier3D`, you will need to modify the bones within that method.

`SkeletonModifier3D` does not execute modifications as stand alone, but is executed by the parent of `Skeleton3D`. By placing `SkeletonModifier3D` as a child of `Skeleton3D`, they are registered in `Skeleton3D`, and the process is executed only once per frame in the `Skeleton3D` update process. Then, **the processing order between modifiers is guaranteed to be the same as the order of the `Skeleton3D`'s child list**.
`SkeletonModifier3D` does not execute modifications by itself, but is executed by the parent of `Skeleton3D`. By placing `SkeletonModifier3D` as a child of `Skeleton3D`, they are registered in `Skeleton3D`, and the process is executed only once per frame in the `Skeleton3D` update process. Then, **the processing order between modifiers is guaranteed to be the same as the order of the children in `Skeleton3D`'s child list**.

Since `AnimationMixer` is applied before the `Skeleton3D` update process, `SkeletonModifier3D` is guaranteed to run after `AnimationMixer`. Also, they do not require `bone_pose_global_override`; This removes any confusion as to whether we should use override or not.

Expand Down Expand Up @@ -99,7 +99,7 @@ Then, how do we create a custom `SkeletonModifier3D`? Let's try to create a simp

## 1. Create a script

Create a blank gdscript file and extends `SkeletonModifier3D`. At this time, register the custom `SkeletonModifier3D` you created with the `class_name` declaration so that it can be added to the scene dock.
Create a blank gdscript file that extends `SkeletonModifier3D`. At this time, register the custom `SkeletonModifier3D` you created with the `class_name` declaration so that it can be added to the scene dock.

```gdscript
class_name CustomModifier
Expand Down Expand Up @@ -171,7 +171,7 @@ func _y_look_at(from: Transform3D, target: Vector3) -> Transform3D:
return from
```

The `_process_modification()` is a virtual method called in the update process after the AnimationMixer has been applied, as described in the sequence diagram above. If you modify bones in it, it is guaranteed that the order in which the modifications are applied will match the order of `SkeletonModifier3D` of the `Skeleton3D`'s child list.
`_process_modification()` is a virtual method called in the update process after the AnimationMixer has been applied, as described in the sequence diagram above. If you modify bones in it, it is guaranteed that the order in which the modifications are applied will match the order of `SkeletonModifier3D` of the `Skeleton3D`'s child list.

<video autoplay loop muted playsinline>
<source src="/storage/blog/design-of-the-skeleton-modifier-3d/custom_modifier.webm?1" type="video/webm">
Expand Down Expand Up @@ -226,9 +226,9 @@ If you want permanent modifications, i.e., if you want to develop something like

For now, Godot 4.3 will be containing only `SkeletonModifier3D` which is a migration of several existing nodes that have been in existence since 4.0.

But, there is good news! We are planning to add some `SkeletonModifier3D` in Godot 4.4, such as new IK, constraint, and jiggle.
But, there is good news! We are planning to add some built in `SkeletonModifier3D`s in Godot 4.4, such as new IK, constraint, and springbone/jiggle.

If you are interested in developing your own `SkeletonModifier3D`, during 4.3 should be a great time to send a proposal to include it in core.
If you are interested in developing your own effect using `SkeletonModifier3D`, feel free to make a proposal to include it in core.

## Support

Expand Down

0 comments on commit 7babe5e

Please sign in to comment.