Merge branch 'master' into gltf_fixes
commit
c0d7ea981a
|
@ -185,6 +185,17 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
|
|||
return unique_name;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
struct FBXConverter::PotentialNode
|
||||
{
|
||||
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
||||
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
||||
aiNode* operator->() { return mNode; }
|
||||
std::unique_ptr<aiNode> mOwnership;
|
||||
aiNode* mNode;
|
||||
};
|
||||
|
||||
/// todo: pre-build node hierarchy
|
||||
/// todo: get bone from stack
|
||||
/// todo: make map of aiBone* to aiNode*
|
||||
|
@ -192,13 +203,12 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
|
|||
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
|
||||
|
||||
std::vector<aiNode *> nodes;
|
||||
std::vector<PotentialNode> nodes;
|
||||
nodes.reserve(conns.size());
|
||||
|
||||
std::vector<aiNode *> nodes_chain;
|
||||
std::vector<aiNode *> post_nodes_chain;
|
||||
std::vector<PotentialNode> nodes_chain;
|
||||
std::vector<PotentialNode> post_nodes_chain;
|
||||
|
||||
try {
|
||||
for (const Connection *con : conns) {
|
||||
// ignore object-property links
|
||||
if (con->PropertyName().length()) {
|
||||
|
@ -237,31 +247,31 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
ai_assert(nodes_chain.size());
|
||||
|
||||
if (need_additional_node) {
|
||||
nodes_chain.push_back(new aiNode(node_name));
|
||||
nodes_chain.emplace_back(PotentialNode(node_name));
|
||||
}
|
||||
|
||||
//setup metadata on newest node
|
||||
SetupNodeMetadata(*model, *nodes_chain.back());
|
||||
SetupNodeMetadata(*model, *nodes_chain.back().mNode);
|
||||
|
||||
// link all nodes in a row
|
||||
aiNode *last_parent = parent;
|
||||
for (aiNode *child : nodes_chain) {
|
||||
ai_assert(child);
|
||||
for (PotentialNode& child : nodes_chain) {
|
||||
ai_assert(child.mNode);
|
||||
|
||||
if (last_parent != parent) {
|
||||
last_parent->mNumChildren = 1;
|
||||
last_parent->mChildren = new aiNode *[1];
|
||||
last_parent->mChildren[0] = child;
|
||||
last_parent->mChildren[0] = child.mOwnership.release();
|
||||
}
|
||||
|
||||
child->mParent = last_parent;
|
||||
last_parent = child;
|
||||
last_parent = child.mNode;
|
||||
|
||||
new_abs_transform *= child->mTransformation;
|
||||
}
|
||||
|
||||
// attach geometry
|
||||
ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform);
|
||||
ConvertModel(*model, nodes_chain.back().mNode, root_node, new_abs_transform);
|
||||
|
||||
// check if there will be any child nodes
|
||||
const std::vector<const Connection *> &child_conns = doc.GetConnectionsByDestinationSequenced(model->ID(), "Model");
|
||||
|
@ -269,27 +279,23 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
// if so, link the geometric transform inverse nodes
|
||||
// before we attach any child nodes
|
||||
if (child_conns.size()) {
|
||||
for (aiNode *postnode : post_nodes_chain) {
|
||||
ai_assert(postnode);
|
||||
for (PotentialNode& postnode : post_nodes_chain) {
|
||||
ai_assert(postnode.mNode);
|
||||
|
||||
if (last_parent != parent) {
|
||||
last_parent->mNumChildren = 1;
|
||||
last_parent->mChildren = new aiNode *[1];
|
||||
last_parent->mChildren[0] = postnode;
|
||||
last_parent->mChildren[0] = postnode.mOwnership.release();
|
||||
}
|
||||
|
||||
postnode->mParent = last_parent;
|
||||
last_parent = postnode;
|
||||
last_parent = postnode.mNode;
|
||||
|
||||
new_abs_transform *= postnode->mTransformation;
|
||||
}
|
||||
} else {
|
||||
// free the nodes we allocated as we don't need them
|
||||
Util::delete_fun<aiNode> deleter;
|
||||
std::for_each(
|
||||
post_nodes_chain.begin(),
|
||||
post_nodes_chain.end(),
|
||||
deleter);
|
||||
post_nodes_chain.clear();
|
||||
}
|
||||
|
||||
// recursion call - child nodes
|
||||
|
@ -303,7 +309,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
ConvertCameras(*model, node_name);
|
||||
}
|
||||
|
||||
nodes.push_back(nodes_chain.front());
|
||||
nodes.push_back(std::move(nodes_chain.front()));
|
||||
nodes_chain.clear();
|
||||
}
|
||||
}
|
||||
|
@ -312,18 +318,15 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
|||
parent->mChildren = new aiNode *[nodes.size()]();
|
||||
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
|
||||
|
||||
std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren);
|
||||
for (unsigned int i = 0; i < nodes.size(); ++i)
|
||||
{
|
||||
parent->mChildren[i] = nodes[i].mOwnership.release();
|
||||
}
|
||||
nodes.clear();
|
||||
} else {
|
||||
parent->mNumChildren = 0;
|
||||
parent->mChildren = nullptr;
|
||||
}
|
||||
|
||||
} catch (std::exception &) {
|
||||
Util::delete_fun<aiNode> deleter;
|
||||
std::for_each(nodes.begin(), nodes.end(), deleter);
|
||||
std::for_each(nodes_chain.begin(), nodes_chain.end(), deleter);
|
||||
std::for_each(post_nodes_chain.begin(), post_nodes_chain.end(), deleter);
|
||||
}
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) {
|
||||
|
@ -681,8 +684,8 @@ std::string FBXConverter::NameTransformationChainNode(const std::string &name, T
|
|||
return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
|
||||
}
|
||||
|
||||
bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std::string &name, std::vector<aiNode *> &output_nodes,
|
||||
std::vector<aiNode *> &post_output_nodes) {
|
||||
bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std::string &name, std::vector<PotentialNode> &output_nodes,
|
||||
std::vector<PotentialNode> &post_output_nodes) {
|
||||
const PropertyTable &props = model.Props();
|
||||
const Model::RotOrder rot = model.RotationOrder();
|
||||
|
||||
|
@ -828,7 +831,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
|
|||
chain[i] = chain[i].Inverse();
|
||||
}
|
||||
|
||||
aiNode *nd = new aiNode();
|
||||
PotentialNode nd;
|
||||
nd->mName.Set(NameTransformationChainNode(name, comp));
|
||||
nd->mTransformation = chain[i];
|
||||
|
||||
|
@ -836,9 +839,9 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
|
|||
if (comp == TransformationComp_GeometricScalingInverse ||
|
||||
comp == TransformationComp_GeometricRotationInverse ||
|
||||
comp == TransformationComp_GeometricTranslationInverse) {
|
||||
post_output_nodes.push_back(nd);
|
||||
post_output_nodes.emplace_back(std::move(nd));
|
||||
} else {
|
||||
output_nodes.push_back(nd);
|
||||
output_nodes.emplace_back(std::move(nd));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -847,8 +850,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
|
|||
}
|
||||
|
||||
// else, we can just multiply the matrices together
|
||||
aiNode *nd = new aiNode();
|
||||
output_nodes.push_back(nd);
|
||||
PotentialNode nd;
|
||||
|
||||
// name passed to the method is already unique
|
||||
nd->mName.Set(name);
|
||||
|
@ -857,6 +859,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
|
|||
for (unsigned int i = TransformationComp_Translation; i < TransformationComp_MAXIMUM; i++) {
|
||||
nd->mTransformation = nd->mTransformation * chain[i];
|
||||
}
|
||||
output_nodes.push_back(std::move(nd));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,9 +171,10 @@ private:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* note: memory for output_nodes will be managed by the caller
|
||||
* note: memory for output_nodes is managed by the caller, via the PotentialNode struct.
|
||||
*/
|
||||
bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
|
||||
struct PotentialNode;
|
||||
bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<PotentialNode>& output_nodes, std::vector<PotentialNode>& post_output_nodes);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SetupNodeMetadata(const Model& model, aiNode& nd);
|
||||
|
|
|
@ -408,6 +408,45 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
|||
}
|
||||
}
|
||||
|
||||
// ... and copy all the morph targets for all the vertices which made it into the new submesh
|
||||
if (pMesh->mNumAnimMeshes > 0) {
|
||||
newMesh->mNumAnimMeshes = pMesh->mNumAnimMeshes;
|
||||
newMesh->mAnimMeshes = new aiAnimMesh*[newMesh->mNumAnimMeshes];
|
||||
|
||||
for (unsigned int morphIdx = 0; morphIdx < newMesh->mNumAnimMeshes; ++morphIdx) {
|
||||
aiAnimMesh* origTarget = pMesh->mAnimMeshes[morphIdx];
|
||||
aiAnimMesh* newTarget = new aiAnimMesh;
|
||||
newTarget->mName = origTarget->mName;
|
||||
newTarget->mWeight = origTarget->mWeight;
|
||||
newTarget->mNumVertices = numSubMeshVertices;
|
||||
newTarget->mVertices = new aiVector3D[numSubMeshVertices];
|
||||
newMesh->mAnimMeshes[morphIdx] = newTarget;
|
||||
|
||||
if (origTarget->HasNormals()) {
|
||||
newTarget->mNormals = new aiVector3D[numSubMeshVertices];
|
||||
}
|
||||
|
||||
if (origTarget->HasTangentsAndBitangents()) {
|
||||
newTarget->mTangents = new aiVector3D[numSubMeshVertices];
|
||||
newTarget->mBitangents = new aiVector3D[numSubMeshVertices];
|
||||
}
|
||||
|
||||
for( unsigned int vi = 0; vi < numSubMeshVertices; ++vi) {
|
||||
// find the source vertex for it in the source mesh
|
||||
unsigned int previousIndex = previousVertexIndices[vi];
|
||||
newTarget->mVertices[vi] = origTarget->mVertices[previousIndex];
|
||||
|
||||
if (newTarget->HasNormals()) {
|
||||
newTarget->mNormals[vi] = origTarget->mNormals[previousIndex];
|
||||
}
|
||||
if (newTarget->HasTangentsAndBitangents()) {
|
||||
newTarget->mTangents[vi] = origTarget->mTangents[previousIndex];
|
||||
newTarget->mBitangents[vi] = origTarget->mBitangents[previousIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I have the strange feeling that this will break apart at some point in time...
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue