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 + -
显示快捷键?