summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/SIBImporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/SIBImporter.cpp')
-rw-r--r--src/3rdparty/assimp/code/SIBImporter.cpp191
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;