The mesh is created in code. The idea is to get a sphere where all verts are an equal distance apart from each other, and where larger spheres have more vertices.
Code:
class Icosahedron
{
public:
void Create ( Mesh &mesh, byte Divs = 1 ); // Create the mesh
void SubDiv ( Mesh &mesh, byte Divs = 1 ); // Add subdivisions to the mesh to smooth it out
private: ;
float PHI = ( 1 + Sqrt( 5 ) ) / 2 ; // Define PHI
void SetPoints ( Mesh &mesh ); // Fill the InitialPoints array
void SetTris ( Mesh &mesh ); // Set the vertices each face uses
}
/******************************************************************************/
void Icosahedron.SetPoints( Mesh &mesh )
{
/*
Set up as:
(+-1, +-PHI, 0)
(0, +-1, +-PHI)
(+-PHI, 0, +-1)
*/
mesh.parts[0].base.vtx.pos( 0 ).set( -1, PHI, 0 ); // Set the initial places
mesh.parts[0].base.vtx.pos( 1 ).set( 1, PHI, 0 );
mesh.parts[0].base.vtx.pos( 2 ).set( -1, -PHI, 0 );
mesh.parts[0].base.vtx.pos( 3 ).set( 1, -PHI, 0 );
mesh.parts[0].base.vtx.pos( 4 ).set( 0, -1, PHI );
mesh.parts[0].base.vtx.pos( 5 ).set( 0, 1, PHI );
mesh.parts[0].base.vtx.pos( 6 ).set( 0, -1, -PHI );
mesh.parts[0].base.vtx.pos( 7 ).set( 0, 1, -PHI );
mesh.parts[0].base.vtx.pos( 8 ).set( PHI, 0, -1 );
mesh.parts[0].base.vtx.pos( 9 ).set( PHI, 0, 1 );
mesh.parts[0].base.vtx.pos( 10 ).set( -PHI, 0, -1 );
mesh.parts[0].base.vtx.pos( 11 ).set( -PHI, 0, 1 );
}
/******************************************************************************/
void Icosahedron.SetTris( Mesh &mesh )
{
MeshBase &base = mesh.parts[0].base;
base.tri.ind( 0 ).set( 0, 11, 5 ); // Set the faces. 5 edges per vert
base.tri.ind( 1 ).set( 0, 5, 1 );
base.tri.ind( 2 ).set( 0, 1, 7 );
base.tri.ind( 3 ).set( 0, 7, 10 );
base.tri.ind( 4 ).set( 0, 10, 11 );
base.tri.ind( 5 ).set( 1, 5, 9 );
base.tri.ind( 6 ).set( 5, 11, 4 );
base.tri.ind( 7 ).set( 11, 10, 2 );
base.tri.ind( 8 ).set( 10, 7, 6 );
base.tri.ind( 9 ).set( 7, 1, 8 );
base.tri.ind( 10 ).set( 3, 9, 4 );
base.tri.ind( 11 ).set( 3, 4, 2 );
base.tri.ind( 12 ).set( 3, 2, 6 );
base.tri.ind( 13 ).set( 3, 6, 8 );
base.tri.ind( 14 ).set( 3, 8, 9 );
base.tri.ind( 15 ).set( 4, 9, 5 );
base.tri.ind( 16 ).set( 2, 4, 11 );
base.tri.ind( 17 ).set( 6, 2, 10 );
base.tri.ind( 18 ).set( 8, 6, 7 );
base.tri.ind( 19 ).set( 9, 8, 1 );
base.setNormals( ); // Set automatic vertex normals
}
/******************************************************************************/
void Icosahedron.Create( Mesh &mesh, byte Divs )
{
mesh.parts.New( ).base.create( 12, 0, 20, 0 ); // Create a new part and base with 12 vertexes, 20 triangles
SetPoints( mesh ); // Create the points in 3D space
SetTris ( mesh ); // Connect the points to make triangles
mesh.setAutoTanBin( ); // Calculate tangents and binormals if needed
mesh.setBox ( ); // Recalculate bounding box from vertexes
SubDiv ( mesh, Divs ); // Set the starting number of verts
}
/******************************************************************************/
void Icosahedron.SubDiv( Mesh &mesh, byte divs )
{
if( !mesh.is( ) ) return; // return if there is no mesh
FREP( divs )
mesh.subdivide( ); // Make it rounder
mesh.setNormals ( );
mesh.setRender ( ); // Set to rendering version
}
/******************************************************************************/