Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Inukai

Member Since 11 Jan 2012
Offline Last Active Today, 04:52 AM
*----

Topics I've Started

wrong(?) bone matrices in animation

09 June 2012 - 05:10 PM

hi guys.
I'm new to 3d-programming and need help with my game.

I exported a fbx model into my own file format and want to load it in my game.
I managed to load all the data from my file and load it into my model class.

I also checked the skinning10 example and managed to create an effect file:
effect.fx:

Texture2D colorMap_ : register( t0 );
SamplerState colorSampler_ : register( s0 );

cbuffer cbChangesEveryFrame : register( b0 )
{
	matrix worldMatrix;
};
cbuffer cbNeverChanges : register( b1 )
{
	matrix viewMatrix;
};
cbuffer cbChangeOnResize : register( b2 )
{
	matrix projMatrix;
};
cbuffer cbBoneMatrix : register( b3 )
{
	  Matrix boneMat[100];
};
struct VS_Input
{
	float4 pos  : POSITION;
	float2 tex0 : TEXCOORD0;
	uint4 bones : BONES;
	float4 weights : WEIGHTS;
};
struct PS_Input
{
	float4 pos  : SV_POSITION;
	float2 tex0 : TEXCOORD0;
};

PS_Input VS_Main( VS_Input vertex )
{
	PS_Input vsOut = ( PS_Input )0;

float4 vertexPos = 0;
  
   int boneId = vertex.bones[0];
   if(vertex.weights[0] > 0) vertexPos += vertex.weights[0]  * mul(boneMat[boneId],vertex.pos);
   boneId = vertex.bones[1];
   if(vertex.weights[1] > 0) vertexPos += vertex.weights[1]  * mul(boneMat[boneId],vertex.pos);
   boneId = vertex.bones[2];
   if(vertex.weights[2] > 0) vertexPos += vertex.weights[2]  * mul(boneMat[boneId],vertex.pos);
   boneId = vertex.bones[3];
   if(vertex.weights[3] > 0) vertexPos += vertex.weights[3]  * mul(boneMat[boneId],vertex.pos);

  
	vsOut.pos = mul( vertexPos, viewMatrix );
	vsOut.pos = mul( vsOut.pos, projMatrix );
	vsOut.tex0 = vertex.tex0;
	return vsOut;
}

float4 PS_Main( PS_Input frag ) : SV_TARGET
{
	return colorMap_.Sample( colorSampler_, frag.tex0 );
}

method to play the animation and create the bone matrices
bool Model::PlayAnimation(std::string aniName)
{
aniName = _animations[0].getName();	//fixed for testing
static int cnt = 0;	  //counter for the keyframes
for(int i = 0; i<_numberOfAnimations; i++)
{
  if(_animations[i].getName() == aniName)
   _currentAni = i;
}

int boneId = 0;	
XMFLOAT4X4 matrix;
XMFLOAT3 rot;
XMFLOAT3 transl;
XMFLOAT3 scal;

//set the world matrix (put it into the root bone)
XMStoreFloat4x4(&matrix, XMMatrixRotationRollPitchYaw(90*PI/180, 0*PI/180, 0*PI/180));
_bones[0].setWorldMatrix(matrix);

//root bone is at i = 0 and bones are sorted so that the parents are called before their childs alwaya
for(int i= 0; i<_numberOfBones; i++)
{
  //get the information from the animation class, I controlled the values, they are right.
  boneId = _animations[_currentAni].getKeyFrames()[i].getBoneId();
  rot	= XMFLOAT3(_animations[_currentAni].getKeyFrames()[i].getRotation()[cnt][0], _animations[_currentAni].getKeyFrames()[i].getRotation()[cnt][1], _animations[_currentAni].getKeyFrames()[i].getRotation()[cnt][2]);
  transl = XMFLOAT3(_animations[_currentAni].getKeyFrames()[i].getTranslation()[cnt][0], _animations[_currentAni].getKeyFrames()[i].getTranslation()[cnt][1], _animations[_currentAni].getKeyFrames()[i].getTranslation()[cnt][2]);
  scal   = XMFLOAT3(_animations[_currentAni].getKeyFrames()[i].getScaling()[cnt][0], _animations[_currentAni].getKeyFrames()[i].getScaling()[cnt][1], _animations[_currentAni].getKeyFrames()[i].getScaling()[cnt][2]);

  //multiply the matrices into the matrix variable
  XMStoreFloat4x4(&matrix,  XMMatrixTranslation(transl.x, transl.y, transl.z));
  XMStoreFloat4x4(&matrix, XMLoadFloat4x4(&matrix)*XMMatrixRotationRollPitchYaw(rot.x*PI/180, rot.y*PI/180, rot.z*PI/180));
  XMStoreFloat4x4(&matrix, XMLoadFloat4x4(&matrix)* XMMatrixScaling(scal.x, scal.y, scal.z));
  _bones[i].setBoneMatrix(matrix, _bones);
  XMStoreFloat4x4(&_boneMatrix[boneId], _bones[i].getPoseMatrix());
}
cnt++;
if(cnt>=20)
{
  cnt = 0;
}
return true;
}

And here are the 3 methods in my bone class:

void setWorldMatrix(XMFLOAT4X4 mat)
{
  _worldMatrix = mat;
}

//get calculated values from the playAnimation method and put it as world matrix for the children
void setBoneMatrix(XMFLOAT4X4 mat, Bone* children)
{
  XMStoreFloat4x4(&_boneMatrix, (XMLoadFloat4x4(&mat)));


  for(int i = 0; i<_numberOfChildren; i++)
  {
   children[_children[i]].setWorldMatrix(mat);
  };
  return;
};

//will be stored in the bonebuffer for the hlsl file
XMMATRIX getPoseMatrix() { return (XMLoadFloat4x4(&_boneMatrix)* XMLoadFloat4x4(&_worldMatrix)); };


My Problem is, that one of my models got strange graphic artifacs (he looks like he is exploded) (human-like with 40 bones, he is moving...kinda)
And the other model(snake like with 2 bones) isn't even moving. (well, the root bone is probably right, but the tail isn't moving(it shoulld move up and down))
Both models are rendered correct when i set the boneMatrices for the hlsl file only on Matrix.Identity(). The hirachy should be right aswell, because I can change the worldMatrix for the root bone and all vertices are moving.

I'm kinda new to 3d programming and I guess I failed with the matrix calculations.
I'll attach the screens of the models. I count on you guy ;)

Posted Image

Model got no depth?

21 May 2012 - 03:03 PM

Hi guys,
I'm quite new to Directx 11 and tried to load my model.
However, I got a problem with its rendering. It looks like my model got no depth(look at his hands, feet, head), even though I got a depth/stencil buffer.


Posted Image
My importer works with less complex models.

Am i missing something?
What could cause this?

I hope you guys can help me ;)

PARTNERS