Merge branch 'master' into ClipperUpdate
commit
4de723d497
|
@ -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
|
if (!ignoreUnitSize) {
|
||||||
|
// Apply unit-size scale calculation
|
||||||
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
|
pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
||||||
0, parser.mUnitSize, 0, 0,
|
parser.mUnitSize, 0, 0, 0,
|
||||||
0, 0, parser.mUnitSize, 0,
|
0, parser.mUnitSize, 0, 0,
|
||||||
0, 0, 0, 1);
|
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) {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -731,7 +731,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
indices[cnti++] = static_cast<unsigned int>(index);
|
indices[cnti++] = static_cast<unsigned int>(index);
|
||||||
} else {
|
} else {
|
||||||
ASSIMP_LOG_WARN("DXF: Skip invisible face.");
|
indices[cnti++] = static_cast<unsigned int>(-index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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
|
// clear
|
||||||
delete[](char *) nzDiff;
|
delete[] (char *)nzDiff;
|
||||||
delete[](char *) nzIdx;
|
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) + 0] = (ai_real)key.mValue.x;
|
||||||
values[(i * 3) + 1] = (ai_real) key.mValue.y;
|
values[(i * 3) + 1] = (ai_real)key.mValue.y;
|
||||||
values[(i * 3) + 2] = (ai_real) key.mValue.z;
|
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) + 0] = (ai_real)key.mValue.x;
|
||||||
values[(i * 3) + 1] = (ai_real) key.mValue.y;
|
values[(i * 3) + 1] = (ai_real)key.mValue.y;
|
||||||
values[(i * 3) + 2] = (ai_real) key.mValue.z;
|
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) + 0] = (ai_real)key.mValue.x;
|
||||||
values[(i * 4) + 1] = (ai_real) key.mValue.y;
|
values[(i * 4) + 1] = (ai_real)key.mValue.y;
|
||||||
values[(i * 4) + 2] = (ai_real) key.mValue.z;
|
values[(i * 4) + 2] = (ai_real)key.mValue.z;
|
||||||
values[(i * 4) + 3] = (ai_real) key.mValue.w;
|
values[(i * 4) + 3] = (ai_real)key.mValue.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
|
sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
|
||||||
|
|
|
@ -64,8 +64,14 @@ inline double GetArea2D(const T& v1, const T& v2, const T& v3) {
|
||||||
* The function accepts an unconstrained template parameter for use with
|
* The function accepts an unconstrained template parameter for use with
|
||||||
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
|
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
|
inline int OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
|
||||||
return GetArea2D(p0,p2,p1) > 0;
|
double area = GetArea2D(p0,p2,p1);
|
||||||
|
if(std::abs(area) < ai_epsilon)
|
||||||
|
return 0;
|
||||||
|
else if(area > 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -75,7 +81,10 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2) {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
|
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp) {
|
||||||
// pp should be left side of the three triangle side, by ccw arrow
|
// pp should be left side of the three triangle side, by ccw arrow
|
||||||
return OnLeftSideOfLine2D(p0, p1, pp) && OnLeftSideOfLine2D(p1, p2, pp) && OnLeftSideOfLine2D(p2, p0, pp);
|
int c1 = OnLeftSideOfLine2D(p0, p1, pp);
|
||||||
|
int c2 = OnLeftSideOfLine2D(p1, p2, pp);
|
||||||
|
int c3 = OnLeftSideOfLine2D(p2, p0, pp);
|
||||||
|
return (c1 >= 0) && (c2 >= 0) && (c3 >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,7 +119,7 @@ inline bool IsCCW(T* in, size_t npoints) {
|
||||||
c = std::sqrt(cc);
|
c = std::sqrt(cc);
|
||||||
theta = std::acos((bb + cc - aa) / (2 * b * c));
|
theta = std::acos((bb + cc - aa) / (2 * b * c));
|
||||||
|
|
||||||
if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1])) {
|
if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1]) == 1) {
|
||||||
// if (convex(in[i].x, in[i].y,
|
// if (convex(in[i].x, in[i].y,
|
||||||
// in[i+1].x, in[i+1].y,
|
// in[i+1].x, in[i+1].y,
|
||||||
// in[i+2].x, in[i+2].y)) {
|
// in[i+2].x, in[i+2].y)) {
|
||||||
|
@ -140,7 +149,7 @@ inline bool IsCCW(T* in, size_t npoints) {
|
||||||
//if (convex(in[npoints-2].x, in[npoints-2].y,
|
//if (convex(in[npoints-2].x, in[npoints-2].y,
|
||||||
// in[0].x, in[0].y,
|
// in[0].x, in[0].y,
|
||||||
// in[1].x, in[1].y)) {
|
// in[1].x, in[1].y)) {
|
||||||
if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0])) {
|
if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0]) == 1) {
|
||||||
convex_turn = AI_MATH_PI_F - theta;
|
convex_turn = AI_MATH_PI_F - theta;
|
||||||
convex_sum += convex_turn;
|
convex_sum += convex_turn;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -451,7 +451,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) {
|
||||||
*pnt2 = &temp_verts[next];
|
*pnt2 = &temp_verts[next];
|
||||||
|
|
||||||
// Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1.
|
// Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1.
|
||||||
if (OnLeftSideOfLine2D(*pnt0,*pnt2,*pnt1)) {
|
if (OnLeftSideOfLine2D(*pnt0,*pnt2,*pnt1) == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue