Dear OSG community,
I try to manage with the model of an aircraft. I whish my 3d model to react to
the mouse cursor when one of its sub-models is intersected by this cursor.
This is the simplified architecture of the OSG file :
*SceneRoot (MatrixTransform) : 1 children
***ExteriorCab (Group) : 4 children
*****ExteriorCab-OFFSET (Group) : 1 children
*******ExteriorCab-GEODE (Geode) : 8 drawables
*****Tail (group) : 3 children
*******Tail-OFFSET (Group) : 1 children
*********Tail-GEODE (Geode) : 3 drawables
*******RearRotor (Group) : 1 children
*********RearRotor-GEODE (Geode) : 2 drawables
*******Cylinder (Group) : 1 children
*********Cylinder-OFFSET (Group) : 1 children
***********Cylinder_GEODE (Geode) : 1 drawable
*****RightWheel (Group) : 2 children
*******RightWheel-OFFSET (Group) : 1 children
*********RightWheel-GEODE (Geode) : 1 drawable
*******RightWheelCylinder (Group) : 1 children
*********RightWheelCylinder-GEODE (Geode) : 1 drawable
*****LeftWheel (Group) : 2 children
*******LeftWheel-OFFSET (Group) : 1 children
*********LeftWheel-GEODE (Geode) : 1 drawable
*******LeftWheelCylinder (Group) : 1 children
*********LeftWheelCylinder-GEODE (Geode) : 1 drawable
(very simplified aircraft !)
the model comes from a file, i can't change it
What I do :
osg::ref_ptr<osg::Group> mRoot;
osg::ref_ptr<osg::Node> mModel;
mModel = osgDB::readNodeFile(m_ModelName);
mRoot->addChild(mModel.get());
osg::Group *groupSceneRoot;
osg::Group *ExteriorCab;
osg::Group *ExteriorCab_OFFSET;
osg::Group *Tail;
osg::Group *RightWheel;
osg::Group *LeftWheel;
osg::Geode *ExteriorCab_GEODE;
osg::Group *Tail_OFFSET;
osg::Group *RearRotor;
osg::Group *Cylinder;
osg::Group *Cylinder_OFFSET;
osg::Geode *Tail_GEODE;
osg::Geode *RearRotor_GEODE;
osg::Geode *Cylinder_GEODE;
osg::Group *RightWheel_OFFSET;
osg::Group *RightWheelCylinder;
osg::Geode *RightWheel_GEODE;
osg::Geode *RightWheelCylinder_GEODE;
osg::Group *LeftWheel_OFFSET;
osg::Group *LeftWheelCylinder;
osg::Geode *LeftWheel_GEODE;
osg::Geode *LeftWheelCylinder_GEODE;
groupSceneRoot = mModel->asGroup();
ExteriorCab = groupSceneRoot->getChild(0)->asGroup();
ExteriorCab_OFFSET = ExteriorCab->getChild(0)->asGroup();
Tail = ExteriorCab->getChild(1)->asGroup();
RightWheel = ExteriorCab->getChild(2)->asGroup();
LeftWheel = ExteriorCab->getChild(3)->asGroup();
ExteriorCab_GEODE = ExteriorCab_OFFSET->getChild(0)->asGeode();
Tail_OFFSET = Tail->getChild(0)->asGroup();
RearRotor = Tail->getChild(1)->asGroup();
Cylinder = Tail->getChild(2)->asGroup();
Cylinder_OFFSET = Cylinder->getChild(0)->asGroup();
Tail_GEODE = Tail_OFFSET->getChild(0)->asGeode();
RearRotor_GEODE = RearRotor->getChild(0)->asGeode();
Cylinder_GEODE = Cylinder_OFFSET->getChild(0)->asGeode();
RightWheel_OFFSET = RightWheel->getChild(0)->asGroup();
RightWheelCylinder = RightWheel->getChild(1)->asGroup();
RightWheel_GEODE = RightWheel_OFFSET->getChild(0)->asGeode();
RightWheelCylinder_GEODE = RightWheelCylinder ->getChild(0)->asGeode();
LeftWheel_OFFSET = LeftWheel->getChild(0)->asGroup();
LeftWheelCylinder = LeftWheel->getChild(1)->asGroup();
LeftWheel_GEODE = LeftWheel_OFFSET->getChild(0)->asGeode();
LeftWheelCylinder_GEODE = LeftWheelCylinder ->getChild(0)->asGeode();
// I have thus access to all geodes ()
// Now i create an array of stateset, and an array of geodes
osg::StateSet *ListGeodeStateSet[8];
osg::Geode *ListGeode[8];
ListGeode[0] = ExteriorCab_GEODE;
ListGeode[1] = Tail_GEODE;
ListGeode[2] = RearRotor_GEODE;
ListGeode[3] = Cylinder_GEODE;
ListGeode[4] = RightWheel_GEODE;
ListGeode[5] = RightWheelCylinder_GEODE;
ListGeode[6] = LeftWheel_GEODE;
ListGeode[7] = LeftWheelCylinder_GEODE;
for (int i=0;i<8;i++)
ListGeodeStateSet[index] = ListGeode[i]->getOrCreateStateSet();
// What I want is to display only polygons if the cursor mouse picks a
sub-model (here, one of the 8 geodes that decompose the whole aircraft):
osg::PolygonMode *PolyModeObj[8];
for (int i=0;i<8;i++)
{
PolyModeObj[i] = dynamic_cast< osg::PolygonMode* >
( ListGeodeStateSet[i]->getAttribute(
osg::StateAttribute::POLYGONMODE ));
if ( !PolyModeObj[i] )
{
PolyModeObj[i] = new osg::PolygonMode;
ListGeodeStateSet[i]->setAttribute( PolyModeObj[i]);
}
}
// In the pick callback, I check which geode was selected by the cursor:
osgUtil::LineSegmentIntersector::Intersections::iterator hitr;
if (Viewer->computeIntersections(x, y, intersections))
{
hitr = intersections.begin();
osg::Geode *GeodeParent = hitr->drawable->getParent(0)->asGeode();
for (int d=0;d<8;d++)
{
if (GeodeParent == ListGeode[d])
{
PolyModeObj[d]->setMode( osg::PolygonMode::FRONT_AND_BACK,
osg::PolygonMode::LINE );
break;
}
}
}
But... when the cursor selects the geode ExteriorCab_GEODE, the whole aircaft
moves to polygon display (even wheels, tail and the rest...). Only the cabin
should appear as polygons.
When the cursor selects a wheel, nothing appears. The setMode(
osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE ); function has no
effect.
ExteriorCab_GEODE has an effect on all the architecture ! Others have not...
I badly initialize the array of StateSet. Unless the problem comes from the
array of PolygonMode. Anyway I don't understand !
I read that former topic:
http://forum.openscenegraph.org/viewtopic.php?t=2814
and that webpage :
http://www.bricoworks.com/articles/stateset/stateset.html
I can't find the answer, and am not experimented enough in StateSet.
Maybe you will find at the first look.
Thanks in advance.
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=30086#30086
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org