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

New and improved IK system for Skeleton3D - Squashed! #51368

Conversation

TwistedTwigleg
Copy link
Contributor

@TwistedTwigleg TwistedTwigleg commented Aug 7, 2021

This PR and commit adds a new IK system for 3D with the Skeleton3D node that adds several new IK solvers.

This work was sponsored by GSoC 2020 and TwistedTwigleg.

Once merged, the code in this PR will be up to the community to maintain. I will help advise and contribute small changes infrequently as best I can, but I cannot take the responsibility of maintaining and overseeing the code.

Huge thanks to everyone that has helped with this PR and getting the PR to this point! 🎉

Copy link
Member

@fire fire left a comment

Choose a reason for hiding this comment

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

Approved, there are improvements for the user interface of the individual IK solvers to be done, but those are future improvements that require design work.

The goal is to get further testing to flush out the bugs in the IK modifier.

I'll try to get some demos created for the group, but isn't blocking this pr.

Is it fine to take the demos from your GSOC IK github repository and using them for demos?

<description>
Returns the rest transform for a bone [code]bone_idx[/code].
Copy link
Member

Choose a reason for hiding this comment

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

global_pose_to_local_pose description disappeared?

editor/plugins/node_3d_editor_gizmos.cpp Show resolved Hide resolved
@TwistedTwigleg TwistedTwigleg force-pushed the GSOC_2020_Working_Branch_IK_SQUASHED branch from 04f381b to 62e9e8f Compare August 7, 2021 17:53
@TwistedTwigleg
Copy link
Contributor Author

Thanks guys! I adjusted the code based on the review feedback.

@fire - feel free to use the demos from the IK repository for demos or whatever, it's all good 👍

@lyuma lyuma added this to the 4.0 milestone Aug 7, 2021
@fire
Copy link
Member

fire commented Aug 10, 2021

As discussed with the Godot Engine meeting today. @AndreaCatania will do a final pass, review, approve and we can merge.

Copy link
Contributor

@AndreaCatania AndreaCatania left a comment

Choose a reason for hiding this comment

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

There are some nit here and there, but the code looks good.

Something to really fix before merge, other than the marked things, are all the float, that should be real_t instead: (If you use Visual Studio Code) you can just use crtl+h to find and replace all those.

Another thing I advice you to fix, but it's not necessary and up to you, is to change the Vector to LocalVector, especially on the skeleton modifications: For example, all the SkeletonModification* classes, are using Vector, but they are doing heavy modifications on it, and not even using the pointer trick to just access the memory; so each access will result in complex operations. As example, you can check the function: void SkeletonModification3DJiggle::_execute_jiggle_joint(int p_joint_idx, Node3D *p_target, float p_delta) {.

Refactor that part is not that complex however, you just need to Change Vector to LocalVector and remove .write where you use it, all the other APIs are the same.

core/math/basis.cpp Outdated Show resolved Hide resolved
core/math/basis.cpp Outdated Show resolved Hide resolved
editor/plugins/node_3d_editor_gizmos.cpp Show resolved Hide resolved
scene/3d/bone_attachment_3d.cpp Outdated Show resolved Hide resolved
scene/3d/bone_attachment_3d.cpp Outdated Show resolved Hide resolved
scene/resources/skeleton_modification_3d_twoboneik.h Outdated Show resolved Hide resolved
scene/resources/skeleton_modification_3d_stackholder.h Outdated Show resolved Hide resolved
scene/resources/skeleton_modification_3d_jiggle.h Outdated Show resolved Hide resolved
scene/resources/skeleton_modification_3d_fabrik.h Outdated Show resolved Hide resolved
scene/resources/skeleton_modification_3d_ccdik.h Outdated Show resolved Hide resolved
@TwistedTwigleg
Copy link
Contributor Author

Thanks for the review @AndreaCatania! I will try to start incorporating the feedback and making changes as soon as I have the time, likely this weekend.

@TwistedTwigleg TwistedTwigleg force-pushed the GSOC_2020_Working_Branch_IK_SQUASHED branch 2 times, most recently from 36da712 to 08671b5 Compare August 12, 2021 20:00
@TwistedTwigleg
Copy link
Contributor Author

TwistedTwigleg commented Aug 12, 2021

I had some spare time today, so I made the changes based on the review! All of the feedback was taken into account and the code modified accordingly.

As of when this was written, there is now a few warnings since unsigned integers are being compared to integers due to the changes from LocalVector to Vector. I will see if I can resolve them though once I have a chance, but everything compiles.

Edit: Fixed the issues. Now compiling does not present the errors.

@TwistedTwigleg TwistedTwigleg force-pushed the GSOC_2020_Working_Branch_IK_SQUASHED branch from 08671b5 to b981368 Compare August 12, 2021 22:04
Copy link
Contributor

@AndreaCatania AndreaCatania left a comment

Choose a reason for hiding this comment

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

Many thanks for the LocalVector usage, few floats remained to be changed and few other changes on the return types are needed.

Please let me know if you have any question or you need help, feel free to ping me on Godot Chat.

editor/plugins/node_3d_editor_gizmos.cpp Show resolved Hide resolved

return bones[p_bone].parent;
}

void Skeleton3D::set_bone_rest(int p_bone, const Transform3D &p_rest) {
ERR_FAIL_INDEX(p_bone, bones.size());
Vector<int> Skeleton3D::get_bone_children(int p_bone) const {
Copy link
Contributor

Choose a reason for hiding this comment

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

This function should now return const LocalVector<int> &, otherwise you will convert a LocalVector (bones[p_bone].child_bones) to a Vector, which is bad. If you can't convert that, I suggest to replace the bones[p_bone].child_bones type and use Vector again.

Of course, depending how you solve the issue you have to consider to also change all it's usage:

// From
Vector<int> child_bones = get_bone_children(p_bone);
// To
const LocalVector<int> &child_bones = get_bone_children(p_bone);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I converted it back to a Vector<int>, as something with exposing the LocalVector properties was causing issues. Here's what the errors looked like:

[ 86%] Compiling ==> scene/3d/skeleton_ik_3d.cpp
In file included from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from ./scene/main/node.h:34,
                 from ./scene/3d/node_3d.h:34,
                 from scene/3d/skeleton_3d.h:36,
                 from scene/3d/skeleton_3d.cpp:31:
./core/object/method_bind.h: In instantiation of 'Variant::Type MethodBindTR<R, P>::_gen_argument_type(int) const [with R = LocalVector<int>; P = {}]':
./core/object/method_bind.h:416:24:   required from here
./core/object/method_bind.h:420:27: error: incomplete type 'GetTypeInfo<LocalVector<int>, void>' used in nested name specifier
  420 |    return GetTypeInfo<R>::VARIANT_TYPE;
      |                           ^~~~~~~~~~~~
./core/object/method_bind.h: In instantiation of 'PropertyInfo MethodBindTR<R, P>::_gen_argument_type_info(int) const [with R = LocalVector<int>; P = {}]':
./core/object/method_bind.h:424:23:   required from here
./core/object/method_bind.h:430:41: error: incomplete type 'GetTypeInfo<LocalVector<int>, void>' used in nested name specifier
  430 |    return GetTypeInfo<R>::get_class_info();
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
./core/object/method_bind.h: In instantiation of 'GodotTypeInfo::Metadata MethodBindTR<R, P>::get_argument_meta(int) const [with R = LocalVector<int>; P = {}]':
./core/object/method_bind.h:440:34:   required from here
./core/object/method_bind.h:444:27: error: incomplete type 'GetTypeInfo<LocalVector<int>, void>' used in nested name specifier
  444 |    return GetTypeInfo<R>::METADATA;
      |                           ^~~~~~~~
./core/object/method_bind.h: In instantiation of 'Variant::Type MethodBindTR<R, P>::_gen_argument_type(int) const [with R = LocalVector<int>; P = {int}]':
./core/object/method_bind.h:416:24:   required from here
./core/object/method_bind.h:420:27: error: incomplete type 'GetTypeInfo<LocalVector<int>, void>' used in nested name specifier
  420 |    return GetTypeInfo<R>::VARIANT_TYPE;
      |                           ^~~~~~~~~~~~
./core/object/method_bind.h: In instantiation of 'PropertyInfo MethodBindTR<R, P>::_gen_argument_type_info(int) const [with R = LocalVector<int>; P = {int}]':
./core/object/method_bind.h:424:23:   required from here
./core/object/method_bind.h:430:41: error: incomplete type 'GetTypeInfo<LocalVector<int>, void>' used in nested name specifier
  430 |    return GetTypeInfo<R>::get_class_info();
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
./core/object/method_bind.h: In instantiation of 'GodotTypeInfo::Metadata MethodBindTR<R, P>::get_argument_meta(int) const [with R = LocalVector<int>; P = {int}]':
./core/object/method_bind.h:440:34:   required from here
./core/object/method_bind.h:444:27: error: incomplete type 'GetTypeInfo<LocalVector<int>, void>' used in nested name specifier
  444 |    return GetTypeInfo<R>::METADATA;
      |                           ^~~~~~~~
In file included from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from ./scene/main/node.h:34,
                 from ./scene/3d/node_3d.h:34,
                 from scene/3d/skeleton_3d.h:36,
                 from scene/3d/skeleton_3d.cpp:31:
./core/variant/binder_common.h: In instantiation of 'void call_with_variant_args_ret_helper(T*, R (T::*)(P ...), const Variant**, Variant&, Callable::CallError&, IndexSequence<Is ...>) [with T = __UnexistingClass; R = LocalVector<int>; P = {}; long unsigned int ...Is = {}]':
./core/variant/binder_common.h:453:35:   required from 'void call_with_variant_args_ret_dv(T*, R (T::*)(P ...), const Variant**, int, Variant&, Callable::CallError&, const Vector<Variant>&) [with T = __UnexistingClass; R = LocalVector<int>; P = {}]'
./core/object/method_bind.h:454:32:   required from 'Variant MethodBindTR<R, P>::call(Object*, const Variant**, int, Callable::CallError&) [with R = LocalVector<int>; P = {}]'
./core/object/method_bind.h:449:18:   required from here
./core/variant/binder_common.h:648:8: error: no match for 'operator=' (operand types are 'Variant' and 'LocalVector<int>')
  648 |  r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ./core/variant/callable_bind.h:35,
                 from ./core/object/object.h:44,
                 from ./core/variant/binder_common.h:35,
                 from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from ./scene/main/node.h:34,
                 from ./scene/3d/node_3d.h:34,
                 from scene/3d/skeleton_3d.h:36,
                 from scene/3d/skeleton_3d.cpp:31:
./core/variant/variant.h:679:7: note: candidate: 'void Variant::operator=(const Variant&)'
  679 |  void operator=(const Variant &p_variant); // only this is enough for all the other types
      |       ^~~~~~~~
./core/variant/variant.h:679:32: note:   no known conversion for argument 1 from 'LocalVector<int>' to 'const Variant&'
  679 |  void operator=(const Variant &p_variant); // only this is enough for all the other types
      |                 ~~~~~~~~~~~~~~~^~~~~~~~~
In file included from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from ./scene/main/node.h:34,
                 from ./scene/3d/node_3d.h:34,
                 from scene/3d/skeleton_3d.h:36,
                 from scene/3d/skeleton_3d.cpp:31:
./core/variant/binder_common.h: In instantiation of 'void call_with_ptr_args_ret_helper(T*, R (T::*)(P ...), const void**, void*, IndexSequence<Is ...>) [with T = __UnexistingClass; R = LocalVector<int>; P = {}; long unsigned int ...Is = {}]':
./core/variant/binder_common.h:501:43:   required from 'void call_with_ptr_args_ret(T*, R (T::*)(P ...), const void**, void*) [with T = __UnexistingClass; R = LocalVector<int>; P = {}]'
./core/object/method_bind.h:463:40:   required from 'void MethodBindTR<R, P>::ptrcall(Object*, const void**, void*) [with R = LocalVector<int>; P = {}]'
./core/object/method_bind.h:459:15:   required from here
./core/variant/binder_common.h:253:21: error: 'encode' is not a member of 'PtrToArg<LocalVector<int> >'
  253 |  PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
      |  ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./core/variant/binder_common.h: In instantiation of 'void call_with_variant_args_ret_helper(T*, R (T::*)(P ...), const Variant**, Variant&, Callable::CallError&, IndexSequence<Is ...>) [with T = __UnexistingClass; R = LocalVector<int>; P = {int}; long unsigned int ...Is = {0}]':
./core/variant/binder_common.h:453:35:   required from 'void call_with_variant_args_ret_dv(T*, R (T::*)(P ...), const Variant**, int, Variant&, Callable::CallError&, const Vector<Variant>&) [with T = __UnexistingClass; R = LocalVector<int>; P = {int}]'
./core/object/method_bind.h:454:32:   required from 'Variant MethodBindTR<R, P>::call(Object*, const Variant**, int, Callable::CallError&) [with R = LocalVector<int>; P = {int}]'
./core/object/method_bind.h:449:18:   required from here
./core/variant/binder_common.h:648:8: error: no match for 'operator=' (operand types are 'Variant' and 'LocalVector<int>')
  648 |  r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ./core/variant/callable_bind.h:35,
                 from ./core/object/object.h:44,
                 from ./core/variant/binder_common.h:35,
                 from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from ./scene/main/node.h:34,
                 from ./scene/3d/node_3d.h:34,
                 from scene/3d/skeleton_3d.h:36,
                 from scene/3d/skeleton_3d.cpp:31:
./core/variant/variant.h:679:7: note: candidate: 'void Variant::operator=(const Variant&)'
  679 |  void operator=(const Variant &p_variant); // only this is enough for all the other types
      |       ^~~~~~~~
./core/variant/variant.h:679:32: note:   no known conversion for argument 1 from 'LocalVector<int>' to 'const Variant&'
  679 |  void operator=(const Variant &p_variant); // only this is enough for all the other types
      |                 ~~~~~~~~~~~~~~~^~~~~~~~~
In file included from ./core/object/method_bind.h:34,
                 from ./core/object/class_db.h:34,
                 from ./core/config/project_settings.h:34,
                 from ./scene/main/node.h:34,
                 from ./scene/3d/node_3d.h:34,
                 from scene/3d/skeleton_3d.h:36,
                 from scene/3d/skeleton_3d.cpp:31:
./core/variant/binder_common.h: In instantiation of 'void call_with_ptr_args_ret_helper(T*, R (T::*)(P ...), const void**, void*, IndexSequence<Is ...>) [with T = __UnexistingClass; R = LocalVector<int>; P = {int}; long unsigned int ...Is = {0}]':
./core/variant/binder_common.h:501:43:   required from 'void call_with_ptr_args_ret(T*, R (T::*)(P ...), const void**, void*) [with T = __UnexistingClass; R = LocalVector<int>; P = {int}]'
./core/object/method_bind.h:463:40:   required from 'void MethodBindTR<R, P>::ptrcall(Object*, const void**, void*) [with R = LocalVector<int>; P = {int}]'
./core/object/method_bind.h:459:15:   required from here
./core/variant/binder_common.h:253:21: error: 'encode' is not a member of 'PtrToArg<LocalVector<int> >'
  253 |  PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
      |  ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Based on the error, I think its a missing function or two that doesn't allow it to work with the properties list, from what I can tell. For now, I figure changing it back to a Vector<int> is probably best since I'm not totally sure what would need to be changed to get it working. (Better to not break something accidentally 😅 )

bool Skeleton3D::is_bone_enabled(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
return bones[p_bone].enabled;
Vector<int> Skeleton3D::get_parentless_bones() const {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above, this should return const LocalVector &, since parentless_bones is now LocalVector, if you can't do the change, please make sure to make parentless_bones a Vector again.

Depending how you solve it, make sure to adjust its usage too.

Vector<int> bones;
Vector<float> weights;
LocalVector<int> bones;
LocalVector<float> weights;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, this should be: real_t.

Vector3 v0 = grests[current_bone_idx].origin;
Vector3 v1 = grests[child_bone_idx].origin;
Vector3 d = skel->get_bone_rest(child_bone_idx).origin.normalized();
float dist = skel->get_bone_rest(child_bone_idx).origin.length();
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, this should be: real_t.

Vector3 d = skel->get_bone_rest(child_bone_idx).origin.normalized();
float dist = skel->get_bone_rest(child_bone_idx).origin.length();

// Find closest axis.
int closest = -1;
float closest_d = 0.0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, this should be: real_t.

for (int j = 0; j < 3; j++) {
float dp = Math::abs(grests[parent].basis[j].normalized().dot(d));
float dp = Math::abs(grests[current_bone_idx].basis[j].normalized().dot(d));
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, this should be: real_t.

@AndreaCatania
Copy link
Contributor

AndreaCatania commented Aug 13, 2021

@TwistedTwigleg Sorry about my previous review, I did a mistake.

	bool _set(const StringName &p_name, const Variant &p_value);
	bool _get(const StringName &p_name, Variant &r_ret) const;
	void _get_property_list(List<PropertyInfo> *p_list) const

These don't need to be virtual, indeed you could not use override, please accept my apologize, if you can't fix it, I'll fix it for you.

@TwistedTwigleg TwistedTwigleg force-pushed the GSOC_2020_Working_Branch_IK_SQUASHED branch 2 times, most recently from 1318736 to ce05962 Compare August 14, 2021 16:24
@TwistedTwigleg
Copy link
Contributor Author

I changed the code based on the latest review. 👍

One thing I noticed: Now I cannot assign modifications to the SkeletonModificationStack3D when it's assigned to a Skeleton. The debugger doesn't show any errors in the Godot console or anything, it just doesn't add the new modification to the stack in the editor UI, making it impossible to configure the modifications and use them.
Is anyone else getting this issue with this PR? If so, does anyone have an idea on what might be causing it?

@fire
Copy link
Member

fire commented Aug 14, 2021

Did you call the scan for new editor updates function? If not you'd have to look away from the godot editor and look back. I don't remember the exact name at this current moment.

Copy link
Contributor

@AndreaCatania AndreaCatania 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, Good Job!

@akien-mga akien-mga merged commit fff9a45 into godotengine:master Aug 16, 2021
@akien-mga
Copy link
Member

Thanks a lot!

@TwistedTwigleg
Copy link
Contributor Author

Awesome, thanks guys 😄

@AndreaCatania
Copy link
Contributor

AndreaCatania commented Aug 16, 2021

Would be lovely if you could also record a video (even short) to show the new features in action, and maybe post on twitter :)

@TwistedTwigleg
Copy link
Contributor Author

Definitely! I'll try to get something made and posted soon.
I might be able to get something posted later today, but worse case I'll have a video and twitter post by the weekend 👍

@TwistedTwigleg
Copy link
Contributor Author

After way too many attempts to post the videos, the tweets are finally up: https://twitter.com/TwistedTwigleg/status/1427430507168600067

Huge thanks to everyone for helping make this possible 👍

swapped = true;
}
}
bonesptr[i].child_bones.clear();
Copy link
Contributor

@pouleyKetchoupp pouleyKetchoupp Aug 17, 2021

Choose a reason for hiding this comment

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

Doing the process in just one loop and removing the child bones for each bone is causing a regression when the bones are not sorted from root to leaves (if the root is last, all other bones are missing, since it removes its child bones).

Adding a first loop just for cleaning the child bones fixes the issue, but I wonder if there's a better solution (like sorting the bones beforehand).

You can reproduce the issue in @TokageItLab's project here: https://github.com/TokageItLab/3d-platform-test-for-godot4

Edit: tentative fix in #51798

@TokageItLab
Copy link
Member

TokageItLab commented Aug 18, 2021

This PR is causing a regression which the SkeletonGizmo is broken after the translation.
The problem is probably in the way the SkeletonGizmo updates, as SkeletonGizmo is transformed with skinning, so which requires the position may should to be calculated only at initialization, or it may be a mix-up between rest and pose.
However, in the first place, the skinning approach has problems with skew due to movement and scaling, so I think we will need to change to a better approach in the future.

CC @fire

2021-08-18.10.11.19-1.mov

@TokageItLab
Copy link
Member

The above broken gizmo problem fixed in #45699. At the same time, gizmo skew caused by translating and scaling is eliminated.

@TwistedTwigleg
Copy link
Contributor Author

TwistedTwigleg commented Aug 31, 2021

The above broken gizmo problem fixed in #45699. At the same time, gizmo skew caused by translating and scaling is eliminated.

Awesome! Thanks for fixing it and my apologies for accidentally breaking the old gizmo. I just ported/adjusted the code to work with the changes in the PR and didn’t realize it was broken (nor right off would I have an idea how to fix it even if I did notice). 😅

@TokageItLab
Copy link
Member

No problem! The octahedron drawing was unstable for a long time ago, so we needed to fix it anyway, and I hope that SkeletonGizmo will make IK easier to use :)

@ywmaa
Copy link
Contributor

ywmaa commented Dec 23, 2021

I need constraints in IK
I don't want my character's head to be twisted 180 degrees ;)

I don't know if I should open this as feature proposal
or here in the main Godot Repository

I opened issue here
godotengine/godot-proposals#3712

@TwistedTwigleg
Copy link
Contributor Author

Opening an issue on the Godot proposal repository, like you have done, is probably the best way to track this feature request 👍

@WuotanStudios
Copy link

Hey lovely people!

The modificationsstacks are really really great and very good to use :-D Thanks for the great work!

I hope my proposals are correctly placed here.
Since i work on an "opensource" human IK/Rig for Godot 4,
i have 2 proposals:

Proposal Nr. 1)
Bone ID should appear if mouse curser hovers over the bone name in the editor.
Problem: if i create IK's through modificationstack or i manipulate bones directly through a script it's currently a pain to find out the bone ID's.

My current workaround is that i am using a script, where i type the bone name to get the bone ID.
But it would be much better to show the bone ID when hovering over the bone name.

see picture:
image

Proposal Nr. 2)
when creating an IK using a target incl. activated "tip" function as good as always the target object rotates the bone in a weird way.
It would be great if the target recieves the bone rotation/position data first and gets adjusted that way,
as soon as the target gets defined.
After that adjustment the bone follows the target data.

i made her also a little workaround - see this tweet: https://twitter.com/WuotanStudios/status/1554773231420248064?s=20&t=lrVZCkoUoJUFmySLBS_6mA

You can find my "opensource project" called GodoDudeMannequin here on github:
https://github.com/WuotanStudios/GodoDudeMannequin

@Zireael07
Copy link
Contributor

@WuotanStudios: Proposals should be made at https://github.com/godotengine/godot-proposals

I think number 2 is a bug, btw.

@WuotanStudios
Copy link

@Zireael07 i don't think that 2 is a bug at all. IMO it's more like a missing function.

A real bug:
if i try to type a bone name inside a modification stack, when typing it writes from right to left.
E.g. if I enter "hand.L", the modificationstack says "L.dnah"

... btw, this was the main reason i made a workaround to find out the bone ID.

@TokageItLab
Copy link
Member

Note: ModificationStack has many design issues and will be refactored as Node by Beta.
#63588

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

Successfully merging this pull request may close these issues.