Irrlicht SceneNodes Collection 2012

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
ikam
Posts: 46
Joined: Sun Jun 24, 2007 4:46 pm
Location: France

Re: Irrlicht SceneNodes Collection 2012

Post by ikam »

really nice collection, thanks.

to complete : an icosphere :

Image

this code adapted for irrlicht come from : http://www.ogre3d.org/tikiwiki/Ogre+Pro ... ry+Library (MIT licence)

Code: Select all

 
//-----------------------------------------------------------------------------------------------------------------
// make IcoSphere
//-----------------------------------------------------------------------------------------------------------------
scene::IMesh* createIcoSphere(f32 mRadius, s32 mNumIterations) const
{
    std::vector<core::vector3df> vertices;
    int offset = 0;
 
    /// Step 1 : Generate icosahedron
    f32 phi = .5f*(1.f+sqrt(5.f));
    f32 invnorm = 1/sqrt(phi*phi+1);
 
    vertices.push_back(invnorm*core::vector3df(-1,  phi, 0));   //0
    vertices.push_back(invnorm*core::vector3df( 1,  phi, 0));   //1
    vertices.push_back(invnorm*core::vector3df(0,   1,  -phi)); //2
    vertices.push_back(invnorm*core::vector3df(0,   1,   phi)); //3
    vertices.push_back(invnorm*core::vector3df(-phi,0,  -1));   //4
    vertices.push_back(invnorm*core::vector3df(-phi,0,   1));   //5
    vertices.push_back(invnorm*core::vector3df( phi,0,  -1));   //6
    vertices.push_back(invnorm*core::vector3df( phi,0,   1));   //7
    vertices.push_back(invnorm*core::vector3df(0,   -1, -phi)); //8
    vertices.push_back(invnorm*core::vector3df(0,   -1,  phi)); //9
    vertices.push_back(invnorm*core::vector3df(-1,  -phi,0));   //10
    vertices.push_back(invnorm*core::vector3df( 1,  -phi,0));   //11
 
    int firstFaces[] = {0,1,2,
                        0,3,1,
                        0,4,5,
                        1,7,6,
                        1,6,2,
                        1,3,7,
                        0,2,4,
                        0,5,3,
                        2,6,8,
                        2,8,4,
                        3,5,9,
                        3,9,7,
                        11,6,7,
                        10,5,4,
                        10,4,8,
                        10,9,5,
                        11,8,6,
                        11,7,9,
                        10,8,11,
                        10,11,9
                       };
 
    std::vector<int> faces(firstFaces, firstFaces + sizeof(firstFaces)/sizeof(*firstFaces));
    int size = 60;
 
    /// Step 2 : tessellate
    for (unsigned short iteration = 0; iteration<mNumIterations; iteration++)
    {
        size*=4;
        std::vector<int> newFaces;
        newFaces.clear();
        //newFaces.resize(size);
        for (int i=0; i<size/12; i++)
        {
            int i1 = faces[i*3];
            int i2 = faces[i*3+1];
            int i3 = faces[i*3+2];
            int i12 = vertices.size();
            int i23 = i12+1;
            int i13 = i12+2;
            core::vector3df v1 = vertices[i1];
            core::vector3df v2 = vertices[i2];
            core::vector3df v3 = vertices[i3];
            //make 1 vertice at the center of each edge and project it onto the sphere
            vertices.push_back((v1+v2).normalize());
            vertices.push_back((v2+v3).normalize());
            vertices.push_back((v1+v3).normalize());
            //now recreate indices
            newFaces.push_back(i1);
            newFaces.push_back(i12);
            newFaces.push_back(i13);
            newFaces.push_back(i2);
            newFaces.push_back(i23);
            newFaces.push_back(i12);
            newFaces.push_back(i3);
            newFaces.push_back(i13);
            newFaces.push_back(i23);
            newFaces.push_back(i12);
            newFaces.push_back(i23);
            newFaces.push_back(i13);
        }
        faces.swap(newFaces);
    }
 
    /// Step 3 : generate texcoords
    std::vector<core::vector2df> texCoords;
    for (unsigned short i=0;i<vertices.size();i++)
    {
        const core::vector3df& vec = vertices[i];
        f32 u, v;
        f32 r0 = sqrtf(vec.X*vec.X+vec.Z*vec.Z);
        f32 alpha;
        alpha = atan2f(vec.Z,vec.X);
        u = alpha/core::PI+.5f;
        v = atan2f(vec.Y, r0)/core::PI + .5f;
        texCoords.push_back(core::vector2df(u,v));
    }
 
    /// Step 4 : fix texcoords
    // find vertices to split
    std::vector<int> indexToSplit;
 
    for (unsigned int i=0;i<faces.size()/3;i++)
    {
        core::vector2df& t0 = texCoords[faces[i*3+0]];
        core::vector2df& t1 = texCoords[faces[i*3+1]];
        core::vector2df& t2 = texCoords[faces[i*3+2]];
        if (abs(t2.X-t0.X)>0.5)
        {
            if (t0.X<0.5)
                indexToSplit.push_back(faces[i*3]);
            else
                indexToSplit.push_back(faces[i*3+2]);
        }
        if (abs(t1.X-t0.X)>0.5)
        {
            if (t0.X<0.5)
                indexToSplit.push_back(faces[i*3]);
            else
                indexToSplit.push_back(faces[i*3+1]);
        }
        if (abs(t2.X-t1.X)>0.5)
        {
            if (t1.X<0.5)
                indexToSplit.push_back(faces[i*3+1]);
            else
                indexToSplit.push_back(faces[i*3+2]);
        }
    }
 
    //split vertices
    for (unsigned short i=0;i<indexToSplit.size();i++)
    {
        int index = indexToSplit[i];
        //duplicate vertex
        core::vector3df v = vertices[index];
        core::vector2df t = texCoords[index] + core::vector2df(1,0);
        vertices.push_back(v);
        texCoords.push_back(t);
        int newIndex = vertices.size()-1;
        //reassign indices
        for (unsigned short j=0;j<faces.size();j++)
        {
            if (faces[j]==index)
            {
                int index1 = faces[(j+1)%3+(j/3)*3];
                int index2 = faces[(j+2)%3+(j/3)*3];
                if ((texCoords[index1].X>0.5) || (texCoords[index2].X>0.5))
                {
                    faces[j] = newIndex;
                }
            }
        }
    }
 
    /// Step 5 : realize
 
    SMeshBuffer* buffer = new SMeshBuffer();
    video::S3DVertex vtx;
    vtx.Color.set(255,255,255,255);  
 
    for (unsigned short i=0; i<vertices.size(); i++)
    {
        vtx.Pos.set( mRadius*vertices[i] );
        vtx.Normal.set( vertices[i] );
        vtx.TCoords.set( texCoords[i].X, texCoords[i].X);
        buffer->Vertices.push_back(vtx);
    }
    for (unsigned short i=0; i<size; i++)
    {
        buffer->Indices.push_back(offset+faces[i]);
    }
    offset+=vertices.size();
 
 
    buffer->Material.BackfaceCulling = true;
    buffer->Material.Wireframe = true;
 
    buffer->recalculateBoundingBox();
    buffer->setHardwareMappingHint(EHM_STATIC);
 
    SMesh* mesh = new SMesh();
    mesh->addMeshBuffer(buffer);
    mesh->recalculateBoundingBox();
    buffer->drop();
    return mesh;
}
 
Post Reply