Ray collision considering transparent materials

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Donner
Posts: 87
Joined: Fri May 18, 2007 11:27 am

Ray collision considering transparent materials

Post by Donner »

Hi,

for the purpose of creating a lightmap generator, I'm wondering if there is a solution to the following problem:

I'm checking the ray going from the light source to the destination point for collision with other objects using getSceneNodeAndCollisionPointFromRay().

Now some objects have materials that make them partly transparent and thus the light should pass through.

getSceneNodeAndCollisionPointFromRay gives me the collision position as well as the scene node and the colliding triangle, but is there a way to find out (considering the materials of the object), what color (and transparency level) the triangle has at the position of the collision point?

Thanks in advance!
D.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Ray collision considering transparent materials

Post by smso »

This function is used by me in a similar way. See if this helps.

Code: Select all

bool getNodeTriangleTextureName
(
        scene::ISceneNode* node,
        const core::triangle3df& tri,
        std::string& texname
)
{
        scene::IMesh* mesh = 0;
       
        scene::ESCENE_NODE_TYPE type = node->getType();
        if ((type == scene::ESNT_MESH) || (type == scene::ESNT_OCTREE))
        {
                mesh = static_cast<scene::IMeshSceneNode*>(node)->getMesh();
        }
        else if (type == scene::ESNT_ANIMATED_MESH)
        {
                mesh = static_cast<scene::IAnimatedMeshSceneNode*>(node)->getMesh()->getMesh(0);
        }
        else
        {
                return false;
        }
       
        if (!mesh)
                return false;
       
        printf("getNodeTriangleTextureName(): mesh found...\n");
        core::vector3df ptA = tri.pointA;
        core::vector3df ptB = tri.pointB;
        core::vector3df ptC = tri.pointC;
       
        core::matrix4 matrix = node->getAbsoluteTransformation();
        core::matrix4 inverse;
        core::vector3df p0, p1, p2;
 
        if (matrix.getInverse(inverse))
        {
                printf("Inverse matrix of node found\n");
                inverse.transformVect(p0, ptA);
                inverse.transformVect(p1, ptB);
                inverse.transformVect(p2, ptC);
          }
        else { p0 = ptA; p1 = ptB; p2 = ptC; }
 
        printf("mesh->getMeshBufferCount()=%i\n", mesh->getMeshBufferCount());
        for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
        {
                bool p0Found = false;
                bool p1Found = false;
                bool p2Found = false;
               
                //printf("mesh->getMeshBuffer(%i): vertexCount=%i\n", i, mesh->getMeshBuffer(i)->getVertexCount());
               
                scene::IMeshBuffer* buf = mesh->getMeshBuffer(i);
                for (u32 j=0; j<buf->getVertexCount(); ++j)
                {
                        core::vector3df pos = buf->getPosition(j);
                        if ((!p0Found) && (pos.equals(p0)))
                        {
                                p0Found = true;
                        }
                       
                        if ((!p1Found) && (pos.equals(p1)))
                        {
                                p1Found = true;
                        }
                       
                        if ((!p2Found) && (pos.equals(p2)))
                        {
                                p2Found = true;
                        }
                }
               
                if (p0Found && p1Found && p2Found)
                {
                        video::ITexture* tex = buf->getMaterial().getTexture(0);
                        if (!tex)
                                return false;
                       
                        texname = std::string(tex->getName().getPath().c_str());
                        return true;
                }
        }
       
        return false;
}
Regards
smso
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Ray collision considering transparent materials

Post by Mel »

The problem with the half transparent polygons and the collision detection comes from the fact that the triangle data provided from Irrlicht doesn't have texture coordinates or colors, or any extra data from the meshes. And thus you really can't know where has the ray hit the polygon in texture space. If the triangle at least provided the texture coordinates and/or vertex color, it would be posible to calculate the point where the ray hit in the texture, and this way, know where the texture is half transparent, and so on...
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Post Reply