67 #ifndef _graphicsproceduralicospheregenerator_cpp
68 #define _graphicsproceduralicospheregenerator_cpp
70 #include "Graphics/Procedural/Mesh/icospheregenerator.h"
72 #include "MathTools/mathtools.h"
83 NumIterations(Iterations)
94 std::vector<Vector3> Vertices;
98 Real phi = .5f * ( 1.f + sqrt(5.f) );
99 Real invnorm = 1 / sqrt( phi * phi + 1 );
101 Vertices.push_back(
Vector3(-1, phi, 0) * invnorm );
102 Vertices.push_back(
Vector3( 1, phi, 0) * invnorm );
103 Vertices.push_back(
Vector3(0, 1, -phi) * invnorm );
104 Vertices.push_back(
Vector3(0, 1, phi) * invnorm );
105 Vertices.push_back(
Vector3(-phi,0, -1) * invnorm );
106 Vertices.push_back(
Vector3(-phi,0, 1) * invnorm );
107 Vertices.push_back(
Vector3( phi,0, -1) * invnorm );
108 Vertices.push_back(
Vector3( phi,0, 1) * invnorm );
109 Vertices.push_back(
Vector3(0, -1, -phi) * invnorm );
110 Vertices.push_back(
Vector3(0, -1, phi) * invnorm );
111 Vertices.push_back(
Vector3(-1, -phi,0) * invnorm );
112 Vertices.push_back(
Vector3( 1, -phi,0) * invnorm );
135 std::vector<Integer> Faces(FirstFaces, FirstFaces +
sizeof(FirstFaces) /
sizeof(*FirstFaces) );
142 std::vector<Integer> NewFaces;
144 for(
Integer Index = 0 ; Index < Size / 12 ; ++Index )
146 Integer i1 = Faces[ Index * 3 ];
147 Integer i2 = Faces[ Index * 3 + 1 ];
148 Integer i3 = Faces[ Index * 3 + 2 ];
156 Vertices.push_back( ( v1 + v2 ).GetNormal() );
157 Vertices.push_back( ( v2 + v3 ).GetNormal() );
158 Vertices.push_back( ( v1 + v3 ).GetNormal() );
160 NewFaces.push_back(i1);
161 NewFaces.push_back(i12);
162 NewFaces.push_back(i13);
163 NewFaces.push_back(i2);
164 NewFaces.push_back(i23);
165 NewFaces.push_back(i12);
166 NewFaces.push_back(i3);
167 NewFaces.push_back(i13);
168 NewFaces.push_back(i23);
169 NewFaces.push_back(i12);
170 NewFaces.push_back(i23);
171 NewFaces.push_back(i13);
173 Faces.swap(NewFaces);
177 std::vector<Vector2> TexCoords;
178 for(
UInt16 Index = 0 ; Index < Vertices.size() ; Index++ )
180 const Vector3& vec = Vertices[Index];
182 Real r0 = sqrtf( vec.
X * vec.
X + vec.
Z * vec.
Z );
184 alpha = atan2f(vec.
Z,vec.
X);
185 u = alpha / MathTools::GetTwoPi() + .5f;
186 v = atan2f(vec.
Y, r0) / MathTools::GetPi() + .5f;
187 TexCoords.push_back(
Vector2(u,v) );
192 std::vector<Integer> IndexToSplit;
193 for(
Whole Index = 0 ; Index < Faces.size() / 3 ; ++Index )
195 Vector2& t0 = TexCoords[ Faces[ Index * 3 + 0 ] ];
196 Vector2& t1 = TexCoords[ Faces[ Index * 3 + 1 ] ];
197 Vector2& t2 = TexCoords[ Faces[ Index * 3 + 2 ] ];
198 if( MathTools::Abs( t2.
X - t0.
X ) > 0.5 ) {
200 IndexToSplit.push_back( Faces[ Index * 3 ] );
202 IndexToSplit.push_back( Faces[ Index * 3 + 2 ] );
205 if( MathTools::Abs( t1.
X - t0.
X ) > 0.5 ) {
207 IndexToSplit.push_back( Faces[ Index * 3 ] );
209 IndexToSplit.push_back( Faces[ Index * 3 + 1 ] );
212 if( MathTools::Abs( t2.
X - t1.
X ) > 0.5 ) {
214 IndexToSplit.push_back( Faces[ Index * 3 + 1 ] );
216 IndexToSplit.push_back( Faces[ Index * 3 + 2 ] );
222 for(
UInt16 Split = 0 ; Split < IndexToSplit.size() ; Split++ )
224 Integer Index = IndexToSplit[Split];
228 Vertices.push_back(v);
229 TexCoords.push_back(t);
230 Integer NewIndex = Vertices.size() - 1;
232 for(
UInt16 j = 0; j < Faces.size() ; j++ )
234 if( Faces[j] == Index ) {
235 Integer index1 = Faces[ ( j + 1 ) % 3 + ( j / 3 ) * 3 ];
236 Integer index2 = Faces[ ( j + 2 ) % 3 + ( j / 3 ) * 3 ];
237 if( ( TexCoords[index1].X > 0.5 ) || ( TexCoords[index2].X > 0.5 ) ) {
249 for(
UInt16 Index = 0 ; Index < Vertices.size() ; ++Index )
253 Vector2( TexCoords[Index].X, TexCoords[Index].Y ) );
255 for(
UInt16 Index = 0 ; Index < Size ; ++Index )
257 Buffer.
AddIndex( Offset + Faces[Index] );
259 Offset += Vertices.size();
276 if( Iterations == 0 )
Real X
Coordinate on the X vector.
Real Z
Coordinate on the Z vector.
Real SphereRadius
The radius of the sphere.
A convenience buffer that stores vertices and indices of a mesh to be generated.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
void EstimateIndexCount(const Whole IndexCount)
Gives an estimation of the number of indices needed for this triangle buffer.
void RebaseOffset()
Rebase index offset.
int Integer
A datatype used to represent any integer close to.
This implements the exception hiearchy for Mezzanine.
float Real
A Datatype used to represent a real floating point number.
uint16_t UInt16
An 16-bit unsigned integer.
Real X
Coordinate on the X vector.
void EstimateVertexCount(const Whole VertexCount)
Gives an estimation of the number of vertices need for this triangle buffer.
This is used to represent a point on a 2 dimentional area, such as a screen.
Real Y
Coordinate on the Y vector.
A generator class for a sphere mesh where all triangles are the same size.
virtual ~IcoSphereGenerator()
Class destructor.
virtual void AddToTriangleBuffer(TriangleBuffer &Buffer) const
Adds the vertices and indices as configured in this generator to a triangle buffer.
void AddPoint(TriangleBuffer &Buffer, const Vector3 &Loc, const Vector3 &Norm, const Vector2 &UV) const
Adds a new point to a triangle buffer, using the format defined for that MeshGenerator.
Thrown when parameters are checked at runtime and found invalid.
TriangleBuffer & AddIndex(const Integer Index)
Adds an index to the index buffer.
This is used to represent a point in space, or a vector through space.
The bulk of the engine components go in this namspace.
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
IcoSphereGenerator & SetRadius(const Real Radius)
Sets the radius of the sphere. the radius is set to 0 or less, a PARAMETERS_EXCEPTION will be thrown...
IcoSphereGenerator(const Real Radius, const Whole Iterations=2)
Class constructor.
IcoSphereGenerator & SetNumIterations(const Whole Iterations)
Sets the number of iterations needed to build the sphere mesh.
Whole NumIterations
The number of iterations needed to build the sphere mesh.