mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
cloning node skeletons and meshes
This commit is contained in:
+6
-5
@@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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){
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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){
|
||||||
|
|||||||
Reference in New Issue
Block a user