Hi Osg-Users,
Here's a topic that I cannot seem to find any reference in the archives for.
 I'm trying to create an Axes rotation indicator Glyph in the lower
left-hand corner of our viewer (X, Y, Z).  I've got working code for this
(see below), but it is an orthographic projection, while my scene is
perspective.  The axes rotation indicator works correctly, (e.g. it
correctly matches the rotation of the trackball & scene) but because it is
ortho and the scene is perspective, it's quite jarring to the user.  Can
someone suggest how I can modify the code below so that it correctly maps
the axes in perspective (ideally, the same perspective frustum as my scene)?

Many thanks.

Sean

Code
---------------------------------------

#ifndef OsgAxes_h
#define OsgAxes_h

// OSG Includes
#include <osg/Group>
#include <osg/Geometry>
#include <osg/Camera>
#include <osg/Quat>
#include <osg/MatrixTransform>
#include <osg/Referenced>
#include <osg/NodeCallback>
#include <osgGA/TrackballManipulator>

class OsgAxes : public osg::Group
{

public:

// Public Constructor
explicit OsgAxes(const osgGA::TrackballManipulator &trackball);

// Public Destructor
virtual ~OsgAxes();

void updateCurrentRotation();

private:

osg::Geometry *createAxes();

// Prevent Copy & Assignment
 OsgAxes(const OsgAxes &);
OsgAxes &operator=(const OsgAxes &);

osg::ref_ptr<osg::MatrixTransform> m_rotation;

const osgGA::TrackballManipulator &m_trackball;
};

class AxesNodeCallback : public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
 {
osg::ref_ptr<OsgAxes> axes =
dynamic_cast<OsgAxes*> (node);
 if(axes)
{
axes->updateCurrentRotation();
 }
traverse(node, nv);
}
};

OsgAxes::OsgAxes(const osgGA::TrackballManipulator &trackball)
: m_trackball(trackball)
{
osg::Camera *camera = new osg::Camera;
 //camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1280, 0, 1024));
camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1280, 0, 1024));
 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
 camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::POST_RENDER);
 camera->setAllowEventFocus(false);

osg::Geode* geode = new osg::Geode();

// turn lighting off for the text and disable depth test to ensure it's
always ontop.
osg::StateSet* stateset = geode->getOrCreateStateSet();
 stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

geode->addDrawable(createAxes());

m_rotation = new osg::MatrixTransform();
m_rotation->setMatrix(osg::Matrix::identity());
 m_rotation->addChild(geode);

osg::MatrixTransform *scale = new osg::MatrixTransform();
 scale->setMatrix(osg::Matrix::scale(osg::Vec3(100.0f, 100.0f, 100.0f)));
scale->addChild(m_rotation.get());

osg::MatrixTransform *translate = new osg::MatrixTransform();
translate->setMatrix(osg::Matrix::translate(osg::Vec3(100.0f, 100.0f,
0.0f)));
 translate->addChild(scale);

camera->addChild(translate);
 addChild(camera);

setUpdateCallback(new AxesNodeCallback);
}

OsgAxes::~OsgAxes()
{

}

osg::Geometry * OsgAxes::createAxes()
{
osg::Geometry* geom = new osg::Geometry;

osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
 vertices->push_back(osg::Vec3(0.5f, 0.0f, 0.0f));
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
 vertices->push_back(osg::Vec3(0.0f, 0.5f, 0.0f));
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
 vertices->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
geom->setVertexArray(vertices);

osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
 geom->setNormalArray(normals);
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f,0.0,0.0f,1.0f));
 colors->push_back(osg::Vec4(0.0f,1.0,0.0f,1.0f));
colors->push_back(osg::Vec4(0.0f,0.0,1.0f,1.0f));
 geom->setColorArray(colors);
geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);

geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,6));

osg::StateSet* stateset = geom->getOrCreateStateSet();
 osg::LineWidth *lw = new osg::LineWidth(2.0f);
stateset->setAttribute(lw);

return geom;
}

void OsgAxes::updateCurrentRotation()
{
osg::Matrix mat(m_trackball.getRotation().inverse());
 m_rotation->setMatrix(mat);
}


---------------------------------------
End Code
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to