m2animation.cpp
来自「3D游戏展示程序」· C++ 代码 · 共 298 行
CPP
298 行
//--------------------------------------------------
// Desc: Bone Animation Interpolate
//--------------------------------------------------
#include "M2Animation.h"
#include "M2Loader.h"
#include "Common.h"
ASINLINE D3DXVECTOR3 FixCoordSystemVector(const D3DXVECTOR3 &v)
{
return D3DXVECTOR3(v.x, v.z, v.y);
}
ASINLINE D3DXVECTOR3 FixCoordSystemScale(const D3DXVECTOR3 &v)
{
return D3DXVECTOR3(v.x, v.z, v.y);
}
ASINLINE Quaternion FixCoordSystemQuat(const Quaternion &v)
{
return Quaternion(-v.x, -v.z, -v.y, v.w);
}
//--------------------------------------------------
// 骨骼转换
//--------------------------------------------------
void M2Bone::Init(uint8 *pData, ModelBoneDef &bone, int *pGlobalSequence)
{
m_bCalc = false;
m_Parent = bone.parent;
m_Point = FixCoordSystemVector(bone.pivot);
m_bBillboard = (bone.flags & 8) != 0;
m_Trans.Init(bone.translation, pData, pGlobalSequence);
m_Rotate.Init(bone.rotation, pData, pGlobalSequence);
m_Scale.Init(bone.scaling, pData, pGlobalSequence);
m_Trans.Fix(FixCoordSystemVector);
m_Rotate.Fix(FixCoordSystemQuat);
m_Scale.Fix(FixCoordSystemScale);
}
//--------------------------------------------------
// 计算骨骼矩阵
//--------------------------------------------------
void M2Bone::CalcMatrix(M2Bone *pBone, int animIndex, int curtime, bool bRotate/* =true */)
{
if(m_bCalc) return;
D3DXMATRIX mat;
Quaternion quat;
D3DXMatrixTranslation(&mat, -m_Point.x, -m_Point.y, -m_Point.z);
D3DXMATRIX matTemp;
D3DXMATRIX matQuat;
if(m_Scale.m_bUsed)
{
D3DXVECTOR3 scale = m_Scale.GetValue(animIndex, curtime);
D3DXMatrixScaling(&matTemp, scale.x, scale.y, scale.z);
mat *= matTemp;
}
//--------------------------------------------------
// TODO: add billboard matrix
//--------------------------------------------------
if(m_Rotate.m_bUsed && bRotate)
{
quat = m_Rotate.GetValue(animIndex, curtime);
D3DXQUATERNION d3dquat(quat.x, quat.y, quat.z, quat.w);
D3DXMatrixRotationQuaternion(&matQuat, &d3dquat);
mat *= matQuat;
}
if(m_Trans.m_bUsed)
{
D3DXVECTOR3 trans = m_Trans.GetValue(animIndex, curtime);
D3DXMatrixTranslation(&matTemp, trans.x, trans.y, trans.z);
mat *= matTemp;
}
D3DXMatrixTranslation(&matTemp, m_Point.x, m_Point.y, m_Point.z);
mat *= matTemp;
// m_matTrans
if(m_Parent > -1)
{
pBone[m_Parent].CalcMatrix(pBone, animIndex, curtime, bRotate);
m_matTrans = mat * pBone[m_Parent].m_matTrans;
}
else
{
m_matTrans = mat;
}
// m_matRotate
if(m_Rotate.m_bUsed && bRotate)
{
if(m_Parent > -1)
{
m_matRotate = matQuat * pBone[m_Parent].m_matRotate;
}
else
{
m_matRotate = matQuat;
}
}
else
{
D3DXMatrixIdentity(&m_matRotate);
}
D3DXVec3TransformCoord(&m_TransPoint, &m_Point, &m_matTrans);
m_bCalc = true;
}
//--------------------------------------------------
// M2Color
//--------------------------------------------------
void M2Color::Init(uint8 *pData, ModelColorDef &colordef, int *pGlobalSequence)
{
m_Color.Init(colordef.color, pData, pGlobalSequence);
m_Opacity.Init(colordef.opacity, pData, pGlobalSequence);
}
//--------------------------------------------------
// M2Transparency
//--------------------------------------------------
void M2Transparency::Init(uint8 *pData, ModelTransDef &transdef, int *pGlobalSequence)
{
m_Transparency.Init(transdef.trans, pData, pGlobalSequence);
}
//--------------------------------------------------
// 附属装备
//--------------------------------------------------
void M2Attachment::Init(const ModelAttachmentDef &attachment)
{
m_Position = FixCoordSystemVector(attachment.pos);
m_Bone = attachment.bone;
m_Id = attachment.id;
}
D3DXMATRIX* M2Attachment::GetMatrix(D3DXMATRIX *pOut, D3DXMATRIX *pBone)
{
D3DXMATRIX matLocate;
D3DXMatrixTranslation(&matLocate, m_Position.x, m_Position.y, m_Position.z);
*pOut = matLocate * (*pBone);
return pOut;
}
//--------------------------------------------------
// Camera
//--------------------------------------------------
void M2Camera::Init(uint8 *pData, ModelCameraDef &camera, int *pGlobalSequence)
{
m_bInit = true;
m_Nearclip = camera.nearclip;
m_Farclip = camera.farclip;
m_Fov = camera.fov;
m_Position = FixCoordSystemVector(camera.pos);
m_Target = FixCoordSystemVector(camera.target);
m_ToPos.Init(camera.transPos, pData, pGlobalSequence);
m_ToTarget.Init(camera.transTarget, pData, pGlobalSequence);
m_Rotate.Init(camera.rot, pData, pGlobalSequence);
m_ToPos.Fix(FixCoordSystemVector);
m_ToTarget.Fix(FixCoordSystemVector);
}
// 此处需要调整
void M2Camera::Setup(int time /* = 0 */)
{
if(!m_bInit) return;
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, m_Fov, (float)(800)/600, m_Nearclip, m_Farclip);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
D3DXVECTOR3 pos = m_Position + m_ToPos.GetValue(0, time);
D3DXVECTOR3 target = m_Target + m_ToTarget.GetValue(0, time);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &pos, &target, &up);
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
}
//--------------------------------------------------
// Render Pass
//--------------------------------------------------
bool M2RenderPass::OpenState(CM2Loader *m)
{
D3DXVECTOR4 oldcol(1.0f, 1.0f, 1.0f, 1.0f);
D3DXVECTOR4 emissioncol(0.0f, 0.0f, 0.0f, 0.0f);
// emission colors
if(m_Color != -1)
{
D3DXVECTOR3 color = m->m_pColor[m_Color].m_Color.GetValue(m->m_CurAnimation, m->m_AnimationTime);
float fopacity = m->m_pColor[m_Color].m_Opacity.GetValue(m->m_CurAnimation, m->m_AnimationTime);
oldcol.w = fopacity;
if(m_bUnLight)
{
oldcol.x = color.x; oldcol.y = color.y; oldcol.z = color.z;
}
else
{
oldcol.x = oldcol.y = oldcol.z = 0;
}
emissioncol = D3DXVECTOR4(color.x, color.y, color.z, oldcol.w);
D3DMATERIAL9 mater;
mater.Emissive.a = 1.0f;//emissioncol.w;
mater.Emissive.r = emissioncol.x;
mater.Emissive.g = emissioncol.y;
mater.Emissive.b = emissioncol.z;
mater.Power = 10.0f;
g_pD3DDevice->SetMaterial(&mater);
}
// opacity
if(m_Opacity != -1)
{
oldcol.w *= m->m_pTransparency[m_Opacity].m_Transparency.GetValue(m->m_CurAnimation, m->m_AnimationTime);
}
if(!((oldcol.w > 0) && (m_Color==-1 || emissioncol.w > 0)))
return false;
switch(m_BlendMode)
{
case BM_OPAQUE:
break;
case BM_TRANSPARENT:
g_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
g_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, 0x7F);
break;
case BM_ALPHA_BLEND:
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
break;
case BM_ADDITIVE:
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
break;
case BM_ADDITIVE_ALPHA:
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
break;
case BM_MODULATE:
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
break;
case BM_MODULATEX2:
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
break;
default:
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
if(m_bCull)
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
else
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
if(!m_bSwrap)
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
if(!m_bTwrap)
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
if(m_bUnLight)
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
return true;
}
void M2RenderPass::CloseState()
{
g_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
if(!m_bCull)
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
if(!m_bSwrap)
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
if(!m_bTwrap)
g_pD3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
if(m_bUnLight)
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?