Hello, everyone.

As usual, I'm going to ask some very basic questions.

I've been reading a source code set as an example, which was made to teach
callbacks, but I couldn't find out exactly what each method does. I'm
ataching the code so you can answer my most serious doubts:

- What does "operator () (...)" does?
- What is the intention on multiplying matrices "osg::Matrix::rotate(...) *
osg::Matrix::translate"?

Thank you.

Renan M Z Mendes
// A small test scenegraph that tests transformation nodes.
// Copyright 2007  Peter Gebauer
// Licensed as Public Domain

#include <osg/Vec3d>
#include <osg/Vec3f>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>

#include <osgViewer/Viewer>
#include <iostream>

////
// Position and rotaion transform update.
////
class PositionRotationCallback : public osg::NodeCallback
{
public:
    // Override the constructor
    PositionRotationCallback(float ax, float ay, float az, float aspeed);
    void operator()(osg::Node* node, osg::NodeVisitor* nv);
private:
    float x;
    float y;
    float z;
    float angle;
    float speed;
};

// Constructor for the rotational callback.
PositionRotationCallback::PositionRotationCallback(float ax, float ay, float 
az, float aspeed) {
    x = ax;
    y = ay;
    z = az;
    angle = 0;
    speed = aspeed;
}

// The node/node visitor operator override.
void PositionRotationCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
    osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node);
    // Increase angle.
    angle += speed;
    while (angle > 359)
        angle -= 360;
    while (angle < 0)
        angle += 360;
    // Transform using a two matrices. The * indicates a multiplication between 
two
    // matrices.
    transform->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(angle), 0.0, 
1.0, 0.0)
                         * osg::Matrix::translate(x, y, z));
    // Continue callbacks for chlildren too.
    ((osg::NodeCallback*) this)->traverse(node, nv);
}

////
// Box class
////
class Box : public osg::MatrixTransform
{
public:
    Box(float x, float y, float z, float size, float speed);
};

Box::Box(float x, float y, float z, float size, float speed)
{
    // First we create a node with transformation capabilities, i.e a geode.
    osg::Geode* geode = new osg::Geode();
    // Now we need a drawable that will be rendered. We use the simplified
    // API of the ShapeDrawable which only requires a shape instance.
    // That way we don't have to deal with creating vertices.
    osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3d(0, 
0, 0), size));
    // Add the drawable.
    geode->addDrawable(drawable);
    // Add the geode to the transform.
    addChild(geode);
    // Put a spin to it. :)
    // The node will be visited every frame to check for an update.
    setUpdateCallback(new PositionRotationCallback(x, y, z, speed);)
}

////
// Scenegraph class
////
class TestScenegraph : public osg::Group
{
public:
    // Override the constructor
    TestScenegraph();
    Box* createBox(float x, float y, float z, float speed, float size);
};

// Scenegraph constructor
TestScenegraph::TestScenegraph() {
    // Create a new transformation node.
    osg::MatrixTransform *transform = new osg::MatrixTransform;
    // A group of shapes.
    osg::Group *shapes = new osg::Group();
    // Add a few boxes to the shapes group.
    shapes->addChild(new Box(0.0, 0.0, 0.0, 1.0, 0.1));
    shapes->addChild(new Box(2.0, 0.0, 0.0, 1.0, 0.2));
    shapes->addChild(new Box(-2.0, 0.0, 0.0, 1.0, -0.1));
    // Put all the shapes into the transform.
    transform->addChild(shapes);
    // Add some matrix transforms to the matrix transformer.
    transform->setUpdateCallback(new PositionRotationCallback(0.0, 10.0, 0.0, 
0.0));
    // Add the transform to the scenegraph.
    addChild(transform);
}

int main(int argc, char **argv)
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);
    osg::DisplaySettings::instance()->setMinimumNumAlphaBits(8);
   
    // construct the viewer.
    osgViewer::Viewer viewer;

    // if user request help write it to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // Create a scenegraph node.
    osg::ref_ptr<osg::Node> node;    

    // Assign the node to our scenegraph.
    node = new TestScenegraph();
    // Add the node data to the viewer.
    viewer.setSceneData(node.get());

    // Run the viewer.
    return viewer.run();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to