|
@@ -65,12 +65,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <cstdint>
|
|
#include <cstdint>
|
|
#include <iomanip>
|
|
#include <iomanip>
|
|
-#include <iostream>
|
|
|
|
#include <iterator>
|
|
#include <iterator>
|
|
#include <memory>
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <sstream>
|
|
-#include <tuple>
|
|
|
|
-#include <vector>
|
|
|
|
|
|
|
|
namespace Assimp {
|
|
namespace Assimp {
|
|
namespace FBX {
|
|
namespace FBX {
|
|
@@ -187,8 +184,7 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
|
|
|
|
|
|
/// This struct manages nodes which may or may not end up in the node hierarchy.
|
|
/// This struct manages nodes which may or may not end up in the node hierarchy.
|
|
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
|
|
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
|
|
-struct FBXConverter::PotentialNode
|
|
|
|
-{
|
|
|
|
|
|
+struct FBXConverter::PotentialNode {
|
|
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
|
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
|
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
|
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
|
aiNode* operator->() { return mNode; }
|
|
aiNode* operator->() { return mNode; }
|
|
@@ -231,7 +227,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|
if (nullptr != model) {
|
|
if (nullptr != model) {
|
|
nodes_chain.clear();
|
|
nodes_chain.clear();
|
|
post_nodes_chain.clear();
|
|
post_nodes_chain.clear();
|
|
-
|
|
|
|
aiMatrix4x4 new_abs_transform = parent->mTransformation;
|
|
aiMatrix4x4 new_abs_transform = parent->mTransformation;
|
|
std::string node_name = FixNodeName(model->Name());
|
|
std::string node_name = FixNodeName(model->Name());
|
|
// even though there is only a single input node, the design of
|
|
// even though there is only a single input node, the design of
|
|
@@ -266,8 +261,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|
|
|
|
|
child->mParent = last_parent;
|
|
child->mParent = last_parent;
|
|
last_parent = child.mNode;
|
|
last_parent = child.mNode;
|
|
-
|
|
|
|
- new_abs_transform *= child->mTransformation;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// attach geometry
|
|
// attach geometry
|
|
@@ -290,8 +283,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|
|
|
|
|
postnode->mParent = last_parent;
|
|
postnode->mParent = last_parent;
|
|
last_parent = postnode.mNode;
|
|
last_parent = postnode.mNode;
|
|
-
|
|
|
|
- new_abs_transform *= postnode->mTransformation;
|
|
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
// free the nodes we allocated as we don't need them
|
|
// free the nodes we allocated as we don't need them
|
|
@@ -452,7 +443,7 @@ void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueNam
|
|
auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
|
|
auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
|
|
unsigned int &i = it_pair.first->second;
|
|
unsigned int &i = it_pair.first->second;
|
|
while (!it_pair.second) {
|
|
while (!it_pair.second) {
|
|
- i++;
|
|
|
|
|
|
+ ++i;
|
|
std::ostringstream ext;
|
|
std::ostringstream ext;
|
|
ext << name << std::setfill('0') << std::setw(3) << i;
|
|
ext << name << std::setfill('0') << std::setw(3) << i;
|
|
uniqueName = ext.str();
|
|
uniqueName = ext.str();
|
|
@@ -651,9 +642,8 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
|
|
|
|
|
|
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
|
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
|
const PropertyTable &props = model.Props();
|
|
const PropertyTable &props = model.Props();
|
|
- bool ok;
|
|
|
|
|
|
|
|
- const float zero_epsilon = ai_epsilon;
|
|
|
|
|
|
+ const auto zero_epsilon = ai_epsilon;
|
|
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
|
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
|
@@ -665,6 +655,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
|
|
|
|
|
bool scale_compare = (comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling);
|
|
bool scale_compare = (comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling);
|
|
|
|
|
|
|
|
+ bool ok = true;
|
|
const aiVector3D &v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok);
|
|
const aiVector3D &v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok);
|
|
if (ok && scale_compare) {
|
|
if (ok && scale_compare) {
|
|
if ((v - all_ones).SquareLength() > zero_epsilon) {
|
|
if ((v - all_ones).SquareLength() > zero_epsilon) {
|
|
@@ -899,20 +890,17 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
|
|
|
|
- const aiMatrix4x4 &absolute_transform) {
|
|
|
|
|
|
+void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform) {
|
|
const std::vector<const Geometry *> &geos = model.GetGeometry();
|
|
const std::vector<const Geometry *> &geos = model.GetGeometry();
|
|
|
|
|
|
std::vector<unsigned int> meshes;
|
|
std::vector<unsigned int> meshes;
|
|
meshes.reserve(geos.size());
|
|
meshes.reserve(geos.size());
|
|
|
|
|
|
for (const Geometry *geo : geos) {
|
|
for (const Geometry *geo : geos) {
|
|
-
|
|
|
|
const MeshGeometry *const mesh = dynamic_cast<const MeshGeometry *>(geo);
|
|
const MeshGeometry *const mesh = dynamic_cast<const MeshGeometry *>(geo);
|
|
const LineGeometry *const line = dynamic_cast<const LineGeometry *>(geo);
|
|
const LineGeometry *const line = dynamic_cast<const LineGeometry *>(geo);
|
|
if (mesh) {
|
|
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, parent, root_node, absolute_transform);
|
|
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
|
|
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
|
|
} else if (line) {
|
|
} else if (line) {
|
|
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
|
|
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
|
|
@@ -933,8 +921,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
|
|
}
|
|
}
|
|
|
|
|
|
std::vector<unsigned int>
|
|
std::vector<unsigned int>
|
|
-FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
|
|
|
|
- const aiMatrix4x4 &absolute_transform) {
|
|
|
|
|
|
+FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform) {
|
|
std::vector<unsigned int> temp;
|
|
std::vector<unsigned int> temp;
|
|
|
|
|
|
MeshMap::const_iterator it = meshes_converted.find(&mesh);
|
|
MeshMap::const_iterator it = meshes_converted.find(&mesh);
|
|
@@ -957,7 +944,7 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *
|
|
const MatIndexArray::value_type base = mindices[0];
|
|
const MatIndexArray::value_type base = mindices[0];
|
|
for (MatIndexArray::value_type index : mindices) {
|
|
for (MatIndexArray::value_type index : mindices) {
|
|
if (index != base) {
|
|
if (index != base) {
|
|
- return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
|
|
|
|
|
|
+ return ConvertMeshMultiMaterial(mesh, model, absolute_transform, parent, root_node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1031,9 +1018,36 @@ aiMesh *FBXConverter::SetupEmptyMesh(const Geometry &mesh, aiNode *parent) {
|
|
return out_mesh;
|
|
return out_mesh;
|
|
}
|
|
}
|
|
|
|
|
|
-unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
|
|
|
|
- const aiMatrix4x4 &absolute_transform, aiNode *parent,
|
|
|
|
- aiNode *) {
|
|
|
|
|
|
+static aiSkeleton *createAiSkeleton(SkeletonBoneContainer &sbc) {
|
|
|
|
+ if (sbc.MeshArray.empty() || sbc.SkeletonBoneToMeshLookup.empty()) {
|
|
|
|
+ return nullptr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ aiSkeleton *skeleton = new aiSkeleton;
|
|
|
|
+ for (auto *mesh : sbc.MeshArray) {
|
|
|
|
+ auto it = sbc.SkeletonBoneToMeshLookup.find(mesh);
|
|
|
|
+ if (it == sbc.SkeletonBoneToMeshLookup.end()) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ SkeletonBoneArray *ba = it->second;
|
|
|
|
+ if (ba == nullptr) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ skeleton->mNumBones = static_cast<unsigned int>(ba->size());
|
|
|
|
+ skeleton->mBones = new aiSkeletonBone*[skeleton->mNumBones];
|
|
|
|
+ size_t index = 0;
|
|
|
|
+ for (auto bone : (* ba)) {
|
|
|
|
+ skeleton->mBones[index] = bone;
|
|
|
|
+ ++index;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return skeleton;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
|
|
|
|
+ aiNode *parent, aiNode *) {
|
|
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
|
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
|
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
|
|
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
|
|
|
|
|
|
@@ -1151,8 +1165,15 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
|
ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
|
|
ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
|
|
}
|
|
}
|
|
|
|
|
|
- if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
|
|
|
|
|
|
+ if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr && !doc.Settings().useSkeleton) {
|
|
ConvertWeights(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr);
|
|
ConvertWeights(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr);
|
|
|
|
+ } else if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr && doc.Settings().useSkeleton) {
|
|
|
|
+ SkeletonBoneContainer sbc;
|
|
|
|
+ ConvertWeightsToSkeleton(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr, sbc);
|
|
|
|
+ aiSkeleton *skeleton = createAiSkeleton(sbc);
|
|
|
|
+ if (skeleton != nullptr) {
|
|
|
|
+ mSkeletons.emplace_back(skeleton);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
std::vector<aiAnimMesh *> animMeshes;
|
|
std::vector<aiAnimMesh *> animMeshes;
|
|
@@ -1199,9 +1220,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
|
}
|
|
}
|
|
|
|
|
|
std::vector<unsigned int>
|
|
std::vector<unsigned int>
|
|
-FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
|
|
|
|
- aiNode *root_node,
|
|
|
|
- const aiMatrix4x4 &absolute_transform) {
|
|
|
|
|
|
+FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, aiNode *parent,
|
|
|
|
+ aiNode *root_node) {
|
|
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
|
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
|
ai_assert(mindices.size());
|
|
ai_assert(mindices.size());
|
|
|
|
|
|
@@ -1211,7 +1231,7 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
|
|
for (MatIndexArray::value_type index : mindices) {
|
|
for (MatIndexArray::value_type index : mindices) {
|
|
if (had.find(index) == had.end()) {
|
|
if (had.find(index) == had.end()) {
|
|
|
|
|
|
- indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
|
|
|
|
|
|
+ indices.push_back(ConvertMeshMultiMaterial(mesh, model, absolute_transform, index, parent, root_node));
|
|
had.insert(index);
|
|
had.insert(index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1219,10 +1239,8 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
|
|
return indices;
|
|
return indices;
|
|
}
|
|
}
|
|
|
|
|
|
-unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
|
|
|
|
- MatIndexArray::value_type index,
|
|
|
|
- aiNode *parent, aiNode *,
|
|
|
|
- const aiMatrix4x4 &absolute_transform) {
|
|
|
|
|
|
+unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
|
|
|
|
+ MatIndexArray::value_type index, aiNode *parent, aiNode *) {
|
|
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
|
|
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
|
|
|
|
|
|
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
|
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
|
@@ -1435,20 +1453,47 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
|
return static_cast<unsigned int>(mMeshes.size() - 1);
|
|
return static_cast<unsigned int>(mMeshes.size() - 1);
|
|
}
|
|
}
|
|
|
|
|
|
-void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
|
|
|
|
- const aiMatrix4x4 &absolute_transform,
|
|
|
|
|
|
+static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *skeletonBone ) {
|
|
|
|
+ skeletonBone->mNumnWeights = bone->mNumWeights;
|
|
|
|
+ skeletonBone->mWeights = bone->mWeights;
|
|
|
|
+ skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
|
|
|
|
+ skeletonBone->mMeshId = mesh;
|
|
|
|
+ skeletonBone->mNode = bone->mNode;
|
|
|
|
+ skeletonBone->mParent = -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent, unsigned int materialIndex,
|
|
|
|
+ std::vector<unsigned int> *outputVertStartIndices, SkeletonBoneContainer &skeletonContainer) {
|
|
|
|
+
|
|
|
|
+ if (skeletonContainer.SkeletonBoneToMeshLookup.find(out) != skeletonContainer.SkeletonBoneToMeshLookup.end()) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ConvertWeights(out, geo, absolute_transform, parent, materialIndex, outputVertStartIndices);
|
|
|
|
+ skeletonContainer.MeshArray.emplace_back(out);
|
|
|
|
+ SkeletonBoneArray *ba = new SkeletonBoneArray;
|
|
|
|
+ for (size_t i = 0; i < out->mNumBones; ++i) {
|
|
|
|
+ aiBone *bone = out->mBones[i];
|
|
|
|
+ if (bone == nullptr) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ aiSkeletonBone *skeletonBone = new aiSkeletonBone;
|
|
|
|
+ copyBoneToSkeletonBone(out, bone, skeletonBone);
|
|
|
|
+ ba->emplace_back(skeletonBone);
|
|
|
|
+ }
|
|
|
|
+ skeletonContainer.SkeletonBoneToMeshLookup[out] = ba;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
|
|
aiNode *parent, unsigned int materialIndex,
|
|
aiNode *parent, unsigned int materialIndex,
|
|
std::vector<unsigned int> *outputVertStartIndices) {
|
|
std::vector<unsigned int> *outputVertStartIndices) {
|
|
ai_assert(geo.DeformerSkin());
|
|
ai_assert(geo.DeformerSkin());
|
|
|
|
|
|
- std::vector<size_t> out_indices;
|
|
|
|
- std::vector<size_t> index_out_indices;
|
|
|
|
- std::vector<size_t> count_out_indices;
|
|
|
|
|
|
+ std::vector<size_t> out_indices, index_out_indices, count_out_indices;
|
|
|
|
|
|
const Skin &sk = *geo.DeformerSkin();
|
|
const Skin &sk = *geo.DeformerSkin();
|
|
|
|
|
|
- std::vector<aiBone *> bones;
|
|
|
|
-
|
|
|
|
|
|
+ std::vector<aiBone*> bones;
|
|
const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
|
|
const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
|
|
ai_assert(no_mat_check || outputVertStartIndices);
|
|
ai_assert(no_mat_check || outputVertStartIndices);
|
|
|
|
|
|
@@ -1521,26 +1566,20 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
|
|
out->mBones = nullptr;
|
|
out->mBones = nullptr;
|
|
out->mNumBones = 0;
|
|
out->mNumBones = 0;
|
|
return;
|
|
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 *GetNodeByName(aiNode *current_node) {
|
|
|
|
- aiNode *iter = current_node;
|
|
|
|
- //printf("Child count: %d", iter->mNumChildren);
|
|
|
|
- return iter;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
|
|
|
|
|
|
+void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
|
|
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
|
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
|
- std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
|
|
|
|
|
|
+ std::vector<size_t> &count_out_indices, const aiMatrix4x4 & /* absolute_transform*/,
|
|
aiNode *) {
|
|
aiNode *) {
|
|
- ai_assert(cl); // make sure cluster valid
|
|
|
|
- std::string deformer_name = cl->TargetNode()->Name();
|
|
|
|
|
|
+ ai_assert(cluster != nullptr); // make sure cluster valid
|
|
|
|
+
|
|
|
|
+ std::string deformer_name = cluster->TargetNode()->Name();
|
|
aiString bone_name = aiString(FixNodeName(deformer_name));
|
|
aiString bone_name = aiString(FixNodeName(deformer_name));
|
|
|
|
|
|
aiBone *bone = nullptr;
|
|
aiBone *bone = nullptr;
|
|
@@ -1553,14 +1592,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
|
|
bone = new aiBone();
|
|
bone = new aiBone();
|
|
bone->mName = bone_name;
|
|
bone->mName = bone_name;
|
|
|
|
|
|
|
|
+ bone->mOffsetMatrix = cluster->Transform();
|
|
// store local transform link for post processing
|
|
// store local transform link for post processing
|
|
- bone->mOffsetMatrix = cl->TransformLink();
|
|
|
|
|
|
+ /*
|
|
|
|
+ bone->mOffsetMatrix = cluster->TransformLink();
|
|
bone->mOffsetMatrix.Inverse();
|
|
bone->mOffsetMatrix.Inverse();
|
|
|
|
|
|
aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
|
|
aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
|
|
|
|
|
|
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
|
|
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
|
|
-
|
|
|
|
|
|
+ */
|
|
//
|
|
//
|
|
// Now calculate the aiVertexWeights
|
|
// Now calculate the aiVertexWeights
|
|
//
|
|
//
|
|
@@ -1571,7 +1612,7 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
|
|
cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
|
|
cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
|
|
|
|
|
|
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
|
|
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
|
|
- const WeightArray &weights = cl->GetWeights();
|
|
|
|
|
|
+ const WeightArray &weights = cluster->GetWeights();
|
|
|
|
|
|
const size_t c = index_out_indices.size();
|
|
const size_t c = index_out_indices.size();
|
|
for (size_t i = 0; i < c; ++i) {
|
|
for (size_t i = 0; i < c; ++i) {
|
|
@@ -2161,6 +2202,9 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
|
|
const float ShininessExponent = PropertyGet<float>(props, "ShininessExponent", ok);
|
|
const float ShininessExponent = PropertyGet<float>(props, "ShininessExponent", ok);
|
|
if (ok) {
|
|
if (ok) {
|
|
out_mat->AddProperty(&ShininessExponent, 1, AI_MATKEY_SHININESS);
|
|
out_mat->AddProperty(&ShininessExponent, 1, AI_MATKEY_SHININESS);
|
|
|
|
+ // Match Blender behavior to extract roughness when only shininess is present
|
|
|
|
+ const float roughness = 1.0f - (sqrt(ShininessExponent) / 10.0f);
|
|
|
|
+ out_mat->AddProperty(&roughness, 1, AI_MATKEY_ROUGHNESS_FACTOR);
|
|
}
|
|
}
|
|
|
|
|
|
// TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
|
|
// TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
|
|
@@ -2613,7 +2657,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
|
|
meshMorphAnim->mNumKeys = numKeys;
|
|
meshMorphAnim->mNumKeys = numKeys;
|
|
meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys];
|
|
meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys];
|
|
unsigned int j = 0;
|
|
unsigned int j = 0;
|
|
- for (auto animIt : *animData) {
|
|
|
|
|
|
+ for (auto &animIt : *animData) {
|
|
morphKeyData *keyData = animIt.second;
|
|
morphKeyData *keyData = animIt.second;
|
|
unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size());
|
|
unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size());
|
|
meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
|
|
meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
|
|
@@ -3188,7 +3232,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
|
|
|
|
|
bool ok = false;
|
|
bool ok = false;
|
|
|
|
|
|
- const float zero_epsilon = ai_epsilon;
|
|
|
|
|
|
+ const auto zero_epsilon = ai_epsilon;
|
|
|
|
|
|
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
|
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
|
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
|
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
|
@@ -3326,13 +3370,17 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
|
|
float vc = curve->GetValues().at(1);
|
|
float vc = curve->GetValues().at(1);
|
|
for (size_t n = 1; n < count; n++) {
|
|
for (size_t n = 1; n < count; n++) {
|
|
while (std::abs(vc - vp) >= 180.0f) {
|
|
while (std::abs(vc - vp) >= 180.0f) {
|
|
- float step = std::floor(float(tc - tp) / (vc - vp) * 179.0f);
|
|
|
|
|
|
+ double step = std::floor(double(tc - tp) / std::abs(vc - vp) * 179.0f);
|
|
int64_t tnew = tp + int64_t(step);
|
|
int64_t tnew = tp + int64_t(step);
|
|
- float vnew = vp + (vc - vp) * step / float(tc - tp);
|
|
|
|
|
|
+ float vnew = vp + (vc - vp) * float(step / (tc - tp));
|
|
if (tnew >= adj_start && tnew <= adj_stop) {
|
|
if (tnew >= adj_start && tnew <= adj_stop) {
|
|
Keys->push_back(tnew);
|
|
Keys->push_back(tnew);
|
|
Values->push_back(vnew);
|
|
Values->push_back(vnew);
|
|
}
|
|
}
|
|
|
|
+ else {
|
|
|
|
+ // Something broke
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
tp = tnew;
|
|
tp = tnew;
|
|
vp = vnew;
|
|
vp = vnew;
|
|
}
|
|
}
|
|
@@ -3633,6 +3681,12 @@ void FBXConverter::TransferDataToScene() {
|
|
|
|
|
|
std::swap_ranges(textures.begin(), textures.end(), mSceneOut->mTextures);
|
|
std::swap_ranges(textures.begin(), textures.end(), mSceneOut->mTextures);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (!mSkeletons.empty()) {
|
|
|
|
+ mSceneOut->mSkeletons = new aiSkeleton *[mSkeletons.size()];
|
|
|
|
+ mSceneOut->mNumSkeletons = static_cast<unsigned int>(mSkeletons.size());
|
|
|
|
+ std::swap_ranges(mSkeletons.begin(), mSkeletons.end(), mSceneOut->mSkeletons);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void FBXConverter::ConvertOrphanedEmbeddedTextures() {
|
|
void FBXConverter::ConvertOrphanedEmbeddedTextures() {
|