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 SpringBoneSimulator3D to wiggle chained bones #101409

Merged
merged 1 commit into from
Jan 13, 2025

Conversation

TokageItLab
Copy link
Member

@TokageItLab TokageItLab commented Jan 10, 2025

spring_bone_demo.mp4

Model: アリシア・ソリッド / CC by DWANGO Co., Ltd.

This SkeletonModifier3D is ported from https://github.com/V-Sekai/godot-vrm and some additional features are implemented.

The movement logic is published by VRM Consortium (https://vrm.dev/en/univrm/springbone/univrm_secondary/) under the MIT license, SpringBoneSimulator3D reproduces that behavior.

This modifier behaves differently from PhysicalBoneSimulator3D as it attempts to return the original pose after modification.

SpringBoneSimulator3D

It has the bone chain settings as an array. Setting the root bone and end bone generates a static array in the joints group with reference to the joints in between.

image

After set root bone and end bone:

image

For simplified setup, you can use curves. When you edit a curve, the values scaled depending on it are cached in the static array.

image

With Option individual_config, detailed settings can also be made for each joint.

image

Parameters

RotationAxis

If sets a specific axis, it acts like a hinge joint.

hinge.mp4

Also, setting this up with aligned axes in a radial shape also helps to prevent collapse of the skirt.

Entend end bone

As explained some times in #32393 and #57038, glTF does not have information about the length of the bones, so even if the end bones have tail in DCC, it will be missing on export.

This option would allow the tail to be added to the end bone without having to add a leaf bone and export it.

Physical Parameters

Radius

It is used for collisions with SpringBoneCollision3D, described below.

Stiffness

The greater the value, the faster it recovers to its initial pose.

Drag

The greater the value, the more suppressed the wiggling.

Gravity

Direction and amount can be set.

SpringBoneCollision3D

Collision for SpringBoneSimulator3D that is processed in the SkeletonModifier3D process independently of PhysicsServer3D. It must be a child of SpringBoneSimulator3D in order to manage the process order. For each bone chain, depending on the SpringBoneSimulator3D.are_all_child_collisions_enabled option, either an excluded list or an allowed list is available.

image

SpringBoneCollisionPlane3D

A infinite plane collision. It is an infinite size XZ plane, and the +Y direction is treated as normal.

SpringBoneCollisionSphere3D

A sphere shape collision.

SpringBoneCollisionCupsule3D

A capsule shape collision.

The capsule and sphere collision have an inside option as the function to trap the joint.

image

@TokageItLab TokageItLab added this to the 4.x milestone Jan 10, 2025
@TokageItLab TokageItLab requested review from a team as code owners January 10, 2025 22:12
@TokageItLab TokageItLab force-pushed the spring-bone branch 3 times, most recently from 1d18c06 to b06f05d Compare January 10, 2025 22:31
@fire fire self-requested a review January 10, 2025 22:39
@fire fire mentioned this pull request Jan 10, 2025
@TokageItLab TokageItLab force-pushed the spring-bone branch 2 times, most recently from 0e22613 to 73bf6b3 Compare January 11, 2025 00:30
@fire
Copy link
Member

fire commented Jan 11, 2025

We had some debate about whitelisting vs blacklisting the collisions.

We mentioned that VRM standard uses whitelisting.

@lyuma had concerns that inverting the listing would suggest that the less performant option is easier to do.

Tokage is ok with either but proposed blacklisting.

@TokageItLab
Copy link
Member Author

TokageItLab commented Jan 11, 2025

If we are concerned about performance, this is not much of a basis for concern, since we need to be careful when using either list.

The most serious problem is that without allow list, you cannot control the order in which collisions are handled on a per-bone chain basis, which could break strict compatibility with VRM. So support for permission lists is a must.

collisions.mp4

However, I believe it is necessary for quality of life, because when using exclusion lists, the user's operation steps when creating a mockup are cut in half or less.

For example, the following case:

  1. There are 4 bone chains, 5 normal collisions, and 1 inside collider.
  2. Apply the 5 normal collisions to all bone chains.
  3. I want to apply the inside collider to only one bone chain. However, I need to exclude the inside collider from the other 3 bone chains.

In this case, the allow list would require 4*5+1=21 steps, whereas the exclude list would only require 3*1=3 steps.

However, in the case where 5 normal collisions are not applied to all bone chains (so if step 2 is not needed), the allow list requires fewer steps.

So it is a matter of which direction to go in to the destination state, and I thought both should be supported. For now, it resets when the allow/exclude list is switched, but I think we can send follow up PR with an option to invert the list in the future if there are demands.

Copy link
Member

@AThousandShips AThousandShips left a comment

Choose a reason for hiding this comment

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

Looks good otherwise

scene/3d/spring_bone_simulator_3d.h Outdated Show resolved Hide resolved
scene/3d/spring_bone_simulator_3d.h Outdated Show resolved Hide resolved
scene/3d/spring_bone_simulator_3d.h Outdated Show resolved Hide resolved
scene/3d/spring_bone_collision_3d.h Outdated Show resolved Hide resolved
scene/3d/spring_bone_collision_3d.h Outdated Show resolved Hide resolved
doc/classes/SpringBoneSimulator3D.xml Outdated Show resolved Hide resolved
doc/classes/SpringBoneSimulator3D.xml Outdated Show resolved Hide resolved
doc/classes/SpringBoneSimulator3D.xml Outdated Show resolved Hide resolved
doc/classes/SpringBoneSimulator3D.xml Outdated Show resolved Hide resolved
doc/classes/SpringBoneSimulator3D.xml Outdated Show resolved Hide resolved
@TokageItLab TokageItLab force-pushed the spring-bone branch 5 times, most recently from 938b933 to aa39b5f Compare January 11, 2025 21:14
@TokageItLab TokageItLab added this to the 4.4 milestone Jan 13, 2025
@TokageItLab
Copy link
Member Author

Squash to include #101422.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

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

Only did a cursory review, seems fairly self-contained and the code looks clean.

scene/3d/spring_bone_collision_3d.cpp Outdated Show resolved Hide resolved
scene/3d/spring_bone_collision_3d.h Outdated Show resolved Hide resolved
Comment on lines +7 to +9
A collision can be a child of [SpringBoneSimulator3D]. If it is not a child of [SpringBoneSimulator3D], it has no effect.
The colliding and sliding are done in the [SpringBoneSimulator3D]'s modification process in order of its collision list which is set by [method SpringBoneSimulator3D.set_collision_path]. If [method SpringBoneSimulator3D.are_all_child_collisions_enabled] is [code]true[/code], the order matches [SceneTree].
If [member bone] is set, it synchronizes with the bone pose of the ancestor [Skeleton3D], which is done in before the [SpringBoneSimulator3D]'s modification process as the pre-process.
Copy link
Member

Choose a reason for hiding this comment

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

@Mickeon I foresee you might want to do a follow-up PR to improve the flow of the docs added in this PR (all SpringBone* classes).

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.

Overall very nice. We should merge it so users can start playing with it. I haven't verified the math entirely but from reading the code it looks familiar / similar to the GDScript godot vrm implementation so I am fairly confident it should work.

The api covers both advanced and simple uses, in a way that adds minimal implementation complexity. I think it should be very nice

small docs question: does height in capsule collision work the same way as height in CollisionShapeCapsule? (Is it inner or outer height including top/bottom) we can fix docs after merge.

@TokageItLab
Copy link
Member Author

TokageItLab commented Jan 13, 2025

small docs question: does height in capsule collision work the same way as height in CollisionShapeCapsule? (Is it inner or outer height including top/bottom) we can fix docs after merge.

Yes, I remember there was a recent change in the height to include the hemisphere in CollisionShapeCapsule, so I adapted the behavior to that.

@TokageItLab TokageItLab requested a review from akien-mga January 13, 2025 20:40
Co-authored-by: lyuma <[email protected]>
Co-authored-by: fire <[email protected]>
Co-authored-by: SaracenOne <[email protected]>
@akien-mga akien-mga merged commit 2f6a18f into godotengine:master Jan 13, 2025
20 checks passed
@akien-mga
Copy link
Member

Thanks!

@shiouhuamien
Copy link

shiouhuamien commented Jan 17, 2025

Sorry, I found 2 issues while testing the 4.4 beta. I don't know if I should report them here. I'm sorry if I offended you.

1.Individual Config are only valid in the editor and will become invalid after running and all settings will be cleared.

2. Collision is only valid in the editor, not during runtime
It turns out that the collision setting is a blacklist. I made a mistake myself. Sorry.

@TokageItLab
Copy link
Member Author

TokageItLab commented Jan 17, 2025

@shiouhuamien It sounds like the Animation and Skeleton processes do not match.

image image

These must be matched. After you check them, if you still have problems, send the issue on the https://github.com/godotengine/godot/issues with the minimal reproduction project file.

@fire
Copy link
Member

fire commented Jan 17, 2025

Maybe matching can be turned into an editor node warning

@TokageItLab
Copy link
Member Author

@shiouhuamien I have confirmed a problem with the indivisual config and sent a fix. Please check it if possible: #101729

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
7 participants