diff options
Diffstat (limited to 'src/3rdparty/assimp/code/SIBImporter.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/SIBImporter.cpp | 191 |
1 files changed, 103 insertions, 88 deletions
diff --git a/src/3rdparty/assimp/code/SIBImporter.cpp b/src/3rdparty/assimp/code/SIBImporter.cpp index b972f28d6..2127e2e0c 100644 --- a/src/3rdparty/assimp/code/SIBImporter.cpp +++ b/src/3rdparty/assimp/code/SIBImporter.cpp @@ -3,7 +3,8 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2016, assimp team +Copyright (c) 2006-2017, assimp team + All rights reserved. @@ -57,11 +58,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ByteSwapper.h" #include "StreamReader.h" #include "TinyFormatter.h" -#include "../contrib/ConvertUTF/ConvertUTF.h" +//#include "../contrib/ConvertUTF/ConvertUTF.h" +#include "../contrib/utf8cpp/source/utf8.h" #include <assimp/IOSystem.hpp> #include <assimp/DefaultLogger.hpp> #include <assimp/scene.h> +#include <assimp/importerdesc.h> +#include <map> using namespace Assimp; @@ -76,25 +80,26 @@ static const aiImporterDesc desc = { "sib" }; -struct SIBChunk -{ +struct SIBChunk { uint32_t Tag; uint32_t Size; } PACK_STRUCT; -enum { POS, NRM, UV, N }; +enum { + POS, + NRM, + UV, + N +}; typedef std::pair<uint32_t, uint32_t> SIBPair; -static SIBPair makePair(uint32_t a, uint32_t b) { return (a<b) ? SIBPair(a, b) : SIBPair(b, a); } -struct SIBEdge -{ +struct SIBEdge { uint32_t faceA, faceB; bool creased; }; -struct SIBMesh -{ +struct SIBMesh { aiMatrix4x4 axis; uint32_t numPts; std::vector<aiVector3D> pos, nrm, uv; @@ -105,15 +110,13 @@ struct SIBMesh std::map<SIBPair, uint32_t> edgeMap; }; -struct SIBObject -{ +struct SIBObject { aiString name; aiMatrix4x4 axis; size_t meshIdx, meshCount; }; -struct SIB -{ +struct SIB { std::vector<aiMaterial*> mtls; std::vector<aiMesh*> meshes; std::vector<aiLight*> lights; @@ -121,8 +124,7 @@ struct SIB }; // ------------------------------------------------------------------------------------------------ -static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) -{ +static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) { SIBPair pair = (posA < posB) ? SIBPair(posA, posB) : SIBPair(posB, posA); std::map<SIBPair, uint32_t>::iterator it = mesh->edgeMap.find(pair); if (it != mesh->edgeMap.end()) @@ -131,7 +133,7 @@ static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) SIBEdge edge; edge.creased = false; edge.faceA = edge.faceB = 0xffffffff; - mesh->edgeMap[pair] = mesh->edges.size(); + mesh->edgeMap[pair] = static_cast<uint32_t>(mesh->edges.size()); mesh->edges.push_back(edge); return mesh->edges.back(); } @@ -161,72 +163,79 @@ static aiColor3D ReadColor(StreamReaderLE* stream) return aiColor3D(r, g, b); } -static void UnknownChunk(StreamReaderLE* stream, const SIBChunk& chunk) +static void UnknownChunk(StreamReaderLE* /*stream*/, const SIBChunk& chunk) { - char temp[5] = { + char temp[5] = { static_cast<char>(( chunk.Tag>>24 ) & 0xff), static_cast<char>(( chunk.Tag>>16 ) & 0xff), static_cast<char>(( chunk.Tag>>8 ) & 0xff), static_cast<char>(chunk.Tag & 0xff), '\0' }; - + DefaultLogger::get()->warn((Formatter::format(), "SIB: Skipping unknown '",temp,"' chunk.")); } // Reads a UTF-16LE string and returns it at UTF-8. -static aiString ReadString(StreamReaderLE* stream, uint32_t numWChars) -{ +static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) { + if ( nullptr == stream || 0 == numWChars ) { + static const aiString empty; + return empty; + } + // Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8) - UTF16* temp = new UTF16[numWChars]; - UTF8* str = new UTF8[numWChars * 4 + 1]; - for (uint32_t n=0;n<numWChars;n++) - temp[n] = stream->GetU2(); + std::vector<unsigned char> str; + str.reserve( numWChars * 4 + 1 ); + uint16_t *temp = new uint16_t[ numWChars ]; + for ( uint32_t n = 0; n < numWChars; ++n ) { + temp[ n ] = stream->GetU2(); + } // Convert it and NUL-terminate. - const UTF16 *start = temp, *end = temp + numWChars; - UTF8 *dest = str, *limit = str + numWChars*4; - ConvertUTF16toUTF8(&start, end, &dest, limit, lenientConversion); - *dest = '\0'; + const uint16_t *start( temp ), *end( temp + numWChars ); + utf8::utf16to8( start, end, back_inserter( str ) ); + str[ str.size() - 1 ] = '\0'; // Return the final string. - aiString result = aiString((const char *)str); - delete[] str; + aiString result = aiString((const char *)&str[0]); delete[] temp; + return result; } // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer -SIBImporter::SIBImporter() -{} +SIBImporter::SIBImporter() { + // empty +} // ------------------------------------------------------------------------------------------------ // Destructor, private as well -SIBImporter::~SIBImporter() -{} +SIBImporter::~SIBImporter() { + // empty +} // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. -bool SIBImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const -{ +bool SIBImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const { return SimpleExtensionCheck(pFile, "sib"); } // ------------------------------------------------------------------------------------------------ -const aiImporterDesc* SIBImporter::GetInfo () const -{ +const aiImporterDesc* SIBImporter::GetInfo () const { return &desc; } // ------------------------------------------------------------------------------------------------ -static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) -{ - mesh->pos.resize(count); +static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) { + if ( nullptr == mesh || nullptr == stream ) { + return; + } - for (uint32_t n=0;n<count;n++) { - mesh->pos[n].x = stream->GetF4(); - mesh->pos[n].y = stream->GetF4(); - mesh->pos[n].z = stream->GetF4(); + mesh->pos.resize(count); + for ( uint32_t n=0; n<count; ++n ) { + mesh->pos[ n ].x = stream->GetF4(); + mesh->pos[ n ].y = stream->GetF4(); + mesh->pos[ n ].z = stream->GetF4(); } } @@ -244,7 +253,7 @@ static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream) mesh->idx[pos-1] = numPoints; uint32_t *idx = &mesh->idx[pos]; - mesh->faceStart.push_back(pos-1); + mesh->faceStart.push_back(static_cast<uint32_t>(pos-1)); mesh->mtls.push_back(0); // Read all the position data. @@ -373,7 +382,7 @@ static void ConnectFaces(SIBMesh* mesh) uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]]; uint32_t numPoints = *idx++; uint32_t prev = idx[(numPoints-1)*N+POS]; - + for (uint32_t i=0;i<numPoints;i++,idx+=N) { uint32_t next = idx[POS]; @@ -385,9 +394,9 @@ static void ConnectFaces(SIBMesh* mesh) // This gives potentially undesirable normals when used // with non-2-manifold surfaces, but then so does Silo to begin with. if (edge.faceA == 0xffffffff) - edge.faceA = faceIdx; - else - edge.faceB = faceIdx; + edge.faceA = static_cast<uint32_t>(faceIdx); + else if (edge.faceB == 0xffffffff) + edge.faceB = static_cast<uint32_t>(faceIdx); prev = next; } @@ -398,7 +407,7 @@ static void ConnectFaces(SIBMesh* mesh) static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_t pos, const std::vector<aiVector3D>& faceNormals) { - // Creased edges complicate this. We need to find the start/end range of the + // Creased edges complicate this. We need to find the start/end range of the // ring of faces that touch this position. // We do this in two passes. The first pass is to find the end of the range, // the second is to work backwards to the start and calculate the final normal. @@ -430,12 +439,17 @@ static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_ { SIBEdge& edge = GetEdge(mesh, posA, posB); - // Move to whichever side we didn't just come from. - if (!edge.creased) { - if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx) - nextFaceIdx = edge.faceA; - else if (edge.faceB != prevFaceIdx && edge.faceB != faceIdx) - nextFaceIdx = edge.faceB; + // Non-manifold meshes can produce faces which share + // positions but have no edge entry, so check it. + if (edge.faceA == faceIdx || edge.faceB == faceIdx) + { + // Move to whichever side we didn't just come from. + if (!edge.creased) { + if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff) + nextFaceIdx = edge.faceA; + else if (edge.faceB != prevFaceIdx && edge.faceB != faceIdx && edge.faceB != 0xffffffff) + nextFaceIdx = edge.faceB; + } } } @@ -449,7 +463,7 @@ static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_ prevFaceIdx = faceIdx; faceIdx = nextFaceIdx; - } + } } // Normalize it. @@ -496,7 +510,7 @@ static void CalculateNormals(SIBMesh* mesh) { uint32_t pos = idx[i*N+POS]; uint32_t nrm = idx[i*N+NRM]; - aiVector3D vtxNorm = CalculateVertexNormal(mesh, faceIdx, pos, faceNormals); + aiVector3D vtxNorm = CalculateVertexNormal(mesh, static_cast<uint32_t>(faceIdx), pos, faceNormals); mesh->nrm[nrm] = vtxNorm; } } @@ -508,7 +522,7 @@ struct TempMesh std::vector<aiVector3D> vtx; std::vector<aiVector3D> nrm; std::vector<aiVector3D> uv; - std::vector<aiFace> faces; + std::vector<aiFace> faces; }; static void ReadShape(SIB* sib, StreamReaderLE* stream) @@ -546,7 +560,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream) stream->SetReadLimit(oldLimit); } - assert(smesh.faceStart.size() == smesh.mtls.size()); // sanity check + ai_assert(smesh.faceStart.size() == smesh.mtls.size()); // sanity check // Silo doesn't store any normals in the file - we need to compute // them ourselves. We can't let AssImp handle it as AssImp doesn't @@ -586,7 +600,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream) for (unsigned pt=0;pt<face.mNumIndices;pt++,idx+=N) { size_t vtxIdx = dest.vtx.size(); - face.mIndices[pt] = vtxIdx; + face.mIndices[pt] = static_cast<unsigned int>(vtxIdx); // De-index it. We don't need to validate here as // we did it when creating the data. @@ -610,7 +624,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream) obj.name = name; obj.axis = smesh.axis; obj.meshIdx = sib->meshes.size(); - + // Now that we know the size of everything, // we can build the final one-material-per-mesh data. for (size_t n=0;n<meshes.size();n++) @@ -621,14 +635,14 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream) aiMesh* mesh = new aiMesh; mesh->mName = name; - mesh->mNumFaces = src.faces.size(); + mesh->mNumFaces = static_cast<unsigned int>(src.faces.size()); mesh->mFaces = new aiFace[mesh->mNumFaces]; - mesh->mNumVertices = src.vtx.size(); + mesh->mNumVertices = static_cast<unsigned int>(src.vtx.size()); mesh->mVertices = new aiVector3D[mesh->mNumVertices]; mesh->mNormals = new aiVector3D[mesh->mNumVertices]; mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; mesh->mNumUVComponents[0] = 2; - mesh->mMaterialIndex = n; + mesh->mMaterialIndex = static_cast<unsigned int>(n); for (unsigned i=0;i<mesh->mNumVertices;i++) { @@ -697,8 +711,8 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream) light->mColorDiffuse = ReadColor(stream); light->mColorAmbient = ReadColor(stream); light->mColorSpecular = ReadColor(stream); - float spotExponent = stream->GetF4(); - float spotCutoff = stream->GetF4(); + ai_real spotExponent = stream->GetF4(); + ai_real spotCutoff = stream->GetF4(); light->mAttenuationConstant = stream->GetF4(); light->mAttenuationLinear = stream->GetF4(); light->mAttenuationQuadratic = stream->GetF4(); @@ -709,9 +723,9 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream) // 99% and 1% percentiles. // OpenGL: I = cos(angle)^E // Solving: angle = acos(I^(1/E)) - float E = 1.0f / std::max(spotExponent, 0.00001f); - float inner = acosf(powf(0.99f, E)); - float outer = acosf(powf(0.01f, E)); + ai_real E = ai_real( 1.0 ) / std::max(spotExponent, (ai_real)0.00001); + ai_real inner = std::acos(std::pow((ai_real)0.99, E)); + ai_real outer = std::acos(std::pow((ai_real)0.01, E)); // Apply the cutoff. outer = std::min(outer, AI_DEG_TO_RAD(spotCutoff)); @@ -792,8 +806,9 @@ static void ReadInstance(SIB* sib, StreamReaderLE* stream) stream->SetReadLimit(oldLimit); } - if (shapeIndex >= sib->objs.size()) - throw DeadlyImportError("SIB: Invalid shape index."); + if ( shapeIndex >= sib->objs.size() ) { + throw DeadlyImportError( "SIB: Invalid shape index." ); + } const SIBObject& src = sib->objs[shapeIndex]; inst.meshIdx = src.meshIdx; @@ -805,8 +820,9 @@ static void ReadInstance(SIB* sib, StreamReaderLE* stream) static void CheckVersion(StreamReaderLE* stream) { uint32_t version = stream->GetU4(); - if (version != 1) - throw DeadlyImportError("SIB: Unsupported file version."); + if ( version < 1 || version > 2 ) { + throw DeadlyImportError( "SIB: Unsupported file version." ); + } } static void ReadScene(SIB* sib, StreamReaderLE* stream) @@ -862,9 +878,9 @@ void SIBImporter::InternReadFile(const std::string& pFile, sib.insts.clear(); // Transfer to the aiScene. - pScene->mNumMaterials = sib.mtls.size(); - pScene->mNumMeshes = sib.meshes.size(); - pScene->mNumLights = sib.lights.size(); + pScene->mNumMaterials = static_cast<unsigned int>(sib.mtls.size()); + pScene->mNumMeshes = static_cast<unsigned int>(sib.meshes.size()); + pScene->mNumLights = static_cast<unsigned int>(sib.lights.size()); pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial*[pScene->mNumMaterials] : NULL; pScene->mMeshes = pScene->mNumMeshes ? new aiMesh*[pScene->mNumMeshes] : NULL; pScene->mLights = pScene->mNumLights ? new aiLight*[pScene->mNumLights] : NULL; @@ -879,13 +895,14 @@ void SIBImporter::InternReadFile(const std::string& pFile, size_t childIdx = 0; aiNode *root = new aiNode(); root->mName.Set("<SIBRoot>"); - root->mNumChildren = sib.objs.size() + sib.lights.size(); + root->mNumChildren = static_cast<unsigned int>(sib.objs.size() + sib.lights.size()); root->mChildren = root->mNumChildren ? new aiNode*[root->mNumChildren] : NULL; pScene->mRootNode = root; // Add nodes for each object. for (size_t n=0;n<sib.objs.size();n++) { + ai_assert(root->mChildren); SIBObject& obj = sib.objs[n]; aiNode* node = new aiNode; root->mChildren[childIdx++] = node; @@ -893,19 +910,16 @@ void SIBImporter::InternReadFile(const std::string& pFile, node->mParent = root; node->mTransformation = obj.axis; - node->mNumMeshes = obj.meshCount; + node->mNumMeshes = static_cast<unsigned int>(obj.meshCount); node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : NULL; for (unsigned i=0;i<node->mNumMeshes;i++) - node->mMeshes[i] = obj.meshIdx + i; + node->mMeshes[i] = static_cast<unsigned int>(obj.meshIdx + i); // Mark instanced objects as being so. if (n >= firstInst) { - node->mMetaData = new aiMetadata; - node->mMetaData->mNumProperties = 1; - node->mMetaData->mKeys = new aiString[1]; - node->mMetaData->mValues = new aiMetadataEntry[1]; - node->mMetaData->Set(0, "IsInstance", true); + node->mMetaData = aiMetadata::Alloc( 1 ); + node->mMetaData->Set( 0, "IsInstance", true ); } } @@ -913,6 +927,7 @@ void SIBImporter::InternReadFile(const std::string& pFile, // (no transformation as the light is already in world space) for (size_t n=0;n<sib.lights.size();n++) { + ai_assert(root->mChildren); aiLight* light = sib.lights[n]; if ( nullptr != light ) { aiNode* node = new aiNode; |