update assimp to 5.2.3 Bugfix-Release

This commit is contained in:
AzaezelX 2022-04-26 11:56:24 -05:00
parent 3f796d2a06
commit f297476092
1150 changed files with 165834 additions and 112019 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,284 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file IRRLoader.h
* @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
* importer class.
*/
#ifndef AI_IRRLOADER_H_INCLUDED
#define AI_IRRLOADER_H_INCLUDED
#include "AssetLib/Irr/IRRShared.h"
#include "Common/Importer.h"
#include <assimp/SceneCombiner.h>
#include <assimp/StringUtils.h>
#include <assimp/anim.h>
namespace Assimp {
// ---------------------------------------------------------------------------
/** Irr importer class.
*
* Irr is the native scene file format of the Irrlight engine and its editor
* irrEdit. As IrrEdit itself is capable of importing quite many file formats,
* it might be a good file format for data exchange.
*/
class IRRImporter : public BaseImporter, public IrrlichtBase {
public:
IRRImporter();
~IRRImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const override;
protected:
const aiImporterDesc* GetInfo () const override;
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
void SetupProperties(const Importer* pImp) override;
private:
/** Data structure for a scene-graph node animator
*/
struct Animator {
// Type of the animator
enum AT {
UNKNOWN = 0x0,
ROTATION = 0x1,
FLY_CIRCLE = 0x2,
FLY_STRAIGHT = 0x3,
FOLLOW_SPLINE = 0x4,
OTHER = 0x5
} type;
explicit Animator(AT t = UNKNOWN)
: type (t)
, speed ( ai_real( 0.001 ) )
, direction ( ai_real( 0.0 ), ai_real( 1.0 ), ai_real( 0.0 ) )
, circleRadius ( ai_real( 1.0) )
, tightness ( ai_real( 0.5 ) )
, loop (true)
, timeForWay (100)
{
}
// common parameters
ai_real speed;
aiVector3D direction;
// FLY_CIRCLE
aiVector3D circleCenter;
ai_real circleRadius;
// FOLLOW_SPLINE
ai_real tightness;
std::vector<aiVectorKey> splineKeys;
// ROTATION (angles given in direction)
// FLY STRAIGHT
// circleCenter = start, direction = end
bool loop;
int timeForWay;
};
/** Data structure for a scene-graph node in an IRR file
*/
struct Node
{
// Type of the node
enum ET
{
LIGHT,
CUBE,
MESH,
SKYBOX,
DUMMY,
CAMERA,
TERRAIN,
SPHERE,
ANIMMESH
} type;
explicit Node(ET t)
: type (t)
, scaling (1.0,1.0,1.0) // assume uniform scaling by default
, parent()
, framesPerSecond (0.0)
, id()
, sphereRadius (1.0)
, spherePolyCountX (100)
, spherePolyCountY (100)
{
// Generate a default name for the node
char buffer[128];
static int cnt;
ai_snprintf(buffer, 128, "IrrNode_%i",cnt++);
name = std::string(buffer);
// reserve space for up to 5 materials
materials.reserve(5);
// reserve space for up to 5 children
children.reserve(5);
}
// Transformation of the node
aiVector3D position, rotation, scaling;
// Name of the node
std::string name;
// List of all child nodes
std::vector<Node*> children;
// Parent node
Node* parent;
// Animated meshes: frames per second
// 0.f if not specified
ai_real framesPerSecond;
// Meshes: path to the mesh to be loaded
std::string meshPath;
unsigned int id;
// Meshes: List of materials to be assigned
// along with their corresponding material flags
std::vector< std::pair<aiMaterial*, unsigned int> > materials;
// Spheres: radius of the sphere to be generates
ai_real sphereRadius;
// Spheres: Number of polygons in the x,y direction
unsigned int spherePolyCountX,spherePolyCountY;
// List of all animators assigned to the node
std::list<Animator> animators;
};
/** Data structure for a vertex in an IRR skybox
*/
struct SkyboxVertex
{
SkyboxVertex()
{}
//! Construction from single vertex components
SkyboxVertex(ai_real px, ai_real py, ai_real pz,
ai_real nx, ai_real ny, ai_real nz,
ai_real uvx, ai_real uvy)
: position (px,py,pz)
, normal (nx,ny,nz)
, uv (uvx,uvy,0.0)
{}
aiVector3D position, normal, uv;
};
// -------------------------------------------------------------------
/// Fill the scene-graph recursively
void GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
BatchLoader& batch,
std::vector<aiMesh*>& meshes,
std::vector<aiNodeAnim*>& anims,
std::vector<AttachmentInfo>& attach,
std::vector<aiMaterial*>& materials,
unsigned int& defaultMatIdx);
// -------------------------------------------------------------------
/// Generate a mesh that consists of just a single quad
aiMesh* BuildSingleQuadMesh(const SkyboxVertex& v1,
const SkyboxVertex& v2,
const SkyboxVertex& v3,
const SkyboxVertex& v4);
// -------------------------------------------------------------------
/// Build a sky-box
///
/// @param meshes Receives 6 output meshes
/// @param materials The last 6 materials are assigned to the newly
/// created meshes. The names of the materials are adjusted.
void BuildSkybox(std::vector<aiMesh*>& meshes,
std::vector<aiMaterial*> materials);
// -------------------------------------------------------------------
/** Copy a material for a mesh to the output material list
*
* @param materials Receives an output material
* @param inmaterials List of input materials
* @param defMatIdx Default material index - UINT_MAX if not present
* @param mesh Mesh to work on
*/
void CopyMaterial(std::vector<aiMaterial*>& materials,
std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials,
unsigned int& defMatIdx,
aiMesh* mesh);
// -------------------------------------------------------------------
/** Compute animations for a specific node
*
* @param root Node to be processed
* @param anims The list of output animations
*/
void ComputeAnimations(Node* root, aiNode* real,
std::vector<aiNodeAnim*>& anims);
private:
/// Configuration option: desired output FPS
double fps;
/// Configuration option: speed flag was set?
bool configSpeedFlag;
};
} // end of namespace Assimp
#endif // AI_IRRIMPORTER_H_INC

View file

@ -0,0 +1,502 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Implementation of the IrrMesh importer class */
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
#include "IRRMeshLoader.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/material.h>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace Assimp;
static const aiImporterDesc desc = {
"Irrlicht Mesh Reader",
"",
"",
"http://irrlicht.sourceforge.net/",
aiImporterFlags_SupportTextFlavour,
0,
0,
0,
0,
"xml irrmesh"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IRRMeshImporter::IRRMeshImporter() :
BaseImporter(),
IrrlichtBase() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IRRMeshImporter::~IRRMeshImporter() {}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
/* NOTE: A simple check for the file extension is not enough
* here. Irrmesh and irr are easy, but xml is too generic
* and could be collada, too. So we need to open the file and
* search for typical tokens.
*/
static const char *tokens[] = { "irrmesh" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}
// ------------------------------------------------------------------------------------------------
// Get a list of all file extensions which are handled by this class
const aiImporterDesc *IRRMeshImporter::GetInfo() const {
return &desc;
}
static void releaseMaterial(aiMaterial **mat) {
if (*mat != nullptr) {
delete *mat;
*mat = nullptr;
}
}
static void releaseMesh(aiMesh **mesh) {
if (*mesh != nullptr) {
delete *mesh;
*mesh = nullptr;
}
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void IRRMeshImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
// Check whether we can read from the file
if (file.get() == NULL)
throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
// Construct the irrXML parser
XmlParser parser;
if (!parser.parse( file.get() )) {
throw DeadlyImportError("XML parse error while loading IRRMESH file ", pFile);
}
XmlNode root = parser.getRootNode();
// final data
std::vector<aiMaterial *> materials;
std::vector<aiMesh *> meshes;
materials.reserve(5);
meshes.reserve(5);
// temporary data - current mesh buffer
aiMaterial *curMat = nullptr;
aiMesh *curMesh = nullptr;
unsigned int curMatFlags = 0;
std::vector<aiVector3D> curVertices, curNormals, curTangents, curBitangents;
std::vector<aiColor4D> curColors;
std::vector<aiVector3D> curUVs, curUV2s;
// some temporary variables
int textMeaning = 0;
int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
bool useColors = false;
// Parse the XML file
for (pugi::xml_node child : root.children()) {
if (child.type() == pugi::node_element) {
if (!ASSIMP_stricmp(child.name(), "buffer") && (curMat || curMesh)) {
// end of previous buffer. A material and a mesh should be there
if (!curMat || !curMesh) {
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
releaseMaterial(&curMat);
releaseMesh(&curMesh);
} else {
materials.push_back(curMat);
meshes.push_back(curMesh);
}
curMat = nullptr;
curMesh = nullptr;
curVertices.clear();
curColors.clear();
curNormals.clear();
curUV2s.clear();
curUVs.clear();
curTangents.clear();
curBitangents.clear();
}
if (!ASSIMP_stricmp(child.name(), "material")) {
if (curMat) {
ASSIMP_LOG_WARN("IRRMESH: Only one material description per buffer, please");
releaseMaterial(&curMat);
}
curMat = ParseMaterial(curMatFlags);
}
/* no else here! */ if (!ASSIMP_stricmp(child.name(), "vertices")) {
pugi::xml_attribute attr = child.attribute("vertexCount");
int num = attr.as_int();
//int num = reader->getAttributeValueAsInt("vertexCount");
if (!num) {
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero vertices");
releaseMaterial(&curMat);
releaseMesh(&curMesh);
textMeaning = 0;
continue;
}
curVertices.reserve(num);
curNormals.reserve(num);
curColors.reserve(num);
curUVs.reserve(num);
// Determine the file format
//const char *t = reader->getAttributeValueSafe("type");
pugi::xml_attribute t = child.attribute("type");
if (!ASSIMP_stricmp("2tcoords", t.name())) {
curUV2s.reserve(num);
vertexFormat = 1;
if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) {
// *********************************************************
// We have a second texture! So use this UV channel
// for it. The 2nd texture can be either a normal
// texture (solid_2layer or lightmap_xxx) or a normal
// map (normal_..., parallax_...)
// *********************************************************
int idx = 1;
aiMaterial *mat = (aiMaterial *)curMat;
if (curMatFlags & AI_IRRMESH_MAT_lightmap) {
mat->AddProperty(&idx, 1, AI_MATKEY_UVWSRC_LIGHTMAP(0));
} else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid) {
mat->AddProperty(&idx, 1, AI_MATKEY_UVWSRC_NORMALS(0));
} else if (curMatFlags & AI_IRRMESH_MAT_solid_2layer) {
mat->AddProperty(&idx, 1, AI_MATKEY_UVWSRC_DIFFUSE(1));
}
}
} else if (!ASSIMP_stricmp("tangents", t.name())) {
curTangents.reserve(num);
curBitangents.reserve(num);
vertexFormat = 2;
} else if (ASSIMP_stricmp("standard", t.name())) {
releaseMaterial(&curMat);
ASSIMP_LOG_WARN("IRRMESH: Unknown vertex format");
} else
vertexFormat = 0;
textMeaning = 1;
} else if (!ASSIMP_stricmp(child.name(), "indices")) {
if (curVertices.empty() && curMat) {
releaseMaterial(&curMat);
throw DeadlyImportError("IRRMESH: indices must come after vertices");
}
textMeaning = 2;
// start a new mesh
curMesh = new aiMesh();
// allocate storage for all faces
pugi::xml_attribute attr = child.attribute("indexCount");
curMesh->mNumVertices = attr.as_int();
if (!curMesh->mNumVertices) {
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero indices");
// mesh - away
releaseMesh(&curMesh);
// material - away
releaseMaterial(&curMat);
textMeaning = 0;
continue;
}
if (curMesh->mNumVertices % 3) {
ASSIMP_LOG_WARN("IRRMESH: Number if indices isn't divisible by 3");
}
curMesh->mNumFaces = curMesh->mNumVertices / 3;
curMesh->mFaces = new aiFace[curMesh->mNumFaces];
// setup some members
curMesh->mMaterialIndex = (unsigned int)materials.size();
curMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// allocate storage for all vertices
curMesh->mVertices = new aiVector3D[curMesh->mNumVertices];
if (curNormals.size() == curVertices.size()) {
curMesh->mNormals = new aiVector3D[curMesh->mNumVertices];
}
if (curTangents.size() == curVertices.size()) {
curMesh->mTangents = new aiVector3D[curMesh->mNumVertices];
}
if (curBitangents.size() == curVertices.size()) {
curMesh->mBitangents = new aiVector3D[curMesh->mNumVertices];
}
if (curColors.size() == curVertices.size() && useColors) {
curMesh->mColors[0] = new aiColor4D[curMesh->mNumVertices];
}
if (curUVs.size() == curVertices.size()) {
curMesh->mTextureCoords[0] = new aiVector3D[curMesh->mNumVertices];
}
if (curUV2s.size() == curVertices.size()) {
curMesh->mTextureCoords[1] = new aiVector3D[curMesh->mNumVertices];
}
}
//break;
//case EXN_TEXT: {
const char *sz = child.child_value();
if (textMeaning == 1) {
textMeaning = 0;
// read vertices
do {
SkipSpacesAndLineEnd(&sz);
aiVector3D temp;
aiColor4D c;
// Read the vertex position
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
curVertices.push_back(temp);
// Read the vertex normals
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
curNormals.push_back(temp);
// read the vertex colors
uint32_t clr = strtoul16(sz, &sz);
ColorFromARGBPacked(clr, c);
if (!curColors.empty() && c != *(curColors.end() - 1))
useColors = true;
curColors.push_back(c);
SkipSpaces(&sz);
// read the first UV coordinate set
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
temp.z = 0.f;
temp.y = 1.f - temp.y; // DX to OGL
curUVs.push_back(temp);
// read the (optional) second UV coordinate set
if (vertexFormat == 1) {
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
temp.y = 1.f - temp.y; // DX to OGL
curUV2s.push_back(temp);
}
// read optional tangent and bitangent vectors
else if (vertexFormat == 2) {
// tangents
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
temp.y *= -1.0f;
curTangents.push_back(temp);
// bitangents
sz = fast_atoreal_move<float>(sz, (float &)temp.x);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.z);
SkipSpaces(&sz);
sz = fast_atoreal_move<float>(sz, (float &)temp.y);
SkipSpaces(&sz);
temp.y *= -1.0f;
curBitangents.push_back(temp);
}
}
/* IMPORTANT: We assume that each vertex is specified in one
line. So we can skip the rest of the line - unknown vertex
elements are ignored.
*/
while (SkipLine(&sz));
} else if (textMeaning == 2) {
textMeaning = 0;
// read indices
aiFace *curFace = curMesh->mFaces;
aiFace *const faceEnd = curMesh->mFaces + curMesh->mNumFaces;
aiVector3D *pcV = curMesh->mVertices;
aiVector3D *pcN = curMesh->mNormals;
aiVector3D *pcT = curMesh->mTangents;
aiVector3D *pcB = curMesh->mBitangents;
aiColor4D *pcC0 = curMesh->mColors[0];
aiVector3D *pcT0 = curMesh->mTextureCoords[0];
aiVector3D *pcT1 = curMesh->mTextureCoords[1];
unsigned int curIdx = 0;
unsigned int total = 0;
while (SkipSpacesAndLineEnd(&sz)) {
if (curFace >= faceEnd) {
ASSIMP_LOG_ERROR("IRRMESH: Too many indices");
break;
}
if (!curIdx) {
curFace->mNumIndices = 3;
curFace->mIndices = new unsigned int[3];
}
unsigned int idx = strtoul10(sz, &sz);
if (idx >= curVertices.size()) {
ASSIMP_LOG_ERROR("IRRMESH: Index out of range");
idx = 0;
}
curFace->mIndices[curIdx] = total++;
*pcV++ = curVertices[idx];
if (pcN) *pcN++ = curNormals[idx];
if (pcT) *pcT++ = curTangents[idx];
if (pcB) *pcB++ = curBitangents[idx];
if (pcC0) *pcC0++ = curColors[idx];
if (pcT0) *pcT0++ = curUVs[idx];
if (pcT1) *pcT1++ = curUV2s[idx];
if (++curIdx == 3) {
++curFace;
curIdx = 0;
}
}
if (curFace != faceEnd)
ASSIMP_LOG_ERROR("IRRMESH: Not enough indices");
// Finish processing the mesh - do some small material workarounds
if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) {
// Take the opacity value of the current material
// from the common vertex color alpha
aiMaterial *mat = (aiMaterial *)curMat;
mat->AddProperty(&curColors[0].a, 1, AI_MATKEY_OPACITY);
}
}
}
}
// End of the last buffer. A material and a mesh should be there
if (curMat || curMesh) {
if (!curMat || !curMesh) {
ASSIMP_LOG_ERROR("IRRMESH: A buffer must contain a mesh and a material");
releaseMaterial(&curMat);
releaseMesh(&curMesh);
} else {
materials.push_back(curMat);
meshes.push_back(curMesh);
}
}
if (materials.empty()) {
throw DeadlyImportError("IRRMESH: Unable to read a mesh from this file");
}
// now generate the output scene
pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mMeshes[i] = meshes[i];
// clean this value ...
pScene->mMeshes[i]->mNumUVComponents[3] = 0;
}
pScene->mNumMaterials = (unsigned int)materials.size();
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
::memcpy(pScene->mMaterials, &materials[0], sizeof(void *) * pScene->mNumMaterials);
pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<IRRMesh>");
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mRootNode->mMeshes[i] = i;
}
}
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER

View file

@ -0,0 +1,94 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file IRRMeshLoader.h
* @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
* importer class.
*/
#ifndef AI_IRRMESHLOADER_H_INCLUDED
#define AI_IRRMESHLOADER_H_INCLUDED
#include "IRRShared.h"
#include <assimp/BaseImporter.h>
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
namespace Assimp {
// ---------------------------------------------------------------------------
/** IrrMesh importer class.
*
* IrrMesh is the native file format of the Irrlight engine and its editor
* irrEdit. As IrrEdit itself is capable of importing quite many file formats,
* it might be a good file format for data exchange.
*/
class IRRMeshImporter : public BaseImporter, public IrrlichtBase {
public:
IRRMeshImporter();
~IRRMeshImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const override;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc *GetInfo() const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler) override;
};
} // end of namespace Assimp
#endif // ASSIMP_BUILD_NO_IRRMESH_IMPORTER
#endif // AI_IRRMESHIMPORTER_H_INC

View file

@ -0,0 +1,387 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file IRRShared.cpp
* @brief Shared utilities for the IRR and IRRMESH loaders
*/
//This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted.
#if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))
#include "IRRShared.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/material.h>
using namespace Assimp;
// Transformation matrix to convert from Assimp to IRR space
const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
// ------------------------------------------------------------------------------------------------
// read a property in hexadecimal format (i.e. ffffffff)
void IrrlichtBase::ReadHexProperty(HexProperty &out ) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string( attrib.value() );
} else if (!ASSIMP_stricmp(attrib.name(),"value")) {
// parse the hexadecimal value
out.value = strtoul16(attrib.name());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a decimal property
void IrrlichtBase::ReadIntProperty(IntProperty & out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.value(),"value")) {
// parse the int value
out.value = strtol10(attrib.name());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a string property
void IrrlichtBase::ReadStringProperty( StringProperty& out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// simple copy the string
out.value = std::string(attrib.value());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a boolean property
void IrrlichtBase::ReadBoolProperty(BoolProperty &out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")){
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// true or false, case insensitive
out.value = (ASSIMP_stricmp(attrib.value(), "true") ? false : true);
}
}
}
// ------------------------------------------------------------------------------------------------
// read a float property
void IrrlichtBase::ReadFloatProperty(FloatProperty &out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// just parse the float
out.value = fast_atof(attrib.value());
}
}
}
// ------------------------------------------------------------------------------------------------
// read a vector property
void IrrlichtBase::ReadVectorProperty( VectorProperty &out ) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// three floats, separated with commas
const char *ptr = attrib.value();
SkipSpaces(&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.x );
SkipSpaces(&ptr);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr);
}
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.y );
SkipSpaces(&ptr);
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
} else {
SkipSpaces(ptr + 1, &ptr);
}
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.z );
}
}
}
// ------------------------------------------------------------------------------------------------
// Convert a string to a proper aiMappingMode
int ConvertMappingMode(const std::string& mode) {
if (mode == "texture_clamp_repeat") {
return aiTextureMapMode_Wrap;
} else if (mode == "texture_clamp_mirror") {
return aiTextureMapMode_Mirror;
}
return aiTextureMapMode_Clamp;
}
// ------------------------------------------------------------------------------------------------
// Parse a material from the XML file
aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) {
aiMaterial* mat = new aiMaterial();
aiColor4D clr;
aiString s;
matFlags = 0; // zero output flags
int cnt = 0; // number of used texture channels
unsigned int nd = 0;
for (pugi::xml_node child : mNode->children()) {
if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties
HexProperty prop;
ReadHexProperty(prop);
if (prop.name == "Diffuse") {
ColorFromARGBPacked(prop.value, clr);
mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
} else if (prop.name == "Ambient") {
ColorFromARGBPacked(prop.value, clr);
mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
} else if (prop.name == "Specular") {
ColorFromARGBPacked(prop.value, clr);
mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
}
// NOTE: The 'emissive' property causes problems. It is
// often != 0, even if there is obviously no light
// emitted by the described surface. In fact I think
// IRRLICHT ignores this property, too.
#if 0
else if (prop.name == "Emissive") {
ColorFromARGBPacked(prop.value,clr);
mat->AddProperty(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
}
#endif
} else if (!ASSIMP_stricmp(child.name(), "float")) { // Float properties
FloatProperty prop;
ReadFloatProperty(prop);
if (prop.name == "Shininess") {
mat->AddProperty(&prop.value, 1, AI_MATKEY_SHININESS);
}
} else if (!ASSIMP_stricmp(child.name(), "bool")) { // Bool properties
BoolProperty prop;
ReadBoolProperty(prop);
if (prop.name == "Wireframe") {
int val = (prop.value ? true : false);
mat->AddProperty(&val, 1, AI_MATKEY_ENABLE_WIREFRAME);
} else if (prop.name == "GouraudShading") {
int val = (prop.value ? aiShadingMode_Gouraud : aiShadingMode_NoShading);
mat->AddProperty(&val, 1, AI_MATKEY_SHADING_MODEL);
} else if (prop.name == "BackfaceCulling") {
int val = (!prop.value);
mat->AddProperty(&val, 1, AI_MATKEY_TWOSIDED);
}
} else if (!ASSIMP_stricmp(child.name(), "texture") ||
!ASSIMP_stricmp(child.name(), "enum")) { // String properties - textures and texture related properties
StringProperty prop;
ReadStringProperty(prop);
if (prop.value.length()) {
// material type (shader)
if (prop.name == "Type") {
if (prop.value == "solid") {
// default material ...
} else if (prop.value == "trans_vertex_alpha") {
matFlags = AI_IRRMESH_MAT_trans_vertex_alpha;
} else if (prop.value == "lightmap") {
matFlags = AI_IRRMESH_MAT_lightmap;
} else if (prop.value == "solid_2layer") {
matFlags = AI_IRRMESH_MAT_solid_2layer;
} else if (prop.value == "lightmap_m2") {
matFlags = AI_IRRMESH_MAT_lightmap_m2;
} else if (prop.value == "lightmap_m4") {
matFlags = AI_IRRMESH_MAT_lightmap_m4;
} else if (prop.value == "lightmap_light") {
matFlags = AI_IRRMESH_MAT_lightmap_light;
} else if (prop.value == "lightmap_light_m2") {
matFlags = AI_IRRMESH_MAT_lightmap_light_m2;
} else if (prop.value == "lightmap_light_m4") {
matFlags = AI_IRRMESH_MAT_lightmap_light_m4;
} else if (prop.value == "lightmap_add") {
matFlags = AI_IRRMESH_MAT_lightmap_add;
} else if (prop.value == "normalmap_solid" ||
prop.value == "parallaxmap_solid") { // Normal and parallax maps are treated equally
matFlags = AI_IRRMESH_MAT_normalmap_solid;
} else if (prop.value == "normalmap_trans_vertex_alpha" ||
prop.value == "parallaxmap_trans_vertex_alpha") {
matFlags = AI_IRRMESH_MAT_normalmap_tva;
} else if (prop.value == "normalmap_trans_add" ||
prop.value == "parallaxmap_trans_add") {
matFlags = AI_IRRMESH_MAT_normalmap_ta;
} else {
ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: ", prop.value);
}
}
// Up to 4 texture channels are supported
if (prop.name == "Texture1") {
// Always accept the primary texture channel
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
} else if (prop.name == "Texture2" && cnt == 1) {
// 2-layer material lightmapped?
if (matFlags & AI_IRRMESH_MAT_lightmap) {
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_LIGHTMAP(0));
// set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) { // alternatively: normal or parallax mapping
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_NORMALS(0));
// set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} else if (matFlags & AI_IRRMESH_MAT_solid_2layer) { // or just as second diffuse texture
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(1));
++nd;
// set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} else {
ASSIMP_LOG_WARN("IRRmat: Skipping second texture");
}
} else if (prop.name == "Texture3" && cnt == 2) {
// Irrlicht does not seem to use these channels.
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(nd + 1));
} else if (prop.name == "Texture4" && cnt == 3) {
// Irrlicht does not seem to use these channels.
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(nd + 2));
}
// Texture mapping options
if (prop.name == "TextureWrap1" && cnt >= 1) {
int map = ConvertMappingMode(prop.value);
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
} else if (prop.name == "TextureWrap2" && cnt >= 2) {
int map = ConvertMappingMode(prop.value);
if (matFlags & AI_IRRMESH_MAT_lightmap) {
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(0));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(0));
} else if (matFlags & (AI_IRRMESH_MAT_normalmap_solid)) {
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_NORMALS(0));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_NORMALS(0));
} else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(1));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(1));
}
} else if (prop.name == "TextureWrap3" && cnt >= 3) {
int map = ConvertMappingMode(prop.value);
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd + 1));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd + 1));
} else if (prop.name == "TextureWrap4" && cnt >= 4) {
int map = ConvertMappingMode(prop.value);
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd + 2));
mat->AddProperty(&map, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd + 2));
}
}
}
//break;
/*case EXN_ELEMENT_END:
// Assume there are no further nested nodes in <material> elements
if ( !ASSIMP_stricmp(reader->getNodeName(),"material") ||
!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
{
// Now process lightmapping flags
// We should have at least one textur to do that ..
if (cnt && matFlags & AI_IRRMESH_MAT_lightmap)
{
float f = 1.f;
unsigned int unmasked = matFlags&~AI_IRRMESH_MAT_lightmap;
// Additive lightmap?
int op = (unmasked & AI_IRRMESH_MAT_lightmap_add
? aiTextureOp_Add : aiTextureOp_Multiply);
// Handle Irrlicht's lightmapping scaling factor
if (unmasked & AI_IRRMESH_MAT_lightmap_m2 ||
unmasked & AI_IRRMESH_MAT_lightmap_light_m2)
{
f = 2.f;
}
else if (unmasked & AI_IRRMESH_MAT_lightmap_m4 ||
unmasked & AI_IRRMESH_MAT_lightmap_light_m4)
{
f = 4.f;
}
mat->AddProperty( &f, 1, AI_MATKEY_TEXBLEND_LIGHTMAP(0));
mat->AddProperty( &op,1, AI_MATKEY_TEXOP_LIGHTMAP(0));
}
return mat;
}
default:
// GCC complains here ...
break;
}
}*/
}
ASSIMP_LOG_ERROR("IRRMESH: Unexpected end of file. Material is not complete");
return mat;
}
#endif // !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))

View file

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