Bladeren bron

Fixed a bug when cloning a MeshSkin.
The bug occurred when cloning a scene with two mesh skins that use the same joint hierarchy. The joints were being cloned twice.

Darryl Gough 13 jaren geleden
bovenliggende
commit
ef58d24b1e
4 gewijzigde bestanden met toevoegingen van 24 en 7 verwijderingen
  1. 13 2
      gameplay/src/MeshSkin.cpp
  2. 3 1
      gameplay/src/MeshSkin.h
  3. 1 1
      gameplay/src/Model.cpp
  4. 7 3
      gameplay/src/Node.cpp

+ 13 - 2
gameplay/src/MeshSkin.cpp

@@ -57,7 +57,7 @@ Joint* MeshSkin::getJoint(const char* id) const
     return NULL;
 }
 
-MeshSkin* MeshSkin::clone() const
+MeshSkin* MeshSkin::clone(NodeCloneContext &context) const
 {
     MeshSkin* skin = new MeshSkin();
     skin->_bindShape = _bindShape;
@@ -67,7 +67,18 @@ MeshSkin* MeshSkin::clone() const
         skin->setJointCount(jointCount);
 
         assert(skin->_rootNode == NULL);
-        skin->_rootNode = _rootNode->clone();
+        
+        // Check if the root node has already been cloned.
+        if (Node* rootNode = context.findClonedNode(_rootNode))
+        {
+            skin->_rootNode = rootNode;
+            rootNode->addRef();
+        }
+        else
+        {
+            skin->_rootNode = _rootNode->cloneRecursive(context);
+        }
+        
         Node* node = skin->_rootNode->findNode(_rootJoint->getId());
         assert(node);
         skin->_rootJoint = static_cast<Joint*>(node);

+ 3 - 1
gameplay/src/MeshSkin.h

@@ -134,9 +134,11 @@ private:
     /**
      * Clones the MeshSkin and the joints that it references.
      * 
+     * @param context The clone context.
+     * 
      * @return The newly created MeshSkin.
      */
-    MeshSkin* clone() const;
+    MeshSkin* clone(NodeCloneContext &context) const;
 
     /**
      * Sets the number of joints that can be stored in this skin.

+ 1 - 1
gameplay/src/Model.cpp

@@ -354,7 +354,7 @@ Model* Model::clone(NodeCloneContext &context)
     Model* model = Model::create(getMesh());
     if (getSkin())
     {
-        model->setSkin(getSkin()->clone());
+        model->setSkin(getSkin()->clone(context));
     }
     Material* materialClone = getMaterial()->clone(context);
     model->setMaterial(materialClone); // TODO: Don't forget material parts

+ 7 - 3
gameplay/src/Node.cpp

@@ -866,10 +866,16 @@ Node* Node::cloneRecursive(NodeCloneContext &context) const
 {
     Node* copy = cloneSingleNode(context);
 
+    Node* lastChild = NULL;
     for (Node* child = getFirstChild(); child != NULL; child = child->getNextSibling())
+    {
+        lastChild = child;
+    }
+    // Loop through the nodes backwards because addChild adds the node to the front.
+    for (Node* child = lastChild; child != NULL; child = child->getPreviousSibling())
     {
         Node* childCopy = child->cloneRecursive(context);
-        copy->addChild(childCopy); // TODO: Does child order matter?
+        copy->addChild(childCopy);
         childCopy->release();
     }
     return copy;
@@ -880,8 +886,6 @@ void Node::cloneInto(Node* node, NodeCloneContext &context) const
     Transform::cloneInto(node, context);
 
     // TODO: Clone the rest of the node data.
-    //node->setCamera(getCamera());
-    //node->setLight(getLight());
 
     if (Camera* camera = getCamera())
     {