Merge branch 'master' into issue_4349
commit
0904490150
|
@ -238,6 +238,7 @@ void ObjFileMtlImporter::load() {
|
||||||
|
|
||||||
case 'a': // Anisotropy
|
case 'a': // Anisotropy
|
||||||
{
|
{
|
||||||
|
++m_DataIt;
|
||||||
getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy);
|
getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy);
|
||||||
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
|
|
@ -78,6 +78,7 @@ SET( PUBLIC_HEADERS
|
||||||
${HEADER_PATH}/matrix4x4.h
|
${HEADER_PATH}/matrix4x4.h
|
||||||
${HEADER_PATH}/matrix4x4.inl
|
${HEADER_PATH}/matrix4x4.inl
|
||||||
${HEADER_PATH}/mesh.h
|
${HEADER_PATH}/mesh.h
|
||||||
|
${HEADER_PATH}/ObjMaterial.h
|
||||||
${HEADER_PATH}/pbrmaterial.h
|
${HEADER_PATH}/pbrmaterial.h
|
||||||
${HEADER_PATH}/GltfMaterial.h
|
${HEADER_PATH}/GltfMaterial.h
|
||||||
${HEADER_PATH}/postprocess.h
|
${HEADER_PATH}/postprocess.h
|
||||||
|
|
|
@ -32,13 +32,13 @@ PROJECT_NAME = Assimp
|
||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "v5.0.1. (December 2020)"
|
PROJECT_NUMBER = "v5.2.2 (January 2022)"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer
|
# for a project that appears at the top of each page and should give viewer
|
||||||
# a quick idea about the purpose of the project. Keep the description short.
|
# a quick idea about the purpose of the project. Keep the description short.
|
||||||
|
|
||||||
PROJECT_BRIEF =
|
PROJECT_BRIEF = The Asset-Importer-Lib API documentation.
|
||||||
|
|
||||||
# With the PROJECT_LOGO tag one can specify an logo or icon that is
|
# With the PROJECT_LOGO tag one can specify an logo or icon that is
|
||||||
# included in the documentation. The maximum height of the logo should not
|
# included in the documentation. The maximum height of the logo should not
|
||||||
|
|
|
@ -50,12 +50,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const char* AICMD_MSG_INFO_HELP_E =
|
const char *AICMD_MSG_INFO_HELP_E =
|
||||||
"assimp info <file> [-r] [-v]\n"
|
"assimp info <file> [-r] [-v]\n"
|
||||||
"\tPrint basic structure of a 3D model\n"
|
"\tPrint basic structure of a 3D model\n"
|
||||||
"\t-r,--raw: No postprocessing, do a raw import\n"
|
"\t-r,--raw: No postprocessing, do a raw import\n"
|
||||||
"\t-v,--verbose: Print verbose info such as node transform data\n"
|
"\t-v,--verbose: Print verbose info such as node transform data\n"
|
||||||
"\t-s, --silent: Print only minimal info\n";
|
"\t-s, --silent: Print only minimal info\n";
|
||||||
|
|
||||||
const char *TREE_BRANCH_ASCII = "|-";
|
const char *TREE_BRANCH_ASCII = "|-";
|
||||||
const char *TREE_BRANCH_UTF8 = "\xe2\x94\x9c\xe2\x95\xb4";
|
const char *TREE_BRANCH_UTF8 = "\xe2\x94\x9c\xe2\x95\xb4";
|
||||||
|
@ -73,411 +73,433 @@ const char *TREE_STOP = TREE_STOP_UTF8;
|
||||||
const char *TREE_CONTINUE = TREE_CONTINUE_UTF8;
|
const char *TREE_CONTINUE = TREE_CONTINUE_UTF8;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int CountNodes(const aiNode* root)
|
unsigned int CountNodes(const aiNode *root) {
|
||||||
{
|
unsigned int i = 0;
|
||||||
unsigned int i = 0;
|
for (unsigned int a = 0; a < root->mNumChildren; ++a) {
|
||||||
for (unsigned int a = 0; a < root->mNumChildren; ++a ) {
|
i += CountNodes(root->mChildren[a]);
|
||||||
i += CountNodes(root->mChildren[a]);
|
}
|
||||||
}
|
return 1 + i;
|
||||||
return 1+i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int GetMaxDepth(const aiNode* root)
|
unsigned int GetMaxDepth(const aiNode *root) {
|
||||||
{
|
unsigned int cnt = 0;
|
||||||
unsigned int cnt = 0;
|
for (unsigned int i = 0; i < root->mNumChildren; ++i) {
|
||||||
for (unsigned int i = 0; i < root->mNumChildren; ++i ) {
|
cnt = std::max(cnt, GetMaxDepth(root->mChildren[i]));
|
||||||
cnt = std::max(cnt,GetMaxDepth(root->mChildren[i]));
|
}
|
||||||
}
|
return cnt + 1;
|
||||||
return cnt+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int CountVertices(const aiScene* scene)
|
unsigned int CountVertices(const aiScene *scene) {
|
||||||
{
|
unsigned int cnt = 0;
|
||||||
unsigned int cnt = 0;
|
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
||||||
for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
cnt += scene->mMeshes[i]->mNumVertices;
|
||||||
cnt += scene->mMeshes[i]->mNumVertices;
|
}
|
||||||
}
|
return cnt;
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int CountFaces(const aiScene* scene)
|
unsigned int CountFaces(const aiScene *scene) {
|
||||||
{
|
unsigned int cnt = 0;
|
||||||
unsigned int cnt = 0;
|
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
||||||
for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
cnt += scene->mMeshes[i]->mNumFaces;
|
||||||
cnt += scene->mMeshes[i]->mNumFaces;
|
}
|
||||||
}
|
return cnt;
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int CountBones(const aiScene* scene)
|
unsigned int CountBones(const aiScene *scene) {
|
||||||
{
|
unsigned int cnt = 0;
|
||||||
unsigned int cnt = 0;
|
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
||||||
for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
cnt += scene->mMeshes[i]->mNumBones;
|
||||||
cnt += scene->mMeshes[i]->mNumBones;
|
}
|
||||||
}
|
return cnt;
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int CountAnimChannels(const aiScene* scene)
|
unsigned int CountAnimChannels(const aiScene *scene) {
|
||||||
{
|
unsigned int cnt = 0;
|
||||||
unsigned int cnt = 0;
|
for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
|
||||||
for(unsigned int i = 0; i < scene->mNumAnimations; ++i) {
|
cnt += scene->mAnimations[i]->mNumChannels;
|
||||||
cnt += scene->mAnimations[i]->mNumChannels;
|
}
|
||||||
}
|
return cnt;
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int GetAvgFacePerMesh(const aiScene* scene) {
|
unsigned int GetAvgFacePerMesh(const aiScene *scene) {
|
||||||
return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountFaces(scene)/scene->mNumMeshes) : 0;
|
return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountFaces(scene) / scene->mNumMeshes) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
unsigned int GetAvgVertsPerMesh(const aiScene* scene) {
|
unsigned int GetAvgVertsPerMesh(const aiScene *scene) {
|
||||||
return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountVertices(scene)/scene->mNumMeshes) : 0;
|
return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountVertices(scene) / scene->mNumMeshes) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void FindSpecialPoints(const aiScene* scene,const aiNode* root,aiVector3D special_points[3],const aiMatrix4x4& mat=aiMatrix4x4())
|
void FindSpecialPoints(const aiScene *scene, const aiNode *root, aiVector3D special_points[3], const aiMatrix4x4 &mat = aiMatrix4x4()) {
|
||||||
{
|
// XXX that could be greatly simplified by using code from code/ProcessHelper.h
|
||||||
// XXX that could be greatly simplified by using code from code/ProcessHelper.h
|
// XXX I just don't want to include it here.
|
||||||
// XXX I just don't want to include it here.
|
const aiMatrix4x4 trafo = root->mTransformation * mat;
|
||||||
const aiMatrix4x4 trafo = root->mTransformation*mat;
|
for (unsigned int i = 0; i < root->mNumMeshes; ++i) {
|
||||||
for(unsigned int i = 0; i < root->mNumMeshes; ++i) {
|
const aiMesh *mesh = scene->mMeshes[root->mMeshes[i]];
|
||||||
const aiMesh* mesh = scene->mMeshes[root->mMeshes[i]];
|
|
||||||
|
|
||||||
for(unsigned int a = 0; a < mesh->mNumVertices; ++a) {
|
for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
|
||||||
aiVector3D v = trafo*mesh->mVertices[a];
|
aiVector3D v = trafo * mesh->mVertices[a];
|
||||||
|
|
||||||
special_points[0].x = std::min(special_points[0].x,v.x);
|
special_points[0].x = std::min(special_points[0].x, v.x);
|
||||||
special_points[0].y = std::min(special_points[0].y,v.y);
|
special_points[0].y = std::min(special_points[0].y, v.y);
|
||||||
special_points[0].z = std::min(special_points[0].z,v.z);
|
special_points[0].z = std::min(special_points[0].z, v.z);
|
||||||
|
|
||||||
special_points[1].x = std::max(special_points[1].x,v.x);
|
special_points[1].x = std::max(special_points[1].x, v.x);
|
||||||
special_points[1].y = std::max(special_points[1].y,v.y);
|
special_points[1].y = std::max(special_points[1].y, v.y);
|
||||||
special_points[1].z = std::max(special_points[1].z,v.z);
|
special_points[1].z = std::max(special_points[1].z, v.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i = 0; i < root->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < root->mNumChildren; ++i) {
|
||||||
FindSpecialPoints(scene,root->mChildren[i],special_points,trafo);
|
FindSpecialPoints(scene, root->mChildren[i], special_points, trafo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void FindSpecialPoints(const aiScene* scene,aiVector3D special_points[3])
|
void FindSpecialPoints(const aiScene *scene, aiVector3D special_points[3]) {
|
||||||
{
|
special_points[0] = aiVector3D(1e10, 1e10, 1e10);
|
||||||
special_points[0] = aiVector3D(1e10,1e10,1e10);
|
special_points[1] = aiVector3D(-1e10, -1e10, -1e10);
|
||||||
special_points[1] = aiVector3D(-1e10,-1e10,-1e10);
|
|
||||||
|
|
||||||
FindSpecialPoints(scene,scene->mRootNode,special_points);
|
FindSpecialPoints(scene, scene->mRootNode, special_points);
|
||||||
special_points[2] = (special_points[0]+special_points[1])*(ai_real)0.5;
|
special_points[2] = (special_points[0] + special_points[1]) * (ai_real)0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
std::string FindPTypes(const aiScene* scene)
|
std::string FindPTypes(const aiScene *scene) {
|
||||||
{
|
bool haveit[4] = { 0 };
|
||||||
bool haveit[4] = {0};
|
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
||||||
for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
const unsigned int pt = scene->mMeshes[i]->mPrimitiveTypes;
|
||||||
const unsigned int pt = scene->mMeshes[i]->mPrimitiveTypes;
|
if (pt & aiPrimitiveType_POINT) {
|
||||||
if (pt & aiPrimitiveType_POINT) {
|
haveit[0] = true;
|
||||||
haveit[0]=true;
|
}
|
||||||
}
|
if (pt & aiPrimitiveType_LINE) {
|
||||||
if (pt & aiPrimitiveType_LINE) {
|
haveit[1] = true;
|
||||||
haveit[1]=true;
|
}
|
||||||
}
|
if (pt & aiPrimitiveType_TRIANGLE) {
|
||||||
if (pt & aiPrimitiveType_TRIANGLE) {
|
haveit[2] = true;
|
||||||
haveit[2]=true;
|
}
|
||||||
}
|
if (pt & aiPrimitiveType_POLYGON) {
|
||||||
if (pt & aiPrimitiveType_POLYGON) {
|
haveit[3] = true;
|
||||||
haveit[3]=true;
|
}
|
||||||
}
|
}
|
||||||
}
|
return (haveit[0] ? std::string("points") : "") + (haveit[1] ? "lines" : "") +
|
||||||
return (haveit[0]?std::string("points"):"")+(haveit[1]?"lines":"")+
|
(haveit[2] ? "triangles" : "") + (haveit[3] ? "n-polygons" : "");
|
||||||
(haveit[2]?"triangles":"")+(haveit[3]?"n-polygons":"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Prettily print the node graph to stdout
|
// Prettily print the node graph to stdout
|
||||||
void PrintHierarchy(
|
void PrintHierarchy(
|
||||||
const aiNode* node,
|
const aiNode *node,
|
||||||
const std::string &indent,
|
const std::string &indent,
|
||||||
bool verbose,
|
bool verbose,
|
||||||
bool last = false,
|
bool last = false,
|
||||||
bool first = true
|
bool first = true) {
|
||||||
){
|
// tree visualization
|
||||||
// tree visualization
|
std::string branchchar;
|
||||||
std::string branchchar;
|
if (first) {
|
||||||
if (first) { branchchar = ""; }
|
branchchar = "";
|
||||||
else if (last) { branchchar = TREE_STOP; } // "'-"
|
} else if (last) {
|
||||||
else { branchchar = TREE_BRANCH; } // "|-"
|
branchchar = TREE_STOP;
|
||||||
|
} // "'-"
|
||||||
|
else {
|
||||||
|
branchchar = TREE_BRANCH;
|
||||||
|
} // "|-"
|
||||||
|
|
||||||
// print the indent and the branch character and the name
|
// print the indent and the branch character and the name
|
||||||
std::cout << indent << branchchar << node->mName.C_Str();
|
std::cout << indent << branchchar << node->mName.C_Str();
|
||||||
|
|
||||||
// if there are meshes attached, indicate this
|
// if there are meshes attached, indicate this
|
||||||
if (node->mNumMeshes) {
|
if (node->mNumMeshes) {
|
||||||
std::cout << " (mesh ";
|
std::cout << " (mesh ";
|
||||||
bool sep = false;
|
bool sep = false;
|
||||||
for (size_t i=0; i < node->mNumMeshes; ++i) {
|
for (size_t i = 0; i < node->mNumMeshes; ++i) {
|
||||||
unsigned int mesh_index = node->mMeshes[i];
|
unsigned int mesh_index = node->mMeshes[i];
|
||||||
if (sep) { std::cout << ", "; }
|
if (sep) {
|
||||||
std::cout << mesh_index;
|
std::cout << ", ";
|
||||||
sep = true;
|
}
|
||||||
}
|
std::cout << mesh_index;
|
||||||
std::cout << ")";
|
sep = true;
|
||||||
}
|
}
|
||||||
|
std::cout << ")";
|
||||||
|
}
|
||||||
|
|
||||||
// finish the line
|
// finish the line
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// in verbose mode, print the transform data as well
|
// in verbose mode, print the transform data as well
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
// indent to use
|
// indent to use
|
||||||
std::string indentadd;
|
std::string indentadd;
|
||||||
if (last) { indentadd += " "; }
|
if (last) {
|
||||||
else { indentadd += TREE_CONTINUE; } // "| "..
|
indentadd += " ";
|
||||||
if (node->mNumChildren == 0) { indentadd += " "; }
|
} else {
|
||||||
else { indentadd += TREE_CONTINUE; } // .."| "
|
indentadd += TREE_CONTINUE;
|
||||||
aiVector3D s, r, t;
|
} // "| "..
|
||||||
node->mTransformation.Decompose(s, r, t);
|
if (node->mNumChildren == 0) {
|
||||||
if (s.x != 1.0 || s.y != 1.0 || s.z != 1.0) {
|
indentadd += " ";
|
||||||
std::cout << indent << indentadd;
|
} else {
|
||||||
printf(" S:[%f %f %f]\n", s.x, s.y, s.z);
|
indentadd += TREE_CONTINUE;
|
||||||
}
|
} // .."| "
|
||||||
if (r.x || r.y || r.z) {
|
aiVector3D s, r, t;
|
||||||
std::cout << indent << indentadd;
|
node->mTransformation.Decompose(s, r, t);
|
||||||
printf(" R:[%f %f %f]\n", r.x, r.y, r.z);
|
if (s.x != 1.0 || s.y != 1.0 || s.z != 1.0) {
|
||||||
}
|
std::cout << indent << indentadd;
|
||||||
if (t.x || t.y || t.z) {
|
printf(" S:[%f %f %f]\n", s.x, s.y, s.z);
|
||||||
std::cout << indent << indentadd;
|
}
|
||||||
printf(" T:[%f %f %f]\n", t.x, t.y, t.z);
|
if (r.x || r.y || r.z) {
|
||||||
}
|
std::cout << indent << indentadd;
|
||||||
}
|
printf(" R:[%f %f %f]\n", r.x, r.y, r.z);
|
||||||
|
}
|
||||||
|
if (t.x || t.y || t.z) {
|
||||||
|
std::cout << indent << indentadd;
|
||||||
|
printf(" T:[%f %f %f]\n", t.x, t.y, t.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// and recurse
|
// and recurse
|
||||||
std::string nextIndent;
|
std::string nextIndent;
|
||||||
if (first) { nextIndent = indent; }
|
if (first) {
|
||||||
else if (last) { nextIndent = indent + " "; }
|
nextIndent = indent;
|
||||||
else { nextIndent = indent + TREE_CONTINUE; } // "| "
|
} else if (last) {
|
||||||
for (size_t i = 0; i < node->mNumChildren; ++i) {
|
nextIndent = indent + " ";
|
||||||
bool lastone = (i == node->mNumChildren - 1);
|
} else {
|
||||||
PrintHierarchy(
|
nextIndent = indent + TREE_CONTINUE;
|
||||||
node->mChildren[i],
|
} // "| "
|
||||||
nextIndent,
|
for (size_t i = 0; i < node->mNumChildren; ++i) {
|
||||||
verbose,
|
bool lastone = (i == node->mNumChildren - 1);
|
||||||
lastone,
|
PrintHierarchy(
|
||||||
false
|
node->mChildren[i],
|
||||||
);
|
nextIndent,
|
||||||
}
|
verbose,
|
||||||
|
lastone,
|
||||||
|
false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Implementation of the assimp info utility to print basic file info
|
// Implementation of the assimp info utility to print basic file info
|
||||||
int Assimp_Info (const char* const* params, unsigned int num) {
|
int Assimp_Info(const char *const *params, unsigned int num) {
|
||||||
// --help
|
// --help
|
||||||
if (!strcmp( params[0],"-h")||!strcmp( params[0],"--help")||!strcmp( params[0],"-?") ) {
|
if (!strcmp(params[0], "-h") || !strcmp(params[0], "--help") || !strcmp(params[0], "-?")) {
|
||||||
printf("%s",AICMD_MSG_INFO_HELP_E);
|
printf("%s", AICMD_MSG_INFO_HELP_E);
|
||||||
return AssimpCmdError::Success;
|
return AssimpCmdError::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// asssimp info <file> [-r]
|
// asssimp info <file> [-r]
|
||||||
if (num < 1) {
|
if (num < 1) {
|
||||||
printf("assimp info: Invalid number of arguments. "
|
printf("assimp info: Invalid number of arguments. "
|
||||||
"See \'assimp info --help\'\n");
|
"See \'assimp info --help\'\n");
|
||||||
return AssimpCmdError::InvalidNumberOfArguments;
|
return AssimpCmdError::InvalidNumberOfArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string in = std::string(params[0]);
|
const std::string in = std::string(params[0]);
|
||||||
|
|
||||||
// get -r and -v arguments
|
// get -r and -v arguments
|
||||||
bool raw = false;
|
bool raw = false;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
for(unsigned int i = 1; i < num; ++i) {
|
for (unsigned int i = 1; i < num; ++i) {
|
||||||
if (!strcmp(params[i],"--raw")||!strcmp(params[i],"-r")) {
|
if (!strcmp(params[i], "--raw") || !strcmp(params[i], "-r")) {
|
||||||
raw = true;
|
raw = true;
|
||||||
}
|
}
|
||||||
if (!strcmp(params[i],"--verbose")||!strcmp(params[i],"-v")) {
|
if (!strcmp(params[i], "--verbose") || !strcmp(params[i], "-v")) {
|
||||||
verbose = true;
|
verbose = true;
|
||||||
}
|
}
|
||||||
if (!strcmp(params[i], "--silent") || !strcmp(params[i], "-s")) {
|
if (!strcmp(params[i], "--silent") || !strcmp(params[i], "-s")) {
|
||||||
silent = true;
|
silent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verbose and silent at the same time are not allowed
|
// Verbose and silent at the same time are not allowed
|
||||||
if ( verbose && silent ) {
|
if (verbose && silent) {
|
||||||
printf("assimp info: Invalid arguments, verbose and silent at the same time are forbidden. ");
|
printf("assimp info: Invalid arguments, verbose and silent at the same time are forbidden. ");
|
||||||
return AssimpCmdInfoError::InvalidCombinaisonOfArguments;
|
return AssimpCmdInfoError::InvalidCombinaisonOfArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse post-processing flags unless -r was specified
|
// Parse post-processing flags unless -r was specified
|
||||||
ImportData import;
|
ImportData import;
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
// get import flags
|
// get import flags
|
||||||
ProcessStandardArguments(import, params + 1, num - 1);
|
ProcessStandardArguments(import, params + 1, num - 1);
|
||||||
|
|
||||||
//No custom post process flags defined, we set all the post process flags active
|
//No custom post process flags defined, we set all the post process flags active
|
||||||
if(import.ppFlags == 0)
|
if (import.ppFlags == 0)
|
||||||
import.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
|
import.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
// import the main model
|
// import the main model
|
||||||
const aiScene* scene = ImportModel(import,in);
|
const aiScene *scene = ImportModel(import, in);
|
||||||
if (!scene) {
|
if (!scene) {
|
||||||
printf("assimp info: Unable to load input file %s\n",
|
printf("assimp info: Unable to load input file %s\n",
|
||||||
in.c_str());
|
in.c_str());
|
||||||
return AssimpCmdError::FailedToLoadInputFile;
|
return AssimpCmdError::FailedToLoadInputFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMemoryInfo mem;
|
aiMemoryInfo mem;
|
||||||
globalImporter->GetMemoryRequirements(mem);
|
globalImporter->GetMemoryRequirements(mem);
|
||||||
|
|
||||||
|
static const char *format_string =
|
||||||
|
"Memory consumption: %i B\n"
|
||||||
|
"Nodes: %i\n"
|
||||||
|
"Maximum depth %i\n"
|
||||||
|
"Meshes: %i\n"
|
||||||
|
"Animations: %i\n"
|
||||||
|
"Textures (embed.): %i\n"
|
||||||
|
"Materials: %i\n"
|
||||||
|
"Cameras: %i\n"
|
||||||
|
"Lights: %i\n"
|
||||||
|
"Vertices: %i\n"
|
||||||
|
"Faces: %i\n"
|
||||||
|
"Bones: %i\n"
|
||||||
|
"Animation Channels: %i\n"
|
||||||
|
"Primitive Types: %s\n"
|
||||||
|
"Average faces/mesh %i\n"
|
||||||
|
"Average verts/mesh %i\n"
|
||||||
|
"Minimum point (%f %f %f)\n"
|
||||||
|
"Maximum point (%f %f %f)\n"
|
||||||
|
"Center point (%f %f %f)\n"
|
||||||
|
|
||||||
static const char* format_string =
|
;
|
||||||
"Memory consumption: %i B\n"
|
|
||||||
"Nodes: %i\n"
|
|
||||||
"Maximum depth %i\n"
|
|
||||||
"Meshes: %i\n"
|
|
||||||
"Animations: %i\n"
|
|
||||||
"Textures (embed.): %i\n"
|
|
||||||
"Materials: %i\n"
|
|
||||||
"Cameras: %i\n"
|
|
||||||
"Lights: %i\n"
|
|
||||||
"Vertices: %i\n"
|
|
||||||
"Faces: %i\n"
|
|
||||||
"Bones: %i\n"
|
|
||||||
"Animation Channels: %i\n"
|
|
||||||
"Primitive Types: %s\n"
|
|
||||||
"Average faces/mesh %i\n"
|
|
||||||
"Average verts/mesh %i\n"
|
|
||||||
"Minimum point (%f %f %f)\n"
|
|
||||||
"Maximum point (%f %f %f)\n"
|
|
||||||
"Center point (%f %f %f)\n"
|
|
||||||
|
|
||||||
;
|
aiVector3D special_points[3];
|
||||||
|
FindSpecialPoints(scene, special_points);
|
||||||
|
printf(format_string,
|
||||||
|
mem.total,
|
||||||
|
CountNodes(scene->mRootNode),
|
||||||
|
GetMaxDepth(scene->mRootNode),
|
||||||
|
scene->mNumMeshes,
|
||||||
|
scene->mNumAnimations,
|
||||||
|
scene->mNumTextures,
|
||||||
|
scene->mNumMaterials,
|
||||||
|
scene->mNumCameras,
|
||||||
|
scene->mNumLights,
|
||||||
|
CountVertices(scene),
|
||||||
|
CountFaces(scene),
|
||||||
|
CountBones(scene),
|
||||||
|
CountAnimChannels(scene),
|
||||||
|
FindPTypes(scene).c_str(),
|
||||||
|
GetAvgFacePerMesh(scene),
|
||||||
|
GetAvgVertsPerMesh(scene),
|
||||||
|
special_points[0][0], special_points[0][1], special_points[0][2],
|
||||||
|
special_points[1][0], special_points[1][1], special_points[1][2],
|
||||||
|
special_points[2][0], special_points[2][1], special_points[2][2]);
|
||||||
|
|
||||||
aiVector3D special_points[3];
|
if (silent) {
|
||||||
FindSpecialPoints(scene,special_points);
|
printf("\n");
|
||||||
printf(format_string,
|
return AssimpCmdError::Success;
|
||||||
mem.total,
|
}
|
||||||
CountNodes(scene->mRootNode),
|
|
||||||
GetMaxDepth(scene->mRootNode),
|
|
||||||
scene->mNumMeshes,
|
|
||||||
scene->mNumAnimations,
|
|
||||||
scene->mNumTextures,
|
|
||||||
scene->mNumMaterials,
|
|
||||||
scene->mNumCameras,
|
|
||||||
scene->mNumLights,
|
|
||||||
CountVertices(scene),
|
|
||||||
CountFaces(scene),
|
|
||||||
CountBones(scene),
|
|
||||||
CountAnimChannels(scene),
|
|
||||||
FindPTypes(scene).c_str(),
|
|
||||||
GetAvgFacePerMesh(scene),
|
|
||||||
GetAvgVertsPerMesh(scene),
|
|
||||||
special_points[0][0],special_points[0][1],special_points[0][2],
|
|
||||||
special_points[1][0],special_points[1][1],special_points[1][2],
|
|
||||||
special_points[2][0],special_points[2][1],special_points[2][2]
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (silent)
|
// meshes
|
||||||
{
|
if (scene->mNumMeshes) {
|
||||||
printf("\n");
|
printf("\nMeshes: (name) [vertices / bones / faces | primitive_types]\n");
|
||||||
return AssimpCmdError::Success;
|
}
|
||||||
}
|
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
||||||
|
const aiMesh *mesh = scene->mMeshes[i];
|
||||||
|
printf(" %d (%s)", i, mesh->mName.C_Str());
|
||||||
|
printf(
|
||||||
|
": [%d / %d / %d |",
|
||||||
|
mesh->mNumVertices,
|
||||||
|
mesh->mNumBones,
|
||||||
|
mesh->mNumFaces);
|
||||||
|
const unsigned int ptypes = mesh->mPrimitiveTypes;
|
||||||
|
if (ptypes & aiPrimitiveType_POINT) {
|
||||||
|
printf(" point");
|
||||||
|
}
|
||||||
|
if (ptypes & aiPrimitiveType_LINE) {
|
||||||
|
printf(" line");
|
||||||
|
}
|
||||||
|
if (ptypes & aiPrimitiveType_TRIANGLE) {
|
||||||
|
printf(" triangle");
|
||||||
|
}
|
||||||
|
if (ptypes & aiPrimitiveType_POLYGON) {
|
||||||
|
printf(" polygon");
|
||||||
|
}
|
||||||
|
printf("]\n");
|
||||||
|
}
|
||||||
|
|
||||||
// meshes
|
// materials
|
||||||
if (scene->mNumMeshes) {
|
if (scene->mNumMaterials)
|
||||||
printf("\nMeshes: (name) [vertices / bones / faces | primitive_types]\n");
|
printf("\nNamed Materials:");
|
||||||
}
|
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
|
||||||
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
|
const aiMaterial *mat = scene->mMaterials[i];
|
||||||
const aiMesh* mesh = scene->mMeshes[i];
|
aiString name = mat->GetName();
|
||||||
printf(" %d (%s)", i, mesh->mName.C_Str());
|
printf("\n \'%s\'", name.data);
|
||||||
printf(
|
if (mat->mNumProperties)
|
||||||
": [%d / %d / %d |",
|
printf(" (prop) [index / bytes | texture semantic]");
|
||||||
mesh->mNumVertices,
|
for (unsigned p = 0; p < mat->mNumProperties; p++) {
|
||||||
mesh->mNumBones,
|
const aiMaterialProperty *prop = mat->mProperties[p];
|
||||||
mesh->mNumFaces
|
const aiTextureType textype = static_cast<aiTextureType>(prop->mSemantic);
|
||||||
);
|
printf("\n %d (%s): [%d / %d | %s]",
|
||||||
const unsigned int ptypes = mesh->mPrimitiveTypes;
|
p,
|
||||||
if (ptypes & aiPrimitiveType_POINT) { printf(" point"); }
|
prop->mKey.data,
|
||||||
if (ptypes & aiPrimitiveType_LINE) { printf(" line"); }
|
prop->mIndex,
|
||||||
if (ptypes & aiPrimitiveType_TRIANGLE) { printf(" triangle"); }
|
prop->mDataLength,
|
||||||
if (ptypes & aiPrimitiveType_POLYGON) { printf(" polygon"); }
|
TextureTypeToString(textype));
|
||||||
printf("]\n");
|
}
|
||||||
}
|
}
|
||||||
|
if (scene->mNumMaterials) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
// materials
|
// textures
|
||||||
unsigned int total=0;
|
unsigned int total = 0;
|
||||||
for(unsigned int i = 0;i < scene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
|
||||||
aiString name;
|
aiString name;
|
||||||
if (AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i],AI_MATKEY_NAME,&name)) {
|
static const aiTextureType types[] = {
|
||||||
printf("%s\n \'%s\'",(total++?"":"\nNamed Materials:" ),name.data);
|
aiTextureType_NONE,
|
||||||
}
|
aiTextureType_DIFFUSE,
|
||||||
}
|
aiTextureType_SPECULAR,
|
||||||
if(total) {
|
aiTextureType_AMBIENT,
|
||||||
printf("\n");
|
aiTextureType_EMISSIVE,
|
||||||
}
|
aiTextureType_HEIGHT,
|
||||||
|
aiTextureType_NORMALS,
|
||||||
|
aiTextureType_SHININESS,
|
||||||
|
aiTextureType_OPACITY,
|
||||||
|
aiTextureType_DISPLACEMENT,
|
||||||
|
aiTextureType_LIGHTMAP,
|
||||||
|
aiTextureType_REFLECTION,
|
||||||
|
aiTextureType_BASE_COLOR,
|
||||||
|
aiTextureType_NORMAL_CAMERA,
|
||||||
|
aiTextureType_EMISSION_COLOR,
|
||||||
|
aiTextureType_METALNESS,
|
||||||
|
aiTextureType_DIFFUSE_ROUGHNESS,
|
||||||
|
aiTextureType_AMBIENT_OCCLUSION,
|
||||||
|
aiTextureType_UNKNOWN
|
||||||
|
};
|
||||||
|
for (unsigned int type = 0; type < sizeof(types) / sizeof(types[0]); ++type) {
|
||||||
|
for (unsigned int idx = 0; AI_SUCCESS == aiGetMaterialString(scene->mMaterials[i],
|
||||||
|
AI_MATKEY_TEXTURE(types[type], idx), &name);
|
||||||
|
++idx) {
|
||||||
|
printf("%s\n \'%s\'", (total++ ? "" : "\nTexture Refs:"), name.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (total) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
// textures
|
// animations
|
||||||
total=0;
|
total = 0;
|
||||||
for(unsigned int i = 0;i < scene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
|
||||||
aiString name;
|
if (scene->mAnimations[i]->mName.length) {
|
||||||
static const aiTextureType types[] = {
|
printf("%s\n \'%s\'", (total++ ? "" : "\nNamed Animations:"), scene->mAnimations[i]->mName.data);
|
||||||
aiTextureType_NONE,
|
}
|
||||||
aiTextureType_DIFFUSE,
|
}
|
||||||
aiTextureType_SPECULAR,
|
if (total) {
|
||||||
aiTextureType_AMBIENT,
|
printf("\n");
|
||||||
aiTextureType_EMISSIVE,
|
}
|
||||||
aiTextureType_HEIGHT,
|
|
||||||
aiTextureType_NORMALS,
|
|
||||||
aiTextureType_SHININESS,
|
|
||||||
aiTextureType_OPACITY,
|
|
||||||
aiTextureType_DISPLACEMENT,
|
|
||||||
aiTextureType_LIGHTMAP,
|
|
||||||
aiTextureType_REFLECTION,
|
|
||||||
aiTextureType_BASE_COLOR,
|
|
||||||
aiTextureType_NORMAL_CAMERA,
|
|
||||||
aiTextureType_EMISSION_COLOR,
|
|
||||||
aiTextureType_METALNESS,
|
|
||||||
aiTextureType_DIFFUSE_ROUGHNESS,
|
|
||||||
aiTextureType_AMBIENT_OCCLUSION,
|
|
||||||
aiTextureType_UNKNOWN
|
|
||||||
};
|
|
||||||
for(unsigned int type = 0; type < sizeof(types)/sizeof(types[0]); ++type) {
|
|
||||||
for(unsigned int idx = 0;AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i],
|
|
||||||
AI_MATKEY_TEXTURE(types[type],idx),&name); ++idx) {
|
|
||||||
printf("%s\n \'%s\'",(total++?"":"\nTexture Refs:" ),name.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(total) {
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// animations
|
// node hierarchy
|
||||||
total=0;
|
printf("\nNode hierarchy:\n");
|
||||||
for(unsigned int i = 0;i < scene->mNumAnimations; ++i) {
|
PrintHierarchy(scene->mRootNode, "", verbose);
|
||||||
if (scene->mAnimations[i]->mName.length) {
|
|
||||||
printf("%s\n \'%s\'",(total++?"":"\nNamed Animations:" ),scene->mAnimations[i]->mName.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(total) {
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// node hierarchy
|
printf("\n");
|
||||||
printf("\nNode hierarchy:\n");
|
return AssimpCmdError::Success;
|
||||||
PrintHierarchy(scene->mRootNode,"",verbose);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
return AssimpCmdError::Success;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue