X Tutup
Skip to content

Implement BoneConstraint3D with CopyTransform/ConvertTransform/Aim Modifiers#100984

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
TokageItLab:bone-constraint
Jun 2, 2025
Merged

Implement BoneConstraint3D with CopyTransform/ConvertTransform/Aim Modifiers#100984
Repiteo merged 1 commit intogodotengine:masterfrom
TokageItLab:bone-constraint

Conversation

@TokageItLab
Copy link
Member

@TokageItLab TokageItLab commented Dec 31, 2024

Contain #104560

BoneConstraint3D

A base class that allows two bones to be specified.

image

Note that interpolation by SkeletonModifier3D.influence for the entire skeleton is done for each SkeletonModifier3D.

However, constraint settings are often applied to multiple bones at the same time. Therefore, it prevents unnecessary interpolation by having the settings in an array so that the number of SkeletonModifier3Ds in the scene does not grow unnecessarily. For this reason, the BoneConstraint3D settings have the apply amount of modification to the bone for each element in the settings array.

AimModifier3D

This is a simple version of LookAtModifier3D that only allows bone to the target without advanced options such as angle limitation or time-based interpolation. The feature is simplified, but instead it is implemented with smooth tracking without euler,

image

CopyTransfromModifier3D

Apply the copied transform of the target bone to the apply bone with processing it with some masks and options.

image

There are 4 ways to apply the transform, depending on the combination of Relative and Additive options.

  • Relative + Additive
    • Extract target pose relative to the rest and add it to the apply bone's pose.
  • Relative + Not Additive
    • Extract target pose relative to the rest and add it to the apply bone's rest.
  • Not Relative + Additive
    • Extract target pose absolutely and add it to the apply bone's pose.
  • Not Relative + Not Additive
    • Extract target pose absolutely and the apply bone's pose is replaced with it.

ConvertTransfromModifier3D

Apply the copied transform of the target bone to the apply bone about the specific axis with remapping it with some options.

image


Compatibility with third-parties

I assume there is some compatibility, but cannot guarantee that the behavior is exactly the same in a particular situation (since Since it has not yet been tested/verified).

Blender

CopyXXX (for rotation with axis mask, rotation mode is roll only) -> CopyTransfromModifier3D
Transformation (for rotation, rotation mode is roll only) -> ConvertTransfromModifier3D
Track/LockedTrack -> AimModifier3D
DampedTrack ->AimModifier3D

VRMConstraint

https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_node_constraint-1.0

RotationConstraint -> CopyTransfromModifier3D with only rotation with all axes without invert flags
RollConstraint -> ConvertTransfromModifier3D with rotation mode
AimConstraint -> AimModifier3D

@TokageItLab TokageItLab added this to the 4.x milestone Dec 31, 2024
@TokageItLab TokageItLab requested a review from a team December 31, 2024 18:27
@TokageItLab TokageItLab force-pushed the bone-constraint branch 2 times, most recently from b5d65a9 to 5490058 Compare December 31, 2024 18:32
@fire fire self-requested a review December 31, 2024 20:01
@fire
Copy link
Member

fire commented Jan 4, 2025

Do we have test scenes?

I'll look into those.

@TokageItLab
Copy link
Member Author

@fire I used this model in quick check to show axes where everything is a sibling of root:

image

constraint_demo.zip

@TokageItLab
Copy link
Member Author

TokageItLab commented Jan 5, 2025

@fire For now, since the feature freeze is nearing, I separated the PR only from the refactoring part, which will cause break compatibility; Since LookAtModifier is added in 4.4, if this PR is carried over to 4.5 it will occur.

@TokageItLab TokageItLab force-pushed the bone-constraint branch 3 times, most recently from d3c358e to 3aaf4e9 Compare January 8, 2025 20:29
@TokageItLab TokageItLab modified the milestones: 4.x, 4.5 Jan 13, 2025
@TokageItLab
Copy link
Member Author

I will write a CI test later, because this module does not depend on external factors such as time, but purely mathematical transformations, so it is possible to check for them.

@fire fire changed the title Implement BoneConstraint3D with CopyTransfrom/ConvertTransfrom/TrackBone Modifiers Implement BoneConstraint3D with CopyTransfrom/ConvertTransform/TrackBone Modifiers Jan 18, 2025
@fire fire changed the title Implement BoneConstraint3D with CopyTransfrom/ConvertTransform/TrackBone Modifiers Implement BoneConstraint3D with CopyTransform/ConvertTransform/TrackBone Modifiers Jan 18, 2025
@TokageItLab TokageItLab force-pushed the bone-constraint branch 3 times, most recently from 5724dec to e6c20fe Compare March 10, 2025 00:01
@aaronfranke
Copy link
Member

aaronfranke commented Mar 10, 2025

For reference, see also this GDScript implementation of VRM constraints I made for godot-vrm: https://github.com/V-Sekai/godot-vrm/blob/master/addons/vrm/node_constraint/bone_node_constraint.gd

Also, I made an example model here: vrm-c/vrm-specification#444 Before merging this PR, we should write a draft PR to godot-vrm that uses this PR and test that it works correctly.

This PR looks much more comprehensive than what I wrote and seems to handle everything in VRM and more, awesome! Feel free to request a review from me once this PR is ready to go.

@aaronfranke aaronfranke self-requested a review March 10, 2025 00:49
@TokageItLab
Copy link
Member Author

Improved handling of zero division in ConvertTransformModifier. Also, "target bone" has been renamed to "reference bone".

While "target" in Aim is clear, the word "target" in Convert and Copy is a bit confusing (although Blender consistently calls it "target"). This rename would make Aim "target" to "reference", but I think it's still understandable.

If anyone has any other better names, suggestions are welcome.

@TokageItLab TokageItLab force-pushed the bone-constraint branch 2 times, most recently from db1470b to 16aab9d Compare March 17, 2025 13:26
@fire
Copy link
Member

fire commented Apr 3, 2025

It's april, my time to work on this is now.

Copy link
Contributor

@lyuma lyuma left a comment

Choose a reason for hiding this comment

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

We discussed in the animation meeting and we had consensus that this feature is good.

We want to try a few extra test cases such as the VRM constraint test models, and it needs a more thorough code review

@TokageItLab TokageItLab force-pushed the bone-constraint branch 4 times, most recently from de4556b to 3c05487 Compare May 20, 2025 08:15
@TokageItLab TokageItLab requested review from SaracenOne and lyuma May 21, 2025 18:56
@TokageItLab
Copy link
Member Author

TokageItLab commented May 21, 2025

I have already shared this with the team, but I will put a demo project for compatibility with VRM (by manually porting settings).

image

constraint_demo.zip

Model:
https://hub.vroid.com/characters/3609285562418162352/models/5465162707471684141

Animation (please download and replace to solve dependency):
https://booth.pm/ja/items/5512385

Finger settings are not ported. There are too many, but I decide that the few files animating the fingers are sufficient without them for testing. If you find anything odd, please compare Unity's UniVRM and Godot's Modifier settings. There may be a mistake in seeing the amount or something else depending on my eyes.

However, Constraint implementation itself should be correct since this PR add and pass the random transforms test with MathCheck.

@TokageItLab
Copy link
Member Author

Rebased to follow #106622 (comment).

Copy link
Member

@SaracenOne SaracenOne left a comment

Choose a reason for hiding this comment

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

I think this is okay to merge now 👍. As you pointed out, it seems to address a pretty substantial amount of features available in both Blender and the VRM spec, and seems relatively easy for the end-user to implement. Since the bone constraints operate on a list of settings, hovering a property in the property inspector does not provide a description as to what the setting does. This would be a pretty nice UX onboarding improvement, but I think this PR has sat here long enough that I'm not going to advocate holding it up any longer.

@TokageItLab TokageItLab moved this from Ready for review to Approved, Waiting for Production in Animation Team Issue Triage Jun 1, 2025
@Repiteo
Copy link
Contributor

Repiteo commented Jun 3, 2025

Thanks!

@scotdoria
Copy link

It might be because I'm misunderstanding the system but is there a way to apply the transform in the local space of the apply bone?

@TokageItLab
Copy link
Member Author

TokageItLab commented Jun 23, 2025

@scotdoria Copy/ConvertTransform mod transfers are performed in local space. Several values (local by based rest, based current pose, based initial transform) can be calculated by combining the Relative/Additive options. You can find the explanation in the class reference.

In the future, model/global spaces possibly also be available, but it will take time to implement many safety calculations. The current implementation focuses on achieving natural character posing by covering compatibility with the VRM format and some Blender settings.

By the way, if local space is not your intended space after retargetingg rest may be overridden by retargeter, so please set up the Advanced import option to use RetargetModifier.

@gaoyan2659365465
Copy link

A 2D version is needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

10 participants

X Tutup