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