Hi
I know that DirectX specifies the GUIDS for data types within an x file in rmxfguid.h. My problem is that the values that my calls to LPD3DXFILEDATA->GetType() in my mesh parser sometimes return guids that are very similar but not exactly the same as those specified in rmxfguid.h.
Heres an Example:
Im loading a mesh with some frames specifed into my frame parser.
The frame parser opens an enumerates the x file and loops through the enumeration picking out each data object of type TID_D3DRMFrame
general X-File Parser
#ifndef _XFILEPARSER_H
#define _XFILEPARSER_H
#include "XFile.h"
class Base;
using namespace std;
class XFileParser
{
public:
XFileParser();
virtual ~XFileParser();
BOOL parse(LPCSTR fileName, void** Data = NULL);
// Functions to help retrieve data object information
char* getObjectName(LPD3DXFILEDATA pDataObj);
void* getObjectData(LPD3DXFILEDATA pDataObj,DWORD* size);
protected:
// Functions called when parsing begins and ends.
virtual BOOL BeginParse(void** Data){return TRUE;}
virtual BOOL EndParse(void** Data){return TRUE;}
// Function Called for every Data object found.
virtual BOOL parseObject(LPD3DXFILEDATA pDataObj,
LPD3DXFILEDATA pParentDataObj,
DWORD Depth,
void** Data, BOOL Reference)
{
return parseChildObjects(pDataObj,Depth,Data,Reference);
}
// Function Called to Enumerate Child Objects.
BOOL parseChildObjects(LPD3DXFILEDATA pDataObj,
DWORD Depth, void** Data,
BOOL ForceReference = FALSE);
LPCSTR FileName;
Base* base;
};
#endif
// CPP
#include "Base.h"
#include "XFileParser.h"
XFileParser::XFileParser()
{
base = Base::Instance();
}
XFileParser::~XFileParser()
{
}
BOOL XFileParser::parse(LPCSTR fileName,void** Data)
{
//Check if the file Exists
if(! base->fileExists(fileName))
{
sprintf(base->buffer,"XFile: '%s' \nDoes not exist!",fileName);
base->messageBox(base->hWnd,base->buffer,"File Not Found");
return FALSE;
}
FileName = fileName;
LPD3DXFILE pDXFile = NULL;
LPD3DXFILEENUMOBJECT pEnum = NULL;
LPD3DXFILEDATA pData = NULL;
//Create an IDirectXFile interface for the XFile.
if(FAILED(D3DXFileCreate(&pDXFile)))
{
base->messageBox(base->hWnd,"Failed to create DirectX XFile Interface!");
pDXFile->Release();
return FALSE;
}
//Register the Standard Templates
if(FAILED(pDXFile->RegisterTemplates((LPVOID)D3DRM_XTEMPLATES,D3DRM_XTEMPLATE_BYTES)))
{
base->messageBox(base->hWnd,"Failed to Register DirectX file Default Templates");
pDXFile->Release();
return FALSE;
}
//Create Enumeration Object
if(FAILED(pDXFile->CreateEnumObject((LPVOID)fileName,DXFILELOAD_FROMFILE,&pEnum)))
{
base->messageBox(base->hWnd,"Failed to Create File Enumeration Object from XFile.");
return FALSE;
}
// Call the begin parse function, continuing if allowed
if(BeginParse(Data) == TRUE) {
// Loop through all top-level objects, breaking on errors
BOOL ParseResult;
SIZE_T numChildren = 0;
pEnum->GetChildren(&numChildren); // This is a new bit
for(SIZE_T i=0; i < numChildren; i++)
{
if(SUCCEEDED(pEnum->GetChild(i,&pData)))
{
ParseResult = parseObject(pData, NULL, 0, Data, FALSE);
SafeRelease(pData);
if(ParseResult == FALSE)
break;
}
}
}
// Call end parse function
EndParse(Data);
//Release COM Objects
SafeRelease(pEnum);
SafeRelease(pDXFile);
return TRUE;
}
BOOL XFileParser::parseChildObjects(LPD3DXFILEDATA pDataObj,
DWORD Depth, void **Data,
BOOL ForceReference)
{
LPD3DXFILE pSubObj = NULL;
LPD3DXFILEDATA pSubData = NULL;
LPVOID pDataRef = NULL;
BOOL ParseResult = TRUE;
// Scan for embedded templates
//while(SUCCEEDED(pDataObj->GetNextObject(&pSubObj)))
//{
// Scan for embedded templates
SIZE_T numChildren = 0;
pDataObj->GetChildren(&numChildren); // This is a new bit
for(SIZE_T i=0; i < numChildren; i++)
{
if(SUCCEEDED(pDataObj->GetChild(i,&pSubData)))
{
// Process embedded references
if(pDataObj->IsReference())
{
// Resolve the data object
//if(SUCCEEDED(pDataRef->Resolve(&pSubData)))
{
// Parse the object, remembering the return code
ParseResult = parseObject(pSubData, pDataObj,Depth+1, Data, TRUE);
SafeRelease(pSubData);
}
SafeDelete(pDataRef);
// Return on parsing failure
if(ParseResult == FALSE)
return FALSE;
// Process non-referenced embedded templates
}else
{
// Parse the object, remembering the return code
ParseResult = parseObject(pSubData, pDataObj,Depth+1, Data,ForceReference);
SafeRelease(pSubData);
}
// Release the data object
SafeRelease(pSubObj);
// Return on parsing failure
if(ParseResult == FALSE)
return FALSE;
}
}
return TRUE;
}
char* XFileParser::getObjectName(LPD3DXFILEDATA pDataObj)
{
char *Name = NULL;
DWORD Size = 0;
// Error checking
if(pDataObj == NULL)
return NULL;
// Get the template name (if any)
if(FAILED(pDataObj->GetName(NULL, &Size)))
{
base->messageBox(base->hWnd,"Failed To Get Object Name!");
return NULL;
}
// Allocate a name buffer and retrieve name
if(Size > 1)
{
if((Name = new char[Size]) != NULL)
pDataObj->GetName(Name, &Size);
}
return Name;
}
void* XFileParser::getObjectData(LPD3DXFILEDATA pDataObj,
DWORD *size)
{
void *TemplateData = NULL;
DWORD TemplateSize = 0;
// Error checking
if(pDataObj == NULL)
return NULL;
// Get a data pointer to template
if(SUCCEEDED(pDataObj->Lock(&TemplateSize,(LPCVOID*)&TemplateData)))
{
pDataObj->Unlock();
}else
{
base->messageBox(base->hWnd,"Failed To Get Object Data");
}
//pDataObj->GetData(NULL,&TemplateSize,(PVOID*)&TemplateData);
// Save size if needed
if(size != NULL)
*size = TemplateSize;
return TemplateData;
}
Derived Frame Parser
#ifndef _FRAME_PARSER_H
#define _FRAME_PARSER_H
#include "XFileParser.h"
#include "XFile.h"
#include "Frame.h"
#include "D3DMESHCONTAINER_EX.h"
using namespace std;
struct FrameList
{
Frame * pFrame;
FrameList* pNext;
FrameList()
{
pFrame = NULL;
pNext = NULL;
}
~FrameList()
{
// SafeDelete(pFrame);
SafeDelete(pNext);
}
};
class FrameParser : public XFileParser
{
public:
FrameParser(); // Default No-args constructor.
FrameParser(LPCSTR fileName); //
virtual ~FrameParser();
void initialise(LPCSTR fileName);
void cleanUp();
UINT numFrames;
FrameList* flatList;
FrameList* flatListRoot;
// the root frame of the heiarachy
Frame* m_RootFrame;
private:
BOOL BeginParse(void** Data);
BOOL parseObject(LPD3DXFILEDATA pDataObj,
LPD3DXFILEDATA pParentDataObj,
DWORD Depth,
void** Data, BOOL Reference);
void appendToFlatList(Frame* pFrame);
};
#endif
// CPP
#include "Base.h"
#include "Frame.h"
#include "FrameParser.h"
FrameParser::FrameParser()
{
m_RootFrame = NULL;
flatList = NULL;
flatListRoot = NULL;
}
FrameParser::FrameParser(LPCSTR fileName)
{
m_RootFrame = NULL;
flatList = NULL;
flatListRoot = NULL;
initialise(fileName);
}
FrameParser::~FrameParser()
{
cleanUp();
}
void FrameParser::cleanUp()
{
SafeDelete(m_RootFrame);
SafeDelete(flatListRoot);
numFrames = 0;
}
void FrameParser::initialise(LPCSTR fileName)
{
parse(fileName);
}
BOOL FrameParser::BeginParse(void** Data)
{
//Clear Hierarchy
cleanUp();
return TRUE;
}
BOOL FrameParser::parseObject(LPD3DXFILEDATA pDataObj,
LPD3DXFILEDATA pParentDataObj,
DWORD Depth,
void** Data, BOOL Reference)
{
//Skip Reference Objects
if(Reference == TRUE)
return TRUE;
GUID type;
pDataObj->GetType( &type );
//If the object type is a frame (non-referenced)
//then add it to the hierarchy
if(type == TID_D3DRMFrame)
{
//char* Name = getObjectName(pDataObj);
//base->messageBox(base->hWnd,Name,"Frame Object");
//delete [] Name;
//Alocate a frame container
Frame* pFrame = new Frame();
numFrames ++;
//Get Frame Name (assign one if none found)
if((pFrame->Name = getObjectName(pDataObj)) == NULL)
{
pFrame->Name = _strdup("No Name Frame");
}
//Link Frame Structure into list
if(Data == NULL)
{
//Link as a sibling of root
pFrame->pFrameSibling = m_RootFrame;
m_RootFrame = pFrame;
appendToFlatList(pFrame);
pFrame = NULL;
Data = (void**)&m_RootFrame;
}
else
{
//Link as a child of the supplied frame
Frame* pFramePtr = (Frame*)*Data;
pFrame->pFrameSibling = pFramePtr->pFrameFirstChild;
pFramePtr->pFrameFirstChild = pFrame;
appendToFlatList(pFrame);
pFrame = NULL;
Data = (void**)&pFramePtr->pFrameFirstChild;
}
SafeDelete(&type);
}
//Load Frame Transformation matrix
if(type == TID_D3DRMFrameTransformMatrix)
{
Frame* pFrame = (Frame*)*Data;
if(pFrame)
{
pFrame->TransformationMatrix = *(D3DXMATRIX*) getObjectData(pDataObj,NULL);
pFrame->matOriginal = pFrame->TransformationMatrix;
}
SafeDelete(&type);
}
return parseChildObjects(pDataObj,Depth,Data,Reference);
}
void FrameParser::appendToFlatList(Frame* pFrame)
{
if(!flatList)
{
flatList = new FrameList();
flatListRoot = flatList;
flatList->pFrame = pFrame;
flatList->pNext = new FrameList();
}else
{
flatList = flatList->pNext;
flatList->pFrame = pFrame;
flatList->pNext = new FrameList();
}
}
The problem is here:
GUID type;
pDataObj->GetType( &type );
//If the object type is a frame (non-referenced)
//then add it to the hierarchy
if(type == TID_D3DRMFrame)
{
The first frame found in each model works fine, the GUID defined in rmxfguid.h for TID_D3DRMFrame is the same as that in the GUID type found by pDataObj->GetType(&type), the parser then continues through other data but when it gets to the next frame, the GetType returns a very similar but not identical GUID. for example:
/* {3D82AB46-62DA-11cf-AB39-0020AF71E433} */
DEFINE_GUID(TID_D3DRMFrame,
0x3d82ab46, 0x62da, 0x11cf, 0xab, 0x39, 0x0, 0x20, 0xaf, 0x71, 0xe4, 0x33);
on the first frame found, type ={3D82AB46-62DA-11cf-AB39-0020AF71E433}, which is correct. However, on the second frame found, type = {3D82AB44-62DA-11cf-AB39-0020AF71E433} (NOTE THAT THE 8th NUMBER IN THE GUID IS DIFFERENT).As a result of that difference, the frame is not recognised as an TID_D3DRMFrame and is lost.
Can anyone think of a reason why this is happening?