Hi All, I'm attaching the updated code where you can see the problem: even if I call dirty() for primitive sets and dirtyBounds() on the related geometry, the graphics is not updated.
Cheers, Gianni ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68671#68671
#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), currentPrimitiveIndex(0) {} 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::RIGHT_MOUSE_BUTTON) { _selector->setVertexArray( new osg::Vec3Array(3) ); } 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) { currentPrimitiveIndex = 0; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2) { currentPrimitiveIndex = 1; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3) { currentPrimitiveIndex = 2; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4) { currentPrimitiveIndex = 3; } 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::Geode* geode = dynamic_cast<osg::Geode*>(result.nodePath[result.nodePath.size()-1]); unsigned int primitiveIndex = getPrimitiveIndex(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), result.primitiveIndex); unsigned int indexInsidePrimitive = getIndexInsidePrimitive(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), result.primitiveIndex); std::cout << "primitiveIndex = " << result.primitiveIndex << std::endl; std::cout << primitiveIndex << " - " << indexInsidePrimitive << std::endl; move(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), primitiveIndex, indexInsidePrimitive, currentPrimitiveIndex); 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(); } unsigned int getPrimitiveIndex(osg::Geometry* geometry, unsigned int globalIndex) { unsigned int numPrimitives = geometry->getNumPrimitiveSets(); unsigned int currentPrimitive = numPrimitives; unsigned int globalCount = 0; for (int i=0; i<numPrimitives; ++i) { osg::PrimitiveSet* primitiveSet = geometry->getPrimitiveSet(i); unsigned int count = primitiveSet->getNumPrimitives(); if (globalCount <= globalIndex && globalIndex < globalCount+count) { currentPrimitive = i; break; } else { globalCount += count; } } return currentPrimitive; } unsigned int getIndexInsidePrimitive(osg::Geometry* geometry, unsigned int globalIndex) { unsigned int numPrimitives = geometry->getNumPrimitiveSets(); unsigned int index = 0; unsigned int globalCount = 0; for (int i=0; i<numPrimitives; ++i) { osg::PrimitiveSet* primitiveSet = geometry->getPrimitiveSet(i); unsigned int count = primitiveSet->getNumPrimitives(); if (globalCount <= globalIndex && globalIndex < globalCount+count) { index = globalIndex - globalCount; break; } else { globalCount += count; } } return index; } void move(osg::Geometry* geometry, unsigned int sourcePrimitiveSetIndex, unsigned int elementIndex, unsigned int destinationPrimitiveIndex) { osg::DrawElementsUInt* sourcePrimitiveSet = dynamic_cast<osg::DrawElementsUInt*>(geometry->getPrimitiveSet(sourcePrimitiveSetIndex)); osg::DrawElementsUInt* destinationPrimitiveSet = dynamic_cast<osg::DrawElementsUInt*>(geometry->getPrimitiveSet(destinationPrimitiveIndex)); destinationPrimitiveSet->push_back(sourcePrimitiveSet->at(elementIndex*3)); destinationPrimitiveSet->push_back(sourcePrimitiveSet->at(elementIndex*3+1)); destinationPrimitiveSet->push_back(sourcePrimitiveSet->at(elementIndex*3+2)); sourcePrimitiveSet->erase(sourcePrimitiveSet->begin()+elementIndex*3); sourcePrimitiveSet->erase(sourcePrimitiveSet->begin()+elementIndex*3); sourcePrimitiveSet->erase(sourcePrimitiveSet->begin()+elementIndex*3); sourcePrimitiveSet->dirty(); destinationPrimitiveSet->dirty(); geometry->dirtyBound(); } protected: osg::ref_ptr<osg::Geometry> _selector; unsigned int currentPrimitiveIndex; }; 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; } osg::Geometry* buildGeometry() { osg::Geometry* geometry = new osg::Geometry; geometry->setDataVariance(osg::Object::DYNAMIC); geometry->setVertexArray(buildVertices()); geometry->setColorArray(buildColors(), osg::Array::BIND_PER_PRIMITIVE_SET); geometry->addPrimitiveSet(buildElement1()); geometry->addPrimitiveSet(buildElement2()); geometry->addPrimitiveSet(buildElement3()); geometry->addPrimitiveSet(buildElement4()); 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