Animations

Started by
1 comment, last by Gabris 3 years, 8 months ago

Hello I been struggling to figure out how to implement skeleton animations using Assimp

I been following openGl tutorial: http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.html​

Any help greatly appreciated.

Loading Bones:

void AssimpLoader::LoadBones(aiMesh* mesh)
{
	bones.resize(mesh->mNumVertices);

	for (int i = 0; i < mesh->mNumBones; i++)
	{
		int BoneIndex = 0;
		std::string BoneName(mesh->mBones[i]->mName.data);
		if (mBoneMapping.find(BoneName) == mBoneMapping.end())
		{
			BoneIndex = mNumBones;
			mNumBones++;
			BoneInfo bi;
			mBoneInfos.push_back(bi);
		}
		else
		{
			BoneIndex = mBoneMapping[BoneName];
		}
		aiTransposeMatrix4(&mesh->mBones[i]->mOffsetMatrix);
		mBoneInfos[BoneIndex].boneOffset = Utility::aiMtoxmM((mesh->mBones[i]->mOffsetMatrix));
		mBoneMapping[BoneName] = BoneIndex;

		for (int x = 0; x < mesh->mBones[i]->mNumWeights; x++)
		{
			int VertexID = mesh->mBones[i]->mWeights[x].mVertexId;
			float Weight = mesh->mBones[i]->mWeights[x].mWeight;

			bones[VertexID].AddBoneData(BoneIndex, Weight);
		}
	}

}
	void ReadNodeHeirachy(float animationTime, const aiNode* pNode, const XMFLOAT4X4& parentTransform)
	{
		std::string nodeName(pNode->mName.data);
		const aiAnimation* pAnimation = scene->mAnimations[0];
		

		XMFLOAT4X4 NT = Utility::aiMtoxmM(pNode->mTransformation);
		
		XMMATRIX nodeTransform = XMLoadFloat4x4(&NT);
		
		const aiNodeAnim* pNodeAnim = animNodes[nodeName];
		if (pNodeAnim)
		{
			XMFLOAT3 Scaling;
			CalcInterpolatedScaling(Scaling, animationTime, pNodeAnim);
			XMMATRIX ScalingMatrix = XMMatrixScaling(Scaling.x, Scaling.y, Scaling.z);

			aiQuaternion RotationQuat;
			CalcInterpolatedRotation(RotationQuat, animationTime, pNodeAnim);
			XMMATRIX RotationMatrix = XMMatrixRotationQuaternion(XMVectorSet(RotationQuat.x, RotationQuat.y, RotationQuat.z, RotationQuat.w));

			XMFLOAT3 Position;
			CalcInterpolatedPosition(Position, animationTime, pNodeAnim);
			XMMATRIX PositionMatrix = XMMatrixTranslation(Position.x, Position.y, Position.z);
			XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
			
			nodeTransform = ScalingMatrix * RotationMatrix * PositionMatrix;
		}




		XMMATRIX globalTransf = nodeTransform * XMLoadFloat4x4(&parentTransform);

		if (mBoneMapping.find(nodeName) != mBoneMapping.end())
		{
			int BoneIndex = mBoneMapping[nodeName];
			XMMATRIX boneoffset = XMLoadFloat4x4(&mBoneInfos[BoneIndex].boneOffset);
			XMMATRIX finaltransf = boneoffset * globalTransf;
			
			XMStoreFloat4x4(&mBoneInfos[BoneIndex].FinalTransform,XMMatrixTranspose(finaltransf));
		}

		for (UINT i = 0; i < pNode->mNumChildren; i++)
		{
			XMFLOAT4X4 GT; XMStoreFloat4x4(&GT, globalTransf);
			ReadNodeHeirachy(animationTime, pNode->mChildren[i], GT);
		}

	}

Advertisement

After some Tweaking i was able to make the animation move but the skin is all stretched

This is the code i have so far

void ReadNodeHeirachy(float animationTime, const aiNode* pNode, const XMFLOAT4X4& parentTransform)
	{
		std::string nodeName(pNode->mName.data);
		const aiAnimation* pAnimation = scene->mAnimations[0];
		aiMatrix4x4 trans = pNode->mTransformation;
		aiTransposeMatrix4(&trans);

		XMFLOAT4X4 NT = Utility::aiMtoxmM(trans);
		
		XMMATRIX nodeTransform = XMLoadFloat4x4(&NT);
		
		const aiNodeAnim* pNodeAnim = animNodes[nodeName];
		if (pNodeAnim)
		{
			XMFLOAT3 Scaling;
			CalcInterpolatedScaling(Scaling, animationTime, pNodeAnim);
			XMMATRIX ScalingMatrix = XMMatrixScaling(Scaling.x, Scaling.y, Scaling.z);

			aiQuaternion RotationQuat;
			CalcInterpolatedRotation(RotationQuat, animationTime, pNodeAnim);
			XMMATRIX RotationMatrix = XMMatrixRotationQuaternion(XMVectorSet(RotationQuat.x, RotationQuat.y, RotationQuat.z, RotationQuat.w));

			XMFLOAT3 Position;
			CalcInterpolatedPosition(Position, animationTime, pNodeAnim);
			XMMATRIX PositionMatrix = XMMatrixTranslation(Position.x, Position.y, Position.z);
			XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
			
			nodeTransform = ScalingMatrix * RotationMatrix * PositionMatrix ;
		}




		XMMATRIX globalTransf = nodeTransform * XMLoadFloat4x4(&parentTransform);

		if (mBoneMapping.find(nodeName) != mBoneMapping.end())
		{
			int BoneIndex = mBoneMapping[nodeName];
			XMMATRIX boneoffset = XMLoadFloat4x4(&mBoneInfos[BoneIndex].boneOffset);
			XMMATRIX finaltransf = boneoffset * globalTransf;
			
			XMStoreFloat4x4(&mBoneInfos[BoneIndex].FinalTransform,XMMatrixTranspose(finaltransf));
		}

		for (UINT i = 0; i < pNode->mNumChildren; i++)
		{
			XMFLOAT4X4 GT; XMStoreFloat4x4(&GT, globalTransf);
			ReadNodeHeirachy(animationTime, pNode->mChildren[i], GT);
		}

	}

If i remove this piece of code the skin looks normal so i believe i am multiplying the nodeTransform by the wrong thing. I can't figure it out.

		if (pNodeAnim)
		{
			XMFLOAT3 Scaling;
			CalcInterpolatedScaling(Scaling, animationTime, pNodeAnim);
			XMMATRIX ScalingMatrix = XMMatrixScaling(Scaling.x, Scaling.y, Scaling.z);

			aiQuaternion RotationQuat;
			CalcInterpolatedRotation(RotationQuat, animationTime, pNodeAnim);
			XMMATRIX RotationMatrix = XMMatrixRotationQuaternion(XMVectorSet(RotationQuat.x, RotationQuat.y, RotationQuat.z, RotationQuat.w));

			XMFLOAT3 Position;
			CalcInterpolatedPosition(Position, animationTime, pNodeAnim);
			XMMATRIX PositionMatrix = XMMatrixTranslation(Position.x, Position.y, Position.z);
			XMVECTOR zero = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
			
			nodeTransform = ScalingMatrix * RotationMatrix * PositionMatrix ;
		}
After removing the interpolation

Seems interesting. Thanks. I usually use home assignment help service for this https://assignmentyoda.com/home/disclosure/

This topic is closed to new replies.

Advertisement