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