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 }
} ;