summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/XGLLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/XGLLoader.cpp')
-rw-r--r--src/3rdparty/assimp/code/XGLLoader.cpp1503
1 files changed, 756 insertions, 747 deletions
diff --git a/src/3rdparty/assimp/code/XGLLoader.cpp b/src/3rdparty/assimp/code/XGLLoader.cpp
index 963407b9e..fafad2f66 100644
--- a/src/3rdparty/assimp/code/XGLLoader.cpp
+++ b/src/3rdparty/assimp/code/XGLLoader.cpp
@@ -3,12 +3,12 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2016, 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
+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
@@ -25,23 +25,23 @@ conditions are met:
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
+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
+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
+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
+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 XGL/ZGL importer class */
-#include "AssimpPCH.h"
+
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
#include "XGLLoader.h"
@@ -50,31 +50,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "StreamReader.h"
#include "MemoryIOWrapper.h"
+#include <assimp/mesh.h>
+#include <assimp/scene.h>
+#include <cctype>
+#include <memory>
using namespace Assimp;
using namespace irr;
using namespace irr::io;
-
-// zlib is needed for compressed XGL files
+// zlib is needed for compressed XGL files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
-# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-# else
-# include "../contrib/zlib/zlib.h"
-# endif
+# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
+# include <zlib.h>
+# else
+# include <contrib/zlib/zlib.h>
+# endif
#endif
// scopeguard for a malloc'ed buffer
struct free_it
{
- free_it(void* free) : free(free) {}
- ~free_it() {
- ::free(this->free);
- }
+ free_it(void* free) : free(free) {}
+ ~free_it() {
+ ::free(this->free);
+ }
- void* free;
+ void* free;
};
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
@@ -83,16 +86,16 @@ template<> const std::string LogFunctions<XGLImporter>::log_prefix = "XGL: ";
}
static const aiImporterDesc desc = {
- "XGL Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "xgl zgl"
+ "XGL Importer",
+ "",
+ "",
+ "",
+ aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
+ 0,
+ 0,
+ 0,
+ 0,
+ "xgl zgl"
};
@@ -102,846 +105,852 @@ XGLImporter::XGLImporter()
{}
// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
+// Destructor, private as well
XGLImporter::~XGLImporter()
{}
// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
+// Returns whether the class can handle the format of the given file.
bool XGLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
- /* NOTE: A simple check for the file extension is not enough
- * here. XGL and ZGL are ok, but xml is too generic
- * and might be collada as well. So open the file and
- * look for typical signal tokens.
- */
- const std::string extension = GetExtension(pFile);
-
- if (extension == "xgl" || extension == "zgl") {
- return true;
- }
- else if (extension == "xml" || checkSig) {
- ai_assert(pIOHandler != NULL);
-
- const char* tokens[] = {"<world>","<World>","<WORLD>"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,3);
- }
- return false;
+ /* NOTE: A simple check for the file extension is not enough
+ * here. XGL and ZGL are ok, but xml is too generic
+ * and might be collada as well. So open the file and
+ * look for typical signal tokens.
+ */
+ const std::string extension = GetExtension(pFile);
+
+ if (extension == "xgl" || extension == "zgl") {
+ return true;
+ }
+ else if (extension == "xml" || checkSig) {
+ ai_assert(pIOHandler != NULL);
+
+ const char* tokens[] = {"<world>","<World>","<WORLD>"};
+ return SearchFileHeaderForToken(pIOHandler,pFile,tokens,3);
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
// Get a list of all file extensions which are handled by this class
const aiImporterDesc* XGLImporter::GetInfo () const
{
- return &desc;
+ return &desc;
}
// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void XGLImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
+// Imports the given file into the given scene structure.
+void XGLImporter::InternReadFile( const std::string& pFile,
+ aiScene* pScene, IOSystem* pIOHandler)
{
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
- Bytef* dest = NULL;
- free_it free_it_really(dest);
+ Bytef* dest = NULL;
+ free_it free_it_really(dest);
#endif
- scene = pScene;
- boost::shared_ptr<IOStream> stream( pIOHandler->Open( pFile, "rb"));
+ scene = pScene;
+ std::shared_ptr<IOStream> stream( pIOHandler->Open( pFile, "rb"));
- // check whether we can read from the file
- if( stream.get() == NULL) {
- throw DeadlyImportError( "Failed to open XGL/ZGL file " + pFile + "");
- }
+ // check whether we can read from the file
+ if( stream.get() == NULL) {
+ throw DeadlyImportError( "Failed to open XGL/ZGL file " + pFile + "");
+ }
- // see if its compressed, if so uncompress it
- if (GetExtension(pFile) == "zgl") {
+ // see if its compressed, if so uncompress it
+ if (GetExtension(pFile) == "zgl") {
#ifdef ASSIMP_BUILD_NO_COMPRESSED_XGL
- ThrowException("Cannot read ZGL file since Assimp was built without compression support");
+ ThrowException("Cannot read ZGL file since Assimp was built without compression support");
#else
- boost::scoped_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
-
- // build a zlib stream
- z_stream zstream;
- zstream.opaque = Z_NULL;
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.data_type = Z_BINARY;
-
- // raw decompression without a zlib or gzip header
- inflateInit2(&zstream, -MAX_WBITS);
-
- // skip two extra bytes, zgl files do carry a crc16 upfront (I think)
- raw_reader->IncPtr(2);
-
- zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
- zstream.avail_in = raw_reader->GetRemainingSize();
-
- size_t total = 0l;
-
- // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
- #define MYBLOCK 1024
- Bytef block[MYBLOCK];
- int ret;
- do {
- zstream.avail_out = MYBLOCK;
- zstream.next_out = block;
- ret = inflate(&zstream, Z_NO_FLUSH);
-
- if (ret != Z_STREAM_END && ret != Z_OK) {
- ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
- }
- const size_t have = MYBLOCK - zstream.avail_out;
- total += have;
- dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
- memcpy(dest + total - have,block,have);
- }
- while (ret != Z_STREAM_END);
-
- // terminate zlib
- inflateEnd(&zstream);
-
- // replace the input stream with a memory stream
- stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total));
+ std::unique_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
+
+ // build a zlib stream
+ z_stream zstream;
+ zstream.opaque = Z_NULL;
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.data_type = Z_BINARY;
+
+ // raw decompression without a zlib or gzip header
+ inflateInit2(&zstream, -MAX_WBITS);
+
+ // skip two extra bytes, zgl files do carry a crc16 upfront (I think)
+ raw_reader->IncPtr(2);
+
+ zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
+ zstream.avail_in = raw_reader->GetRemainingSize();
+
+ size_t total = 0l;
+
+ // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
+ #define MYBLOCK 1024
+ Bytef block[MYBLOCK];
+ int ret;
+ do {
+ zstream.avail_out = MYBLOCK;
+ zstream.next_out = block;
+ ret = inflate(&zstream, Z_NO_FLUSH);
+
+ if (ret != Z_STREAM_END && ret != Z_OK) {
+ ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
+ }
+ const size_t have = MYBLOCK - zstream.avail_out;
+ total += have;
+ dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
+ memcpy(dest + total - have,block,have);
+ }
+ while (ret != Z_STREAM_END);
+
+ // terminate zlib
+ inflateEnd(&zstream);
+
+ // replace the input stream with a memory stream
+ stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total));
#endif
- }
-
- // construct the irrXML parser
- CIrrXML_IOStreamReader st(stream.get());
- boost::scoped_ptr<IrrXMLReader> read( createIrrXMLReader((IFileReadCallBack*) &st) );
- reader = read.get();
-
- // parse the XML file
- TempScope scope;
-
- while (ReadElement()) {
- if (!ASSIMP_stricmp(reader->getNodeName(),"world")) {
- ReadWorld(scope);
- }
- }
-
-
- std::vector<aiMesh*>& meshes = scope.meshes_linear;
- std::vector<aiMaterial*>& materials = scope.materials_linear;
- if(!meshes.size() || !materials.size()) {
- ThrowException("failed to extract data from XGL file, no meshes loaded");
- }
-
- // copy meshes
- scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
- std::copy(meshes.begin(),meshes.end(),scene->mMeshes);
-
- // copy materials
- scene->mNumMaterials = static_cast<unsigned int>(materials.size());
- scene->mMaterials = new aiMaterial*[scene->mNumMaterials]();
- std::copy(materials.begin(),materials.end(),scene->mMaterials);
-
- if (scope.light) {
- scene->mNumLights = 1;
- scene->mLights = new aiLight*[1];
- scene->mLights[0] = scope.light;
-
- scope.light->mName = scene->mRootNode->mName;
- }
-
- scope.dismiss();
+ }
+
+ // construct the irrXML parser
+ CIrrXML_IOStreamReader st(stream.get());
+ std::unique_ptr<IrrXMLReader> read( createIrrXMLReader((IFileReadCallBack*) &st) );
+ reader = read.get();
+
+ // parse the XML file
+ TempScope scope;
+
+ while (ReadElement()) {
+ if (!ASSIMP_stricmp(reader->getNodeName(),"world")) {
+ ReadWorld(scope);
+ }
+ }
+
+
+ std::vector<aiMesh*>& meshes = scope.meshes_linear;
+ std::vector<aiMaterial*>& materials = scope.materials_linear;
+ if(!meshes.size() || !materials.size()) {
+ ThrowException("failed to extract data from XGL file, no meshes loaded");
+ }
+
+ // copy meshes
+ scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
+ scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
+ std::copy(meshes.begin(),meshes.end(),scene->mMeshes);
+
+ // copy materials
+ scene->mNumMaterials = static_cast<unsigned int>(materials.size());
+ scene->mMaterials = new aiMaterial*[scene->mNumMaterials]();
+ std::copy(materials.begin(),materials.end(),scene->mMaterials);
+
+ if (scope.light) {
+ scene->mNumLights = 1;
+ scene->mLights = new aiLight*[1];
+ scene->mLights[0] = scope.light;
+
+ scope.light->mName = scene->mRootNode->mName;
+ }
+
+ scope.dismiss();
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadElement()
{
- while(reader->read()) {
- if (reader->getNodeType() == EXN_ELEMENT) {
- return true;
- }
- }
- return false;
+ while(reader->read()) {
+ if (reader->getNodeType() == EXN_ELEMENT) {
+ return true;
+ }
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadElementUpToClosing(const char* closetag)
{
- while(reader->read()) {
- if (reader->getNodeType() == EXN_ELEMENT) {
- return true;
- }
- else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),closetag)) {
- return false;
- }
- }
- LogError("unexpected EOF, expected closing <" + std::string(closetag) + "> tag");
- return false;
+ while(reader->read()) {
+ if (reader->getNodeType() == EXN_ELEMENT) {
+ return true;
+ }
+ else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),closetag)) {
+ return false;
+ }
+ }
+ LogError("unexpected EOF, expected closing <" + std::string(closetag) + "> tag");
+ return false;
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::SkipToText()
{
- while(reader->read()) {
- if (reader->getNodeType() == EXN_TEXT) {
- return true;
- }
- else if (reader->getNodeType() == EXN_ELEMENT || reader->getNodeType() == EXN_ELEMENT_END) {
- ThrowException("expected text contents but found another element (or element end)");
- }
- }
- return false;
+ while(reader->read()) {
+ if (reader->getNodeType() == EXN_TEXT) {
+ return true;
+ }
+ else if (reader->getNodeType() == EXN_ELEMENT || reader->getNodeType() == EXN_ELEMENT_END) {
+ ThrowException("expected text contents but found another element (or element end)");
+ }
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
std::string XGLImporter::GetElementName()
{
- const char* s = reader->getNodeName();
- size_t len = strlen(s);
+ const char* s = reader->getNodeName();
+ size_t len = strlen(s);
- std::string ret;
- ret.resize(len);
+ std::string ret;
+ ret.resize(len);
- std::transform(s,s+len,ret.begin(),::tolower);
- return ret;
+ std::transform(s,s+len,ret.begin(),::tolower);
+ return ret;
}
// ------------------------------------------------------------------------------------------------
void XGLImporter::ReadWorld(TempScope& scope)
{
- while (ReadElementUpToClosing("world")) {
- const std::string& s = GetElementName();
- // XXX right now we'd skip <lighting> if it comes after
- // <object> or <mesh>
- if (s == "lighting") {
- ReadLighting(scope);
- }
- else if (s == "object" || s == "mesh" || s == "mat") {
- break;
- }
- }
-
-
- aiNode* const nd = ReadObject(scope,true,"world");
- if(!nd) {
- ThrowException("failure reading <world>");
- }
- if(!nd->mName.length) {
- nd->mName.Set("WORLD");
- }
-
- scene->mRootNode = nd;
+ while (ReadElementUpToClosing("world")) {
+ const std::string& s = GetElementName();
+ // XXX right now we'd skip <lighting> if it comes after
+ // <object> or <mesh>
+ if (s == "lighting") {
+ ReadLighting(scope);
+ }
+ else if (s == "object" || s == "mesh" || s == "mat") {
+ break;
+ }
+ }
+
+
+ aiNode* const nd = ReadObject(scope,true,"world");
+ if(!nd) {
+ ThrowException("failure reading <world>");
+ }
+ if(!nd->mName.length) {
+ nd->mName.Set("WORLD");
+ }
+
+ scene->mRootNode = nd;
}
// ------------------------------------------------------------------------------------------------
void XGLImporter::ReadLighting(TempScope& scope)
{
- while (ReadElementUpToClosing("lighting")) {
- const std::string& s = GetElementName();
- if (s == "directionallight") {
- scope.light = ReadDirectionalLight();
- }
- else if (s == "ambient") {
- LogWarn("ignoring <ambient> tag");
- }
- else if (s == "spheremap") {
- LogWarn("ignoring <spheremap> tag");
- }
- }
+ while (ReadElementUpToClosing("lighting")) {
+ const std::string& s = GetElementName();
+ if (s == "directionallight") {
+ scope.light = ReadDirectionalLight();
+ }
+ else if (s == "ambient") {
+ LogWarn("ignoring <ambient> tag");
+ }
+ else if (s == "spheremap") {
+ LogWarn("ignoring <spheremap> tag");
+ }
+ }
}
// ------------------------------------------------------------------------------------------------
aiLight* XGLImporter::ReadDirectionalLight()
{
- ScopeGuard<aiLight> l(new aiLight());
- l->mType = aiLightSource_DIRECTIONAL;
-
- while (ReadElementUpToClosing("directionallight")) {
- const std::string& s = GetElementName();
- if (s == "direction") {
- l->mDirection = ReadVec3();
- }
- else if (s == "diffuse") {
- l->mColorDiffuse = ReadCol3();
- }
- else if (s == "specular") {
- l->mColorSpecular = ReadCol3();
- }
- }
- return l.dismiss();
+ ScopeGuard<aiLight> l(new aiLight());
+ l->mType = aiLightSource_DIRECTIONAL;
+
+ while (ReadElementUpToClosing("directionallight")) {
+ const std::string& s = GetElementName();
+ if (s == "direction") {
+ l->mDirection = ReadVec3();
+ }
+ else if (s == "diffuse") {
+ l->mColorDiffuse = ReadCol3();
+ }
+ else if (s == "specular") {
+ l->mColorSpecular = ReadCol3();
+ }
+ }
+ return l.dismiss();
}
// ------------------------------------------------------------------------------------------------
aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* closetag)
{
- ScopeGuard<aiNode> nd(new aiNode());
- std::vector<aiNode*> children;
- std::vector<unsigned int> meshes;
-
- try {
- while (skipFirst || ReadElementUpToClosing(closetag)) {
- skipFirst = false;
-
- const std::string& s = GetElementName();
- if (s == "mesh") {
- const size_t prev = scope.meshes_linear.size();
- if(ReadMesh(scope)) {
- const size_t newc = scope.meshes_linear.size();
- for(size_t i = 0; i < newc-prev; ++i) {
- meshes.push_back(static_cast<unsigned int>(i+prev));
- }
- }
- }
- else if (s == "mat") {
- ReadMaterial(scope);
- }
- else if (s == "object") {
- children.push_back(ReadObject(scope));
- }
- else if (s == "objectref") {
- // XXX
- }
- else if (s == "meshref") {
- const unsigned int id = static_cast<unsigned int>( ReadIndexFromText() );
-
- std::multimap<unsigned int, aiMesh*>::iterator it = scope.meshes.find(id), end = scope.meshes.end();
- if (it == end) {
- ThrowException("<meshref> index out of range");
- }
-
- for(; it != end && (*it).first == id; ++it) {
- // ok, this is n^2 and should get optimized one day
- aiMesh* const m = (*it).second;
-
- unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size());
- for(; i < mcount; ++i) {
- if (scope.meshes_linear[i] == m) {
- meshes.push_back(i);
- break;
- }
- }
-
- ai_assert(i < mcount);
- }
- }
- else if (s == "transform") {
- nd->mTransformation = ReadTrafo();
- }
- }
-
- } catch(...) {
- BOOST_FOREACH(aiNode* ch, children) {
- delete ch;
- }
- throw;
- }
-
- // link meshes to node
- nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
- if (nd->mNumMeshes) {
- nd->mMeshes = new unsigned int[nd->mNumMeshes]();
- for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
- nd->mMeshes[i] = meshes[i];
- }
- }
-
- // link children to parent
- nd->mNumChildren = static_cast<unsigned int>(children.size());
- if (nd->mNumChildren) {
- nd->mChildren = new aiNode*[nd->mNumChildren]();
- for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
- nd->mChildren[i] = children[i];
- children[i]->mParent = nd;
- }
- }
-
- return nd.dismiss();
+ ScopeGuard<aiNode> nd(new aiNode());
+ std::vector<aiNode*> children;
+ std::vector<unsigned int> meshes;
+
+ try {
+ while (skipFirst || ReadElementUpToClosing(closetag)) {
+ skipFirst = false;
+
+ const std::string& s = GetElementName();
+ if (s == "mesh") {
+ const size_t prev = scope.meshes_linear.size();
+ if(ReadMesh(scope)) {
+ const size_t newc = scope.meshes_linear.size();
+ for(size_t i = 0; i < newc-prev; ++i) {
+ meshes.push_back(static_cast<unsigned int>(i+prev));
+ }
+ }
+ }
+ else if (s == "mat") {
+ ReadMaterial(scope);
+ }
+ else if (s == "object") {
+ children.push_back(ReadObject(scope));
+ }
+ else if (s == "objectref") {
+ // XXX
+ }
+ else if (s == "meshref") {
+ const unsigned int id = static_cast<unsigned int>( ReadIndexFromText() );
+
+ std::multimap<unsigned int, aiMesh*>::iterator it = scope.meshes.find(id), end = scope.meshes.end();
+ if (it == end) {
+ ThrowException("<meshref> index out of range");
+ }
+
+ for(; it != end && (*it).first == id; ++it) {
+ // ok, this is n^2 and should get optimized one day
+ aiMesh* const m = (*it).second;
+
+ unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size());
+ for(; i < mcount; ++i) {
+ if (scope.meshes_linear[i] == m) {
+ meshes.push_back(i);
+ break;
+ }
+ }
+
+ ai_assert(i < mcount);
+ }
+ }
+ else if (s == "transform") {
+ nd->mTransformation = ReadTrafo();
+ }
+ }
+
+ } catch(...) {
+ for(aiNode* ch : children) {
+ delete ch;
+ }
+ throw;
+ }
+
+ // FIX: since we used std::multimap<> to keep meshes by id, mesh order now depends on the behaviour
+ // of the multimap implementation with respect to the ordering of entries with same values.
+ // C++11 gives the guarantee that it uses insertion order, before it is implementation-specific.
+ // Sort by material id to always guarantee a deterministic result.
+ std::sort(meshes.begin(), meshes.end(), SortMeshByMaterialId(scope));
+
+ // link meshes to node
+ nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
+ if (nd->mNumMeshes) {
+ nd->mMeshes = new unsigned int[nd->mNumMeshes]();
+ for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
+ nd->mMeshes[i] = meshes[i];
+ }
+ }
+
+ // link children to parent
+ nd->mNumChildren = static_cast<unsigned int>(children.size());
+ if (nd->mNumChildren) {
+ nd->mChildren = new aiNode*[nd->mNumChildren]();
+ for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
+ nd->mChildren[i] = children[i];
+ children[i]->mParent = nd;
+ }
+ }
+
+ return nd.dismiss();
}
// ------------------------------------------------------------------------------------------------
aiMatrix4x4 XGLImporter::ReadTrafo()
{
- aiVector3D forward, up, right, position;
- float scale = 1.0f;
-
- while (ReadElementUpToClosing("transform")) {
- const std::string& s = GetElementName();
- if (s == "forward") {
- forward = ReadVec3();
- }
- else if (s == "up") {
- up = ReadVec3();
- }
- else if (s == "position") {
- position = ReadVec3();
- }
- if (s == "scale") {
- scale = ReadFloat();
- if(scale < 0.f) {
- // this is wrong, but we can leave the value and pass it to the caller
- LogError("found negative scaling in <transform>, ignoring");
- }
- }
- }
-
- aiMatrix4x4 m;
- if(forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
- LogError("A direction vector in <transform> is zero, ignoring trafo");
- return m;
- }
-
- forward.Normalize();
- up.Normalize();
-
- right = forward ^ up;
- if (std::fabs(up * forward) > 1e-4) {
- // this is definitely wrong - a degenerate coordinate space ruins everything
- // so subtitute identity transform.
- LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");
- return m;
- }
-
- right *= scale;
- up *= scale;
- forward *= scale;
-
- m.a1 = right.x;
- m.b1 = right.y;
- m.c1 = right.z;
-
- m.a2 = up.x;
- m.b2 = up.y;
- m.c2 = up.z;
-
- m.a3 = forward.x;
- m.b3 = forward.y;
- m.c3 = forward.z;
-
- m.a4 = position.x;
- m.b4 = position.y;
- m.c4 = position.z;
-
- return m;
+ aiVector3D forward, up, right, position;
+ float scale = 1.0f;
+
+ while (ReadElementUpToClosing("transform")) {
+ const std::string& s = GetElementName();
+ if (s == "forward") {
+ forward = ReadVec3();
+ }
+ else if (s == "up") {
+ up = ReadVec3();
+ }
+ else if (s == "position") {
+ position = ReadVec3();
+ }
+ if (s == "scale") {
+ scale = ReadFloat();
+ if(scale < 0.f) {
+ // this is wrong, but we can leave the value and pass it to the caller
+ LogError("found negative scaling in <transform>, ignoring");
+ }
+ }
+ }
+
+ aiMatrix4x4 m;
+ if(forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
+ LogError("A direction vector in <transform> is zero, ignoring trafo");
+ return m;
+ }
+
+ forward.Normalize();
+ up.Normalize();
+
+ right = forward ^ up;
+ if (fabs(up * forward) > 1e-4) {
+ // this is definitely wrong - a degenerate coordinate space ruins everything
+ // so substitute identity transform.
+ LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");
+ return m;
+ }
+
+ right *= scale;
+ up *= scale;
+ forward *= scale;
+
+ m.a1 = right.x;
+ m.b1 = right.y;
+ m.c1 = right.z;
+
+ m.a2 = up.x;
+ m.b2 = up.y;
+ m.c2 = up.z;
+
+ m.a3 = forward.x;
+ m.b3 = forward.y;
+ m.c3 = forward.z;
+
+ m.a4 = position.x;
+ m.b4 = position.y;
+ m.c4 = position.z;
+
+ return m;
}
// ------------------------------------------------------------------------------------------------
aiMesh* XGLImporter::ToOutputMesh(const TempMaterialMesh& m)
{
- ScopeGuard<aiMesh> mesh(new aiMesh());
-
- mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- std::copy(m.positions.begin(),m.positions.end(),mesh->mVertices);
-
- if(m.normals.size()) {
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- std::copy(m.normals.begin(),m.normals.end(),mesh->mNormals);
- }
-
- if(m.uvs.size()) {
- mesh->mNumUVComponents[0] = 2;
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
-
- for(unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x,m.uvs[i].y,0.f);
- }
- }
-
- mesh->mNumFaces = static_cast<unsigned int>(m.vcounts.size());
- mesh->mFaces = new aiFace[m.vcounts.size()];
-
- unsigned int idx = 0;
- for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
- aiFace& f = mesh->mFaces[i];
- f.mNumIndices = m.vcounts[i];
- f.mIndices = new unsigned int[f.mNumIndices];
- for(unsigned int c = 0; c < f.mNumIndices; ++c) {
- f.mIndices[c] = idx++;
- }
- }
-
- ai_assert(idx == mesh->mNumVertices);
-
- mesh->mPrimitiveTypes = m.pflags;
- mesh->mMaterialIndex = m.matid;
- return mesh.dismiss();
+ ScopeGuard<aiMesh> mesh(new aiMesh());
+
+ mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
+ mesh->mVertices = new aiVector3D[mesh->mNumVertices];
+ std::copy(m.positions.begin(),m.positions.end(),mesh->mVertices);
+
+ if(m.normals.size()) {
+ mesh->mNormals = new aiVector3D[mesh->mNumVertices];
+ std::copy(m.normals.begin(),m.normals.end(),mesh->mNormals);
+ }
+
+ if(m.uvs.size()) {
+ mesh->mNumUVComponents[0] = 2;
+ mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
+
+ for(unsigned int i = 0; i < mesh->mNumVertices; ++i) {
+ mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x,m.uvs[i].y,0.f);
+ }
+ }
+
+ mesh->mNumFaces = static_cast<unsigned int>(m.vcounts.size());
+ mesh->mFaces = new aiFace[m.vcounts.size()];
+
+ unsigned int idx = 0;
+ for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
+ aiFace& f = mesh->mFaces[i];
+ f.mNumIndices = m.vcounts[i];
+ f.mIndices = new unsigned int[f.mNumIndices];
+ for(unsigned int c = 0; c < f.mNumIndices; ++c) {
+ f.mIndices[c] = idx++;
+ }
+ }
+
+ ai_assert(idx == mesh->mNumVertices);
+
+ mesh->mPrimitiveTypes = m.pflags;
+ mesh->mMaterialIndex = m.matid;
+ return mesh.dismiss();
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadMesh(TempScope& scope)
{
- TempMesh t;
-
- std::map<unsigned int, TempMaterialMesh> bymat;
- const unsigned int mesh_id = ReadIDAttr();
-
- while (ReadElementUpToClosing("mesh")) {
- const std::string& s = GetElementName();
-
- if (s == "mat") {
- ReadMaterial(scope);
- }
- else if (s == "p") {
- if (!reader->getAttributeValue("ID")) {
- LogWarn("no ID attribute on <p>, ignoring");
- }
- else {
- int id = reader->getAttributeValueAsInt("ID");
- t.points[id] = ReadVec3();
- }
- }
- else if (s == "n") {
- if (!reader->getAttributeValue("ID")) {
- LogWarn("no ID attribute on <n>, ignoring");
- }
- else {
- int id = reader->getAttributeValueAsInt("ID");
- t.normals[id] = ReadVec3();
- }
- }
- else if (s == "tc") {
- if (!reader->getAttributeValue("ID")) {
- LogWarn("no ID attribute on <tc>, ignoring");
- }
- else {
- int id = reader->getAttributeValueAsInt("ID");
- t.uvs[id] = ReadVec2();
- }
- }
- else if (s == "f" || s == "l" || s == "p") {
- const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
-
- unsigned int mid = ~0u;
- TempFace tf[3];
- bool has[3] = {0};
-
- while (ReadElementUpToClosing(s.c_str())) {
- const std::string& s = GetElementName();
- if (s == "fv1" || s == "lv1" || s == "pv1") {
- ReadFaceVertex(t,tf[0]);
- has[0] = true;
- }
- else if (s == "fv2" || s == "lv2") {
- ReadFaceVertex(t,tf[1]);
- has[1] = true;
- }
- else if (s == "fv3") {
- ReadFaceVertex(t,tf[2]);
- has[2] = true;
- }
- else if (s == "mat") {
- if (mid != ~0u) {
- LogWarn("only one material tag allowed per <f>");
- }
- mid = ResolveMaterialRef(scope);
- }
- else if (s == "matref") {
- if (mid != ~0u) {
- LogWarn("only one material tag allowed per <f>");
- }
- mid = ResolveMaterialRef(scope);
- }
- }
-
- if (mid == ~0u) {
- ThrowException("missing material index");
- }
-
- bool nor = false;
- bool uv = false;
- for(unsigned int i = 0; i < vcount; ++i) {
- if (!has[i]) {
- ThrowException("missing face vertex data");
- }
-
- nor = nor || tf[i].has_normal;
- uv = uv || tf[i].has_uv;
- }
-
- if (mid >= (1<<30)) {
- LogWarn("material indices exhausted, this may cause errors in the output");
- }
- unsigned int meshId = mid | ((nor?1:0)<<31) | ((uv?1:0)<<30);
-
- TempMaterialMesh& mesh = bymat[meshId];
- mesh.matid = mid;
-
- for(unsigned int i = 0; i < vcount; ++i) {
- mesh.positions.push_back(tf[i].pos);
- if(nor) {
- mesh.normals.push_back(tf[i].normal);
- }
- if(uv) {
- mesh.uvs.push_back(tf[i].uv);
- }
-
- mesh.pflags |= 1 << (vcount-1);
- }
-
- mesh.vcounts.push_back(vcount);
- }
- }
-
- // finally extract output meshes and add them to the scope
- typedef std::pair<unsigned int, TempMaterialMesh> pairt;
- BOOST_FOREACH(const pairt& p, bymat) {
- aiMesh* const m = ToOutputMesh(p.second);
- scope.meshes_linear.push_back(m);
-
- // if this is a definition, keep it on the stack
- if(mesh_id != ~0u) {
- scope.meshes.insert(std::pair<unsigned int, aiMesh*>(mesh_id,m));
- }
- }
-
- // no id == not a reference, insert this mesh right *here*
- return mesh_id == ~0u;
+ TempMesh t;
+
+ std::map<unsigned int, TempMaterialMesh> bymat;
+ const unsigned int mesh_id = ReadIDAttr();
+
+ while (ReadElementUpToClosing("mesh")) {
+ const std::string& s = GetElementName();
+
+ if (s == "mat") {
+ ReadMaterial(scope);
+ }
+ else if (s == "p") {
+ if (!reader->getAttributeValue("ID")) {
+ LogWarn("no ID attribute on <p>, ignoring");
+ }
+ else {
+ int id = reader->getAttributeValueAsInt("ID");
+ t.points[id] = ReadVec3();
+ }
+ }
+ else if (s == "n") {
+ if (!reader->getAttributeValue("ID")) {
+ LogWarn("no ID attribute on <n>, ignoring");
+ }
+ else {
+ int id = reader->getAttributeValueAsInt("ID");
+ t.normals[id] = ReadVec3();
+ }
+ }
+ else if (s == "tc") {
+ if (!reader->getAttributeValue("ID")) {
+ LogWarn("no ID attribute on <tc>, ignoring");
+ }
+ else {
+ int id = reader->getAttributeValueAsInt("ID");
+ t.uvs[id] = ReadVec2();
+ }
+ }
+ else if (s == "f" || s == "l" || s == "p") {
+ const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
+
+ unsigned int mid = ~0u;
+ TempFace tf[3];
+ bool has[3] = {0};
+
+ while (ReadElementUpToClosing(s.c_str())) {
+ const std::string& s = GetElementName();
+ if (s == "fv1" || s == "lv1" || s == "pv1") {
+ ReadFaceVertex(t,tf[0]);
+ has[0] = true;
+ }
+ else if (s == "fv2" || s == "lv2") {
+ ReadFaceVertex(t,tf[1]);
+ has[1] = true;
+ }
+ else if (s == "fv3") {
+ ReadFaceVertex(t,tf[2]);
+ has[2] = true;
+ }
+ else if (s == "mat") {
+ if (mid != ~0u) {
+ LogWarn("only one material tag allowed per <f>");
+ }
+ mid = ResolveMaterialRef(scope);
+ }
+ else if (s == "matref") {
+ if (mid != ~0u) {
+ LogWarn("only one material tag allowed per <f>");
+ }
+ mid = ResolveMaterialRef(scope);
+ }
+ }
+
+ if (mid == ~0u) {
+ ThrowException("missing material index");
+ }
+
+ bool nor = false;
+ bool uv = false;
+ for(unsigned int i = 0; i < vcount; ++i) {
+ if (!has[i]) {
+ ThrowException("missing face vertex data");
+ }
+
+ nor = nor || tf[i].has_normal;
+ uv = uv || tf[i].has_uv;
+ }
+
+ if (mid >= (1<<30)) {
+ LogWarn("material indices exhausted, this may cause errors in the output");
+ }
+ unsigned int meshId = mid | ((nor?1:0)<<31) | ((uv?1:0)<<30);
+
+ TempMaterialMesh& mesh = bymat[meshId];
+ mesh.matid = mid;
+
+ for(unsigned int i = 0; i < vcount; ++i) {
+ mesh.positions.push_back(tf[i].pos);
+ if(nor) {
+ mesh.normals.push_back(tf[i].normal);
+ }
+ if(uv) {
+ mesh.uvs.push_back(tf[i].uv);
+ }
+
+ mesh.pflags |= 1 << (vcount-1);
+ }
+
+ mesh.vcounts.push_back(vcount);
+ }
+ }
+
+ // finally extract output meshes and add them to the scope
+ typedef std::pair<unsigned int, TempMaterialMesh> pairt;
+ for(const pairt& p : bymat) {
+ aiMesh* const m = ToOutputMesh(p.second);
+ scope.meshes_linear.push_back(m);
+
+ // if this is a definition, keep it on the stack
+ if(mesh_id != ~0u) {
+ scope.meshes.insert(std::pair<unsigned int, aiMesh*>(mesh_id,m));
+ }
+ }
+
+ // no id == not a reference, insert this mesh right *here*
+ return mesh_id == ~0u;
}
// ----------------------------------------------------------------------------------------------
unsigned int XGLImporter::ResolveMaterialRef(TempScope& scope)
{
- const std::string& s = GetElementName();
- if (s == "mat") {
- ReadMaterial(scope);
- return scope.materials_linear.size()-1;
- }
-
- const int id = ReadIndexFromText();
-
- std::map<unsigned int, aiMaterial*>::iterator it = scope.materials.find(id), end = scope.materials.end();
- if (it == end) {
- ThrowException("<matref> index out of range");
- }
-
- // ok, this is n^2 and should get optimized one day
- aiMaterial* const m = (*it).second;
-
- unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size());
- for(; i < mcount; ++i) {
- if (scope.materials_linear[i] == m) {
- return i;
- }
- }
-
- ai_assert(false);
- return 0;
+ const std::string& s = GetElementName();
+ if (s == "mat") {
+ ReadMaterial(scope);
+ return scope.materials_linear.size()-1;
+ }
+
+ const int id = ReadIndexFromText();
+
+ std::map<unsigned int, aiMaterial*>::iterator it = scope.materials.find(id), end = scope.materials.end();
+ if (it == end) {
+ ThrowException("<matref> index out of range");
+ }
+
+ // ok, this is n^2 and should get optimized one day
+ aiMaterial* const m = (*it).second;
+
+ unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size());
+ for(; i < mcount; ++i) {
+ if (scope.materials_linear[i] == m) {
+ return i;
+ }
+ }
+
+ ai_assert(false);
+ return 0;
}
// ------------------------------------------------------------------------------------------------
void XGLImporter::ReadMaterial(TempScope& scope)
{
- const unsigned int mat_id = ReadIDAttr();
-
- ScopeGuard<aiMaterial> mat(new aiMaterial());
- while (ReadElementUpToClosing("mat")) {
- const std::string& s = GetElementName();
- if (s == "amb") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
- }
- else if (s == "diff") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
- }
- else if (s == "spec") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
- }
- else if (s == "emiss") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_EMISSIVE);
- }
- else if (s == "alpha") {
- const float f = ReadFloat();
- mat->AddProperty(&f,1,AI_MATKEY_OPACITY);
- }
- else if (s == "shine") {
- const float f = ReadFloat();
- mat->AddProperty(&f,1,AI_MATKEY_SHININESS);
- }
- }
-
- scope.materials[mat_id] = mat;
- scope.materials_linear.push_back(mat.dismiss());
+ const unsigned int mat_id = ReadIDAttr();
+
+ ScopeGuard<aiMaterial> mat(new aiMaterial());
+ while (ReadElementUpToClosing("mat")) {
+ const std::string& s = GetElementName();
+ if (s == "amb") {
+ const aiColor3D c = ReadCol3();
+ mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
+ }
+ else if (s == "diff") {
+ const aiColor3D c = ReadCol3();
+ mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
+ }
+ else if (s == "spec") {
+ const aiColor3D c = ReadCol3();
+ mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
+ }
+ else if (s == "emiss") {
+ const aiColor3D c = ReadCol3();
+ mat->AddProperty(&c,1,AI_MATKEY_COLOR_EMISSIVE);
+ }
+ else if (s == "alpha") {
+ const float f = ReadFloat();
+ mat->AddProperty(&f,1,AI_MATKEY_OPACITY);
+ }
+ else if (s == "shine") {
+ const float f = ReadFloat();
+ mat->AddProperty(&f,1,AI_MATKEY_SHININESS);
+ }
+ }
+
+ scope.materials[mat_id] = mat;
+ scope.materials_linear.push_back(mat.dismiss());
}
// ----------------------------------------------------------------------------------------------
void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
{
- const std::string& end = GetElementName();
-
- bool havep = false;
- while (ReadElementUpToClosing(end.c_str())) {
- const std::string& s = GetElementName();
- if (s == "pref") {
- const unsigned int id = ReadIndexFromText();
- std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id);
- if (it == t.points.end()) {
- ThrowException("point index out of range");
- }
-
- out.pos = (*it).second;
- havep = true;
- }
- else if (s == "nref") {
- const unsigned int id = ReadIndexFromText();
- std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id);
- if (it == t.normals.end()) {
- ThrowException("normal index out of range");
- }
-
- out.normal = (*it).second;
- out.has_normal = true;
- }
- else if (s == "tcref") {
- const unsigned int id = ReadIndexFromText();
- std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id);
- if (it == t.uvs.end()) {
- ThrowException("uv index out of range");
- }
-
- out.uv = (*it).second;
- out.has_uv = true;
- }
- else if (s == "p") {
- out.pos = ReadVec3();
- }
- else if (s == "n") {
- out.normal = ReadVec3();
- }
- else if (s == "tc") {
- out.uv = ReadVec2();
- }
- }
-
- if (!havep) {
- ThrowException("missing <pref> in <fvN> element");
- }
+ const std::string& end = GetElementName();
+
+ bool havep = false;
+ while (ReadElementUpToClosing(end.c_str())) {
+ const std::string& s = GetElementName();
+ if (s == "pref") {
+ const unsigned int id = ReadIndexFromText();
+ std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id);
+ if (it == t.points.end()) {
+ ThrowException("point index out of range");
+ }
+
+ out.pos = (*it).second;
+ havep = true;
+ }
+ else if (s == "nref") {
+ const unsigned int id = ReadIndexFromText();
+ std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id);
+ if (it == t.normals.end()) {
+ ThrowException("normal index out of range");
+ }
+
+ out.normal = (*it).second;
+ out.has_normal = true;
+ }
+ else if (s == "tcref") {
+ const unsigned int id = ReadIndexFromText();
+ std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id);
+ if (it == t.uvs.end()) {
+ ThrowException("uv index out of range");
+ }
+
+ out.uv = (*it).second;
+ out.has_uv = true;
+ }
+ else if (s == "p") {
+ out.pos = ReadVec3();
+ }
+ else if (s == "n") {
+ out.normal = ReadVec3();
+ }
+ else if (s == "tc") {
+ out.uv = ReadVec2();
+ }
+ }
+
+ if (!havep) {
+ ThrowException("missing <pref> in <fvN> element");
+ }
}
// ------------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadIDAttr()
{
- for(int i = 0, e = reader->getAttributeCount(); i < e; ++i) {
-
- if(!ASSIMP_stricmp(reader->getAttributeName(i),"id")) {
- return reader->getAttributeValueAsInt(i);
- }
- }
- return ~0u;
+ for(int i = 0, e = reader->getAttributeCount(); i < e; ++i) {
+
+ if(!ASSIMP_stricmp(reader->getAttributeName(i),"id")) {
+ return reader->getAttributeValueAsInt(i);
+ }
+ }
+ return ~0u;
}
// ------------------------------------------------------------------------------------------------
float XGLImporter::ReadFloat()
{
- if(!SkipToText()) {
- LogError("unexpected EOF reading float element contents");
- return 0.f;
- }
- const char* s = reader->getNodeData(), *se;
-
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse float");
- return 0.f;
- }
-
- float t;
- se = fast_atoreal_move(s,t);
-
- if (se == s) {
- LogError("failed to read float text");
- return 0.f;
- }
-
- return t;
+ if(!SkipToText()) {
+ LogError("unexpected EOF reading float element contents");
+ return 0.f;
+ }
+ const char* s = reader->getNodeData(), *se;
+
+ if(!SkipSpaces(&s)) {
+ LogError("unexpected EOL, failed to parse float");
+ return 0.f;
+ }
+
+ float t;
+ se = fast_atoreal_move(s,t);
+
+ if (se == s) {
+ LogError("failed to read float text");
+ return 0.f;
+ }
+
+ return t;
}
// ------------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadIndexFromText()
{
- if(!SkipToText()) {
- LogError("unexpected EOF reading index element contents");
- return ~0u;
- }
- const char* s = reader->getNodeData(), *se;
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse index element");
- return ~0u;
- }
-
- const unsigned int t = strtoul10(s,&se);
-
- if (se == s) {
- LogError("failed to read index");
- return ~0u;
- }
-
- return t;
+ if(!SkipToText()) {
+ LogError("unexpected EOF reading index element contents");
+ return ~0u;
+ }
+ const char* s = reader->getNodeData(), *se;
+ if(!SkipSpaces(&s)) {
+ LogError("unexpected EOL, failed to parse index element");
+ return ~0u;
+ }
+
+ const unsigned int t = strtoul10(s,&se);
+
+ if (se == s) {
+ LogError("failed to read index");
+ return ~0u;
+ }
+
+ return t;
}
// ------------------------------------------------------------------------------------------------
aiVector2D XGLImporter::ReadVec2()
{
- aiVector2D vec;
-
- if(!SkipToText()) {
- LogError("unexpected EOF reading vec2 contents");
- return vec;
- }
- const char* s = reader->getNodeData();
-
- for(int i = 0; i < 2; ++i) {
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse vec2");
- return vec;
- }
- vec[i] = fast_atof(&s);
-
- SkipSpaces(&s);
- if (i != 1 && *s != ',') {
- LogError("expected comma, failed to parse vec2");
- return vec;
- }
- ++s;
- }
-
- return vec;
+ aiVector2D vec;
+
+ if(!SkipToText()) {
+ LogError("unexpected EOF reading vec2 contents");
+ return vec;
+ }
+ const char* s = reader->getNodeData();
+
+ for(int i = 0; i < 2; ++i) {
+ if(!SkipSpaces(&s)) {
+ LogError("unexpected EOL, failed to parse vec2");
+ return vec;
+ }
+ vec[i] = fast_atof(&s);
+
+ SkipSpaces(&s);
+ if (i != 1 && *s != ',') {
+ LogError("expected comma, failed to parse vec2");
+ return vec;
+ }
+ ++s;
+ }
+
+ return vec;
}
// ------------------------------------------------------------------------------------------------
aiVector3D XGLImporter::ReadVec3()
{
- aiVector3D vec;
-
- if(!SkipToText()) {
- LogError("unexpected EOF reading vec3 contents");
- return vec;
- }
- const char* s = reader->getNodeData();
-
- for(int i = 0; i < 3; ++i) {
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse vec3");
- return vec;
- }
- vec[i] = fast_atof(&s);
-
- SkipSpaces(&s);
- if (i != 2 && *s != ',') {
- LogError("expected comma, failed to parse vec3");
- return vec;
- }
- ++s;
- }
-
- return vec;
+ aiVector3D vec;
+
+ if(!SkipToText()) {
+ LogError("unexpected EOF reading vec3 contents");
+ return vec;
+ }
+ const char* s = reader->getNodeData();
+
+ for(int i = 0; i < 3; ++i) {
+ if(!SkipSpaces(&s)) {
+ LogError("unexpected EOL, failed to parse vec3");
+ return vec;
+ }
+ vec[i] = fast_atof(&s);
+
+ SkipSpaces(&s);
+ if (i != 2 && *s != ',') {
+ LogError("expected comma, failed to parse vec3");
+ return vec;
+ }
+ ++s;
+ }
+
+ return vec;
}
// ------------------------------------------------------------------------------------------------
aiColor3D XGLImporter::ReadCol3()
{
- const aiVector3D& v = ReadVec3();
- if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) {
- LogWarn("color values out of range, ignoring");
- }
- return aiColor3D(v.x,v.y,v.z);
+ const aiVector3D& v = ReadVec3();
+ if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) {
+ LogWarn("color values out of range, ignoring");
+ }
+ return aiColor3D(v.x,v.y,v.z);
}
-#endif
+#endif