start to migrate colladat and amf

pull/2966/head
Kim Kulling 2020-06-27 15:57:06 +02:00
parent 2be731d1bf
commit fb20e15163
14 changed files with 1108 additions and 782 deletions

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -82,7 +80,7 @@ void AMFImporter::Clear() {
mTexture_Converted.clear(); mTexture_Converted.clear();
// Delete all elements // Delete all elements
if (!mNodeElement_List.empty()) { if (!mNodeElement_List.empty()) {
for (CAMFImporter_NodeElement *ne : mNodeElement_List) { for (AMFNodeElementBase *ne : mNodeElement_List) {
delete ne; delete ne;
} }
@ -90,8 +88,14 @@ void AMFImporter::Clear() {
} }
} }
AMFImporter::AMFImporter() :
mNodeElement_Cur(nullptr),
mXmlParser(nullptr) {
// empty
}
AMFImporter::~AMFImporter() { AMFImporter::~AMFImporter() {
if (mReader != nullptr) delete mReader; delete mXmlParser;
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted. // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
Clear(); Clear();
} }
@ -100,10 +104,12 @@ AMFImporter::~AMFImporter() {
/************************************************************ Functions: find set ************************************************************/ /************************************************************ Functions: find set ************************************************************/
/*********************************************************************************************************************************************/ /*********************************************************************************************************************************************/
bool AMFImporter::Find_NodeElement(const std::string &pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement **pNodeElement) const { bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const {
for (CAMFImporter_NodeElement *ne : mNodeElement_List) { for (AMFNodeElementBase *ne : mNodeElement_List) {
if ((ne->ID == pID) && (ne->Type == pType)) { if ((ne->ID == pID) && (ne->Type == pType)) {
if (pNodeElement != nullptr) *pNodeElement = ne; if (pNodeElement != nullptr) {
*pNodeElement = ne;
}
return true; return true;
} }
@ -117,7 +123,9 @@ bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list<aiNode *>
for (aiNode *node : pNodeList) { for (aiNode *node : pNodeList) {
if (node->mName == node_name) { if (node->mName == node_name) {
if (pNode != nullptr) *pNode = node; if (pNode != nullptr) {
*pNode = node;
}
return true; return true;
} }
@ -129,7 +137,9 @@ bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list<aiNode *>
bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const { bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const {
for (const SPP_Material &mat : mMaterial_Converted) { for (const SPP_Material &mat : mMaterial_Converted) {
if (mat.ID == pID) { if (mat.ID == pID) {
if (pConvertedMaterial != nullptr) *pConvertedMaterial = &mat; if (pConvertedMaterial != nullptr) {
*pConvertedMaterial = &mat;
}
return true; return true;
} }
@ -142,20 +152,20 @@ bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Mater
/************************************************************ Functions: throw set ***********************************************************/ /************************************************************ Functions: throw set ***********************************************************/
/*********************************************************************************************************************************************/ /*********************************************************************************************************************************************/
void AMFImporter::Throw_CloseNotFound(const std::string &pNode) { void AMFImporter::Throw_CloseNotFound(const std::string &nodeName) {
throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt."); throw DeadlyImportError("Close tag for node <" + nodeName + "> not found. Seems file is corrupt.");
} }
void AMFImporter::Throw_IncorrectAttr(const std::string &pAttrName) { void AMFImporter::Throw_IncorrectAttr(const std::string &nodeName, const std::string &attrName) {
throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\"."); throw DeadlyImportError("Node <" + nodeName + "> has incorrect attribute \"" + attrName + "\".");
} }
void AMFImporter::Throw_IncorrectAttrValue(const std::string &pAttrName) { void AMFImporter::Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &attrName) {
throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value."); throw DeadlyImportError("Attribute \"" + attrName + "\" in node <" + nodeName + "> has incorrect value.");
} }
void AMFImporter::Throw_MoreThanOnceDefined(const std::string &pNodeType, const std::string &pDescription) { void AMFImporter::Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) {
throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription); throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + nodeName + ". Description: " + pDescription);
} }
void AMFImporter::Throw_ID_NotFound(const std::string &pID) const { void AMFImporter::Throw_ID_NotFound(const std::string &pID) const {
@ -166,8 +176,10 @@ void AMFImporter::Throw_ID_NotFound(const std::string &pID) const {
/************************************************************* Functions: XML set ************************************************************/ /************************************************************* Functions: XML set ************************************************************/
/*********************************************************************************************************************************************/ /*********************************************************************************************************************************************/
void AMFImporter::XML_CheckNode_MustHaveChildren() { void AMFImporter::XML_CheckNode_MustHaveChildren(pugi::xml_node &node) {
if (mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children."); if (node.children().begin() == node.children().end()) {
throw DeadlyImportError(std::string("Node <") + node.name() + "> must have children.");
}
} }
void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string &pParentNodeName) { void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string &pParentNodeName) {
@ -211,9 +223,10 @@ casu_cres:
} }
} }
bool AMFImporter::XML_SearchNode(const std::string &pNodeName) { bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
mXmlParser->h(nodeName);
while (mReader->read()) { while (mReader->read()) {
if ((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true; if ((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(nodeName)) return true;
} }
return false; return false;
@ -366,23 +379,24 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if (file.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + "."); if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
}
// generate a XML reader for it mXmlParser = new XmlParser();
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get())); if (!mXmlParser->parse( file.get() ) {
mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); delete mXmlParser;
if (!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
// }
// start reading
// search for root tag <amf> // Start reading, search for root tag <amf>
if (XML_SearchNode("amf")) if (!mXmlParser->hasNode("amf")) {
ParseNode_Root();
else
throw DeadlyImportError("Root node \"amf\" not found."); throw DeadlyImportError("Root node \"amf\" not found.");
}
ParseNode_Root();
delete mReader; delete mReader;
// restore old XMLreader
mReader = OldReader;
} }
// <amf // <amf

View File

@ -52,11 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter_Node.hpp" #include "AMFImporter_Node.hpp"
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include "assimp/types.h" #include "assimp/types.h"
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h> #include <assimp/XmlParser.h>
#include <assimp/importerdesc.h>
#include <assimp/DefaultLogger.hpp>
// Header files, stdlib. // Header files, stdlib.
#include <set> #include <set>
@ -261,11 +261,7 @@ private:
public: public:
/// Default constructor. /// Default constructor.
AMFImporter() AI_NO_EXCEPT AMFImporter() AI_NO_EXCEPT;
: mNodeElement_Cur(nullptr)
, mXmlParser(nullptr) {
// empty
}
/// Default destructor. /// Default destructor.
~AMFImporter(); ~AMFImporter();
@ -280,6 +276,15 @@ public:
void GetExtensionList(std::set<std::string> &pExtensionList); void GetExtensionList(std::set<std::string> &pExtensionList);
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
const aiImporterDesc *GetInfo() const; const aiImporterDesc *GetInfo() const;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, std::list<aiNode *> &pNodeList, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
void Throw_CloseNotFound(const std::string &nodeName);
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
void Throw_ID_NotFound(const std::string &pID) const;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
AMFImporter(const AMFImporter &pScene) = delete; AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter &operator=(const AMFImporter &pScene) = delete; AMFImporter &operator=(const AMFImporter &pScene) = delete;
@ -290,11 +295,9 @@ private:
AMFNodeElementBase *mNodeElement_Cur; ///< Current element. AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph. std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
XmlParser *mXmlParser; XmlParser *mXmlParser;
//irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mUnit; std::string mUnit;
std::list<SPP_Material> mMaterial_Converted; ///< List of converted materials for postprocessing step. std::list<SPP_Material> mMaterial_Converted; ///< List of converted materials for postprocessing step.
std::list<SPP_Texture> mTexture_Converted; ///< List of converted textures for postprocessing step. std::list<SPP_Texture> mTexture_Converted; ///< List of converted textures for postprocessing step.
}; };
} // namespace Assimp } // namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -51,22 +49,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter.hpp" #include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp" #include "AMFImporter_Macro.hpp"
namespace Assimp #include <assimp/ParsingUtils.h>
{
namespace Assimp {
// <mesh> // <mesh>
// </mesh> // </mesh>
// A 3D mesh hull. // A 3D mesh hull.
// Multi elements - Yes. // Multi elements - Yes.
// Parent element - <object>. // Parent element - <object>.
void AMFImporter::ParseNode_Mesh() void AMFImporter::ParseNode_Mesh(XmlNode &node) {
{ AMFNodeElementBase *ne = nullptr;
CAMFImporter_NodeElement* ne;
// create new mesh object. // create new mesh object.
ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur); ne = new AMFMesh(mNodeElement_Cur);
// Check for child nodes // Check for child nodes
if(!mReader->isEmptyElement()) if (0 != ASSIMP_stricmp(node.name(), "mesh")) {
return;
}
bool found_verts = false, found_volumes = false;
pugi::xml_node vertNode = node.child("vertices");
if (!vertNode.empty()) {
ParseNode_Vertices(vertNode);
found_verts = true;
}
pugi::xml_node volumeNode = node.child("volume");
if (!volumeNode.empty()) {
ParseNode_Volume(volumeNode);
found_volumes = true;
}
/*if(!mReader->isEmptyElement())
{ {
bool vert_read = false; bool vert_read = false;
@ -87,12 +102,14 @@ CAMFImporter_NodeElement* ne;
MACRO_NODECHECK_LOOPEND("mesh"); MACRO_NODECHECK_LOOPEND("mesh");
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
}// if(!mReader->isEmptyElement()) }// if(!mReader->isEmptyElement())
else else*/
{ // Add element to child list of current element
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element if (!found_verts && !found_volumes) {
mNodeElement_Cur->Child.push_back(ne);
} // if(!mReader->isEmptyElement()) else } // if(!mReader->isEmptyElement()) else
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. // and to node element list because its a new object in graph.
mNodeElement_List.push_back(ne);
} }
// <vertices> // <vertices>
@ -100,25 +117,32 @@ CAMFImporter_NodeElement* ne;
// The list of vertices to be used in defining triangles. // The list of vertices to be used in defining triangles.
// Multi elements - No. // Multi elements - No.
// Parent element - <mesh>. // Parent element - <mesh>.
void AMFImporter::ParseNode_Vertices() void AMFImporter::ParseNode_Vertices(XmlNode &node) {
{ AMFNodeElementBase *ne = nullptr;
CAMFImporter_NodeElement* ne;
// create new mesh object. // create new mesh object.
ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur); ne = new AMFVertices(mNodeElement_Cur);
// Check for child nodes // Check for child nodes
if(!mReader->isEmptyElement()) pugi::xml_node vertexNode = node.child("vertex");
{ if (!vertexNode.empty()) {
ParseNode_Vertex(vertexNode);
} else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else
/*if (!mReader->isEmptyElement()) {
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("vertices"); MACRO_NODECHECK_LOOPBEGIN("vertices");
if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; } if (XML_CheckNode_NameEqual("vertex")) {
ParseNode_Vertex();
continue;
}
MACRO_NODECHECK_LOOPEND("vertices"); MACRO_NODECHECK_LOOPEND("vertices");
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
} // if(!mReader->isEmptyElement()) } // if(!mReader->isEmptyElement())
else else {
{
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
}// if(!mReader->isEmptyElement()) else } // if(!mReader->isEmptyElement()) else*/
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
} }
@ -128,22 +152,33 @@ CAMFImporter_NodeElement* ne;
// A vertex to be referenced in triangles. // A vertex to be referenced in triangles.
// Multi elements - Yes. // Multi elements - Yes.
// Parent element - <vertices>. // Parent element - <vertices>.
void AMFImporter::ParseNode_Vertex() void AMFImporter::ParseNode_Vertex(XmlNode &node) {
{ AMFNodeElementBase *ne = nullptr;
CAMFImporter_NodeElement* ne;
// create new mesh object. // create new mesh object.
ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur); ne = new AMFVertex(mNodeElement_Cur);
// Check for child nodes pugi::xml_node colorNode = node.child("color");
if(!mReader->isEmptyElement())
{
bool col_read = false; bool col_read = false;
bool coord_read = false; bool coord_read = false;
if (!colorNode.empty()) {
ParseNode_Color(colorNode);
col_read = true;
}
pugi::xml_node coordNode = node.child("coordinates");
if (!coordNode.empty()) {
ParseNode_Coordinates(coordNode);
coord_read = true;
}
if (!coord_read && !coord_read) {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
}
// Check for child nodes
/* if (!mReader->isEmptyElement()) {
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("vertex"); MACRO_NODECHECK_LOOPBEGIN("vertex");
if(XML_CheckNode_NameEqual("color")) if (XML_CheckNode_NameEqual("color")) {
{
// Check if data already defined. // Check if data already defined.
if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>."); if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>.");
// read data and set flag about it // read data and set flag about it
@ -153,8 +188,7 @@ CAMFImporter_NodeElement* ne;
continue; continue;
} }
if(XML_CheckNode_NameEqual("coordinates")) if (XML_CheckNode_NameEqual("coordinates")) {
{
// Check if data already defined. // Check if data already defined.
if (coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>."); if (coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>.");
// read data and set flag about it // read data and set flag about it
@ -164,15 +198,17 @@ CAMFImporter_NodeElement* ne;
continue; continue;
} }
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } if (XML_CheckNode_NameEqual("metadata")) {
ParseNode_Metadata();
continue;
}
MACRO_NODECHECK_LOOPEND("vertex"); MACRO_NODECHECK_LOOPEND("vertex");
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
} // if(!mReader->isEmptyElement()) } // if(!mReader->isEmptyElement())
else else {
{
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else } // if(!mReader->isEmptyElement()) else
*/
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
} }
@ -186,18 +222,24 @@ CAMFImporter_NodeElement* ne;
// <x>, <y>, <z> // <x>, <y>, <z>
// Multi elements - No. // Multi elements - No.
// X, Y, or Z coordinate, respectively, of a vertex position in space. // X, Y, or Z coordinate, respectively, of a vertex position in space.
void AMFImporter::ParseNode_Coordinates() void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
{ AMFNodeElementBase *ne = nullptr;
CAMFImporter_NodeElement* ne;
// create new color object. // create new color object.
ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur); ne = new AMFCoordinates(mNodeElement_Cur);
CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
// Check for child nodes if (node.attributes().begin() != node.attributes().end()) {
if(!mReader->isEmptyElement()) als.Coordinate.x = (ai_real)node.attribute("x").as_float();
{ als.Coordinate.y = (ai_real)node.attribute("y").as_float();
als.Coordinate.z = (ai_real)node.attribute("z").as_float();
} else {
mNodeElement_Cur->Child.push_back(ne);
}
/*// Check for child nodes
if (!mReader->isEmptyElement()) {
bool read_flag[3] = { false, false, false }; bool read_flag[3] = { false, false, false };
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
@ -211,10 +253,9 @@ CAMFImporter_NodeElement* ne;
if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined."); if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined.");
} // if(!mReader->isEmptyElement()) } // if(!mReader->isEmptyElement())
else else {
{
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
}// if(!mReader->isEmptyElement()) else } // if(!mReader->isEmptyElement()) else*/
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
} }
@ -228,32 +269,31 @@ CAMFImporter_NodeElement* ne;
// Defines a volume from the established vertex list. // Defines a volume from the established vertex list.
// Multi elements - Yes. // Multi elements - Yes.
// Parent element - <mesh>. // Parent element - <mesh>.
void AMFImporter::ParseNode_Volume() void AMFImporter::ParseNode_Volume(XmlNode &node) {
{
std::string materialid; std::string materialid;
std::string type; std::string type;
CAMFImporter_NodeElement* ne; AMFNodeElementBase *ne = new AMFVolume(mNodeElement_Cur);
// Read attributes for node <color>. // Read attributes for node <color>.
MACRO_ATTRREAD_LOOPBEG; /*MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND; MACRO_ATTRREAD_LOOPEND;*/
// create new object. // create new object.
ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur); //ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur);
// and assign read data // and assign read data
((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid;
((CAMFImporter_NodeElement_Volume*)ne)->Type = type; ((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string();
((AMFVolume *)ne)->Type = type;
// Check for child nodes // Check for child nodes
if(!mReader->isEmptyElement()) if (!mReader->isEmptyElement()) {
{
bool col_read = false; bool col_read = false;
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("volume"); MACRO_NODECHECK_LOOPBEGIN("volume");
if(XML_CheckNode_NameEqual("color")) if (XML_CheckNode_NameEqual("color")) {
{
// Check if data already defined. // Check if data already defined.
if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>."); if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>.");
// read data and set flag about it // read data and set flag about it
@ -263,13 +303,18 @@ CAMFImporter_NodeElement* ne;
continue; continue;
} }
if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; } if (XML_CheckNode_NameEqual("triangle")) {
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } ParseNode_Triangle();
continue;
}
if (XML_CheckNode_NameEqual("metadata")) {
ParseNode_Metadata();
continue;
}
MACRO_NODECHECK_LOOPEND("volume"); MACRO_NODECHECK_LOOPEND("volume");
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
} // if(!mReader->isEmptyElement()) } // if(!mReader->isEmptyElement())
else else {
{
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else } // if(!mReader->isEmptyElement()) else
@ -286,8 +331,7 @@ CAMFImporter_NodeElement* ne;
// <v1>, <v2>, <v3> // <v1>, <v2>, <v3>
// Multi elements - No. // Multi elements - No.
// Index of the desired vertices in a triangle or edge. // Index of the desired vertices in a triangle or edge.
void AMFImporter::ParseNode_Triangle() void AMFImporter::ParseNode_Triangle() {
{
CAMFImporter_NodeElement *ne; CAMFImporter_NodeElement *ne;
// create new color object. // create new color object.
@ -296,15 +340,13 @@ CAMFImporter_NodeElement* ne;
CAMFImporter_NodeElement_Triangle &als = *((CAMFImporter_NodeElement_Triangle *)ne); // alias for convenience CAMFImporter_NodeElement_Triangle &als = *((CAMFImporter_NodeElement_Triangle *)ne); // alias for convenience
// Check for child nodes // Check for child nodes
if(!mReader->isEmptyElement()) if (!mReader->isEmptyElement()) {
{
bool col_read = false, tex_read = false; bool col_read = false, tex_read = false;
bool read_flag[3] = { false, false, false }; bool read_flag[3] = { false, false, false };
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("triangle"); MACRO_NODECHECK_LOOPBEGIN("triangle");
if(XML_CheckNode_NameEqual("color")) if (XML_CheckNode_NameEqual("color")) {
{
// Check if data already defined. // Check if data already defined.
if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>."); if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>.");
// read data and set flag about it // read data and set flag about it
@ -323,8 +365,7 @@ CAMFImporter_NodeElement* ne;
tex_read = true; tex_read = true;
continue; continue;
} } else if (XML_CheckNode_NameEqual("map")) // old name of node: "map".
else if(XML_CheckNode_NameEqual("map"))// old name of node: "map".
{ {
// Check if data already defined. // Check if data already defined.
if (tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>."); if (tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>.");
@ -344,8 +385,7 @@ CAMFImporter_NodeElement* ne;
if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined."); if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined.");
} // if(!mReader->isEmptyElement()) } // if(!mReader->isEmptyElement())
else else {
{
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else } // if(!mReader->isEmptyElement()) else

View File

@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter.hpp" #include "AMFImporter.hpp"
//#include "AMFImporter_Macro.hpp" //#include "AMFImporter_Macro.hpp"
namespace Assimp namespace Assimp {
{
// <color // <color
// profile="" - The ICC color space used to interpret the three color channels <r>, <g> and <b>. // profile="" - The ICC color space used to interpret the three color channels <r>, <g> and <b>.
@ -79,18 +78,19 @@ void AMFImporter::ParseNode_Color(XmlNode &node) {
if (!node.empty()) { if (!node.empty()) {
bool read_flag[4] = { false, false, false, false }; bool read_flag[4] = { false, false, false, false };
for (pugi::xml_node &child : node.children()) { for (pugi::xml_node &child : node.children()) {
if (child.name() == "r") { std::string name = child.name();
if ( name == "r") {
read_flag[0] = true; read_flag[0] = true;
als.Color.r = atof(child.value()); als.Color.r = (ai_real)::atof(child.value());
} else if (child.name() == "g") { } else if (name == "g") {
read_flag[1] = true; read_flag[1] = true;
als.Color.g = atof(child.value()); als.Color.g = (ai_real)::atof(child.value());
} else if (child.name() == "b") { } else if (name == "b") {
read_flag[2] = true; read_flag[2] = true;
als.Color.b = atof(child.value()); als.Color.b = (ai_real)::atof(child.value());
} else if (child.name() == "g") { } else if (name == "g") {
read_flag[3] = true; read_flag[3] = true;
als.Color.a = atof(child.value()); als.Color.a = (ai_real) ::atof(child.value());
} }
} }
// check that all components was defined // check that all components was defined
@ -127,10 +127,11 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
if (!node.empty()) { if (!node.empty()) {
bool col_read = false; bool col_read = false;
for (pugi::xml_node &child : node.children()) { for (pugi::xml_node &child : node.children()) {
if (child.name() == "color") { const std::string name = child.name();
if (name == "color") {
col_read = true; col_read = true;
ParseNode_Color(child); ParseNode_Color(child);
} else if (child.name() == "metadata") { } else if (name == "metadata") {
ParseNode_Metadata(child); ParseNode_Metadata(child);
} }
} }
@ -256,44 +257,46 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
if (!pUseOldName) { if (!pUseOldName) {
for (pugi::xml_attribute &attr : node.attributes()) { for (pugi::xml_attribute &attr : node.attributes()) {
if (attr.name() == "utex1") { const std::string name = attr.name();
if (name == "utex1") {
read_flag[0] = true; read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float(); als.TextureCoordinate[0].x = attr.as_float();
} else if (attr.name() == "utex2") { } else if (name == "utex2") {
read_flag[1] = true; read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float(); als.TextureCoordinate[1].x = attr.as_float();
} else if (attr.name() == "utex3") { } else if (name == "utex3") {
read_flag[2] = true; read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float(); als.TextureCoordinate[2].x = attr.as_float();
} else if (attr.name() == "vtex1") { } else if (name == "vtex1") {
read_flag[3] = true; read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float(); als.TextureCoordinate[0].y = attr.as_float();
} else if (attr.name() == "vtex2") { } else if (name == "vtex2") {
read_flag[4] = true; read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float(); als.TextureCoordinate[1].y = attr.as_float();
} else if (attr.name() == "vtex3") { } else if (name == "vtex3") {
read_flag[5] = true; read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float(); als.TextureCoordinate[0].y = attr.as_float();
} }
} }
} else { } else {
for (pugi::xml_attribute &attr : node.attributes()) { for (pugi::xml_attribute &attr : node.attributes()) {
if (attr.name() == "u") { const std::string name = attr.name();
if (name == "u") {
read_flag[0] = true; read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float(); als.TextureCoordinate[0].x = attr.as_float();
} else if (attr.name() == "u2") { } else if (name == "u2") {
read_flag[1] = true; read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float(); als.TextureCoordinate[1].x = attr.as_float();
} else if (attr.name() == "u3") { } else if (name == "u3") {
read_flag[2] = true; read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float(); als.TextureCoordinate[2].x = attr.as_float();
} else if (attr.name() == "v1") { } else if (name == "v1") {
read_flag[3] = true; read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float(); als.TextureCoordinate[0].y = attr.as_float();
} else if (attr.name() == "v2") { } else if (name == "v2") {
read_flag[4] = true; read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float(); als.TextureCoordinate[1].y = attr.as_float();
} else if (attr.name() == "v3") { } else if (name == "v3") {
read_flag[5] = true; read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float(); als.TextureCoordinate[0].y = attr.as_float();
} }

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -83,39 +81,41 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
return tcol; return tcol;
} }
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray, void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
std::vector<CAMFImporter_NodeElement_Color *> &pVertexColorArray) const { std::vector<AMFColor *> &pVertexColorArray) const {
CAMFImporter_NodeElement_Vertices *vn = nullptr; AMFVertex *vn = nullptr;
size_t col_idx; size_t col_idx;
// All data stored in "vertices", search for it. // All data stored in "vertices", search for it.
for (CAMFImporter_NodeElement *ne_child : pNodeElement.Child) { for (AMFNodeElementBase *ne_child : pNodeElement.Child) {
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices *)ne_child; if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
vn = (AMFVertex *)ne_child;
}
} }
// If "vertices" not found then no work for us. // If "vertices" not found then no work for us.
if (vn == nullptr) return; if (vn == nullptr) {
return;
}
pVertexCoordinateArray.reserve(vn->Child.size()); // all coordinates stored as child and we need to reserve space for future push_back's. pVertexCoordinateArray.reserve(vn->Child.size()); // all coordinates stored as child and we need to reserve space for future push_back's.
pVertexColorArray.resize(vn->Child.size()); // colors count equal vertices count. pVertexColorArray.resize(vn->Child.size()); // colors count equal vertices count.
col_idx = 0; col_idx = 0;
// Inside vertices collect all data and place to arrays // Inside vertices collect all data and place to arrays
for (CAMFImporter_NodeElement *vn_child : vn->Child) { for (AMFNodeElementBase *vn_child : vn->Child) {
// vertices, colors // vertices, colors
if (vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex) { if (vn_child->Type == AMFNodeElementBase::ENET_Vertex) {
// by default clear color for current vertex // by default clear color for current vertex
pVertexColorArray[col_idx] = nullptr; pVertexColorArray[col_idx] = nullptr;
for (CAMFImporter_NodeElement *vtx : vn_child->Child) { for (AMFNodeElementBase *vtx : vn_child->Child) {
if (vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates) { if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates *)vtx)->Coordinate); pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
continue; continue;
} }
if (vtx->Type == CAMFImporter_NodeElement::ENET_Color) { if (vtx->Type == AMFNodeElementBase::ENET_Color) {
pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color *)vtx; pVertexColorArray[col_idx] = (AMFColor *)vtx;
continue; continue;
} }
} // for(CAMFImporter_NodeElement* vtx: vn_child->Child) } // for(CAMFImporter_NodeElement* vtx: vn_child->Child)
@ -146,59 +146,77 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
} }
} }
//
// Converted texture not found, create it. // Converted texture not found, create it.
// AMFTexture *src_texture[4] {
CAMFImporter_NodeElement_Texture *src_texture[4]{ nullptr }; nullptr
std::vector<CAMFImporter_NodeElement_Texture *> src_texture_4check; };
std::vector<AMFTexture *> src_texture_4check;
SPP_Texture converted_texture; SPP_Texture converted_texture;
{ // find all specified source textures { // find all specified source textures
CAMFImporter_NodeElement *t_tex; AMFNodeElementBase *t_tex;
// R // R
if (!pID_R.empty()) { if (!pID_R.empty()) {
if (!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R); pugi::xml_node *node = mXmlParser->findNode(pID_R);
if (nullptr == node) {
throw DeadlyImportError("Id not found " + pID_R + ".");
}
//if (!Find_NodeElement(pID_R, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);
src_texture[0] = (CAMFImporter_NodeElement_Texture *)t_tex; src_texture[0] = (AMFTexture *)t_tex;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex); src_texture_4check.push_back((AMFTexture *)t_tex);
} else { } else {
src_texture[0] = nullptr; src_texture[0] = nullptr;
} }
// G // G
if (!pID_G.empty()) { if (!pID_G.empty()) {
if (!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G); pugi::xml_node *node = mXmlParser->findNode(pID_G);
if (nullptr == node) {
throw DeadlyImportError("Id not found " + pID_G + ".");
}
src_texture[1] = (CAMFImporter_NodeElement_Texture *)t_tex; //if (!Find_NodeElement(pID_G, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[1] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else { } else {
src_texture[1] = nullptr; src_texture[1] = nullptr;
} }
// B // B
if (!pID_B.empty()) { if (!pID_B.empty()) {
if (!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B); //if (!Find_NodeElement(pID_B, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B);
pugi::xml_node *node = mXmlParser->findNode(pID_B);
if (nullptr == node) {
throw DeadlyImportError("Id not found " + pID_B + ".");
}
src_texture[2] = (CAMFImporter_NodeElement_Texture *)t_tex; src_texture[2] = (AMFTexture *)t_tex;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex); src_texture_4check.push_back((AMFTexture *)t_tex);
} else { } else {
src_texture[2] = nullptr; src_texture[2] = nullptr;
} }
// A // A
if (!pID_A.empty()) { if (!pID_A.empty()) {
if (!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A); pugi::xml_node *node = mXmlParser->findNode(pID_A);
if (nullptr == node) {
throw DeadlyImportError("Id not found " + pID_A + ".");
}
src_texture[3] = (CAMFImporter_NodeElement_Texture *)t_tex; //if (!Find_NodeElement(pID_A, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[3] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else { } else {
src_texture[3] = nullptr; src_texture[3] = nullptr;
} }
} // END: find all specified source textures } // END: find all specified source textures
// check that all textures has same size // check that all textures has same size
if (src_texture_4check.size() > 1) { if (!src_texture_4check.empty() ) {
for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++) { for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++) {
if ((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) || if ((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) ||
(src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth)) { (src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth)) {
@ -255,7 +273,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
auto CopyTextureData = [&](const std::string &pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void { auto CopyTextureData = [&](const std::string &pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void {
if (!pID.empty()) { if (!pID.empty()) {
for (size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) { for (size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
CAMFImporter_NodeElement_Texture *tex = src_texture[pSrcTexNum]; AMFTexture *tex = src_texture[pSrcTexNum];
ai_assert(tex); ai_assert(tex);
converted_texture.Data[idx_target] = tex->Data.at(idx_src); converted_texture.Data[idx_target] = tex->Data.at(idx_src);
} }
@ -276,7 +294,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
} }
void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace> &pInputList, std::list<std::list<SComplexFace>> &pOutputList_Separated) { void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace> &pInputList, std::list<std::list<SComplexFace>> &pOutputList_Separated) {
auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap *pTexMap1, const CAMFImporter_NodeElement_TexMap *pTexMap2) -> bool { auto texmap_is_equal = [](const AMFTexMap *pTexMap1, const AMFTexMap *pTexMap2) -> bool {
if ((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true; if ((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true;
if (pTexMap1 == nullptr) return false; if (pTexMap1 == nullptr) return false;
if (pTexMap2 == nullptr) return false; if (pTexMap2 == nullptr) return false;
@ -313,56 +331,61 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
} while (!pInputList.empty()); } while (!pInputList.empty());
} }
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata *> &metadataList, aiNode &sceneNode) const { void AMFImporter::Postprocess_AddMetadata(const std::list<AMFMetadata *> &metadataList, aiNode &sceneNode) const {
if (!metadataList.empty()) { if (metadataList.empty()) {
if (sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); return;
}
if (sceneNode.mMetaData != nullptr) {
throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
}
// copy collected metadata to output node. // copy collected metadata to output node.
sceneNode.mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metadataList.size())); sceneNode.mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metadataList.size()));
size_t meta_idx(0); size_t meta_idx(0);
for (const CAMFImporter_NodeElement_Metadata &metadata : metadataList) { for (const AMFMetadata &metadata : metadataList) {
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value)); sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
} }
} // if(!metadataList.empty())
} }
void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode) { void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode) {
CAMFImporter_NodeElement_Color *object_color = nullptr; AMFColor *object_color = nullptr;
// create new aiNode and set name as <object> has. // create new aiNode and set name as <object> has.
*pSceneNode = new aiNode; *pSceneNode = new aiNode;
(*pSceneNode)->mName = pNodeElement.ID; (*pSceneNode)->mName = pNodeElement.ID;
// read mesh and color // read mesh and color
for (const CAMFImporter_NodeElement *ne_child : pNodeElement.Child) { for (const AMFNodeElementBase *ne_child : pNodeElement.Child) {
std::vector<aiVector3D> vertex_arr; std::vector<aiVector3D> vertex_arr;
std::vector<CAMFImporter_NodeElement_Color *> color_arr; std::vector<AMFColor *> color_arr;
// color for object // color for object
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color *)ne_child; if (ne_child->Type == AMFNodeElementBase::ENET_Color) {
object_color = (AMFColor *) ne_child;
}
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh) { if (ne_child->Type == AMFNodeElementBase::ENET_Mesh) {
// Create arrays from children of mesh: vertices. // Create arrays from children of mesh: vertices.
PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh *)ne_child), vertex_arr, color_arr); PostprocessHelper_CreateMeshDataArray(*((AMFMesh *)ne_child), vertex_arr, color_arr);
// Use this arrays as a source when creating every aiMesh // Use this arrays as a source when creating every aiMesh
Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh *)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode); Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
} }
} // for(const CAMFImporter_NodeElement* ne_child: pNodeElement) } // for(const CAMFImporter_NodeElement* ne_child: pNodeElement)
} }
void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray, void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray,
const std::vector<CAMFImporter_NodeElement_Color *> &pVertexColorArray, const std::vector<AMFColor *> &pVertexColorArray,
const CAMFImporter_NodeElement_Color *pObjectColor, std::list<aiMesh *> &pMeshList, aiNode &pSceneNode) { const AMFColor *pObjectColor, std::list<aiMesh *> &pMeshList, aiNode &pSceneNode) {
std::list<unsigned int> mesh_idx; std::list<unsigned int> mesh_idx;
// all data stored in "volume", search for it. // all data stored in "volume", search for it.
for (const CAMFImporter_NodeElement *ne_child : pNodeElement.Child) { for (const AMFNodeElementBase *ne_child : pNodeElement.Child) {
const CAMFImporter_NodeElement_Color *ne_volume_color = nullptr; const AMFColor *ne_volume_color = nullptr;
const SPP_Material *cur_mat = nullptr; const SPP_Material *cur_mat = nullptr;
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) { if (ne_child->Type == AMFNodeElementBase::ENET_Volume) {
/******************* Get faces *******************/ /******************* Get faces *******************/
const CAMFImporter_NodeElement_Volume *ne_volume = reinterpret_cast<const CAMFImporter_NodeElement_Volume *>(ne_child); const AMFVolume *ne_volume = reinterpret_cast<const AMFVolume *>(ne_child);
std::list<SComplexFace> complex_faces_list; // List of the faces of the volume. std::list<SComplexFace> complex_faces_list; // List of the faces of the volume.
std::list<std::list<SComplexFace>> complex_faces_toplist; // List of the face list for every mesh. std::list<std::list<SComplexFace>> complex_faces_toplist; // List of the face list for every mesh.
@ -373,13 +396,13 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
} }
// inside "volume" collect all data and place to arrays or create new objects // inside "volume" collect all data and place to arrays or create new objects
for (const CAMFImporter_NodeElement *ne_volume_child : ne_volume->Child) { for (const AMFNodeElementBase *ne_volume_child : ne_volume->Child) {
// color for volume // color for volume
if (ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color) { if (ne_volume_child->Type == AMFNodeElementBase::ENET_Color) {
ne_volume_color = reinterpret_cast<const CAMFImporter_NodeElement_Color *>(ne_volume_child); ne_volume_color = reinterpret_cast<const AMFColor *>(ne_volume_child);
} else if (ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle) // triangles, triangles colors } else if (ne_volume_child->Type == AMFNodeElementBase::ENET_Triangle) // triangles, triangles colors
{ {
const CAMFImporter_NodeElement_Triangle &tri_al = *reinterpret_cast<const CAMFImporter_NodeElement_Triangle *>(ne_volume_child); const AMFTriangle &tri_al = *reinterpret_cast<const AMFTriangle *>(ne_volume_child);
SComplexFace complex_face; SComplexFace complex_face;
@ -388,11 +411,11 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
complex_face.TexMap = nullptr; complex_face.TexMap = nullptr;
// get data from triangle children: color, texture coordinates. // get data from triangle children: color, texture coordinates.
if (tri_al.Child.size()) { if (tri_al.Child.size()) {
for (const CAMFImporter_NodeElement *ne_triangle_child : tri_al.Child) { for (const AMFNodeElementBase *ne_triangle_child : tri_al.Child) {
if (ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color) if (ne_triangle_child->Type == AMFNodeElementBase::ENET_Color)
complex_face.Color = reinterpret_cast<const CAMFImporter_NodeElement_Color *>(ne_triangle_child); complex_face.Color = reinterpret_cast<const AMFColor *>(ne_triangle_child);
else if (ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap) else if (ne_triangle_child->Type == AMFNodeElementBase::ENET_TexMap)
complex_face.TexMap = reinterpret_cast<const CAMFImporter_NodeElement_TexMap *>(ne_triangle_child); complex_face.TexMap = reinterpret_cast<const AMFTexMap *>(ne_triangle_child);
} }
} // if(tri_al.Child.size()) } // if(tri_al.Child.size())
@ -422,15 +445,18 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
if (face.Face.mIndices[idx_vert] > *pBiggerThan) { if (face.Face.mIndices[idx_vert] > *pBiggerThan) {
rv = face.Face.mIndices[idx_vert]; rv = face.Face.mIndices[idx_vert];
found = true; found = true;
break; break;
} }
} }
if (found) break; if (found) {
break;
}
} }
if (!found) return *pBiggerThan; if (!found) {
return *pBiggerThan;
}
} else { } else {
rv = pFaceList.front().Face.mIndices[0]; rv = pFaceList.front().Face.mIndices[0];
} // if(pBiggerThan != nullptr) else } // if(pBiggerThan != nullptr) else
@ -505,9 +531,9 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
tmesh->mNumFaces = static_cast<unsigned int>(face_list_cur.size()); tmesh->mNumFaces = static_cast<unsigned int>(face_list_cur.size());
tmesh->mFaces = new aiFace[tmesh->mNumFaces]; tmesh->mFaces = new aiFace[tmesh->mNumFaces];
// Create vertices list and optimize indices. Optimisation mean following.In AMF all volumes use one big list of vertices. And one volume // Create vertices list and optimize indices. Optimization mean following.In AMF all volumes use one big list of vertices. And one volume
// can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10. // can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10.
// Do you need all this thousands of garbage? Of course no. So, optimisation step transformate sparse indices set to continuous. // Do you need all this thousands of garbage? Of course no. So, optimization step transform sparse indices set to continuous.
size_t VertexCount_Max = tmesh->mNumFaces * 3; // 3 - triangles. size_t VertexCount_Max = tmesh->mNumFaces * 3; // 3 - triangles.
std::vector<aiVector3D> vert_arr, texcoord_arr; std::vector<aiVector3D> vert_arr, texcoord_arr;
std::vector<aiColor4D> col_arr; std::vector<aiColor4D> col_arr;
@ -566,7 +592,7 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
size_t idx_vert_new = vert_arr.size(); size_t idx_vert_new = vert_arr.size();
///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for ///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for
/// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about /// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about
/// optimisation. /// optimization.
bool *idx_vert_used; bool *idx_vert_used;
idx_vert_used = new bool[VertexCount_Max * 2]; idx_vert_used = new bool[VertexCount_Max * 2];
@ -639,15 +665,15 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
} // if(mesh_idx.size() > 0) } // if(mesh_idx.size() > 0)
} }
void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material &pMaterial) { void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &pMaterial) {
SPP_Material new_mat; SPP_Material new_mat;
new_mat.ID = pMaterial.ID; new_mat.ID = pMaterial.ID;
for (const CAMFImporter_NodeElement *mat_child : pMaterial.Child) { for (const AMFNodeElementBase *mat_child : pMaterial.Child) {
if (mat_child->Type == CAMFImporter_NodeElement::ENET_Color) { if (mat_child->Type == AMFNodeElementBase::ENET_Color) {
new_mat.Color = (CAMFImporter_NodeElement_Color *)mat_child; new_mat.Color = (AMFColor*)mat_child;
} else if (mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata) { } else if (mat_child->Type == AMFNodeElementBase::ENET_Metadata) {
new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata *)mat_child); new_mat.Metadata.push_back((AMFMetadata *)mat_child);
} }
} // for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child) } // for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child)
@ -655,7 +681,7 @@ void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Mater
mMaterial_Converted.push_back(new_mat); mMaterial_Converted.push_back(new_mat);
} }
void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation &pConstellation, std::list<aiNode *> &pNodeList) const { void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, std::list<aiNode *> &pNodeList) const {
aiNode *con_node; aiNode *con_node;
std::list<aiNode *> ch_node; std::list<aiNode *> ch_node;
@ -672,8 +698,8 @@ void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Conste
aiNode *t_node; aiNode *t_node;
aiNode *found_node; aiNode *found_node;
if (ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue; if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue;
if (ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>."); if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
// create alias for conveniance // create alias for conveniance
CAMFImporter_NodeElement_Instance &als = *((CAMFImporter_NodeElement_Instance *)ne); CAMFImporter_NodeElement_Instance &als = *((CAMFImporter_NodeElement_Instance *)ne);
@ -723,10 +749,10 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
pScene->mRootNode->mParent = nullptr; pScene->mRootNode->mParent = nullptr;
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED; pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
// search for root(<amf>) element // search for root(<amf>) element
CAMFImporter_NodeElement *root_el = nullptr; AMFNodeElementBase *root_el = nullptr;
for (CAMFImporter_NodeElement *ne : mNodeElement_List) { for (AMFNodeElementBase *ne : mNodeElement_List) {
if (ne->Type != CAMFImporter_NodeElement::ENET_Root) continue; if (ne->Type != AMFNodeElementBase::ENET_Root) continue;
root_el = ne; root_el = ne;
@ -742,15 +768,15 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
// //
// 1. <material> // 1. <material>
// 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet // 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
for (const CAMFImporter_NodeElement *root_child : root_el->Child) { for (const AMFNodeElementBase *root_child : root_el->Child) {
if (root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material *)root_child)); if (root_child->Type == AMFNodeElementBase::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material *)root_child));
} }
// After "appearance" nodes we must read <object> because it will be used in <constellation> -> <instance>. // After "appearance" nodes we must read <object> because it will be used in <constellation> -> <instance>.
// //
// 3. <object> // 3. <object>
for (const CAMFImporter_NodeElement *root_child : root_el->Child) { for (const AMFNodeElementBase *root_child : root_el->Child) {
if (root_child->Type == CAMFImporter_NodeElement::ENET_Object) { if (root_child->Type == AMFNodeElementBase::ENET_Object) {
aiNode *tnode = nullptr; aiNode *tnode = nullptr;
// for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance> // for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance>
@ -761,15 +787,15 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
// And finally read rest of nodes. // And finally read rest of nodes.
// //
for (const CAMFImporter_NodeElement *root_child : root_el->Child) { for (const AMFNodeElementBase *root_child : root_el->Child) {
// 4. <constellation> // 4. <constellation>
if (root_child->Type == CAMFImporter_NodeElement::ENET_Constellation) { if (root_child->Type == AMFNodeElementBase::ENET_Constellation) {
// <object> and <constellation> at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's. // <object> and <constellation> at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's.
Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation *)root_child), node_list); Postprocess_BuildConstellation(*((AMFConstellation *)root_child), node_list);
} }
// 5, <metadata> // 5, <metadata>
if (root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata *)root_child); if (root_child->Type == AMFNodeElementBase::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata *)root_child);
} // for(const CAMFImporter_NodeElement* root_child: root_el->Child) } // for(const CAMFImporter_NodeElement* root_child: root_el->Child)
// at now we can add collected metadata to root node // at now we can add collected metadata to root node

View File

@ -68,7 +68,7 @@ using namespace Assimp::Formatter;
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
mFileName(pFile), mFileName(pFile),
mReader(nullptr), mXmlParser(),
mDataLibrary(), mDataLibrary(),
mAccessorLibrary(), mAccessorLibrary(),
mMeshLibrary(), mMeshLibrary(),
@ -116,16 +116,19 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
throw DeadlyImportError("Failed to open file '" + pFile + "'."); throw DeadlyImportError("Failed to open file '" + pFile + "'.");
} }
} }
pugi::xml_node *root = mXmlParser.parse(daefile.get());
// generate a XML reader for it // generate a XML reader for it
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(daefile.get())); if (nullptr == root) {
ThrowException("Unable to read file, malformed XML");
}
/*std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(daefile.get()));
mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
if (!mReader) { if (!mReader) {
ThrowException("Unable to read file, malformed XML"); ThrowException("Unable to read file, malformed XML");
} }*/
// start reading // start reading
ReadContents(); ReadContents(*root);
// read embedded textures // read embedded textures
if (zip_archive && zip_archive->isOpen()) { if (zip_archive && zip_archive->isOpen()) {
@ -136,7 +139,6 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
ColladaParser::~ColladaParser() { ColladaParser::~ColladaParser() {
delete mReader;
for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it) for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
delete it->second; delete it->second;
for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it) for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
@ -252,8 +254,28 @@ ai_real ColladaParser::ReadFloatFromTextContent() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the contents of the file // Reads the contents of the file
void ColladaParser::ReadContents() { void ColladaParser::ReadContents(XmlNode &node) {
while (mReader->read()) { for (pugi::xml_node &curNode : node.children()) {
pugi::xml_attribute attr = curNode.attribute("version");
if (attr) {
const char *version = attr.as_string();
aiString v;
v.Set(version);
mAssetMetaData.emplace(AI_METADATA_SOURCE_FORMAT_VERSION, v);
if (!::strncmp(version, "1.5", 3)) {
mFormat = FV_1_5_n;
ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
} else if (!::strncmp(version, "1.4", 3)) {
mFormat = FV_1_4_n;
ASSIMP_LOG_DEBUG("Collada schema version is 1.4.n");
} else if (!::strncmp(version, "1.3", 3)) {
mFormat = FV_1_3_n;
ASSIMP_LOG_DEBUG("Collada schema version is 1.3.n");
}
}
ReadStructure(curNode);
}
/*while (mReader->read()) {
// handle the root element "COLLADA" // handle the root element "COLLADA"
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("COLLADA")) { if (IsElement("COLLADA")) {
@ -287,13 +309,44 @@ void ColladaParser::ReadContents() {
} else { } else {
// skip everything else silently // skip everything else silently
} }
} }*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the structure of the file // Reads the structure of the file
void ColladaParser::ReadStructure() { void ColladaParser::ReadStructure(XmlNode &node) {
while (mReader->read()) { for (pugi::xml_node curNode : node.children()) {
const std::string name = std::string(curNode.name());
if (name == "asset")
ReadAssetInfo(curNode);
else if (name == "library_animations")
ReadAnimationLibrary(curNode);
else if (name == "library_animation_clips")
ReadAnimationClipLibrary(curNode);
else if (name == "library_controllers")
ReadControllerLibrary(curNode);
else if (name == "library_images")
ReadImageLibrary(curNode);
else if (name == "library_materials")
ReadMaterialLibrary(curNode);
else if (name == "library_effects")
ReadEffectLibrary(curNode);
else if (name == "library_geometries")
ReadGeometryLibrary(curNode);
else if (name == "library_visual_scenes")
ReadSceneLibrary(curNode);
else if (name == "library_lights")
ReadLightLibrary(curNode);
else if (name == "library_cameras")
ReadCameraLibrary(curNode);
else if (name == "library_nodes")
ReadSceneNode(NULL); /* some hacking to reuse this piece of code */
else if (name == "scene")
ReadScene(curNode);
//else
// SkipElement();
}
/* while (mReader->read()) {
// beginning of elements // beginning of elements
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("asset")) if (IsElement("asset"))
@ -319,15 +372,14 @@ void ColladaParser::ReadStructure() {
else if (IsElement("library_cameras")) else if (IsElement("library_cameras"))
ReadCameraLibrary(); ReadCameraLibrary();
else if (IsElement("library_nodes")) else if (IsElement("library_nodes"))
ReadSceneNode(NULL); /* some hacking to reuse this piece of code */ ReadSceneNode(NULL); // some hacking to reuse this piece of code
else if (IsElement("scene")) else if (IsElement("scene"))
ReadScene(); ReadScene();
else else
SkipElement(); SkipElement();
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { } else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
break; break;
} }*/
}
PostProcessRootAnimations(); PostProcessRootAnimations();
PostProcessControllers(); PostProcessControllers();
@ -335,11 +387,32 @@ void ColladaParser::ReadStructure() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads asset information such as coordinate system information and legal blah // Reads asset information such as coordinate system information and legal blah
void ColladaParser::ReadAssetInfo() { void ColladaParser::ReadAssetInfo(XmlNode &node) {
if (mReader->isEmptyElement()) /* if (mReader->isEmptyElement())
return; return;*/
while (mReader->read()) { for (pugi::xml_node &curNode : node.children()) {
const std::string name = std::string(curNode.name());
if (name == "unit") {
pugi::xml_attribute attr = curNode.attribute("meter");
mUnitSize = 1.f;
if (attr) {
mUnitSize = attr.as_double();
}
} else if (name == "up_axis") {
const char *content = curNode.value();
if (strncmp(content, "X_UP", 4) == 0) {
mUpDirection = UP_X;
} else if (strncmp(content, "Z_UP", 4) == 0) {
mUpDirection = UP_Z;
} else {
mUpDirection = UP_Y;
}
} else if (name == "contributor") {
ReadMetaDataItem(curNode, mAssetMetaData);
}
}
/*while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("unit")) { if (IsElement("unit")) {
// read unit data from the element's attributes // read unit data from the element's attributes
@ -376,12 +449,12 @@ void ColladaParser::ReadAssetInfo() {
break; break;
} }
} }*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the contributor info // Reads the contributor info
void ColladaParser::ReadContributorInfo() { /*void ColladaParser::ReadContributorInfo(XmlNode & node) {
if (mReader->isEmptyElement()) if (mReader->isEmptyElement())
return; return;
@ -394,7 +467,7 @@ void ColladaParser::ReadContributorInfo() {
break; break;
} }
} }
} }*/
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) { static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
for (size_t i = 0; i < key_renaming.size(); ++i) { for (size_t i = 0; i < key_renaming.size(); ++i) {
@ -404,15 +477,36 @@ static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVecto
} }
} }
found_index = std::numeric_limits<size_t>::max(); found_index = std::numeric_limits<size_t>::max();
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a single string metadata item // Reads a single string metadata item
void ColladaParser::ReadMetaDataItem(StringMetaData &metadata) { void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase(); const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
const std::string name = node.name();
if (!name.empty()) {
const char *value_char = node.value();
if (nullptr != value_char) {
aiString aistr;
aistr.Set(value_char);
std::string camel_key_str(name);
ToCamelCase(camel_key_str);
size_t found_index;
if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
metadata.emplace(key_renaming[found_index].second, aistr);
} else {
metadata.emplace(camel_key_str, aistr);
}
}
}
// Metadata such as created, keywords, subject etc // Metadata such as created, keywords, subject etc
const char *key_char = mReader->getNodeName(); /*const char *key_char = mReader->getNodeName();
if (key_char != nullptr) { if (key_char != nullptr) {
const std::string key_str(key_char); const std::string key_str(key_char);
const char *value_char = TestTextContent(); const char *value_char = TestTextContent();
@ -432,16 +526,53 @@ void ColladaParser::ReadMetaDataItem(StringMetaData &metadata) {
} }
TestClosing(key_str.c_str()); TestClosing(key_str.c_str());
} else } else
SkipElement(); SkipElement();*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the animation clips // Reads the animation clips
void ColladaParser::ReadAnimationClipLibrary() { void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) /*if (mReader->isEmptyElement())
return;*/
if (node.empty()) {
return; return;
}
while (mReader->read()) { std::string animName;
pugi::xml_attribute nameAttr = node.attribute("name");
if (nameAttr) {
animName = nameAttr.as_string();
} else {
pugi::xml_attribute idAttr = node.attribute("id");
if (idAttr) {
animName = idAttr.as_string();
} else {
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
}
}
std::pair<std::string, std::vector<std::string>> clip;
clip.first = animName;
for (pugi::xml_node &curNode : node.children()) {
const std::string currentName = curNode.name();
if (currentName == "instance_animation") {
pugi::xml_attribute url = curNode.attribute("url");
if (url) {
const std::string urlName = url.as_string();
if (urlName[0] != '#') {
ThrowException("Unknown reference format");
}
clip.second.push_back(url);
}
}
if (clip.second.size() > 0) {
mAnimationClipLibrary.push_back(clip);
}
}
/* while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("animation_clip")) { if (IsElement("animation_clip")) {
// optional name given as an attribute // optional name given as an attribute
@ -497,7 +628,7 @@ void ColladaParser::ReadAnimationClipLibrary() {
break; break;
} }
} }*/
} }
void ColladaParser::PostProcessControllers() { void ColladaParser::PostProcessControllers() {
@ -517,7 +648,11 @@ void ColladaParser::PostProcessControllers() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Re-build animations from animation clip library, if present, otherwise combine single-channel animations // Re-build animations from animation clip library, if present, otherwise combine single-channel animations
void ColladaParser::PostProcessRootAnimations() { void ColladaParser::PostProcessRootAnimations() {
if (mAnimationClipLibrary.size() > 0) { if (mAnimationClipLibrary.empty()) {
mAnims.CombineSingleChannelAnimations();
return;
}
Animation temp; Animation temp;
for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) { for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) {
@ -545,18 +680,21 @@ void ColladaParser::PostProcessRootAnimations() {
// Ensure no double deletes. // Ensure no double deletes.
temp.mSubAnims.clear(); temp.mSubAnims.clear();
} else {
mAnims.CombineSingleChannelAnimations();
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the animation library // Reads the animation library
void ColladaParser::ReadAnimationLibrary() { void ColladaParser::ReadAnimationLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) /*if (mReader->isEmptyElement())
return; return;*/
for (pugi::xml_node &curNode : node.children()) {
const std::string currentName = curNode.name();
if (currentName == "animation") {
ReadAnimation(curNode, &mAnims);
}
}
while (mReader->read()) { /*while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("animation")) { if (IsElement("animation")) {
// delegate the reading. Depending on the inner elements it will be a container or a anim channel // delegate the reading. Depending on the inner elements it will be a container or a anim channel
@ -571,14 +709,17 @@ void ColladaParser::ReadAnimationLibrary() {
break; break;
} }
} }*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an animation into the given parent structure // Reads an animation into the given parent structure
void ColladaParser::ReadAnimation(Collada::Animation *pParent) { void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
// an <animation> element may be a container for grouping sub-elements or an animation channel // an <animation> element may be a container for grouping sub-elements or an animation channel
// this is the channel collection by ID, in case it has channels // this is the channel collection by ID, in case it has channels
@ -589,11 +730,22 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
// optional name given as an attribute // optional name given as an attribute
std::string animName; std::string animName;
std::string animID; pugi::xml_attribute nameAttr = node.attribute("name");
int indexName = TestAttribute("name"); if (nameAttr) {
int indexID = TestAttribute("id"); animName = nameAttr.as_string();
} else {
animName = "animation";
}
if (indexID >= 0) std::string animID;
pugi::xml_attribute idAttr = node.attribute("id");
if (idAttr) {
animID = idAttr.as_string();
}
/* int indexName = TestAttribute("name");
int indexID = TestAttribute("id");*/
/*if (indexID >= 0)
animID = mReader->getAttributeValue(indexID); animID = mReader->getAttributeValue(indexID);
if (indexName >= 0) if (indexName >= 0)
@ -602,8 +754,44 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
animName = animID; animName = animID;
else else
animName = "animation"; animName = "animation";
*/
for (pugi::xml_node &curNode : node.children()) {
const std::string currentName = curNode.name();
if (currentName == "animation") {
if (!anim) {
anim = new Animation;
anim->mName = animName;
pParent->mSubAnims.push_back(anim);
}
while (mReader->read()) { // recurse into the sub-element
ReadAnimation(curNode, anim);
} else if (currentName == "source") {
ReadSource(curNode);
} else if (currentName == "sampler") {
pugi::xml_attribute sampler_id = curNode.attribute("id");
if (sampler_id) {
std::string id = sampler_id.as_string();
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
// have it read into a channel
ReadAnimationSampler(curNode, newChannel->second);
} else if (currentName == "channel") {
pugi::xml_attribute target = curNode.attribute("target");
pugi::xml_attribute source = curNode.attribute("source");
std::string source_name = source.as_string();
if (source_name[0] == '#') {
source_name = source_name.substr(1, source_name.size() - 1);
}
ChannelMap::iterator cit = channels.find(source_name);
if (cit != channels.end()) {
cit->second.mTarget = target.as_string();
}
}
}
}
/*while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
// we have subanimations // we have subanimations
if (IsElement("animation")) { if (IsElement("animation")) {
@ -652,7 +840,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
break; break;
} }
} }*/
// it turned out to have channels - add them // it turned out to have channels - add them
if (!channels.empty()) { if (!channels.empty()) {
@ -679,7 +867,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
for (ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it) for (ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
anim->mChannels.push_back(it->second); anim->mChannels.push_back(it->second);
if (indexID >= 0) { if (idAttr >= 0) {
mAnimationLibrary[animID] = anim; mAnimationLibrary[animID] = anim;
} }
} }
@ -688,8 +876,16 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an animation sampler into the given anim channel // Reads an animation sampler into the given anim channel
void ColladaParser::ReadAnimationSampler(Collada::AnimationChannel &pChannel) { void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
while (mReader->read()) { for (pugi::xml_node &curNode : node.children()) {
const std::string currentName = curNode.name();
if (currentName == "input") {
pugi::xml_attribute semantic = curNode.attribute("semantic");
if (semantic) {
}
}
}
/*while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("input")) { if (IsElement("input")) {
int indexSemantic = GetAttribute("semantic"); int indexSemantic = GetAttribute("semantic");
@ -723,14 +919,17 @@ void ColladaParser::ReadAnimationSampler(Collada::AnimationChannel &pChannel) {
break; break;
} }
} }*/
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the skeleton controller library // Reads the skeleton controller library
void ColladaParser::ReadControllerLibrary() { void ColladaParser::ReadControllerLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -759,7 +958,7 @@ void ColladaParser::ReadControllerLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a controller into the given mesh structure // Reads a controller into the given mesh structure
void ColladaParser::ReadController(Collada::Controller &pController) { void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pController) {
// initial values // initial values
pController.mType = Skin; pController.mType = Skin;
pController.mMethod = Normalized; pController.mMethod = Normalized;
@ -838,7 +1037,7 @@ void ColladaParser::ReadController(Collada::Controller &pController) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the joint definitions for the given controller // Reads the joint definitions for the given controller
void ColladaParser::ReadControllerJoints(Collada::Controller &pController) { void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
// Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX" // Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX"
@ -879,7 +1078,7 @@ void ColladaParser::ReadControllerJoints(Collada::Controller &pController) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the joint weights for the given controller // Reads the joint weights for the given controller
void ColladaParser::ReadControllerWeights(Collada::Controller &pController) { void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
// read vertex count from attributes and resize the array accordingly // read vertex count from attributes and resize the array accordingly
int indexCount = GetAttribute("count"); int indexCount = GetAttribute("count");
size_t vertexCount = (size_t)mReader->getAttributeValueAsInt(indexCount); size_t vertexCount = (size_t)mReader->getAttributeValueAsInt(indexCount);
@ -963,9 +1162,12 @@ void ColladaParser::ReadControllerWeights(Collada::Controller &pController) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the image library contents // Reads the image library contents
void ColladaParser::ReadImageLibrary() { void ColladaParser::ReadImageLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -994,7 +1196,7 @@ void ColladaParser::ReadImageLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an image entry into the given image // Reads an image entry into the given image
void ColladaParser::ReadImage(Collada::Image &pImage) { void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
// Need to run different code paths here, depending on the Collada XSD version // Need to run different code paths here, depending on the Collada XSD version
@ -1080,9 +1282,12 @@ void ColladaParser::ReadImage(Collada::Image &pImage) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the material library // Reads the material library
void ColladaParser::ReadMaterialLibrary() { void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
std::map<std::string, int> names; std::map<std::string, int> names;
while (mReader->read()) { while (mReader->read()) {
@ -1129,9 +1334,12 @@ void ColladaParser::ReadMaterialLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the light library // Reads the light library
void ColladaParser::ReadLightLibrary() { void ColladaParser::ReadLightLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1158,9 +1366,12 @@ void ColladaParser::ReadLightLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the camera library // Reads the camera library
void ColladaParser::ReadCameraLibrary() { void ColladaParser::ReadCameraLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1192,7 +1403,7 @@ void ColladaParser::ReadCameraLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a material entry into the given material // Reads a material entry into the given material
void ColladaParser::ReadMaterial(Collada::Material &pMaterial) { void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("material")) { if (IsElement("material")) {
@ -1222,7 +1433,7 @@ void ColladaParser::ReadMaterial(Collada::Material &pMaterial) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a light entry into the given light // Reads a light entry into the given light
void ColladaParser::ReadLight(Collada::Light &pLight) { void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("light")) { if (IsElement("light")) {
@ -1300,34 +1511,26 @@ void ColladaParser::ReadLight(Collada::Light &pLight) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a camera entry into the given light // Reads a camera entry into the given light
void ColladaParser::ReadCamera(Collada::Camera& camera) void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
{ while (mReader->read()) {
while (mReader->read())
{
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("camera")) { if (IsElement("camera")) {
SkipElement(); SkipElement();
} } else if (IsElement("orthographic")) {
else if (IsElement("orthographic")) {
camera.mOrtho = true; camera.mOrtho = true;
} } else if (IsElement("xfov") || IsElement("xmag")) {
else if (IsElement("xfov") || IsElement("xmag")) {
camera.mHorFov = ReadFloatFromTextContent(); camera.mHorFov = ReadFloatFromTextContent();
TestClosing((camera.mOrtho ? "xmag" : "xfov")); TestClosing((camera.mOrtho ? "xmag" : "xfov"));
} } else if (IsElement("yfov") || IsElement("ymag")) {
else if (IsElement("yfov") || IsElement("ymag")) {
camera.mVerFov = ReadFloatFromTextContent(); camera.mVerFov = ReadFloatFromTextContent();
TestClosing((camera.mOrtho ? "ymag" : "yfov")); TestClosing((camera.mOrtho ? "ymag" : "yfov"));
} } else if (IsElement("aspect_ratio")) {
else if (IsElement("aspect_ratio")) {
camera.mAspect = ReadFloatFromTextContent(); camera.mAspect = ReadFloatFromTextContent();
TestClosing("aspect_ratio"); TestClosing("aspect_ratio");
} } else if (IsElement("znear")) {
else if (IsElement("znear")) {
camera.mZNear = ReadFloatFromTextContent(); camera.mZNear = ReadFloatFromTextContent();
TestClosing("znear"); TestClosing("znear");
} } else if (IsElement("zfar")) {
else if (IsElement("zfar")) {
camera.mZFar = ReadFloatFromTextContent(); camera.mZFar = ReadFloatFromTextContent();
TestClosing("zfar"); TestClosing("zfar");
} }
@ -1340,10 +1543,13 @@ void ColladaParser::ReadCamera(Collada::Camera& camera)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the effect library // Reads the effect library
void ColladaParser::ReadEffectLibrary() { void ColladaParser::ReadEffectLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) { if (node.empty()) {
return; return;
} }
/*if (mReader->isEmptyElement()) {
return;
}*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1371,7 +1577,7 @@ void ColladaParser::ReadEffectLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an effect entry into the given effect // Reads an effect entry into the given effect
void ColladaParser::ReadEffect(Collada::Effect &pEffect) { void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
// for the moment we don't support any other type of effect. // for the moment we don't support any other type of effect.
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1390,7 +1596,7 @@ void ColladaParser::ReadEffect(Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an COMMON effect profile // Reads an COMMON effect profile
void ColladaParser::ReadEffectProfileCommon(Collada::Effect &pEffect) { void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("newparam")) { if (IsElement("newparam")) {
@ -1496,10 +1702,13 @@ void ColladaParser::ReadEffectProfileCommon(Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read texture wrapping + UV transform settings from a profile==Maya chunk // Read texture wrapping + UV transform settings from a profile==Maya chunk
void ColladaParser::ReadSamplerProperties(Sampler &out) { void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
if (mReader->isEmptyElement()) { if (node.empty()) {
return; return;
} }
/*if (mReader->isEmptyElement()) {
return;
}*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1576,9 +1785,12 @@ void ColladaParser::ReadSamplerProperties(Sampler &out) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an effect entry containing a color or a texture defining that color // Reads an effect entry containing a color or a texture defining that color
void ColladaParser::ReadEffectColor(aiColor4D &pColor, Sampler &pSampler) { void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &pSampler) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
// Save current element name // Save current element name
const std::string curElem = mReader->getNodeName(); const std::string curElem = mReader->getNodeName();
@ -1639,7 +1851,7 @@ void ColladaParser::ReadEffectColor(aiColor4D &pColor, Sampler &pSampler) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an effect entry containing a float // Reads an effect entry containing a float
void ColladaParser::ReadEffectFloat(ai_real &pFloat) { void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("float")) { if (IsElement("float")) {
@ -1661,7 +1873,7 @@ void ColladaParser::ReadEffectFloat(ai_real &pFloat) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an effect parameter specification of any kind // Reads an effect parameter specification of any kind
void ColladaParser::ReadEffectParam(Collada::EffectParam &pParam) { void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("surface")) { if (IsElement("surface")) {
@ -1707,9 +1919,12 @@ void ColladaParser::ReadEffectParam(Collada::EffectParam &pParam) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the geometry library contents // Reads the geometry library contents
void ColladaParser::ReadGeometryLibrary() { void ColladaParser::ReadGeometryLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1755,9 +1970,12 @@ void ColladaParser::ReadGeometryLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a geometry from the geometry library. // Reads a geometry from the geometry library.
void ColladaParser::ReadGeometry(Collada::Mesh &pMesh) { void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1779,9 +1997,12 @@ void ColladaParser::ReadGeometry(Collada::Mesh &pMesh) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a mesh from the geometry library // Reads a mesh from the geometry library
void ColladaParser::ReadMesh(Mesh &pMesh) { void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1814,7 +2035,7 @@ void ColladaParser::ReadMesh(Mesh &pMesh) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a source element // Reads a source element
void ColladaParser::ReadSource() { void ColladaParser::ReadSource(XmlNode &node) {
int indexID = GetAttribute("id"); int indexID = GetAttribute("id");
std::string sourceID = mReader->getAttributeValue(indexID); std::string sourceID = mReader->getAttributeValue(indexID);
@ -1846,7 +2067,7 @@ void ColladaParser::ReadSource() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a data array holding a number of floats, and stores it in the global library // Reads a data array holding a number of floats, and stores it in the global library
void ColladaParser::ReadDataArray() { void ColladaParser::ReadDataArray(XmlNode &node) {
std::string elmName = mReader->getNodeName(); std::string elmName = mReader->getNodeName();
bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array"); bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
bool isEmptyElement = mReader->isEmptyElement(); bool isEmptyElement = mReader->isEmptyElement();
@ -1904,7 +2125,7 @@ void ColladaParser::ReadDataArray() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads an accessor and stores it in the global library // Reads an accessor and stores it in the global library
void ColladaParser::ReadAccessor(const std::string &pID) { void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
// read accessor attributes // read accessor attributes
int attrSource = GetAttribute("source"); int attrSource = GetAttribute("source");
const char *source = mReader->getAttributeValue(attrSource); const char *source = mReader->getAttributeValue(attrSource);
@ -2009,7 +2230,7 @@ void ColladaParser::ReadAccessor(const std::string &pID) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads input declarations of per-vertex mesh data into the given mesh // Reads input declarations of per-vertex mesh data into the given mesh
void ColladaParser::ReadVertexData(Mesh &pMesh) { void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about // extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
int attrID = GetAttribute("id"); int attrID = GetAttribute("id");
pMesh.mVertexID = mReader->getAttributeValue(attrID); pMesh.mVertexID = mReader->getAttributeValue(attrID);
@ -2033,7 +2254,7 @@ void ColladaParser::ReadVertexData(Mesh &pMesh) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads input declarations of per-index mesh data into the given mesh // Reads input declarations of per-index mesh data into the given mesh
void ColladaParser::ReadIndexData(Mesh &pMesh) { void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
std::vector<size_t> vcount; std::vector<size_t> vcount;
std::vector<InputChannel> perIndexData; std::vector<InputChannel> perIndexData;
@ -2128,7 +2349,7 @@ void ColladaParser::ReadIndexData(Mesh &pMesh) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a single input channel element and stores it in the given array, if valid // Reads a single input channel element and stores it in the given array, if valid
void ColladaParser::ReadInputChannel(std::vector<InputChannel> &poChannels) { void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &poChannels) {
InputChannel channel; InputChannel channel;
// read semantic // read semantic
@ -2170,7 +2391,7 @@ void ColladaParser::ReadInputChannel(std::vector<InputChannel> &poChannels) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a <p> primitive index list and assembles the mesh data into the given mesh // Reads a <p> primitive index list and assembles the mesh data into the given mesh
size_t ColladaParser::ReadPrimitives(Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels, size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t> &pVCount, PrimitiveType pPrimType) { size_t pNumPrimitives, const std::vector<size_t> &pVCount, PrimitiveType pPrimType) {
// determine number of indices coming per vertex // determine number of indices coming per vertex
// find the offset index for all per-vertex channels // find the offset index for all per-vertex channels
@ -2337,7 +2558,8 @@ size_t ColladaParser::ReadPrimitives(Mesh &pMesh, std::vector<InputChannel> &pPe
///@note This function willn't work correctly if both PerIndex and PerVertex channels have same channels. ///@note This function willn't work correctly if both PerIndex and PerVertex channels have same channels.
///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates. ///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior ///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) { void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
// calculate the base offset of the vertex whose attributes we ant to copy // calculate the base offset of the vertex whose attributes we ant to copy
size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets; size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
@ -2355,7 +2577,8 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]); pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
} }
void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) { void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels,
size_t currentPrimitive, const std::vector<size_t> &indices) {
if (currentPrimitive % 2 != 0) { if (currentPrimitive % 2 != 0) {
//odd tristrip triangles need their indices mangled, to preserve winding direction //odd tristrip triangles need their indices mangled, to preserve winding direction
CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
@ -2470,9 +2693,12 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the library of node hierarchies and scene parts // Reads the library of node hierarchies and scene parts
void ColladaParser::ReadSceneLibrary() { void ColladaParser::ReadSceneLibrary(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -2510,10 +2736,14 @@ void ColladaParser::ReadSceneLibrary() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a scene node's contents including children and stores it in the given node // Reads a scene node's contents including children and stores it in the given node
void ColladaParser::ReadSceneNode(Node *pNode) { void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
// quit immediately on <bla/> elements // quit immediately on <bla/> elements
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/* if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -2628,9 +2858,12 @@ void ColladaParser::ReadSceneNode(Node *pNode) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a node transformation entry of the given type and adds it to the given node's transformation list. // Reads a node transformation entry of the given type and adds it to the given node's transformation list.
void ColladaParser::ReadNodeTransformation(Node *pNode, TransformType pType) { void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
std::string tagName = mReader->getNodeName(); std::string tagName = mReader->getNodeName();
@ -2663,7 +2896,7 @@ void ColladaParser::ReadNodeTransformation(Node *pNode, TransformType pType) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ColladaParser::ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl) { void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) {
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("bind_vertex_input")) { if (IsElement("bind_vertex_input")) {
@ -2714,7 +2947,7 @@ void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a mesh reference in a node and adds it to the node's mesh list // Reads a mesh reference in a node and adds it to the node's mesh list
void ColladaParser::ReadNodeGeometry(Node *pNode) { void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
// referred mesh is given as an attribute of the <instance_geometry> element // referred mesh is given as an attribute of the <instance_geometry> element
int attrUrl = GetAttribute("url"); int attrUrl = GetAttribute("url");
const char *url = mReader->getAttributeValue(attrUrl); const char *url = mReader->getAttributeValue(attrUrl);
@ -2760,9 +2993,12 @@ void ColladaParser::ReadNodeGeometry(Node *pNode) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the collada scene // Reads the collada scene
void ColladaParser::ReadScene() { void ColladaParser::ReadScene(XmlNode &node) {
if (mReader->isEmptyElement()) if (node.empty()) {
return; return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) { while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -2813,7 +3049,7 @@ void ColladaParser::ReportWarning(const char *msg, ...) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Skips all data until the end node of the current element // Skips all data until the end node of the current element
void ColladaParser::SkipElement() { /*void ColladaParser::SkipElement() {
// nothing to skip if it's an <element /> // nothing to skip if it's an <element />
if (mReader->isEmptyElement()) { if (mReader->isEmptyElement()) {
return; return;
@ -2821,11 +3057,11 @@ void ColladaParser::SkipElement() {
// reroute // reroute
SkipElement(mReader->getNodeName()); SkipElement(mReader->getNodeName());
} }*/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Skips all data until the end node of the given element // Skips all data until the end node of the given element
void ColladaParser::SkipElement(const char *pElement) { /*void ColladaParser::SkipElement(const char *pElement) {
// copy the current node's name because it'a pointer to the reader's internal buffer, // copy the current node's name because it'a pointer to the reader's internal buffer,
// which is going to change with the upcoming parsing // which is going to change with the upcoming parsing
std::string element = pElement; std::string element = pElement;
@ -2836,11 +3072,11 @@ void ColladaParser::SkipElement(const char *pElement) {
} }
} }
} }
} }*/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Tests for an opening element of the given name, throws an exception if not found // Tests for an opening element of the given name, throws an exception if not found
void ColladaParser::TestOpening(const char *pName) { /*void ColladaParser::TestOpening(const char *pName) {
// read element start // read element start
if (!mReader->read()) { if (!mReader->read()) {
ThrowException(format() << "Unexpected end of file while beginning of <" << pName << "> element."); ThrowException(format() << "Unexpected end of file while beginning of <" << pName << "> element.");
@ -2855,11 +3091,11 @@ void ColladaParser::TestOpening(const char *pName) {
if (mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp(mReader->getNodeName(), pName) != 0) { if (mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp(mReader->getNodeName(), pName) != 0) {
ThrowException(format() << "Expected start of <" << pName << "> element."); ThrowException(format() << "Expected start of <" << pName << "> element.");
} }
} }*/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Tests for the closing tag of the given element, throws an exception if not found // Tests for the closing tag of the given element, throws an exception if not found
void ColladaParser::TestClosing(const char *pName) { /*void ColladaParser::TestClosing(const char *pName) {
// check if we have an empty (self-closing) element // check if we have an empty (self-closing) element
if (mReader->isEmptyElement()) { if (mReader->isEmptyElement()) {
return; return;
@ -2885,7 +3121,7 @@ void ColladaParser::TestClosing(const char *pName) {
if (mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp(mReader->getNodeName(), pName) != 0) { if (mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp(mReader->getNodeName(), pName) != 0) {
ThrowException(format() << "Expected end of <" << pName << "> element."); ThrowException(format() << "Expected end of <" << pName << "> element.");
} }
} }*/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes // Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
@ -2940,7 +3176,7 @@ const char *ColladaParser::TestTextContent() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Calculates the resulting transformation fromm all the given transform steps // Calculates the resulting transformation from all the given transform steps
aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform> &pTransforms) const { aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform> &pTransforms) const {
aiMatrix4x4 res; aiMatrix4x4 res;

View File

@ -50,9 +50,10 @@
#include "ColladaHelper.h" #include "ColladaHelper.h"
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/irrXMLWrapper.h> #include <assimp/XmlParser.h>
namespace Assimp { namespace Assimp {
class ZipArchiveIOSystem; class ZipArchiveIOSystem;
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
@ -81,25 +82,25 @@ protected:
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive); static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
/** Reads the contents of the file */ /** Reads the contents of the file */
void ReadContents(); void ReadContents(XmlNode &node);
/** Reads the structure of the file */ /** Reads the structure of the file */
void ReadStructure(); void ReadStructure(XmlNode &node);
/** Reads asset information such as coordinate system information and legal blah */ /** Reads asset information such as coordinate system information and legal blah */
void ReadAssetInfo(); void ReadAssetInfo(XmlNode &node);
/** Reads contributor information such as author and legal blah */ /** Reads contributor information such as author and legal blah */
void ReadContributorInfo(); void ReadContributorInfo(XmlNode &node);
/** Reads generic metadata into provided map and renames keys for Assimp */ /** Reads generic metadata into provided map and renames keys for Assimp */
void ReadMetaDataItem(StringMetaData &metadata); void ReadMetaDataItem(XmlNode &node, StringMetaData &metadata);
/** Reads the animation library */ /** Reads the animation library */
void ReadAnimationLibrary(); void ReadAnimationLibrary(XmlNode &node);
/** Reads the animation clip library */ /** Reads the animation clip library */
void ReadAnimationClipLibrary(); void ReadAnimationClipLibrary(XmlNode &node);
/** Unwrap controllers dependency hierarchy */ /** Unwrap controllers dependency hierarchy */
void PostProcessControllers(); void PostProcessControllers();
@ -108,103 +109,103 @@ protected:
void PostProcessRootAnimations(); void PostProcessRootAnimations();
/** Reads an animation into the given parent structure */ /** Reads an animation into the given parent structure */
void ReadAnimation(Collada::Animation *pParent); void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
/** Reads an animation sampler into the given anim channel */ /** Reads an animation sampler into the given anim channel */
void ReadAnimationSampler(Collada::AnimationChannel &pChannel); void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel);
/** Reads the skeleton controller library */ /** Reads the skeleton controller library */
void ReadControllerLibrary(); void ReadControllerLibrary(XmlNode &node);
/** Reads a controller into the given mesh structure */ /** Reads a controller into the given mesh structure */
void ReadController(Collada::Controller &pController); void ReadController(XmlNode &node, Collada::Controller &pController);
/** Reads the joint definitions for the given controller */ /** Reads the joint definitions for the given controller */
void ReadControllerJoints(Collada::Controller &pController); void ReadControllerJoints(XmlNode &node, Collada::Controller &pController);
/** Reads the joint weights for the given controller */ /** Reads the joint weights for the given controller */
void ReadControllerWeights(Collada::Controller &pController); void ReadControllerWeights(XmlNode &node, Collada::Controller &pController);
/** Reads the image library contents */ /** Reads the image library contents */
void ReadImageLibrary(); void ReadImageLibrary(XmlNode &node);
/** Reads an image entry into the given image */ /** Reads an image entry into the given image */
void ReadImage(Collada::Image &pImage); void ReadImage(XmlNode &node, Collada::Image &pImage);
/** Reads the material library */ /** Reads the material library */
void ReadMaterialLibrary(); void ReadMaterialLibrary(XmlNode &node);
/** Reads a material entry into the given material */ /** Reads a material entry into the given material */
void ReadMaterial(Collada::Material &pMaterial); void ReadMaterial(XmlNode &node, Collada::Material &pMaterial);
/** Reads the camera library */ /** Reads the camera library */
void ReadCameraLibrary(); void ReadCameraLibrary(XmlNode &node);
/** Reads a camera entry into the given camera */ /** Reads a camera entry into the given camera */
void ReadCamera(Collada::Camera &pCamera); void ReadCamera(XmlNode &node, Collada::Camera &pCamera);
/** Reads the light library */ /** Reads the light library */
void ReadLightLibrary(); void ReadLightLibrary(XmlNode &node);
/** Reads a light entry into the given light */ /** Reads a light entry into the given light */
void ReadLight(Collada::Light &pLight); void ReadLight(XmlNode &node, Collada::Light &pLight);
/** Reads the effect library */ /** Reads the effect library */
void ReadEffectLibrary(); void ReadEffectLibrary(XmlNode &node);
/** Reads an effect entry into the given effect*/ /** Reads an effect entry into the given effect*/
void ReadEffect(Collada::Effect &pEffect); void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
/** Reads an COMMON effect profile */ /** Reads an COMMON effect profile */
void ReadEffectProfileCommon(Collada::Effect &pEffect); void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
/** Read sampler properties */ /** Read sampler properties */
void ReadSamplerProperties(Collada::Sampler &pSampler); void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
/** Reads an effect entry containing a color or a texture defining that color */ /** Reads an effect entry containing a color or a texture defining that color */
void ReadEffectColor(aiColor4D &pColor, Collada::Sampler &pSampler); void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
/** Reads an effect entry containing a float */ /** Reads an effect entry containing a float */
void ReadEffectFloat(ai_real &pFloat); void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
/** Reads an effect parameter specification of any kind */ /** Reads an effect parameter specification of any kind */
void ReadEffectParam(Collada::EffectParam &pParam); void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
/** Reads the geometry library contents */ /** Reads the geometry library contents */
void ReadGeometryLibrary(); void ReadGeometryLibrary(XmlNode &node);
/** Reads a geometry from the geometry library. */ /** Reads a geometry from the geometry library. */
void ReadGeometry(Collada::Mesh &pMesh); void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
/** Reads a mesh from the geometry library */ /** Reads a mesh from the geometry library */
void ReadMesh(Collada::Mesh &pMesh); void ReadMesh(XmlNode &node, Collada::Mesh &pMesh);
/** Reads a source element - a combination of raw data and an accessor defining /** Reads a source element - a combination of raw data and an accessor defining
* things that should not be redefinable. Yes, that's another rant. * things that should not be redefinable. Yes, that's another rant.
*/ */
void ReadSource(); void ReadSource(XmlNode &node);
/** Reads a data array holding a number of elements, and stores it in the global library. /** Reads a data array holding a number of elements, and stores it in the global library.
* Currently supported are array of floats and arrays of strings. * Currently supported are array of floats and arrays of strings.
*/ */
void ReadDataArray(); void ReadDataArray(XmlNode &node);
/** Reads an accessor and stores it in the global library under the given ID - /** Reads an accessor and stores it in the global library under the given ID -
* accessors use the ID of the parent <source> element * accessors use the ID of the parent <source> element
*/ */
void ReadAccessor(const std::string &pID); void ReadAccessor(XmlNode &node, const std::string &pID);
/** Reads input declarations of per-vertex mesh data into the given mesh */ /** Reads input declarations of per-vertex mesh data into the given mesh */
void ReadVertexData(Collada::Mesh &pMesh); void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */ /** Reads input declarations of per-index mesh data into the given mesh */
void ReadIndexData(Collada::Mesh &pMesh); void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh);
/** Reads a single input channel element and stores it in the given array, if valid */ /** Reads a single input channel element and stores it in the given array, if valid */
void ReadInputChannel(std::vector<Collada::InputChannel> &poChannels); void ReadInputChannel(XmlNode &node, std::vector<Collada::InputChannel> &poChannels);
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */ /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
size_t ReadPrimitives(Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels, size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType); size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
/** Copies the data for a single primitive into the mesh, based on the InputChannels */ /** Copies the data for a single primitive into the mesh, based on the InputChannels */
@ -220,22 +221,22 @@ protected:
void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh); void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
/** Reads the library of node hierarchies and scene parts */ /** Reads the library of node hierarchies and scene parts */
void ReadSceneLibrary(); void ReadSceneLibrary(XmlNode &node);
/** Reads a scene node's contents including children and stores it in the given node */ /** Reads a scene node's contents including children and stores it in the given node */
void ReadSceneNode(Collada::Node *pNode); void ReadSceneNode(XmlNode &node, Collada::Node *pNode);
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
void ReadNodeTransformation(Collada::Node *pNode, Collada::TransformType pType); void ReadNodeTransformation(XmlNode &node, Collada::Node *pNode, Collada::TransformType pType);
/** Reads a mesh reference in a node and adds it to the node's mesh list */ /** Reads a mesh reference in a node and adds it to the node's mesh list */
void ReadNodeGeometry(Collada::Node *pNode); void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
/** Reads the collada scene */ /** Reads the collada scene */
void ReadScene(); void ReadScene(XmlNode &node);
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl); void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
/** Reads embedded textures from a ZAE archive*/ /** Reads embedded textures from a ZAE archive*/
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
@ -246,19 +247,19 @@ protected:
void ReportWarning(const char *msg, ...); void ReportWarning(const char *msg, ...);
/** Skips all data until the end node of the current element */ /** Skips all data until the end node of the current element */
void SkipElement(); //void SkipElement();
/** Skips all data until the end node of the given element */ /** Skips all data until the end node of the given element */
void SkipElement(const char *pElement); //void SkipElement(const char *pElement);
/** Compares the current xml element name to the given string and returns true if equal */ /** Compares the current xml element name to the given string and returns true if equal */
bool IsElement(const char *pName) const; bool IsElement(const char *pName) const;
/** Tests for the opening tag of the given element, throws an exception if not found */ /** Tests for the opening tag of the given element, throws an exception if not found */
void TestOpening(const char *pName); //void TestOpening(const char *pName);
/** Tests for the closing tag of the given element, throws an exception if not found */ /** Tests for the closing tag of the given element, throws an exception if not found */
void TestClosing(const char *pName); //void TestClosing(const char *pName);
/** Checks the present element for the presence of the attribute, returns its index /** Checks the present element for the presence of the attribute, returns its index
or throws an exception if not found */ or throws an exception if not found */
@ -293,11 +294,12 @@ protected:
const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const; const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
protected: protected:
/** Filename, for a verbose error message */ // Filename, for a verbose error message
std::string mFileName; std::string mFileName;
/** XML reader, member for everyday use */ // XML reader, member for everyday use
irr::io::IrrXMLReader *mReader; //irr::io::IrrXMLReader *mReader;
XmlParser mXmlParser;
/** All data arrays found in the file by ID. Might be referred to by actually /** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */ everyone. Collada, you are a steaming pile of indirection. */

View File

@ -73,7 +73,11 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
IRRMeshImporter::IRRMeshImporter() {} IRRMeshImporter::IRRMeshImporter() :
BaseImporter(),
IrrlichtBase() {
// empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -47,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IRRMESHLOADER_H_INCLUDED #ifndef AI_IRRMESHLOADER_H_INCLUDED
#define AI_IRRMESHLOADER_H_INCLUDED #define AI_IRRMESHLOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include "IRRShared.h" #include "IRRShared.h"
#include <assimp/BaseImporter.h>
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER #ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
@ -61,15 +60,11 @@ namespace Assimp {
* irrEdit. As IrrEdit itself is capable of importing quite many file formats, * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
* it might be a good file format for data exchange. * it might be a good file format for data exchange.
*/ */
class IRRMeshImporter : public BaseImporter, public IrrlichtBase class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
{
public: public:
IRRMeshImporter(); IRRMeshImporter();
~IRRMeshImporter(); ~IRRMeshImporter();
public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
@ -78,7 +73,6 @@ public:
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
@ -91,7 +85,6 @@ protected:
*/ */
void InternReadFile(const std::string &pFile, aiScene *pScene, void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler); IOSystem *pIOHandler);
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -43,8 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Shared utilities for the IRR and IRRMESH loaders * @brief Shared utilities for the IRR and IRRMESH loaders
*/ */
//This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted. //This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted.
#if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER)) #if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))
@ -57,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
// Transformation matrix to convert from Assimp to IRR space // Transformation matrix to convert from Assimp to IRR space
static const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 ( const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
@ -66,7 +64,7 @@ static const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a property in hexadecimal format (i.e. ffffffff) // read a property in hexadecimal format (i.e. ffffffff)
void IrrlichtBase::ReadHexProperty(HexProperty &out ) { void IrrlichtBase::ReadHexProperty(HexProperty &out ) {
for (pugi::xml_attribute attrib : mNode.attributes()) { for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) { if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string( attrib.value() ); out.name = std::string( attrib.value() );
} else if (!ASSIMP_stricmp(attrib.name(),"value")) { } else if (!ASSIMP_stricmp(attrib.name(),"value")) {
@ -79,7 +77,7 @@ void IrrlichtBase::ReadHexProperty(HexProperty &out ) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a decimal property // read a decimal property
void IrrlichtBase::ReadIntProperty(IntProperty & out) { void IrrlichtBase::ReadIntProperty(IntProperty & out) {
for (pugi::xml_attribute attrib : mNode.attributes()) { for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) { if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value()); out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.value(),"value")) { } else if (!ASSIMP_stricmp(attrib.value(),"value")) {
@ -92,7 +90,7 @@ void IrrlichtBase::ReadIntProperty(IntProperty & out) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a string property // read a string property
void IrrlichtBase::ReadStringProperty( StringProperty& out) { void IrrlichtBase::ReadStringProperty( StringProperty& out) {
for (pugi::xml_attribute attrib : mNode.attributes()) { for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) { if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value()); out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) { } else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -105,7 +103,7 @@ void IrrlichtBase::ReadStringProperty (StringProperty& out) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a boolean property // read a boolean property
void IrrlichtBase::ReadBoolProperty(BoolProperty &out) { void IrrlichtBase::ReadBoolProperty(BoolProperty &out) {
for (pugi::xml_attribute attrib : mNode.attributes()) { for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")){ if (!ASSIMP_stricmp(attrib.name(), "name")){
out.name = std::string(attrib.value()); out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) { } else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -118,7 +116,7 @@ void IrrlichtBase::ReadBoolProperty(BoolProperty &out) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a float property // read a float property
void IrrlichtBase::ReadFloatProperty(FloatProperty &out) { void IrrlichtBase::ReadFloatProperty(FloatProperty &out) {
for (pugi::xml_attribute attrib : mNode.attributes()) { for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) { if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value()); out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) { } else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -131,7 +129,7 @@ void IrrlichtBase::ReadFloatProperty(FloatProperty &out) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a vector property // read a vector property
void IrrlichtBase::ReadVectorProperty( VectorProperty &out ) { void IrrlichtBase::ReadVectorProperty( VectorProperty &out ) {
for (pugi::xml_attribute attrib : mNode.attributes()) { for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) { if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value()); out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) { } else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -181,7 +179,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) {
int cnt = 0; // number of used texture channels int cnt = 0; // number of used texture channels
unsigned int nd = 0; unsigned int nd = 0;
for (pugi::xml_node child : mNode.children()) { for (pugi::xml_node child : mNode->children()) {
if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties
HexProperty prop; HexProperty prop;
ReadHexProperty(prop); ReadHexProperty(prop);

View File

@ -7,8 +7,8 @@
#ifndef INCLUDED_AI_IRRSHARED_H #ifndef INCLUDED_AI_IRRSHARED_H
#define INCLUDED_AI_IRRSHARED_H #define INCLUDED_AI_IRRSHARED_H
#include <assimp/XmlParser.h>
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h>
#include <stdint.h> #include <stdint.h>
struct aiMaterial; struct aiMaterial;
@ -19,7 +19,6 @@ namespace Assimp {
*/ */
extern const aiMatrix4x4 AI_TO_IRR_MATRIX; extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
// Default: 0 = solid, one texture // Default: 0 = solid, one texture
#define AI_IRRMESH_MAT_solid_2layer 0x10000 #define AI_IRRMESH_MAT_solid_2layer 0x10000
@ -57,15 +56,21 @@ extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
* Declares some irrlight-related xml parsing utilities and provides tools * Declares some irrlight-related xml parsing utilities and provides tools
* to load materials from IRR and IRRMESH files. * to load materials from IRR and IRRMESH files.
*/ */
class IrrlichtBase class IrrlichtBase {
{
protected: protected:
IrrlichtBase() :
mNode(nullptr) {
// empty
}
~IrrlichtBase() {
// empty
}
/** @brief Data structure for a simple name-value property /** @brief Data structure for a simple name-value property
*/ */
template <class T> template <class T>
struct Property struct Property {
{
std::string name; std::string name;
T value; T value;
}; };
@ -79,7 +84,7 @@ protected:
/// XML reader instance /// XML reader instance
XmlParser mParser; XmlParser mParser;
pugi::xml_node &mNode; pugi::xml_node *mNode;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a material description from the XML /** Parse a material description from the XML
@ -100,11 +105,9 @@ protected:
void ReadIntProperty(IntProperty &out); void ReadIntProperty(IntProperty &out);
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Unpack a hex color, e.g. 0xdcdedfff // Unpack a hex color, e.g. 0xdcdedfff
inline inline void ColorFromARGBPacked(uint32_t in, aiColor4D &clr) {
void ColorFromARGBPacked(uint32_t in, aiColor4D& clr) {
clr.a = ((in >> 24) & 0xff) / 255.f; clr.a = ((in >> 24) & 0xff) / 255.f;
clr.r = ((in >> 16) & 0xff) / 255.f; clr.r = ((in >> 16) & 0xff) / 255.f;
clr.g = ((in >> 8) & 0xff) / 255.f; clr.g = ((in >> 8) & 0xff) / 255.f;

View File

@ -1251,6 +1251,8 @@ namespace pugi
}; };
#ifndef PUGIXML_NO_EXCEPTIONS #ifndef PUGIXML_NO_EXCEPTIONS
#pragma warning(push)
#pragma warning( disable: 4275 )
// XPath exception class // XPath exception class
class PUGIXML_CLASS xpath_exception: public std::exception class PUGIXML_CLASS xpath_exception: public std::exception
{ {
@ -1268,7 +1270,7 @@ namespace pugi
const xpath_parse_result& result() const; const xpath_parse_result& result() const;
}; };
#endif #endif
#pragma warning(pop)
// XPath node class (either xml_node or xml_attribute) // XPath node class (either xml_node or xml_attribute)
class PUGIXML_CLASS xpath_node class PUGIXML_CLASS xpath_node
{ {

View File

@ -109,6 +109,10 @@ public:
return &node; return &node;
} }
bool hasNode( const std::string &name ) const {
return nullptr != findNode(name);
}
TNodeType *parse(IOStream *stream) { TNodeType *parse(IOStream *stream) {
if (nullptr == stream) { if (nullptr == stream) {
return nullptr; return nullptr;