diff --git a/Readme.md b/Readme.md
index 1af71fad8..9a8ac7c33 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,6 +1,8 @@
Open Asset Import Library (assimp)
==================================
-A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
+
+Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
+
### Current project status ###
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
@@ -22,15 +24,19 @@ Additionally, assimp features various __mesh post processing tools__: normals an
### Latest Doc's ###
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
-### Get involved ###
-This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
-
-You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
-
-Please check our Wiki as well: https://github.com/assimp/assimp/wiki
+### Prebuild binaries ###
+Please check our [Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib)
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
+### Communities ###
+- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
+- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
+- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
+- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
+
+And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
#### Supported file formats ####
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
@@ -65,28 +71,18 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
/port Ports to other languages and scripts to maintain those.
/test Unit- and regression tests, test suite of models
/tools Tools (old assimp viewer, command line `assimp`)
- /samples A small number of samples to illustrate possible
- use cases for Assimp
+ /samples A small number of samples to illustrate possible use-cases for Assimp
The source code is organized in the following way:
code/Common The base implementation for importers and the infrastructure
+ code/CApi Special implementations which are only used for the C-API
+ code/Geometry A collection of geometry tools
+ code/Material The material system
+ code/PBR An exporter for physical based models
code/PostProcessing The post-processing steps
code/AssetLib/ Implementation for import and export for the format
-### Where to get help ###
-To find our documentation, visit [our website](https://assimp.org/) or check out [Wiki](https://github.com/assimp/assimp/wiki)
-
-If the docs don't solve your problem, you can:
-- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
-- Ask on [Assimp-Community on Reddit](https://www.reddit.com/r/Assimp/)
-- Ask a question at [The Assimp-Discussion Board](https://github.com/assimp/assimp/discussions)
-- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
-
-Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
-
-And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
### Contributing ###
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
a pull request with your changes against the main repository's `master` branch.
diff --git a/code/AssetLib/B3D/B3DImporter.cpp b/code/AssetLib/B3D/B3DImporter.cpp
index e87744603..bf8145798 100644
--- a/code/AssetLib/B3D/B3DImporter.cpp
+++ b/code/AssetLib/B3D/B3DImporter.cpp
@@ -418,7 +418,6 @@ void B3DImporter::ReadTRIS(int v0) {
ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
#endif
Fail("Bad triangle index");
- continue;
}
face->mNumIndices = 3;
face->mIndices = new unsigned[3];
diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp
index f1f57c10b..d742af447 100644
--- a/code/AssetLib/FBX/FBXConverter.cpp
+++ b/code/AssetLib/FBX/FBXConverter.cpp
@@ -152,7 +152,7 @@ void FBXConverter::ConvertRootNode() {
mSceneOut->mRootNode->mName.Set(unique_name);
// root has ID 0
- ConvertNodes(0L, mSceneOut->mRootNode, mSceneOut->mRootNode);
+ ConvertNodes(0L, mSceneOut->mRootNode, mSceneOut->mRootNode, aiMatrix4x4());
}
static std::string getAncestorBaseName(const aiNode *node) {
@@ -196,7 +196,7 @@ struct FBXConverter::PotentialNode {
/// todo: get bone from stack
/// todo: make map of aiBone* to aiNode*
/// then update convert clusters to the new format
-void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
+void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &globalTransform) {
const std::vector &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
std::vector nodes;
@@ -290,14 +290,15 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
}
// recursion call - child nodes
- ConvertNodes(model->ID(), last_parent, root_node);
+ aiMatrix4x4 newGlobalMatrix = globalTransform * nodes_chain.front().mNode->mTransformation;
+ ConvertNodes(model->ID(), last_parent, root_node, newGlobalMatrix);
if (doc.Settings().readLights) {
ConvertLights(*model, node_name);
}
if (doc.Settings().readCameras) {
- ConvertCameras(*model, node_name);
+ ConvertCameras(*model, node_name, newGlobalMatrix);
}
nodes.push_back(std::move(nodes_chain.front()));
@@ -327,12 +328,14 @@ void FBXConverter::ConvertLights(const Model &model, const std::string &orig_nam
}
}
-void FBXConverter::ConvertCameras(const Model &model, const std::string &orig_name) {
+void FBXConverter::ConvertCameras(const Model &model,
+ const std::string &orig_name,
+ const aiMatrix4x4 &transform) {
const std::vector &node_attrs = model.GetAttributes();
for (const NodeAttribute *attr : node_attrs) {
const Camera *const cam = dynamic_cast(attr);
if (cam) {
- ConvertCamera(*cam, orig_name);
+ ConvertCamera(*cam, orig_name, transform);
}
}
}
@@ -413,7 +416,9 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name
}
}
-void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name) {
+void FBXConverter::ConvertCamera(const Camera &cam,
+ const std::string &orig_name,
+ aiMatrix4x4 transform) {
cameras.push_back(new aiCamera());
aiCamera *const out_camera = cameras.back();
@@ -421,9 +426,16 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
+ aiVector3D pos = cam.Position();
+ out_camera->mLookAt = cam.InterestPosition();
+ out_camera->mUp = pos + cam.UpVector();
+ transform.Inverse();
+ pos *= transform;
+ out_camera->mLookAt *= transform;
+ out_camera->mUp *= transform;
+ out_camera->mLookAt -= pos;
+ out_camera->mUp -= pos;
out_camera->mPosition = aiVector3D(0.0f);
- out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
- out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
@@ -640,7 +652,7 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
const PropertyTable &props = model.Props();
- const auto zero_epsilon = ai_epsilon;
+ const auto zero_epsilon = Math::getEpsilon();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
const TransformationComp comp = static_cast(i);
diff --git a/code/AssetLib/FBX/FBXConverter.h b/code/AssetLib/FBX/FBXConverter.h
index 41acb6ffe..b9b6c46b0 100644
--- a/code/AssetLib/FBX/FBXConverter.h
+++ b/code/AssetLib/FBX/FBXConverter.h
@@ -134,19 +134,22 @@ private:
// ------------------------------------------------------------------------------------------------
// collect and assign child nodes
- void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
+ void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &globalTransform);
// ------------------------------------------------------------------------------------------------
void ConvertLights(const Model& model, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------
- void ConvertCameras(const Model& model, const std::string &orig_name );
+ void ConvertCameras(const Model& model, const std::string &orig_name,
+ const aiMatrix4x4 &transform);
// ------------------------------------------------------------------------------------------------
void ConvertLight( const Light& light, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------
- void ConvertCamera( const Camera& cam, const std::string &orig_name );
+ void ConvertCamera(const Camera& cam, const std::string &orig_name,
+ aiMatrix4x4 transform);
// ------------------------------------------------------------------------------------------------
void GetUniqueName( const std::string &name, std::string& uniqueName );
diff --git a/code/AssetLib/LWO/LWOMaterial.cpp b/code/AssetLib/LWO/LWOMaterial.cpp
index 50bac884b..8d83dfb67 100644
--- a/code/AssetLib/LWO/LWOMaterial.cpp
+++ b/code/AssetLib/LWO/LWOMaterial.cpp
@@ -345,7 +345,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface &surf, aiMaterial *pcMat) {
// (the diffuse value is just a scaling factor)
// If a diffuse texture is set, we set this value to 1.0
- clr = (b && false ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
+ clr = (b ? aiColor3D(1.0, 1.0, 1.0) : surf.mColor);
clr.r *= surf.mDiffuseValue;
clr.g *= surf.mDiffuseValue;
clr.b *= surf.mDiffuseValue;
diff --git a/code/AssetLib/glTF/glTFAsset.h b/code/AssetLib/glTF/glTFAsset.h
index d2ae84b49..b5e6375ad 100644
--- a/code/AssetLib/glTF/glTFAsset.h
+++ b/code/AssetLib/glTF/glTFAsset.h
@@ -513,21 +513,22 @@ struct Camera : public Object {
};
Type type;
+ struct Perspective {
+ float aspectRatio; //!
- void ExtractData(T *&outData);
+ size_t ExtractData(T *&outData, const std::vector *remappingIndices = nullptr);
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
void WriteSparseValues(size_t count, const void *src_data, size_t src_dataStride);
diff --git a/code/AssetLib/glTF2/glTF2Asset.inl b/code/AssetLib/glTF2/glTF2Asset.inl
index 3a3ba376e..da5ef182b 100644
--- a/code/AssetLib/glTF2/glTF2Asset.inl
+++ b/code/AssetLib/glTF2/glTF2Asset.inl
@@ -962,14 +962,15 @@ inline size_t Accessor::GetMaxByteSize() {
}
template
-void Accessor::ExtractData(T *&outData) {
+size_t Accessor::ExtractData(T *&outData, const std::vector *remappingIndices) {
uint8_t *data = GetPointer();
if (!data) {
throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
}
+ const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
const size_t elemSize = GetElementSize();
- const size_t totalSize = elemSize * count;
+ const size_t totalSize = elemSize * usedCount;
const size_t stride = GetStride();
@@ -980,18 +981,31 @@ void Accessor::ExtractData(T *&outData) {
}
const size_t maxSize = GetMaxByteSize();
- if (count * stride > maxSize) {
- throw DeadlyImportError("GLTF: count*stride ", (count * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
- }
- outData = new T[count];
- if (stride == elemSize && targetElemSize == elemSize) {
- memcpy(outData, data, totalSize);
- } else {
- for (size_t i = 0; i < count; ++i) {
- memcpy(outData + i, data + i * stride, elemSize);
+ outData = new T[usedCount];
+
+ if (remappingIndices != nullptr) {
+ const unsigned int maxIndex = static_cast(maxSize / stride - 1);
+ for (size_t i = 0; i < usedCount; ++i) {
+ size_t srcIdx = (*remappingIndices)[i];
+ if (srcIdx > maxIndex) {
+ throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
+ }
+ memcpy(outData + i, data + srcIdx * stride, elemSize);
+ }
+ } else { // non-indexed cases
+ if (usedCount * stride > maxSize) {
+ throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
+ }
+ if (stride == elemSize && targetElemSize == elemSize) {
+ memcpy(outData, data, totalSize);
+ } else {
+ for (size_t i = 0; i < usedCount; ++i) {
+ memcpy(outData + i, data + i * stride, elemSize);
+ }
}
}
+ return usedCount;
}
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {
diff --git a/code/AssetLib/glTF2/glTF2Importer.cpp b/code/AssetLib/glTF2/glTF2Importer.cpp
index 4a3ee4928..39499bcde 100644
--- a/code/AssetLib/glTF2/glTF2Importer.cpp
+++ b/code/AssetLib/glTF2/glTF2Importer.cpp
@@ -464,6 +464,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
unsigned int k = 0;
meshOffsets.clear();
+
+ std::vector usedVertexIndices;
+ std::vector reverseMappingIndices;
+ std::vector indexBuffer;
+
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
Mesh &mesh = r.meshes[m];
@@ -473,6 +478,50 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
Mesh::Primitive &prim = mesh.primitives[p];
+ Mesh::Primitive::Attributes &attr = prim.attributes;
+
+ // Find out the maximum number of vertices:
+ size_t numAllVertices = 0;
+ if (!attr.position.empty() && attr.position[0]) {
+ numAllVertices = attr.position[0]->count;
+ }
+
+ // Extract used vertices:
+ bool useIndexBuffer = prim.indices;
+ std::vector* vertexRemappingTable = nullptr;
+ if (useIndexBuffer) {
+ size_t count = prim.indices->count;
+ indexBuffer.resize(count);
+ usedVertexIndices.clear();
+ reverseMappingIndices.clear();
+ usedVertexIndices.reserve(count / 3); // this is a very rough heuristic to reduce re-allocations
+ vertexRemappingTable = &usedVertexIndices;
+ Accessor::Indexer data = prim.indices->GetIndexer();
+ if (!data.IsValid()) {
+ throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
+ }
+
+ // Build the vertex remapping table and the modified index buffer (used later instead of the original one)
+ // In case no index buffer is used, the original vertex arrays are being used so no remapping is required in the first place.
+ const unsigned int unusedIndex = ~0u;
+ for (unsigned int i = 0; i < count; ++i) {
+ unsigned int index = data.GetUInt(i);
+ if (index >= numAllVertices) {
+ // Out-of-range indices will be filtered out when adding the faces and then lead to a warning. At this stage, we just keep them.
+ indexBuffer[i] = index;
+ continue;
+ }
+ if (index >= reverseMappingIndices.size()) {
+ reverseMappingIndices.resize(index + 1, unusedIndex);
+ }
+ if (reverseMappingIndices[index] == unusedIndex) {
+ reverseMappingIndices[index] = static_cast(usedVertexIndices.size());
+ usedVertexIndices.push_back(index);
+ }
+ indexBuffer[i] = reverseMappingIndices[index];
+ }
+ }
+
aiMesh *aim = new aiMesh();
meshes.push_back(std::unique_ptr(aim));
@@ -502,28 +551,25 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
break;
}
- Mesh::Primitive::Attributes &attr = prim.attributes;
-
if (!attr.position.empty() && attr.position[0]) {
- aim->mNumVertices = static_cast(attr.position[0]->count);
- attr.position[0]->ExtractData(aim->mVertices);
+ aim->mNumVertices = static_cast(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable));
}
if (!attr.normal.empty() && attr.normal[0]) {
- if (attr.normal[0]->count != aim->mNumVertices) {
+ if (attr.normal[0]->count != numAllVertices) {
DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored.");
} else {
- attr.normal[0]->ExtractData(aim->mNormals);
+ attr.normal[0]->ExtractData(aim->mNormals, vertexRemappingTable);
// only extract tangents if normals are present
if (!attr.tangent.empty() && attr.tangent[0]) {
- if (attr.tangent[0]->count != aim->mNumVertices) {
+ if (attr.tangent[0]->count != numAllVertices) {
DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored.");
} else {
// generate bitangents from normals and tangents according to spec
Tangent *tangents = nullptr;
- attr.tangent[0]->ExtractData(tangents);
+ attr.tangent[0]->ExtractData(tangents, vertexRemappingTable);
aim->mTangents = new aiVector3D[aim->mNumVertices];
aim->mBitangents = new aiVector3D[aim->mNumVertices];
@@ -540,7 +586,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
- if (attr.color[c]->count != aim->mNumVertices) {
+ if (attr.color[c]->count != numAllVertices) {
DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name,
"\" does not match the vertex count");
continue;
@@ -548,7 +594,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
auto componentType = attr.color[c]->componentType;
if (componentType == glTF2::ComponentType_FLOAT) {
- attr.color[c]->ExtractData(aim->mColors[c]);
+ attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable);
} else {
if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
aim->mColors[c] = GetVertexColorsForType(attr.color[c]);
@@ -563,13 +609,13 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
continue;
}
- if (attr.texcoord[tc]->count != aim->mNumVertices) {
+ if (attr.texcoord[tc]->count != numAllVertices) {
DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name,
"\" does not match the vertex count");
continue;
}
- attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
+ attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], vertexRemappingTable);
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
aiVector3D *values = aim->mTextureCoords[tc];
@@ -594,11 +640,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
Mesh::Primitive::Target &target = targets[i];
if (needPositions) {
- if (target.position[0]->count != aim->mNumVertices) {
+ if (target.position[0]->count != numAllVertices) {
ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
aiVector3D *positionDiff = nullptr;
- target.position[0]->ExtractData(positionDiff);
+ target.position[0]->ExtractData(positionDiff, vertexRemappingTable);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
}
@@ -606,11 +652,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
}
if (needNormals) {
- if (target.normal[0]->count != aim->mNumVertices) {
+ if (target.normal[0]->count != numAllVertices) {
ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
aiVector3D *normalDiff = nullptr;
- target.normal[0]->ExtractData(normalDiff);
+ target.normal[0]->ExtractData(normalDiff, vertexRemappingTable);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
}
@@ -621,14 +667,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
if (!aiAnimMesh.HasNormals()) {
// prevent nullptr access to aiAnimMesh.mNormals below when no normals are available
ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals.");
- } else if (target.tangent[0]->count != aim->mNumVertices) {
+ } else if (target.tangent[0]->count != numAllVertices) {
ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
} else {
Tangent *tangent = nullptr;
- attr.tangent[0]->ExtractData(tangent);
+ attr.tangent[0]->ExtractData(tangent, vertexRemappingTable);
aiVector3D *tangentDiff = nullptr;
- target.tangent[0]->ExtractData(tangentDiff);
+ target.tangent[0]->ExtractData(tangentDiff, vertexRemappingTable);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
tangent[vertexId].xyz += tangentDiff[vertexId];
@@ -652,20 +698,15 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
aiFace *facePtr = nullptr;
size_t nFaces = 0;
- if (prim.indices) {
- size_t count = prim.indices->count;
-
- Accessor::Indexer data = prim.indices->GetIndexer();
- if (!data.IsValid()) {
- throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
- }
+ if (useIndexBuffer) {
+ size_t count = indexBuffer.size();
switch (prim.mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) {
- SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i));
+ SetFaceAndAdvance1(facePtr, aim->mNumVertices, indexBuffer[i]);
}
break;
}
@@ -678,7 +719,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
- SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1));
+ SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1]);
}
break;
}
@@ -687,12 +728,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
facePtr = faces = new aiFace[nFaces];
- SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1));
+ SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1]);
for (unsigned int i = 2; i < count; ++i) {
- SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i));
+ SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i - 1], indexBuffer[i]);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
- SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast(count) - 1), faces[0].mIndices[0]);
+ SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[static_cast(count) - 1], faces[0].mIndices[0]);
}
break;
}
@@ -705,7 +746,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
}
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
- SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
+ SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
}
break;
}
@@ -716,10 +757,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
// The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i + 1) % 2 == 0) {
// For even n, vertices n + 1, n, and n + 2 define triangle n
- SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
+ SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i + 1], indexBuffer[i], indexBuffer[i + 2]);
} else {
// For odd n, vertices n, n+1, and n+2 define triangle n
- SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
+ SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
}
}
break;
@@ -727,9 +768,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
case PrimitiveMode_TRIANGLE_FAN:
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
- SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
+ SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1], indexBuffer[2]);
for (unsigned int i = 1; i < nFaces; ++i) {
- SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2));
+ SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[i + 1], indexBuffer[i + 2]);
}
break;
}
@@ -1183,11 +1224,6 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector &
if (node.camera) {
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
- if (node.translation.isPresent) {
- aiVector3D trans;
- CopyValue(node.translation.value, trans);
- pScene->mCameras[node.camera.GetIndex()]->mPosition = trans;
- }
}
if (node.light) {
diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt
index ba5415fe0..6f74823df 100644
--- a/code/CMakeLists.txt
+++ b/code/CMakeLists.txt
@@ -1195,7 +1195,67 @@ TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
IF (ASSIMP_WARNINGS_AS_ERRORS)
MESSAGE(STATUS "Treating all warnings as errors (for assimp library only)")
IF (MSVC)
- TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
+
+ IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
+ TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror
+ -Wno-unused-function
+ -Wno-microsoft-enum-value
+ -Wno-switch-enum
+ -Wno-covered-switch-default
+ -Wno-reserved-identifier
+ -Wno-c++98-compat-pedantic
+ -Wno-c++98-compat
+ -Wno-documentation
+ -Wno-documentation-unknown-command
+ -Wno-deprecated-dynamic-exception-spec
+ -Wno-undef
+ -Wno-suggest-destructor-override
+ -Wno-suggest-override
+ -Wno-inconsistent-missing-destructor-override
+ -Wno-zero-as-null-pointer-constant
+ -Wno-global-constructors
+ -Wno-exit-time-destructors
+ -Wno-extra-semi-stmt
+ -Wno-missing-prototypes
+ -Wno-old-style-cast
+ -Wno-cast-align
+ -Wno-cast-qual
+ -Wno-float-equal
+ -Wno-implicit-int-float-conversion
+ -Wno-sign-conversion
+ -Wno-implicit-float-conversion
+ -Wno-implicit-int-conversion
+ -Wno-float-conversion
+ -Wno-double-promotion
+ -Wno-unused-macros
+ -Wno-disabled-macro-expansion
+ -Wno-shadow-field
+ -Wno-shadow
+ -Wno-language-extension-token
+ -Wno-header-hygiene
+ -Wno-tautological-value-range-compare
+ -Wno-tautological-type-limit-compare
+ -Wno-missing-noreturn
+ -Wno-missing-variable-declarations
+ -Wno-extra-semi
+ -Wno-nonportable-system-include-path
+ -Wno-undefined-reinterpret-cast
+ -Wno-shift-sign-overflow
+ -Wno-deprecated-copy-with-user-provided-dtor
+ -Wno-deprecated-copy-with-dtor
+ -Wno-deprecated
+ -Wno-format-nonliteral
+ -Wno-comma
+ -Wno-unreachable-code-break
+ -Wno-unreachable-code-return
+ -Wno-implicit-fallthrough
+ -Wno-unused-template
+ -Wno-undefined-func-template
+ -Wno-declaration-after-statement
+ )
+ ELSE()
+ TARGET_COMPILE_OPTIONS(assimp PRIVATE /W4 /WX)
+ ENDIF()
ELSE()
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Wall -Werror)
ENDIF()
diff --git a/code/Common/ImporterRegistry.cpp b/code/Common/ImporterRegistry.cpp
index 78c02d96d..c67fee936 100644
--- a/code/Common/ImporterRegistry.cpp
+++ b/code/Common/ImporterRegistry.cpp
@@ -214,7 +214,12 @@ void GetImporterInstanceList(std::vector &out) {
// Some importers may be unimplemented or otherwise unsuitable for general use
// in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
// local environment to enable them, otherwise they're left out of the registry.
+#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
+ // not supported under uwp
const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
+#else
+ const char *envStr = { "0" };
+#endif
bool devImportersEnabled = envStr && strcmp(envStr, "0");
// Ensure no unused var warnings if all uses are #ifndef'd away below:
@@ -377,9 +382,6 @@ void GetImporterInstanceList(std::vector &out) {
#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
out.push_back(new IQMImporter());
#endif
- //#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
- // out.push_back(new StepFile::StepFileImporter());
- //#endif
}
/** will delete all registered importers. */
diff --git a/code/PostProcessing/PretransformVertices.cpp b/code/PostProcessing/PretransformVertices.cpp
index b6bb6155e..16548f09c 100644
--- a/code/PostProcessing/PretransformVertices.cpp
+++ b/code/PostProcessing/PretransformVertices.cpp
@@ -577,7 +577,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
// multiply all properties of the camera with the absolute
// transformation of the corresponding node
cam->mPosition = nd->mTransformation * cam->mPosition;
- cam->mLookAt = aiMatrix3x3(nd->mTransformation) * cam->mLookAt;
+ cam->mLookAt = nd->mTransformation * cam->mLookAt;
cam->mUp = aiMatrix3x3(nd->mTransformation) * cam->mUp;
}
diff --git a/contrib/poly2tri/poly2tri/sweep/sweep.cc b/contrib/poly2tri/poly2tri/sweep/sweep.cc
index 8e3d794c0..565a198d8 100644
--- a/contrib/poly2tri/poly2tri/sweep/sweep.cc
+++ b/contrib/poly2tri/poly2tri/sweep/sweep.cc
@@ -118,8 +118,8 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
Point* p1 = triangle->PointCCW(point);
Orientation o1 = Orient2d(eq, *p1, ep);
if (o1 == COLLINEAR) {
- // ASSIMP_CHANGE (aramis_acg)
- throw std::runtime_error("EdgeEvent - collinear points not supported");
+
+
if( triangle->Contains(&eq, p1)) {
triangle->MarkConstrainedEdge(&eq, p1 );
// We are modifying the constraint maybe it would be better to
@@ -137,8 +137,8 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
Point* p2 = triangle->PointCW(point);
Orientation o2 = Orient2d(eq, *p2, ep);
if (o2 == COLLINEAR) {
- // ASSIMP_CHANGE (aramis_acg)
- throw std::runtime_error("EdgeEvent - collinear points not supported");
+
+
if( triangle->Contains(&eq, p2)) {
triangle->MarkConstrainedEdge(&eq, p2 );
diff --git a/contrib/unzip/crypt.c b/contrib/unzip/crypt.c
index 4cc731b3e..cc6650630 100644
--- a/contrib/unzip/crypt.c
+++ b/contrib/unzip/crypt.c
@@ -103,7 +103,7 @@ int cryptrand(unsigned char *buf, unsigned int len)
unsigned __int64 pentium_tsc[1];
int result = 0;
-
+ #if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
{
result = CryptGenRandom(provider, len, buf);
@@ -111,6 +111,7 @@ int cryptrand(unsigned char *buf, unsigned int len)
if (result)
return len;
}
+ #endif
for (rlen = 0; rlen < (int)len; ++rlen)
{
diff --git a/contrib/zlib/CMakeLists.txt b/contrib/zlib/CMakeLists.txt
index 469151ff6..5bc2d6065 100644
--- a/contrib/zlib/CMakeLists.txt
+++ b/contrib/zlib/CMakeLists.txt
@@ -76,7 +76,15 @@ if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype")
+ endif()
+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+else()
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-non-prototype")
+ endif()
endif()
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
@@ -88,7 +96,7 @@ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
message(STATUS "to 'zconf.h.included' because this file is included with zlib")
message(STATUS "but CMake generates it automatically in the build directory.")
file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
- endif()
+ endif()
endif()
set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h
index 59c6e9ead..cd8726785 100644
--- a/include/assimp/StringUtils.h
+++ b/include/assimp/StringUtils.h
@@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#define AI_SIZEFMT "%Iu"
#else
#define AI_SIZEFMT "%zu"
diff --git a/test/unit/utglTF2ImportExport.cpp b/test/unit/utglTF2ImportExport.cpp
index b63fd3944..56f79d307 100644
--- a/test/unit/utglTF2ImportExport.cpp
+++ b/test/unit/utglTF2ImportExport.cpp
@@ -382,7 +382,7 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLines) {
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_08.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u);
- std::array l1 = { { 0u, 3u, 2u, 1u, 0u } };
+ std::array l1 = { { 0u, 1u, 2u, 3u, 0u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2u);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
@@ -396,7 +396,7 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLineLoop) {
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_09.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u);
- std::array l1 = { { 0, 3u, 2u, 1u, 0u } };
+ std::array l1 = { { 0, 1u, 2u, 3u, 0u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2u);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
@@ -410,7 +410,7 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLineStrip) {
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_10.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u);
- std::array l1 = { { 0u, 3u, 2u, 1u, 0u } };
+ std::array l1 = { { 0u, 1u, 2u, 3u, 0u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2u);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
@@ -425,13 +425,13 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesStrip) {
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2u);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u);
- std::array f1 = { { 0u, 3u, 1u } };
+ std::array f1 = { { 0u, 1u, 2u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3u);
for (size_t i = 0; i < 3; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
- std::array f2 = { { 1u, 3u, 2u } };
+ std::array f2 = { { 2u, 1u, 3u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3u);
for (size_t i = 0; i < 3; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);
@@ -445,13 +445,13 @@ TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesFan) {
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4u);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2u);
- std::array f1 = { { 0u, 3u, 2u } };
+ std::array f1 = { { 0u, 1u, 2u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3u);
for (size_t i = 0; i < 3; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
- std::array f2 = { { 0u, 2u, 1u } };
+ std::array f2 = { { 0u, 2u, 3u } };
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3u);
for (size_t i = 0; i < 3; ++i) {
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);