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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org