📄 core_graphics.cpp
字号:
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, NULL, &Mesh->m_NumMaterials,
&Mesh->m_SkinInfo,
&Mesh->m_Mesh))) {
delete Mesh;
return;
}
// Calculate the bounding box and sphere
if(SUCCEEDED(Mesh->m_Mesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&Ptr))) {
D3DXComputeBoundingBox((D3DXVECTOR3*)Ptr, Mesh->m_Mesh->GetNumVertices(),
Mesh->m_Mesh->GetNumBytesPerVertex(), &Mesh->m_Min, &Mesh->m_Max);
D3DXComputeBoundingSphere((D3DXVECTOR3*)Ptr, Mesh->m_Mesh->GetNumVertices(),
Mesh->m_Mesh->GetNumBytesPerVertex(),
&D3DXVECTOR3(0.0f,0.0f,0.0f), &Mesh->m_Radius);
Mesh->m_Mesh->UnlockVertexBuffer();
}
// Store # of bones (if any)
if(Mesh->m_SkinInfo)
Mesh->m_NumBones = Mesh->m_SkinInfo->GetNumBones();
// Create a matching skinned mesh if bone exist
if(Mesh->m_SkinInfo != NULL && Mesh->m_NumBones != 0) {
if(FAILED(Mesh->m_Mesh->CloneMeshFVF(0, Mesh->m_Mesh->GetFVF(),
m_Graphics->GetDeviceCOM(), &Mesh->m_SkinMesh)))
ReleaseCOM(Mesh->m_SkinInfo);
}
// Create an array of matrices to store bone transformations
if(Mesh->m_SkinInfo != NULL && Mesh->m_NumBones != 0) {
// 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;
}
// Load materials or create a default one if none
if(!Mesh->m_NumMaterials) {
// Create a default one
Mesh->m_Materials = new D3DMATERIAL9[1];
Mesh->m_Textures = new LPDIRECT3DTEXTURE9[1];
ZeroMemory(Mesh->m_Materials, sizeof(D3DMATERIAL9));
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 D3DMATERIAL9[Mesh->m_NumMaterials];
Mesh->m_Textures = new LPDIRECT3DTEXTURE9[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;
// 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_SkinInfo && Mesh->m_NumBones && Mesh->m_Matrices != NULL && Mesh->m_FrameMatrices != NULL) {
for(i=0;i<Mesh->m_NumBones;i++) {
if(!strcmp(Frame->m_Name, Mesh->m_SkinInfo->GetBoneName(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();
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -