📄 game_skinmesh.h
字号:
#ifndef GAMEENGINE_SKINMESH_INCLUDE
#define GAMEENGINE_SKINMESH_INCLUDE
#include "Game_Mesh.h"
#define MINFLOAT 0.0005//误差
//-----------------------------------------------------------------------------
// Name: struct D3DXFRAME_DERIVED
// Desc: Structure derived from D3DXFRAME so we can add some app-specific
// info that will be stored with each frame
//-----------------------------------------------------------------------------
struct D3DXFRAME_DERIVED: public D3DXFRAME
{
D3DXMATRIXA16 CombinedTransformationMatrix;
};
//-----------------------------------------------------------------------------
// Name: struct D3DXMESHCONTAINER_DERIVED
// Desc: Structure derived from D3DXMESHCONTAINER so we can add some app-specific
// info that will be stored with each mesh
//-----------------------------------------------------------------------------
struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER
{
LPDIRECT3DTEXTURE9* ppTextures; // array of textures, entries are NULL if no texture specified
// SkinMesh info
LPD3DXMESH pOrigMesh;
LPD3DXATTRIBUTERANGE pAttributeTable;
DWORD NumAttributeGroups;
DWORD NumInfl;
LPD3DXBUFFER pBoneCombinationBuf;
D3DXMATRIX** ppBoneMatrixPtrs;
D3DXMATRIX* pBoneOffsetMatrices;
DWORD NumPaletteEntries;
bool UseSoftwareVP;
DWORD iAttributeSW; // used to denote the split between SW and HW if necessary for non-indexed skinning
};
// enum for various skinning modes possible
enum METHOD
{
D3DNONINDEXED,
D3DINDEXED,
SOFTWARE,
NONE
};
class CSkinMesh;
//-----------------------------------------------------------------------------
// Name: class CAllocateHierarchy
// Desc: Custom version of ID3DXAllocateHierarchy with custom methods to create
// frames and meshcontainers.
//-----------------------------------------------------------------------------
//这里是Directx9.0a的
class CAllocateHierarchy: public ID3DXAllocateHierarchy
{
public:
STDMETHOD(CreateFrame)(THIS_ LPCTSTR Name, LPD3DXFRAME *ppNewFrame);
#if (D3D_SDK_VERSION &31) //这里是Directx9.0b的
STDMETHOD(CreateMeshContainer)(THIS_ LPCTSTR Name,
LPD3DXMESHDATA pMeshData,
LPD3DXMATERIAL pMaterials,
LPD3DXEFFECTINSTANCE pEffectInstances,
DWORD NumMaterials,
DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer);
#else //这里是Directx9.0c的
STDMETHOD(CreateMeshContainer)(THIS_
LPCSTR Name,
CONST D3DXMESHDATA *pMeshData,
CONST D3DXMATERIAL *pMaterials,
CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials,
CONST DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer);
#endif
STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree);
STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerBase);
CAllocateHierarchy(CSkinMesh *pSkinMesh) :m_pSkinMesh(pSkinMesh) {}
public:
CSkinMesh* m_pSkinMesh;
};
//这里是DirectX9.0C的
class CMesh;
//蒙皮动画
class CSkinMesh
{
public:
VOID SetAnim(BOOL bAnim);
BOOL CSkinMesh::InterSect( D3DVECTOR *pRayOrig,
D3DVECTOR *pRayDir,D3DVECTOR* pVRet);
VOID UpdateFrameMatrices( LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix );
LPDIRECT3DVERTEXSHADER9 m_pIndexedVertexShader[4];
D3DXMATRIXA16* m_pBoneMatrices;
UINT m_NumBoneMatricesMax;
METHOD m_SkinningMethod;
D3DCAPS9 m_d3dCaps;
D3DXVECTOR3 m_vObjectCenter; // Center of bounding sphere of object
FLOAT m_fObjectRadius; // Radius of bounding sphere of object
D3DXVECTOR3 m_vMin;
D3DXVECTOR3 m_vMax;
//考虑到模型的重复引用,这里可以定义不使用模型自身的坐标,比例和角度
FLOAT m_fAngle;
FLOAT m_pXangle; //模型要X轴旋转的角度
FLOAT m_fScale;
D3DXVECTOR3 m_vPos;
D3DXVECTOR3 m_vbornPos;
D3DXVECTOR3 m_vPosOld; //
D3DXVECTOR3 m_vTarget;
D3DXVECTOR3 m_vMovingPos;
bool m_isMoving; //鼠标点击状态
float m_speed1; // 跑步速度
float m_speed2; // 旋转速度
BOOL m_bLoop; // 是否循环播放
LPD3DXANIMATIONSET m_pCurAnimSet; // 当前动画
double m_CurTime;
BOOL m_bMoving;
BOOL m_isAttacking;
BOOL m_isdead;
FLOAT m_EXP;
FLOAT m_MAXHP;
FLOAT m_MAXMP;
FLOAT m_MAXEXP;
FLOAT m_CURHP;
FLOAT m_CURMP;
FLOAT m_CUREXP;
LPD3DXMESH m_pMesh;
D3DXMATRIXA16 m_matWorld;
float n; //模型绕Y轴旋转系数
VOID SetPosition(D3DXVECTOR3 *pPos) {m_vPos=*pPos;};
VOID SetPosition(float x,float y,float z) {m_vPos.x=x;m_vPos.y=y;m_vPos.z=z;};
VOID SetDirection(float fAngle){m_fAngle=fAngle;};
VOID SetScale(float s){m_fScale=s;};
VOID GetPosition(D3DXVECTOR3 *vPos)
{
*vPos=m_vPos;
}
D3DXVECTOR3 GetPosition() {return D3DXVECTOR3(this->m_vPos.x, this->m_vPos.y, this->m_vPos.z);}
//VOID D3DXVECTOR3 GetPosition()
//{
// return &m_vPos;
//}
VOID GetDirection1(D3DXVECTOR3 *vDir) //前后移动
{
vDir->x=sinf(m_fAngle);
vDir->y=0;
vDir->z=cosf(m_fAngle);
}
VOID GetDirection2(D3DXVECTOR3 *vDir) //左右移动
{
vDir->x=cosf(m_fAngle);
vDir->y=0;
vDir->z=-sinf(m_fAngle);
}
VOID GetDirection3(D3DXVECTOR3 *vDir) //右上移动
{
vDir->x=sinf(m_fAngle + D3DX_PI/4);
vDir->y=0;
vDir->z=cosf(m_fAngle + D3DX_PI/4);
}
VOID GetDirection4(D3DXVECTOR3 *vDir) //左上移动
{
vDir->x=-sinf(D3DX_PI/4 - m_fAngle);
vDir->y=0;
vDir->z=cosf(D3DX_PI/4 - m_fAngle);
}
VOID GetDirection(D3DXVECTOR3 *vDir)
{
vDir->x=sinf(m_fAngle);
vDir->y=0;
vDir->z=cosf(m_fAngle);
};
VOID Render(float fElapsedAppTime)
{
Render(fElapsedAppTime, m_vPos, m_fAngle, m_fScale,n);
};
// 目 的:设置是否循环播放
VOID SetLoop( BOOL bLoop ) { m_bLoop = bLoop; }
// 目 的:判断当前动画是否播完
BOOL IsAnimEnd( float& passTime )
{
static float couTime = (float)m_pCurAnimSet->GetPeriod();
// 如果播放的时间超过了动画时间即播放完毕,返回ture
if( m_bLoop )
{
m_CurTime = 0.0;
return false;
}
else
{
// 超出播放时间
if( m_CurTime + passTime >= couTime )
{
passTime = (float)(couTime - m_CurTime);
//m_CurTime = 0.0;
return true;
}
else
{
m_CurTime += passTime;
return false;
}
}
}
VOID GetBoundingBox(D3DXVECTOR3 *vMin,D3DXVECTOR3 *vMax)
{
*vMin=m_vPos+m_vMin*m_fScale;
*vMax=m_vPos+m_vMax*m_fScale;
}
VOID Turn(float fAngle)
{
m_fAngle+=fAngle;
}
VOID WalkFoward(float fDistance, int n)
{
m_vPosOld=m_vPos;
D3DXVECTOR3 vDir;
if(n == 1)
GetDirection1(&vDir);
else if(n == 2)
GetDirection2(&vDir);
else if(n == 3)
GetDirection3(&vDir);
else if(n == 4)
GetDirection4(&vDir);
m_vPos += fDistance*vDir;
}
VOID Back()
{
m_vPos=m_vPosOld;
}
VOID SetSpeed(float sp)
{
m_speed1 = sp;
}
VOID SetAltitude(float y)
{
m_vPos.y=y;
}
LRESULT CollisionTestAABB(CSkinMesh *pMesh)
{
D3DXVECTOR3 A1,A2;
D3DXVECTOR3 B1,B2;
GetBoundingBox(&A1,&A2);
pMesh->GetBoundingBox(&B1,&B2);
return (A1.x<B2.x && A2.x>B1.x
&& A1.y<B2.y && A2.y>B1.y
&& A1.z<B2.z && A2.z>B1.z);
}
//碰撞不带骨骼MESH
LRESULT CollisionTestAABB(CMesh *pMesh,float n)
{
D3DXVECTOR3 A1,A2;
D3DXVECTOR3 B1,B2;
GetBoundingBox(&A1,&A2);
pMesh->GetBoundingBox(&B1,&B2,n);
return (A1.x<B2.x && A2.x>B1.x
&& A1.y<B2.y && A2.y>B1.y
&& A1.z<B2.z && A2.z>B1.z);
}
//求2点之间的距离
float DistanceOfTwoVec3(const D3DXVECTOR3 v1, const D3DXVECTOR3 v2)
{
float x,z,dist;
x = v1.x - v2.x;
z = v1.z - v2.z;
dist = sqrt(x*x + z*z);
return dist;
}
//求2点间线段与坐标系夹角
float GetYaw(const D3DXVECTOR3 v1, const D3DXVECTOR3 v2)
{
float x,m_alpha,z, dist;
x = v1.x - v2.x;
z = v1.z - v2.z;
dist = DistanceOfTwoVec3(v1, v2);
if(dist == 0)
return 0;
else
m_alpha = asin(z/dist);
if(abs(m_alpha) <= MINFLOAT)
{
if(x > 0)
return D3DX_PI/2;
else if(x < 0)
return -D3DX_PI/2;
}
if(x > 0)
return D3DX_PI/2 - m_alpha;
else
return m_alpha - D3DX_PI/2;
}
//移动到目标点
D3DXVECTOR3 MoveTo(D3DXVECTOR3 IntersectPoint, float tFrameTime, float Speed1);
HRESULT CalculateStaticBondingBox(LPD3DXFRAME pFrameBase,
const LPD3DXVECTOR3 pVmin,const LPD3DXVECTOR3 pVmax);
LPD3DXANIMATIONCONTROLLER GetAnimController()
{return m_pAnimController;};
BOOL SetAnimationName(char *strAnimName);
VOID Render(float fTimeFromLastFrame,D3DXVECTOR3 vPos,float angle,float scale=1.0f,float n=1.0f);
HRESULT LoadFromXFile(char* strFileName, float scalex, float scalez);
HRESULT GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer);
//找到节点的矩阵
LRESULT GetFrameMatrix(LPD3DXFRAME pFrameBase, char *strFrameName,D3DMATRIX *pMat);
CSkinMesh(LPDIRECT3DDEVICE9 pD3DDevice);
virtual ~CSkinMesh();
protected:
LPDIRECT3DDEVICE9 m_pd3dDevice;
LPD3DXFRAME m_pFrameRoot;
LPD3DXANIMATIONCONTROLLER m_pAnimController;
FLOAT m_fElapsedTime; // Time elapsed since last frame
VOID DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase);
VOID DrawFrame(LPD3DXFRAME pFrame);
HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainerBase );
HRESULT SetupBoneMatrixPointers( LPD3DXFRAME pFrame );
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -