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

VRMC_node_constraint malfunctions on some rigs #71

Open
lyuma opened this issue Aug 4, 2023 · 4 comments
Open

VRMC_node_constraint malfunctions on some rigs #71

lyuma opened this issue Aug 4, 2023 · 4 comments
Labels
bug Something isn't working

Comments

@lyuma
Copy link
Member

lyuma commented Aug 4, 2023

It seems to rotate the bone the wrong way relative to the origin. Likely one of the bone diff matrices is not being applied correctly.

image

Example VRM file showing the problem: VRM1_Constraint_Twist_Sample.vrm
You must select LeftUpperArm in the inspector on GeneralSkeleton, and rotate it using the gizmo to observe the constraint rotation: the constraint does not update unless the bone is posed.

It seems to be a coordinate axis issue related to retarget: for example, if I rotate the arm to point straight up, then the sleeve sticks to the side as it would have been expected in the t-pose.

@lyuma
Copy link
Member Author

lyuma commented Aug 4, 2023

@aaronfranke I'm worried this issue is caused by the roll axis being an enum rather than a Vector3, as in:

enum AimRollAxis {
	NONE = 0,
	POSITIVE_X = 1,
	POSITIVE_Y = 2,
	POSITIVE_Z = 3,
	NEGATIVE_X = 4,
	NEGATIVE_Y = 5,
	NEGATIVE_Z = 6,
}

Since we're rotating bones as part of retargeting, is it possible that the constraint can no longer be representable after the retargeting process...

Normally, I pass the quaternion or basis that represents the diff which happened during retarget and multiply it by vectors/axes or matrices. But in this case, I can't multiply this enum by that matrix, so I'm not sure what to do...

For example, let's say the arm's y axis is pointing 45 degrees down, as in an A-Pose, but the model is in a T-pose, so we re-create the bone axes using the SkeletonProfile. Now the constraint specifies a roll axis as +X or +Z.... how we do rotate that to the correct axis? Is this solvable by adding a child bone?

@fire
Copy link
Member

fire commented Aug 4, 2023

A vector3 can be used if not we'll have to decompose to three axes as nodes.

@aaronfranke
Copy link
Contributor

aaronfranke commented Aug 4, 2023

The enum is designed to represent the data in the VRM spec, which can be "X", "Y", or "Z" for the roll constraint. While we could convert this to Vector3, that would not be something we can re-export because it does not match VRM. Also, this logic is hard-coded for roll around just one of these axes, matching what VRM allows.

But anyway, I doubt changing the enum is the solution. I have not looked into this deeply but I would recommend trying to have the retargeter adjust the source_rest_transform and target_rest_transform values instead. These values are set during import and are what the constraint is relative to, so they are likely no longer correct after the retargeter does its thing. See the _get_posed_source_transform and _set_weighted_posed_target_rotation methods.

This is where I was setting it on my PR https://github.com/aaronfranke/godot-vrm/blob/node_constraint/addons/vrm/node_constraint/vrm_node_constraint_doc_ext.gd#L39 I don't know where you moved this code to. EDIT: Oh, it's in addons/vrm/1.0 now, I don't know why it was separated from the rest of the constraint code.

@fire
Copy link
Member

fire commented Aug 31, 2023

@lyuma What's the approach to fixing this?

@fire fire added the bug Something isn't working label Sep 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants