Merge branch 'master' into patch-2
commit
693d681813
|
@ -49,8 +49,8 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
||||||
IF(ASSIMP_HUNTER_ENABLED)
|
IF(ASSIMP_HUNTER_ENABLED)
|
||||||
include("cmake-modules/HunterGate.cmake")
|
include("cmake-modules/HunterGate.cmake")
|
||||||
HunterGate(
|
HunterGate(
|
||||||
URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz"
|
URL "https://github.com/cpp-pm/hunter/archive/v0.24.17.tar.gz"
|
||||||
SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd"
|
SHA1 "e6396699e414120e32557fe92db097b7655b760b"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions(-DASSIMP_USE_HUNTER)
|
add_definitions(-DASSIMP_USE_HUNTER)
|
||||||
|
|
|
@ -115,7 +115,9 @@ void HMPImporter::InternReadFile(const std::string &pFile,
|
||||||
throw DeadlyImportError("HMP File is too small.");
|
throw DeadlyImportError("HMP File is too small.");
|
||||||
|
|
||||||
// Allocate storage and copy the contents of the file to a memory buffer
|
// Allocate storage and copy the contents of the file to a memory buffer
|
||||||
mBuffer = new uint8_t[fileSize];
|
auto deleter=[this](uint8_t* ptr){ delete[] ptr; mBuffer = nullptr; };
|
||||||
|
std::unique_ptr<uint8_t[], decltype(deleter)> buffer(new uint8_t[fileSize], deleter);
|
||||||
|
mBuffer = buffer.get();
|
||||||
file->Read((void *)mBuffer, 1, fileSize);
|
file->Read((void *)mBuffer, 1, fileSize);
|
||||||
iFileSize = (unsigned int)fileSize;
|
iFileSize = (unsigned int)fileSize;
|
||||||
|
|
||||||
|
@ -143,9 +145,6 @@ void HMPImporter::InternReadFile(const std::string &pFile,
|
||||||
// Print the magic word to the logger
|
// Print the magic word to the logger
|
||||||
std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
|
std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
|
||||||
|
|
||||||
delete[] mBuffer;
|
|
||||||
mBuffer = nullptr;
|
|
||||||
|
|
||||||
// We're definitely unable to load this file
|
// We're definitely unable to load this file
|
||||||
throw DeadlyImportError("Unknown HMP subformat ", pFile,
|
throw DeadlyImportError("Unknown HMP subformat ", pFile,
|
||||||
". Magic word (", szBuffer, ") is not known");
|
". Magic word (", szBuffer, ") is not known");
|
||||||
|
@ -153,9 +152,6 @@ void HMPImporter::InternReadFile(const std::string &pFile,
|
||||||
|
|
||||||
// Set the AI_SCENE_FLAGS_TERRAIN bit
|
// Set the AI_SCENE_FLAGS_TERRAIN bit
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
|
pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
|
||||||
|
|
||||||
delete[] mBuffer;
|
|
||||||
mBuffer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -445,11 +441,11 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szC
|
||||||
szCursor += sizeof(uint32_t);
|
szCursor += sizeof(uint32_t);
|
||||||
|
|
||||||
// allocate an output material
|
// allocate an output material
|
||||||
aiMaterial *pcMat = new aiMaterial();
|
std::unique_ptr<aiMaterial> pcMat(new aiMaterial());
|
||||||
|
|
||||||
// read the skin, this works exactly as for MDL7
|
// read the skin, this works exactly as for MDL7
|
||||||
ParseSkinLump_3DGS_MDL7(szCursor, &szCursor,
|
ParseSkinLump_3DGS_MDL7(szCursor, &szCursor,
|
||||||
pcMat, iType, iWidth, iHeight);
|
pcMat.get(), iType, iWidth, iHeight);
|
||||||
|
|
||||||
// now we need to skip any other skins ...
|
// now we need to skip any other skins ...
|
||||||
for (unsigned int i = 1; i < iNumSkins; ++i) {
|
for (unsigned int i = 1; i < iNumSkins; ++i) {
|
||||||
|
@ -468,7 +464,7 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szC
|
||||||
// setup the material ...
|
// setup the material ...
|
||||||
pScene->mNumMaterials = 1;
|
pScene->mNumMaterials = 1;
|
||||||
pScene->mMaterials = new aiMaterial *[1];
|
pScene->mMaterials = new aiMaterial *[1];
|
||||||
pScene->mMaterials[0] = pcMat;
|
pScene->mMaterials[0] = pcMat.release();
|
||||||
|
|
||||||
*szCursorOut = szCursor;
|
*szCursorOut = szCursor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,15 +228,20 @@ bool MD5Parser::ParseSection(Section &out) {
|
||||||
out.data[out.length] = '\0';
|
out.data[out.length] = '\0';
|
||||||
|
|
||||||
// parse a string, enclosed in quotation marks
|
// parse a string, enclosed in quotation marks
|
||||||
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
|
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
|
||||||
while ('\"' != *sz) \
|
out.length = 0; \
|
||||||
++sz; \
|
while ('\"' != *sz && '\0' != *sz) \
|
||||||
const char *szStart = ++sz; \
|
++sz; \
|
||||||
while ('\"' != *sz) \
|
if ('\0' != *sz) { \
|
||||||
++sz; \
|
const char *szStart = ++sz; \
|
||||||
const char *szEnd = (sz++); \
|
while ('\"' != *sz && '\0' != *sz) \
|
||||||
out.length = (ai_uint32)(szEnd - szStart); \
|
++sz; \
|
||||||
::memcpy(out.data, szStart, out.length); \
|
if ('\0' != *sz) { \
|
||||||
|
const char *szEnd = (sz++); \
|
||||||
|
out.length = (ai_uint32)(szEnd - szStart); \
|
||||||
|
::memcpy(out.data, szStart, out.length); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
out.data[out.length] = '\0';
|
out.data[out.length] = '\0';
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// .MD5MESH parsing function
|
// .MD5MESH parsing function
|
||||||
|
|
|
@ -274,7 +274,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Check whether we're still inside the valid file range
|
// Check whether we're still inside the valid file range
|
||||||
void MDLImporter::SizeCheck(const void *szPos) {
|
void MDLImporter::SizeCheck(const void *szPos) {
|
||||||
if (!szPos || (const unsigned char *)szPos > this->mBuffer + this->iFileSize) {
|
if (!szPos || (const unsigned char *)szPos > this->mBuffer + this->iFileSize || szPos < this->mBuffer) {
|
||||||
throw DeadlyImportError("Invalid MDL file. The file is too small "
|
throw DeadlyImportError("Invalid MDL file. The file is too small "
|
||||||
"or contains invalid data.");
|
"or contains invalid data.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,7 +703,14 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7(
|
||||||
tex.pcData = bad_texel;
|
tex.pcData = bad_texel;
|
||||||
tex.mHeight = iHeight;
|
tex.mHeight = iHeight;
|
||||||
tex.mWidth = iWidth;
|
tex.mWidth = iWidth;
|
||||||
ParseTextureColorData(szCurrent, iMasked, &iSkip, &tex);
|
|
||||||
|
try {
|
||||||
|
ParseTextureColorData(szCurrent, iMasked, &iSkip, &tex);
|
||||||
|
} catch (...) {
|
||||||
|
// FIX: Important, otherwise the destructor will crash
|
||||||
|
tex.pcData = nullptr;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
// FIX: Important, otherwise the destructor will crash
|
// FIX: Important, otherwise the destructor will crash
|
||||||
tex.pcData = nullptr;
|
tex.pcData = nullptr;
|
||||||
|
|
|
@ -284,7 +284,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
for (unsigned int i = 0; i < numFaces; ) {
|
for (unsigned int i = 0; i < numFaces; ) {
|
||||||
if(!GetNextLine(buffer,line)) {
|
if(!GetNextLine(buffer,line)) {
|
||||||
ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect");
|
ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect");
|
||||||
break;
|
throw DeadlyImportError("OFF: The number of faces in the header is incorrect");
|
||||||
}
|
}
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
sz = line; SkipSpaces(&sz);
|
sz = line; SkipSpaces(&sz);
|
||||||
|
|
|
@ -100,8 +100,6 @@ glTF2Importer::glTF2Importer() :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
glTF2Importer::~glTF2Importer() = default;
|
|
||||||
|
|
||||||
const aiImporterDesc *glTF2Importer::GetInfo() const {
|
const aiImporterDesc *glTF2Importer::GetInfo() const {
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
@ -443,10 +441,10 @@ 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, std::vector<unsigned int> *vertexRemappingTable) {
|
||||||
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, vertexRemappingTable);
|
||||||
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(
|
||||||
|
@ -461,20 +459,26 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
ASSIMP_LOG_DEBUG("Importing ", r.meshes.Size(), " meshes");
|
ASSIMP_LOG_DEBUG("Importing ", r.meshes.Size(), " meshes");
|
||||||
std::vector<std::unique_ptr<aiMesh>> meshes;
|
std::vector<std::unique_ptr<aiMesh>> meshes;
|
||||||
|
|
||||||
unsigned int k = 0;
|
|
||||||
meshOffsets.clear();
|
meshOffsets.clear();
|
||||||
|
meshOffsets.reserve(r.meshes.Size() + 1);
|
||||||
|
mVertexRemappingTables.clear();
|
||||||
|
|
||||||
|
// Count the number of aiMeshes
|
||||||
|
unsigned int num_aiMeshes = 0;
|
||||||
|
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
|
||||||
|
meshOffsets.push_back(num_aiMeshes);
|
||||||
|
num_aiMeshes += unsigned(r.meshes[m].primitives.size());
|
||||||
|
}
|
||||||
|
meshOffsets.push_back(num_aiMeshes); // add a last element so we can always do meshOffsets[n+1] - meshOffsets[n]
|
||||||
|
|
||||||
std::vector<unsigned int> usedVertexIndices;
|
|
||||||
std::vector<unsigned int> reverseMappingIndices;
|
std::vector<unsigned int> reverseMappingIndices;
|
||||||
std::vector<unsigned int> indexBuffer;
|
std::vector<unsigned int> indexBuffer;
|
||||||
|
meshes.reserve(num_aiMeshes);
|
||||||
|
mVertexRemappingTables.resize(num_aiMeshes);
|
||||||
|
|
||||||
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
|
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
|
||||||
Mesh &mesh = r.meshes[m];
|
Mesh &mesh = r.meshes[m];
|
||||||
|
|
||||||
meshOffsets.push_back(k);
|
|
||||||
k += unsigned(mesh.primitives.size());
|
|
||||||
|
|
||||||
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
||||||
Mesh::Primitive &prim = mesh.primitives[p];
|
Mesh::Primitive &prim = mesh.primitives[p];
|
||||||
|
|
||||||
|
@ -488,14 +492,14 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
|
|
||||||
// Extract used vertices:
|
// Extract used vertices:
|
||||||
bool useIndexBuffer = prim.indices;
|
bool useIndexBuffer = prim.indices;
|
||||||
std::vector<unsigned int>* vertexRemappingTable = nullptr;
|
std::vector<unsigned int> *vertexRemappingTable = nullptr;
|
||||||
|
|
||||||
if (useIndexBuffer) {
|
if (useIndexBuffer) {
|
||||||
size_t count = prim.indices->count;
|
size_t count = prim.indices->count;
|
||||||
indexBuffer.resize(count);
|
indexBuffer.resize(count);
|
||||||
usedVertexIndices.clear();
|
|
||||||
reverseMappingIndices.clear();
|
reverseMappingIndices.clear();
|
||||||
usedVertexIndices.reserve(count / 3); // this is a very rough heuristic to reduce re-allocations
|
vertexRemappingTable = &mVertexRemappingTables[meshes.size()];
|
||||||
vertexRemappingTable = &usedVertexIndices;
|
vertexRemappingTable->reserve(count / 3); // this is a very rough heuristic to reduce re-allocations
|
||||||
Accessor::Indexer data = prim.indices->GetIndexer();
|
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||||
if (!data.IsValid()) {
|
if (!data.IsValid()) {
|
||||||
throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
|
throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
|
||||||
|
@ -515,8 +519,8 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
reverseMappingIndices.resize(index + 1, unusedIndex);
|
reverseMappingIndices.resize(index + 1, unusedIndex);
|
||||||
}
|
}
|
||||||
if (reverseMappingIndices[index] == unusedIndex) {
|
if (reverseMappingIndices[index] == unusedIndex) {
|
||||||
reverseMappingIndices[index] = static_cast<unsigned int>(usedVertexIndices.size());
|
reverseMappingIndices[index] = static_cast<unsigned int>(vertexRemappingTable->size());
|
||||||
usedVertexIndices.push_back(index);
|
vertexRemappingTable->push_back(index);
|
||||||
}
|
}
|
||||||
indexBuffer[i] = reverseMappingIndices[index];
|
indexBuffer[i] = reverseMappingIndices[index];
|
||||||
}
|
}
|
||||||
|
@ -597,9 +601,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable);
|
attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable);
|
||||||
} else {
|
} else {
|
||||||
if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
|
if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
|
||||||
aim->mColors[c] = GetVertexColorsForType<unsigned char>(attr.color[c]);
|
aim->mColors[c] = GetVertexColorsForType<unsigned char>(attr.color[c], vertexRemappingTable);
|
||||||
} else if (componentType == glTF2::ComponentType_UNSIGNED_SHORT) {
|
} else if (componentType == glTF2::ComponentType_UNSIGNED_SHORT) {
|
||||||
aim->mColors[c] = GetVertexColorsForType<unsigned short>(attr.color[c]);
|
aim->mColors[c] = GetVertexColorsForType<unsigned short>(attr.color[c], vertexRemappingTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,8 +879,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meshOffsets.push_back(k);
|
|
||||||
|
|
||||||
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
|
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,7 +1011,8 @@ static void GetNodeTransform(aiMatrix4x4 &matrix, const glTF2::Node &node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BuildVertexWeightMapping(Mesh::Primitive &primitive, std::vector<std::vector<aiVertexWeight>> &map) {
|
static void BuildVertexWeightMapping(Mesh::Primitive &primitive, std::vector<std::vector<aiVertexWeight>> &map, std::vector<unsigned int>* vertexRemappingTablePtr) {
|
||||||
|
|
||||||
Mesh::Primitive::Attributes &attr = primitive.attributes;
|
Mesh::Primitive::Attributes &attr = primitive.attributes;
|
||||||
if (attr.weight.empty() || attr.joint.empty()) {
|
if (attr.weight.empty() || attr.joint.empty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1018,14 +1021,14 @@ static void BuildVertexWeightMapping(Mesh::Primitive &primitive, std::vector<std
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_vertices = attr.weight[0]->count;
|
size_t num_vertices = 0;
|
||||||
|
|
||||||
struct Weights {
|
struct Weights {
|
||||||
float values[4];
|
float values[4];
|
||||||
};
|
};
|
||||||
Weights **weights = new Weights*[attr.weight.size()];
|
Weights **weights = new Weights*[attr.weight.size()];
|
||||||
for (size_t w = 0; w < attr.weight.size(); ++w) {
|
for (size_t w = 0; w < attr.weight.size(); ++w) {
|
||||||
attr.weight[w]->ExtractData(weights[w]);
|
num_vertices = attr.weight[w]->ExtractData(weights[w], vertexRemappingTablePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Indices8 {
|
struct Indices8 {
|
||||||
|
@ -1039,12 +1042,12 @@ static void BuildVertexWeightMapping(Mesh::Primitive &primitive, std::vector<std
|
||||||
if (attr.joint[0]->GetElementSize() == 4) {
|
if (attr.joint[0]->GetElementSize() == 4) {
|
||||||
indices8 = new Indices8*[attr.joint.size()];
|
indices8 = new Indices8*[attr.joint.size()];
|
||||||
for (size_t j = 0; j < attr.joint.size(); ++j) {
|
for (size_t j = 0; j < attr.joint.size(); ++j) {
|
||||||
attr.joint[j]->ExtractData(indices8[j]);
|
attr.joint[j]->ExtractData(indices8[j], vertexRemappingTablePtr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
indices16 = new Indices16 *[attr.joint.size()];
|
indices16 = new Indices16 *[attr.joint.size()];
|
||||||
for (size_t j = 0; j < attr.joint.size(); ++j) {
|
for (size_t j = 0; j < attr.joint.size(); ++j) {
|
||||||
attr.joint[j]->ExtractData(indices16[j]);
|
attr.joint[j]->ExtractData(indices16[j], vertexRemappingTablePtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -1109,7 +1112,7 @@ void ParseExtras(aiMetadata* metadata, const Extras& extras) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &meshOffsets, glTF2::Ref<glTF2::Node> &ptr) {
|
aiNode *glTF2Importer::ImportNode(glTF2::Asset &r, glTF2::Ref<glTF2::Node> &ptr) {
|
||||||
Node &node = *ptr;
|
Node &node = *ptr;
|
||||||
|
|
||||||
aiNode *ainode = new aiNode(GetNodeName(node));
|
aiNode *ainode = new aiNode(GetNodeName(node));
|
||||||
|
@ -1121,7 +1124,7 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
|
||||||
std::fill(ainode->mChildren, ainode->mChildren + ainode->mNumChildren, nullptr);
|
std::fill(ainode->mChildren, ainode->mChildren + ainode->mNumChildren, nullptr);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
|
||||||
aiNode *child = ImportNode(pScene, r, meshOffsets, node.children[i]);
|
aiNode *child = ImportNode(r, node.children[i]);
|
||||||
child->mParent = ainode;
|
child->mParent = ainode;
|
||||||
ainode->mChildren[i] = child;
|
ainode->mChildren[i] = child;
|
||||||
}
|
}
|
||||||
|
@ -1154,11 +1157,13 @@ 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];
|
unsigned int aiMeshIdx = meshOffsets[mesh_idx] + primitiveNo;
|
||||||
|
aiMesh *mesh = mScene->mMeshes[aiMeshIdx];
|
||||||
unsigned int numBones = static_cast<unsigned int>(node.skin->jointNames.size());
|
unsigned int numBones = static_cast<unsigned int>(node.skin->jointNames.size());
|
||||||
|
std::vector<unsigned int> *vertexRemappingTablePtr = mVertexRemappingTables[aiMeshIdx].empty() ? nullptr : &mVertexRemappingTables[aiMeshIdx];
|
||||||
|
|
||||||
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, vertexRemappingTablePtr);
|
||||||
|
|
||||||
mesh->mNumBones = static_cast<unsigned int>(numBones);
|
mesh->mNumBones = static_cast<unsigned int>(numBones);
|
||||||
mesh->mBones = new aiBone *[mesh->mNumBones];
|
mesh->mBones = new aiBone *[mesh->mNumBones];
|
||||||
|
@ -1175,7 +1180,7 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
|
||||||
// mapping which makes things doubly-slow.
|
// mapping which makes things doubly-slow.
|
||||||
|
|
||||||
mat4 *pbindMatrices = nullptr;
|
mat4 *pbindMatrices = nullptr;
|
||||||
node.skin->inverseBindMatrices->ExtractData(pbindMatrices);
|
node.skin->inverseBindMatrices->ExtractData(pbindMatrices, nullptr);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < numBones; ++i) {
|
for (uint32_t i = 0; i < numBones; ++i) {
|
||||||
const std::vector<aiVertexWeight> &weights = weighting[i];
|
const std::vector<aiVertexWeight> &weights = weighting[i];
|
||||||
|
@ -1221,11 +1226,11 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.camera) {
|
if (node.camera) {
|
||||||
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
|
mScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.light) {
|
if (node.light) {
|
||||||
pScene->mLights[node.light.GetIndex()]->mName = ainode->mName;
|
mScene->mLights[node.light.GetIndex()]->mName = ainode->mName;
|
||||||
|
|
||||||
// range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
|
// range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
|
||||||
// it is added to meta data of parent node, because there is no other place to put it
|
// it is added to meta data of parent node, because there is no other place to put it
|
||||||
|
@ -1257,7 +1262,7 @@ void glTF2Importer::ImportNodes(glTF2::Asset &r) {
|
||||||
// The root nodes
|
// The root nodes
|
||||||
unsigned int numRootNodes = unsigned(rootNodes.size());
|
unsigned int numRootNodes = unsigned(rootNodes.size());
|
||||||
if (numRootNodes == 1) { // a single root node: use it
|
if (numRootNodes == 1) { // a single root node: use it
|
||||||
mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
|
mScene->mRootNode = ImportNode(r, rootNodes[0]);
|
||||||
} else if (numRootNodes > 1) { // more than one root node: create a fake root
|
} else if (numRootNodes > 1) { // more than one root node: create a fake root
|
||||||
aiNode *root = mScene->mRootNode = new aiNode("ROOT");
|
aiNode *root = mScene->mRootNode = new aiNode("ROOT");
|
||||||
|
|
||||||
|
@ -1265,7 +1270,7 @@ void glTF2Importer::ImportNodes(glTF2::Asset &r) {
|
||||||
std::fill(root->mChildren, root->mChildren + numRootNodes, nullptr);
|
std::fill(root->mChildren, root->mChildren + numRootNodes, nullptr);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numRootNodes; ++i) {
|
for (unsigned int i = 0; i < numRootNodes; ++i) {
|
||||||
aiNode *node = ImportNode(mScene, r, meshOffsets, rootNodes[i]);
|
aiNode *node = ImportNode(r, rootNodes[i]);
|
||||||
node->mParent = root;
|
node->mParent = root;
|
||||||
root->mChildren[root->mNumChildren++] = node;
|
root->mChildren[root->mNumChildren++] = node;
|
||||||
}
|
}
|
||||||
|
@ -1666,6 +1671,7 @@ void glTF2Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IO
|
||||||
|
|
||||||
// clean all member arrays
|
// clean all member arrays
|
||||||
meshOffsets.clear();
|
meshOffsets.clear();
|
||||||
|
mVertexRemappingTables.clear();
|
||||||
mEmbeddedTexIdxs.clear();
|
mEmbeddedTexIdxs.clear();
|
||||||
|
|
||||||
this->mScene = pScene;
|
this->mScene = pScene;
|
||||||
|
|
|
@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_GLTF2IMPORTER_H_INC
|
#define AI_GLTF2IMPORTER_H_INC
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
|
#include <AssetLib/glTF2/glTF2Asset.h>
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ namespace Assimp {
|
||||||
class glTF2Importer : public BaseImporter {
|
class glTF2Importer : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
glTF2Importer();
|
glTF2Importer();
|
||||||
~glTF2Importer() override;
|
~glTF2Importer() override = default;
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -76,10 +77,12 @@ private:
|
||||||
void ImportNodes(glTF2::Asset &a);
|
void ImportNodes(glTF2::Asset &a);
|
||||||
void ImportAnimations(glTF2::Asset &a);
|
void ImportAnimations(glTF2::Asset &a);
|
||||||
void ImportCommonMetadata(glTF2::Asset &a);
|
void ImportCommonMetadata(glTF2::Asset &a);
|
||||||
|
aiNode *ImportNode(glTF2::Asset &r, glTF2::Ref<glTF2::Node> &ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<unsigned int> meshOffsets;
|
std::vector<unsigned int> meshOffsets;
|
||||||
std::vector<int> mEmbeddedTexIdxs;
|
std::vector<int> mEmbeddedTexIdxs;
|
||||||
|
std::vector<std::vector<unsigned int>> mVertexRemappingTables; // for each converted aiMesh in the scene, it stores a list of vertices that are actually used
|
||||||
aiScene *mScene;
|
aiScene *mScene;
|
||||||
|
|
||||||
/// An instance of rapidjson::IRemoteSchemaDocumentProvider
|
/// An instance of rapidjson::IRemoteSchemaDocumentProvider
|
||||||
|
|
|
@ -81,6 +81,7 @@ void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) {
|
void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) {
|
||||||
this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
|
this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
|
||||||
|
this->mRemoveEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -172,9 +173,9 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove empty bones
|
// remove empty bones
|
||||||
#ifdef AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES
|
if (mRemoveEmptyBones) {
|
||||||
pMesh->mNumBones = removeEmptyBones(pMesh);
|
pMesh->mNumBones = removeEmptyBones(pMesh);
|
||||||
#endif // AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES
|
}
|
||||||
|
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
|
ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
|
||||||
|
|
|
@ -133,6 +133,7 @@ public:
|
||||||
|
|
||||||
/** Maximum number of bones influencing any single vertex. */
|
/** Maximum number of bones influencing any single vertex. */
|
||||||
unsigned int mMaxWeights;
|
unsigned int mMaxWeights;
|
||||||
|
bool mRemoveEmptyBones;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
Loading…
Reference in New Issue