cloning node skeletons and meshes

This commit is contained in:
devZoGok
2022-03-27 19:42:41 +03:00
parent fdf751cde5
commit 85a6b846bc
6 changed files with 94 additions and 59 deletions
+6 -5
View File
@@ -7,13 +7,14 @@ namespace vb01{
class Node; class Node;
struct Attachable{ struct Attachable{
std::string fullName = ""; public:
Node *node = nullptr;
Attachable(std::string fullName){this->fullName = fullName;} Attachable(std::string fullName){this->fullName = fullName;}
Attachable(){} Attachable(){}
virtual void onAttached(Node*){} virtual void onAttached(Node *node){this->node = node;}
std::string getFullName(){return fullName;} std::string getAttachableName(){return fullName;}
protected:
std::string fullName = "";
Node *node = nullptr;
}; };
} }
+48 -38
View File
@@ -68,54 +68,65 @@ namespace vb01{
} }
Node* Node::clone(){ Node* Node::clone(){
return cloneNode(true); vector<Node*> originalDescendants = vector<Node*>{this};
getDescendants(originalDescendants);
int numDescendants = originalDescendants.size();
vector<Node*> clonedDescendants;
for(int i = 0; i < numDescendants; i++){
Node *original = originalDescendants[i];
Node *clone = new Node(original->getPosition(), original->getOrientation(), original->getScale(), original->getName());
for(int j = 0; j < i; j++)
if(original->getParent() == originalDescendants[j]){
clonedDescendants[j]->attachChild(clone);
break;
} }
Node* Node::cloneNode(bool firstIter){ clonedDescendants.push_back(clone);
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){ for(int i = 0; i < numDescendants; i++){
vector<Bone*> bones = skel->getBones(); Node *original = originalDescendants[i];
Skeleton *sk = new Skeleton(skel->getName());
for(Bone *bone : bones) for(Skeleton *skel : original->getSkeletons()){
sk->addBone(bone, nullptr); Skeleton *sk = new Skeleton(skel->getAttachableName());
node->addSkeleton(sk); for(Bone *bone : skel->getBones())
for(int j = 0; j < numDescendants; j++)
if(bone == originalDescendants[j]){
sk->addBone((Bone*)clonedDescendants[j], nullptr);
break;
} }
for(Node *child : children) clonedDescendants[i]->addSkeleton(sk);
node->attachChild(child->cloneNode(false)); }
if(firstIter){ for(Mesh *mesh : original->getMeshes()){
vector<Node*> descendants = vector<Node*>{node}; Mesh *m = new Mesh(MeshData(mesh->getMeshBase()));
node->getDescendants(descendants);
vector<Mesh*> meshes;
for(Node *desc : descendants) if(mesh->getSkeleton())
for(Mesh *mesh : desc->getMeshes()) for(int j = 0; j < numDescendants; j++)
meshes.push_back(mesh); for(int k = 0; k < clonedDescendants[j]->getNumSkeletons(); k++)
if(
clonedDescendants[j]->getName() == originalDescendants[j]->getName() &&
clonedDescendants[j]->getSkeleton(k)->getAttachableName() == mesh->getSkeleton()->getAttachableName()
){
m->setSkeleton(clonedDescendants[j]->getSkeleton(k));
break;
}
for(Mesh *mesh : meshes){ clonedDescendants[i]->attachMesh(m);
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) for(Driver *driver : original->getDrivers()){
if(nodeName == desc->getName()) Driver *dr = new Driver(nullptr, driver->getKeyframeChannel(), driver->getType());
for(Skeleton *sk : desc->getSkeletons()) clonedDescendants[i]->addDriver(dr);
if(sk->getName() == skelName)
mesh->setSkeleton(sk);
} }
} }
return node; return clonedDescendants[0];
} }
float Node::getDriverValue(Driver::VariableType type){ float Node::getDriverValue(Driver::VariableType type){
@@ -180,7 +191,7 @@ namespace vb01{
void Node::attachMesh(Mesh *mesh){ void Node::attachMesh(Mesh *mesh){
meshes.push_back(mesh); meshes.push_back(mesh);
mesh->setNode(this); mesh->onAttached(this);
} }
void Node::addSkeleton(Skeleton *skeleton){ void Node::addSkeleton(Skeleton *skeleton){
@@ -189,27 +200,26 @@ namespace vb01{
void Node::attachParticleEmitter(ParticleEmitter *emitter){ void Node::attachParticleEmitter(ParticleEmitter *emitter){
emitters.push_back(emitter); emitters.push_back(emitter);
emitter->setNode(this); emitter->onAttached(this);
} }
void Node::addLight(Light *light){ void Node::addLight(Light *light){
Root::getSingleton()->shiftNumLights(true); Root::getSingleton()->shiftNumLights(true);
lights.push_back(light); lights.push_back(light);
light->setNode(this); light->onAttached(this);
updateShaders(); updateShaders();
} }
void Node::removeLight(int id){ void Node::removeLight(int id){
Root::getSingleton()->shiftNumLights(false); Root::getSingleton()->shiftNumLights(false);
Light *light = lights[id]; Light *light = lights[id];
light->setNode(nullptr);
lights.erase(lights.begin() + id); lights.erase(lights.begin() + id);
updateShaders(); updateShaders();
} }
void Node::addText(Text *text){ void Node::addText(Text *text){
texts.push_back(text); texts.push_back(text);
text->setNode(this); text->onAttached(this);
} }
void Node::lookAt(Vector3 newDir, Vector3 newUp){ void Node::lookAt(Vector3 newDir, Vector3 newUp){
+3 -1
View File
@@ -46,6 +46,7 @@ namespace vb01{
Vector3 localToGlobalScale(Vector3); Vector3 localToGlobalScale(Vector3);
Vector3 globalToLocalScale(Vector3); Vector3 globalToLocalScale(Vector3);
inline Skeleton* getSkeleton(int i){return skeletons[i];} inline Skeleton* getSkeleton(int i){return skeletons[i];}
inline int getNumSkeletons(){return skeletons.size();}
inline Text* getText(int i){return texts[i];} inline Text* getText(int i){return texts[i];}
inline std::vector<Mesh*>& getMeshes(){return meshes;} inline std::vector<Mesh*>& getMeshes(){return meshes;}
inline std::vector<Skeleton*>& getSkeletons(){return skeletons;} inline std::vector<Skeleton*>& getSkeletons(){return skeletons;}
@@ -67,8 +68,9 @@ namespace vb01{
inline bool isVisible(){return visible;} inline bool isVisible(){return visible;}
inline void setVisible(bool v){this->visible = v;} inline void setVisible(bool v){this->visible = v;}
inline void addDriver(Driver *d){drivers.push_back(d);} inline void addDriver(Driver *d){drivers.push_back(d);}
inline Driver* getDriver(int i){return drivers[i];}
inline std::vector<Driver*> getDrivers(){return drivers;}
private: private:
Node* cloneNode(bool);
void adjustUp(Vector3); void adjustUp(Vector3);
void adjustDir(Vector3); void adjustDir(Vector3);
void updateShaders(); void updateShaders();
+31 -11
View File
@@ -79,15 +79,12 @@ namespace vb01{
} }
void NodeTest::testClonedDrivers(){ void NodeTest::testClonedDrivers(){
vector<Keyframe> keyframes = vector<Keyframe>{ vector<Keyframe> keyframes;
KeyframeChannel::createKeyframe(KeyframeInterpolation::LINEAR, 1, 1),
KeyframeChannel::createKeyframe(KeyframeInterpolation::LINEAR, 2, 2),
KeyframeChannel::createKeyframe(KeyframeInterpolation::LINEAR, 3, 3)
};
KeyframeChannelType channelType = KeyframeChannelType::POS_X; KeyframeChannelType channelType = KeyframeChannelType::POS_X;
KeyframeChannel channel = KeyframeChannel::createKeyframeChannel(channelType, "D", keyframes); string animName = "D";
KeyframeChannel channel = KeyframeChannel::createKeyframeChannel(channelType, animName, keyframes);
Driver::VariableType driverType = Driver::POS_X; Driver::VariableType driverType = Driver::POS_X;
Driver *driver = new Driver(nullptr, channel, driverType); Driver *driver = new Driver(originalD, channel, driverType);
originalB->addDriver(driver); originalB->addDriver(driver);
Node *clonedA = originalA->clone(); Node *clonedA = originalA->clone();
@@ -101,7 +98,7 @@ namespace vb01{
clonedB = desc; clonedB = desc;
break; break;
} }
else if(desc->getName() == "D"){ else if(desc->getName() == animName){
clonedD = desc; clonedD = desc;
break; break;
} }
@@ -110,17 +107,17 @@ namespace vb01{
Driver *driverClone = clonedB->getDriver(0); Driver *driverClone = clonedB->getDriver(0);
CPPUNIT_ASSERT(driverClone->getAnimatable() == clonedD); CPPUNIT_ASSERT(driverClone->getAnimatable() == clonedD);
CPPUNIT_ASSERT(driverClone->getKeyframeChannel().type == channelType); CPPUNIT_ASSERT(driverClone->getKeyframeChannel().type == channelType);
CPPUNIT_ASSERT(driverClone->getKeyframeChannel().animatable == animName);
CPPUNIT_ASSERT(driverClone->getType() == driverType); CPPUNIT_ASSERT(driverClone->getType() == driverType);
} }
void NodeTest::testClonedSkeletons(){ void NodeTest::testClonedSkeletons(){
Skeleton *skeleton = new Skeleton(); Skeleton *skeleton = new Skeleton();
skeleton->addBone((Bone*)originalC, nullptr); skeleton->addBone((Bone*)originalC, (Bone*)originalC->getParent());
skeleton->addBone((Bone*)originalD, nullptr); skeleton->addBone((Bone*)originalD, (Bone*)originalD->getParent());
originalA->addSkeleton(skeleton); originalA->addSkeleton(skeleton);
Node *clonedA = originalA->clone(); Node *clonedA = originalA->clone();
CPPUNIT_ASSERT(!empty(clonedA->getSkeletons()));
CPPUNIT_ASSERT(clonedA->getSkeleton(0)); CPPUNIT_ASSERT(clonedA->getSkeleton(0));
Skeleton *clonedSkeleton = originalA->getSkeleton(0); Skeleton *clonedSkeleton = originalA->getSkeleton(0);
@@ -128,6 +125,29 @@ namespace vb01{
CPPUNIT_ASSERT(clonedSkeleton->getBone(1)->getName() == originalD->getName()); CPPUNIT_ASSERT(clonedSkeleton->getBone(1)->getName() == originalD->getName());
} }
void NodeTest::testClonedMeshSkeleton(){
string name = "skeleton";
Mesh *mesh = new Mesh(MeshData(nullptr, nullptr, 0));
Skeleton *skeleton = new Skeleton(name);
mesh->setSkeleton(skeleton);
originalD->attachMesh(mesh);
originalD->addSkeleton(skeleton);
Node *clonedA = originalA->clone();
Node *clonedD = nullptr;
vector<Node*> clonedDescendands;
clonedA->getDescendants(clonedDescendands);
for(Node *desc : clonedDescendands)
if(desc->getName() == "D"){
clonedD = desc;
break;
}
CPPUNIT_ASSERT(clonedD->getMesh(0)->getSkeleton()->getAttachableName() == name);
}
void NodeTest::testGetAncestors(){ void NodeTest::testGetAncestors(){
vector<Node*> ancestors = ancestorD->getAncestors(); vector<Node*> ancestors = ancestorD->getAncestors();
CPPUNIT_ASSERT(ancestors[ancestors.size() - 1] == rootNode); CPPUNIT_ASSERT(ancestors[ancestors.size() - 1] == rootNode);
+2
View File
@@ -12,6 +12,7 @@ namespace vb01{
CPPUNIT_TEST(testClonedMeshes); CPPUNIT_TEST(testClonedMeshes);
CPPUNIT_TEST(testClonedDrivers); CPPUNIT_TEST(testClonedDrivers);
CPPUNIT_TEST(testClonedSkeletons); CPPUNIT_TEST(testClonedSkeletons);
CPPUNIT_TEST(testClonedMeshSkeleton);
CPPUNIT_TEST(testGetAncestors); CPPUNIT_TEST(testGetAncestors);
CPPUNIT_TEST(testAdjustDir); CPPUNIT_TEST(testAdjustDir);
CPPUNIT_TEST(testAdjustUp); CPPUNIT_TEST(testAdjustUp);
@@ -30,6 +31,7 @@ namespace vb01{
void testClonedMeshes(); void testClonedMeshes();
void testClonedDrivers(); void testClonedDrivers();
void testClonedSkeletons(); void testClonedSkeletons();
void testClonedMeshSkeleton();
void testAdjustDir(); void testAdjustDir();
void testAdjustUp(); void testAdjustUp();
void testDetachChild(); void testDetachChild();
+1 -1
View File
@@ -89,8 +89,8 @@ namespace vb01{
if(parent) if(parent)
parent->attachChild(bone); parent->attachChild(bone);
bone->setSkeleton(this);
bones.push_back(bone); bones.push_back(bone);
bone->setSkeleton(this);
} }
Bone* Skeleton::getBone(string name){ Bone* Skeleton::getBone(string name){