Sfoglia il codice sorgente

Merge branch 'master' into semi-desert-master

Kim Kulling 2 anni fa
parent
commit
e41fe74b2a

+ 11 - 6
code/AssetLib/Collada/ColladaLoader.cpp

@@ -95,6 +95,7 @@ ColladaLoader::ColladaLoader() :
         noSkeletonMesh(false),
         noSkeletonMesh(false),
         removeEmptyBones(false),
         removeEmptyBones(false),
         ignoreUpDirection(false),
         ignoreUpDirection(false),
+        ignoreUnitSize(false),
         useColladaName(false),
         useColladaName(false),
         mNodeNameCounter(0) {
         mNodeNameCounter(0) {
     // empty
     // empty
@@ -122,6 +123,7 @@ void ColladaLoader::SetupProperties(const Importer *pImp) {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
     removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
     removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
+    ignoreUnitSize = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE, 0) != 0;
     useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
     useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
 }
 }
 
 
@@ -170,12 +172,15 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
     // ... then fill the materials with the now adjusted settings
     // ... then fill the materials with the now adjusted settings
     FillMaterials(parser, pScene);
     FillMaterials(parser, pScene);
 
 
-    // Apply unit-size scale calculation
-
-    pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
-            0, parser.mUnitSize, 0, 0,
-            0, 0, parser.mUnitSize, 0,
-            0, 0, 0, 1);
+    if (!ignoreUnitSize) {
+        // Apply unit-size scale calculation
+        pScene->mRootNode->mTransformation *= aiMatrix4x4(
+                parser.mUnitSize, 0, 0, 0,
+                0, parser.mUnitSize, 0, 0,
+                0, 0, parser.mUnitSize, 0,
+                0, 0, 0, 1);
+    }
+    
     if (!ignoreUpDirection) {
     if (!ignoreUpDirection) {
         // Convert to Y_UP, if different orientation
         // Convert to Y_UP, if different orientation
         if (parser.mUpDirection == ColladaParser::UP_X) {
         if (parser.mUpDirection == ColladaParser::UP_X) {

+ 1 - 0
code/AssetLib/Collada/ColladaLoader.h

@@ -239,6 +239,7 @@ protected:
     bool noSkeletonMesh;
     bool noSkeletonMesh;
     bool removeEmptyBones;
     bool removeEmptyBones;
     bool ignoreUpDirection;
     bool ignoreUpDirection;
+    bool ignoreUnitSize;
     bool useColladaName;
     bool useColladaName;
 
 
     /** Used by FindNameForNode() to generate unique node names */
     /** Used by FindNameForNode() to generate unique node names */

+ 1 - 1
code/AssetLib/FBX/FBXParser.cpp

@@ -211,7 +211,7 @@ Scope::Scope(Parser& parser,bool topLevel)
                 elements.insert(ElementMap::value_type(str, element));
                 elements.insert(ElementMap::value_type(str, element));
                 return;
                 return;
             }
             }
-            delete element;
+            delete_Element(element);
             ParseError("unexpected end of file",parser.LastToken());
             ParseError("unexpected end of file",parser.LastToken());
         } else {
         } else {
             elements.insert(ElementMap::value_type(str, element));
             elements.insert(ElementMap::value_type(str, element));

+ 55 - 45
code/AssetLib/glTF2/glTF2Exporter.cpp

@@ -263,7 +263,7 @@ size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn,
     for (short idx = 0; bufferData_ptr < bufferData_end; idx += 1, bufferData_ptr += numCompsIn) {
     for (short idx = 0; bufferData_ptr < bufferData_end; idx += 1, bufferData_ptr += numCompsIn) {
         bool bNonZero = false;
         bool bNonZero = false;
 
 
-        //for the data, check any component Non Zero
+        // for the data, check any component Non Zero
         for (unsigned int j = 0; j < numCompsOut; j++) {
         for (unsigned int j = 0; j < numCompsOut; j++) {
             double valueData = bufferData_ptr[j];
             double valueData = bufferData_ptr[j];
             double valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
             double valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
@@ -273,11 +273,11 @@ size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn,
             }
             }
         }
         }
 
 
-        //all zeros, continue
+        // all zeros, continue
         if (!bNonZero)
         if (!bNonZero)
             continue;
             continue;
 
 
-        //non zero, store the data
+        // non zero, store the data
         for (unsigned int j = 0; j < numCompsOut; j++) {
         for (unsigned int j = 0; j < numCompsOut; j++) {
             T valueData = bufferData_ptr[j];
             T valueData = bufferData_ptr[j];
             T valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
             T valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
@@ -286,14 +286,14 @@ size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn,
         vNZIdx.push_back(idx);
         vNZIdx.push_back(idx);
     }
     }
 
 
-    //avoid all-0, put 1 item
+    // avoid all-0, put 1 item
     if (vNZDiff.size() == 0) {
     if (vNZDiff.size() == 0) {
         for (unsigned int j = 0; j < numCompsOut; j++)
         for (unsigned int j = 0; j < numCompsOut; j++)
             vNZDiff.push_back(0);
             vNZDiff.push_back(0);
         vNZIdx.push_back(0);
         vNZIdx.push_back(0);
     }
     }
 
 
-    //process data
+    // process data
     outputNZDiff = new T[vNZDiff.size()];
     outputNZDiff = new T[vNZDiff.size()];
     memcpy(outputNZDiff, vNZDiff.data(), vNZDiff.size() * sizeof(T));
     memcpy(outputNZDiff, vNZDiff.data(), vNZDiff.size() * sizeof(T));
 
 
@@ -361,7 +361,7 @@ inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffe
         acc->sparse.reset(new Accessor::Sparse);
         acc->sparse.reset(new Accessor::Sparse);
         acc->sparse->count = nzCount;
         acc->sparse->count = nzCount;
 
 
-        //indices
+        // indices
         unsigned int bytesPerIdx = sizeof(unsigned short);
         unsigned int bytesPerIdx = sizeof(unsigned short);
         size_t indices_offset = buffer->byteLength;
         size_t indices_offset = buffer->byteLength;
         size_t indices_padding = indices_offset % bytesPerIdx;
         size_t indices_padding = indices_offset % bytesPerIdx;
@@ -379,7 +379,7 @@ inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffe
         acc->sparse->indicesByteOffset = 0;
         acc->sparse->indicesByteOffset = 0;
         acc->WriteSparseIndices(nzCount, nzIdx, 1 * bytesPerIdx);
         acc->WriteSparseIndices(nzCount, nzIdx, 1 * bytesPerIdx);
 
 
-        //values
+        // values
         size_t values_offset = buffer->byteLength;
         size_t values_offset = buffer->byteLength;
         size_t values_padding = values_offset % bytesPerComp;
         size_t values_padding = values_offset % bytesPerComp;
         values_offset += values_padding;
         values_offset += values_padding;
@@ -395,9 +395,9 @@ inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffe
         acc->sparse->valuesByteOffset = 0;
         acc->sparse->valuesByteOffset = 0;
         acc->WriteSparseValues(nzCount, nzDiff, numCompsIn * bytesPerComp);
         acc->WriteSparseValues(nzCount, nzDiff, numCompsIn * bytesPerComp);
 
 
-        //clear
-        delete[](char *) nzDiff;
-        delete[](char *) nzIdx;
+        // clear
+        delete[] (char *)nzDiff;
+        delete[] (char *)nzIdx;
     }
     }
     return acc;
     return acc;
 }
 }
@@ -599,7 +599,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
                 if (curTex != nullptr) { // embedded
                 if (curTex != nullptr) { // embedded
                     texture->source->name = curTex->mFilename.C_Str();
                     texture->source->name = curTex->mFilename.C_Str();
 
 
-                    //basisu: embedded ktx2, bu
+                    // basisu: embedded ktx2, bu
                     if (curTex->achFormatHint[0]) {
                     if (curTex->achFormatHint[0]) {
                         std::string mimeType = "image/";
                         std::string mimeType = "image/";
                         if (memcmp(curTex->achFormatHint, "jpg", 3) == 0)
                         if (memcmp(curTex->achFormatHint, "jpg", 3) == 0)
@@ -619,7 +619,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
                     }
                     }
 
 
                     // The asset has its own buffer, see Image::SetData
                     // The asset has its own buffer, see Image::SetData
-                    //basisu: "image/ktx2", "image/basis" as is
+                    // basisu: "image/ktx2", "image/basis" as is
                     texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
                     texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
                 } else {
                 } else {
                     texture->source->uri = path;
                     texture->source->uri = path;
@@ -629,7 +629,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
                     }
                     }
                 }
                 }
 
 
-                //basisu
+                // basisu
                 if (useBasisUniversal) {
                 if (useBasisUniversal) {
                     mAsset->extensionsUsed.KHR_texture_basisu = true;
                     mAsset->extensionsUsed.KHR_texture_basisu = true;
                     mAsset->extensionsRequired.KHR_texture_basisu = true;
                     mAsset->extensionsRequired.KHR_texture_basisu = true;
@@ -652,7 +652,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, ai
     GetMatTex(mat, texture, prop.texCoord, tt, slot);
     GetMatTex(mat, texture, prop.texCoord, tt, slot);
 
 
     if (texture) {
     if (texture) {
-        //GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
+        // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
         GetMatTexProp(mat, prop.scale, "scale", tt, slot);
         GetMatTexProp(mat, prop.scale, "scale", tt, slot);
     }
     }
 }
 }
@@ -663,7 +663,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, OcclusionTextureInfo &prop,
     GetMatTex(mat, texture, prop.texCoord, tt, slot);
     GetMatTex(mat, texture, prop.texCoord, tt, slot);
 
 
     if (texture) {
     if (texture) {
-        //GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
+        // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
         GetMatTexProp(mat, prop.strength, "strength", tt, slot);
         GetMatTexProp(mat, prop.strength, "strength", tt, slot);
     }
     }
 }
 }
@@ -832,20 +832,30 @@ void glTF2Exporter::ExportMaterials() {
         GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_BASE_COLOR);
         GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_BASE_COLOR);
 
 
         if (!m->pbrMetallicRoughness.baseColorTexture.texture) {
         if (!m->pbrMetallicRoughness.baseColorTexture.texture) {
-            //if there wasn't a baseColorTexture defined in the source, fallback to any diffuse texture
+            // if there wasn't a baseColorTexture defined in the source, fallback to any diffuse texture
             GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE);
             GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE);
         }
         }
 
 
-        GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
+        GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_DIFFUSE_ROUGHNESS);
+
+        if (!m->pbrMetallicRoughness.metallicRoughnessTexture.texture) {
+            // if there wasn't a aiTextureType_DIFFUSE_ROUGHNESS defined in the source, fallback to aiTextureType_METALNESS
+            GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_METALNESS);
+        }
+
+        if (!m->pbrMetallicRoughness.metallicRoughnessTexture.texture) {
+            // if there still wasn't a aiTextureType_METALNESS defined in the source, fallback to AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE
+            GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
+        }
 
 
         if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_BASE_COLOR) != AI_SUCCESS) {
         if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_BASE_COLOR) != AI_SUCCESS) {
             // if baseColorFactor wasn't defined, then the source is likely not a metallic roughness material.
             // if baseColorFactor wasn't defined, then the source is likely not a metallic roughness material.
-            //a fallback to any diffuse color should be used instead
+            // a fallback to any diffuse color should be used instead
             GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
             GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
         }
         }
 
 
         if (mat.Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
         if (mat.Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
-            //if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0
+            // if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0
             m->pbrMetallicRoughness.metallicFactor = 0;
             m->pbrMetallicRoughness.metallicFactor = 0;
         }
         }
 
 
@@ -858,10 +868,10 @@ void glTF2Exporter::ExportMaterials() {
             if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
             if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
                 // convert specular color to luminance
                 // convert specular color to luminance
                 float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
                 float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
-                //normalize shininess (assuming max is 1000) with an inverse exponentional curve
+                // normalize shininess (assuming max is 1000) with an inverse exponentional curve
                 float normalizedShininess = std::sqrt(shininess / 1000);
                 float normalizedShininess = std::sqrt(shininess / 1000);
 
 
-                //clamp the shininess value between 0 and 1
+                // clamp the shininess value between 0 and 1
                 normalizedShininess = std::min(std::max(normalizedShininess, 0.0f), 1.0f);
                 normalizedShininess = std::min(std::max(normalizedShininess, 0.0f), 1.0f);
                 // low specular intensity values should produce a rough material even if shininess is high.
                 // low specular intensity values should produce a rough material even if shininess is high.
                 normalizedShininess = normalizedShininess * specularIntensity;
                 normalizedShininess = normalizedShininess * specularIntensity;
@@ -1059,7 +1069,7 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
                 if (boneIndexFitted != -1) {
                 if (boneIndexFitted != -1) {
                     vertexJointData[vertexId][boneIndexFitted] = static_cast<float>(jointNamesIndex);
                     vertexJointData[vertexId][boneIndexFitted] = static_cast<float>(jointNamesIndex);
                 }
                 }
-            }else {
+            } else {
                 vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
                 vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
                 vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
                 vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
 
 
@@ -1071,7 +1081,7 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
 
 
     Mesh::Primitive &p = meshRef->primitives.back();
     Mesh::Primitive &p = meshRef->primitives.back();
     Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
     Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
-        vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
+            vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
     if (vertexJointAccessor) {
     if (vertexJointAccessor) {
         size_t offset = vertexJointAccessor->bufferView->byteOffset;
         size_t offset = vertexJointAccessor->bufferView->byteOffset;
         size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
         size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
@@ -1155,7 +1165,7 @@ void glTF2Exporter::ExportMeshes() {
 
 
         /******************* Vertices ********************/
         /******************* Vertices ********************/
         Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3,
         Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3,
-            AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
+                AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
         if (v) {
         if (v) {
             p.attributes.position.push_back(v);
             p.attributes.position.push_back(v);
         }
         }
@@ -1169,7 +1179,7 @@ void glTF2Exporter::ExportMeshes() {
         }
         }
 
 
         Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3,
         Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3,
-            AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
+                AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
         if (n) {
         if (n) {
             p.attributes.normal.push_back(n);
             p.attributes.normal.push_back(n);
         }
         }
@@ -1191,7 +1201,7 @@ void glTF2Exporter::ExportMeshes() {
                 AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
                 AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
 
 
                 Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i],
                 Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i],
-                    AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
+                        AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
                 if (tc) {
                 if (tc) {
                     p.attributes.texcoord.push_back(tc);
                     p.attributes.texcoord.push_back(tc);
                 }
                 }
@@ -1201,7 +1211,7 @@ void glTF2Exporter::ExportMeshes() {
         /*************** Vertex colors ****************/
         /*************** Vertex colors ****************/
         for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
         for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
             Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel],
             Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel],
-                AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
+                    AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
             if (c) {
             if (c) {
                 p.attributes.color.push_back(c);
                 p.attributes.color.push_back(c);
             }
             }
@@ -1219,7 +1229,7 @@ void glTF2Exporter::ExportMeshes() {
             }
             }
 
 
             p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR,
             p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR,
-                ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
+                    ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
         }
         }
 
 
         switch (aim->mPrimitiveTypes) {
         switch (aim->mPrimitiveTypes) {
@@ -1362,24 +1372,24 @@ void glTF2Exporter::MergeMeshes() {
 
 
         unsigned int nMeshes = static_cast<unsigned int>(node->meshes.size());
         unsigned int nMeshes = static_cast<unsigned int>(node->meshes.size());
 
 
-        //skip if it's 1 or less meshes per node
+        // skip if it's 1 or less meshes per node
         if (nMeshes > 1) {
         if (nMeshes > 1) {
             Ref<Mesh> firstMesh = node->meshes.at(0);
             Ref<Mesh> firstMesh = node->meshes.at(0);
 
 
-            //loop backwards to allow easy removal of a mesh from a node once it's merged
+            // loop backwards to allow easy removal of a mesh from a node once it's merged
             for (unsigned int m = nMeshes - 1; m >= 1; --m) {
             for (unsigned int m = nMeshes - 1; m >= 1; --m) {
                 Ref<Mesh> mesh = node->meshes.at(m);
                 Ref<Mesh> mesh = node->meshes.at(m);
 
 
-                //append this mesh's primitives to the first mesh's primitives
+                // append this mesh's primitives to the first mesh's primitives
                 firstMesh->primitives.insert(
                 firstMesh->primitives.insert(
                         firstMesh->primitives.end(),
                         firstMesh->primitives.end(),
                         mesh->primitives.begin(),
                         mesh->primitives.begin(),
                         mesh->primitives.end());
                         mesh->primitives.end());
 
 
-                //remove the mesh from the list of meshes
+                // remove the mesh from the list of meshes
                 unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str());
                 unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str());
 
 
-                //find the presence of the removed mesh in other nodes
+                // find the presence of the removed mesh in other nodes
                 for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) {
                 for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) {
                     Ref<Node> curNode = mAsset->nodes.Get(nn);
                     Ref<Node> curNode = mAsset->nodes.Get(nn);
 
 
@@ -1398,7 +1408,7 @@ void glTF2Exporter::MergeMeshes() {
                 }
                 }
             }
             }
 
 
-            //since we were looping backwards, reverse the order of merged primitives to their original order
+            // since we were looping backwards, reverse the order of merged primitives to their original order
             std::reverse(firstMesh->primitives.begin() + 1, firstMesh->primitives.end());
             std::reverse(firstMesh->primitives.begin() + 1, firstMesh->primitives.end());
         }
         }
     }
     }
@@ -1430,7 +1440,7 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) {
     return node.GetIndex();
     return node.GetIndex();
 }
 }
 
 
- /*
+/*
  * Export node and recursively calls ExportNode for all children.
  * Export node and recursively calls ExportNode for all children.
  * Since these nodes are not the root node, we also export the parent Ref<Node>
  * Since these nodes are not the root node, we also export the parent Ref<Node>
  */
  */
@@ -1525,9 +1535,9 @@ inline void ExtractTranslationSampler(Asset &asset, std::string &animId, Ref<Buf
         const aiVectorKey &key = nodeChannel->mPositionKeys[i];
         const aiVectorKey &key = nodeChannel->mPositionKeys[i];
         // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
         // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
         times[i] = static_cast<float>(key.mTime / ticksPerSecond);
         times[i] = static_cast<float>(key.mTime / ticksPerSecond);
-        values[(i * 3) + 0] = (ai_real) key.mValue.x;
-        values[(i * 3) + 1] = (ai_real) key.mValue.y;
-        values[(i * 3) + 2] = (ai_real) key.mValue.z;
+        values[(i * 3) + 0] = (ai_real)key.mValue.x;
+        values[(i * 3) + 1] = (ai_real)key.mValue.y;
+        values[(i * 3) + 2] = (ai_real)key.mValue.z;
     }
     }
 
 
     sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
     sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
@@ -1544,9 +1554,9 @@ inline void ExtractScaleSampler(Asset &asset, std::string &animId, Ref<Buffer> &
         const aiVectorKey &key = nodeChannel->mScalingKeys[i];
         const aiVectorKey &key = nodeChannel->mScalingKeys[i];
         // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
         // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
         times[i] = static_cast<float>(key.mTime / ticksPerSecond);
         times[i] = static_cast<float>(key.mTime / ticksPerSecond);
-        values[(i * 3) + 0] = (ai_real) key.mValue.x;
-        values[(i * 3) + 1] = (ai_real) key.mValue.y;
-        values[(i * 3) + 2] = (ai_real) key.mValue.z;
+        values[(i * 3) + 0] = (ai_real)key.mValue.x;
+        values[(i * 3) + 1] = (ai_real)key.mValue.y;
+        values[(i * 3) + 2] = (ai_real)key.mValue.z;
     }
     }
 
 
     sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
     sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
@@ -1563,10 +1573,10 @@ inline void ExtractRotationSampler(Asset &asset, std::string &animId, Ref<Buffer
         const aiQuatKey &key = nodeChannel->mRotationKeys[i];
         const aiQuatKey &key = nodeChannel->mRotationKeys[i];
         // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
         // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
         times[i] = static_cast<float>(key.mTime / ticksPerSecond);
         times[i] = static_cast<float>(key.mTime / ticksPerSecond);
-        values[(i * 4) + 0] = (ai_real) key.mValue.x;
-        values[(i * 4) + 1] = (ai_real) key.mValue.y;
-        values[(i * 4) + 2] = (ai_real) key.mValue.z;
-        values[(i * 4) + 3] = (ai_real) key.mValue.w;
+        values[(i * 4) + 0] = (ai_real)key.mValue.x;
+        values[(i * 4) + 1] = (ai_real)key.mValue.y;
+        values[(i * 4) + 2] = (ai_real)key.mValue.z;
+        values[(i * 4) + 3] = (ai_real)key.mValue.w;
     }
     }
 
 
     sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
     sampler.input = GetSamplerInputRef(asset, animId, buffer, times);

+ 2 - 1
code/AssetLib/glTF2/glTF2Importer.cpp

@@ -234,7 +234,8 @@ inline void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
     SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot);
     SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot);
 
 
     if (prop.texture && prop.texture->source) {
     if (prop.texture && prop.texture->source) {
-        mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot));
+        std::string textureStrengthKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + "strength";
+        mat->AddProperty(&prop.strength, 1, textureStrengthKey.c_str(), texType, texSlot);
     }
     }
 }
 }
 
 

+ 20 - 16
code/CMakeLists.txt

@@ -1418,25 +1418,29 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
       COMPILE_PDB_NAME assimp${LIBRARY_SUFFIX}
       COMPILE_PDB_NAME assimp${LIBRARY_SUFFIX}
       COMPILE_PDB_NAME_DEBUG assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}
       COMPILE_PDB_NAME_DEBUG assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}
     )
     )
-  ENDIF()
 
 
-  IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
-    install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
-      DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-      CONFIGURATIONS Debug
-    )
-    install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb
-      DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-      CONFIGURATIONS RelWithDebInfo
-    )
+    IF(GENERATOR_IS_MULTI_CONFIG)
+      install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
+        DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+        CONFIGURATIONS Debug
+      )
+      install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb
+        DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+        CONFIGURATIONS RelWithDebInfo
+      )
+    ELSE()
+      install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
+        DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+        CONFIGURATIONS Debug
+      )
+      install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}.pdb
+        DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+        CONFIGURATIONS RelWithDebInfo
+      )
+    ENDIF()
   ELSE()
   ELSE()
-    install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
-      DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-      CONFIGURATIONS Debug
-    )
-    install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}.pdb
+    install(FILES $<TARGET_PDB_FILE:assimp>
       DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
       DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-      CONFIGURATIONS RelWithDebInfo
     )
     )
   ENDIF()
   ENDIF()
 ENDIF ()
 ENDIF ()

+ 7 - 2
contrib/openddlparser/CMakeLists.txt

@@ -15,9 +15,11 @@ option( DDL_STATIC_LIBRARY		"Deprecated, use BUILD_SHARED_LIBS instead."
 # for backwards compatibility use DDL_STATIC_LIBRARY as initial value for cmake variable BUILD_SHARED_LIBS
 # for backwards compatibility use DDL_STATIC_LIBRARY as initial value for cmake variable BUILD_SHARED_LIBS
 # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
 # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
 if ( DDL_STATIC_LIBRARY )
 if ( DDL_STATIC_LIBRARY )
-    set ( build_shared_libs_default OFF )
+  message("Building shared lib.")
+  set ( build_shared_libs_default OFF )
 else()
 else()
-    set ( build_shared_libs_default ON )
+  message("Building static lib.")
+  set ( build_shared_libs_default ON )
 endif()
 endif()
 option( DDL_BUILD_SHARED_LIBS   "Set to ON to build shared libary of OpenDDL Parser."                         ${build_shared_libs_default} )
 option( DDL_BUILD_SHARED_LIBS   "Set to ON to build shared libary of OpenDDL Parser."                         ${build_shared_libs_default} )
 option( COVERALLS               "Generate coveralls data"                                                     OFF )
 option( COVERALLS               "Generate coveralls data"                                                     OFF )
@@ -36,6 +38,7 @@ endif()
 add_definitions( -D_VARIADIC_MAX=10 )
 add_definitions( -D_VARIADIC_MAX=10 )
 add_definitions( -DGTEST_HAS_PTHREAD=0 )
 add_definitions( -DGTEST_HAS_PTHREAD=0 )
 if ( DDL_DEBUG_OUTPUT )
 if ( DDL_DEBUG_OUTPUT )
+    message("Enable debug output.")
     add_definitions( -DDDL_DEBUG_HEADER_NAME)
     add_definitions( -DDDL_DEBUG_HEADER_NAME)
 endif()
 endif()
 
 
@@ -62,10 +65,12 @@ if (COVERALLS)
     include(Coveralls)
     include(Coveralls)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
+    message("Enable coveralls.")
 endif()
 endif()
 
 
 # Include the doc component.
 # Include the doc component.
 if(DDL_DOCUMENTATION)
 if(DDL_DOCUMENTATION)
+    message("Generate doxygen documentation.")
     find_package(Doxygen REQUIRED)
     find_package(Doxygen REQUIRED)
     CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
     CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
     add_custom_target(doc ALL
     add_custom_target(doc ALL

+ 16 - 11
contrib/openddlparser/README.md

@@ -5,13 +5,15 @@ The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-pa
 
 
 Build status
 Build status
 ============
 ============
-Linux build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
+
+Linux build status: [![Build Status](https://travis-ci.com/kimkulling/openddl-parser.svg?branch=master)](https://travis-ci.com/kimkulling/openddl-parser)
 Current coverity check status:
 Current coverity check status:
 <a href="https://scan.coverity.com/projects/5606">
 <a href="https://scan.coverity.com/projects/5606">
   <img alt="Coverity Scan Build Status"
   <img alt="Coverity Scan Build Status"
        src="https://scan.coverity.com/projects/5606/badge.svg"/>
        src="https://scan.coverity.com/projects/5606/badge.svg"/>
 </a>
 </a>
 Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
 Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
+
 Get the source code
 Get the source code
 ===================
 ===================
 You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
 You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
@@ -57,11 +59,11 @@ USE_ODDLPARSER_NS;
 
 
 int main( int argc, char *argv[] ) {
 int main( int argc, char *argv[] ) {
     if( argc < 3 ) {
     if( argc < 3 ) {
-        return 1;
+        return Error;
     }
     }
 
 
     char *filename( nullptr );
     char *filename( nullptr );
-    if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) {
+    if( 0 == strncmp( FileOption, argv[1], strlen( FileOption ) ) ) {
         filename = argv[ 2 ];
         filename = argv[ 2 ];
     }
     }
     std::cout << "file to import: " << filename << std::endl;   
     std::cout << "file to import: " << filename << std::endl;   
@@ -73,24 +75,27 @@ int main( int argc, char *argv[] ) {
     FILE *fileStream = fopen( filename, "r+" );
     FILE *fileStream = fopen( filename, "r+" );
     if( NULL == filename ) {
     if( NULL == filename ) {
         std::cerr << "Cannot open file " << filename << std::endl;
         std::cerr << "Cannot open file " << filename << std::endl;
-        return 1;
+        return Error;
     }
     }
 
 
     // obtain file size:
     // obtain file size:
     fseek( fileStream, 0, SEEK_END );
     fseek( fileStream, 0, SEEK_END );
-    const size_t size( ftell( fileStream ) );   
+    const size_t size = ftell( fileStream );   
     rewind( fileStream );   
     rewind( fileStream );   
     if( size > 0 ) {
     if( size > 0 ) {
         char *buffer = new char[ size ];
         char *buffer = new char[ size ];
-        const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) );
+        const size_t readSize = fread( buffer, sizeof( char ), size, fileStream );
         assert( readSize == size );
         assert( readSize == size );
+
+        // Set the memory buffer
         OpenDDLParser theParser;
         OpenDDLParser theParser;
         theParser.setBuffer( buffer, size );
         theParser.setBuffer( buffer, size );
-        const bool result( theParser.parse() );
-        if( !result ) {
+        if( !theParser.parse() ) {
             std::cerr << "Error while parsing file " << filename << "." << std::endl;
             std::cerr << "Error while parsing file " << filename << "." << std::endl;
+            return Error;
         }
         }
     }
     }
+  
     return 0;
     return 0;
 }
 }
 
 
@@ -106,9 +111,9 @@ theParser.setBuffer( buffer, size );
 const bool result( theParser.parse() );
 const bool result( theParser.parse() );
 if ( result ) {
 if ( result ) {
     DDLNode *root = theParser.getRoot();
     DDLNode *root = theParser.getRoot();
-    DDLNode::DllNodeList childs = root->getChildNodeList();
-    for ( size_t i=0; i<childs.size(); i++ ) {
-        DDLNode *child = childs[ i ];
+    DDLNode::DllNodeList children = root->getChildNodeList();
+    for ( size_t i=0; i<children.size(); i++ ) {
+        DDLNode *child = children[ i ];
         Property *prop   = child->getProperty(); // to get properties
         Property *prop   = child->getProperty(); // to get properties
         std::string type = child->getType();     // to get the node type
         std::string type = child->getType();     // to get the node type
         Value *values    = child->getValue();    // to get the data;
         Value *values    = child->getValue();    // to get the data;

+ 3 - 2
contrib/openddlparser/code/OpenDDLExport.cpp

@@ -134,9 +134,10 @@ bool OpenDDLExport::writeToStream(const std::string &statement) {
 }
 }
 
 
 bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
 bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
+    bool success(true);
     writeNodeHeader(node, statement);
     writeNodeHeader(node, statement);
     if (node->hasProperties()) {
     if (node->hasProperties()) {
-        writeProperties(node, statement);
+        success = writeProperties(node, statement);
     }
     }
     writeLineEnd(statement);
     writeLineEnd(statement);
 
 
@@ -160,7 +161,7 @@ bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
 
 
     writeToStream(statement);
     writeToStream(statement);
 
 
-    return true;
+    return success;
 }
 }
 
 
 bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) {
 bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) {

+ 44 - 25
contrib/openddlparser/code/OpenDDLParser.cpp

@@ -30,7 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <sstream>
 #include <sstream>
 
 
 #ifdef _WIN32
 #ifdef _WIN32
-#include <windows.h>
+#   ifndef WIN32_LEAN_AND_MEAN
+#     define WIN32_LEAN_AND_MEAN
+#   endif
+#   include <windows.h>
 #endif // _WIN32
 #endif // _WIN32
 
 
 BEGIN_ODDLPARSER_NS
 BEGIN_ODDLPARSER_NS
@@ -71,7 +74,7 @@ const char *getTypeToken(Value::ValueType type) {
     return Grammar::PrimitiveTypeToken[(size_t)type];
     return Grammar::PrimitiveTypeToken[(size_t)type];
 }
 }
 
 
-static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
+static void logInvalidTokenError(const char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
     if (callback) {
     if (callback) {
         std::string full(in);
         std::string full(in);
         std::string part(full.substr(0, 50));
         std::string part(full.substr(0, 50));
@@ -338,20 +341,25 @@ char *OpenDDLParser::parseStructure(char *in, char *end) {
 
 
     bool error(false);
     bool error(false);
     in = lookForNextToken(in, end);
     in = lookForNextToken(in, end);
-    if (*in == *Grammar::OpenBracketToken) {
-        // loop over all children ( data and nodes )
-        do {
-            in = parseStructureBody(in, end, error);
-            if (in == nullptr) {
-                return nullptr;
+    if (in != end) {
+        if (*in == *Grammar::OpenBracketToken) {
+            // loop over all children ( data and nodes )
+            do {
+                in = parseStructureBody(in, end, error);
+                if (in == nullptr) {
+                    return nullptr;
+                }
+            } while (in  != end &&
+                     *in != *Grammar::CloseBracketToken);
+            if (in != end) {
+                ++in;
             }
             }
-        } while (*in != *Grammar::CloseBracketToken);
-        ++in;
-    } else {
-        ++in;
-        logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback);
-        error = true;
-        return nullptr;
+        } else {
+            ++in;
+            logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback);
+            error = true;
+            return nullptr;
+        }
     }
     }
     in = lookForNextToken(in, end);
     in = lookForNextToken(in, end);
 
 
@@ -418,8 +426,8 @@ char *OpenDDLParser::parseStructureBody(char *in, char *end, bool &error) {
         }
         }
 
 
         in = lookForNextToken(in, end);
         in = lookForNextToken(in, end);
-        if (*in != '}') {
-            logInvalidTokenError(in, std::string(Grammar::CloseBracketToken), m_logCallback);
+        if (in == end || *in != '}') {
+            logInvalidTokenError(in == end ? "" : in, std::string(Grammar::CloseBracketToken), m_logCallback);
             return nullptr;
             return nullptr;
         } else {
         } else {
             //in++;
             //in++;
@@ -455,7 +463,7 @@ DDLNode *OpenDDLParser::top() {
         return nullptr;
         return nullptr;
     }
     }
 
 
-    DDLNode *top(m_stack.back());
+    DDLNode *top = m_stack.back();
     return top;
     return top;
 }
 }
 
 
@@ -647,12 +655,15 @@ char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) {
 
 
     in = lookForNextToken(in, end);
     in = lookForNextToken(in, end);
     char *start(in);
     char *start(in);
+
+    size_t len(0);
     while (!isSeparator(*in) && in != end) {
     while (!isSeparator(*in) && in != end) {
         ++in;
         ++in;
+        ++len;
     }
     }
-    int res = ::strncmp(Grammar::BoolTrue, start, strlen(Grammar::BoolTrue));
+    int res = ::strncmp(Grammar::BoolTrue, start, len);
     if (0 != res) {
     if (0 != res) {
-        res = ::strncmp(Grammar::BoolFalse, start, strlen(Grammar::BoolFalse));
+        res = ::strncmp(Grammar::BoolFalse, start, len);
         if (0 != res) {
         if (0 != res) {
             *boolean = nullptr;
             *boolean = nullptr;
             return in;
             return in;
@@ -733,7 +744,7 @@ char *OpenDDLParser::parseFloatingLiteral(char *in, char *end, Value **floating,
 
 
     in = lookForNextToken(in, end);
     in = lookForNextToken(in, end);
     char *start(in);
     char *start(in);
-    while (!isSeparator(*in) && in != end) {
+    while (in != end && !isSeparator(*in)) {
         ++in;
         ++in;
     }
     }
 
 
@@ -838,6 +849,13 @@ char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) {
     int value(0);
     int value(0);
     while (pos > 0) {
     while (pos > 0) {
         int v = hex2Decimal(*start);
         int v = hex2Decimal(*start);
+        if (v < 0) {
+            while (isEndofLine(*in)) {
+                ++in;
+            }
+            return in;
+        }
+            
         --pos;
         --pos;
         value = (value << 4) | v;
         value = (value << 4) | v;
         ++start;
         ++start;
@@ -901,10 +919,10 @@ char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, V
     }
     }
 
 
     in = lookForNextToken(in, end);
     in = lookForNextToken(in, end);
-    if (*in == '{') {
+    if (in != end && *in == '{') {
         ++in;
         ++in;
         Value *current(nullptr), *prev(nullptr);
         Value *current(nullptr), *prev(nullptr);
-        while ('}' != *in) {
+        while (in != end && '}' != *in) {
             current = nullptr;
             current = nullptr;
             in = lookForNextToken(in, end);
             in = lookForNextToken(in, end);
             if (Value::ValueType::ddl_ref == type) {
             if (Value::ValueType::ddl_ref == type) {
@@ -962,11 +980,12 @@ char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, V
             }
             }
 
 
             in = getNextSeparator(in, end);
             in = getNextSeparator(in, end);
-            if (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in)) {
+            if (in == end || (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in))) {
                 break;
                 break;
             }
             }
         }
         }
-        ++in;
+        if (in != end)
+            ++in;
     }
     }
 
 
     return in;
     return in;

+ 2 - 2
contrib/openddlparser/include/openddlparser/OpenDDLCommon.h

@@ -26,8 +26,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
 #ifndef _WIN32
 #ifndef _WIN32
 #include <inttypes.h>
 #include <inttypes.h>
 #endif
 #endif

+ 0 - 9
contrib/openddlparser/include/openddlparser/OpenDDLParser.h

@@ -40,15 +40,6 @@ struct Identifier;
 struct Reference;
 struct Reference;
 struct Property;
 struct Property;
 
 
-template <class T>
-inline bool isEmbeddedCommentOpenTag(T *in, T *end) {
-    if (in == '/' && in + 1 == '*') {
-        return true;
-    }
-
-    return false;
-}
-
 ///	@brief  Utility function to search for the next token or the end of the buffer.
 ///	@brief  Utility function to search for the next token or the end of the buffer.
 /// @param  in      [in] The start position in the buffer.
 /// @param  in      [in] The start position in the buffer.
 /// @param  end     [in] The end position in the buffer.
 /// @param  end     [in] The end position in the buffer.

+ 8 - 2
contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h

@@ -54,7 +54,9 @@ inline bool isSeparator(T in) {
     return false;
     return false;
 }
 }
 
 
-static const unsigned char chartype_table[256] = {
+const size_t CharTableSize = 256;
+
+static const unsigned char chartype_table[CharTableSize] = {
     0,
     0,
     0,
     0,
     0,
     0,
@@ -318,6 +320,10 @@ static const unsigned char chartype_table[256] = {
 
 
 template <class T>
 template <class T>
 inline bool isNumeric(const T in) {
 inline bool isNumeric(const T in) {
+    if (static_cast<size_t>(in) >= CharTableSize) {
+        return '\0';
+    }
+
     size_t idx = static_cast<size_t>(in);
     size_t idx = static_cast<size_t>(in);
     return idx < sizeof(chartype_table) && (chartype_table[idx] == 1);
     return idx < sizeof(chartype_table) && (chartype_table[idx] == 1);
 }
 }
@@ -433,7 +439,7 @@ inline bool isEndofLine(const T in) {
 
 
 template <class T>
 template <class T>
 inline static T *getNextSeparator(T *in, T *end) {
 inline static T *getNextSeparator(T *in, T *end) {
-    while (!isSeparator(*in) || in == end) {
+    while (in != end && !isSeparator(*in)) {
         ++in;
         ++in;
     }
     }
     return in;
     return in;

+ 3 - 1
include/assimp/XmlParser.h

@@ -302,7 +302,9 @@ bool TXmlParser<TNodeType>::parse(IOStream *stream) {
     stream->Read(&mData[0], 1, len);
     stream->Read(&mData[0], 1, len);
 
 
     mDoc = new pugi::xml_document();
     mDoc = new pugi::xml_document();
-    pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
+    // load_string assumes native encoding (aka always utf-8 per build options)
+    //pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
+     pugi::xml_parse_result parse_result = mDoc->load_buffer(&mData[0], mData.size(), pugi::parse_full);
     if (parse_result.status == pugi::status_ok) {
     if (parse_result.status == pugi::status_ok) {
         return true;
         return true;
     }
     }

+ 9 - 0
include/assimp/config.h.in

@@ -1035,6 +1035,15 @@ enum aiComponent
  */
  */
 #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
 #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
 
 
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the Collada loader will ignore the provided unit size.
+ *
+ * If this property is set to true, the unit size provided in the file header will
+ * be ignored and the file will be loaded without scaling the assets.
+ * Property type: Bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE "IMPORT_COLLADA_IGNORE_UNIT_SIZE"
+
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** @brief Specifies whether the Collada loader should use Collada names.
 /** @brief Specifies whether the Collada loader should use Collada names.
  *
  *

+ 2 - 1
include/assimp/material.inl

@@ -211,7 +211,8 @@ AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
         unsigned int idx,aiColor3D& pOut) const {
         unsigned int idx,aiColor3D& pOut) const {
     aiColor4D c;
     aiColor4D c;
     const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
     const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
-    pOut = aiColor3D(c.r,c.g,c.b);
+    if (ret == aiReturn_SUCCESS)
+        pOut = aiColor3D(c.r,c.g,c.b);
     return ret;
     return ret;
 }
 }
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------