Hi All, I've attached an example. Hope this helps to have a reply from somebody (Robert?).
Part of that example is from the OSG 3 Cookbook. Suppose I have geometry build of triangles. I would like to understand which is the better way to change the color of a selected triangle. And if there is a preferred way to organize the object geometry to facilitate the color change feature. The user chooses the current color punshing 1,2,3 or 4 key. Then pushing CTRL+LEFTMOUSE on the 3D geometry a triangle is selected. I need to apply the current selected color to the corresponding selected triangle. Should I use the osgUtil::LineSegmentIntersector::Intersection::indexList value to find the corresponding primitive set the selected triangle belongs to? That seems too much of a hack from my point of view. Isn't that possible in OSG using primitive sets then I have to split the object geometry into different pieces? (i.e. one Geode for each color so that I can then use the osgUtil::LineSegmentIntersector::Intersection::nodePath instead?) Thanks for the help. Gianni ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68657#68657
#include "stdafx.h" #include <QTimer> #include <QApplication> #include <QGridLayout> #include <osg/Geometry> #include <osg/Geode> #include <osg/MatrixTransform> #include <osg/PolygonOffset> #include <osgViewer/CompositeViewer> #include <osgViewer/ViewerEventHandlers> #include <osgGA/MultiTouchTrackballManipulator> #include <osgDB/ReadFile> #include <osgQt/GraphicsWindowQt> #include <iostream> const osg::Vec4 selectedColor(1.0f, 1.0f, 1.0f, 0.5f); const osg::Vec4 color1(1.0f, 0.0f, 0.0f, 1.0f); const osg::Vec4 color2(0.0f, 1.0f, 0.0f, 1.0f); const osg::Vec4 color3(0.0f, 0.0f, 1.0f, 1.0f); const osg::Vec4 color4(1.0f, 0.0f, 1.0f, 1.0f); class SelectModelHandler : public osgGA::GUIEventHandler { public: SelectModelHandler() : _selector(0), currentColor(color1) {} osg::Geode* createFaceSelector() { osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1); (*colors)[0] = selectedColor; _selector = new osg::Geometry; _selector->setDataVariance( osg::Object::DYNAMIC ); _selector->setUseDisplayList( false ); _selector->setUseVertexBufferObjects( true ); _selector->setVertexArray( new osg::Vec3Array(3) ); _selector->setColorArray( colors.get() ); _selector->setColorBinding( osg::Geometry::BIND_OVERALL ); _selector->addPrimitiveSet( new osg::DrawArrays(GL_TRIANGLES, 0, 3) ); osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable( _selector.get() ); geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); geode->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON ); geode->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); geode->getOrCreateStateSet()->setAttributeAndModes(new osg::PolygonOffset(-1.0f, -1.0f)); return geode.release(); } virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) { if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON && ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) { osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa); if ( viewer ) { osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY()); osgUtil::IntersectionVisitor iv(intersector.get()); osg::Camera* camera = viewer->getCamera(); camera->accept( iv ); if ( intersector->containsIntersections() ) { osgUtil::LineSegmentIntersector::Intersection result = *(intersector->getIntersections().begin()); doUserOperations( result ); } } } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1) { currentColor = color1; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2) { currentColor = color2; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3) { currentColor = color3; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4) { currentColor = color4; } return false; } virtual void doUserOperations( osgUtil::LineSegmentIntersector::Intersection& result ) { osg::Geometry* geom = dynamic_cast<osg::Geometry*>( result.drawable.get() ); if ( !geom || !_selector || geom==_selector ) return; osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() ); osg::Vec3Array* selVertices = dynamic_cast<osg::Vec3Array*>( _selector->getVertexArray() ); if ( !vertices || !selVertices ) return; osg::Matrix matrix = osg::computeLocalToWorld( result.nodePath ); const std::vector<unsigned int>& selIndices = result.indexList; for ( unsigned int i=0; i<3 && i<selIndices.size(); ++i ) { unsigned int pos = selIndices[i]; (*selVertices)[i] = (*vertices)[pos] * matrix; } selVertices->dirty(); _selector->dirtyBound(); } protected: osg::ref_ptr<osg::Geometry> _selector; osg::Vec4 currentColor; }; osg::Vec3Array* buildVertices() { osg::Vec3Array* vertices = new osg::Vec3Array; vertices->push_back(osg::Vec3(0,0,0)); vertices->push_back(osg::Vec3(10,0,0)); vertices->push_back(osg::Vec3(10,10,0)); vertices->push_back(osg::Vec3(0,10,0)); vertices->push_back(osg::Vec3(20,0,0)); vertices->push_back(osg::Vec3(20,10,0)); vertices->push_back(osg::Vec3(20,20,0)); vertices->push_back(osg::Vec3(10,20,0)); vertices->push_back(osg::Vec3(0,20,0)); return vertices; } osg::DrawElementsUInt* buildElement1() { osg::DrawElementsUInt* element = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); element->push_back(0); element->push_back(1); element->push_back(2); element->push_back(0); element->push_back(2); element->push_back(3); return element; } osg::DrawElementsUInt* buildElement2() { osg::DrawElementsUInt* element = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); element->push_back(1); element->push_back(4); element->push_back(5); element->push_back(1); element->push_back(5); element->push_back(2); return element; } osg::DrawElementsUInt* buildElement3() { osg::DrawElementsUInt* element = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); element->push_back(2); element->push_back(5); element->push_back(6); element->push_back(2); element->push_back(6); element->push_back(7); return element; } osg::DrawElementsUInt* buildElement4() { osg::DrawElementsUInt* element = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); element->push_back(3); element->push_back(2); element->push_back(7); element->push_back(3); element->push_back(7); element->push_back(8); return element; } osg::Vec4Array* buildColors() { osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); colors->push_back(osg::Vec4(1.0f, 0.0f, 1.0f, 1.0f)); return colors; } std::vector<osg::DrawElementsUInt*> buildElements() { std::vector<osg::DrawElementsUInt*> elements; elements.push_back(buildElement1()); elements.push_back(buildElement2()); elements.push_back(buildElement3()); elements.push_back(buildElement4()); return elements; } osg::Geometry* buildGeometry() { osg::Geometry* geometry = new osg::Geometry; geometry->setVertexArray(buildVertices()); geometry->setColorArray(buildColors(), osg::Array::BIND_PER_PRIMITIVE_SET); std::vector<osg::DrawElementsUInt*> elements = buildElements(); for (std::vector<osg::DrawElementsUInt*>::iterator i = elements.begin(); i != elements.end(); ++i) { geometry->addPrimitiveSet(*i); } return geometry; } osg::Node* createScene() { osg::Geode* geode = new osg::Geode; geode->addDrawable(buildGeometry()); return geode; } int main( int argc, char** argv ) { osg::ArgumentParser arguments(&argc, argv); osgViewer::Viewer viewer(arguments); osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(createScene()); osg::ref_ptr<SelectModelHandler> selector = new SelectModelHandler; root->addChild(selector->createFaceSelector()); viewer.setSceneData(root); viewer.addEventHandler(selector.get()); viewer.setCameraManipulator( new osgGA::TrackballManipulator ); // add the window size toggle handler viewer.addEventHandler(new osgViewer::WindowSizeHandler); viewer.run(); }
_______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org