* Adjustment: Update Assimp version to 5.0.1.

This commit is contained in:
Robert MacGregor 2021-10-21 21:14:55 -04:00
parent 14ebeaf3eb
commit 4758f7bdaf
679 changed files with 50502 additions and 19698 deletions

View file

@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
Copyright (c) 2006-2019, assimp team
All rights reserved.
@ -60,8 +60,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/CreateAnimMesh.h>
#include <assimp/commonMetaData.h>
#include <assimp/StringUtils.h>
#include <tuple>
#include <memory>
@ -70,8 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <iomanip>
#include <cstdint>
#include <iostream>
#include <stdlib.h>
namespace Assimp {
namespace FBX {
@ -80,7 +77,7 @@ namespace Assimp {
#define MAGIC_NODE_TAG "_$AssimpFbx$"
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
: defaultMaterialIndex()
@ -99,14 +96,6 @@ namespace Assimp {
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
ConvertAnimations();
// Embedded textures in FBX could be connected to nothing but to itself,
// for instance Texture -> Video connection only but not to the main graph,
// The idea here is to traverse all objects to find these Textures and convert them,
// so later during material conversion it will find converted texture in the textures_converted array.
if (doc.Settings().readTextures)
{
ConvertOrphantEmbeddedTextures();
}
ConvertRootNode();
if (doc.Settings().readAllMaterials) {
@ -156,7 +145,7 @@ namespace Assimp {
out->mRootNode->mName.Set(unique_name);
// root has ID 0
ConvertNodes(0L, out->mRootNode, out->mRootNode);
ConvertNodes(0L, *out->mRootNode);
}
static std::string getAncestorBaseName(const aiNode* node)
@ -190,11 +179,8 @@ namespace Assimp {
GetUniqueName(original_name, unique_name);
return unique_name;
}
/// todo: pre-build node hierarchy
/// todo: get bone from stack
/// todo: make map of aiBone* to aiNode*
/// then update convert clusters to the new format
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
std::vector<aiNode*> nodes;
@ -205,69 +191,62 @@ namespace Assimp {
try {
for (const Connection* con : conns) {
// ignore object-property links
if (con->PropertyName().length()) {
// really important we document why this is ignored.
FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored");
continue; //?
}
// convert connection source object into Object base class
const Object* const object = con->SourceObject();
if (nullptr == object) {
FBXImporter::LogError("failed to convert source object for Model link");
continue;
}
// FBX Model::Cube, Model::Bone001, etc elements
// This detects if we can cast the object into this model structure.
const Object* const object = con->SourceObject();
if (nullptr == object) {
FBXImporter::LogWarn("failed to convert source object for Model link");
continue;
}
const Model* const model = dynamic_cast<const Model*>(object);
if (nullptr != model) {
nodes_chain.clear();
post_nodes_chain.clear();
aiMatrix4x4 new_abs_transform = parent->mTransformation;
std::string node_name = FixNodeName(model->Name());
aiMatrix4x4 new_abs_transform = parent_transform;
std::string unique_name = MakeUniqueNodeName(model, parent);
// even though there is only a single input node, the design of
// assimp (or rather: the complicated transformation chain that
// is employed by fbx) means that we may need multiple aiNode's
// to represent a fbx node's transformation.
const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain);
// generate node transforms - this includes pivot data
// if need_additional_node is true then you t
const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain);
// assert that for the current node we must have at least a single transform
ai_assert(nodes_chain.size());
if (need_additional_node) {
nodes_chain.push_back(new aiNode(node_name));
nodes_chain.push_back(new aiNode(unique_name));
}
//setup metadata on newest node
SetupNodeMetadata(*model, *nodes_chain.back());
// link all nodes in a row
aiNode* last_parent = parent;
for (aiNode* child : nodes_chain) {
ai_assert(child);
aiNode* last_parent = &parent;
for (aiNode* prenode : nodes_chain) {
ai_assert(prenode);
if (last_parent != parent) {
if (last_parent != &parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[1];
last_parent->mChildren[0] = child;
last_parent->mChildren[0] = prenode;
}
child->mParent = last_parent;
last_parent = child;
prenode->mParent = last_parent;
last_parent = prenode;
new_abs_transform *= child->mTransformation;
new_abs_transform *= prenode->mTransformation;
}
// attach geometry
ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform);
ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
// check if there will be any child nodes
const std::vector<const Connection*>& child_conns
@ -279,7 +258,7 @@ namespace Assimp {
for (aiNode* postnode : post_nodes_chain) {
ai_assert(postnode);
if (last_parent != parent) {
if (last_parent != &parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[1];
last_parent->mChildren[0] = postnode;
@ -301,15 +280,15 @@ namespace Assimp {
);
}
// recursion call - child nodes
ConvertNodes(model->ID(), last_parent, root_node);
// attach sub-nodes (if any)
ConvertNodes(model->ID(), *last_parent, new_abs_transform);
if (doc.Settings().readLights) {
ConvertLights(*model, node_name);
ConvertLights(*model, unique_name);
}
if (doc.Settings().readCameras) {
ConvertCameras(*model, node_name);
ConvertCameras(*model, unique_name);
}
nodes.push_back(nodes_chain.front());
@ -318,17 +297,11 @@ namespace Assimp {
}
if (nodes.size()) {
parent->mChildren = new aiNode*[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
parent.mChildren = new aiNode*[nodes.size()]();
parent.mNumChildren = static_cast<unsigned int>(nodes.size());
std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren);
std::swap_ranges(nodes.begin(), nodes.end(), parent.mChildren);
}
else
{
parent->mNumChildren = 0;
parent->mChildren = nullptr;
}
}
catch (std::exception&) {
Util::delete_fun<aiNode> deleter;
@ -830,7 +803,7 @@ namespace Assimp {
// is_complex needs to be consistent with NeedsComplexTransformationChain()
// or the interplay between this code and the animation converter would
// not be guaranteed.
//ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
// now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's
@ -932,8 +905,7 @@ namespace Assimp {
}
}
void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform)
void FBXConverter::ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform)
{
const std::vector<const Geometry*>& geos = model.GetGeometry();
@ -945,12 +917,11 @@ namespace Assimp {
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo);
if (mesh) {
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, parent, root_node,
absolute_transform);
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else if (line) {
const std::vector<unsigned int>& indices = ConvertLine(*line, model, parent, root_node);
const std::vector<unsigned int>& indices = ConvertLine(*line, model, node_global_transform, nd);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else {
@ -959,16 +930,15 @@ namespace Assimp {
}
if (meshes.size()) {
parent->mMeshes = new unsigned int[meshes.size()]();
parent->mNumMeshes = static_cast<unsigned int>(meshes.size());
nd.mMeshes = new unsigned int[meshes.size()]();
nd.mNumMeshes = static_cast<unsigned int>(meshes.size());
std::swap_ranges(meshes.begin(), meshes.end(), parent->mMeshes);
std::swap_ranges(meshes.begin(), meshes.end(), nd.mMeshes);
}
}
std::vector<unsigned int>
FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform)
std::vector<unsigned int> FBXConverter::ConvertMesh(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd)
{
std::vector<unsigned int> temp;
@ -992,18 +962,18 @@ namespace Assimp {
const MatIndexArray::value_type base = mindices[0];
for (MatIndexArray::value_type index : mindices) {
if (index != base) {
return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
return ConvertMeshMultiMaterial(mesh, model, node_global_transform, nd);
}
}
}
// faster code-path, just copy the data
temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node));
temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform, nd));
return temp;
}
std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model,
aiNode *parent, aiNode *root_node)
const aiMatrix4x4& node_global_transform, aiNode& nd)
{
std::vector<unsigned int> temp;
@ -1014,7 +984,7 @@ namespace Assimp {
return temp;
}
aiMesh* const out_mesh = SetupEmptyMesh(line, root_node);
aiMesh* const out_mesh = SetupEmptyMesh(line, nd);
out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
// copy vertices
@ -1049,7 +1019,7 @@ namespace Assimp {
return temp;
}
aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode *parent)
aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd)
{
aiMesh* const out_mesh = new aiMesh();
meshes.push_back(out_mesh);
@ -1066,18 +1036,17 @@ namespace Assimp {
}
else
{
out_mesh->mName = parent->mName;
out_mesh->mName = nd.mName;
}
return out_mesh;
}
unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
const aiMatrix4x4 &absolute_transform, aiNode *parent,
aiNode *root_node)
unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd)
{
const MatIndexArray& mindices = mesh.GetMaterialIndices();
aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
@ -1144,7 +1113,7 @@ namespace Assimp {
binormals = &tempBinormals;
}
else {
binormals = nullptr;
binormals = NULL;
}
}
@ -1194,9 +1163,8 @@ namespace Assimp {
ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
}
if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, NO_MATERIAL_SEPARATION,
nullptr);
if (doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION);
}
std::vector<aiAnimMesh*> animMeshes;
@ -1241,10 +1209,8 @@ namespace Assimp {
return static_cast<unsigned int>(meshes.size() - 1);
}
std::vector<unsigned int>
FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
aiNode *root_node,
const aiMatrix4x4 &absolute_transform)
std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd)
{
const MatIndexArray& mindices = mesh.GetMaterialIndices();
ai_assert(mindices.size());
@ -1255,7 +1221,7 @@ namespace Assimp {
for (MatIndexArray::value_type index : mindices) {
if (had.find(index) == had.end()) {
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform, nd));
had.insert(index);
}
}
@ -1263,18 +1229,18 @@ namespace Assimp {
return indices;
}
unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
MatIndexArray::value_type index,
aiNode *parent, aiNode *root_node,
const aiMatrix4x4 &absolute_transform)
unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
MatIndexArray::value_type index,
const aiMatrix4x4& node_global_transform,
aiNode& nd)
{
aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
const MatIndexArray& mindices = mesh.GetMaterialIndices();
const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != nullptr;
const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != NULL;
unsigned int count_faces = 0;
unsigned int count_vertices = 0;
@ -1334,7 +1300,7 @@ namespace Assimp {
binormals = &tempBinormals;
}
else {
binormals = nullptr;
binormals = NULL;
}
}
@ -1433,7 +1399,7 @@ namespace Assimp {
ConvertMaterialForMesh(out_mesh, model, mesh, index);
if (process_weights) {
ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, index, &reverseMapping);
ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
}
std::vector<aiAnimMesh*> animMeshes;
@ -1483,10 +1449,10 @@ namespace Assimp {
return static_cast<unsigned int>(meshes.size() - 1);
}
void FBXConverter::ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo,
const aiMatrix4x4 &absolute_transform,
aiNode *parent, aiNode *root_node, unsigned int materialIndex,
std::vector<unsigned int> *outputVertStartIndices)
void FBXConverter::ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
const aiMatrix4x4& node_global_transform,
unsigned int materialIndex,
std::vector<unsigned int>* outputVertStartIndices)
{
ai_assert(geo.DeformerSkin());
@ -1497,12 +1463,13 @@ namespace Assimp {
const Skin& sk = *geo.DeformerSkin();
std::vector<aiBone*> bones;
bones.reserve(sk.Clusters().size());
const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
ai_assert(no_mat_check || outputVertStartIndices);
try {
// iterate over the sub deformers
for (const Cluster* cluster : sk.Clusters()) {
ai_assert(cluster);
@ -1516,16 +1483,15 @@ namespace Assimp {
index_out_indices.clear();
out_indices.clear();
// now check if *any* of these weights is contained in the output mesh,
// taking notes so we don't need to do it twice.
for (WeightIndexArray::value_type index : indices) {
unsigned int count = 0;
const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count);
// ToOutputVertexIndex only returns nullptr if index is out of bounds
// ToOutputVertexIndex only returns NULL if index is out of bounds
// which should never happen
ai_assert(out_idx != nullptr);
ai_assert(out_idx != NULL);
index_out_indices.push_back(no_index_sentinel);
count_out_indices.push_back(0);
@ -1554,15 +1520,13 @@ namespace Assimp {
}
}
}
// if we found at least one, generate the output bones
// XXX this could be heavily simplified by collecting the bone
// data in a single step.
ConvertCluster(bones, cluster, out_indices, index_out_indices,
count_out_indices, absolute_transform, parent, root_node);
ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
count_out_indices, node_global_transform);
}
bone_map.clear();
}
catch (std::exception&) {
std::for_each(bones.begin(), bones.end(), Util::delete_fun<aiBone>());
@ -1570,90 +1534,54 @@ namespace Assimp {
}
if (bones.empty()) {
out->mBones = nullptr;
out->mNumBones = 0;
return;
} else {
out->mBones = new aiBone *[bones.size()]();
out->mNumBones = static_cast<unsigned int>(bones.size());
std::swap_ranges(bones.begin(), bones.end(), out->mBones);
}
out->mBones = new aiBone*[bones.size()]();
out->mNumBones = static_cast<unsigned int>(bones.size());
std::swap_ranges(bones.begin(), bones.end(), out->mBones);
}
const aiNode* FBXConverter::GetNodeByName( const aiString& name, aiNode *current_node )
void FBXConverter::ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
std::vector<size_t>& out_indices,
std::vector<size_t>& index_out_indices,
std::vector<size_t>& count_out_indices,
const aiMatrix4x4& node_global_transform)
{
aiNode * iter = current_node;
//printf("Child count: %d", iter->mNumChildren);
return iter;
}
void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
aiNode *parent, aiNode *root_node) {
ai_assert(cl); // make sure cluster valid
std::string deformer_name = cl->TargetNode()->Name();
aiString bone_name = aiString(FixNodeName(deformer_name));
aiBone* const bone = new aiBone();
bones.push_back(bone);
aiBone *bone = nullptr;
bone->mName = FixNodeName(cl.TargetNode()->Name());
if (bone_map.count(deformer_name)) {
ASSIMP_LOG_DEBUG_F("retrieved bone from lookup ", bone_name.C_Str(), ". Deformer:", deformer_name);
bone = bone_map[deformer_name];
} else {
ASSIMP_LOG_DEBUG_F("created new bone ", bone_name.C_Str(), ". Deformer: ", deformer_name);
bone = new aiBone();
bone->mName = bone_name;
bone->mOffsetMatrix = cl.TransformLink();
bone->mOffsetMatrix.Inverse();
// store local transform link for post processing
bone->mOffsetMatrix = cl->TransformLink();
bone->mOffsetMatrix.Inverse();
bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
const WeightArray& weights = cl.GetWeights();
const size_t c = index_out_indices.size();
for (size_t i = 0; i < c; ++i) {
const size_t index_index = index_out_indices[i];
//
// Now calculate the aiVertexWeights
//
aiVertexWeight *cursor = nullptr;
bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
const WeightArray& weights = cl->GetWeights();
const size_t c = index_out_indices.size();
for (size_t i = 0; i < c; ++i) {
const size_t index_index = index_out_indices[i];
if (index_index == no_index_sentinel) {
continue;
}
const size_t cc = count_out_indices[i];
for (size_t j = 0; j < cc; ++j) {
// cursor runs from first element relative to the start
// or relative to the start of the next indexes.
aiVertexWeight& out_weight = *cursor++;
out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
out_weight.mWeight = weights[i];
}
if (index_index == no_index_sentinel) {
continue;
}
bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone));
const size_t cc = count_out_indices[i];
for (size_t j = 0; j < cc; ++j) {
aiVertexWeight& out_weight = *cursor++;
out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
out_weight.mWeight = weights[i];
}
}
ASSIMP_LOG_DEBUG_F("bone research: Indicies size: ", out_indices.size());
// lookup must be populated in case something goes wrong
// this also allocates bones to mesh instance outside
local_mesh_bones.push_back(bone);
}
void FBXConverter::ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@ -1783,7 +1711,7 @@ namespace Assimp {
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
unsigned int index;
VideoMap::const_iterator it = textures_converted.find(*media);
VideoMap::const_iterator it = textures_converted.find(media);
if (it != textures_converted.end()) {
index = (*it).second;
textureReady = true;
@ -1791,7 +1719,7 @@ namespace Assimp {
else {
if (media->ContentLength() > 0) {
index = ConvertVideo(*media);
textures_converted[*media] = index;
textures_converted[media] = index;
textureReady = true;
}
}
@ -2088,14 +2016,7 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
// 3DSMax PBR
TrySetTextureProperties(out_mat, textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "3dsMax|Parameters|bump_map", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, textures, "3dsMax|Parameters|emission_map", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "3dsMax|Parameters|metalness_map", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "3dsMax|Parameters|roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
}
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@ -2322,13 +2243,13 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
if (media != nullptr && media->ContentLength() > 0) {
unsigned int index;
VideoMap::const_iterator it = textures_converted.find(*media);
VideoMap::const_iterator it = textures_converted.find(media);
if (it != textures_converted.end()) {
index = (*it).second;
}
else {
index = ConvertVideo(*media);
textures_converted[*media] = index;
textures_converted[media] = index;
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
@ -2756,7 +2677,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
// sanity check whether the input is ok
static void validateAnimCurveNodes(const std::vector<const AnimationCurveNode*>& curves,
bool strictMode) {
const Object* target(nullptr);
const Object* target(NULL);
for (const AnimationCurveNode* node : curves) {
if (!target) {
target = node->Target();
@ -2787,7 +2708,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
#ifdef ASSIMP_BUILD_DEBUG
validateAnimCurveNodes(curves, doc.Settings().strictMode);
#endif
const AnimationCurveNode* curve_node = nullptr;
const AnimationCurveNode* curve_node = NULL;
for (const AnimationCurveNode* node : curves) {
ai_assert(node);
@ -3612,9 +3533,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
return;
}
const bool hasGenerator = !doc.Creator().empty();
out->mMetaData = aiMetadata::Alloc(16 + (hasGenerator ? 1 : 0));
out->mMetaData = aiMetadata::Alloc(15);
out->mMetaData->Set(0, "UpAxis", doc.GlobalSettings().UpAxis());
out->mMetaData->Set(1, "UpAxisSign", doc.GlobalSettings().UpAxisSign());
out->mMetaData->Set(2, "FrontAxis", doc.GlobalSettings().FrontAxis());
@ -3630,11 +3549,6 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
out->mMetaData->Set(12, "TimeSpanStart", doc.GlobalSettings().TimeSpanStart());
out->mMetaData->Set(13, "TimeSpanStop", doc.GlobalSettings().TimeSpanStop());
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
out->mMetaData->Set(15, AI_METADATA_SOURCE_FORMAT_VERSION, aiString(to_string(doc.FBXVersion())));
if (hasGenerator)
{
out->mMetaData->Set(16, AI_METADATA_SOURCE_GENERATOR, aiString(doc.Creator()));
}
}
void FBXConverter::TransferDataToScene()
@ -3642,7 +3556,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
ai_assert(!out->mMeshes);
ai_assert(!out->mNumMeshes);
// note: the trailing () ensures initialization with nullptr - not
// note: the trailing () ensures initialization with NULL - not
// many C++ users seem to know this, so pointing it out to avoid
// confusion why this code works.
@ -3689,47 +3603,6 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
}
void FBXConverter::ConvertOrphantEmbeddedTextures()
{
// in C++14 it could be:
// for (auto&& [id, object] : objects)
for (auto&& id_and_object : doc.Objects())
{
auto&& id = std::get<0>(id_and_object);
auto&& object = std::get<1>(id_and_object);
// If an object doesn't have parent
if (doc.ConnectionsBySource().count(id) == 0)
{
const Texture* realTexture = nullptr;
try
{
const auto& element = object->GetElement();
const Token& key = element.KeyToken();
const char* obtype = key.begin();
const size_t length = static_cast<size_t>(key.end() - key.begin());
if (strncmp(obtype, "Texture", length) == 0)
{
const Texture* texture = static_cast<const Texture*>(object->Get());
if (texture->Media() && texture->Media()->ContentLength() > 0)
{
realTexture = texture;
}
}
}
catch (...)
{
// do nothing
}
if (realTexture)
{
const Video* media = realTexture->Media();
unsigned int index = ConvertVideo(*media);
textures_converted[*media] = index;
}
}
}
}
// ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{