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 ;)
Edited by Inukai, 09 June 2012 - 05:11 PM.






