www.pudn.com > sxdl.zip > keyframedmesh.cpp


#include "keyframedmesh.h" 
 
CKeyFramedMesh::CKeyFramedMesh ( FileFormat Tag , int FileId , int TextureId , int ShaderId , Color color ) :  
	CCustomRenderer (  
		CVertex::PosNormalTex0 ,  
		0 ,  // VB Size unknown yet  
		0 ,  // Usage normal  
		false , // static VB  
		0 , // IB Size unknown yet  
		TextureId , 0 , 0 , 0 ,  
		ShaderId , 0 )  
{ 
	this->Tag       = Tag ;  
	this->FileId    = FileId ;  
	this->TextureId = TextureId ;  
	this->ShaderId  = ShaderId ;  
	this->color     = color ;  
 
	Layer = SxDL::Models ; 
	//  
	HRESULT hr = Game->Media.LoadDataFile ( FileId ) ;  
	if ( SUCCEEDED ( hr ) )  
	{ 
		Model = new CMd2 ( ( unsigned char * ) Game->Media.Instance ( FileId ) ) ;  
		Vertices = Model->Header->FrameCount * Model->Header->FaceCount * 3 ; 
		CCustomRenderer::VbSize = Vertices ;  
		CCustomRenderer::IbSize = 0 ;  
	} 
	else 
	{ 
	} ;  
} 
 
CKeyFramedMesh::~CKeyFramedMesh (void) 
{ 
	Game->Media.UnloadDataFile ( FileId ) ;  
} 
 
 
HRESULT CKeyFramedMesh::OnPopulateBuffers ( void * pVertices , void * pIndices )						 
{  
	// Cast to our vertex format  
    VertexPosNormalTex0 * Vertex = ( VertexPosNormalTex0 * ) pVertices ;  
 
	Md2TexCoord * TexCoords = Model->TexCoords ;  
	float SkinWidth  = ( float ) Model->Header->SkinWidth ;  
	float SkinHeight = ( float ) Model->Header->SkinHeight ;  
 
	for ( int i = 0 ; i < Model->Header->FrameCount ; ++ i ) 
	{ 
		Md2Frame * Frame = ( Md2Frame * ) ( ( char * ) Model->Frames + i * Model->Header->FrameSize ) ; 
 
		for ( int j = 0 ; j < Model->Header->FaceCount ; ++ j ) 
		{ 
			Md2Face * Face = & Model->Faces [ j ] ;  
			for ( int k = 0 ; k < 3 ; ++ k ) 
			{ 
				// pos 
				int VertexIndex = Face->VertexIndices [ k ] ;  
				Vertex->p.x = Frame->Vertices [ VertexIndex ].v [ 0 ] * Frame->Scale [ 0 ] + Frame->Translate [ 0 ] ; 
				Vertex->p.y = Frame->Vertices [ VertexIndex ].v [ 2 ] * Frame->Scale [ 2 ] + Frame->Translate [ 2 ] ; 
				Vertex->p.z = Frame->Vertices [ VertexIndex ].v [ 1 ] * Frame->Scale [ 1 ] + Frame->Translate [ 1 ] ; 
				// normal  
				Vertex->n = CMd2::Normal ( Frame->Vertices [ VertexIndex ].LightNormalIndex ) ;  
				// tex 
				int TextureIndex = Face->TextureIndices [ k ] ;  
				Vertex->tu = TexCoords [ TextureIndex ].s / SkinWidth ;  
				Vertex->tv = TexCoords [ TextureIndex ].t / SkinHeight ;  
				// next  
				Vertex ++ ;  
			} ; // end for vertex 
		} ; // end for face 
	} ; // end for frames  
 
	return S_OK ;  
} ;  
 
HRESULT CKeyFramedMesh::OnRestore ( )  
{ 
	// Clean up the vertex declaration 
	LPDIRECT3DVERTEXDECLARATION9 OldVertexDeclaration = ( LPDIRECT3DVERTEXDECLARATION9 ) Game->Media.InstanceData ( ShaderId ) ;  
	SAFE_RELEASE ( OldVertexDeclaration ) ; 
	// Multi stream setup  
    D3DVERTEXELEMENT9 MultiStream [ ] = 
    { 
        // First stream is current frame 
        { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0},  
        { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_NORMAL,   0},  
        { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 0},  
        // Second stream is next frame 
        { 1,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 1},  
        { 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_NORMAL,   1},  
        { 1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 1},  
        D3DDECL_END() 
    } ; 
	HRESULT hr = Device->CreateVertexDeclaration ( MultiStream , & VertexDeclaration ) ;  
	if ( SUCCEEDED ( hr ) )  
		Game->Media.InstanceData ( ShaderId , ( void * ) VertexDeclaration ) ;  
	else  
		Game->Media.InstanceData ( ShaderId , NULL ) ;  
	return hr ;  
} ;  
 
HRESULT CKeyFramedMesh::OnSetVertexShaderConstants ( LPDIRECT3DDEVICE9 Device , CEntity * Entity )	 
{  
	int CurrentAnimation = ( int ) Entity->GetRenderStyle ( ) ;  
	// from now we work in milliseconds so that we can use int and the mod op ( % )  
	int MillisecTime = ( int ) ( 1000.0f * Game->Timing.GetAbsolute ( ) ) ;  
	int Fps          = CMd2::Animations [ CurrentAnimation ].Fps ;  
	int FirstFrame   = CMd2::Animations [ CurrentAnimation ].FirstFrame ;  
	int LastFrame    = CMd2::Animations [ CurrentAnimation ].LastFrame ;  
	TotalFrames  = 1 + LastFrame - FirstFrame ;  
	int AnimationTime = ( ( 1 + LastFrame - FirstFrame ) * 1000 ) / Fps ;  
	float Percentage = ( float ) ( MillisecTime % AnimationTime ) / ( float ) AnimationTime ;  
	CurrentFrame  = FirstFrame + ( ( int ) ( Percentage * TotalFrames ) ) ;  
	int NextFrame     = ( CurrentFrame == LastFrame ) ? FirstFrame : CurrentFrame + 1 ;  
	if ( TotalFrames == 1 )  
	{ 
		NextFrame = CurrentFrame ;  
	} ;  
	D3DXMATRIX View       = Game->Camera.GetViewMatrix ( ) ; 
	D3DXMATRIX Projection = Game->Camera.GetProjectionMatrix ( ) ; 
	D3DXMATRIX ShaderMatrix ;  
	D3DXMatrixTranspose ( & ShaderMatrix, & ( Entity->GetWorldMatrix ( ) * View * Projection ) ); 
	Device->SetVertexShaderConstantF ( 4, ( const float * ) & ShaderMatrix , 4 ); 
 
	// Some basic constants 
	D3DXVECTOR4 Zero ( 0.0f, 0.0f, 0.0f, 0.0f  ) ; 
	D3DXVECTOR4 One  ( 1.0f, 0.5f, 0.2f, 0.05f ) ; 
 
	// Compute the blending weights 
	float CurrentFramePercentage = ( float ) ( CurrentFrame - FirstFrame ) / ( float ) TotalFrames ;  
	float SingleFramePercentage  = 1.0f / ( float ) TotalFrames ;  
	float BlendIntoNext = ( Percentage - CurrentFramePercentage ) / SingleFramePercentage ;  
	float BlendIntoCurrent = 1.0f - BlendIntoNext ; 
	Vector4 Weights ( BlendIntoCurrent , BlendIntoNext , 0.0f , 0.0f ); 
 
	// Lighting vector and other constants 
	float Light[]    = { 1.00f, 0.00f, 0.00f, 0.00f }; 
	float Diffuse[]  = { 1.00f, 2.00f, 2.00f, 2.00f }; 
	float Ambient[]  = { 0.50f, 0.50f, 0.50f, 0.50f }; 
 
	// Set the vertex shader constants 
	Device->SetVertexShaderConstantF (  0, (float*) & Zero,     1 ) ; 
	Device->SetVertexShaderConstantF (  1, (float*) & One,      1 ) ; 
	Device->SetVertexShaderConstantF (  2, (float*) & Weights,  1 ) ; 
	Device->SetVertexShaderConstantF ( 20, (float*)   Light,    1 ) ; 
	Device->SetVertexShaderConstantF ( 21, (float*)   Diffuse,  1 ) ; 
	Device->SetVertexShaderConstantF ( 22, (float*)   Ambient,  1 ) ; 
 
	HRESULT hr ; 
	int VertexSize = CVertex::VertexSize [ Vertex ] ;  
	int FrameOffset = Model->Header->FaceCount * 3 * VertexSize ;  
	hr = CachedDevice->SetStreamSource ( 0, VertexBuffer , CurrentFrame * FrameOffset , VertexSize ) ; 
	hr = CachedDevice->SetStreamSource ( 1, VertexBuffer , NextFrame    * FrameOffset , VertexSize ) ; 
	  
	return hr ;  
} ;  
 
HRESULT CKeyFramedMesh::OnRender ( LPDIRECT3DDEVICE9 Device , float RenderStyle ) 
{  
	HRESULT hr = Device->DrawPrimitive ( D3DPT_TRIANGLELIST, 0 , Model->Header->FaceCount ) ;  
	return hr ;  
}  
 
Md2Animation CMd2::Animations [ ] =  
{ 
	{   0,  39,  9 },	// STAND 
	{  40,  45, 10 },	// RUN 
	{  46,  53, 10 },	// ATTACK 
	{  54,  57,  7 },	// PAIN_A 
	{  58,  61,  7 },	// PAIN_B 
	{  62,  65,  7 },	// PAIN_C 
	{  66,  71,  7 },	// JUMP 
	{  72,  83,  7 },	// FLIPOFF 
	{  84,  94,  7 },	// SALUTE 
	{  95, 111, 10 },	// TAUNT 
	{ 112, 122,  7 },	// WAVE 
	{ 123, 134,  6 },	// POINT 
	{ 135, 153, 10 },	// CROUCH_STAND 
	{ 154, 159,  7 },	// CROUCH_WALK 
	{ 160, 168, 10 },	// CROUCH_ATTACK 
	{ 169, 172,  7 },	// CROUCH_PAIN 
	{ 173, 177,  5 },	// CROUCH_DEATH 
	{ 178, 183,  7 },	// DEATH_FALLBACK 
	{ 184, 189,  7 },	// DEATH_FALLFORWARD 
	{ 190, 197,  7 },	// DEATH_FALLBACKSLOW 
} ; 
 
const char * CMd2::AnimationNames [ ] =  
{ 
	"STAND" , 
	"RUN", 
	"ATTACK", 
	"PAIN_A", 
	"PAIN_B", 
	"PAIN_C", 
	"JUMP", 
	"FLIPOFF", 
	"SALUTE", 
	"TAUNT", 
	"WAVE", 
	"POINT", 
	"CROUCH_STAND", 
	"CROUCH_WALK", 
	"CROUCH_ATTACK", 
	"CROUCH_PAIN", 
	"CROUCH_DEATH",  
	"DEATH_FALLBACK", 
	"DEATH_FALLFORWARD", 
	"DEATH_FALLBACKSLOW", 
} ; 
 
// MD2 precalculated normal vectors 
Md2Float3 CMd2::PrecalculatedNormals [ ] =  
{ 
	{ -0.525731f,  0.000000f,  0.850651f },  
	{ -0.442863f,  0.238856f,  0.864188f },  
	{ -0.295242f,  0.000000f,  0.955423f },  
	{ -0.309017f,  0.500000f,  0.809017f },  
	{ -0.162460f,  0.262866f,  0.951056f },  
	{  0.000000f,  0.000000f,  1.000000f },  
	{  0.000000f,  0.850651f,  0.525731f },  
	{ -0.147621f,  0.716567f,  0.681718f },  
	{  0.147621f,  0.716567f,  0.681718f },  
	{  0.000000f,  0.525731f,  0.850651f },  
	{  0.309017f,  0.500000f,  0.809017f },  
	{  0.525731f,  0.000000f,  0.850651f },  
	{  0.295242f,  0.000000f,  0.955423f },  
	{  0.442863f,  0.238856f,  0.864188f },  
	{  0.162460f,  0.262866f,  0.951056f },  
	{ -0.681718f,  0.147621f,  0.716567f },  
	{ -0.809017f,  0.309017f,  0.500000f },  
	{ -0.587785f,  0.425325f,  0.688191f },  
	{ -0.850651f,  0.525731f,  0.000000f },  
	{ -0.864188f,  0.442863f,  0.238856f },  
	{ -0.716567f,  0.681718f,  0.147621f },  
	{ -0.688191f,  0.587785f,  0.425325f },  
	{ -0.500000f,  0.809017f,  0.309017f },  
	{ -0.238856f,  0.864188f,  0.442863f },  
	{ -0.425325f,  0.688191f,  0.587785f },  
	{ -0.716567f,  0.681718f, -0.147621f },  
	{ -0.500000f,  0.809017f, -0.309017f },  
	{ -0.525731f,  0.850651f,  0.000000f },  
	{  0.000000f,  0.850651f, -0.525731f },  
	{ -0.238856f,  0.864188f, -0.442863f },  
	{  0.000000f,  0.955423f, -0.295242f },  
	{ -0.262866f,  0.951056f, -0.162460f },  
	{  0.000000f,  1.000000f,  0.000000f },  
	{  0.000000f,  0.955423f,  0.295242f },  
	{ -0.262866f,  0.951056f,  0.162460f },  
	{  0.238856f,  0.864188f,  0.442863f },  
	{  0.262866f,  0.951056f,  0.162460f },  
	{  0.500000f,  0.809017f,  0.309017f },  
	{  0.238856f,  0.864188f, -0.442863f },  
	{  0.262866f,  0.951056f, -0.162460f },  
	{  0.500000f,  0.809017f, -0.309017f },  
	{  0.850651f,  0.525731f,  0.000000f },  
	{  0.716567f,  0.681718f,  0.147621f },  
	{  0.716567f,  0.681718f, -0.147621f },  
	{  0.525731f,  0.850651f,  0.000000f },  
	{  0.425325f,  0.688191f,  0.587785f },  
	{  0.864188f,  0.442863f,  0.238856f },  
	{  0.688191f,  0.587785f,  0.425325f },  
	{  0.809017f,  0.309017f,  0.500000f },  
	{  0.681718f,  0.147621f,  0.716567f },  
	{  0.587785f,  0.425325f,  0.688191f },  
	{  0.955423f,  0.295242f,  0.000000f },  
	{  1.000000f,  0.000000f,  0.000000f },  
	{  0.951056f,  0.162460f,  0.262866f },  
	{  0.850651f, -0.525731f,  0.000000f },  
	{  0.955423f, -0.295242f,  0.000000f },  
	{  0.864188f, -0.442863f,  0.238856f },  
	{  0.951056f, -0.162460f,  0.262866f },  
	{  0.809017f, -0.309017f,  0.500000f },  
	{  0.681718f, -0.147621f,  0.716567f },  
	{  0.850651f,  0.000000f,  0.525731f },  
	{  0.864188f,  0.442863f, -0.238856f },  
	{  0.809017f,  0.309017f, -0.500000f },  
	{  0.951056f,  0.162460f, -0.262866f },  
	{  0.525731f,  0.000000f, -0.850651f },  
	{  0.681718f,  0.147621f, -0.716567f },  
	{  0.681718f, -0.147621f, -0.716567f },  
	{  0.850651f,  0.000000f, -0.525731f },  
	{  0.809017f, -0.309017f, -0.500000f },  
	{  0.864188f, -0.442863f, -0.238856f },  
	{  0.951056f, -0.162460f, -0.262866f },  
	{  0.147621f,  0.716567f, -0.681718f },  
	{  0.309017f,  0.500000f, -0.809017f },  
	{  0.425325f,  0.688191f, -0.587785f },  
	{  0.442863f,  0.238856f, -0.864188f },  
	{  0.587785f,  0.425325f, -0.688191f },  
	{  0.688191f,  0.587785f, -0.425325f },  
	{ -0.147621f,  0.716567f, -0.681718f },  
	{ -0.309017f,  0.500000f, -0.809017f },  
	{  0.000000f,  0.525731f, -0.850651f },  
	{ -0.525731f,  0.000000f, -0.850651f },  
	{ -0.442863f,  0.238856f, -0.864188f },  
	{ -0.295242f,  0.000000f, -0.955423f },  
	{ -0.162460f,  0.262866f, -0.951056f },  
	{  0.000000f,  0.000000f, -1.000000f },  
	{  0.295242f,  0.000000f, -0.955423f },  
	{  0.162460f,  0.262866f, -0.951056f },  
	{ -0.442863f, -0.238856f, -0.864188f },  
	{ -0.309017f, -0.500000f, -0.809017f },  
	{ -0.162460f, -0.262866f, -0.951056f },  
	{  0.000000f, -0.850651f, -0.525731f },  
	{ -0.147621f, -0.716567f, -0.681718f },  
	{  0.147621f, -0.716567f, -0.681718f },  
	{  0.000000f, -0.525731f, -0.850651f },  
	{  0.309017f, -0.500000f, -0.809017f },  
	{  0.442863f, -0.238856f, -0.864188f },  
	{  0.162460f, -0.262866f, -0.951056f },  
	{  0.238856f, -0.864188f, -0.442863f },  
	{  0.500000f, -0.809017f, -0.309017f },  
	{  0.425325f, -0.688191f, -0.587785f },  
	{  0.716567f, -0.681718f, -0.147621f },  
	{  0.688191f, -0.587785f, -0.425325f },  
	{  0.587785f, -0.425325f, -0.688191f },  
	{  0.000000f, -0.955423f, -0.295242f },  
	{  0.000000f, -1.000000f,  0.000000f },  
	{  0.262866f, -0.951056f, -0.162460f },  
	{  0.000000f, -0.850651f,  0.525731f },  
	{  0.000000f, -0.955423f,  0.295242f },  
	{  0.238856f, -0.864188f,  0.442863f },  
	{  0.262866f, -0.951056f,  0.162460f },  
	{  0.500000f, -0.809017f,  0.309017f },  
	{  0.716567f, -0.681718f,  0.147621f },  
	{  0.525731f, -0.850651f,  0.000000f },  
	{ -0.238856f, -0.864188f, -0.442863f },  
	{ -0.500000f, -0.809017f, -0.309017f },  
	{ -0.262866f, -0.951056f, -0.162460f },  
	{ -0.850651f, -0.525731f,  0.000000f },  
	{ -0.716567f, -0.681718f, -0.147621f },  
	{ -0.716567f, -0.681718f,  0.147621f },  
	{ -0.525731f, -0.850651f,  0.000000f },  
	{ -0.500000f, -0.809017f,  0.309017f },  
	{ -0.238856f, -0.864188f,  0.442863f },  
	{ -0.262866f, -0.951056f,  0.162460f },  
	{ -0.864188f, -0.442863f,  0.238856f },  
	{ -0.809017f, -0.309017f,  0.500000f },  
	{ -0.688191f, -0.587785f,  0.425325f },  
	{ -0.681718f, -0.147621f,  0.716567f },  
	{ -0.442863f, -0.238856f,  0.864188f },  
	{ -0.587785f, -0.425325f,  0.688191f },  
	{ -0.309017f, -0.500000f,  0.809017f },  
	{ -0.147621f, -0.716567f,  0.681718f },  
	{ -0.425325f, -0.688191f,  0.587785f },  
	{ -0.162460f, -0.262866f,  0.951056f },  
	{  0.442863f, -0.238856f,  0.864188f },  
	{  0.162460f, -0.262866f,  0.951056f },  
	{  0.309017f, -0.500000f,  0.809017f },  
	{  0.147621f, -0.716567f,  0.681718f },  
	{  0.000000f, -0.525731f,  0.850651f },  
	{  0.425325f, -0.688191f,  0.587785f },  
	{  0.587785f, -0.425325f,  0.688191f },  
	{  0.688191f, -0.587785f,  0.425325f },  
	{ -0.955423f,  0.295242f,  0.000000f },  
	{ -0.951056f,  0.162460f,  0.262866f },  
	{ -1.000000f,  0.000000f,  0.000000f },  
	{ -0.850651f,  0.000000f,  0.525731f },  
	{ -0.955423f, -0.295242f,  0.000000f },  
	{ -0.951056f, -0.162460f,  0.262866f },  
	{ -0.864188f,  0.442863f, -0.238856f },  
	{ -0.951056f,  0.162460f, -0.262866f },  
	{ -0.809017f,  0.309017f, -0.500000f },  
	{ -0.864188f, -0.442863f, -0.238856f },  
	{ -0.951056f, -0.162460f, -0.262866f },  
	{ -0.809017f, -0.309017f, -0.500000f },  
	{ -0.681718f,  0.147621f, -0.716567f },  
	{ -0.681718f, -0.147621f, -0.716567f },  
	{ -0.850651f,  0.000000f, -0.525731f },  
	{ -0.688191f,  0.587785f, -0.425325f },  
	{ -0.587785f,  0.425325f, -0.688191f },  
	{ -0.425325f,  0.688191f, -0.587785f },  
	{ -0.425325f, -0.688191f, -0.587785f },  
	{ -0.587785f, -0.425325f, -0.688191f },  
	{ -0.688191f, -0.587785f, -0.425325f }  
} ;