- fbx: bone bind matrix now includes mesh world transformation.
parent
d5d6df36e3
commit
3899fc5257
|
@ -154,7 +154,7 @@ private:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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");
|
||||
|
||||
|
@ -182,6 +182,8 @@ private:
|
|||
if(model) {
|
||||
nodes_chain.clear();
|
||||
|
||||
aiMatrix4x4 new_abs_transform = parent_transform;
|
||||
|
||||
// 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
|
||||
|
@ -221,13 +223,15 @@ private:
|
|||
|
||||
prenode->mParent = last_parent;
|
||||
last_parent = prenode;
|
||||
|
||||
new_abs_transform *= prenode->mTransformation;
|
||||
}
|
||||
|
||||
// attach geometry
|
||||
ConvertModel(*model, *nodes_chain.back());
|
||||
ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
|
||||
|
||||
// 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_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();
|
||||
|
||||
|
@ -538,7 +542,7 @@ private:
|
|||
|
||||
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
|
||||
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) );
|
||||
}
|
||||
else {
|
||||
|
@ -557,7 +561,7 @@ private:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
|
@ -581,13 +585,13 @@ private:
|
|||
const unsigned int base = mindices[0];
|
||||
BOOST_FOREACH(unsigned int index, mindices) {
|
||||
if(index != base) {
|
||||
return ConvertMeshMultiMaterial(mesh, model);
|
||||
return ConvertMeshMultiMaterial(mesh, model, node_global_transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// faster codepath, just copy the data
|
||||
temp.push_back(ConvertMeshSingleMaterial(mesh, model));
|
||||
temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform));
|
||||
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();
|
||||
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) {
|
||||
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);
|
||||
|
@ -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();
|
||||
ai_assert(mindices.size());
|
||||
|
@ -752,7 +756,7 @@ private:
|
|||
BOOST_FOREACH(unsigned int index, mindices) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -927,7 +931,7 @@ private:
|
|||
ConvertMaterialForMesh(out_mesh,model,mesh,index);
|
||||
|
||||
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);
|
||||
|
@ -943,6 +947,7 @@ private:
|
|||
* - outputVertStartIndices is only used when a material index is specified, it gives for
|
||||
* each output vertex the DOM index it maps to. */
|
||||
void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||
const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
|
||||
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
||||
std::vector<unsigned int>* outputVertStartIndices = NULL)
|
||||
{
|
||||
|
@ -1024,7 +1029,8 @@ private:
|
|||
// XXX this could be heavily simplified by collecting the bone
|
||||
// data in a single step.
|
||||
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>& 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();
|
||||
bones.push_back(bone);
|
||||
|
||||
bone->mName = FixNodeName(cl.TargetNode()->Name());
|
||||
|
||||
bone->mOffsetMatrix = cl.TransformLink();
|
||||
bone->mOffsetMatrix.Inverse();
|
||||
|
||||
bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
|
||||
|
||||
bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
|
||||
aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
|
||||
|
||||
|
|
Loading…
Reference in New Issue