Hi,

I finally found another post that gets pretty close to what I wanted, but did 
not work right out of the box (see 
http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2009-January/021653.html).
  I wrote the following function starting from the above post's code and it 
seems to work well, at least for my few test models.
 

Code:

float GetAlphaAtTexCoords(const osgUtil::LineSegmentIntersector::Intersection 
*hit)
{
    osg::Vec2 tc(0.0f,0.0f);
    float alpha = -1.0f;

    osg::Drawable* drawable = hit->drawable.get();
    osg::Geometry* geometry = drawable ? drawable->asGeometry() : NULL;
    osg::Vec3Array* vertices = geometry ? 
dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : NULL;
    if (vertices)
    {
        // get the vertex indices.
        const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices 
= hit->indexList;
        const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios 
= hit->ratioList;

        if (3 == ratios.size() && 3 == indices.size())
        {
            osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? 
geometry->getTexCoordArray(0) : NULL;
            osg::Vec2Array* texcoords_Vec2Array = 
dynamic_cast<osg::Vec2Array*>(texcoords);
            if (texcoords_Vec2Array)
            {
                osg::Vec2 tc0 = (*texcoords_Vec2Array)[indices[0]];
                osg::Vec2 tc1 = (*texcoords_Vec2Array)[indices[1]];
                osg::Vec2 tc2 = (*texcoords_Vec2Array)[indices[2]];
                tc = tc0 * ratios[0] + tc1 * ratios[1] + tc2 * ratios[2];
            }
            else
                return alpha;
        }
        else
            return alpha;
    }
    else
        return alpha;

    osg::TexMat* activeTexMat = NULL;
    osg::Texture2D* activeTexture = NULL;
    osg::Image* activeImage = NULL;

    if (geometry->getStateSet())
    {
        osg::TexMat* texMat = 
dynamic_cast<osg::TexMat*>(geometry->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXMAT));
        if (texMat) 
            activeTexMat = texMat;

        osg::Texture2D* texture = 
dynamic_cast<osg::Texture2D*>(geometry->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
        if (texture) 
            activeTexture = texture;
        else
            return alpha;
        activeImage = activeTexture->getImage();
    }
    else if (drawable->getNumParents() > 0)
    {
        // XXX - assumes texture info is at most one level up
        for (unsigned int i = 0; i < drawable->getNumParents(); ++i)
        {
            // reset all ptrs just in case
            activeTexMat = NULL;
            activeTexture = NULL;
            activeImage = NULL;
            // get the current parent ptr
            osg::Node *p = drawable->getParent(i);
            if (p->getStateSet())
            {
                osg::TexMat* texMat = 
dynamic_cast<osg::TexMat*>(p->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXMAT));
                if (texMat) 
                    activeTexMat = texMat;

                osg::Texture2D* texture = 
dynamic_cast<osg::Texture2D*>(p->getStateSet()->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
                if (texture) 
                    activeTexture = texture;
                else
                    continue;
                activeImage = activeTexture->getImage();
                if (activeImage)
                    break;// bail from the for loop
            }
        }
    }

    if (activeTexMat)
    {
        osg::Vec4 tc_transformed = osg::Vec4(tc.x(),tc.y(),0.0f,0.0f) * 
activeTexMat->getMatrix();
        tc.x() = tc_transformed.x();
        tc.y() = tc_transformed.y();
    }

    if (activeImage)
    {
        // handle s wrapping
        switch (activeTexture->getWrap(osg::Texture::WRAP_S))
        {
        case osg::Texture::CLAMP:
        case osg::Texture::CLAMP_TO_BORDER:
        case osg::Texture::CLAMP_TO_EDGE:
            if (tc.x() < 0.0f)
                tc.x() = 0.0f;
            if (tc.x() > 1.0f)
                tc.x() = 1.0f;
            break;
        case osg::Texture::MIRROR:
            tc.x() = tc.x() - floor(tc.x());
            if ((int)(floor(tc.x())) % 2)
                tc.x() = 1.0f - tc.x();
            break;
        case osg::Texture::REPEAT:
            tc.x() = tc.x() - floor(tc.x());
            break;
        }
        // handle t wrapping
        switch (activeTexture->getWrap(osg::Texture::WRAP_T))
        {
        case osg::Texture::CLAMP:
        case osg::Texture::CLAMP_TO_BORDER:
        case osg::Texture::CLAMP_TO_EDGE:
            if (tc.y() < 0.0f)
                tc.y() = 0.0f;
            if (tc.y() > 1.0f)
                tc.y() = 1.0f;
            break;
        case osg::Texture::MIRROR:
            tc.y() = tc.y() - floor(tc.y());
            if ((int)(floor(tc.y())) % 2)
                tc.y() = 1.0f - tc.y();
            break;
        case osg::Texture::REPEAT:
            tc.y() = tc.y() - floor(tc.y());
            break;
        }
        osg::Vec4 rgba = activeImage->getColor(tc);
        alpha = rgba.a();
    }
    return alpha;
}




Any comments on this function would be greatly appreciated.  Thanks again for 
your replies.

On a side note, during my testing I found that the indices vector (indices = 
hit->indexList in the above code) from the 
osgUtil::My_LineSegmentIntersector::Intersection class was corrupted.  To be 
more specific, the values in the vector's internal array were correct, but the 
vector's internal members that keep track of its beginning, end, etc were 
incorrect.  This resulted in access violations and even failure when attempting 
to clear the vector as well as incorrect reporting of its size.  At first I 
thought a leak was causing this, but found no corruption in the surrounding 
memory and found that regardless of the order to the struct Intersection 
members the index vector was the only member affected.  Also, interestingly the 
problem disappears if I switch the vector from unsigned int to signed int.  My 
guess is that this problem is caused by code that is improperly accessing the 
vector memory via a raw pointer instead of the vector's normal interface.  None 
of my code does th
 is, so I am left assuming that code somewhere in osg is doing this.  In any 
case, I have not yet found the cause.  If anyone has any insight, I would 
greatly appreciate it.

Thank you!

Cheers,
Matthew

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





_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to