?? core_graphics.cpp
字號:
if(MinX != NULL)
*MinX *= XScale;
if(MinY != NULL)
*MinY *= YScale;
if(MinZ != NULL)
*MinZ *= ZScale;
if(MaxX != NULL)
*MaxX *= XScale;
if(MaxY != NULL)
*MaxY *= YScale;
if(MaxZ != NULL)
*MaxZ *= ZScale;
if(Radius != NULL) {
Length = (float)sqrt(XScale*XScale+YScale*YScale+ZScale*ZScale);
(*Radius) *= Length;
}
return TRUE;
}
BOOL cObject::Update()
{
// Update the world position
m_Pos.Update(m_Graphics);
return TRUE;
}
BOOL cObject::UpdateAnimation(unsigned long Time, BOOL Smooth)
{
if(m_AnimationSet != NULL) {
m_Mesh->GetParentFrame()->ResetMatrices();
m_AnimationSet->Update(Time - m_StartTime, Smooth);
}
return TRUE;
}
BOOL cObject::AnimationComplete(unsigned long Time)
{
if(m_AnimationSet == NULL)
return TRUE;
if((Time - m_StartTime) >= m_AnimationSet->m_Length)
return TRUE;
return FALSE;
}
BOOL cObject::Render()
{
D3DXMATRIX Matrix;
// Error checking
if(m_Graphics == NULL || m_Mesh == NULL || m_Mesh->GetParentFrame() == NULL || m_Mesh->GetParentMesh() == NULL)
return FALSE;
// Update the object matrix
Update();
// Update the frame matrices
D3DXMatrixIdentity(&Matrix);
UpdateFrame(m_Mesh->GetParentFrame(), &Matrix);
// Copy frame matrices to bone matrices
m_Mesh->GetParentMesh()->CopyFrameToBoneMatrices();
// Draw all frame meshes
DrawFrame(m_Mesh->GetParentFrame());
return TRUE;
}
void cObject::UpdateFrame(sFrame *Frame, D3DXMATRIX *Matrix)
{
// Return if no more frames
if(Frame == NULL)
return;
// Calculate frame matrix based on animation or not
if(m_AnimationSet == NULL)
D3DXMatrixMultiply(&Frame->m_matCombined, &Frame->m_matOriginal, Matrix);
else
D3DXMatrixMultiply(&Frame->m_matCombined, &Frame->m_matTransformed, Matrix);
// Update child frames
UpdateFrame(Frame->m_Child, &Frame->m_matCombined);
// Update sibling frames
UpdateFrame(Frame->m_Sibling, Matrix);
}
void cObject::DrawFrame(sFrame *Frame)
{
sFrameMeshList *List;
sMesh *Mesh;
D3DXMATRIX matWorld;
DWORD i;
if(Frame == NULL)
return;
if((List = Frame->m_MeshList) != NULL) {
while(List != NULL) {
// See if there's a mesh to draw
if((Mesh = List->m_Mesh) != NULL) {
// Generate the mesh if using bones and set world matrix
if(Mesh->m_NumBones && Mesh->m_SkinMesh != NULL) {
Mesh->m_SkinMesh->UpdateSkinnedMesh(Mesh->m_Matrices, Mesh->m_Mesh);
// Set object world transformation
m_Graphics->GetDeviceCOM()->SetTransform(D3DTS_WORLD, m_Pos.GetMatrix());
} else {
// Set the world transformation matrix for this frame
D3DXMatrixMultiply(&matWorld, &Frame->m_matCombined, m_Pos.GetMatrix());
m_Graphics->GetDeviceCOM()->SetTransform(D3DTS_WORLD, &matWorld);
}
// Loop through materials and draw the mesh
for(i=0;i<Mesh->m_NumMaterials;i++) {
// Don't draw materials with no alpha (0.0)
if(Mesh->m_Materials[i].Diffuse.a != 0.0f) {
m_Graphics->GetDeviceCOM()->SetMaterial(&Mesh->m_Materials[i]);
m_Graphics->GetDeviceCOM()->SetTexture(0, Mesh->m_Textures[i]);
// Enabled alpha blending based on material alpha
if(Mesh->m_Materials[i].Diffuse.a != 1.0f)
m_Graphics->EnableAlphaBlending(TRUE, D3DBLEND_SRCCOLOR, D3DBLEND_ONE);
Mesh->m_Mesh->DrawSubset(i);
// Disable alpha blending based on material alpha
if(Mesh->m_Materials[i].Diffuse.a != 1.0f)
m_Graphics->EnableAlphaBlending(FALSE);
}
}
}
// Next mesh in list
List = List->m_Next;
}
}
// Next child mesh
DrawFrame(Frame->m_Child);
DrawFrame(Frame->m_Sibling);
}
cAnimation::cAnimation()
{
m_NumAnimations = 0;
m_AnimationSet = NULL;
}
cAnimation::~cAnimation()
{
Free();
}
BOOL cAnimation::Load(char *Filename, cMesh *MapMesh)
{
IDirectXFile *pDXFile = NULL;
IDirectXFileEnumObject *pDXEnum = NULL;
IDirectXFileData *pDXData = NULL;
// Free a prior animation
Free();
// Error checking
if(Filename == NULL)
return FALSE;
// Create the file object
if(FAILED(DirectXFileCreate(&pDXFile)))
return FALSE;
// Register the templates
if(FAILED(pDXFile->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES))) {
pDXFile->Release();
return FALSE;
}
// Create an enumeration object
if(FAILED(pDXFile->CreateEnumObject((LPVOID)Filename, DXFILELOAD_FROMFILE, &pDXEnum))) {
pDXFile->Release();
return FALSE;
}
// Loop through all objects looking for the animation
while(SUCCEEDED(pDXEnum->GetNextDataObject(&pDXData))) {
ParseXFileData(pDXData, NULL, NULL);
ReleaseCOM(pDXData);
}
ReleaseCOM(pDXEnum);
ReleaseCOM(pDXFile);
// Map the animation to the supplied mesh (if any)
if(MapMesh != NULL)
MapToMesh(MapMesh);
return TRUE;
}
void cAnimation::ParseXFileData(IDirectXFileData *pDataObj, sAnimationSet *ParentAnim, sAnimation *CurrentAnim)
{
IDirectXFileObject *pSubObj = NULL;
IDirectXFileData *pSubData = NULL;
IDirectXFileDataReference *pDataRef = NULL;
const GUID *Type = NULL;
char *Name = NULL;
DWORD Size;
PBYTE *DataPtr;
DWORD i;
DWORD KeyType, NumKeys, Time;
sXFileRotateKey *RotKey;
sXFileScaleKey *ScaleKey;
sXFilePositionKey *PosKey;
sXFileMatrixKey *MatKey;
sAnimationSet *SubAnimSet = NULL;
sAnimation *SubAnim = NULL;
sAnimation *Anim = NULL;
sAnimationSet *AnimSet = NULL;
// Get the template type
if(FAILED(pDataObj->GetType(&Type)))
return;
// Get the template name (if any)
if(FAILED(pDataObj->GetName(NULL, &Size)))
return;
if(Size) {
if((Name = new char[Size]) != NULL)
pDataObj->GetName(Name, &Size);
}
// Give template a default name if none found
if(Name == NULL) {
if((Name = new char[9]) == NULL)
return;
strcpy(Name, "$NoName$");
}
// Set sub frame parent
SubAnimSet = ParentAnim;
SubAnim = CurrentAnim;
// Process the templates
// Process an animation set
if(*Type == TID_D3DRMAnimationSet) {
// Create a animation set structure
if((AnimSet = new sAnimationSet()) == NULL)
return;
// Set the name
AnimSet->m_Name = Name;
Name = NULL;
// Link into the animation set list
AnimSet->m_Next = m_AnimationSet;
m_AnimationSet = AnimSet;
// Set as new parent
SubAnimSet = AnimSet;
}
// Process an animation
if(*Type == TID_D3DRMAnimation && ParentAnim != NULL) {
// Create an animation structure
if((Anim = new sAnimation()) == NULL)
return;
// Set the name
Anim->m_Name = Name;
Name = NULL;
// Link into the animation list
Anim->m_Next = ParentAnim->m_Animation;
ParentAnim->m_Animation = Anim;
SubAnim = Anim;
}
// Process an animation key
if(*Type == TID_D3DRMAnimationKey && CurrentAnim != NULL) {
// Load in this animation's key data
if(FAILED(pDataObj->GetData(NULL, &Size, (PVOID*)&DataPtr)))
return;
KeyType = ((DWORD*)DataPtr)[0];
NumKeys = ((DWORD*)DataPtr)[1];
switch(KeyType) {
case 0:
delete [] CurrentAnim->m_RotateKeys;
if((CurrentAnim->m_RotateKeys = new sRotateKey[NumKeys]) == NULL)
return;
CurrentAnim->m_NumRotateKeys = NumKeys;
RotKey = (sXFileRotateKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
for(i=0;i<NumKeys;i++) {
CurrentAnim->m_RotateKeys[i].Time = RotKey->Time;
CurrentAnim->m_RotateKeys[i].Quaternion.x = -RotKey->x;
CurrentAnim->m_RotateKeys[i].Quaternion.y = -RotKey->y;
CurrentAnim->m_RotateKeys[i].Quaternion.z = -RotKey->z;
CurrentAnim->m_RotateKeys[i].Quaternion.w = RotKey->w;
if(RotKey->Time > ParentAnim->m_Length)
ParentAnim->m_Length = RotKey->Time;
RotKey += 1;
}
break;
case 1:
delete [] CurrentAnim->m_ScaleKeys;
if((CurrentAnim->m_ScaleKeys = new sScaleKey[NumKeys]) == NULL)
return;
CurrentAnim->m_NumScaleKeys = NumKeys;
ScaleKey = (sXFileScaleKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
for(i=0;i<NumKeys;i++) {
CurrentAnim->m_ScaleKeys[i].Time = ScaleKey->Time;
CurrentAnim->m_ScaleKeys[i].Scale = ScaleKey->Scale;
if(ScaleKey->Time > ParentAnim->m_Length)
ParentAnim->m_Length = ScaleKey->Time;
ScaleKey += 1;
}
// Calculate the interpolation values
if(NumKeys > 1) {
for(i=0;i<NumKeys-1;i++) {
CurrentAnim->m_ScaleKeys[i].ScaleInterpolation = CurrentAnim->m_ScaleKeys[i+1].Scale - CurrentAnim->m_ScaleKeys[i].Scale;
Time = CurrentAnim->m_ScaleKeys[i+1].Time - CurrentAnim->m_ScaleKeys[i].Time;
if(!Time)
Time = 1;
CurrentAnim->m_ScaleKeys[i].ScaleInterpolation /= (float)Time;
}
}
break;
case 2:
delete [] CurrentAnim->m_PositionKeys;
if((CurrentAnim->m_PositionKeys = new sPositionKey[NumKeys]) == NULL)
return;
CurrentAnim->m_NumPositionKeys = NumKeys;
PosKey = (sXFilePositionKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
for(i=0;i<NumKeys;i++) {
CurrentAnim->m_PositionKeys[i].Time = PosKey->Time;
CurrentAnim->m_PositionKeys[i].Pos = PosKey->Pos;
if(PosKey->Time > ParentAnim->m_Length)
ParentAnim->m_Length = PosKey->Time;
PosKey += 1;
}
// Calculate the interpolation values
if(NumKeys > 1) {
for(i=0;i<NumKeys-1;i++) {
CurrentAnim->m_PositionKeys[i].PosInterpolation = CurrentAnim->m_PositionKeys[i+1].Pos - CurrentAnim->m_PositionKeys[i].Pos;
Time = CurrentAnim->m_PositionKeys[i+1].Time - CurrentAnim->m_PositionKeys[i].Time;
if(!Time)
Time = 1;
CurrentAnim->m_PositionKeys[i].PosInterpolation /= (float)Time;
}
}
break;
case 4:
delete [] CurrentAnim->m_MatrixKeys;
if((CurrentAnim->m_MatrixKeys = new sMatrixKey[NumKeys]) == NULL)
return;
CurrentAnim->m_NumMatrixKeys = NumKeys;
MatKey = (sXFileMatrixKey*)((char*)DataPtr + (sizeof(DWORD) * 2));
for(i=0;i<NumKeys;i++) {
CurrentAnim->m_MatrixKeys[i].Time = MatKey->Time;
CurrentAnim->m_MatrixKeys[i].Matrix = MatKey->Matrix;
if(MatKey->Time > ParentAnim->m_Length)
ParentAnim->m_Length = MatKey->Time;
MatKey+=1;
}
// Calculate the interpolation matrices
if(NumKeys > 1) {
for(i=0;i<NumKeys-1;i++) {
CurrentAnim->m_MatrixKeys[i].MatInterpolation = CurrentAnim->m_MatrixKeys[i+1].Matrix - CurrentAnim->m_MatrixKeys[i].Matrix;
Time = CurrentAnim->m_MatrixKeys[i+1].Time - CurrentAnim->m_MatrixKeys[i].Time;
if(!Time)
Time = 1;
CurrentAnim->m_MatrixKeys[i].MatInterpolation /= (float)Time;
}
}
break;
}
}
// Process animation options
if(*Type == TID_D3DRMAnimationOptions && CurrentAnim != NULL) {
// Load in this animation's options
if(FAILED(pDataObj->GetData(NULL, &Size, (PVOID*)&DataPtr)))
return;
// Process looping information
if(!((DWORD*)DataPtr)[0])
CurrentAnim->m_Loop = TRUE;
else
CurrentAnim->m_Loop = FALSE;
// Process linear information
if(!((DWORD*)DataPtr)[1])
CurrentAnim->m_Linear = FALSE;
else
CurrentAnim->m_Linear = TRUE;
}
// Process a frame reference
if(*Type == TID_D3DRMFrame && CurrentAnim != NULL) {
CurrentAnim->m_FrameName = Name;
Name = NULL;
// Don't enumerate child templates
return;
}
// Release name buffer
delete [] Name;
// Scan for embedded templates
while(SUCCEEDED(pDataObj->GetNextObject(&pSubObj))) {
// Process embedded references
if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileDataReference, (void**)&pDataRef))) {
if(SUCCEEDED(pDataRef->Resolve(&pSubData))) {
ParseXFileData(pSubData, SubAnimSet, SubAnim);
ReleaseCOM(pSubData);
}
ReleaseCOM(pDataRef);
}
// Process non-referenced embedded templates
if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileData, (void**)&pSubData))) {
ParseXFileData(pSubData, SubAnimSet, SubAnim);
ReleaseCOM(pSubData);
}
ReleaseCOM(pSubObj);
}
}
BOOL cAnimation::Free()
{
delete m_AnimationSet;
m_AnimationSet = NULL;
m_NumAnimations = 0;
return TRUE;
}
BOOL cAnimation::IsLoaded()
{
if(m_AnimationSet == NULL)
return FALSE;
return TRUE;
}
BOOL cAnimation::MapToMesh(cMesh *Mesh)
{
sAnimationSet *AnimSet;
sAnimation *Anim;
// Make sure there's a mesh to work with
if(Mesh == NULL)
return FALSE;
// Assign links to frames by name
if((AnimSet = m_AnimationSet) == NULL)
return FALSE;
// Scan through all animation sets
while(AnimSet != NULL) {
// Scan through all animations
Anim = AnimSet->m_Animation;
while(Anim != NULL) {
// Find the matching frame from Mesh
Anim->m_Frame = Mesh->GetFrame(Anim->m_FrameName);
Anim = Anim->m_Next;
}
AnimSet = AnimSet->m_Next;
}
return TRUE;
}
long cAnimation::GetNumAnimations()
{
return m_NumAnimations;
}
sAnimationSet *cAnimation::GetAnimationSet(char *Name)
{
if(m_AnimationSet == NULL)
return NULL;
return m_AnimationSet->FindSet(Name);
}
BOOL cAnimation::SetLoop(BOOL ToLoop, char *Name)
{
sAnimationSet *AnimSet;
sAnimation *Anim;
if((AnimSet = GetAnimationSet(Name)) == NULL)
return FALSE;
Anim = AnimSet->m_Animation;
while(Anim != NULL) {
Anim->m_Loop = ToLoop;
Anim = Anim->m_Next;
}
return TRUE;
}
unsigned long cAnimation::GetLength(char *Name)
{
sAnimationSet *AnimSet;
if((AnimSet = GetAnimationSet(Name)) == NULL)
return 0;
return AnimSet->m_Length;
}
cTexture::cTexture()
{
m_Graphics = NULL;
m_Texture = NULL;
m_Width = m_Height = 0;
}
cTexture::~cTexture()
{
Free();
}
BOOL cTexture::Load(cGraphics *Graphics, char *Filename, DWORD Transparent, D3DFORMAT Format)
{
Free();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -