Thanks agin for helping me with this.

While I am very new to all of this, I have spent the better part of the last 5 
weeks learning open scene graph.  I have a basic knowledge of a fair chunck of 
it I believe.  My problem is, is that I have gone through many of the examples, 
I have worked through the majority of the OpenSceneGraph for Beginners book and 
scoured the forums many a time. 

The osgrobot example is a good example, except it shows you how to assemble 
your own shapes and add them to global MatrixTransforms.  I suppose I could 
build a simple hand model of capsules and shapes as well and get them to 
function similarily. 

But why put the time into rebuilding a lower quality hand model when I already 
have one.  My problem is just that with the .3ds hand model I haven't built it 
myself and don't know the exact structure.  Also I am doing this for my company 
and I unfortunately have a time pressure over my head.  

In the osgRobot example, its very clear that we have a group of 
MatrixTransforms that have drawables as children to the MatrixTransforms.  So 
when a rotation is applied to the transform it is also applied to its children 
hence moving a part of the model.

The hand model is not made up of clear indivudal parts however.  If it is, I 
don't know how to access them.  I can traverse through the hands parts and see 
how its built and what parts have what names.  This doesn't help me understand 
how to manipulate its geometry though. 

For example the hand is made up of 5 fingers.  Each finger has 4 joints and an 
end aside from the thumb which has 3 joints and an end.  These joints and ends 
show up as MatrixTransforms when I call className() on them from a given Node 
in a traversal class.

Ex:


Code:

class TestTraverser : public osg::NodeVisitor
{
public:
        TestTraverser() : NodeVisitor(TRAVERSE_ALL_CHILDREN), spaces(0){}

        virtual void apply(osg::Node &node)
        {
                
                OSG_NOTICE << std::string(spaces * 2, ' ') << "Traverse Class.  
This node is a: " << node.libraryName() << "::" << node.className() << " and 
has the associated name: " << node.getName() << std::endl;

                spaces++;
                traverse(node);
                spaces--;
        }

protected:
        int spaces;
};




For the Index finger I would get this output:

Traverse Class.  This node is a: osg::MatrixTransform and has the associated 
name: L_IndexA
          Traverse Class.  This node is a: osg::MatrixTransform and has the 
associated name: L_IndexB
            Traverse Class.  This node is a: osg::MatrixTransform and has the 
associated name: L_IndexC
              Traverse Class.  This node is a: osg::MatrixTransform and has the 
associated name: L_IndexD
                Traverse Class.  This node is a: osg::MatrixTransform and has 
the associated name: L_IndexEND
                  Traverse Class.  This node is a: osg::Geode and has the 
associated name: 
                Traverse Class.  This node is a: osg::Geode and has the 
associated name: 
              Traverse Class.  This node is a: osg::Geode and has the 
associated name: 
            Traverse Class.  This node is a: osg::Geode and has the associated 
name: 
          Traverse Class.  This node is a: osg::Geode and has the associated 
name: 

Notice how the Goeds don't have names.  I am assuming this because they don't 
need names when someone is modelling in a modeling program they worry only 
about labeling the joints.  The Geodes are actually just representations of the 
geometry that makes up a fingers appearence, correct?

So I can then grab say for example a single node and create a reference to it, 
something like:

   
    osg::ref_ptr<osg::MatrixTransform> indexB = new osg::MatrixTransform;
    if(node.getName() == "L_IndexB")
        indexB = node;   

Then in later on assuming indexB is global I can do
    indexB->setMatrix(osg::Matrix::translate(1,0,0));
in an Update() method that runs every frame.


This should move the matrixTransform, and I would expect the finger to look 
weird on the screen when running the application.  Assuming B is the middle 
knuckle of the finger, the left index finger knuckle should be bowed out to the 
left.  But it never is.

So to make sure I was actually moving something I added an axes to all the 
MatrixTransforms.  Like in the osgrobot example where it shows axes arrows on 
each shape.   So then I could see all the matrixTransforms on my hand model 
because the axes are on there.  AND! I could now see that the axis that would 
normally be where the left index finger joint is now over to the left.  So the 
matrix is actually moved but the hand itself is visually unchanged.  

I can even do something like 
    indexB->setMatrix(osg::Matrix::rotate(50, osg::Z_AXIS) * 
indexB->getMatrix());

And then the axes will spin around and around, but the finger never does.  What 
I don't understnad is why.  Thats whay I was hoping to get at.  

Also, because Im new my terminology is useless, I understand a lot of the 
concepts even though I can't expess them in the same way one who has more 
experience does.  Also one who has experience as yourself might think what you 
are saying to me is crytal clear but because I may not be used to hearing 
certain terms or have maybe a key concept mixed up in my brain I misunderstand.

Really I am just trying to prove right now that I think I have enough 
understanding to figure this out.  I feel like Im so close, I can make any of 
my own drawables and shapes move this way, but not the hand model.   

To help clarify even more I've attached a simple example of what I am trying to 
achieve in order to learn how to do this.  Maybe that will make things clearer. 
 Here is the link to the hand model i am using from my dropbox:

https://dl.dropboxusercontent.com/u/44220561/lefthand.3ds

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=61065#61065



#include <osgViewer\Viewer>
#include <osg\MatrixTransform>
#include <osgDB\ReadFile>

using namespace osg;

ref_ptr<Geode> createAxis(float scale)
{
        ref_ptr<Geode>          geode = new Geode();
        ref_ptr<Geometry>       geometry = new Geometry();
        ref_ptr<Vec3Array>      vertices = new Vec3Array();
        ref_ptr<Vec4Array>      colors = new Vec4Array();

        vertices->push_back(Vec3(0.0f, 0.0f, 0.0f));
        vertices->push_back(Vec3(scale, 0.0f, 0.0f));
        vertices->push_back(Vec3(0.0f, 0.0f, 0.0f));
        vertices->push_back(Vec3(0.0f, scale, 0.0f));
        vertices->push_back(Vec3(0.0f, 0.0f, 0.0f));
        vertices->push_back(Vec3(0.0f, 0.0f, scale));

        colors->push_back(Vec4(1.0f, 0.0f, 0.0f, 1.0f));
        colors->push_back(Vec4(1.0f, 0.0f, 0.0f, 1.0f));
        colors->push_back(Vec4(0.0f, 1.0f, 0.0f, 1.0f));
        colors->push_back(Vec4(0.0f, 1.0f, 0.0f, 1.0f));
        colors->push_back(Vec4(0.0f, 0.0f, 1.0f, 1.0f));
        colors->push_back(Vec4(0.0f, 0.0f, 1.0f, 1.0f));

        geometry->setVertexArray(vertices);
        geometry->setColorArray(colors);
        geometry->setColorBinding(Geometry::BIND_PER_VERTEX);
        geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::LINES, 0, 6));
        geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
        geode->addDrawable(geometry);

        return geode;
}
std::map<std::string, ref_ptr<MatrixTransform>> fingerParts;

class testTraverser : public osg::NodeVisitor
{
public:
        testTraverser() : NodeVisitor(TRAVERSE_ALL_CHILDREN), spaces(0){}

        virtual void apply(osg::Node &node)
        {
                ref_ptr<MatrixTransform> mt = 
dynamic_cast<MatrixTransform*>(&node);
                OSG_NOTICE << std::string(spaces * 2, ' ') << "Traverse Class.  
This node is a: " << node.libraryName() << "::" << node.className() << " and 
has the associated name: " << node.getName() << std::endl;

                if (mt)
                {       
                        mt->addChild(createAxis(5));
                        fingerParts.insert(std::pair< std::string, 
ref_ptr<MatrixTransform>>(mt->getName() != "" ? mt->getName() : "no name", mt));
                }

                spaces++;
                traverse(node);
                spaces--;
        }

protected:
        int spaces;
};

bool once = true;

void update()
{
        fingerParts.at("L_IndexB")->setMatrix(Matrix::rotate(50, Z_AXIS)* 
fingerParts.at("L_IndexB")->getMatrix());
}



int main(int argc, char** argv)
{

        testTraverser *TT       = new testTraverser();
        ref_ptr<Group> root = new Group;
        ref_ptr<Node> hand      = osgDB::readNodeFile("lefthand.3ds");

        hand->setDataVariance   (Object::DYNAMIC);
        hand->accept                    (*TT);
        root->addChild                  (hand);

        osgViewer::Viewer viewer;
        ref_ptr<Camera> cam = new Camera(*(viewer.getCamera()));
        cam->setViewMatrixAsLookAt(Vec3d(0, -80, 0), Vec3d(-30, 0, 10), 
Vec3d(0, 0, 1));

        viewer.setCamera(cam.get());
        viewer.setSceneData(root.get());

        viewer.realize();

        while (!viewer.done())
        {
                update();
                viewer.frame();
        }

        delete TT;
        return 0;
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to