-
-
Save sbrkopac/2ea619b90573c4cb25af639589c31e2d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*** | |
This example intentionally doesn't include any stacked transforms or animations. | |
It is just being used to showcase that the osgAnimation skeleton doesn't traverse | |
all bones down the hierarchy | |
***/ | |
#include <iostream> | |
#include <osgViewer/Viewer> | |
#include <osgAnimation/Bone> | |
#include <osgAnimation/UpdateBone> | |
#include <osgAnimation/Skeleton> | |
// override classes to get outputs | |
namespace test | |
{ | |
class Bone : public osgAnimation::Bone | |
{ | |
public: | |
Bone(const std::string name = "") : osgAnimation::Bone(name) | |
{ | |
} | |
virtual ~Bone() | |
{ | |
std::cout << "test::Bone::~Bone(" << getName() << ")" << std::endl; | |
} | |
}; | |
class UpdateBone : public osgAnimation::UpdateBone | |
{ | |
public: | |
UpdateBone(const std::string name = "") : osgAnimation::UpdateBone(name) | |
{ | |
std::cout << "test::UpdateBone::UpdateBone(" << name << ") constructed" << std::endl; | |
} | |
virtual ~UpdateBone() | |
{ | |
std::cout << "test::UpdateBone::~UpdateBone(" << getName() << ")" << std::endl; | |
} | |
void operator()(osg::Node* node, osg::NodeVisitor* nv) | |
{ | |
std::cout << "test::UpdateBone::operator(node, nv) being called for " << node->getName() << " should traverse[" << node->getNumChildrenRequiringUpdateTraversal() << "] children" << std::endl; | |
osgAnimation::UpdateBone::operator()(node, nv); | |
} | |
}; | |
} | |
// struct used in plugin | |
struct BoneInfo | |
{ | |
BoneInfo(std::string name, unsigned int parent) : name(name), parent(parent) {} | |
std::string name; | |
unsigned int parent; | |
unsigned int flags; | |
}; | |
// this is parsed from binary data and held prior to generating the OSG bone structure | |
std::vector<BoneInfo> boneNamesLoadedFromPlugin; | |
void addDummyBoneWithNameAndParent(std::string name, unsigned int parent); | |
void generateDummyBoneNames(); | |
int main(int argc, char* argv[]) | |
{ | |
osgViewer::Viewer viewer; | |
generateDummyBoneNames(); | |
// create our skeleton and add the callback | |
osg::ref_ptr<osgAnimation::Skeleton> skeleton = new osgAnimation::Skeleton; | |
skeleton->setDefaultUpdateCallback(); | |
viewer.getCamera()->setCullingMode(osg::CullSettings::NO_CULLING); | |
skeleton->setCullingActive(false); | |
// hold a reference to all bones for quick and easy lookup | |
std::vector<test::Bone *> vecBoneLookup; | |
const std::string& rootBoneName = boneNamesLoadedFromPlugin[0].name; | |
osg::ref_ptr<test::Bone> rootBone = new test::Bone(rootBoneName); | |
// add our root bone to our skeleton and our lookup | |
skeleton->addChild(rootBone); | |
vecBoneLookup.push_back(rootBone); | |
osg::ref_ptr<test::UpdateBone> rootBoneUpdater = new test::UpdateBone(rootBoneName); | |
rootBone->setUpdateCallback(rootBoneUpdater); | |
// loop over our entire bone information loaded from the plugin | |
for (unsigned int i = 0; i < boneNamesLoadedFromPlugin.size(); ++i) | |
{ | |
test::Bone* parentBone = nullptr; | |
// just grab the root bone as it already exists | |
if (i == 0) | |
{ | |
parentBone = rootBone; | |
std::cout << "Dealing with rootBone[" << parentBone->getName() << "]" << std::endl; | |
} | |
// create a new bone and add it to our look up | |
if (parentBone == nullptr) | |
{ | |
// get name from the loaded list | |
parentBone = new test::Bone(boneNamesLoadedFromPlugin[i].name); | |
vecBoneLookup.push_back(parentBone); | |
} | |
// loop over our children and create our hierarchy | |
for (unsigned int j = 0; j < boneNamesLoadedFromPlugin.size(); ++j) | |
{ | |
// check to make sure we don't parent a bone to itself | |
if (i != j && i == boneNamesLoadedFromPlugin[j].parent) | |
{ | |
std::string childBoneName = boneNamesLoadedFromPlugin[j].name; | |
osg::ref_ptr<test::Bone> childBone = new test::Bone(childBoneName); | |
// add it to its parent | |
parentBone->addChild(childBone); | |
// setup the updater | |
osg::ref_ptr <test::UpdateBone> updateBone = new test::UpdateBone(childBoneName); | |
childBone->addUpdateCallback(updateBone); | |
} | |
} | |
std::cout << "Parent bone [" << parentBone->getName() << "] has [" << parentBone->getNumChildren() << "] children" << std::endl; | |
} | |
// create our scene | |
osg::ref_ptr<osg::Group> scene = new osg::Group; | |
scene->addChild(skeleton); | |
viewer.setSceneData(scene); | |
std::cout << "-------------" << std::endl; | |
for (test::Bone* bone : vecBoneLookup) | |
{ | |
std::cout << "Bone[" << bone->getName() << "] has [" << bone->getNumChildren() << "] children" << std::endl; | |
} | |
std::cout << "-------------" << std::endl; | |
return viewer.run(); | |
} | |
void addDummyBoneWithNameAndParent(std::string name, unsigned int parent) | |
{ | |
boneNamesLoadedFromPlugin.push_back(BoneInfo(name, parent)); | |
} | |
void generateDummyBoneNames() | |
{ | |
boneNamesLoadedFromPlugin.clear(); | |
// add a root bone | |
addDummyBoneWithNameAndParent("root", 0); // index 0 | |
// add two children to our root bone | |
addDummyBoneWithNameAndParent("rootChild1", 0); // index 1 | |
addDummyBoneWithNameAndParent("rootChild2", 0); // index 2 | |
// add one child to the rootChild1 and rootChild2 | |
addDummyBoneWithNameAndParent("child1X", 1); // index 3 | |
addDummyBoneWithNameAndParent("child2X", 2); // index 4 | |
// add two children to child1X and child2X | |
addDummyBoneWithNameAndParent("child1X1", 3); // index 5 | |
addDummyBoneWithNameAndParent("child1X2", 3); // index 6 | |
addDummyBoneWithNameAndParent("child2X1", 4); // index 7 | |
addDummyBoneWithNameAndParent("child2x2", 4); // index 8 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment