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