?? core_graphics.cpp
字號:
while(Mesh != NULL) {
if(Mesh->m_SkinMesh != NULL) {
Matrix = new D3DXMATRIX[Mesh->m_NumBones];
for(i=0;i<Mesh->m_NumBones;i++)
D3DXMatrixIdentity(&Matrix[i]);
Mesh->m_SkinMesh->UpdateSkinnedMesh(Matrix, Mesh->m_Mesh);
delete [] Matrix;
}
Mesh = Mesh->m_Next;
}
}
// Calculate bounding box and sphere
if((Mesh = m_Meshes) != NULL) {
while(Mesh != NULL) {
m_Min.x = min(m_Min.x, Mesh->m_Min.x);
m_Min.y = min(m_Min.y, Mesh->m_Min.y);
m_Min.z = min(m_Min.z, Mesh->m_Min.z);
m_Max.x = max(m_Max.x, Mesh->m_Max.x);
m_Max.y = max(m_Max.y, Mesh->m_Max.y);
m_Max.z = max(m_Max.z, Mesh->m_Max.z);
m_Radius = max(m_Radius, Mesh->m_Radius);
Mesh = Mesh->m_Next;
}
}
return TRUE;
}
void cMesh::ParseXFileData(IDirectXFileData *pDataObj, sFrame *ParentFrame, char *TexturePath)
{
IDirectXFileObject *pSubObj = NULL;
IDirectXFileData *pSubData = NULL;
IDirectXFileDataReference *pDataRef = NULL;
const GUID *Type = NULL;
char *Name = NULL;
DWORD Size;
sFrame *SubFrame = NULL;
char Path[MAX_PATH];
sFrame *Frame = NULL;
D3DXMATRIX *FrameMatrix = NULL;
sMesh *Mesh = NULL;
ID3DXBuffer *MaterialBuffer = NULL;
D3DXMATERIAL *Materials = NULL;
ID3DXBuffer *Adjacency = NULL;
DWORD *AdjacencyIn = NULL;
DWORD *AdjacencyOut = NULL;
DWORD i;
BYTE **Ptr;
// 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
SubFrame = ParentFrame;
// Process the templates
// Frame
if(*Type == TID_D3DRMFrame) {
// Create a new frame structure
Frame = new sFrame();
// Store the name
Frame->m_Name = Name;
Name = NULL;
// Add to parent frame
Frame->m_Parent = ParentFrame;
Frame->m_Sibling = ParentFrame->m_Child;
ParentFrame->m_Child = Frame;
// Increase frame count
m_NumFrames++;
// Set sub frame parent
SubFrame = Frame;
}
// Frame transformation matrix
if(*Type == TID_D3DRMFrameTransformMatrix) {
if(FAILED(pDataObj->GetData(NULL, &Size, (PVOID*)&FrameMatrix)))
return;
ParentFrame->m_matOriginal = *FrameMatrix;
}
// Mesh
if(*Type == TID_D3DRMMesh) {
// See if mesh already loaded
if(m_Meshes == NULL || m_Meshes->FindMesh(Name) == NULL) {
// Create a new mesh structure
Mesh = new sMesh();
// Store the name
Mesh->m_Name = Name;
Name = NULL;
// Load mesh data
if(FAILED(D3DXLoadSkinMeshFromXof(pDataObj, 0,
m_Graphics->GetDeviceCOM(),
&Adjacency,
&MaterialBuffer, &Mesh->m_NumMaterials,
&Mesh->m_BoneNames, &Mesh->m_BoneTransforms,
&Mesh->m_SkinMesh))) {
delete Mesh;
return;
}
// Calculate the bounding box and sphere
if(SUCCEEDED(Mesh->m_SkinMesh->LockVertexBuffer(D3DLOCK_READONLY, (BYTE**)&Ptr))) {
D3DXComputeBoundingBox((void*)Ptr, Mesh->m_SkinMesh->GetNumVertices(), Mesh->m_SkinMesh->GetFVF(), &Mesh->m_Min, &Mesh->m_Max);
D3DXComputeBoundingSphere((void*)Ptr, Mesh->m_SkinMesh->GetNumVertices(), Mesh->m_SkinMesh->GetFVF(), &D3DXVECTOR3(0.0f,0.0f,0.0f), &Mesh->m_Radius);
Mesh->m_SkinMesh->UnlockVertexBuffer();
}
// Convert to regular mesh if no bones
if(!(Mesh->m_NumBones = Mesh->m_SkinMesh->GetNumBones())) {
// Convert to a regular mesh
Mesh->m_SkinMesh->GetOriginalMesh(&Mesh->m_Mesh);
ReleaseCOM(Mesh->m_SkinMesh);
} else {
// Create the bone matrix array and clear it out
Mesh->m_Matrices = new D3DXMATRIX[Mesh->m_NumBones];
for(i=0;i<Mesh->m_NumBones;i++)
D3DXMatrixIdentity(&Mesh->m_Matrices[i]);
// Create the frame mapping matrix array and clear out
Mesh->m_FrameMatrices = new D3DXMATRIX*[Mesh->m_NumBones];
for(i=0;i<Mesh->m_NumBones;i++)
Mesh->m_FrameMatrices[i] = NULL;
// Get a pointer to bone matrices
Mesh->m_BoneMatrices = (D3DXMATRIX*)Mesh->m_BoneTransforms->GetBufferPointer();
AdjacencyIn = (DWORD*)Adjacency->GetBufferPointer();
AdjacencyOut = new DWORD[Mesh->m_SkinMesh->GetNumFaces() * 3];
// Generate the skin mesh object
if(FAILED(Mesh->m_SkinMesh->GenerateSkinnedMesh(
D3DXMESH_WRITEONLY, 0.0f,
AdjacencyIn, AdjacencyOut,
&Mesh->m_Mesh))) {
// Convert to a regular mesh if error
Mesh->m_SkinMesh->GetOriginalMesh(&Mesh->m_Mesh);
ReleaseCOM(Mesh->m_SkinMesh);
Mesh->m_NumBones = 0;
}
delete [] AdjacencyOut;
ReleaseCOM(Adjacency);
}
// Load materials or create a default one if none
if(!Mesh->m_NumMaterials) {
// Create a default one
Mesh->m_Materials = new D3DMATERIAL8[1];
Mesh->m_Textures = new LPDIRECT3DTEXTURE8[1];
ZeroMemory(Mesh->m_Materials, sizeof(D3DMATERIAL8));
Mesh->m_Materials[0].Diffuse.r = 1.0f;
Mesh->m_Materials[0].Diffuse.g = 1.0f;
Mesh->m_Materials[0].Diffuse.b = 1.0f;
Mesh->m_Materials[0].Diffuse.a = 1.0f;
Mesh->m_Materials[0].Ambient = Mesh->m_Materials[0].Diffuse;
Mesh->m_Materials[0].Specular = Mesh->m_Materials[0].Diffuse;
Mesh->m_Textures[0] = NULL;
Mesh->m_NumMaterials = 1;
} else {
// Load the materials
Materials = (D3DXMATERIAL*)MaterialBuffer->GetBufferPointer();
Mesh->m_Materials = new D3DMATERIAL8[Mesh->m_NumMaterials];
Mesh->m_Textures = new LPDIRECT3DTEXTURE8[Mesh->m_NumMaterials];
for(i=0;i<Mesh->m_NumMaterials;i++) {
Mesh->m_Materials[i] = Materials[i].MatD3D;
Mesh->m_Materials[i].Ambient = Mesh->m_Materials[i].Diffuse;
// Build a texture path and load it
sprintf(Path, "%s%s", TexturePath, Materials[i].pTextureFilename);
if(FAILED(D3DXCreateTextureFromFile(m_Graphics->GetDeviceCOM(),
Path,
&Mesh->m_Textures[i]))) {
Mesh->m_Textures[i] = NULL;
}
}
}
ReleaseCOM(MaterialBuffer);
// link in mesh
Mesh->m_Next = m_Meshes;
m_Meshes = Mesh;
m_NumMeshes++;
} else {
// Find mesh in list
Mesh = m_Meshes->FindMesh(Name);
}
// Add mesh to frame
if(Mesh != NULL)
ParentFrame->AddMesh(Mesh);
}
// Skip animation sets and animations
if(*Type == TID_D3DRMAnimationSet || *Type == TID_D3DRMAnimation || *Type == TID_D3DRMAnimationKey) {
delete [] Name;
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, SubFrame, TexturePath);
ReleaseCOM(pSubData);
}
ReleaseCOM(pDataRef);
}
// Process non-referenced embedded templates
if(SUCCEEDED(pSubObj->QueryInterface(IID_IDirectXFileData, (void**)&pSubData))) {
ParseXFileData(pSubData, SubFrame, TexturePath);
ReleaseCOM(pSubData);
}
ReleaseCOM(pSubObj);
}
return;
}
void cMesh::MapFramesToBones(sFrame *Frame)
{
sMesh *Mesh;
DWORD i;
char **Name;
// Return if no more frames to map
if(Frame == NULL || Frame->m_Name == NULL)
return;
// Scan through meshes looking for bone matches
Mesh = m_Meshes;
while(Mesh != NULL) {
if(Mesh->m_NumBones && Mesh->m_BoneNames != NULL && Mesh->m_Matrices != NULL && Mesh->m_FrameMatrices != NULL) {
Name = (char**)Mesh->m_BoneNames->GetBufferPointer();
for(i=0;i<Mesh->m_NumBones;i++) {
if(!strcmp(Frame->m_Name, Name[i])) {
Mesh->m_FrameMatrices[i] = &Frame->m_matCombined;
break;
}
}
}
Mesh = Mesh->m_Next;
}
// Scan through child frames
MapFramesToBones(Frame->m_Child);
// Scan through sibling frames
MapFramesToBones(Frame->m_Sibling);
}
BOOL cMesh::Free()
{
m_Graphics = NULL;
m_NumMeshes = 0;
delete m_Meshes;
m_Meshes = NULL;
m_NumFrames = 0;
delete m_Frames;
m_Frames = NULL;
m_Min.x = m_Min.y = m_Min.z = m_Max.x = m_Max.y = m_Max.z = 0.0f;
m_Radius = 0.0f;
return TRUE;
}
BOOL cMesh::IsLoaded()
{
if(m_Meshes != NULL && m_Frames != NULL)
return TRUE;
return FALSE;
}
long cMesh::GetNumFrames()
{
return m_NumFrames;
}
sFrame *cMesh::GetParentFrame()
{
return m_Frames;
}
sFrame *cMesh::GetFrame(char *Name)
{
if(m_Frames == NULL)
return NULL;
return m_Frames->FindFrame(Name);
}
long cMesh::GetNumMeshes()
{
return m_NumMeshes;
}
sMesh *cMesh::GetParentMesh()
{
return m_Meshes;
}
sMesh *cMesh::GetMesh(char *Name)
{
if(m_Meshes == NULL)
return NULL;
return m_Meshes->FindMesh(Name);
}
BOOL cMesh::GetBounds(float *MinX, float *MinY, float *MinZ, float *MaxX, float *MaxY, float *MaxZ, float *Radius)
{
if(MinX != NULL)
*MinX = m_Min.x;
if(MinY != NULL)
*MinY = m_Min.y;
if(MinZ != NULL)
*MinZ = m_Min.z;
if(MaxX != NULL)
*MaxX = m_Max.x;
if(MaxY != NULL)
*MaxY = m_Max.y;
if(MaxZ != NULL)
*MaxZ = m_Max.z;
if(Radius != NULL)
*Radius = m_Radius;
return TRUE;
}
cObject::cObject()
{
m_Graphics = NULL;
m_Mesh = NULL;
m_AnimationSet = NULL;
}
cObject::~cObject()
{
Free();
}
BOOL cObject::Create(cGraphics *Graphics, cMesh *Mesh)
{
if((m_Graphics = Graphics) == NULL)
return FALSE;
m_Mesh = Mesh;
Move(0.0f, 0.0f, 0.0f);
Rotate(0.0f, 0.0f, 0.0f);
Scale(1.0f, 1.0f, 1.0f);
return TRUE;
}
BOOL cObject::Free()
{
m_Graphics = NULL;
m_Mesh = NULL;
m_AnimationSet = NULL;
return TRUE;
}
BOOL cObject::EnableBillboard(BOOL Enable)
{
m_Pos.EnableBillboard(Enable);
return TRUE;
}
BOOL cObject::AttachToObject(cObject *Object, char *FrameName)
{
sFrame *Frame;
if(Object == NULL || Object->m_Mesh == NULL) {
m_Pos.SetCombineMatrix1(NULL);
m_Pos.SetCombineMatrix2(NULL);
} else {
Frame = Object->m_Mesh->GetFrame(FrameName);
if(Frame == NULL) {
m_Pos.SetCombineMatrix1(NULL);
m_Pos.SetCombineMatrix2(NULL);
} else {
m_Pos.SetCombineMatrix1(&Frame->m_matCombined);
m_Pos.SetCombineMatrix2(Object->m_Pos.GetMatrix());
}
}
return TRUE;
}
BOOL cObject::Move(float XPos, float YPos, float ZPos)
{
return m_Pos.Move(XPos, YPos, ZPos);
}
BOOL cObject::MoveRel(float XAdd, float YAdd, float ZAdd)
{
return m_Pos.MoveRel(XAdd, YAdd, ZAdd);
}
BOOL cObject::Rotate(float XRot, float YRot, float ZRot)
{
return m_Pos.Rotate(XRot, YRot, ZRot);
}
BOOL cObject::RotateRel(float XAdd, float YAdd, float ZAdd)
{
return m_Pos.RotateRel(XAdd, YAdd, ZAdd);
}
BOOL cObject::Scale(float XScale, float YScale, float ZScale)
{
return m_Pos.Scale(XScale, YScale, ZScale);
}
BOOL cObject::ScaleRel(float XAdd, float YAdd, float ZAdd)
{
return m_Pos.ScaleRel(XAdd, YAdd, ZAdd);
}
D3DXMATRIX *cObject::GetMatrix()
{
return m_Pos.GetMatrix();
}
BOOL cObject::SetMesh(cMesh *Mesh)
{
m_Mesh = Mesh;
return TRUE;
}
cMesh *cObject::GetMesh()
{
return m_Mesh;
}
BOOL cObject::SetAnimation(cAnimation *Animation, char *Name, unsigned long StartTime)
{
m_StartTime = StartTime;
if(Animation == NULL)
m_AnimationSet = NULL;
else
m_AnimationSet = Animation->GetAnimationSet(Name);
return TRUE;
}
char *cObject::GetAnimation()
{
if(m_AnimationSet == NULL)
return NULL;
return m_AnimationSet->m_Name;
}
BOOL cObject::ResetAnimation(unsigned long StartTime)
{
m_StartTime = StartTime;
return TRUE;
}
float cObject::GetXPos()
{
return m_Pos.GetXPos();
}
float cObject::GetYPos()
{
return m_Pos.GetYPos();
}
float cObject::GetZPos()
{
return m_Pos.GetZPos();
}
float cObject::GetXRotation()
{
return m_Pos.GetXRotation();
}
float cObject::GetYRotation()
{
return m_Pos.GetYRotation();
}
float cObject::GetZRotation()
{
return m_Pos.GetZRotation();
}
float cObject::GetXScale()
{
return m_Pos.GetXScale();
}
float cObject::GetYScale()
{
return m_Pos.GetYScale();
}
float cObject::GetZScale()
{
return m_Pos.GetZScale();
}
BOOL cObject::GetBounds(float *MinX, float *MinY, float *MinZ, float *MaxX, float *MaxY, float *MaxZ, float *Radius)
{
float Length, XScale, YScale, ZScale;
if(m_Mesh == NULL)
return FALSE;
m_Mesh->GetBounds(MinX, MinY, MinZ, MaxX, MaxY, MaxZ, Radius);
// Scale bounds
XScale = m_Pos.GetXScale();
YScale = m_Pos.GetYScale();
ZScale = m_Pos.GetZScale();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -