Sign in to follow this  

Skinned Animation System acting funny! Help

This topic is 405 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey Guys!
 
So i am building a custom c++ engine for my game but the skinned animation system is acting funny the animation is not acting correctly 
I am thinking it has to do with the Joint Hierarchy maybe not been applied correctly during the skinned animation process and the joint poses are not set to the correct space, but at first glance what do you guys think the problem could be and what should i look at to fix it?

 

This would be the way its suppose to work (This are GIFs so click them so they can animate)

[attachment=33840:Animation_Walk.gif]

 

This is the way it actually shows up in game  (This are GIFs so click them so they can animate)

[attachment=33841:Wrong_Walk_Animation.gif]

 

Here is some of the animation code

Animation* Current_Animation = _Model->GetAnimation(_AnimName);

	Mesh* TempMesh = _Model->GetMesh();

	//Final Vector with animation Updated Vertex Positions
	vector<FLOAT4X4> CurrentPoses = ProcessChannels(Current_Animation,_DT);
	vector<Vector_Struct> FinalVertexs;
	for (unsigned int i = 0; i < _Model->GetOrgVertexs().size(); i++)
	{
		Vector_Struct vSum = {};

		for (unsigned int x = 0; x < TempMesh->The_Influences[i].size(); x++)
		{
			int JointIndex = TempMesh->The_Influences[i][x].joint_index;
			float Weight = TempMesh->The_Influences[i][x].weight;

			FLOAT4 CurrentVertexOffset = {};
			FLOAT4 Result = {};
			FLOAT4X4 BindPoseInverse = {};

			//Get the inverse bind pose to but the vertex into the correct space
			FLOAT4X4 Bind_Pose = TempMesh->The_Joints[JointIndex].bind_pose_transform;
			BindPoseInverse = Math::GetInstance()->FLOAT4X4Inverse(Bind_Pose);
			//Put the Original Vertex into the correct space
			CurrentVertexOffset = _Model->GetOrgVertexs()[i].Position * BindPoseInverse;
			//Get the pose for the current animation frame
			FLOAT4X4 pose = CurrentPoses[JointIndex];// Current_Animation->channels[JointIndex].keys[CurrentKey].node;
			//apply the pose to the updated vertex
			Result = CurrentVertexOffset * pose;

			//affect the Vertex by the correct weight and apply the result affected by the weight into the complete vertex for the final version
			Result *= Weight;
			vSum.Position += Result;
		}
		//add it into the vector
		FinalVertexs.push_back(vSum);
	}


	for (unsigned int i = 0; i < FinalVertexs.size(); i++)
	{
		_Model->GetVertexs()[i].Position = FinalVertexs[i].Position;
	}

	UpdateVertexBuffer = false;
	_Model->SetAnimated(true);
Edited by Continuous_Dreamer

Share this post


Link to post
Share on other sites

It looks like the joints are upside down as if the shoulders are by the feet and the hip joint is between the feet rather than above them, but it does look like they are doing the correct rotations just around joints in the wrong positions.

 

Can you confirm if the joints are in the correct(ish) position? Should be easy to see if the shoulders are where they should be rather than by the feet, once you have updated your vertex positions. If they are we then know we should be looking at if the rights joints are being used with/to create the right rotations.

Share this post


Link to post
Share on other sites

Your right! :D

the joints are in incorrect positions also i decided to make a shoulder shrug animation and once imported into the engine nothing happens meaning the model doesn't animate at all

 

which makes me think that the hand joints are not taking the shoulder joints into account at all

 

i also found out that the shoulders are actually by the feet in the engine version of the model.

 

Do you think this mean i am not taking the joint hierarchy correctly? or that maybe the model was rigged incorrectly?

 

thanks for the help btw

Edited by Continuous_Dreamer

Share this post


Link to post
Share on other sites

So the first thing you need to look at is why are the positions incorrect in your engine, once you found that out it should be easier to work out why the hand joints are not taking the shoulder joints into account.

 

the joints are in incorrect positions

 

The first thing I would do is check that when you load your model that the positions are correct?

If so, look at anything that updated/modifies those positions - for example does 'BindPoseInverse = Math::GetInstance()->FLOAT4X4Inverse(Bind_Pose);' or other functions return what your expecting?

If that all looks fine, check how your uploading that data to the GPU. Are the buffers being created and filled correctly?

If that looks correct, check your shaders. Although if it is the vertex shader I would have thought the whole model would be inverted.

 

 

which makes me think that the hand joints are not taking the shoulder joints into account at all

 

For this, you need to get the parent joint (I'm guessing you're storing it as a matrix) and include (multiplication) that when you are translating or rotating a child joint. For example, the shoulders move so the hands need to know where the shoulders are now when they are moving.

Share this post


Link to post
Share on other sites

FIXED IT! 

 

Thanks for the help LWard!  :D

 

The problem was that i was using the wrong math operation here 

CurrentVertexOffset = _Model->GetOrgVertexs()[i].Position * BindPoseInverse;

 were this is taking into account the FLOAT4 w value which isnt needed which therefore messed up all of the other values all i had to do was 

do the operation as if it was a FLOAT3 

CurrentVertexOffset = Math::GetInstance()->FLOAT3Transform(_Model->GetOrgVertexs()[i].Position, BindPoseInverse);

and everything started working great!  :D

Edited by Continuous_Dreamer

Share this post


Link to post
Share on other sites

This topic is 405 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this