Added support for tracking mouse movement and computing the intersection of the mouse position
into texture coords.
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user