Advertisement

Animation translation as player position

Started by December 21, 2023 09:54 PM
2 comments, last by Juliean 11 months ago

Hi,

I am working on implementing animation and I am quite confused on a specific area. I have a turn animation which turns the player but it also has translation data. Once the animation finishes, it snaps back to the original position it started from instead of remaining where it finished the animation. I am wondering how you handle animation translation and how you can keep the animations position as the new player position once the animation has finished.

Currently I am applying the translation data per frame to the Root bone.

// This will find the new rotation and translation data for the current frame
// you get back a pair which gives .first as rotation and .second and translation
std::pair<Quaternion, vec3> updatedPose = NewPose(frame, time_in_seconds, scale, joint->id);
Mat4 rotationMatrixFromQuat = updatedPose.first.ToRotationMatrix();

vec4 offsetFromParent = vec4(jointOffsetX, jointOffsetY, jointOffsetZ, 1.0f);

if(joint->jointName == "Root")
{
	offsetFromParent.x = updatedPose.second.x;
	
	  /* There is y-translation, but this makes animations go up and down between transitions. I am not sure how to handle this. */
	//offsetFromParent.y = updatedPose.second.y;

	offsetFromParent.z = updatedPose.second.z;
}

This is the current result I am getting where the animations turns but snaps back to the place it started instead of remaining where it was.

Well, animation just sucks. :D

I would go to the artist, tell i can't use the animation this way, and ask him to fix it so the character always walks on spot.

If that's not possible, i would try to preprocess the animation to fix it myself. However, then we need to answer where this ‘spot’ should be, which is not trivial.

One option is to use the center of mass to define a spot. You give each bone a mass, ideally looking up some reference data about average mass distribution for the average human body. You might need this to set up ragdolls anyway.
Then you can project the com down to the ground plane, which usually is well defined for animations. Then you preprocess the animation so this spot is always at the origin.
(You want to preprocess anyway, to convert Euler angles into quaternions upfront. You should not do this conversation at runtime for each frame and every bone like you currently do, because that's a lot of redundant matrix multiplies and trig.)

However, if you do this, you will notice it's not ideal.
The com is not good to defiene a spot on round, because the com wobbles while we walk. To lift the right leg, you first need to move the com over the left leg. So the com tends to be over the 'stance leg'. It moves left and right as we do steps with alternating feet.
This gives a better idea: You find the foot that is actually closer to the projected com, and then you use this foot for your desired ground spot. (If your foot has two bones, heel and toe, i propose to use the joint position between those bones, because this point is usually always in contact with the ground, no matter if the heel rolls up or not.)

But sadly this gives us a new problem: Now our spot jumps between the left and right foot, so the whole character jumps. To make it work, we would need to know where we place our next step. But we don't know this, and that's actually a big reason why we use this damn animation data at all.
So probably we go back to the com approach, but eventually we can use our method to predict contact to do some refinements.
I fail to imagine how it would work all out, and can't do better proposals at this point.
And we have not even talked about something like a ‘forwards orientation’, which we need just as much as a ‘spot on ground’, especially if the character turns..
It's surely some work and research to make this work, and maybe that time is better spend elsewhere.

So i give up, and fall back to the artist request. They spend millions on mocap and hire Keanu, and they do manual post processing to clean up captured data anyway, So it's their job to get those things right. It's a content creation problem imo.

Advertisement

The generic solution to your problem is commonly called “root motion" (https://docs.unrealengine.com/4.27/en-US/AnimatingObjects/SkeletalMeshAnimation/RootMotion/​ , https://docs.unity3d.com/Manual/RootMotion.html).

I have no experience in implementing it myself, only used it in the various engines. It seems to have requirements for how the animation needs to be setup, but given those requirements are fulfilled (and you find a good source for how to implement it) you should be able to use the animation you have and create a character-motion based on it.

This topic is closed to new replies.

Advertisement