start to migrate colladat and amf

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

View File

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

View File

@ -52,11 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter_Node.hpp" #include "AMFImporter_Node.hpp"
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include "assimp/types.h" #include "assimp/types.h"
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h> #include <assimp/XmlParser.h>
#include <assimp/importerdesc.h>
#include <assimp/DefaultLogger.hpp>
// Header files, stdlib. // Header files, stdlib.
#include <set> #include <set>
@ -99,22 +99,22 @@ namespace Assimp {
/// ///
class AMFImporter : public BaseImporter { class AMFImporter : public BaseImporter {
private: private:
struct SPP_Material;// forward declaration struct SPP_Material; // forward declaration
/// \struct SPP_Composite /// \struct SPP_Composite
/// Data type for post-processing step. More suitable container for part of material's composition. /// Data type for post-processing step. More suitable container for part of material's composition.
struct SPP_Composite { struct SPP_Composite {
SPP_Material* Material;///< Pointer to material - part of composition. SPP_Material *Material; ///< Pointer to material - part of composition.
std::string Formula;///< Formula for calculating ratio of \ref Material. std::string Formula; ///< Formula for calculating ratio of \ref Material.
}; };
/// \struct SPP_Material /// \struct SPP_Material
/// Data type for post-processing step. More suitable container for material. /// Data type for post-processing step. More suitable container for material.
struct SPP_Material { struct SPP_Material {
std::string ID;///< Material ID. std::string ID; ///< Material ID.
std::list<AMFMetadata*> Metadata;///< Metadata of material. std::list<AMFMetadata *> Metadata; ///< Metadata of material.
AMFColor* Color;///< Color of material. AMFColor *Color; ///< Color of material.
std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another. std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
/// Return color calculated for specified coordinate. /// Return color calculated for specified coordinate.
/// \param [in] pX - "x" coordinate. /// \param [in] pX - "x" coordinate.
@ -127,176 +127,179 @@ private:
/// Data type for post-processing step. More suitable container for texture. /// Data type for post-processing step. More suitable container for texture.
struct SPP_Texture { struct SPP_Texture {
std::string ID; std::string ID;
size_t Width, Height, Depth; size_t Width, Height, Depth;
bool Tiled; bool Tiled;
char FormatHint[9];// 8 for string + 1 for terminator. char FormatHint[9]; // 8 for string + 1 for terminator.
uint8_t *Data; uint8_t *Data;
}; };
/// Data type for post-processing step. Contain face data. /// Data type for post-processing step. Contain face data.
struct SComplexFace { struct SComplexFace {
aiFace Face;///< Face vertices. aiFace Face; ///< Face vertices.
const AMFColor* Color;///< Face color. Equal to nullptr if color is not set for the face. const AMFColor *Color; ///< Face color. Equal to nullptr if color is not set for the face.
const AMFTexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
}; };
/// Clear all temporary data. /// Clear all temporary data.
void Clear(); void Clear();
/// Get data stored in <vertices> and place it to arrays. /// Get data stored in <vertices> and place it to arrays.
/// \param [in] pNodeElement - reference to node element which kept <object> data. /// \param [in] pNodeElement - reference to node element which kept <object> data.
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>. /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
/// \param [in] pVertexColorArray - reference to vertices colors for all <vertex's. If color for vertex is not set then corresponding member of array /// \param [in] pVertexColorArray - reference to vertices colors for all <vertex's. If color for vertex is not set then corresponding member of array
/// contain nullptr. /// contain nullptr.
void PostprocessHelper_CreateMeshDataArray(const AMFMesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, void PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
std::vector<AMFColor*>& pVertexColorArray) const; std::vector<AMFColor *> &pVertexColorArray) const;
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
/// to converted textures list. /// to converted textures list.
/// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified. /// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
/// \param [in] pID_R - ID of source "red" texture. /// \param [in] pID_R - ID of source "red" texture.
/// \param [in] pID_G - ID of source "green" texture. /// \param [in] pID_G - ID of source "green" texture.
/// \param [in] pID_B - ID of source "blue" texture. /// \param [in] pID_B - ID of source "blue" texture.
/// \param [in] pID_A - ID of source "alpha" texture. /// \param [in] pID_A - ID of source "alpha" texture.
/// \return index of the texture in array of the converted textures. /// \return index of the texture in array of the converted textures.
size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A); size_t PostprocessHelper_GetTextureID_Or_Create(const std::string &pID_R, const std::string &pID_G, const std::string &pID_B, const std::string &pID_A);
/// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc). /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
/// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
/// processing. /// processing.
/// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing. /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated); void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace> &pInputList, std::list<std::list<SComplexFace>> &pOutputList_Separated);
/// Check if child elements of node element is metadata and add it to scene node. /// Check if child elements of node element is metadata and add it to scene node.
/// \param [in] pMetadataList - reference to list with collected metadata. /// \param [in] pMetadataList - reference to list with collected metadata.
/// \param [out] pSceneNode - scene node in which metadata will be added. /// \param [out] pSceneNode - scene node in which metadata will be added.
void Postprocess_AddMetadata(const std::list<AMFMetadata*>& pMetadataList, aiNode& pSceneNode) const; void Postprocess_AddMetadata(const std::list<AMFMetadata *> &pMetadataList, aiNode &pSceneNode) const;
/// To create aiMesh and aiNode for it from <object>. /// To create aiMesh and aiNode for it from <object>.
/// \param [in] pNodeElement - reference to node element which kept <object> data. /// \param [in] pNodeElement - reference to node element which kept <object> data.
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene. /// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
/// \param [out] pSceneNode - pointer to place where new aiNode will be created. /// \param [out] pSceneNode - pointer to place where new aiNode will be created.
void Postprocess_BuildNodeAndObject(const AMFObject& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode); void Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode);
/// Create mesh for every <volume> in <mesh>. /// Create mesh for every <volume> in <mesh>.
/// \param [in] pNodeElement - reference to node element which kept <mesh> data. /// \param [in] pNodeElement - reference to node element which kept <mesh> data.
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s. /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
/// \param [in] pVertexColorArray - reference to vertices colors for all <volume>'s. If color for vertex is not set then corresponding member of array /// \param [in] pVertexColorArray - reference to vertices colors for all <volume>'s. If color for vertex is not set then corresponding member of array
/// contain nullptr. /// contain nullptr.
/// \param [in] pObjectColor - pointer to colors for <object>. If color is not set then argument contain nullptr. /// \param [in] pObjectColor - pointer to colors for <object>. If color is not set then argument contain nullptr.
/// \param [in] pMaterialList - reference to a list with defined materials. /// \param [in] pMaterialList - reference to a list with defined materials.
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene. /// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
/// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's. /// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's.
void Postprocess_BuildMeshSet(const AMFMesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray, void Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray,
const std::vector<AMFColor*>& pVertexColorArray, const AMFColor* pObjectColor, const std::vector<AMFColor *> &pVertexColorArray, const AMFColor *pObjectColor,
std::list<aiMesh*>& pMeshList, aiNode& pSceneNode); std::list<aiMesh *> &pMeshList, aiNode &pSceneNode);
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
void Postprocess_BuildMaterial(const AMFMaterial& pMaterial); void Postprocess_BuildMaterial(const AMFMaterial &pMaterial);
/// Create and add to aiNode's list new part of scene graph defined by <constellation>. /// Create and add to aiNode's list new part of scene graph defined by <constellation>.
/// \param [in] pConstellation - reference to <constellation> node. /// \param [in] pConstellation - reference to <constellation> node.
/// \param [out] pNodeList - reference to aiNode's list. /// \param [out] pNodeList - reference to aiNode's list.
void Postprocess_BuildConstellation(AMFConstellation& pConstellation, std::list<aiNode*>& pNodeList) const; void Postprocess_BuildConstellation(AMFConstellation &pConstellation, std::list<aiNode *> &pNodeList) const;
/// Build Assimp scene graph in aiScene from collected data. /// Build Assimp scene graph in aiScene from collected data.
/// \param [out] pScene - pointer to aiScene where tree will be built. /// \param [out] pScene - pointer to aiScene where tree will be built.
void Postprocess_BuildScene(aiScene* pScene); void Postprocess_BuildScene(aiScene *pScene);
/// Decode Base64-encoded data. /// Decode Base64-encoded data.
/// \param [in] pInputBase64 - reference to input Base64-encoded string. /// \param [in] pInputBase64 - reference to input Base64-encoded string.
/// \param [out] pOutputData - reference to output array for decoded data. /// \param [out] pOutputData - reference to output array for decoded data.
void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const; void ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const;
/// Parse <AMF> node of the file. /// Parse <AMF> node of the file.
void ParseNode_Root(XmlNode &root); void ParseNode_Root(XmlNode &root);
/// Parse <constellation> node of the file. /// Parse <constellation> node of the file.
void ParseNode_Constellation(XmlNode &node); void ParseNode_Constellation(XmlNode &node);
/// Parse <instance> node of the file. /// Parse <instance> node of the file.
void ParseNode_Instance(XmlNode &node); void ParseNode_Instance(XmlNode &node);
/// Parse <material> node of the file. /// Parse <material> node of the file.
void ParseNode_Material(XmlNode &node); void ParseNode_Material(XmlNode &node);
/// Parse <metadata> node. /// Parse <metadata> node.
void ParseNode_Metadata(XmlNode &node); void ParseNode_Metadata(XmlNode &node);
/// Parse <object> node of the file. /// Parse <object> node of the file.
void ParseNode_Object(XmlNode &node); void ParseNode_Object(XmlNode &node);
/// Parse <texture> node of the file. /// Parse <texture> node of the file.
void ParseNode_Texture(XmlNode &node); void ParseNode_Texture(XmlNode &node);
/// Parse <coordinates> node of the file. /// Parse <coordinates> node of the file.
void ParseNode_Coordinates(XmlNode &node); void ParseNode_Coordinates(XmlNode &node);
/// Parse <edge> node of the file. /// Parse <edge> node of the file.
void ParseNode_Edge(XmlNode &node); void ParseNode_Edge(XmlNode &node);
/// Parse <mesh> node of the file. /// Parse <mesh> node of the file.
void ParseNode_Mesh(XmlNode &node); void ParseNode_Mesh(XmlNode &node);
/// Parse <triangle> node of the file. /// Parse <triangle> node of the file.
void ParseNode_Triangle(XmlNode &node); void ParseNode_Triangle(XmlNode &node);
/// Parse <vertex> node of the file. /// Parse <vertex> node of the file.
void ParseNode_Vertex(XmlNode &node); void ParseNode_Vertex(XmlNode &node);
/// Parse <vertices> node of the file. /// Parse <vertices> node of the file.
void ParseNode_Vertices(XmlNode &node); void ParseNode_Vertices(XmlNode &node);
/// Parse <volume> node of the file. /// Parse <volume> node of the file.
void ParseNode_Volume(XmlNode &node); void ParseNode_Volume(XmlNode &node);
/// Parse <color> node of the file. /// Parse <color> node of the file.
void ParseNode_Color(XmlNode &node); void ParseNode_Color(XmlNode &node);
/// Parse <texmap> of <map> node of the file. /// Parse <texmap> of <map> node of the file.
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>. /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false); void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
public: public:
/// Default constructor. /// Default constructor.
AMFImporter() AI_NO_EXCEPT AMFImporter() AI_NO_EXCEPT;
: mNodeElement_Cur(nullptr)
, mXmlParser(nullptr) {
// empty
}
/// Default destructor. /// Default destructor.
~AMFImporter(); ~AMFImporter();
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be thrown if trouble will found. /// Also exception can be thrown if trouble will found.
/// \param [in] pFile - name of file to be parsed. /// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object. /// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string& pFile, IOSystem* pIOHandler); void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const; bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
void GetExtensionList(std::set<std::string>& pExtensionList); void GetExtensionList(std::set<std::string> &pExtensionList);
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
const aiImporterDesc* GetInfo ()const; const aiImporterDesc *GetInfo() const;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, std::list<aiNode *> &pNodeList, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
void Throw_CloseNotFound(const std::string &nodeName);
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
void Throw_ID_NotFound(const std::string &pID) const;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
AMFImporter(const AMFImporter& pScene) = delete; AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter& operator=(const AMFImporter& pScene) = delete; AMFImporter &operator=(const AMFImporter &pScene) = delete;
private: private:
static const aiImporterDesc Description; static const aiImporterDesc Description;
AMFNodeElementBase* mNodeElement_Cur;///< Current element. AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
std::list<AMFNodeElementBase*> mNodeElement_List;///< All elements of scene graph. std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
XmlParser *mXmlParser; XmlParser *mXmlParser;
//irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mUnit; std::string mUnit;
std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step. std::list<SPP_Material> mMaterial_Converted; ///< List of converted materials for postprocessing step.
std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step. std::list<SPP_Texture> mTexture_Converted; ///< List of converted textures for postprocessing step.
}; };
}// namespace Assimp } // namespace Assimp
#endif // INCLUDED_AI_AMF_IMPORTER_H #endif // INCLUDED_AI_AMF_IMPORTER_H

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -7,49 +7,48 @@
#ifndef INCLUDED_AI_IRRSHARED_H #ifndef INCLUDED_AI_IRRSHARED_H
#define INCLUDED_AI_IRRSHARED_H #define INCLUDED_AI_IRRSHARED_H
#include <assimp/XmlParser.h>
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h>
#include <stdint.h> #include <stdint.h>
struct aiMaterial; struct aiMaterial;
namespace Assimp { namespace Assimp {
/** @brief Matrix to convert from Assimp to IRR and backwards /** @brief Matrix to convert from Assimp to IRR and backwards
*/ */
extern const aiMatrix4x4 AI_TO_IRR_MATRIX; extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
// Default: 0 = solid, one texture // Default: 0 = solid, one texture
#define AI_IRRMESH_MAT_solid_2layer 0x10000 #define AI_IRRMESH_MAT_solid_2layer 0x10000
// Transparency flags // Transparency flags
#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1 #define AI_IRRMESH_MAT_trans_vertex_alpha 0x1
#define AI_IRRMESH_MAT_trans_add 0x2 #define AI_IRRMESH_MAT_trans_add 0x2
// Lightmapping flags // Lightmapping flags
#define AI_IRRMESH_MAT_lightmap 0x2 #define AI_IRRMESH_MAT_lightmap 0x2
#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4) #define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap | 0x4)
#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x8) #define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap | 0x8)
#define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap|0x10) #define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap | 0x10)
#define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap|0x20) #define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap | 0x20)
#define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap|0x40) #define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap | 0x40)
#define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap|0x80) #define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap | 0x80)
// Standard NormalMap (or Parallax map, they're treated equally) // Standard NormalMap (or Parallax map, they're treated equally)
#define AI_IRRMESH_MAT_normalmap_solid (0x100) #define AI_IRRMESH_MAT_normalmap_solid (0x100)
// Normal map combined with vertex alpha // Normal map combined with vertex alpha
#define AI_IRRMESH_MAT_normalmap_tva \ #define AI_IRRMESH_MAT_normalmap_tva \
(AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_vertex_alpha) (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_vertex_alpha)
// Normal map combined with additive transparency // Normal map combined with additive transparency
#define AI_IRRMESH_MAT_normalmap_ta \ #define AI_IRRMESH_MAT_normalmap_ta \
(AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_add) (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_add)
// Special flag. It indicates a second texture has been found // Special flag. It indicates a second texture has been found
// Its type depends ... either a normal textue or a normal map // Its type depends ... either a normal textue or a normal map
#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000 #define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Base class for the Irr and IrrMesh importers. /** Base class for the Irr and IrrMesh importers.
@ -57,58 +56,62 @@ extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
* Declares some irrlight-related xml parsing utilities and provides tools * Declares some irrlight-related xml parsing utilities and provides tools
* to load materials from IRR and IRRMESH files. * to load materials from IRR and IRRMESH files.
*/ */
class IrrlichtBase class IrrlichtBase {
{
protected: protected:
IrrlichtBase() :
mNode(nullptr) {
// empty
}
~IrrlichtBase() {
// empty
}
/** @brief Data structure for a simple name-value property /** @brief Data structure for a simple name-value property
*/ */
template <class T> template <class T>
struct Property struct Property {
{
std::string name; std::string name;
T value; T value;
}; };
typedef Property<uint32_t> HexProperty; typedef Property<uint32_t> HexProperty;
typedef Property<std::string> StringProperty; typedef Property<std::string> StringProperty;
typedef Property<bool> BoolProperty; typedef Property<bool> BoolProperty;
typedef Property<float> FloatProperty; typedef Property<float> FloatProperty;
typedef Property<aiVector3D> VectorProperty; typedef Property<aiVector3D> VectorProperty;
typedef Property<int> IntProperty; typedef Property<int> IntProperty;
/// XML reader instance /// XML reader instance
XmlParser mParser; XmlParser mParser;
pugi::xml_node &mNode; pugi::xml_node *mNode;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a material description from the XML /** Parse a material description from the XML
* @return The created material * @return The created material
* @param matFlags Receives AI_IRRMESH_MAT_XX flags * @param matFlags Receives AI_IRRMESH_MAT_XX flags
*/ */
aiMaterial* ParseMaterial(unsigned int& matFlags); aiMaterial *ParseMaterial(unsigned int &matFlags);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read a property of the specified type from the current XML element. /** Read a property of the specified type from the current XML element.
* @param out Receives output data * @param out Receives output data
*/ */
void ReadHexProperty (HexProperty& out); void ReadHexProperty(HexProperty &out);
void ReadStringProperty (StringProperty& out); void ReadStringProperty(StringProperty &out);
void ReadBoolProperty (BoolProperty& out); void ReadBoolProperty(BoolProperty &out);
void ReadFloatProperty (FloatProperty& out); void ReadFloatProperty(FloatProperty &out);
void ReadVectorProperty (VectorProperty& out); void ReadVectorProperty(VectorProperty &out);
void ReadIntProperty (IntProperty& out); void ReadIntProperty(IntProperty &out);
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Unpack a hex color, e.g. 0xdcdedfff // Unpack a hex color, e.g. 0xdcdedfff
inline inline void ColorFromARGBPacked(uint32_t in, aiColor4D &clr) {
void ColorFromARGBPacked(uint32_t in, aiColor4D& clr) {
clr.a = ((in >> 24) & 0xff) / 255.f; clr.a = ((in >> 24) & 0xff) / 255.f;
clr.r = ((in >> 16) & 0xff) / 255.f; clr.r = ((in >> 16) & 0xff) / 255.f;
clr.g = ((in >> 8) & 0xff) / 255.f; clr.g = ((in >> 8) & 0xff) / 255.f;
clr.b = ((in ) & 0xff) / 255.f; clr.b = ((in)&0xff) / 255.f;
} }
} // end namespace Assimp } // end namespace Assimp

View File

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

View File

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