Class suggestion for new AnimSystem: BoneChannel

No, afaik it is applying in relative way that is controlled by transitionWeight.

“walk” will move joint A to some interpolated value between rotation 1 and rotation 2, location 1 and location 2.

“turn head” will move joint A to some separate interpolated value between rotation 1 and rotation 2, location 1 and location 2.

It won’t add it on top of the one from “walk”. It completely replaces the Vector3f and the Quaternion each time.

…unless for some reason “turn head” only does rotation or only does location and then it’s behaving exactly as it should.

From what I get, this is only when the weight is 1, otherwise, it will interpolate based on the local transform.

I guess I would need to understand what setup was trying to animate head turning on top of walk but only halfway. And either way, some layer is going to reset that transform every frame or there is already problems without layers or masks. (Edit: so it wouldn’t jump around, it would be consistently mixed.)

Someone needs to setup a full simple test case so we can see if the test case is crazy or the code is buggy.

1 Like

@yaRnMcDonuts can you try setting TransitionLength to 0 in both animations. You can do it with action.setTransitionLength(0).

It looks like this method is only available in the BlendAction class, but I’m still just using basic Actions for now. (I think I will want to use BlendAction to create a version of my walk and run animation to do a slower blend as the player accelerates, but for now I haven’t gotten that advanced.)

But I think I should clarify that when I talk about “blending” in the way I’ve been mentioning it in this thread, I’m referring to the default blending functionality that seems to automatically happens for a split second when you play any regular action so the model transitions clean from the last position.

When I’m working with just a walk and idle animation on the full rootMask, this default blending works really nice.

But as soon as I try to run other animations on other masks (i.e. a swing animation on the upper body while the lower body is standing or walking), it doesn’t seem to blend correctly every time.

To elaborate, here is a video showing the upperBody swinging while the lowerBody is playing the idle stand animation to sway her hips left and right. I eventually realized that if I start the swing animation when the character’s hips have just swayed to the right, then the animation will properly blend when its done. Otherwise, the blending is non-existent and it immediately jumps to the next frame of the stand animation when the swing is over:

https://i.imgur.com/9Ly1T5m.mp4

So this seems like it could definitely be a potential bug that comes out when working with more than one armature mask.

I also eliminated the bad twitching I mentioned earlier by getting rid of one of my armatureMasks for a weird situation where I was calling setTime() on a bend animation with 0 speed to bend the player’s waist and neck to look up/down based on the camera angle. This was just making all the bugginess with getting different masks/layers to work much worse so I’ll worry about that later. But the blending issue that my video displays is persisting even since I cleaned up some other things that were on my end.

No, it is also available in ClipAction because it extends BlendableAction.

You can cast the “walk” and “talk” actions to “ClipAction” and then call setTransitionLength(0) on it .

I tried to use this code right after setting the current action :

 animComposer.setCurrentAction(currentAnimation, layerName);
((BlendableAction)animComposer.getCurrentAction(layerName)).setTransitionLength(0.0);

But got this error saying it is a BaseAction and cannot be cast to BlendableAction:

java.lang.ClassCastException: class com.jme3.anim.tween.action.BaseAction cannot be cast to class com.jme3.anim.tween.action.BlendableAction (com.jme3.anim.tween.action.BaseAction and com.jme3.anim.tween.action.BlendableAction are in unnamed module of loader 'app')
	

I also figured out the cause of the blending issue shown in my video, but cannot figure out a way to solve it without causing another issue.

The underlying cause is that I’m calling setTime() on some layers still, and apparently that breaks the blending because whenever I remove those calls the blending works perfect.

However, I need to call setTime() on the upper body once it is done swinging to make the time of the animation match the time of the legs. Otherwise, the upper body and lower body are both playing the same idle animation out of sync and it distorts the animation.

So I need to figure out a way to be able to call animComposer.setTime(layerName, time) without it randomly breaking the blending sometimes.

I just realized you said to cast to ClipAction instead of BlendableAction, my mistake. It doesn’t throw the casting error when I do it correctly as you said, but the blending issue still appears to be there.

I think it will help a lot if you can provide us with a simple test case we can run.

1 Like

For a test model, if you need one…

The reason I feel like masking is supposed to work the way we expect is because when nehon and I were working on a game together, he added the “aim up” and “aim down” animations so that we could layer them over walk/run to use this model before the real model was ready. And I’m 99% sure he told me I just had to make sure the armature mask only applied to the upper body.

…so even in his mind, I should be able to have a layer the simply overrode the main layer.

1 Like

I will try a bit more to fix the issue by doing it the way you describe worked for you, and if I still am unable to figure it out afterwards then I will make a test case.

One question I have before my next attempt: what do you do to end the aim up/down animation and to prevent it from looping? I suspect that if I can properly end the animation on the upperBody while the rootMask is still playing walk, it will blend back to the animation playing on the rootMask correctly and function like you’re describing.

Previously I tried this using a done tween to remove the action from playing on that layer and also by setting speed to 0, but both caused some other bugginess that’s much worse than where I’m at as of my last video, so I removed the on-finish tweens and am no longer trying to do anything at the end of a non-looping animation, I just let have the upper body mask play the next animation over the last instead of trying to cancel the previous to make the upper mask blank (which is why I must call setTime(), because it is possible the upper body tries to resume walking but has its time out of sync with the lower body)

I never got around to trying it. I’m only saying that the original author of the new animation system also seemed to indicate that it should work this way.

the up down animations are meant to be blended together and it’s fine that they loop as they are only one frame each.

1 Like

this was really helpful to read-thank you for the insight.

hope everyone is having a nice day :palm_tree:

1 Like