From 2cfafd7de6875f1d146be0b0152aa88679cd7d07 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sat, 19 Mar 2022 21:10:45 +0200 Subject: [PATCH] fixed model asset cloning --- meshData.cpp | 3 +- meshData.h | 3 +- model.cpp | 12 ++++---- node.cpp | 69 ++++++++++++++++++++++++++++++++++------------ node.h | 3 +- xmlModelReader.cpp | 26 ++--------------- 6 files changed, 64 insertions(+), 52 deletions(-) diff --git a/meshData.cpp b/meshData.cpp index 29d9fdf..c032ae3 100644 --- a/meshData.cpp +++ b/meshData.cpp @@ -17,12 +17,13 @@ namespace vb01{ } } - MeshData::MeshData(Vertex *vertices, u32 *indices, int numTris, string *vertexGroups, int numVertexGroups, ShapeKey *shapeKeys, int numShapeKeys){ + MeshData::MeshData(Vertex *vertices, u32 *indices, int numTris, string *vertexGroups, int numVertexGroups, string fullSkeletonName, ShapeKey *shapeKeys, int numShapeKeys){ this->vertices = vertices; this->indices = indices; this->numTris = numTris; this->vertexGroups = vertexGroups; this->numVertexGroups = numVertexGroups; + this->fullSkeletonName = fullSkeletonName; this->shapeKeys = shapeKeys; this->numShapeKeys = numShapeKeys; } diff --git a/meshData.h b/meshData.h index 336dde9..3a11e1a 100644 --- a/meshData.h +++ b/meshData.h @@ -30,9 +30,10 @@ namespace vb01{ ShapeKey *shapeKeys = nullptr; u32 *indices, VAO, VBO, EBO; int numTris, numVertexGroups = 0, numShapeKeys = 0; + std::string fullSkeletonName = ""; MeshData(){} - MeshData(Vertex*, u32*, int, std::string *vg = nullptr, int = 0, ShapeKey *sk = nullptr, int = 0); + MeshData(Vertex*, u32*, int, std::string *vg = nullptr, int = 0, std::string = "", ShapeKey *sk = nullptr, int = 0); }; } diff --git a/model.cpp b/model.cpp index e5ceda0..287c842 100755 --- a/model.cpp +++ b/model.cpp @@ -20,14 +20,12 @@ using namespace std; using namespace Assimp; namespace vb01{ - Model::Model(string path) : Node(((ModelAsset*)AssetManager::getSingleton()->getAsset(path))->rootNode){ - vector descendants; - getDescendants(descendants); + Model::Model(string path) : Node(){ + ModelAsset *asset = ((ModelAsset*)AssetManager::getSingleton()->getAsset(path)); + Node *clonedRoot = asset->rootNode->clone(); - for(Node *desc : descendants) - for(Mesh *mesh : desc->getMeshes()){ - mesh->construct(); - } + for(Node *child : clonedRoot->getChildren()) + attachChild(child); } Model::~Model(){ diff --git a/node.cpp b/node.cpp index 6f40c3d..647c1c1 100755 --- a/node.cpp +++ b/node.cpp @@ -22,24 +22,6 @@ namespace vb01{ this->orientation = orientation; } - Node::Node(Node *node) : Animatable(node->getName()){ - for(Mesh *m : node->getMeshes()) - attachMesh(new Mesh(m->getMeshBase())); - - for(Skeleton *skel : node->getSkeletons()){ - Skeleton *sk = new Skeleton(); - vector bones = skel->getBones(); - - for(Bone *b : bones) - sk->addBone(b, nullptr); - - addSkeleton(sk); - } - - for(Node *child : node->getChildren()) - attachChild(new Node(child)); - } - Node::~Node(){ for(Mesh *m : meshes) delete m; @@ -82,6 +64,57 @@ namespace vb01{ driver->drive(getDriverValue(driver->getType())); } + Node* Node::clone(){ + return cloneNode(true); + } + + Node* Node::cloneNode(bool firstIter){ + Node *node = new Node(pos, orientation, scale, name); + + for(Mesh *mesh : meshes){ + Mesh *m = new Mesh(mesh->getMeshBase()); + m->construct(); + node->attachMesh(m); + } + + for(Skeleton *skel : skeletons){ + vector bones = skel->getBones(); + Skeleton *sk = new Skeleton(skel->getName()); + + for(Bone *bone : bones) + sk->addBone(bone, nullptr); + + node->addSkeleton(sk); + } + + for(Node *child : children) + node->attachChild(child->cloneNode(false)); + + if(firstIter){ + vector descendants = vector{node}; + node->getDescendants(descendants); + vector meshes; + + for(Node *desc : descendants) + for(Mesh *mesh : desc->getMeshes()) + meshes.push_back(mesh); + + for(Mesh *mesh : meshes){ + int dotId = mesh->getMeshBase().fullSkeletonName.find_first_of("."); + string nodeName = mesh->getMeshBase().fullSkeletonName.substr(0, dotId); + string skelName = mesh->getMeshBase().fullSkeletonName.substr(dotId + 1, string::npos); + + for(Node *desc : descendants) + if(nodeName == desc->getName()) + for(Skeleton *sk : desc->getSkeletons()) + if(sk->getName() == skelName) + mesh->setSkeleton(sk); + } + } + + return node; + } + float Node::getDriverValue(Driver::VariableType type){ float driverValue; diff --git a/node.h b/node.h index b526709..7ab7db7 100755 --- a/node.h +++ b/node.h @@ -21,8 +21,8 @@ namespace vb01{ class Node : public Animatable{ public: Node(Vector3 = Vector3::VEC_ZERO, Quaternion = Quaternion::QUAT_W, Vector3 = Vector3::VEC_IJK, std::string = ""); - Node(Node*); virtual ~Node(); + Node* clone(); void addSkeleton(Skeleton*); void attachMesh(Mesh*); void attachParticleEmitter(ParticleEmitter*); @@ -68,6 +68,7 @@ namespace vb01{ inline void setVisible(bool v){this->visible = v;} inline void addDriver(Driver *d){drivers.push_back(d);} private: + Node* cloneNode(bool); void adjustUp(Vector3); void adjustDir(Vector3); void updateShaders(); diff --git a/xmlModelReader.cpp b/xmlModelReader.cpp index 02a44d7..9cc1596 100644 --- a/xmlModelReader.cpp +++ b/xmlModelReader.cpp @@ -42,21 +42,6 @@ namespace vb01{ assetRootNode->getDescendants(descendants); setupDrivers(descendants); - vector meshes; - - for(Node *desc : descendants) - for(Mesh *m : desc->getMeshes()) - if(m->getSkeleton()) - meshes.push_back(m); - - for(Mesh *m : meshes) - for(Node *desc : descendants) - for(Skeleton *sk : desc->getSkeletons()) - if(m->getSkeleton()->getName() == sk->getName()){ - delete m->getSkeleton(); - m->setSkeleton(sk); - } - return asset; } @@ -175,15 +160,8 @@ namespace vb01{ vertices[j].shapeKeyOffsets[i] = shapeKeyPos[vertIds[j]] - vertPos[vertIds[j]]; } - Mesh *mesh = new Mesh(MeshData(vertices, indices, numVertices / 3, vertexGroups, numVertexGroups, shapeKeys, numShapeKeys)); - - const char *skeletonName = meshEl->Attribute("skeleton"); - - if(skeletonName){ - int dotId = string(skeletonName).find_first_of("."); - string name = string(skeletonName).substr(dotId + 1, string::npos); - mesh->setSkeleton(new Skeleton(name)); - } + const char *fullSkeletonName = meshEl->Attribute("skeleton"); + Mesh *mesh = new Mesh(MeshData(vertices, indices, numVertices / 3, vertexGroups, numVertexGroups, (fullSkeletonName ? fullSkeletonName : ""), shapeKeys, numShapeKeys)); return mesh; }