Hi Nick, the triangle shown in white has just being added to highlight the selection. We can discard it for a while. For that reason I completly removed the selection highlight in my example. Please see attached code. If you run the example and select a triangle pushing CTRL+LEFTMOUSE you will see a couple of messages on the console, something like:
"moving from primitive 1 to 0 ... BUT why triangle does not change color?" That's the point! In my example I have 4 primitive sets: index 0 = red index 1 = green index 2 = blue index 3 = pink Picking a green triangle it is moved from the original primitive set (1 i.e. green) to the primitive set with index = 0 (i.e. red). But why the triangle moved from green to red is still green? I would expect it to be red. Regards, Gianni ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=68692#68692
#include "stdafx.h" #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), currentPrimitiveSetIndex(0) {} 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) { currentPrimitiveSetIndex = 0; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2) { currentPrimitiveSetIndex = 1; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3) { currentPrimitiveSetIndex = 2; } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4) { currentPrimitiveSetIndex = 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::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); if (primitiveIndex != currentPrimitiveSetIndex) { std::cout << "moving from primitive " << primitiveIndex << " to " << currentPrimitiveSetIndex << std::endl; move(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), primitiveIndex, indexInsidePrimitive, currentPrimitiveSetIndex); std::cout << "... BUT why triangle does not change color?" << std::endl; } else { std::cout << "nothing to move" << std::endl; } } 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 destinationPrimitiveSetIndex) { osg::DrawElementsUInt* sourcePrimitiveSet = dynamic_cast<osg::DrawElementsUInt*>(geometry->getPrimitiveSet(sourcePrimitiveSetIndex)); osg::DrawElementsUInt* destinationPrimitiveSet = dynamic_cast<osg::DrawElementsUInt*>(geometry->getPrimitiveSet(destinationPrimitiveSetIndex)); 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 currentPrimitiveSetIndex; }; 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; 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