Merge branch 'master' into issue_4349

pull/4437/head
Kim Kulling 2022-03-15 14:11:57 +01:00 committed by GitHub
commit 0904490150
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 561 additions and 536 deletions

View File

@ -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;

View File

@ -42,23 +42,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER) #if !defined(ASSIMP_BUILD_NO_GLTF_IMPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_IMPORTER)
#include "AssetLib/glTF2/glTF2Importer.h" #include "AssetLib/glTF2/glTF2Importer.h"
#include "PostProcessing/MakeVerboseFormat.h"
#include "AssetLib/glTF2/glTF2Asset.h" #include "AssetLib/glTF2/glTF2Asset.h"
#include "PostProcessing/MakeVerboseFormat.h"
#if !defined(ASSIMP_BUILD_NO_EXPORT) #if !defined(ASSIMP_BUILD_NO_EXPORT)
#include "AssetLib/glTF2/glTF2AssetWriter.h" #include "AssetLib/glTF2/glTF2AssetWriter.h"
#endif #endif
#include <assimp/CreateAnimMesh.h> #include <assimp/CreateAnimMesh.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/commonMetaData.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/commonMetaData.h>
#include <assimp/DefaultIOSystem.h>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@ -111,7 +111,7 @@ const aiImporterDesc *glTF2Importer::GetInfo() const {
return &desc; return &desc;
} }
bool glTF2Importer::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig ) const { bool glTF2Importer::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
const std::string extension = GetExtension(filename); const std::string extension = GetExtension(filename);
if (!checkSig && (extension != "gltf") && (extension != "glb")) { if (!checkSig && (extension != "gltf") && (extension != "glb")) {
return false; return false;
@ -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;
@ -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,8 +1070,7 @@ 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.");
@ -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

View File

@ -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

View File

@ -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

View File

@ -50,7 +50,7 @@ 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"
@ -73,149 +73,144 @@ 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) { branchchar = ""; } if (first) {
else if (last) { branchchar = TREE_STOP; } // "'-" branchchar = "";
else { branchchar = TREE_BRANCH; } // "|-" } else if (last) {
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();
@ -224,9 +219,11 @@ void PrintHierarchy(
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 << ", ";
}
std::cout << mesh_index; std::cout << mesh_index;
sep = true; sep = true;
} }
@ -240,10 +237,16 @@ void PrintHierarchy(
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;
} // "| "..
if (node->mNumChildren == 0) {
indentadd += " ";
} else {
indentadd += TREE_CONTINUE;
} // .."| "
aiVector3D s, r, t; aiVector3D s, r, t;
node->mTransformation.Decompose(s, r, t); node->mTransformation.Decompose(s, r, t);
if (s.x != 1.0 || s.y != 1.0 || s.z != 1.0) { if (s.x != 1.0 || s.y != 1.0 || s.z != 1.0) {
@ -262,9 +265,13 @@ void PrintHierarchy(
// 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) {
nextIndent = indent + " ";
} else {
nextIndent = indent + TREE_CONTINUE;
} // "| "
for (size_t i = 0; i < node->mNumChildren; ++i) { for (size_t i = 0; i < node->mNumChildren; ++i) {
bool lastone = (i == node->mNumChildren - 1); bool lastone = (i == node->mNumChildren - 1);
PrintHierarchy( PrintHierarchy(
@ -272,17 +279,16 @@ void PrintHierarchy(
nextIndent, nextIndent,
verbose, verbose,
lastone, lastone,
false 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;
} }
@ -299,11 +305,11 @@ int Assimp_Info (const char* const* params, unsigned int num) {
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")) {
@ -312,7 +318,7 @@ int Assimp_Info (const char* const* params, unsigned int num) {
} }
// 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;
} }
@ -324,12 +330,12 @@ int Assimp_Info (const char* const* params, unsigned int num) {
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());
@ -339,8 +345,7 @@ int Assimp_Info (const char* const* params, unsigned int num) {
aiMemoryInfo mem; aiMemoryInfo mem;
globalImporter->GetMemoryRequirements(mem); globalImporter->GetMemoryRequirements(mem);
static const char *format_string =
static const char* format_string =
"Memory consumption: %i B\n" "Memory consumption: %i B\n"
"Nodes: %i\n" "Nodes: %i\n"
"Maximum depth %i\n" "Maximum depth %i\n"
@ -364,7 +369,7 @@ int Assimp_Info (const char* const* params, unsigned int num) {
; ;
aiVector3D special_points[3]; aiVector3D special_points[3];
FindSpecialPoints(scene,special_points); FindSpecialPoints(scene, special_points);
printf(format_string, printf(format_string,
mem.total, mem.total,
CountNodes(scene->mRootNode), CountNodes(scene->mRootNode),
@ -382,14 +387,11 @@ int Assimp_Info (const char* const* params, unsigned int num) {
FindPTypes(scene).c_str(), FindPTypes(scene).c_str(),
GetAvgFacePerMesh(scene), GetAvgFacePerMesh(scene),
GetAvgVertsPerMesh(scene), GetAvgVertsPerMesh(scene),
special_points[0][0],special_points[0][1],special_points[0][2], 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[1][0], special_points[1][1], special_points[1][2],
special_points[2][0],special_points[2][1],special_points[2][2] special_points[2][0], special_points[2][1], special_points[2][2]);
)
;
if (silent) if (silent) {
{
printf("\n"); printf("\n");
return AssimpCmdError::Success; return AssimpCmdError::Success;
} }
@ -399,37 +401,56 @@ int Assimp_Info (const char* const* params, unsigned int num) {
printf("\nMeshes: (name) [vertices / bones / faces | primitive_types]\n"); printf("\nMeshes: (name) [vertices / bones / faces | primitive_types]\n");
} }
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
const aiMesh* mesh = scene->mMeshes[i]; const aiMesh *mesh = scene->mMeshes[i];
printf(" %d (%s)", i, mesh->mName.C_Str()); printf(" %d (%s)", i, mesh->mName.C_Str());
printf( printf(
": [%d / %d / %d |", ": [%d / %d / %d |",
mesh->mNumVertices, mesh->mNumVertices,
mesh->mNumBones, mesh->mNumBones,
mesh->mNumFaces mesh->mNumFaces);
);
const unsigned int ptypes = mesh->mPrimitiveTypes; const unsigned int ptypes = mesh->mPrimitiveTypes;
if (ptypes & aiPrimitiveType_POINT) { printf(" point"); } if (ptypes & aiPrimitiveType_POINT) {
if (ptypes & aiPrimitiveType_LINE) { printf(" line"); } printf(" point");
if (ptypes & aiPrimitiveType_TRIANGLE) { printf(" triangle"); } }
if (ptypes & aiPrimitiveType_POLYGON) { printf(" polygon"); } if (ptypes & aiPrimitiveType_LINE) {
printf(" line");
}
if (ptypes & aiPrimitiveType_TRIANGLE) {
printf(" triangle");
}
if (ptypes & aiPrimitiveType_POLYGON) {
printf(" polygon");
}
printf("]\n"); printf("]\n");
} }
// materials // materials
unsigned int total=0; if (scene->mNumMaterials)
for(unsigned int i = 0;i < scene->mNumMaterials; ++i) { printf("\nNamed Materials:");
aiString name; for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
if (AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i],AI_MATKEY_NAME,&name)) { const aiMaterial *mat = scene->mMaterials[i];
printf("%s\n \'%s\'",(total++?"":"\nNamed Materials:" ),name.data); aiString name = mat->GetName();
printf("\n \'%s\'", name.data);
if (mat->mNumProperties)
printf(" (prop) [index / bytes | texture semantic]");
for (unsigned p = 0; p < mat->mNumProperties; p++) {
const aiMaterialProperty *prop = mat->mProperties[p];
const aiTextureType textype = static_cast<aiTextureType>(prop->mSemantic);
printf("\n %d (%s): [%d / %d | %s]",
p,
prop->mKey.data,
prop->mIndex,
prop->mDataLength,
TextureTypeToString(textype));
} }
} }
if(total) { if (scene->mNumMaterials) {
printf("\n"); printf("\n");
} }
// textures // textures
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;
static const aiTextureType types[] = { static const aiTextureType types[] = {
aiTextureType_NONE, aiTextureType_NONE,
@ -452,31 +473,32 @@ int Assimp_Info (const char* const* params, unsigned int num) {
aiTextureType_AMBIENT_OCCLUSION, aiTextureType_AMBIENT_OCCLUSION,
aiTextureType_UNKNOWN aiTextureType_UNKNOWN
}; };
for(unsigned int type = 0; type < sizeof(types)/sizeof(types[0]); ++type) { for (unsigned int type = 0; type < sizeof(types) / sizeof(types[0]); ++type) {
for(unsigned int idx = 0;AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i], for (unsigned int idx = 0; AI_SUCCESS == aiGetMaterialString(scene->mMaterials[i],
AI_MATKEY_TEXTURE(types[type],idx),&name); ++idx) { AI_MATKEY_TEXTURE(types[type], idx), &name);
printf("%s\n \'%s\'",(total++?"":"\nTexture Refs:" ),name.data); ++idx) {
printf("%s\n \'%s\'", (total++ ? "" : "\nTexture Refs:"), name.data);
} }
} }
} }
if(total) { if (total) {
printf("\n"); printf("\n");
} }
// animations // animations
total=0; total = 0;
for(unsigned int i = 0;i < scene->mNumAnimations; ++i) { for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
if (scene->mAnimations[i]->mName.length) { if (scene->mAnimations[i]->mName.length) {
printf("%s\n \'%s\'",(total++?"":"\nNamed Animations:" ),scene->mAnimations[i]->mName.data); printf("%s\n \'%s\'", (total++ ? "" : "\nNamed Animations:"), scene->mAnimations[i]->mName.data);
} }
} }
if(total) { if (total) {
printf("\n"); printf("\n");
} }
// node hierarchy // node hierarchy
printf("\nNode hierarchy:\n"); printf("\nNode hierarchy:\n");
PrintHierarchy(scene->mRootNode,"",verbose); PrintHierarchy(scene->mRootNode, "", verbose);
printf("\n"); printf("\n");
return AssimpCmdError::Success; return AssimpCmdError::Success;