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

Reply via email to