[Solved] Modify mesh

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
malloc
Posts: 13
Joined: Sat Feb 04, 2012 7:25 pm

[Solved] Modify mesh

Post by malloc »

Edit: Thanks so much! :D

Hi

I've been feeling a little bad about posting here so much. I tried to avoid it, but I just can't figure it out. I'm trying to delete the indices and vertices that compose a cube within a mesh that I used Lonesome Ducky's mesh combiner to meld together. From reading the forums here, I learnt that a cube is made of 12 vertices and 36 indices. I managed to erase that from the mesh fine, but not the cube I wanted to remove (the one highlighted by the triangle selector). So I made a few loops and tried to reach the right vertices and indices within the array, but it always seems to erase from the front. smso wrote me some code in another thread to find the right index, and it seemed to work but only for 1 of the indices. Then it stopped working entirely and I couldn't revert it back.

Another strange problem is that inversing hitTriangle's coordinates never seems to change anything. p0 and ptA are always the same.

I made a youtube video of my problem, to hopefully help. Here's my code. It's within the event receiver for a right click.

Code: Select all

case EMIE_RMOUSE_PRESSED_DOWN:
        if(World.mapcreator == 1 || World.running == 1 && selectedSceneNode && Player->iequipped == 0) {
                irr::scene::IMesh *mesh = selectedSceneNode->getMesh();
                irr::scene::CMeshBuffer<S3DVertex> *buffer =
                        (irr::scene::CMeshBuffer<S3DVertex>*)mesh->getMeshBuffer(0);
                                                
                std::cout << buffer->getIndexCount() << std::endl << buffer->getVertexCount() << std::endl;
                                                
                irr::core::vector3df ptA = hitTriangle.pointA;
                irr::core::vector3df ptB = hitTriangle.pointB;
                irr::core::vector3df ptC = hitTriangle.pointC;
                                           
                irr::core::matrix4 matrix = selectedSceneNode->getAbsoluteTransformation();
                irr::core::matrix4 inverse;
                irr::core::vector3df p0, p1, p2, intersectioninverse;
                                 
                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: %.2f %.2f %.2f\n", ptA.X, ptA.Y, ptA.Z); //Util::print(ptA);
                        printf("ptB: %.2f %.2f %.2f\n", ptB.X, ptB.Y, ptB.Z);
                        printf("ptC: %.2f %.2f %.2f\n", ptC.X, ptC.Y, ptC.Z);
                        printf("p0: %.2f %.2f %.2f\n", p0.X, p0.Y, p0.Z); //Util::print(p0);
                        printf("p1: %.2f %.2f %.2f\n", p1.X, p1.Y, p1.Z);
                        printf("p2: %.2f %.2f %.2f\n", p2.X, p2.Y, p2.Z);
                }
                else { puts("not found"); p0 = ptA; p1 = ptB; p2 = ptC; }
                                                
                selectedSceneNode->setDebugDataVisible(irr::scene::EDS_BBOX);
                                                
                int i, q, icount, vcount;
                icount = buffer->getIndexCount();
                vcount = buffer->getVertexCount();
                                                
                printf("Intersection: %.2f %.2f %.2f\np0: %.2f %.2f %.2f\np1: %.2f %.2f %.2f\np2: %.2f %.2f %.2f\n",
                        intersection.X, intersection.Y, intersection.Z, p0.X, p0.Y, p0.Z, p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z);
                                                
                if(p0.equals(intersection)) {
                        puts("pto == intersection");
                }
                                                
                irr::core::vector3df bpos;
                for(i=0, q=0; i<icount; i+=36, q+=12) {
                        bpos = buffer->getPosition(i);
                        //printf("%d: %.2f, %.2f, %.2f\np0: %.2f, %.2f, %.2f\n", i, bpos.X, bpos.Y, bpos.Z, p0.X, p0.Y, p0.Z);
                        if(bpos.X > intersection.X && bpos.X < intersection.X+50) {
                                if(bpos.Z > intersection.Z && bpos.Z < intersection.Z+50) {
                                        puts("here?");
                                        for(int j = 0; j<36; j++)
                                                buffer->Indices.erase(i+j);
                                                //buffer->Indices.erase(i);
                                                for(int j = 0; j<12; j++)
                                                buffer->Vertices.erase(q+j);
                                }
                        }
                                                        
                
                                                        
                }
                                                
                irr::scene::ITriangleSelector *selector = selectedSceneNode->getTriangleSelector();
                selectedSceneNode->setTriangleSelector(0);
                g_selector->removeTriangleSelector(selector);
                                                
                buffer->recalculateBoundingBox();
                                                
                selector = g_smgr->createOctreeTriangleSelector(selectedSceneNode->getMesh(), selectedSceneNode);
                selectedSceneNode->setTriangleSelector(selector);
                g_selector->addTriangleSelector(selector);
                selector->drop();
                                                
                                                
        }
        break;
Thank you. Apologies again.
Last edited by malloc on Wed Mar 07, 2012 4:33 am, edited 1 time in total.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Modify mesh

Post by smso »

I remove the triangles one by one from a cube (created by the scene manager) using the function removeNodeTriangle() below.

I found that for the cube scene node:
mesh->getMeshBuffer(0)->getVertexCount() gives 12 instead of 8, i.e. some of the vertices are repeated.

The function (updated) can now take care of this.

Hope this helps.

Regards from smso


Code: Select all

void print(const core::vector3df& vec);
 
u32 MeshUtil::removeNodeTriangles
(
        scene::ISceneNode* node,
        const core::triangle3df& tri
)
{
        if (!node)
                return 0;
        
        scene::IMesh* mesh = 0;
        
        scene::ESCENE_NODE_TYPE type = node->getType();
        if ((type == scene::ESNT_MESH) || (type == scene::ESNT_OCTREE) || (type == scene::ESNT_CUBE))
        {
                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 0;
        }
        
        if (!mesh)
                return 0;
        
        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: "); print(ptA);
                printf("points to search:\n");
                printf("p0: "); print(p0);
                printf("p1: "); print(p1);
                printf("p2: "); print(p2);
        }
        else
                return 0;
        
        printf("mesh->getMeshBufferCount()=%i\n", mesh->getMeshBufferCount());
        if (mesh->getMeshBufferCount() == 0)
                return 0;
        
        bool p0Found = false;
        bool p1Found = false;
        bool p2Found = false;
                
        //printf("mesh->getMeshBuffer(%i): vertexCount=%i\n", i, mesh->getMeshBuffer(i)->getVertexCount());
        f32 tolerance = 0.001f;
        std::set<u32> indices0Found, indices1Found, indices2Found;
        u32 index0Found, index1Found, index2Found;
        scene::IMeshBuffer* buf = mesh->getMeshBuffer(0);
        for (u32 j=0; j<buf->getVertexCount(); ++j)
        {
                core::vector3df pos = buf->getPosition(j);
                printf("vertex in mesh buffer: "); print(pos);
                        
                //if (pos.equals(p0) || pos.equals(p1) || pos.equals(p2))
                        //printf("vertice found!\n");
                        
                //if ((!p0Found) && (pos.equals(p0, tolerance)))
                if (pos.equals(p0, tolerance))
                {
                        p0Found = true;
                        index0Found = j;
                        indices0Found.insert(index0Found);
                        printf("p0Found: pos=%i\n", j);
                }
                        
                //if ((!p1Found) && (pos.equals(p1, tolerance)))
                if (pos.equals(p1, tolerance))
                {
                        p1Found = true;
                        index1Found = j;
                        indices1Found.insert(index1Found);
                        printf("p1Found: pos=%i\n", j);
                }
                        
                //if ((!p2Found) && (pos.equals(p2, tolerance)))
                if (pos.equals(p2, tolerance))
                {
                        p2Found = true;
                        index2Found = j;
                        indices2Found.insert(index2Found);
                        printf("p2Found: pos=%i\n", j);
                }
        }
 
        u32 tn = ((scene::SMeshBuffer*)buf)->Indices.size()/3; // tn is the number of triangles
        for (u32 t=0; t<tn; ++t)
        {
                u16 i0 = ((scene::SMeshBuffer*)buf)->Indices[t*3];
                u16 i1 = ((scene::SMeshBuffer*)buf)->Indices[t*3+1];
                u16 i2 = ((scene::SMeshBuffer*)buf)->Indices[t*3+2];
                printf("tri(%i) in mesh buffer = (%i, %i, %i)\n", t, i0, i1, i2);
        }
        
        
        if ((!p0Found) || (!p1Found) || (!p2Found))
                return 0;
////////////////////////////////////////////////////////////////////////////////
printf
(
        "indices0Found.size()=%i,indices1Found.size()=%i,indices2Found.size()=%i\n",
        indices0Found.size(), indices1Found.size(), indices2Found.size()
);
 
 
////////////////////////////////////////////////////////////////////////////////        
u32 numberOfTrianglesRemoved = 0;
////////////////////////////////////////////////////////////////////////////////
std::set<u32>::iterator iterator0;
std::set<u32>::iterator iterator1;
std::set<u32>::iterator iterator2;
for (iterator0=indices0Found.begin(); iterator0!=indices0Found.end(); ++iterator0)
{
        index0Found = *iterator0;
for (iterator1=indices1Found.begin(); iterator1!=indices1Found.end(); ++iterator1)
{
        index1Found = *iterator1;
for (iterator2=indices2Found.begin(); iterator2!=indices2Found.end(); ++iterator2)
{
        index2Found = *iterator2;
        printf("triangle found=(%i, %i, %i)\n", index0Found, index1Found, index2Found);
//}}}
 
                ////////////////////////////////////////////////////////////////////////
                /***/
                std::set<u32> indicesFound;
                indicesFound.insert(index0Found);
                indicesFound.insert(index1Found);
                indicesFound.insert(index2Found);
                
                core::array<u16> newIndices;
                
                // search triangle-wise
                u32 triNum = ((scene::SMeshBuffer*)buf)->Indices.size()/3;
                for (u32 tri=0; tri<triNum; ++tri)
                {
                        u32 t0 = tri*3;
                        u32 t1 = tri*3+1;
                        u32 t2 = tri*3+2;
                        
                        u16 index0 = ((scene::SMeshBuffer*)buf)->Indices[t0];
                        u16 index1 = ((scene::SMeshBuffer*)buf)->Indices[t1];
                        u16 index2 = ((scene::SMeshBuffer*)buf)->Indices[t2];
                        
                        if
                        (
                                (indicesFound.find(index0) != indicesFound.end())
                                && (indicesFound.find(index1) != indicesFound.end())
                                && (indicesFound.find(index2) != indicesFound.end())
                        )
                        {
                                ++numberOfTrianglesRemoved;
                                continue;
                        }
                        newIndices.push_back(index0);
                        newIndices.push_back(index1);
                        newIndices.push_back(index2);
                }
                        
                ((scene::SMeshBuffer*)buf)->Indices.clear();
                ((scene::SMeshBuffer*)buf)->Indices = newIndices;
                /***/
                ////////////////////////////////////////////////////////////////////////
}}}
////////////////////////////////////////////////////////////////////////////////
        //return 1;
        return numberOfTrianglesRemoved;
}
 
 
void print(const core::vector3df& vec)
{
        printf("(%.1f,%.1f,%.1f)\n", vec.X, vec.Y, vec.Z);
}
 
 
example of usage:

Code: Select all

else if (event.KeyInput.Key == irr::KEY_F2)
{
        // find collision triangle:
        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()*10000.0f;
 
        core::vector3df intersection;
        core::triangle3df tri;
        const scene::ISceneNode* selectedNode = 0;
        
        selectedNode = cmgr->getSceneNodeAndCollisionPointFromRay(ray, intersection, tri);
        if (!selectedNode)
                return true;                    
        
        // remove it:
        removeNodeTriangle(cube, tri);
        
        // ?
        cube->getMesh()->setDirty(scene::EBT_INDEX);
                                
        // force cube render buffer to reload
        cube->setPosition(cube->getPosition());
        
        // thanks for mallo's code              
        cube->setTriangleSelector(0);
        selector = device->getSceneManager()->createTriangleSelector(cube->getMesh(), cube);
        cube->setTriangleSelector(selector);
        selector->drop();
                        
}
 
Last edited by smso on Tue Mar 06, 2012 1:06 pm, edited 1 time in total.
greenya
Posts: 1012
Joined: Sun Jan 21, 2007 1:46 pm
Location: Ukraine
Contact:

Re: Modify mesh

Post by greenya »

smso wrote:I found that for the cube scene node:
mesh->getMeshBuffer(0)->getVertexCount() gives 12 instead of 8, i.e. some of the vertices are repeated.
As I know this is for proper texturing.
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Re: Modify mesh

Post by serengeor »

greenya wrote:
smso wrote:I found that for the cube scene node:
mesh->getMeshBuffer(0)->getVertexCount() gives 12 instead of 8, i.e. some of the vertices are repeated.
As I know this is for proper texturing.
Probably lighting too (normals)? or is 8 vertices sufficient for good lighting?
Working on game: Marrbles (Currently stopped).
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Modify mesh

Post by smso »

removeNodeTriangles() updated to take care of repeated vertices, see my previous post.

Regards
smso
Post Reply