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
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -82,7 +80,7 @@ void AMFImporter::Clear() {
mTexture_Converted.clear();
// Delete all elements
if (!mNodeElement_List.empty()) {
for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
for (AMFNodeElementBase *ne : mNodeElement_List) {
delete ne;
}
@ -90,8 +88,14 @@ void AMFImporter::Clear() {
}
}
AMFImporter::AMFImporter() :
mNodeElement_Cur(nullptr),
mXmlParser(nullptr) {
// empty
}
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();
}
@ -100,10 +104,12 @@ AMFImporter::~AMFImporter() {
/************************************************************ Functions: find set ************************************************************/
/*********************************************************************************************************************************************/
bool AMFImporter::Find_NodeElement(const std::string &pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement **pNodeElement) const {
for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const {
for (AMFNodeElementBase *ne : mNodeElement_List) {
if ((ne->ID == pID) && (ne->Type == pType)) {
if (pNodeElement != nullptr) *pNodeElement = ne;
if (pNodeElement != nullptr) {
*pNodeElement = ne;
}
return true;
}
@ -117,7 +123,9 @@ bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list<aiNode *>
for (aiNode *node : pNodeList) {
if (node->mName == node_name) {
if (pNode != nullptr) *pNode = node;
if (pNode != nullptr) {
*pNode = node;
}
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 {
for (const SPP_Material &mat : mMaterial_Converted) {
if (mat.ID == pID) {
if (pConvertedMaterial != nullptr) *pConvertedMaterial = &mat;
if (pConvertedMaterial != nullptr) {
*pConvertedMaterial = &mat;
}
return true;
}
@ -142,20 +152,20 @@ bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Mater
/************************************************************ Functions: throw set ***********************************************************/
/*********************************************************************************************************************************************/
void AMFImporter::Throw_CloseNotFound(const std::string &pNode) {
throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
void AMFImporter::Throw_CloseNotFound(const std::string &nodeName) {
throw DeadlyImportError("Close tag for node <" + nodeName + "> not found. Seems file is corrupt.");
}
void AMFImporter::Throw_IncorrectAttr(const std::string &pAttrName) {
throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\".");
void AMFImporter::Throw_IncorrectAttr(const std::string &nodeName, const std::string &attrName) {
throw DeadlyImportError("Node <" + nodeName + "> has incorrect attribute \"" + attrName + "\".");
}
void AMFImporter::Throw_IncorrectAttrValue(const std::string &pAttrName) {
throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
void AMFImporter::Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &attrName) {
throw DeadlyImportError("Attribute \"" + attrName + "\" in node <" + nodeName + "> has incorrect value.");
}
void AMFImporter::Throw_MoreThanOnceDefined(const std::string &pNodeType, const std::string &pDescription) {
throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + 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 " + nodeName + ". Description: " + pDescription);
}
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 ************************************************************/
/*********************************************************************************************************************************************/
void AMFImporter::XML_CheckNode_MustHaveChildren() {
if (mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children.");
void AMFImporter::XML_CheckNode_MustHaveChildren(pugi::xml_node &node) {
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) {
@ -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()) {
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;
@ -366,23 +379,24 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// 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
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
if (!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
//
// start reading
// search for root tag <amf>
if (XML_SearchNode("amf"))
ParseNode_Root();
else
mXmlParser = new XmlParser();
if (!mXmlParser->parse( file.get() ) {
delete mXmlParser;
throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
}
// Start reading, search for root tag <amf>
if (!mXmlParser->hasNode("amf")) {
throw DeadlyImportError("Root node \"amf\" not found.");
}
ParseNode_Root();
delete mReader;
// restore old XMLreader
mReader = OldReader;
}
// <amf

View File

@ -52,11 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter_Node.hpp"
// Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include "assimp/types.h"
#include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h>
#include <assimp/importerdesc.h>
#include <assimp/DefaultLogger.hpp>
// Header files, stdlib.
#include <set>
@ -261,11 +261,7 @@ private:
public:
/// Default constructor.
AMFImporter() AI_NO_EXCEPT
: mNodeElement_Cur(nullptr)
, mXmlParser(nullptr) {
// empty
}
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter();
@ -280,6 +276,15 @@ public:
void GetExtensionList(std::set<std::string> &pExtensionList);
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
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 &operator=(const AMFImporter &pScene) = delete;
@ -290,11 +295,9 @@ private:
AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
XmlParser *mXmlParser;
//irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mUnit;
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.
};
} // namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
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_Macro.hpp"
namespace Assimp
{
#include <assimp/ParsingUtils.h>
namespace Assimp {
// <mesh>
// </mesh>
// A 3D mesh hull.
// Multi elements - Yes.
// Parent element - <object>.
void AMFImporter::ParseNode_Mesh()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Mesh(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new mesh object.
ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur);
ne = new AMFMesh(mNodeElement_Cur);
// 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;
@ -87,12 +102,14 @@ CAMFImporter_NodeElement* ne;
MACRO_NODECHECK_LOOPEND("mesh");
ParseHelper_Node_Exit();
}// if(!mReader->isEmptyElement())
else
{
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
else*/
// Add element to child list of current element
if (!found_verts && !found_volumes) {
mNodeElement_Cur->Child.push_back(ne);
} // 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>
@ -100,25 +117,32 @@ CAMFImporter_NodeElement* ne;
// The list of vertices to be used in defining triangles.
// Multi elements - No.
// Parent element - <mesh>.
void AMFImporter::ParseNode_Vertices()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Vertices(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new mesh object.
ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur);
ne = new AMFVertices(mNodeElement_Cur);
// 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);
MACRO_NODECHECK_LOOPBEGIN("vertices");
if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; }
if (XML_CheckNode_NameEqual("vertex")) {
ParseNode_Vertex();
continue;
}
MACRO_NODECHECK_LOOPEND("vertices");
ParseHelper_Node_Exit();
} // if(!mReader->isEmptyElement())
else
{
else {
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.
}
@ -128,22 +152,33 @@ CAMFImporter_NodeElement* ne;
// A vertex to be referenced in triangles.
// Multi elements - Yes.
// Parent element - <vertices>.
void AMFImporter::ParseNode_Vertex()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Vertex(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new mesh object.
ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur);
// Check for child nodes
if(!mReader->isEmptyElement())
{
ne = new AMFVertex(mNodeElement_Cur);
pugi::xml_node colorNode = node.child("color");
bool col_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);
MACRO_NODECHECK_LOOPBEGIN("vertex");
if(XML_CheckNode_NameEqual("color"))
{
if (XML_CheckNode_NameEqual("color")) {
// Check if data already defined.
if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>.");
// read data and set flag about it
@ -153,8 +188,7 @@ CAMFImporter_NodeElement* ne;
continue;
}
if(XML_CheckNode_NameEqual("coordinates"))
{
if (XML_CheckNode_NameEqual("coordinates")) {
// Check if data already defined.
if (coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>.");
// read data and set flag about it
@ -164,15 +198,17 @@ CAMFImporter_NodeElement* ne;
continue;
}
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
if (XML_CheckNode_NameEqual("metadata")) {
ParseNode_Metadata();
continue;
}
MACRO_NODECHECK_LOOPEND("vertex");
ParseHelper_Node_Exit();
} // if(!mReader->isEmptyElement())
else
{
else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else
*/
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>
// Multi elements - No.
// X, Y, or Z coordinate, respectively, of a vertex position in space.
void AMFImporter::ParseNode_Coordinates()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// 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(!mReader->isEmptyElement())
{
if (node.attributes().begin() != node.attributes().end()) {
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 };
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(!mReader->isEmptyElement())
else
{
else {
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.
}
@ -228,32 +269,31 @@ CAMFImporter_NodeElement* ne;
// Defines a volume from the established vertex list.
// Multi elements - Yes.
// Parent element - <mesh>.
void AMFImporter::ParseNode_Volume()
{
void AMFImporter::ParseNode_Volume(XmlNode &node) {
std::string materialid;
std::string type;
CAMFImporter_NodeElement* ne;
AMFNodeElementBase *ne = new AMFVolume(mNodeElement_Cur);
// Read attributes for node <color>.
MACRO_ATTRREAD_LOOPBEG;
/*MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue);
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
MACRO_ATTRREAD_LOOPEND;*/
// create new object.
ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur);
//ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur);
// 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
if(!mReader->isEmptyElement())
{
if (!mReader->isEmptyElement()) {
bool col_read = false;
ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("volume");
if(XML_CheckNode_NameEqual("color"))
{
if (XML_CheckNode_NameEqual("color")) {
// Check if data already defined.
if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>.");
// read data and set flag about it
@ -263,13 +303,18 @@ CAMFImporter_NodeElement* ne;
continue;
}
if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; }
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
if (XML_CheckNode_NameEqual("triangle")) {
ParseNode_Triangle();
continue;
}
if (XML_CheckNode_NameEqual("metadata")) {
ParseNode_Metadata();
continue;
}
MACRO_NODECHECK_LOOPEND("volume");
ParseHelper_Node_Exit();
} // if(!mReader->isEmptyElement())
else
{
else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else
@ -286,8 +331,7 @@ CAMFImporter_NodeElement* ne;
// <v1>, <v2>, <v3>
// Multi elements - No.
// Index of the desired vertices in a triangle or edge.
void AMFImporter::ParseNode_Triangle()
{
void AMFImporter::ParseNode_Triangle() {
CAMFImporter_NodeElement *ne;
// create new color object.
@ -296,15 +340,13 @@ CAMFImporter_NodeElement* ne;
CAMFImporter_NodeElement_Triangle &als = *((CAMFImporter_NodeElement_Triangle *)ne); // alias for convenience
// Check for child nodes
if(!mReader->isEmptyElement())
{
if (!mReader->isEmptyElement()) {
bool col_read = false, tex_read = false;
bool read_flag[3] = { false, false, false };
ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("triangle");
if(XML_CheckNode_NameEqual("color"))
{
if (XML_CheckNode_NameEqual("color")) {
// Check if data already defined.
if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>.");
// read data and set flag about it
@ -323,8 +365,7 @@ CAMFImporter_NodeElement* ne;
tex_read = true;
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.
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(!mReader->isEmptyElement())
else
{
else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // 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_Macro.hpp"
namespace Assimp
{
namespace Assimp {
// <color
// 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()) {
bool read_flag[4] = { false, false, false, false };
for (pugi::xml_node &child : node.children()) {
if (child.name() == "r") {
std::string name = child.name();
if ( name == "r") {
read_flag[0] = true;
als.Color.r = atof(child.value());
} else if (child.name() == "g") {
als.Color.r = (ai_real)::atof(child.value());
} else if (name == "g") {
read_flag[1] = true;
als.Color.g = atof(child.value());
} else if (child.name() == "b") {
als.Color.g = (ai_real)::atof(child.value());
} else if (name == "b") {
read_flag[2] = true;
als.Color.b = atof(child.value());
} else if (child.name() == "g") {
als.Color.b = (ai_real)::atof(child.value());
} else if (name == "g") {
read_flag[3] = true;
als.Color.a = atof(child.value());
als.Color.a = (ai_real) ::atof(child.value());
}
}
// check that all components was defined
@ -127,10 +127,11 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
if (!node.empty()) {
bool col_read = false;
for (pugi::xml_node &child : node.children()) {
if (child.name() == "color") {
const std::string name = child.name();
if (name == "color") {
col_read = true;
ParseNode_Color(child);
} else if (child.name() == "metadata") {
} else if (name == "metadata") {
ParseNode_Metadata(child);
}
}
@ -256,44 +257,46 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
if (!pUseOldName) {
for (pugi::xml_attribute &attr : node.attributes()) {
if (attr.name() == "utex1") {
const std::string name = attr.name();
if (name == "utex1") {
read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float();
} else if (attr.name() == "utex2") {
} else if (name == "utex2") {
read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float();
} else if (attr.name() == "utex3") {
} else if (name == "utex3") {
read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float();
} else if (attr.name() == "vtex1") {
} else if (name == "vtex1") {
read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float();
} else if (attr.name() == "vtex2") {
} else if (name == "vtex2") {
read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float();
} else if (attr.name() == "vtex3") {
} else if (name == "vtex3") {
read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float();
}
}
} else {
for (pugi::xml_attribute &attr : node.attributes()) {
if (attr.name() == "u") {
const std::string name = attr.name();
if (name == "u") {
read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float();
} else if (attr.name() == "u2") {
} else if (name == "u2") {
read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float();
} else if (attr.name() == "u3") {
} else if (name == "u3") {
read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float();
} else if (attr.name() == "v1") {
} else if (name == "v1") {
read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float();
} else if (attr.name() == "v2") {
} else if (name == "v2") {
read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float();
} else if (attr.name() == "v3") {
} else if (name == "v3") {
read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float();
}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
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
All rights reserved.
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;
}
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
std::vector<CAMFImporter_NodeElement_Color *> &pVertexColorArray) const {
CAMFImporter_NodeElement_Vertices *vn = nullptr;
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
std::vector<AMFColor *> &pVertexColorArray) const {
AMFVertex *vn = nullptr;
size_t col_idx;
// All data stored in "vertices", search for it.
for (CAMFImporter_NodeElement *ne_child : pNodeElement.Child) {
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices *)ne_child;
for (AMFNodeElementBase *ne_child : pNodeElement.Child) {
if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
vn = (AMFVertex *)ne_child;
}
}
// 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.
pVertexColorArray.resize(vn->Child.size()); // colors count equal vertices count.
col_idx = 0;
// Inside vertices collect all data and place to arrays
for (CAMFImporter_NodeElement *vn_child : vn->Child) {
for (AMFNodeElementBase *vn_child : vn->Child) {
// vertices, colors
if (vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex) {
if (vn_child->Type == AMFNodeElementBase::ENET_Vertex) {
// by default clear color for current vertex
pVertexColorArray[col_idx] = nullptr;
for (CAMFImporter_NodeElement *vtx : vn_child->Child) {
if (vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates) {
pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates *)vtx)->Coordinate);
for (AMFNodeElementBase *vtx : vn_child->Child) {
if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
continue;
}
if (vtx->Type == CAMFImporter_NodeElement::ENET_Color) {
pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color *)vtx;
if (vtx->Type == AMFNodeElementBase::ENET_Color) {
pVertexColorArray[col_idx] = (AMFColor *)vtx;
continue;
}
} // 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.
//
CAMFImporter_NodeElement_Texture *src_texture[4]{ nullptr };
std::vector<CAMFImporter_NodeElement_Texture *> src_texture_4check;
AMFTexture *src_texture[4] {
nullptr
};
std::vector<AMFTexture *> src_texture_4check;
SPP_Texture converted_texture;
{ // find all specified source textures
CAMFImporter_NodeElement *t_tex;
AMFNodeElementBase *t_tex;
// R
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_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[0] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else {
src_texture[0] = nullptr;
}
// G
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;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
//if (!Find_NodeElement(pID_G, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);
src_texture[1] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else {
src_texture[1] = nullptr;
}
// B
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_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[2] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else {
src_texture[2] = nullptr;
}
// A
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;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
//if (!Find_NodeElement(pID_A, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);
src_texture[3] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else {
src_texture[3] = nullptr;
}
} // END: find all specified source textures
// 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++) {
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)) {
@ -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 {
if (!pID.empty()) {
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);
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) {
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) return false;
if (pTexMap2 == nullptr) return false;
@ -313,56 +331,61 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
} while (!pInputList.empty());
}
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata *> &metadataList, aiNode &sceneNode) const {
if (!metadataList.empty()) {
if (sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
void AMFImporter::Postprocess_AddMetadata(const std::list<AMFMetadata *> &metadataList, aiNode &sceneNode) const {
if (metadataList.empty()) {
return;
}
if (sceneNode.mMetaData != nullptr) {
throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
}
// copy collected metadata to output node.
sceneNode.mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metadataList.size()));
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));
}
} // if(!metadataList.empty())
}
void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode) {
CAMFImporter_NodeElement_Color *object_color = nullptr;
void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode) {
AMFColor *object_color = nullptr;
// create new aiNode and set name as <object> has.
*pSceneNode = new aiNode;
(*pSceneNode)->mName = pNodeElement.ID;
// 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<CAMFImporter_NodeElement_Color *> color_arr;
std::vector<AMFColor *> color_arr;
// 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.
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
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)
}
void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray,
const std::vector<CAMFImporter_NodeElement_Color *> &pVertexColorArray,
const CAMFImporter_NodeElement_Color *pObjectColor, std::list<aiMesh *> &pMeshList, aiNode &pSceneNode) {
void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray,
const std::vector<AMFColor *> &pVertexColorArray,
const AMFColor *pObjectColor, std::list<aiMesh *> &pMeshList, aiNode &pSceneNode) {
std::list<unsigned int> mesh_idx;
// all data stored in "volume", search for it.
for (const CAMFImporter_NodeElement *ne_child : pNodeElement.Child) {
const CAMFImporter_NodeElement_Color *ne_volume_color = nullptr;
for (const AMFNodeElementBase *ne_child : pNodeElement.Child) {
const AMFColor *ne_volume_color = nullptr;
const SPP_Material *cur_mat = nullptr;
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) {
if (ne_child->Type == AMFNodeElementBase::ENET_Volume) {
/******************* 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<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
for (const CAMFImporter_NodeElement *ne_volume_child : ne_volume->Child) {
for (const AMFNodeElementBase *ne_volume_child : ne_volume->Child) {
// color for volume
if (ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color) {
ne_volume_color = reinterpret_cast<const CAMFImporter_NodeElement_Color *>(ne_volume_child);
} else if (ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle) // triangles, triangles colors
if (ne_volume_child->Type == AMFNodeElementBase::ENET_Color) {
ne_volume_color = reinterpret_cast<const AMFColor *>(ne_volume_child);
} 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;
@ -388,11 +411,11 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
complex_face.TexMap = nullptr;
// get data from triangle children: color, texture coordinates.
if (tri_al.Child.size()) {
for (const CAMFImporter_NodeElement *ne_triangle_child : tri_al.Child) {
if (ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color)
complex_face.Color = reinterpret_cast<const CAMFImporter_NodeElement_Color *>(ne_triangle_child);
else if (ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap)
complex_face.TexMap = reinterpret_cast<const CAMFImporter_NodeElement_TexMap *>(ne_triangle_child);
for (const AMFNodeElementBase *ne_triangle_child : tri_al.Child) {
if (ne_triangle_child->Type == AMFNodeElementBase::ENET_Color)
complex_face.Color = reinterpret_cast<const AMFColor *>(ne_triangle_child);
else if (ne_triangle_child->Type == AMFNodeElementBase::ENET_TexMap)
complex_face.TexMap = reinterpret_cast<const AMFTexMap *>(ne_triangle_child);
}
} // if(tri_al.Child.size())
@ -422,15 +445,18 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
if (face.Face.mIndices[idx_vert] > *pBiggerThan) {
rv = face.Face.mIndices[idx_vert];
found = true;
break;
}
}
if (found) break;
if (found) {
break;
}
}
if (!found) return *pBiggerThan;
if (!found) {
return *pBiggerThan;
}
} else {
rv = pFaceList.front().Face.mIndices[0];
} // 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->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.
// 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.
std::vector<aiVector3D> vert_arr, texcoord_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();
///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
/// optimisation.
/// optimization.
bool *idx_vert_used;
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)
}
void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material &pMaterial) {
void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &pMaterial) {
SPP_Material new_mat;
new_mat.ID = pMaterial.ID;
for (const CAMFImporter_NodeElement *mat_child : pMaterial.Child) {
if (mat_child->Type == CAMFImporter_NodeElement::ENET_Color) {
new_mat.Color = (CAMFImporter_NodeElement_Color *)mat_child;
} else if (mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata) {
new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata *)mat_child);
for (const AMFNodeElementBase *mat_child : pMaterial.Child) {
if (mat_child->Type == AMFNodeElementBase::ENET_Color) {
new_mat.Color = (AMFColor*)mat_child;
} else if (mat_child->Type == AMFNodeElementBase::ENET_Metadata) {
new_mat.Metadata.push_back((AMFMetadata *)mat_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);
}
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;
std::list<aiNode *> ch_node;
@ -672,8 +698,8 @@ void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Conste
aiNode *t_node;
aiNode *found_node;
if (ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue;
if (ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue;
if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
// create alias for conveniance
CAMFImporter_NodeElement_Instance &als = *((CAMFImporter_NodeElement_Instance *)ne);
@ -723,10 +749,10 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
pScene->mRootNode->mParent = nullptr;
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
// search for root(<amf>) element
CAMFImporter_NodeElement *root_el = nullptr;
AMFNodeElementBase *root_el = nullptr;
for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
if (ne->Type != CAMFImporter_NodeElement::ENET_Root) continue;
for (AMFNodeElementBase *ne : mNodeElement_List) {
if (ne->Type != AMFNodeElementBase::ENET_Root) continue;
root_el = ne;
@ -742,15 +768,15 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
//
// 1. <material>
// 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
for (const CAMFImporter_NodeElement *root_child : root_el->Child) {
if (root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material *)root_child));
for (const AMFNodeElementBase *root_child : root_el->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>.
//
// 3. <object>
for (const CAMFImporter_NodeElement *root_child : root_el->Child) {
if (root_child->Type == CAMFImporter_NodeElement::ENET_Object) {
for (const AMFNodeElementBase *root_child : root_el->Child) {
if (root_child->Type == AMFNodeElementBase::ENET_Object) {
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>
@ -761,15 +787,15 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
// 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>
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.
Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation *)root_child), node_list);
Postprocess_BuildConstellation(*((AMFConstellation *)root_child), node_list);
}
// 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)
// 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
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
mFileName(pFile),
mReader(nullptr),
mXmlParser(),
mDataLibrary(),
mAccessorLibrary(),
mMeshLibrary(),
@ -116,16 +116,19 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
throw DeadlyImportError("Failed to open file '" + pFile + "'.");
}
}
pugi::xml_node *root = mXmlParser.parse(daefile.get());
// 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());
if (!mReader) {
ThrowException("Unable to read file, malformed XML");
}
}*/
// start reading
ReadContents();
ReadContents(*root);
// read embedded textures
if (zip_archive && zip_archive->isOpen()) {
@ -136,7 +139,6 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ColladaParser::~ColladaParser() {
delete mReader;
for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
delete it->second;
for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
@ -252,8 +254,28 @@ ai_real ColladaParser::ReadFloatFromTextContent() {
// ------------------------------------------------------------------------------------------------
// Reads the contents of the file
void ColladaParser::ReadContents() {
while (mReader->read()) {
void ColladaParser::ReadContents(XmlNode &node) {
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"
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("COLLADA")) {
@ -287,13 +309,44 @@ void ColladaParser::ReadContents() {
} else {
// skip everything else silently
}
}
}*/
}
// ------------------------------------------------------------------------------------------------
// Reads the structure of the file
void ColladaParser::ReadStructure() {
while (mReader->read()) {
void ColladaParser::ReadStructure(XmlNode &node) {
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
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("asset"))
@ -319,15 +372,14 @@ void ColladaParser::ReadStructure() {
else if (IsElement("library_cameras"))
ReadCameraLibrary();
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"))
ReadScene();
else
SkipElement();
} else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
break;
}
}
}*/
PostProcessRootAnimations();
PostProcessControllers();
@ -335,11 +387,32 @@ void ColladaParser::ReadStructure() {
// ------------------------------------------------------------------------------------------------
// Reads asset information such as coordinate system information and legal blah
void ColladaParser::ReadAssetInfo() {
if (mReader->isEmptyElement())
return;
void ColladaParser::ReadAssetInfo(XmlNode &node) {
/* if (mReader->isEmptyElement())
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 (IsElement("unit")) {
// read unit data from the element's attributes
@ -376,12 +449,12 @@ void ColladaParser::ReadAssetInfo() {
break;
}
}
}*/
}
// ------------------------------------------------------------------------------------------------
// Reads the contributor info
void ColladaParser::ReadContributorInfo() {
/*void ColladaParser::ReadContributorInfo(XmlNode & node) {
if (mReader->isEmptyElement())
return;
@ -394,7 +467,7 @@ void ColladaParser::ReadContributorInfo() {
break;
}
}
}
}*/
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) {
@ -404,15 +477,36 @@ static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVecto
}
}
found_index = std::numeric_limits<size_t>::max();
return false;
}
// ------------------------------------------------------------------------------------------------
// 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 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
const char *key_char = mReader->getNodeName();
/*const char *key_char = mReader->getNodeName();
if (key_char != nullptr) {
const std::string key_str(key_char);
const char *value_char = TestTextContent();
@ -432,16 +526,53 @@ void ColladaParser::ReadMetaDataItem(StringMetaData &metadata) {
}
TestClosing(key_str.c_str());
} else
SkipElement();
SkipElement();*/
}
// ------------------------------------------------------------------------------------------------
// Reads the animation clips
void ColladaParser::ReadAnimationClipLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
/*if (mReader->isEmptyElement())
return;*/
if (node.empty()) {
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 (IsElement("animation_clip")) {
// optional name given as an attribute
@ -497,7 +628,7 @@ void ColladaParser::ReadAnimationClipLibrary() {
break;
}
}
}*/
}
void ColladaParser::PostProcessControllers() {
@ -517,7 +648,11 @@ void ColladaParser::PostProcessControllers() {
// ------------------------------------------------------------------------------------------------
// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
void ColladaParser::PostProcessRootAnimations() {
if (mAnimationClipLibrary.size() > 0) {
if (mAnimationClipLibrary.empty()) {
mAnims.CombineSingleChannelAnimations();
return;
}
Animation temp;
for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) {
@ -545,18 +680,21 @@ void ColladaParser::PostProcessRootAnimations() {
// Ensure no double deletes.
temp.mSubAnims.clear();
} else {
mAnims.CombineSingleChannelAnimations();
}
}
// ------------------------------------------------------------------------------------------------
// Reads the animation library
void ColladaParser::ReadAnimationLibrary() {
if (mReader->isEmptyElement())
return;
void ColladaParser::ReadAnimationLibrary(XmlNode &node) {
/*if (mReader->isEmptyElement())
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 (IsElement("animation")) {
// 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;
}
}
}*/
}
// ------------------------------------------------------------------------------------------------
// Reads an animation into the given parent structure
void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
if (mReader->isEmptyElement())
void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
// 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
@ -589,11 +730,22 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
// optional name given as an attribute
std::string animName;
std::string animID;
int indexName = TestAttribute("name");
int indexID = TestAttribute("id");
pugi::xml_attribute nameAttr = node.attribute("name");
if (nameAttr) {
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);
if (indexName >= 0)
@ -602,8 +754,44 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
animName = animID;
else
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) {
// we have subanimations
if (IsElement("animation")) {
@ -652,7 +840,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
break;
}
}
}*/
// it turned out to have channels - add them
if (!channels.empty()) {
@ -679,7 +867,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
for (ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
anim->mChannels.push_back(it->second);
if (indexID >= 0) {
if (idAttr >= 0) {
mAnimationLibrary[animID] = anim;
}
}
@ -688,8 +876,16 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
// ------------------------------------------------------------------------------------------------
// Reads an animation sampler into the given anim channel
void ColladaParser::ReadAnimationSampler(Collada::AnimationChannel &pChannel) {
while (mReader->read()) {
void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
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 (IsElement("input")) {
int indexSemantic = GetAttribute("semantic");
@ -723,14 +919,17 @@ void ColladaParser::ReadAnimationSampler(Collada::AnimationChannel &pChannel) {
break;
}
}
}*/
}
// ------------------------------------------------------------------------------------------------
// Reads the skeleton controller library
void ColladaParser::ReadControllerLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadControllerLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -759,7 +958,7 @@ void ColladaParser::ReadControllerLibrary() {
// ------------------------------------------------------------------------------------------------
// Reads a controller into the given mesh structure
void ColladaParser::ReadController(Collada::Controller &pController) {
void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pController) {
// initial values
pController.mType = Skin;
pController.mMethod = Normalized;
@ -838,7 +1037,7 @@ void ColladaParser::ReadController(Collada::Controller &pController) {
// ------------------------------------------------------------------------------------------------
// 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()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
// 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
void ColladaParser::ReadControllerWeights(Collada::Controller &pController) {
void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) {
// read vertex count from attributes and resize the array accordingly
int indexCount = GetAttribute("count");
size_t vertexCount = (size_t)mReader->getAttributeValueAsInt(indexCount);
@ -963,9 +1162,12 @@ void ColladaParser::ReadControllerWeights(Collada::Controller &pController) {
// ------------------------------------------------------------------------------------------------
// Reads the image library contents
void ColladaParser::ReadImageLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadImageLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -994,7 +1196,7 @@ void ColladaParser::ReadImageLibrary() {
// ------------------------------------------------------------------------------------------------
// 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()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
// 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
void ColladaParser::ReadMaterialLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
std::map<std::string, int> names;
while (mReader->read()) {
@ -1129,9 +1334,12 @@ void ColladaParser::ReadMaterialLibrary() {
// ------------------------------------------------------------------------------------------------
// Reads the light library
void ColladaParser::ReadLightLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadLightLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1158,9 +1366,12 @@ void ColladaParser::ReadLightLibrary() {
// ------------------------------------------------------------------------------------------------
// Reads the camera library
void ColladaParser::ReadCameraLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadCameraLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1192,7 +1403,7 @@ void ColladaParser::ReadCameraLibrary() {
// ------------------------------------------------------------------------------------------------
// 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()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("material")) {
@ -1222,7 +1433,7 @@ void ColladaParser::ReadMaterial(Collada::Material &pMaterial) {
// ------------------------------------------------------------------------------------------------
// 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()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("light")) {
@ -1300,34 +1511,26 @@ void ColladaParser::ReadLight(Collada::Light &pLight) {
// ------------------------------------------------------------------------------------------------
// Reads a camera entry into the given light
void ColladaParser::ReadCamera(Collada::Camera& camera)
{
while (mReader->read())
{
void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("camera")) {
SkipElement();
}
else if (IsElement("orthographic")) {
} else if (IsElement("orthographic")) {
camera.mOrtho = true;
}
else if (IsElement("xfov") || IsElement("xmag")) {
} else if (IsElement("xfov") || IsElement("xmag")) {
camera.mHorFov = ReadFloatFromTextContent();
TestClosing((camera.mOrtho ? "xmag" : "xfov"));
}
else if (IsElement("yfov") || IsElement("ymag")) {
} else if (IsElement("yfov") || IsElement("ymag")) {
camera.mVerFov = ReadFloatFromTextContent();
TestClosing((camera.mOrtho ? "ymag" : "yfov"));
}
else if (IsElement("aspect_ratio")) {
} else if (IsElement("aspect_ratio")) {
camera.mAspect = ReadFloatFromTextContent();
TestClosing("aspect_ratio");
}
else if (IsElement("znear")) {
} else if (IsElement("znear")) {
camera.mZNear = ReadFloatFromTextContent();
TestClosing("znear");
}
else if (IsElement("zfar")) {
} else if (IsElement("zfar")) {
camera.mZFar = ReadFloatFromTextContent();
TestClosing("zfar");
}
@ -1340,10 +1543,13 @@ void ColladaParser::ReadCamera(Collada::Camera& camera)
// ------------------------------------------------------------------------------------------------
// Reads the effect library
void ColladaParser::ReadEffectLibrary() {
if (mReader->isEmptyElement()) {
void ColladaParser::ReadEffectLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement()) {
return;
}*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1371,7 +1577,7 @@ void ColladaParser::ReadEffectLibrary() {
// ------------------------------------------------------------------------------------------------
// 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.
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1390,7 +1596,7 @@ void ColladaParser::ReadEffect(Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------
// Reads an COMMON effect profile
void ColladaParser::ReadEffectProfileCommon(Collada::Effect &pEffect) {
void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) {
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("newparam")) {
@ -1496,10 +1702,13 @@ void ColladaParser::ReadEffectProfileCommon(Collada::Effect &pEffect) {
// ------------------------------------------------------------------------------------------------
// Read texture wrapping + UV transform settings from a profile==Maya chunk
void ColladaParser::ReadSamplerProperties(Sampler &out) {
if (mReader->isEmptyElement()) {
void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement()) {
return;
}*/
while (mReader->read()) {
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
void ColladaParser::ReadEffectColor(aiColor4D &pColor, Sampler &pSampler) {
if (mReader->isEmptyElement())
void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &pSampler) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
// Save current element name
const std::string curElem = mReader->getNodeName();
@ -1639,7 +1851,7 @@ void ColladaParser::ReadEffectColor(aiColor4D &pColor, Sampler &pSampler) {
// ------------------------------------------------------------------------------------------------
// Reads an effect entry containing a float
void ColladaParser::ReadEffectFloat(ai_real &pFloat) {
void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("float")) {
@ -1661,7 +1873,7 @@ void ColladaParser::ReadEffectFloat(ai_real &pFloat) {
// ------------------------------------------------------------------------------------------------
// 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()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
if (IsElement("surface")) {
@ -1707,9 +1919,12 @@ void ColladaParser::ReadEffectParam(Collada::EffectParam &pParam) {
// ------------------------------------------------------------------------------------------------
// Reads the geometry library contents
void ColladaParser::ReadGeometryLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadGeometryLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1755,9 +1970,12 @@ void ColladaParser::ReadGeometryLibrary() {
// ------------------------------------------------------------------------------------------------
// Reads a geometry from the geometry library.
void ColladaParser::ReadGeometry(Collada::Mesh &pMesh) {
if (mReader->isEmptyElement())
void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1779,9 +1997,12 @@ void ColladaParser::ReadGeometry(Collada::Mesh &pMesh) {
// ------------------------------------------------------------------------------------------------
// Reads a mesh from the geometry library
void ColladaParser::ReadMesh(Mesh &pMesh) {
if (mReader->isEmptyElement())
void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
@ -1814,7 +2035,7 @@ void ColladaParser::ReadMesh(Mesh &pMesh) {
// ------------------------------------------------------------------------------------------------
// Reads a source element
void ColladaParser::ReadSource() {
void ColladaParser::ReadSource(XmlNode &node) {
int indexID = GetAttribute("id");
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
void ColladaParser::ReadDataArray() {
void ColladaParser::ReadDataArray(XmlNode &node) {
std::string elmName = mReader->getNodeName();
bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
bool isEmptyElement = mReader->isEmptyElement();
@ -1904,7 +2125,7 @@ void ColladaParser::ReadDataArray() {
// ------------------------------------------------------------------------------------------------
// 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
int attrSource = GetAttribute("source");
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
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
int attrID = GetAttribute("id");
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
void ColladaParser::ReadIndexData(Mesh &pMesh) {
void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
std::vector<size_t> vcount;
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
void ColladaParser::ReadInputChannel(std::vector<InputChannel> &poChannels) {
void ColladaParser::ReadInputChannel(XmlNode &node, std::vector<InputChannel> &poChannels) {
InputChannel channel;
// 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
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) {
// determine number of indices coming per vertex
// 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.
///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
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
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]);
}
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) {
//odd tristrip triangles need their indices mangled, to preserve winding direction
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
void ColladaParser::ReadSceneLibrary() {
if (mReader->isEmptyElement())
void ColladaParser::ReadSceneLibrary(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
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
void ColladaParser::ReadSceneNode(Node *pNode) {
void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
// quit immediately on <bla/> elements
if (mReader->isEmptyElement())
if (node.empty()) {
return;
}
/* if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
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.
void ColladaParser::ReadNodeTransformation(Node *pNode, TransformType pType) {
if (mReader->isEmptyElement())
void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
std::string tagName = mReader->getNodeName();
@ -2663,7 +2896,7 @@ void ColladaParser::ReadNodeTransformation(Node *pNode, TransformType pType) {
// ------------------------------------------------------------------------------------------------
// Processes bind_vertex_input and bind elements
void ColladaParser::ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl) {
void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) {
while (mReader->read()) {
if (mReader->getNodeType() == irr::io::EXN_ELEMENT) {
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
void ColladaParser::ReadNodeGeometry(Node *pNode) {
void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
// referred mesh is given as an attribute of the <instance_geometry> element
int attrUrl = GetAttribute("url");
const char *url = mReader->getAttributeValue(attrUrl);
@ -2760,9 +2993,12 @@ void ColladaParser::ReadNodeGeometry(Node *pNode) {
// ------------------------------------------------------------------------------------------------
// Reads the collada scene
void ColladaParser::ReadScene() {
if (mReader->isEmptyElement())
void ColladaParser::ReadScene(XmlNode &node) {
if (node.empty()) {
return;
}
/*if (mReader->isEmptyElement())
return;*/
while (mReader->read()) {
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
void ColladaParser::SkipElement() {
/*void ColladaParser::SkipElement() {
// nothing to skip if it's an <element />
if (mReader->isEmptyElement()) {
return;
@ -2821,11 +3057,11 @@ void ColladaParser::SkipElement() {
// reroute
SkipElement(mReader->getNodeName());
}
}*/
// ------------------------------------------------------------------------------------------------
// 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,
// which is going to change with the upcoming parsing
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
void ColladaParser::TestOpening(const char *pName) {
/*void ColladaParser::TestOpening(const char *pName) {
// read element start
if (!mReader->read()) {
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) {
ThrowException(format() << "Expected start of <" << pName << "> element.");
}
}
}*/
// ------------------------------------------------------------------------------------------------
// 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
if (mReader->isEmptyElement()) {
return;
@ -2885,7 +3121,7 @@ void ColladaParser::TestClosing(const char *pName) {
if (mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp(mReader->getNodeName(), pName) != 0) {
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
@ -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 res;

View File

@ -50,9 +50,10 @@
#include "ColladaHelper.h"
#include <assimp/TinyFormatter.h>
#include <assimp/ai_assert.h>
#include <assimp/irrXMLWrapper.h>
#include <assimp/XmlParser.h>
namespace Assimp {
class ZipArchiveIOSystem;
// ------------------------------------------------------------------------------------------
@ -81,25 +82,25 @@ protected:
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
/** Reads the contents of the file */
void ReadContents();
void ReadContents(XmlNode &node);
/** Reads the structure of the file */
void ReadStructure();
void ReadStructure(XmlNode &node);
/** 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 */
void ReadContributorInfo();
void ReadContributorInfo(XmlNode &node);
/** 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 */
void ReadAnimationLibrary();
void ReadAnimationLibrary(XmlNode &node);
/** Reads the animation clip library */
void ReadAnimationClipLibrary();
void ReadAnimationClipLibrary(XmlNode &node);
/** Unwrap controllers dependency hierarchy */
void PostProcessControllers();
@ -108,103 +109,103 @@ protected:
void PostProcessRootAnimations();
/** 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 */
void ReadAnimationSampler(Collada::AnimationChannel &pChannel);
void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel);
/** Reads the skeleton controller library */
void ReadControllerLibrary();
void ReadControllerLibrary(XmlNode &node);
/** 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 */
void ReadControllerJoints(Collada::Controller &pController);
void ReadControllerJoints(XmlNode &node, Collada::Controller &pController);
/** 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 */
void ReadImageLibrary();
void ReadImageLibrary(XmlNode &node);
/** Reads an image entry into the given image */
void ReadImage(Collada::Image &pImage);
void ReadImage(XmlNode &node, Collada::Image &pImage);
/** Reads the material library */
void ReadMaterialLibrary();
void ReadMaterialLibrary(XmlNode &node);
/** Reads a material entry into the given material */
void ReadMaterial(Collada::Material &pMaterial);
void ReadMaterial(XmlNode &node, Collada::Material &pMaterial);
/** Reads the camera library */
void ReadCameraLibrary();
void ReadCameraLibrary(XmlNode &node);
/** Reads a camera entry into the given camera */
void ReadCamera(Collada::Camera &pCamera);
void ReadCamera(XmlNode &node, Collada::Camera &pCamera);
/** Reads the light library */
void ReadLightLibrary();
void ReadLightLibrary(XmlNode &node);
/** Reads a light entry into the given light */
void ReadLight(Collada::Light &pLight);
void ReadLight(XmlNode &node, Collada::Light &pLight);
/** Reads the effect library */
void ReadEffectLibrary();
void ReadEffectLibrary(XmlNode &node);
/** 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 */
void ReadEffectProfileCommon(Collada::Effect &pEffect);
void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
/** 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 */
void ReadEffectColor(aiColor4D &pColor, Collada::Sampler &pSampler);
void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
/** 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 */
void ReadEffectParam(Collada::EffectParam &pParam);
void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
/** Reads the geometry library contents */
void ReadGeometryLibrary();
void ReadGeometryLibrary(XmlNode &node);
/** 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 */
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
* 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.
* 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 -
* 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 */
void ReadVertexData(Collada::Mesh &pMesh);
void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
/** 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 */
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 */
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);
/** 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);
/** 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 */
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. */
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 */
void ReadNodeGeometry(Collada::Node *pNode);
void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
/** Reads the collada scene */
void ReadScene();
void ReadScene(XmlNode &node);
// 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*/
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
@ -246,19 +247,19 @@ protected:
void ReportWarning(const char *msg, ...);
/** 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 */
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 */
bool IsElement(const char *pName) const;
/** 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 */
void TestClosing(const char *pName);
//void TestClosing(const char *pName);
/** Checks the present element for the presence of the attribute, returns its index
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;
protected:
/** Filename, for a verbose error message */
// Filename, for a verbose error message
std::string mFileName;
/** XML reader, member for everyday use */
irr::io::IrrXMLReader *mReader;
// XML reader, member for everyday use
//irr::io::IrrXMLReader *mReader;
XmlParser mXmlParser;
/** All data arrays found in the file by ID. Might be referred to by actually
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
IRRMeshImporter::IRRMeshImporter() {}
IRRMeshImporter::IRRMeshImporter() :
BaseImporter(),
IrrlichtBase() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
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
#define AI_IRRMESHLOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include "IRRShared.h"
#include <assimp/BaseImporter.h>
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
@ -61,15 +60,11 @@ namespace Assimp {
* irrEdit. As IrrEdit itself is capable of importing quite many file formats,
* it might be a good file format for data exchange.
*/
class IRRMeshImporter : public BaseImporter, public IrrlichtBase
{
class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
public:
IRRMeshImporter();
~IRRMeshImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
@ -78,7 +73,6 @@ public:
bool checkSig) const;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
@ -91,7 +85,6 @@ protected:
*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
};
} // 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
*/
//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))
@ -57,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
// 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,
0.0f, 0.0f, 1.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)
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")) {
out.name = std::string( attrib.value() );
} else if (!ASSIMP_stricmp(attrib.name(),"value")) {
@ -79,7 +77,7 @@ void IrrlichtBase::ReadHexProperty(HexProperty &out ) {
// ------------------------------------------------------------------------------------------------
// read a decimal property
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")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.value(),"value")) {
@ -92,7 +90,7 @@ void IrrlichtBase::ReadIntProperty(IntProperty & out) {
// ------------------------------------------------------------------------------------------------
// read a string property
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")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -105,7 +103,7 @@ void IrrlichtBase::ReadStringProperty (StringProperty& out) {
// ------------------------------------------------------------------------------------------------
// read a boolean property
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")){
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -118,7 +116,7 @@ void IrrlichtBase::ReadBoolProperty(BoolProperty &out) {
// ------------------------------------------------------------------------------------------------
// read a float property
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")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
@ -131,7 +129,7 @@ void IrrlichtBase::ReadFloatProperty(FloatProperty &out) {
// ------------------------------------------------------------------------------------------------
// read a vector property
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")) {
out.name = std::string(attrib.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
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
HexProperty prop;
ReadHexProperty(prop);

View File

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

View File

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

View File

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