X File child frame workaround
X File child frame workaround
It seems that some X file exporters (e.g. PandaExporter with 3dsmax 5) create sub child hierachies that can't be processed by Irrlicht.
I present the following workaround. It isn't a complete solution, rather a quick and dirty fix. It works by bypassing a frame/transformation matrix combo that follows an initial frame/transformation combo. This works for me and may for others. It should also be compatible with simpler/flater formats. It may still not accomodate advanced setups where a better child frame processing would be beneficial.
Updates in red:
bool CXFileReader::parseDataObjectFrame(SXFrame& frame)
{
static skip=0;
static skip_closing_brackets=0;
#ifdef _XREADER_DEBUG
os::Printer::log("CXFileReader: Reading frame");
#endif
// A coordinate frame, or "frame of reference." The Frame template
// is open and can contain any object. The Direct3D extensions (D3DX)
// mesh-loading functions recognize Mesh, FrameTransformMatrix, and
// Frame template instances as child objects when loading a Frame
// instance.
if (!readHeadOfDataObject(&frame.Name))
{
os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING);
return false;
}
// jetzt sind wir im frame.
// solange tokens lesen, bis closing brace erreicht
while(true)
{
if (skip>0)
skip--;
core::stringc objectName = getNextToken();
if (objectName.size() == 0)
{
os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING);
return false;
}
else
if (objectName == "}")
{
if (skip_closing_brackets==0)
break; // frame finished
else
skip_closing_brackets--;
}
else
if (objectName == "Frame")
{
if (skip!=0)
{
getNextToken();
}
else
{
frame.ChildFrames.push_back(SXFrame());
if (!parseDataObjectFrame(frame.ChildFrames[frame.ChildFrames.size()-1]))
return false;
}
}
else
if (objectName == "FrameTransformMatrix")
{
if (skip!=0)
{
parseUnknownDataObject();
}
else
{
skip=3;
skip_closing_brackets=1;
if (!parseDataObjectTransformationMatrix(frame.LocalMatrix))
return false;
}
}
else
if (objectName == "Mesh")
{
frame.Meshes.push_back(SXMesh());
if (!parseDataObjectMesh(frame.Meshes[frame.Meshes.size()-1]))
return false;
}
else
{
os::Printer::log("Unknown data object in frame in x file", objectName.c_str());
if (!parseUnknownDataObject())
return false;
}
}
return true;
}
Regards
Joe
I present the following workaround. It isn't a complete solution, rather a quick and dirty fix. It works by bypassing a frame/transformation matrix combo that follows an initial frame/transformation combo. This works for me and may for others. It should also be compatible with simpler/flater formats. It may still not accomodate advanced setups where a better child frame processing would be beneficial.
Updates in red:
bool CXFileReader::parseDataObjectFrame(SXFrame& frame)
{
static skip=0;
static skip_closing_brackets=0;
#ifdef _XREADER_DEBUG
os::Printer::log("CXFileReader: Reading frame");
#endif
// A coordinate frame, or "frame of reference." The Frame template
// is open and can contain any object. The Direct3D extensions (D3DX)
// mesh-loading functions recognize Mesh, FrameTransformMatrix, and
// Frame template instances as child objects when loading a Frame
// instance.
if (!readHeadOfDataObject(&frame.Name))
{
os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING);
return false;
}
// jetzt sind wir im frame.
// solange tokens lesen, bis closing brace erreicht
while(true)
{
if (skip>0)
skip--;
core::stringc objectName = getNextToken();
if (objectName.size() == 0)
{
os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING);
return false;
}
else
if (objectName == "}")
{
if (skip_closing_brackets==0)
break; // frame finished
else
skip_closing_brackets--;
}
else
if (objectName == "Frame")
{
if (skip!=0)
{
getNextToken();
}
else
{
frame.ChildFrames.push_back(SXFrame());
if (!parseDataObjectFrame(frame.ChildFrames[frame.ChildFrames.size()-1]))
return false;
}
}
else
if (objectName == "FrameTransformMatrix")
{
if (skip!=0)
{
parseUnknownDataObject();
}
else
{
skip=3;
skip_closing_brackets=1;
if (!parseDataObjectTransformationMatrix(frame.LocalMatrix))
return false;
}
}
else
if (objectName == "Mesh")
{
frame.Meshes.push_back(SXMesh());
if (!parseDataObjectMesh(frame.Meshes[frame.Meshes.size()-1]))
return false;
}
else
{
os::Printer::log("Unknown data object in frame in x file", objectName.c_str());
if (!parseUnknownDataObject())
return false;
}
}
return true;
}
Regards
Joe
-
- Posts: 1
- Joined: Mon Oct 04, 2004 1:45 am
Could you wrap that in
Code: Select all
tags so that the whitespace isn't lost plz?
Here you go:
Code: Select all
bool CXFileReader::parseDataObjectFrame(SXFrame& frame)
{
static skip=0;
static skip_closing_brackets=0;
#ifdef _XREADER_DEBUG
os::Printer::log("CXFileReader: Reading frame");
#endif
// A coordinate frame, or "frame of reference." The Frame template
// is open and can contain any object. The Direct3D extensions (D3DX)
// mesh-loading functions recognize Mesh, FrameTransformMatrix, and
// Frame template instances as child objects when loading a Frame
// instance.
if (!readHeadOfDataObject(&frame.Name))
{
os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING);
return false;
}
// jetzt sind wir im frame.
// solange tokens lesen, bis closing brace erreicht
while(true)
{
if (skip>0)
skip--;
core::stringc objectName = getNextToken();
if (objectName.size() == 0)
{
os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING);
return false;
}
else
if (objectName == "}")
{
if (skip_closing_brackets==0)
break; // frame finished
else
skip_closing_brackets--;
}
else
if (objectName == "Frame")
{
if (skip!=0)
{
getNextToken();
}
else
{
frame.ChildFrames.push_back(SXFrame());
if (!parseDataObjectFrame(frame.ChildFrames[frame.ChildFrames.size()-1]))
return false;
}
}
else
if (objectName == "FrameTransformMatrix")
{
if (skip!=0)
{
parseUnknownDataObject();
}
else
{
skip=3;
skip_closing_brackets=1;
if (!parseDataObjectTransformationMatrix(frame.LocalMatrix))
return false;
}
}
else
if (objectName == "Mesh")
{
frame.Meshes.push_back(SXMesh());
if (!parseDataObjectMesh(frame.Meshes[frame.Meshes.size()-1]))
return false;
}
else
{
os::Printer::log("Unknown data object in frame in x file", objectName.c_str());
if (!parseUnknownDataObject())
return false;
}
}
return true;
}
Dear niko:
I find the bug about the load the Xfile, and I send the file to the JoeWright. and below is his reply
I've just had a quick look at it. Even with the bug fixes I put in the forum I don't think Irrlicht will read it because of the frame hierachy. I think my sub frame fix only fixed it if there were two layers but in your's there is 3.
I've left it to Niko to sort the sub frame stuff out. Maybe if you posted a message in the bug forum it would remind him.
Regards
Joe
ttom
I find the bug about the load the Xfile, and I send the file to the JoeWright. and below is his reply
I've just had a quick look at it. Even with the bug fixes I put in the forum I don't think Irrlicht will read it because of the frame hierachy. I think my sub frame fix only fixed it if there were two layers but in your's there is 3.
I've left it to Niko to sort the sub frame stuff out. Maybe if you posted a message in the bug forum it would remind him.
Regards
Joe
ttom