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

Is there an equivalent of springBoneManager.setCenter from three-vrm v0.6 in the latest version? #1112

Open
ButzYung opened this issue Nov 19, 2022 · 16 comments
Assignees

Comments

@ButzYung
Copy link

ButzYung commented Nov 19, 2022

In v0.6 of three.vrm, there is the springBoneManager.setCenter function which allows offseting the spring bones center. This is useful in my case when I have to do something like

springBoneManager.setCenter(vrm_mesh)

to prevent the spring bones from jumping crazy (I don't know what causes the crazy spring movements. Maybe it's because vrm_mesh is far away from (0,0,0), or maybe it's because vrm_mesh is scaled).

However, in v1.0 of three-vrm, this function is gone and I can't find an equivalent.

@0b5vr
Copy link
Contributor

0b5vr commented Nov 22, 2022

mmm, I'm not sure why I removed the interface. Maybe it's because the early VRM 1.0 beta versions did not have the center.
We might consider re-adding the method.

For now, as a workaround, you can iterate over VRMSpringBoneManager.springBones and manually set its VRMSpringBoneJoint.center.

@0b5vr 0b5vr self-assigned this Nov 22, 2022
@0b5vr
Copy link
Contributor

0b5vr commented Nov 22, 2022

The implementation of setCenter in v0.x:

/**
* Set all bones be calculated based on the space relative from this object.
* If `null` is given, springbone will be calculated in world space.
* @param root Root object, or `null`
*/
public setCenter(root: THREE.Object3D | null): void {
this.springBoneGroupList.forEach((springBoneGroup) => {
springBoneGroup.forEach((springBone) => {
springBone.center = root;
});
});
}

@ButzYung
Copy link
Author

ButzYung commented Nov 22, 2022

@0b5vr I tried to implement something like the previous .setCenter, but it doesn't work exactly like it was before.

springBoneManager.constructor.prototype.setCenter = function (obj3d) {
  this.joints.forEach(joint=>{
    joint.center = obj3d;
  });
};

It doesn't change much and the springs are still jumping more than usual. By trial and error, I have to add the following to make it behave more like the old version.

springBoneManager.reset();
springBoneManager.setInitState();

But still it doesn't look exactly like the old version. The spring movement looks normal this time, but the colliding behavior appears to be missing.

@0b5vr
Copy link
Contributor

0b5vr commented Nov 28, 2022

Mmmmm, I thought I had fixed that behavior once before...

I have to investigate this.

@0b5vr
Copy link
Contributor

0b5vr commented Dec 12, 2022

@ButzYung Could you provide a demo that behaves wrong with your colliders? I have tested on my end and could not point to any issues.

@ButzYung
Copy link
Author

ButzYung commented Dec 12, 2022

@0b5vr I don't have a demo right now, but after some further testings, I can confirm the problem comes from scaling the VRM mesh (I am scaling the mesh up by roughly 10 times, something like mesh.scale(10,10,10). If I don't touch the scale, everything is normal. If I scale the mesh up, the physics becomes crazy as if every rotation is maginifed by the scale. .setCenter fixes the problem for three-vrm v0.6, but not v1.0. In v1.0, the spring movements work with my above fix, but the colliding behavior is totally gone.

@0b5vr
Copy link
Contributor

0b5vr commented Dec 13, 2022

scale! got it. will try to reproduce.

@0b5vr
Copy link
Contributor

0b5vr commented Dec 13, 2022

@ButzYung When do you want to change the scale of meshes?

If it's in initializing, how about hitting vrm.springBoneManager.setInitState() after you have prepared your scene (including setting the scale to the model)?, because it's dependent on world matrices of objects.

Honestly, I found that setting the scene with scales is difficult even for me 😅
I might write dedicated documentation for this topic or improve the API.

@0b5vr
Copy link
Contributor

0b5vr commented Dec 13, 2022

And also, to explain why we don't have SpringBoneManager.setCenter() in v1.0,
Some VRM files have their own settings of centers which reduce excessive spring behavior of certain bones.
Such settings should not be overwritten by the application side.

And, we are yet to come up with any reasonable API to achieve that process so far.
I think it's a topic that we have to cover in our documentation at least.

@0b5vr
Copy link
Contributor

0b5vr commented Dec 13, 2022

I'm trying to improve the usability of scale + SpringBone setups in a PR:
#1132

@ButzYung
Copy link
Author

I change the scale of the mesh right after the model is loaded, and it basically never changes again afterwards. Changing the scale before or after adding the model to three.scene, and where .setInitState()/.setCenter() is placed doesn't seem to make any difference. I think I should give up fixing it on my app side and simply wait for your fix on the new PR lol

@0b5vr
Copy link
Contributor

0b5vr commented Dec 14, 2022

@ButzYung I've released v1.0.7-alpha.0 on npm, which includes the changes of #1132. Could you try that?

https://www.npmjs.com/package/@pixiv/three-vrm/v/1.0.7-alpha.0

@ButzYung
Copy link
Author

ButzYung commented Dec 14, 2022

I have tested with your latest v1.0.7-alpha.0 with mesh scaled up.

  • If I don't do anything extra (i.e. no .setCenter() .reset() .setInitState()), the spring motion is like the opposite of v1.0.5 (which is very fast). Now it's like 10 times slower than usual as if the character is moving in space with very low gravity.
  • If I add .setCenter(), everything looks normal again (i.e. no need for .reset() and .setInitState(), and that's an improvement).

Talking about the colliding behavior, I wonder if I have a misunderstanding of how it works, or there may actually be something wrong with the current implementation in v1.0...? I have tried your three-vrm example.

https://pixiv.github.io/three-vrm/packages/three-vrm/examples/humanoidAnimation/index.html

with the Alicia VRM model

https://3d.nicovideo.jp/works/td32797

and dance motion from Mixamo such as this one

https://www.mixamo.com/#/?page=1&query=Capoeira

When Alicia dances, her legs pass through her skirt with no physical interaction, as if the skirt colliders don't exist. Is it supposed to be like that? I tried v0.6 in my own project with other motions, and the colliding behavior was visible (still far from perfect as legs passing through skirts still occur, but at least the colliding interaction is more noticable).

@0b5vr
Copy link
Contributor

0b5vr commented Dec 27, 2022

@ButzYung I've pushed a new document describing spring bone behavior under scaled VRM models. Does it help?

https://github.com/pixiv/three-vrm/blob/improve-springbone/docs/spring-bones-on-scaled-models.md

@ButzYung
Copy link
Author

@0b5vr I am using v1.0.7-alpha.0 along with your new fixes, and this seems to solve the problem. I hope the colliding behavior could be more sensitive to avoid skirt pass-thru, but at least the current behavior is visibly the same as v0.6 (with .setCenter).

@0b5vr
Copy link
Contributor

0b5vr commented Jan 6, 2023

I hope the colliding behavior could be more sensitive to avoid skirt pass-thru

That's another problem we have to fix from the spec side ground-up.

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

No branches or pull requests

2 participants