123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805 |
- /*
- ---------------------------------------------------------------------------
- Open Asset Import Library (ASSIMP)
- ---------------------------------------------------------------------------
- Copyright (c) 2006-2008, ASSIMP Development 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 Development 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 */
- #include "AssimpPCH.h"
- #include "IRRMeshLoader.h"
- #include "ParsingUtils.h"
- #include "fast_atof.h"
- using namespace Assimp;
- /**** AT FIRST: IrrlightBase, base class for IrrMesh and Irr *******/
- // ------------------------------------------------------------------------------------------------
- // read a property in hexadecimal format (i.e. ffffffff)
- void IrrlichtBase::ReadHexProperty (HexProperty& out)
- {
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // parse the hexadecimal value
- out.value = strtol16(reader->getAttributeValue(i));
- }
- }
- }
- // ------------------------------------------------------------------------------------------------
- // read a decimal property
- void IrrlichtBase::ReadIntProperty (IntProperty& out)
- {
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // parse the ecimal value
- out.value = strtol10s(reader->getAttributeValue(i));
- }
- }
- }
- // ------------------------------------------------------------------------------------------------
- // read a string property
- void IrrlichtBase::ReadStringProperty (StringProperty& out)
- {
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // simple copy the string
- out.value = std::string (reader->getAttributeValue(i));
- }
- }
- }
- // ------------------------------------------------------------------------------------------------
- // read a boolean property
- void IrrlichtBase::ReadBoolProperty (BoolProperty& out)
- {
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // true or false, case insensitive
- out.value = (ASSIMP_stricmp( reader->getAttributeValue(i),
- "true") ? false : true);
- }
- }
- }
- // ------------------------------------------------------------------------------------------------
- // read a float property
- void IrrlichtBase::ReadFloatProperty (FloatProperty& out)
- {
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // just parse the float
- out.value = fast_atof( reader->getAttributeValue(i) );
- }
- }
- }
- // ------------------------------------------------------------------------------------------------
- // read a vector property
- void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
- {
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // three floats, separated with commas
- const char* ptr = reader->getAttributeValue(i);
- SkipSpaces(&ptr);
- ptr = fast_atof_move( ptr,(float&)out.value.x );
- SkipSpaces(&ptr);
- if (',' != *ptr)
- {
- DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
- }
- else SkipSpaces(ptr+1,&ptr);
- ptr = fast_atof_move( ptr,(float&)out.value.y );
- SkipSpaces(&ptr);
- if (',' != *ptr)
- {
- DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
- }
- else SkipSpaces(ptr+1,&ptr);
- ptr = fast_atof_move( ptr,(float&)out.value.z );
- }
- }
- }
- // ------------------------------------------------------------------------------------------------
- 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;
- }
- // ------------------------------------------------------------------------------------------------
- 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)
- {
- MaterialHelper* mat = new MaterialHelper();
- aiColor4D clr;
- aiString s;
- matFlags = 0;
- // Continue reading from the file
- while (reader->read())
- {
- switch (reader->getNodeType())
- {
- case EXN_ELEMENT:
- // Hex properties
- if (!ASSIMP_stricmp(reader->getNodeName(),"color"))
- {
- 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);
- }
- else if (prop.name == "Emissive")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
- }
- }
- // Float properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"float"))
- {
- FloatProperty prop;
- ReadFloatProperty(prop);
- if (prop.name == "Shininess")
- {
- mat->AddProperty(&prop.value,1,AI_MATKEY_SHININESS);
- }
- }
- // Bool properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"bool"))
- {
- 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);
- }
- }
- // String properties - textures and texture related properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"texture") ||
- !ASSIMP_stricmp(reader->getNodeName(),"enum"))
- {
- StringProperty prop;
- ReadStringProperty(prop);
- int cnt = 0;
- if (prop.value.length())
- {
- // material type (shader)
- if (prop.name == "Type")
- {
- 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 == "lightmap_m2")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_m2;
- }
- else if (prop.value == "lightmap_m4")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_m4;
- }
- }
- // Up to 4 texture channels are supported
- else if (prop.name == "Texture1")
- {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else if (prop.name == "Texture2")
- {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1));
- }
- else if (prop.name == "Texture3")
- {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(2));
- }
- else if (prop.name == "Texture4" )
- {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(3));
- }
- // 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);
- 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(2));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(2));
- }
- else if (prop.name == "TextureWrap4" && cnt >= 4)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(3));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(3));
- }
- }
- }
- break;
- case EXN_ELEMENT_END:
- /* Assume there are no further nested nodes in <material> elements
- */
- if (/* IRRMESH */ !ASSIMP_stricmp(reader->getNodeName(),"material") ||
- /* IRR */ !ASSIMP_stricmp(reader->getNodeName(),"attributes"))
- {
- return mat;
- }
- default:
- // GCC complains here ...
- break;
- }
- }
- DefaultLogger::get()->error("IRRMESH: Unexpected end of file. Material is not complete");
- return mat;
- }
- // ------------------------------------------------------------------------------------------------
- // Constructor to be privately used by Importer
- IRRMeshImporter::IRRMeshImporter()
- {
- // nothing to do here
- }
- // ------------------------------------------------------------------------------------------------
- // Destructor, private as well
- IRRMeshImporter::~IRRMeshImporter()
- {
- // nothing to do here
- }
- // ------------------------------------------------------------------------------------------------
- // Returns whether the class can handle the format of the given file.
- bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) 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.
- */
- std::string::size_type pos = pFile.find_last_of('.');
- // no file extension - can't read
- if( pos == std::string::npos)
- return false;
- std::string extension = pFile.substr( pos);
- for (std::string::iterator i = extension.begin(); i != extension.end();++i)
- *i = ::tolower(*i);
- if (extension == ".irrmesh")return true;
- else if (extension == ".xml")
- {
- /* If CanRead() is called to check whether the loader
- * supports a specific file extension in general we
- * must return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"irrmesh"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
- }
- // ------------------------------------------------------------------------------------------------
- // Imports the given file into the given scene structure.
- void IRRMeshImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
- {
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw new ImportErrorException( "Failed to open IRRMESH file " + pFile + "");
- // Construct the irrXML parser
- CIrrXML_IOStreamReader st(file.get());
- reader = createIrrXMLReader((IFileReadCallBack*) &st);
- // final data
- std::vector<aiMaterial*> materials;
- std::vector<aiMesh*> meshes;
- materials.reserve (5);
- meshes.reserve (5);
- // temporary data - current mesh buffer
- aiMaterial* curMat = NULL;
- aiMesh* curMesh = NULL;
- unsigned int curMatFlags;
- 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
- while (reader->read())
- {
- switch (reader->getNodeType())
- {
- case EXN_ELEMENT:
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh))
- {
- // end of previous buffer. A material and a mesh should be there
- if ( !curMat || !curMesh)
- {
- DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
- delete curMat;
- delete curMesh;
- }
- else
- {
- materials.push_back(curMat);
- meshes.push_back(curMesh);
- }
- curMat = NULL;
- curMesh = NULL;
- curVertices.clear();
- curColors.clear();
- curNormals.clear();
- curUV2s.clear();
- curUVs.clear();
- curTangents.clear();
- curBitangents.clear();
- }
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"material"))
- {
- if (curMat)
- {
- DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please");
- delete curMat;
- }
- curMat = ParseMaterial(curMatFlags);
- }
- /* no else here! */ if (!ASSIMP_stricmp(reader->getNodeName(),"vertices"))
- {
- int num = reader->getAttributeValueAsInt("vertexCount");
- curVertices.reserve (num);
- curNormals.reserve (num);
- curColors.reserve (num);
- curUVs.reserve (num);
- // Determine the file format
- const char* t = reader->getAttributeValueSafe("type");
- if (!ASSIMP_stricmp("2tcoords", t))
- {
- curUV2s.reserve (num);
- vertexFormat = 1;
- }
- else if (!ASSIMP_stricmp("tangents", t))
- {
- curTangents.reserve (num);
- curBitangents.reserve (num);
- vertexFormat = 2;
- }
- else if (ASSIMP_stricmp("standard", t))
- {
- DefaultLogger::get()->warn("IRRMESH: Unknown vertex format");
- }
- else vertexFormat = 0;
- textMeaning = 1;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"indices"))
- {
- if (curVertices.empty())
- throw new ImportErrorException("IRRMESH: indices must come after vertices");
- textMeaning = 2;
- // start a new mesh
- curMesh = new aiMesh();
- // allocate storage for all faces
- curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
- if (curMesh->mNumVertices % 3)
- {
- DefaultLogger::get()->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 = reader->getNodeData();
- if (textMeaning == 1)
- {
- textMeaning = 0;
- // read vertices
- do
- {
- SkipSpacesAndLineEnd(&sz);
- aiVector3D temp;aiColor4D c;
- // Read the vertex position
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curVertices.push_back(temp);
- // Read the vertex normals
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curNormals.push_back(temp);
- // read the vertex colors
- uint32_t clr = strtol16(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_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
- sz = fast_atof_move(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_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
- sz = fast_atof_move(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_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curTangents.push_back(temp);
- // bitangents
- sz = fast_atof_move(sz,(float&)temp.x);
- SkipSpaces(&sz);
- sz = fast_atof_move(sz,(float&)temp.z);
- SkipSpaces(&sz);
- sz = fast_atof_move(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)
- {
- DefaultLogger::get()->error("IRRMESH: Too many indices");
- break;
- }
- if (!curIdx)
- {
- curFace->mNumIndices = 3;
- curFace->mIndices = new unsigned int[3];
- }
- unsigned int idx = strtol10(sz,&sz);
- if (idx >= curVertices.size())
- {
- DefaultLogger::get()->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)
- DefaultLogger::get()->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
- MaterialHelper* mat = (MaterialHelper*)curMat;
- mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY);
- }
- /* TODO: Add lightmapping support here */
- }}
- break;
- default:
- // GCC complains here ...
- break;
- };
- }
- // end of the last buffer. A material and a mesh should be there
- if (curMat || curMesh)
- {
- if ( !curMat || !curMesh)
- {
- DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
- delete curMat;
- delete curMesh;
- }
- else
- {
- materials.push_back(curMat);
- meshes.push_back(curMesh);
- }
- }
- if (materials.empty())
- throw new ImportErrorException("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];
- ::memcpy(pScene->mMeshes,&meshes[0],sizeof(void*)*pScene->mNumMeshes);
- 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;
- delete reader;
- AI_DEBUG_INVALIDATE_PTR(reader);
- }
|