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

Reply via email to