Hi Mike
Hi,

I am wanting to do a dust cloud when an entity (helicopter) lands on a terrain. Ideally, 
would like the color of the dust cloud to be similar to the material/texture that the 
entity is on. Is there a way to do a "material/texture color" query based on an 
entity position, kind of like an LOS intersector test?
Thank you!

You can use the osgUtil::LineSegmentIntersector to retrieve intersections.
The result will contain the information on the primitives hit, so you can get the stateset containing the material properties from there. As for the textures: you can also retrieve the texel you hit.
I've attached some code-snippet out of some test-application of mine.

<snip>

if (!mExternalPickPositionHandler.empty() && computeIntersections(view, ea, intersections) )
    {
        osg::Vec3d pos = (intersections.begin())->getWorldIntersectPoint();
osg::Vec3d normal = (intersections.begin())->getWorldIntersectNormal();
#ifdef TEST_TEXELS
    // use the nearest intersection
const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin());
        osg::Drawable* drawable = intersection.drawable.get();
        osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0;
osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
        if (vertices)
        {
            // get the vertex indices.
const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList; const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList;

            if (indices.size()==3 && ratios.size()==3)
            {
                unsigned int i1 = indices[0];
                unsigned int i2 = indices[1];
                unsigned int i3 = indices[2];

                float r1 = ratios[0];
                float r2 = ratios[1];
                float r3 = ratios[2];

osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0; osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
                if (texcoords_Vec2Array)
                {
                    osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
                    osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
                    osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
                    osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3;
//normalize, since negative tex-coords are not handled by osg::Image::set/getImage
                    float int_part;
if (tc[0] < 0) { tc[0] = 1.0 - modf(tc[0], &int_part); } if (tc[1] < 0) { tc[1] = 1.0 - modf(tc[1], &int_part); }

osg::Texture* texture = intersection.getTextureLookUp(osg::Vec3(tc,0));
                    osg::Image* image = nullptr;

                    if (texture && (image = texture->getImage(0)))
                    {
                        osg::Vec4 color = image->getColor(osg::Vec3(tc,0));
std::cout << SCRed() << "HIT texture: " << image->getFileName() << " at " << color << std::endl; image->setColor(osg::Vec4(color) * 0.9,osg::Vec3(tc,0));
                        image->dirty();
texture->setDataVariance(osg::Object::DYNAMIC);
                    }
                }
            }
        }
</snip>

Cheers,
Mike

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=64857#64857





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to