- fbx: bone bind matrix now includes mesh world transformation.
parent
d5d6df36e3
commit
3899fc5257
|
@ -154,7 +154,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// collect and assign child nodes
|
// collect and assign child nodes
|
||||||
void ConvertNodes(uint64_t id, aiNode& parent)
|
void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4())
|
||||||
{
|
{
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
|
||||||
|
|
||||||
|
@ -182,6 +182,8 @@ private:
|
||||||
if(model) {
|
if(model) {
|
||||||
nodes_chain.clear();
|
nodes_chain.clear();
|
||||||
|
|
||||||
|
aiMatrix4x4 new_abs_transform = parent_transform;
|
||||||
|
|
||||||
// even though there is only a single input node, the design of
|
// even though there is only a single input node, the design of
|
||||||
// assimp (or rather: the complicated transformation chain that
|
// assimp (or rather: the complicated transformation chain that
|
||||||
// is employed by fbx) means that we may need multiple aiNode's
|
// is employed by fbx) means that we may need multiple aiNode's
|
||||||
|
@ -221,13 +223,15 @@ private:
|
||||||
|
|
||||||
prenode->mParent = last_parent;
|
prenode->mParent = last_parent;
|
||||||
last_parent = prenode;
|
last_parent = prenode;
|
||||||
|
|
||||||
|
new_abs_transform *= prenode->mTransformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach geometry
|
// attach geometry
|
||||||
ConvertModel(*model, *nodes_chain.back());
|
ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
|
||||||
|
|
||||||
// attach sub-nodes
|
// attach sub-nodes
|
||||||
ConvertNodes(model->ID(), *nodes_chain.back());
|
ConvertNodes(model->ID(), *nodes_chain.back(), new_abs_transform);
|
||||||
|
|
||||||
nodes.push_back(nodes_chain.front());
|
nodes.push_back(nodes_chain.front());
|
||||||
nodes_chain.clear();
|
nodes_chain.clear();
|
||||||
|
@ -527,7 +531,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertModel(const Model& model, aiNode& nd)
|
void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform)
|
||||||
{
|
{
|
||||||
const std::vector<const Geometry*>& geos = model.GetGeometry();
|
const std::vector<const Geometry*>& geos = model.GetGeometry();
|
||||||
|
|
||||||
|
@ -538,7 +542,7 @@ private:
|
||||||
|
|
||||||
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
|
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
|
||||||
if(mesh) {
|
if(mesh) {
|
||||||
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model);
|
const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform);
|
||||||
std::copy(indices.begin(),indices.end(),std::back_inserter(meshes) );
|
std::copy(indices.begin(),indices.end(),std::back_inserter(meshes) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -557,7 +561,7 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
|
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
|
||||||
std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model)
|
std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh,const Model& model, const aiMatrix4x4& node_global_transform)
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> temp;
|
std::vector<unsigned int> temp;
|
||||||
|
|
||||||
|
@ -581,13 +585,13 @@ private:
|
||||||
const unsigned int base = mindices[0];
|
const unsigned int base = mindices[0];
|
||||||
BOOST_FOREACH(unsigned int index, mindices) {
|
BOOST_FOREACH(unsigned int index, mindices) {
|
||||||
if(index != base) {
|
if(index != base) {
|
||||||
return ConvertMeshMultiMaterial(mesh, model);
|
return ConvertMeshMultiMaterial(mesh, model, node_global_transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// faster codepath, just copy the data
|
// faster codepath, just copy the data
|
||||||
temp.push_back(ConvertMeshSingleMaterial(mesh, model));
|
temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform));
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,7 +618,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model)
|
unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, const aiMatrix4x4& node_global_transform)
|
||||||
{
|
{
|
||||||
const std::vector<unsigned int>& mindices = mesh.GetMaterialIndices();
|
const std::vector<unsigned int>& mindices = mesh.GetMaterialIndices();
|
||||||
aiMesh* const out_mesh = SetupEmptyMesh(mesh,mindices.size() ? mindices[0] : static_cast<unsigned int>(-1));
|
aiMesh* const out_mesh = SetupEmptyMesh(mesh,mindices.size() ? mindices[0] : static_cast<unsigned int>(-1));
|
||||||
|
@ -733,7 +737,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
if(doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
|
if(doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
|
||||||
ConvertWeights(out_mesh, model, mesh, NO_MATERIAL_SEPARATION);
|
ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<unsigned int>(meshes.size() - 1);
|
return static_cast<unsigned int>(meshes.size() - 1);
|
||||||
|
@ -741,7 +745,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model)
|
std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, const aiMatrix4x4& node_global_transform)
|
||||||
{
|
{
|
||||||
const std::vector<unsigned int>& mindices = mesh.GetMaterialIndices();
|
const std::vector<unsigned int>& mindices = mesh.GetMaterialIndices();
|
||||||
ai_assert(mindices.size());
|
ai_assert(mindices.size());
|
||||||
|
@ -752,7 +756,7 @@ private:
|
||||||
BOOST_FOREACH(unsigned int index, mindices) {
|
BOOST_FOREACH(unsigned int index, mindices) {
|
||||||
if(had.find(index) == had.end()) {
|
if(had.find(index) == had.end()) {
|
||||||
|
|
||||||
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index));
|
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform));
|
||||||
had.insert(index);
|
had.insert(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -762,7 +766,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, unsigned int index)
|
unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, unsigned int index, const aiMatrix4x4& node_global_transform)
|
||||||
{
|
{
|
||||||
aiMesh* const out_mesh = SetupEmptyMesh(mesh, index);
|
aiMesh* const out_mesh = SetupEmptyMesh(mesh, index);
|
||||||
|
|
||||||
|
@ -927,7 +931,7 @@ private:
|
||||||
ConvertMaterialForMesh(out_mesh,model,mesh,index);
|
ConvertMaterialForMesh(out_mesh,model,mesh,index);
|
||||||
|
|
||||||
if(process_weights) {
|
if(process_weights) {
|
||||||
ConvertWeights(out_mesh, model, mesh, index, &reverseMapping);
|
ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<unsigned int>(meshes.size() - 1);
|
return static_cast<unsigned int>(meshes.size() - 1);
|
||||||
|
@ -943,6 +947,7 @@ private:
|
||||||
* - outputVertStartIndices is only used when a material index is specified, it gives for
|
* - outputVertStartIndices is only used when a material index is specified, it gives for
|
||||||
* each output vertex the DOM index it maps to. */
|
* each output vertex the DOM index it maps to. */
|
||||||
void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
|
void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||||
|
const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
|
||||||
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
||||||
std::vector<unsigned int>* outputVertStartIndices = NULL)
|
std::vector<unsigned int>* outputVertStartIndices = NULL)
|
||||||
{
|
{
|
||||||
|
@ -1024,7 +1029,8 @@ private:
|
||||||
// XXX this could be heavily simplified by collecting the bone
|
// XXX this could be heavily simplified by collecting the bone
|
||||||
// data in a single step.
|
// data in a single step.
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ConvertCluster(bones, *cluster, out_indices, index_out_indices, count_out_indices);
|
ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
|
||||||
|
count_out_indices, node_global_transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1044,20 +1050,25 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertCluster(std::vector<aiBone*>& bones, const Cluster& cl,
|
void ConvertCluster(std::vector<aiBone*>& bones, const Model& model, const Cluster& cl,
|
||||||
std::vector<size_t>& out_indices,
|
std::vector<size_t>& out_indices,
|
||||||
std::vector<size_t>& index_out_indices,
|
std::vector<size_t>& index_out_indices,
|
||||||
std::vector<size_t>& count_out_indices
|
std::vector<size_t>& count_out_indices,
|
||||||
)
|
const aiMatrix4x4& node_global_transform)
|
||||||
{
|
{
|
||||||
|
|
||||||
aiBone* const bone = new aiBone();
|
aiBone* const bone = new aiBone();
|
||||||
bones.push_back(bone);
|
bones.push_back(bone);
|
||||||
|
|
||||||
bone->mName = FixNodeName(cl.TargetNode()->Name());
|
bone->mName = FixNodeName(cl.TargetNode()->Name());
|
||||||
|
|
||||||
bone->mOffsetMatrix = cl.TransformLink();
|
bone->mOffsetMatrix = cl.TransformLink();
|
||||||
bone->mOffsetMatrix.Inverse();
|
bone->mOffsetMatrix.Inverse();
|
||||||
|
|
||||||
|
bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
|
||||||
|
|
||||||
bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
|
bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
|
||||||
aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
|
aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue