Vertex Skinning

Started by
-1 comments, last by PyemanKOP 7 years, 9 months ago

I'm working on vertex skinning by loading animation data from compiled model objects(.CMO) that visual studio generates from .FBX models.

here is what i have:

Untitled.png

This is totaly wrong but i dont know why!

here is my code for rendering animations:




for (auto it = model->meshes.cbegin(); it != model->meshes.cend(); ++it)
{
auto mesh = it->get();
if (mesh->enableSkinning)
{
for (int i = 0;i < mesh->bones.size();i++)
{
mesh->armatureBuffer.Const.Bones[i]= mesh->bones[i]->LocalTransform;
}


//Animate
Keyframe * lastKeyForBones = 
new Keyframe[mesh->bones.size()];


bool *lerpedBones = new bool[mesh->bones.size()];
for (int i = 0;i < mesh->bones.size();i++)
{
//lerpedBones[i] = false;
}
for (int i = 0;i < mesh->animationClips[1]->Keys;i++)
{
Keyframe * frame =
mesh->animationClips[1]->keyFrames[i];
if (elapsedTime >= frame->Time)
{
lastKeyForBones
[frame->BoneIndex]
= *frame;


mesh->armatureBuffer.Const.Bones
[frame->BoneIndex] =
frame->Transform;
}
else
{
if (!lerpedBones
[frame->BoneIndex])
{
Keyframe * prevFrame;
if (&lastKeyForBones
[frame->BoneIndex] != nullptr)
{
prevFrame =
&lastKeyForBones[frame->BoneIndex];
}
else
continue;


lerpedBones[frame->BoneIndex] = true;
float lenght = frame->Time
- prevFrame->Time;
float timeDiff = elapsedTime - prevFrame->Time;
float amount = timeDiff / lenght;
DirectX::XMVECTOR t1, t2, s1, s2, r1, r2;
DirectX::XMMatrixDecompose(
&s1, &r1, &t1,
DirectX::XMLoadFloat4x4
(&prevFrame->Transform));


DirectX::XMMatrixDecompose(
&s2, &r2, &t2,
DirectX::XMLoadFloat4x4
(&frame->Transform));


DirectX::XMVECTOR lerpedScale =
DirectX::XMVectorLerp(s1, s2, amount);


DirectX::XMVECTOR lerpedtranslation =
DirectX::XMVectorLerp(t1, t2, amount);


DirectX::XMVECTOR lerpedrotation =
DirectX::XMQuaternionSlerp(r1, r2, amount);


DirectX::XMStoreFloat4x4
(&mesh->armatureBuffer.Const.Bones
[frame->BoneIndex],
DirectX::XMMatrixScaling(
lerpedScale.m128_f32[0],
lerpedScale.m128_f32[1],
lerpedScale.m128_f32[2])
*
DirectX::XMMatrixRotationQuaternion(
lerpedrotation)
*
DirectX::XMMatrixTranslation(
lerpedtranslation.m128_f32[0]
, lerpedtranslation.m128_f32[1],
lerpedtranslation.m128_f32[2]));
}
}
}


OutputDebugStringA("\n");
OutputDebugStringA(std::to_string(elapsedTime).c_str());
for (int i = 0;i < mesh->bones.size();i++)
{
if (mesh->bones[i]->ParentIndex>-1)
{
DirectX::XMFLOAT4X4 parentTransform
= mesh->bones[mesh->bones[i]->ParentIndex]->LocalTransform;
DirectX::XMStoreFloat4x4(
&mesh->armatureBuffer.Const.Bones[i],
DirectX::XMMatrixMultiply(
DirectX::XMLoadFloat4x4(&mesh->armatureBuffer.Const.Bones[i])
, DirectX::XMLoadFloat4x4(&parentTransform)));
}
}








for (int i = 0;i < mesh->bones.size();i++)
{
DirectX::XMStoreFloat4x4(&mesh->armatureBuffer.Const.Bones[i], 
DirectX::XMMatrixTranspose(
DirectX::XMMatrixMultiply(
DirectX::XMLoadFloat4x4(&mesh->bones[i]->InvBindPos)
, DirectX::XMLoadFloat4x4(&mesh->armatureBuffer.Const.Bones[i]))));
}


if (elapsedTime > mesh->animationClips[1]->end)
{
elapsedTime = 0.0f;
}
}
}
elapsedTime += timer.GetElapsedSeconds();

the animation plays but the model seems messing up! i think there is something wrong with matrix constructions. also i adapt this code from Direct3D rendering cook book that its written in C#!

Also model render correctly when i render it without skinning.

also here is vertex shade code:


PS_IN_MESH OUT = (PS_IN_MESH)0;
float4x3 skinning = 0;


[unroll]
for (int i = 0; i <2 ; i++)
{
skinning += Bones[IN.Indices[i]] * IN.Weights[i];
}
float3 skinnedPos = mul(IN.PosL, skinning);
OUT.position = mul(float4(skinnedPos,1.0f), WVP);
OUT.positionVS = mul((IN.PosL), World).xyz;
OUT.texCoord = IN.UV;
//OUT.tangentVS = mul(IN.Tangent, World).xyz;
OUT.normalVS = mul(IN.Normal, World).xyz;


float4 posCurrent = OUT.position;
float4 posLast= mul((IN.PosL), WVPLast);
//posCurrent /= posCurrent.w;
//posLast /= posLast.w;
float2 velocity = posCurrent - posLast;
velocity /= 2.0f;
OUT.velocity = velocity;
OUT.binormalVS = cross(OUT.tangentVS, OUT.normalVS);
OUT.shadowPosH = mul((IN.PosL), World);
OUT.shadowPosH = mul(OUT.shadowPosH, lightViewMatrix);
OUT.shadowPosH = mul(OUT.shadowPosH, lightProjectionMatrix);


//Skinning
//if (IN.Weights.x != 0)


return OUT;

Any one have idea what is wrong with it?

if you want more information tell me :)

This topic is closed to new replies.

Advertisement