Added support for tracking mouse movement and computing the intersection of the mouse position

into texture coords.
This commit is contained in:
Robert Osfield
2006-01-12 22:43:36 +00:00
parent 3235f4fa22
commit e4e95a1d60

View File

@@ -13,8 +13,10 @@
#include <osg/TexMat>
#include <osg/CullFace>
#include <osg/ImageStream>
#include <osg/io_utils>
#include <osgGA/TrackballManipulator>
#include <osgGA/EventVisitor>
osg::ImageStream* s_imageStream = 0;
class PostSwapFinishCallback : public Producer::Camera::Callback
@@ -46,7 +48,7 @@ public:
virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); }
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv);
virtual void getUsage(osg::ApplicationUsage& usage) const;
@@ -125,10 +127,95 @@ void MovieEventHandler::set(osg::Node* node)
}
bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
{
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::MOVE):
case(osgGA::GUIEventAdapter::PUSH):
case(osgGA::GUIEventAdapter::RELEASE):
{
osgProducer::Viewer* viewer = dynamic_cast<osgProducer::Viewer*>(&aa);
osgUtil::IntersectVisitor::HitList hlist;
if (viewer->computeIntersections(ea.getX(),ea.getY(), nv->getNodePath().back(), hlist))
{
if (!hlist.empty())
{
// use the nearest intersection
osgUtil::Hit& hit = hlist.front();
osg::Drawable* drawable = hit.getDrawable();
osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0;
osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
if (vertices)
{
// get the vertex indices.
const osgUtil::Hit::VecIndexList& vil = hit.getVecIndexList();
if (vil.size()==3)
{
int i1 = vil[0];
int i2 = vil[1];
int i3 = vil[2];
osg::Vec3 v1 = (*vertices)[i1];
osg::Vec3 v2 = (*vertices)[i2];
osg::Vec3 v3 = (*vertices)[i3];
osg::Vec3 v = hit.getLocalIntersectPoint();
osg::Vec3 p1 = hit.getLocalLineSegment()->start();
osg::Vec3 p2 = hit.getLocalLineSegment()->end();
osg::Vec3 p12 = p1-p2;
osg::Vec3 v13 = v1-v3;
osg::Vec3 v23 = v2-v3;
osg::Vec3 p1v3 = p1-v3;
osg::Matrix matrix(p12.x(), v13.x(), v23.x(), 0.0,
p12.y(), v13.y(), v23.y(), 0.0,
p12.z(), v13.z(), v23.z(), 0.0,
0.0, 0.0, 0.0, 1.0);
osg::Matrix inverse;
inverse.invert(matrix);
osg::Vec3 ratio = inverse*p1v3;
// extract the baricentric coordinates.
float r1 = ratio.y();
float r2 = ratio.z();
float r3 = 1.0f-r1-r2;
osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0;
osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
if (texcoords_Vec2Array)
{
// we have tex coord array so now we can compute the final tex coord at the point of intersection.
osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3;
osg::notify(osg::NOTICE)<<"We hit tex coords "<<tc<<std::endl;
}
}
else
{
osg::notify(osg::NOTICE)<<"Hit but insufficient indices to work with";
}
}
}
}
else
{
osg::notify(osg::NOTICE)<<"No hit"<<std::endl;
}
break;
}
case(osgGA::GUIEventAdapter::KEYDOWN):
{
if (ea.getKey()=='s')
@@ -190,6 +277,7 @@ bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAction
default:
return false;
}
return false;
}
void MovieEventHandler::getUsage(osg::ApplicationUsage& usage) const
@@ -257,11 +345,6 @@ int main(int argc, char** argv)
// set up the value with sensible default event handlers.
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
// register the handler to add keyboard and mosue handling.
MovieEventHandler* meh = new MovieEventHandler();
viewer.getEventHandlerList().push_front(meh);
// get details on keyboard and mouse bindings used by the viewer.
viewer.getUsage(*arguments.getApplicationUsage());
@@ -343,8 +426,12 @@ int main(int argc, char** argv)
// nothing loaded.
return 1;
}
// pass the model to the MovieEventHandler so it can pick out ImageStream's to manipulate.
MovieEventHandler* meh = new MovieEventHandler();
geode->setEventCallback(meh);
meh->set(geode.get());
// report any errors if they have occured when parsing the program aguments.