Merge pull request #4425 from sacereda/metallic-roughness-split

glTF2: Metallic roughness split
pull/4426/head^2
Kim Kulling 2022-03-15 10:56:43 +01:00 committed by GitHub
commit e1dae1402e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 189 additions and 188 deletions

View File

@ -42,23 +42,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER) #if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
#include "AssetLib/glTF2/glTF2Importer.h" #include "AssetLib/glTF2/glTF2Importer.h"
#include "PostProcessing/MakeVerboseFormat.h"
#include "AssetLib/glTF2/glTF2Asset.h" #include "AssetLib/glTF2/glTF2Asset.h"
#include "PostProcessing/MakeVerboseFormat.h"
#if !defined(ASSIMP_BUILD_NO_EXPORT) #if !defined(ASSIMP_BUILD_NO_EXPORT)
#include "AssetLib/glTF2/glTF2AssetWriter.h" #include "AssetLib/glTF2/glTF2AssetWriter.h"
#endif #endif
#include <assimp/CreateAnimMesh.h> #include <assimp/CreateAnimMesh.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/commonMetaData.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/commonMetaData.h>
#include <assimp/DefaultIOSystem.h>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@ -111,7 +111,7 @@ const aiImporterDesc *glTF2Importer::GetInfo() const {
return &desc; return &desc;
} }
bool glTF2Importer::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig ) const { bool glTF2Importer::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(filename); const std::string extension = GetExtension(filename);
if (!checkSig && (extension != "gltf") && (extension != "glb")) { if (!checkSig && (extension != "gltf") && (extension != "glb")) {
return false; return false;
@ -127,16 +127,16 @@ bool glTF2Importer::CanRead(const std::string &filename, IOSystem *pIOHandler, b
static inline aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode) { static inline aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode) {
switch (gltfWrapMode) { switch (gltfWrapMode) {
case SamplerWrap::Mirrored_Repeat: case SamplerWrap::Mirrored_Repeat:
return aiTextureMapMode_Mirror; return aiTextureMapMode_Mirror;
case SamplerWrap::Clamp_To_Edge: case SamplerWrap::Clamp_To_Edge:
return aiTextureMapMode_Clamp; return aiTextureMapMode_Clamp;
case SamplerWrap::UNSET: case SamplerWrap::UNSET:
case SamplerWrap::Repeat: case SamplerWrap::Repeat:
default: default:
return aiTextureMapMode_Wrap; return aiTextureMapMode_Wrap;
} }
} }
@ -185,8 +185,9 @@ static void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
// coordinate of the actual meshes during import. // coordinate of the actual meshes during import.
const ai_real rcos(cos(-transform.mRotation)); const ai_real rcos(cos(-transform.mRotation));
const ai_real rsin(sin(-transform.mRotation)); const ai_real rsin(sin(-transform.mRotation));
transform.mTranslation.x = (static_cast<ai_real>( 0.5 ) * transform.mScaling.x) * (-rcos + rsin + 1) + prop.TextureTransformExt_t.offset[0]; transform.mTranslation.x = (static_cast<ai_real>(0.5) * transform.mScaling.x) * (-rcos + rsin + 1) + prop.TextureTransformExt_t.offset[0];
transform.mTranslation.y = ((static_cast<ai_real>( 0.5 ) * transform.mScaling.y) * (rsin + rcos - 1)) + 1 - transform.mScaling.y - prop.TextureTransformExt_t.offset[1];; transform.mTranslation.y = ((static_cast<ai_real>(0.5) * transform.mScaling.y) * (rsin + rcos - 1)) + 1 - transform.mScaling.y - prop.TextureTransformExt_t.offset[1];
;
mat->AddProperty(&transform, 1, _AI_MATKEY_UVTRANSFORM_BASE, texType, texSlot); mat->AddProperty(&transform, 1, _AI_MATKEY_UVTRANSFORM_BASE, texType, texSlot);
} }
@ -259,7 +260,10 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE);
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_BASE_COLOR); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_BASE_COLOR);
// Keep AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE for backwards compatibility
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, aiTextureType_METALNESS);
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, aiTextureType_DIFFUSE_ROUGHNESS);
aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_METALLIC_FACTOR); aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_METALLIC_FACTOR);
aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_ROUGHNESS_FACTOR); aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_ROUGHNESS_FACTOR);
@ -305,7 +309,6 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
aimat->AddProperty(&shadingMode, 1, AI_MATKEY_SHADING_MODEL); aimat->AddProperty(&shadingMode, 1, AI_MATKEY_SHADING_MODEL);
// KHR_materials_sheen // KHR_materials_sheen
if (mat.materialSheen.isPresent) { if (mat.materialSheen.isPresent) {
MaterialSheen &sheen = mat.materialSheen.value; MaterialSheen &sheen = mat.materialSheen.value;
@ -378,7 +381,7 @@ void glTF2Importer::ImportMaterials(Asset &r) {
} }
} }
static inline void SetFaceAndAdvance1(aiFace*& face, unsigned int numVertices, unsigned int a) { static inline void SetFaceAndAdvance1(aiFace *&face, unsigned int numVertices, unsigned int a) {
if (a >= numVertices) { if (a >= numVertices) {
return; return;
} }
@ -388,7 +391,7 @@ static inline void SetFaceAndAdvance1(aiFace*& face, unsigned int numVertices, u
++face; ++face;
} }
static inline void SetFaceAndAdvance2(aiFace*& face, unsigned int numVertices, static inline void SetFaceAndAdvance2(aiFace *&face, unsigned int numVertices,
unsigned int a, unsigned int b) { unsigned int a, unsigned int b) {
if ((a >= numVertices) || (b >= numVertices)) { if ((a >= numVertices) || (b >= numVertices)) {
return; return;
@ -400,7 +403,7 @@ static inline void SetFaceAndAdvance2(aiFace*& face, unsigned int numVertices,
++face; ++face;
} }
static inline void SetFaceAndAdvance3(aiFace*& face, unsigned int numVertices, unsigned int a, static inline void SetFaceAndAdvance3(aiFace *&face, unsigned int numVertices, unsigned int a,
unsigned int b, unsigned int c) { unsigned int b, unsigned int c) {
if ((a >= numVertices) || (b >= numVertices) || (c >= numVertices)) { if ((a >= numVertices) || (b >= numVertices) || (c >= numVertices)) {
return; return;
@ -427,17 +430,16 @@ static inline bool CheckValidFacesIndices(aiFace *faces, unsigned nFaces, unsign
} }
#endif // ASSIMP_BUILD_DEBUG #endif // ASSIMP_BUILD_DEBUG
template<typename T> template <typename T>
aiColor4D* GetVertexColorsForType(Ref<Accessor> input) { aiColor4D *GetVertexColorsForType(Ref<Accessor> input) {
constexpr float max = std::numeric_limits<T>::max(); constexpr float max = std::numeric_limits<T>::max();
aiColor4t<T>* colors; aiColor4t<T> *colors;
input->ExtractData(colors); input->ExtractData(colors);
auto output = new aiColor4D[input->count]; auto output = new aiColor4D[input->count];
for (size_t i = 0; i < input->count; i++) { for (size_t i = 0; i < input->count; i++) {
output[i] = aiColor4D( output[i] = aiColor4D(
colors[i].r / max, colors[i].g / max, colors[i].r / max, colors[i].g / max,
colors[i].b / max, colors[i].a / max colors[i].b / max, colors[i].a / max);
);
} }
delete[] colors; delete[] colors;
return output; return output;
@ -471,21 +473,21 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
} }
switch (prim.mode) { switch (prim.mode) {
case PrimitiveMode_POINTS: case PrimitiveMode_POINTS:
aim->mPrimitiveTypes |= aiPrimitiveType_POINT; aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
break; break;
case PrimitiveMode_LINES: case PrimitiveMode_LINES:
case PrimitiveMode_LINE_LOOP: case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: case PrimitiveMode_LINE_STRIP:
aim->mPrimitiveTypes |= aiPrimitiveType_LINE; aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
break; break;
case PrimitiveMode_TRIANGLES: case PrimitiveMode_TRIANGLES:
case PrimitiveMode_TRIANGLE_STRIP: case PrimitiveMode_TRIANGLE_STRIP:
case PrimitiveMode_TRIANGLE_FAN: case PrimitiveMode_TRIANGLE_FAN:
aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
break; break;
} }
Mesh::Primitive::Attributes &attr = prim.attributes; Mesh::Primitive::Attributes &attr = prim.attributes;
@ -528,7 +530,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) { 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 != aim->mNumVertices) {
DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name, DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name,
"\" does not match the vertex count"); "\" does not match the vertex count");
continue; continue;
} }
@ -551,7 +553,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
if (attr.texcoord[tc]->count != aim->mNumVertices) { if (attr.texcoord[tc]->count != aim->mNumVertices) {
DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name, DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name,
"\" does not match the vertex count"); "\" does not match the vertex count");
continue; continue;
} }
@ -644,77 +646,77 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
} }
switch (prim.mode) { switch (prim.mode) {
case PrimitiveMode_POINTS: { case PrimitiveMode_POINTS: {
nFaces = count; nFaces = count;
facePtr = faces = new aiFace[nFaces]; facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) { for (unsigned int i = 0; i < count; ++i) {
SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i)); SetFaceAndAdvance1(facePtr, aim->mNumVertices, data.GetUInt(i));
}
break;
} }
break;
}
case PrimitiveMode_LINES: { case PrimitiveMode_LINES: {
nFaces = count / 2; nFaces = count / 2;
if (nFaces * 2 != count) { if (nFaces * 2 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped."); ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = nFaces * 2; count = nFaces * 2;
}
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));
}
break;
} }
facePtr = faces = new aiFace[nFaces];
case PrimitiveMode_LINE_LOOP: for (unsigned int i = 0; i < count; i += 2) {
case PrimitiveMode_LINE_STRIP: { SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i), data.GetUInt(i + 1));
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1));
for (unsigned int i = 2; i < count; ++i) {
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i));
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast<int>(count) - 1), faces[0].mIndices[0]);
}
break;
} }
break;
}
case PrimitiveMode_TRIANGLES: { case PrimitiveMode_LINE_LOOP:
nFaces = count / 3; case PrimitiveMode_LINE_STRIP: {
if (nFaces * 3 != count) { nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped."); facePtr = faces = new aiFace[nFaces];
count = nFaces * 3; SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1));
} for (unsigned int i = 2; i < count; ++i) {
facePtr = faces = new aiFace[nFaces]; SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(i - 1), data.GetUInt(i));
for (unsigned int i = 0; i < count; i += 3) { }
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFaceAndAdvance2(facePtr, aim->mNumVertices, data.GetUInt(static_cast<int>(count) - 1), faces[0].mIndices[0]);
}
break;
}
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
if (nFaces * 3 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = nFaces * 3;
}
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));
}
break;
}
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//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));
} 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, data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
} }
break;
} }
case PrimitiveMode_TRIANGLE_STRIP: { break;
nFaces = count - 2; }
facePtr = faces = new aiFace[nFaces]; case PrimitiveMode_TRIANGLE_FAN:
for (unsigned int i = 0; i < nFaces; ++i) { nFaces = count - 2;
//The ordering is to ensure that the triangles are all drawn with the same orientation facePtr = faces = new aiFace[nFaces];
if ((i + 1) % 2 == 0) { SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
//For even n, vertices n + 1, n, and n + 2 define triangle n for (unsigned int i = 1; i < nFaces; ++i) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2)); SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(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));
}
}
break;
} }
case PrimitiveMode_TRIANGLE_FAN: break;
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
for (unsigned int i = 1; i < nFaces; ++i) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, data.GetUInt(0), data.GetUInt(i + 1), data.GetUInt(i + 2));
}
break;
} }
} else { // no indices provided so directly generate from counts } else { // no indices provided so directly generate from counts
@ -722,77 +724,77 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
unsigned int count = aim->mNumVertices; unsigned int count = aim->mNumVertices;
switch (prim.mode) { switch (prim.mode) {
case PrimitiveMode_POINTS: { case PrimitiveMode_POINTS: {
nFaces = count; nFaces = count;
facePtr = faces = new aiFace[nFaces]; facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) { for (unsigned int i = 0; i < count; ++i) {
SetFaceAndAdvance1(facePtr, aim->mNumVertices, i); SetFaceAndAdvance1(facePtr, aim->mNumVertices, i);
}
break;
} }
break;
}
case PrimitiveMode_LINES: { case PrimitiveMode_LINES: {
nFaces = count / 2; nFaces = count / 2;
if (nFaces * 2 != count) { if (nFaces * 2 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped."); ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
count = (unsigned int)nFaces * 2; count = (unsigned int)nFaces * 2;
}
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFaceAndAdvance2(facePtr, aim->mNumVertices, i, i + 1);
}
break;
} }
facePtr = faces = new aiFace[nFaces];
case PrimitiveMode_LINE_LOOP: for (unsigned int i = 0; i < count; i += 2) {
case PrimitiveMode_LINE_STRIP: { SetFaceAndAdvance2(facePtr, aim->mNumVertices, i, i + 1);
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance2(facePtr, aim->mNumVertices, 0, 1);
for (unsigned int i = 2; i < count; ++i) {
SetFaceAndAdvance2(facePtr, aim->mNumVertices, i - 1, i);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFaceAndAdvance2(facePtr, aim->mNumVertices, count - 1, 0);
}
break;
} }
break;
}
case PrimitiveMode_TRIANGLES: { case PrimitiveMode_LINE_LOOP:
nFaces = count / 3; case PrimitiveMode_LINE_STRIP: {
if (nFaces * 3 != count) { nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped."); facePtr = faces = new aiFace[nFaces];
count = (unsigned int)nFaces * 3; SetFaceAndAdvance2(facePtr, aim->mNumVertices, 0, 1);
} for (unsigned int i = 2; i < count; ++i) {
facePtr = faces = new aiFace[nFaces]; SetFaceAndAdvance2(facePtr, aim->mNumVertices, i - 1, i);
for (unsigned int i = 0; i < count; i += 3) { }
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFaceAndAdvance2(facePtr, aim->mNumVertices, count - 1, 0);
}
break;
}
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
if (nFaces * 3 != count) {
ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
count = (unsigned int)nFaces * 3;
}
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
}
break;
}
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//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, i + 1, i, i + 2);
} else {
//For odd n, vertices n, n+1, and n+2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2); SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
} }
break;
} }
case PrimitiveMode_TRIANGLE_STRIP: { break;
nFaces = count - 2; }
facePtr = faces = new aiFace[nFaces]; case PrimitiveMode_TRIANGLE_FAN:
for (unsigned int i = 0; i < nFaces; ++i) { nFaces = count - 2;
//The ordering is to ensure that the triangles are all drawn with the same orientation facePtr = faces = new aiFace[nFaces];
if ((i + 1) % 2 == 0) { SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, 1, 2);
//For even n, vertices n + 1, n, and n + 2 define triangle n for (unsigned int i = 1; i < nFaces; ++i) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i + 1, i, i + 2); SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, i + 1, i + 2);
} else {
//For odd n, vertices n, n+1, and n+2 define triangle n
SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
}
}
break;
} }
case PrimitiveMode_TRIANGLE_FAN: break;
nFaces = count - 2;
facePtr = faces = new aiFace[nFaces];
SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, 1, 2);
for (unsigned int i = 1; i < nFaces; ++i) {
SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, i + 1, i + 2);
}
break;
} }
} }
@ -876,15 +878,15 @@ void glTF2Importer::ImportLights(glTF2::Asset &r) {
aiLight *ail = mScene->mLights[i] = new aiLight(); aiLight *ail = mScene->mLights[i] = new aiLight();
switch (light.type) { switch (light.type) {
case Light::Directional: case Light::Directional:
ail->mType = aiLightSource_DIRECTIONAL; ail->mType = aiLightSource_DIRECTIONAL;
break; break;
case Light::Point: case Light::Point:
ail->mType = aiLightSource_POINT; ail->mType = aiLightSource_POINT;
break; break;
case Light::Spot: case Light::Spot:
ail->mType = aiLightSource_SPOT; ail->mType = aiLightSource_SPOT;
break; break;
} }
if (ail->mType != aiLightSource_POINT) { if (ail->mType != aiLightSource_POINT) {
@ -926,7 +928,7 @@ static void GetNodeTransform(aiMatrix4x4 &matrix, const glTF2::Node &node) {
if (node.matrix.isPresent) { if (node.matrix.isPresent) {
CopyValue(node.matrix.value, matrix); CopyValue(node.matrix.value, matrix);
return; return;
} }
if (node.translation.isPresent) { if (node.translation.isPresent) {
aiVector3D trans; aiVector3D trans;
@ -1021,7 +1023,7 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) {
metadata->Add(extension.name, extension.mBoolValue.value); metadata->Add(extension.name, extension.mBoolValue.value);
} else if (extension.mValues.isPresent) { } else if (extension.mValues.isPresent) {
aiMetadata val; aiMetadata val;
for (auto const & subExtension : extension.mValues.value) { for (auto const &subExtension : extension.mValues.value) {
ParseExtensions(&val, subExtension); ParseExtensions(&val, subExtension);
} }
metadata->Add(extension.name, val); metadata->Add(extension.name, val);
@ -1030,7 +1032,7 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) {
void ParseExtras(aiMetadata *metadata, const CustomExtension &extension) { void ParseExtras(aiMetadata *metadata, const CustomExtension &extension) {
if (extension.mValues.isPresent) { if (extension.mValues.isPresent) {
for (auto const & subExtension : extension.mValues.value) { for (auto const &subExtension : extension.mValues.value) {
ParseExtensions(metadata, subExtension); ParseExtensions(metadata, subExtension);
} }
} }
@ -1068,11 +1070,10 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
if (!node.meshes.empty()) { if (!node.meshes.empty()) {
// GLTF files contain at most 1 mesh per node. // GLTF files contain at most 1 mesh per node.
if (node.meshes.size() > 1) if (node.meshes.size() > 1) {
{
throw DeadlyImportError("GLTF: Invalid input, found ", node.meshes.size(), throw DeadlyImportError("GLTF: Invalid input, found ", node.meshes.size(),
" meshes in ", getContextForErrorMessages(node.id, node.name), " meshes in ", getContextForErrorMessages(node.id, node.name),
", but only 1 mesh per node allowed."); ", but only 1 mesh per node allowed.");
} }
int mesh_idx = node.meshes[0].GetIndex(); int mesh_idx = node.meshes[0].GetIndex();
int count = meshOffsets[mesh_idx + 1] - meshOffsets[mesh_idx]; int count = meshOffsets[mesh_idx + 1] - meshOffsets[mesh_idx];
@ -1083,7 +1084,7 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
if (node.skin) { if (node.skin) {
for (int primitiveNo = 0; primitiveNo < count; ++primitiveNo) { for (int primitiveNo = 0; primitiveNo < count; ++primitiveNo) {
aiMesh *mesh = pScene->mMeshes[meshOffsets[mesh_idx] + primitiveNo]; aiMesh *mesh = pScene->mMeshes[meshOffsets[mesh_idx] + primitiveNo];
unsigned int numBones =static_cast<unsigned int>(node.skin->jointNames.size()); unsigned int numBones = static_cast<unsigned int>(node.skin->jointNames.size());
std::vector<std::vector<aiVertexWeight>> weighting(numBones); std::vector<std::vector<aiVertexWeight>> weighting(numBones);
BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting); BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting);
@ -1222,7 +1223,7 @@ struct AnimationSamplers {
Animation::Sampler *weight; Animation::Sampler *weight;
}; };
aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &samplers) { aiNodeAnim *CreateNodeAnim(glTF2::Asset &, Node &node, AnimationSamplers &samplers) {
aiNodeAnim *anim = new aiNodeAnim(); aiNodeAnim *anim = new aiNodeAnim();
try { try {
@ -1313,7 +1314,7 @@ aiNodeAnim *CreateNodeAnim(glTF2::Asset&, Node &node, AnimationSamplers &sampler
} }
} }
aiMeshMorphAnim *CreateMeshMorphAnim(glTF2::Asset&, Node &node, AnimationSamplers &samplers) { aiMeshMorphAnim *CreateMeshMorphAnim(glTF2::Asset &, Node &node, AnimationSamplers &samplers) {
auto *anim = new aiMeshMorphAnim(); auto *anim = new aiMeshMorphAnim();
try { try {
@ -1366,7 +1367,7 @@ std::unordered_map<unsigned int, AnimationSamplers> GatherSamplers(Animation &an
continue; continue;
} }
auto& animsampler = anim.samplers[channel.sampler]; auto &animsampler = anim.samplers[channel.sampler];
if (!animsampler.input) { if (!animsampler.input) {
ASSIMP_LOG_WARN("Animation ", anim.name, ": Missing sampler input. Skipping."); ASSIMP_LOG_WARN("Animation ", anim.name, ": Missing sampler input. Skipping.");
@ -1555,9 +1556,9 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) {
if (ext) { if (ext) {
if (strcmp(ext, "jpeg") == 0) { if (strcmp(ext, "jpeg") == 0) {
ext = "jpg"; ext = "jpg";
} else if(strcmp(ext, "ktx2") == 0) { //basisu: ktx remains } else if (strcmp(ext, "ktx2") == 0) { //basisu: ktx remains
ext = "kx2"; ext = "kx2";
} else if(strcmp(ext, "basis") == 0) { //basisu } else if (strcmp(ext, "basis") == 0) { //basisu
ext = "bu"; ext = "bu";
} }
@ -1570,7 +1571,7 @@ void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) {
} }
} }
void glTF2Importer::ImportCommonMetadata(glTF2::Asset& a) { void glTF2Importer::ImportCommonMetadata(glTF2::Asset &a) {
ASSIMP_LOG_DEBUG("Importing metadata"); ASSIMP_LOG_DEBUG("Importing metadata");
ai_assert(mScene->mMetaData == nullptr); ai_assert(mScene->mMetaData == nullptr);
const bool hasVersion = !a.asset.version.empty(); const bool hasVersion = !a.asset.version.empty();
@ -1604,7 +1605,7 @@ void glTF2Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IO
this->mScene = pScene; this->mScene = pScene;
// read the asset file // read the asset file
glTF2::Asset asset(pIOHandler, static_cast<rapidjson::IRemoteSchemaDocumentProvider*>(mSchemaDocumentProvider)); glTF2::Asset asset(pIOHandler, static_cast<rapidjson::IRemoteSchemaDocumentProvider *>(mSchemaDocumentProvider));
asset.Load(pFile, GetExtension(pFile) == "glb"); asset.Load(pFile, GetExtension(pFile) == "glb");
if (asset.scene) { if (asset.scene) {
pScene->mName = asset.scene->name; pScene->mName = asset.scene->name;
@ -1631,7 +1632,7 @@ void glTF2Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IO
} }
void glTF2Importer::SetupProperties(const Importer *pImp) { void glTF2Importer::SetupProperties(const Importer *pImp) {
mSchemaDocumentProvider = static_cast<rapidjson::IRemoteSchemaDocumentProvider*>(pImp->GetPropertyPointer(AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER)); mSchemaDocumentProvider = static_cast<rapidjson::IRemoteSchemaDocumentProvider *>(pImp->GetPropertyPointer(AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER));
} }
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER #endif // ASSIMP_BUILD_NO_GLTF_IMPORTER