Get texture name of collision triangle

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Get texture name of collision triangle

Post by smso »

The following are convenience functions I used in dealing with collision in irrlicht. Hope these are useful to you too.

Usage:

Put drawWayPoint() in the render loop:

Code: Select all

drawWayPoint(device, 0xFFFF0000);
Show texture name in console if needed:

Code: Select all

showWayPointTextureName(device);

Code: Select all

void drawWayPoint
(
        IrrlichtDevice* device,
        video::SColor color
)
{
        if (!device)
                return;
        
        
        scene::ISceneCollisionManager* cmgr = device->getSceneManager()->getSceneCollisionManager();
        scene::ICameraSceneNode* camera = device->getSceneManager()->getActiveCamera();
        camera->updateAbsolutePosition();
        
        
        core::line3df ray;
        ray.start = camera->getAbsolutePosition();
        ray.end = ray.start + (camera->getTarget() - ray.start).normalize()*1000.0f;
 
        core::vector3df intersection;
        core::triangle3df tri;
        const scene::ISceneNode* selectedNode = 0;
        
        
        selectedNode = cmgr->getSceneNodeAndCollisionPointFromRay(ray, intersection, tri);
        if (selectedNode)
                drawWayPoint(device, intersection, tri, color);
}
 
 
void drawWayPoint
(
        IrrlichtDevice* device,
        const core::vector3df& intersection,
        const core::triangle3df& tri,
        video::SColor color
)
{
        if (!device)
                return;
        
        video::IVideoDriver* driver = device->getVideoDriver();
        if (!driver)
                return;
        
        // set mat:
        video::SMaterial lineMaterial;
        lineMaterial.Lighting = false;
        lineMaterial.Thickness = 2.0f;
        lineMaterial.FrontfaceCulling = false;
        lineMaterial.BackfaceCulling = false;
        lineMaterial.MaterialType = video::EMT_SOLID;
        //lineMaterial.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
        driver->setMaterial(lineMaterial);
        driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
        
        
        
        core::vector3df yaxis(0.0f, 1.0f, 0.0f);
        core::vector3df normal = tri.getNormal().normalize();
        core::matrix4 matrix;
        matrix.buildRotateFromTo(yaxis, normal);
 
        core::vector3df pos = intersection + normal*0.001f;
 
        driver->draw3DLine(tri.pointA+normal*0.001f, tri.pointB+normal*0.001f, color);
        driver->draw3DLine(tri.pointB+normal*0.001f, tri.pointC+normal*0.001f, color);
        driver->draw3DLine(tri.pointC+normal*0.001f, tri.pointA+normal*0.001f, color);
        
        // draw hit point with a cross:
        core::vector3df vect(0.0f, 0.0f, 1.0f);
        matrix.rotateVect(vect);
        vect.setLength(1.0f);
        core::vector3df p1 = vect + pos;
        
        core::quaternion quat;
        quat.fromAngleAxis(90.0f * core::DEGTORAD, normal);
        core::matrix4 mat = quat.getMatrix();
        mat.rotateVect(vect);
        core::vector3df p3 = vect + pos;
        
        mat.rotateVect(vect);
        core::vector3df p2 = vect + pos;
 
        mat.rotateVect(vect);
        core::vector3df p4 = vect + pos;
 
        driver->draw3DLine(p1, p2, color);
        driver->draw3DLine(p3, p4, color);
        
}

Code: Select all

void showWayPointTextureName
(
        IrrlichtDevice* device
)
{
        scene::ISceneCollisionManager* cmgr = device->getSceneManager()->getSceneCollisionManager();
        scene::ICameraSceneNode* camera = device->getSceneManager()->getActiveCamera();
        camera->updateAbsolutePosition();
        
        
        core::line3df ray;
        ray.start = camera->getAbsolutePosition();
        ray.end = ray.start + (camera->getTarget() - ray.start).normalize()*1000.0f;
        
        core::vector3df point;
        core::triangle3df tri;
        
        scene::ISceneNode* selectedNode = 0;
        selectedNode = cmgr->getSceneNodeAndCollisionPointFromRay(ray, point, tri);
        
        if (!selectedNode)
                return;
        
        std::string texname;
        if (getNodeTriangleTextureName(selectedNode, tri, texname))
                printf("texname=%s\n", texname.c_str());
}
 
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("Util::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);
 
                printf("ptA: "); Util::print(ptA);
                printf("p0: "); Util::print(p0);
        }
        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 (pos.equals(p0) || pos.equals(p1) || pos.equals(p2))
                                //printf("vertice found!\n");
                        
                        if ((!p0Found) && (pos.equals(p0)))
                        //if (pos.equals(p0))
                        {
                                p0Found = true;
                        }
                        
                        if ((!p1Found) && (pos.equals(p1)))
                        //if (pos.equals(p1))
                        {
                                p1Found = true;
                        }
                        
                        if ((!p2Found) && (pos.equals(p2)))
                        //if (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;
}
Post Reply