From e4e95a1d6069030bb3cc68804866001afbe5d2a2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 12 Jan 2006 22:43:36 +0000 Subject: [PATCH] Added support for tracking mouse movement and computing the intersection of the mouse position into texture coords. --- examples/osgmovie/osgmovie.cpp | 101 ++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 7 deletions(-) diff --git a/examples/osgmovie/osgmovie.cpp b/examples/osgmovie/osgmovie.cpp index f603422bb..ad81b731e 100644 --- a/examples/osgmovie/osgmovie.cpp +++ b/examples/osgmovie/osgmovie.cpp @@ -13,8 +13,10 @@ #include #include #include +#include #include +#include 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(&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(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(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 "<setEventCallback(meh); meh->set(geode.get()); // report any errors if they have occured when parsing the program aguments.