Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

SphereMesh Class Reference

#include <spheremesh.h>

List of all members.

Public Member Functions

MeshconvertToMesh () const
 Convert this object into a standard Celestia mesh.
 SphereMesh (Vec3f size, int _nRings, int _nSlices, DisplacementMapFunc func, void *info)
 SphereMesh (Vec3f size, const DisplacementMap &dispmap, float height=1.0f)
 SphereMesh (Vec3f size, int _nRings, int _nSlices)
 SphereMesh (float radius, int _nRings, int _nSlices)
 ~SphereMesh ()

Private Member Functions

void createSphere (float radius, int nRings, int nSlices)
void displace (DisplacementMapFunc func, void *info)
void displace (const DisplacementMap &dispmap, float height)
void fixNormals ()
void generateNormals ()
void scale (Vec3f)

Private Attributes

unsigned short * indices
int nIndices
float * normals
int nRings
int nSlices
int nVertices
float * tangents
float * texCoords
float * vertices


Detailed Description

The SphereMesh class is used to generate displacement mapped spheres when loading the now-deprecated .cms geometry files. It remains in the Celestia code base for backward compatibility, and it's use is discouraged.

Definition at line 23 of file spheremesh.h.


Constructor & Destructor Documentation

SphereMesh::SphereMesh float  radius,
int  _nRings,
int  _nSlices
 

Definition at line 18 of file spheremesh.cpp.

References createSphere().

00018                                                               :
00019     vertices(NULL), normals(NULL), texCoords(NULL), indices(NULL)
00020 {
00021     createSphere(radius, _nRings, _nSlices);
00022 }

SphereMesh::SphereMesh Vec3f  size,
int  _nRings,
int  _nSlices
 

Definition at line 24 of file spheremesh.cpp.

References createSphere(), and scale().

00024                                                             :
00025     vertices(NULL), normals(NULL), texCoords(NULL), indices(NULL)
00026 {
00027     createSphere(1.0f, _nRings, _nSlices);
00028     scale(size);
00029 }

SphereMesh::SphereMesh Vec3f  size,
const DisplacementMap dispmap,
float  height = 1.0f
 

Definition at line 31 of file spheremesh.cpp.

References createSphere(), displace(), fixNormals(), generateNormals(), and scale().

00033                                      :
00034     vertices(NULL), normals(NULL), texCoords(NULL), indices(NULL)
00035 {
00036     createSphere(1.0f, dispmap.getHeight(), dispmap.getWidth());
00037     scale(size);
00038     displace(dispmap, height);
00039     generateNormals();
00040     fixNormals();
00041 }

SphereMesh::SphereMesh Vec3f  size,
int  _nRings,
int  _nSlices,
DisplacementMapFunc  func,
void *  info
 

Definition at line 43 of file spheremesh.cpp.

References createSphere(), displace(), fixNormals(), generateNormals(), and scale().

00047 {
00048     createSphere(1.0f, _nRings, _nSlices);
00049     scale(size);
00050     displace(func, info);
00051     generateNormals();
00052     fixNormals();
00053 }

SphereMesh::~SphereMesh  ) 
 

Definition at line 55 of file spheremesh.cpp.

References indices, normals, texCoords, and vertices.

00056 {
00057     if (vertices != NULL)
00058         delete[] vertices;
00059     if (normals != NULL)
00060         delete[] normals;
00061     if (texCoords != NULL)
00062         delete[] texCoords;
00063     if (indices != NULL)
00064         delete[] indices;
00065 }


Member Function Documentation

Mesh * SphereMesh::convertToMesh  )  const
 

Convert this object into a standard Celestia mesh.

Definition at line 346 of file spheremesh.cpp.

References Mesh::addGroup(), normals, nRings, nSlices, nVertices, Mesh::setVertexDescription(), Mesh::setVertices(), texCoords, and vertices.

Referenced by LoadCelestiaMesh().

00347 {
00348     uint32 stride = 32;
00349     Mesh::VertexAttribute attributes[3];
00350     attributes[0] = Mesh::VertexAttribute(Mesh::Position, Mesh::Float3, 0);
00351     attributes[1] = Mesh::VertexAttribute(Mesh::Normal, Mesh::Float3, 12);
00352     attributes[2] = Mesh::VertexAttribute(Mesh::Texture0, Mesh::Float2, 24);
00353 
00354     Mesh* mesh = new Mesh();
00355 
00356     mesh->setVertexDescription(Mesh::VertexDescription(stride, 3, attributes));
00357 
00358     // Copy the vertex data from the separate position, normal, and texture coordinate
00359     // arrays into a single array.
00360     char* vertexData = new char[stride * nVertices];
00361 
00362     int i;
00363     for (i = 0; i < nVertices; i++)
00364     {
00365         float* vertex = reinterpret_cast<float*>(vertexData + stride * i);
00366         vertex[0] = vertices[i * 3];
00367         vertex[1] = vertices[i * 3 + 1];
00368         vertex[2] = vertices[i * 3 + 2];
00369         vertex[3] = normals[i * 3];
00370         vertex[4] = normals[i * 3 + 1];
00371         vertex[5] = normals[i * 3 + 2];
00372         vertex[6] = texCoords[i * 2];
00373         vertex[7] = texCoords[i * 2 + 1];
00374     }
00375 
00376     mesh->setVertices(nVertices, vertexData);
00377 
00378     for (i = 0; i < nRings - 1; i++)
00379     {
00380         uint32* indexData = new uint32[(nSlices + 1) * 2];
00381         for (int j = 0; j <= nSlices; j++)
00382         {
00383             indexData[j * 2 + 0] = i * (nSlices + 1) + j;
00384             indexData[j * 2 + 1] = (i + 1) * (nSlices + 1) + j;
00385         }
00386 
00387         mesh->addGroup(Mesh::TriStrip, ~0, (nSlices + 1) * 2, indexData);
00388     }
00389     
00390     return mesh;
00391 }

void SphereMesh::createSphere float  radius,
int  nRings,
int  nSlices
[private]
 

Definition at line 68 of file spheremesh.cpp.

References cos(), indices, nIndices, normals, nRings, nSlices, nVertices, PI, sin(), tangents, texCoords, and vertices.

Referenced by SphereMesh().

00069 {
00070     nRings = _nRings;
00071     nSlices = _nSlices;
00072     nVertices = nRings * (nSlices + 1);
00073     vertices = new float[nVertices * 3];
00074     normals = new float[nVertices * 3];
00075     texCoords = new float[nVertices * 2];
00076     nIndices = (nRings - 1) * (nSlices + 1) * 2;
00077     indices = new unsigned short[nIndices];
00078     tangents = new float[nVertices * 3];
00079     
00080     int i;
00081     for (i = 0; i < nRings; i++)
00082     {
00083         float phi = ((float) i / (float) (nRings - 1) - 0.5f) * (float) PI;
00084         for (int j = 0; j <= nSlices; j++)
00085         {
00086             float theta = (float) j / (float) nSlices * (float) PI * 2;
00087             int n = i * (nSlices + 1) + j;
00088             float x = (float) (cos(phi) * cos(theta));
00089             float y = (float) sin(phi);
00090             float z = (float) (cos(phi) * sin(theta));
00091             vertices[n * 3]      = x * radius;
00092             vertices[n * 3 + 1]  = y * radius;
00093             vertices[n * 3 + 2]  = z * radius;
00094             normals[n * 3]       = x;
00095             normals[n * 3 + 1]   = y;
00096             normals[n * 3 + 2]   = z;
00097             texCoords[n * 2]     = 1.0f - (float) j / (float) nSlices;
00098             texCoords[n * 2 + 1] = 1.0f - (float) i / (float) (nRings - 1);
00099 
00100             // Compute the tangent--required for bump mapping
00101             float tx = (sin(phi) * sin(theta));
00102             float ty = -cos(phi);
00103             float tz = (sin(phi) * cos(theta));
00104             tangents[n * 3]      = tx;
00105             tangents[n * 3 + 1]  = ty;
00106             tangents[n * 3 + 2]  = tz;
00107         }
00108     }
00109 
00110     for (i = 0; i < nRings - 1; i++)
00111     {
00112         for (int j = 0; j <= nSlices; j++)
00113         {
00114             int n = i * (nSlices + 1) + j;
00115             indices[n * 2 + 0] = i * (nSlices + 1) + j;
00116             indices[n * 2 + 1] = (i + 1) * (nSlices + 1) + j;
00117         }
00118     }
00119 }

void SphereMesh::displace DisplacementMapFunc  func,
void *  info
[private]
 

Definition at line 327 of file spheremesh.cpp.

References normals, nRings, nSlices, vertices, Vector3< T >::x, Vector3< T >::y, and Vector3< T >::z.

00328 {
00329     for (int i = 0; i < nRings; i++)
00330     {
00331         float v = (float) i / (float) (nRings - 1);
00332         for (int j = 0; j <= nSlices; j++)
00333         {
00334             float u = (float) j / (float) nSlices;
00335             int n = (i * (nSlices + 1) + j) * 3;
00336             Vec3f normal(normals[n], normals[n + 1], normals[n + 2]);
00337             Vec3f vert = normal * func(u, v, info);
00338             vertices[n] += vert.x;
00339             vertices[n + 1] += vert.y;
00340             vertices[n + 2] += vert.z;
00341         }
00342     }
00343 }

void SphereMesh::displace const DisplacementMap dispmap,
float  height
[private]
 

Definition at line 298 of file spheremesh.cpp.

References normals, nRings, nSlices, vertices, Vector3< T >::x, Vector3< T >::y, and Vector3< T >::z.

Referenced by SphereMesh().

00300 {
00301     // assert(dispMap.getWidth() == nSlices);
00302     // assert(dispMap.getHeight() == nRings);
00303 
00304     for (int i = 0; i < nRings; i++)
00305     {
00306         for (int j = 0; j <= nSlices; j++)
00307         {
00308             int n = (i * (nSlices + 1) + j) * 3;
00309             /*
00310             float theta = (float) j / (float) nSlices * (float) PI * 2;
00311             float x = (float) (cos(phi) * cos(theta));
00312             float y = (float) sin(phi);
00313             float z = (float) (cos(phi) * sin(theta));
00314             */
00315             Vec3f normal(normals[n], normals[n + 1], normals[n + 2]);
00316 
00317             int k = (j == nSlices) ? 0 : j;
00318             Vec3f v = normal * dispmap.getDisplacement(k, i) * height;
00319             vertices[n] += v.x;
00320             vertices[n + 1] += v.y;
00321             vertices[n + 2] += v.z;
00322         }
00323     }
00324 }

void SphereMesh::fixNormals  )  [private]
 

Definition at line 249 of file spheremesh.cpp.

References Vector3< T >::normalize(), normals, nRings, nSlices, Vector3< T >::x, Vector3< T >::y, and Vector3< T >::z.

Referenced by SphereMesh().

00250 {
00251     for (int i = 0; i < nRings; i++)
00252     {
00253         float* v0 = normals + (i * (nSlices + 1)) * 3;
00254         float* v1 = normals + ((i + 1) * (nSlices + 1) - 1) * 3;
00255         Vec3f n0(v0[0], v0[1], v0[2]);
00256         Vec3f n1(v0[0], v0[1], v0[2]);
00257         Vec3f normal = n0 + n1;
00258         normal.normalize();
00259         v0[0] = normal.x;
00260         v0[1] = normal.y;
00261         v0[2] = normal.z;
00262         v1[0] = normal.x;
00263         v1[1] = normal.y;
00264         v1[2] = normal.z;
00265     }
00266 }

void SphereMesh::generateNormals  )  [private]
 

Definition at line 123 of file spheremesh.cpp.

References cross(), Vector3< T >::length(), normals, nRings, nSlices, nVertices, sqrt(), vertices, Vector3< T >::x, Vector3< T >::y, and Vector3< T >::z.

Referenced by SphereMesh().

00124 {
00125     int nQuads = nSlices * (nRings - 1);
00126     Vec3f* faceNormals = new Vec3f[nQuads];
00127     int i;
00128 
00129     // Compute face normals for the mesh
00130     for (i = 0; i < nRings - 1; i++)
00131     {
00132         for (int j = 0; j < nSlices; j++)
00133         {
00134             float* p0 = vertices + (i * (nSlices + 1) + j) * 3;
00135             float* p1 = vertices + ((i + 1) * (nSlices + 1) + j) * 3;
00136             float* p2 = vertices + ((i + 1) * (nSlices + 1) + j + 1) * 3;
00137             float* p3 = vertices + (i * (nSlices + 1) + j + 1) * 3;
00138 
00139             // Compute the face normal.  Watch out for degenerate (zero-length)
00140             // edges.  If there are two degenerate edges, the entire face must
00141             // be degenerate and we'll handle that later
00142             Vec3f v0(p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]);
00143             Vec3f v1(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);
00144             if (v0.length() < 1e-6f)
00145             {
00146                 v0 = Vec3f(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);
00147                 v1 = Vec3f(p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]);
00148             }
00149             else if (v1.length() < 1e-6f)
00150             {
00151                 v0 = Vec3f(p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]);
00152                 v1 = Vec3f(p0[0] - p3[0], p0[1] - p3[1], p0[2] - p3[2]);
00153             }
00154 
00155             Vec3f faceNormal = cross(v0, v1);
00156             float length = faceNormal.length();
00157             if (length != 0)
00158                 faceNormal *= (1 / length);
00159 
00160             faceNormals[i * nSlices + j] = faceNormal;
00161         }
00162     }
00163 
00164     int* faceCounts = new int[nVertices];
00165     for (i = 0; i < nVertices; i++)
00166     {
00167         faceCounts[i] = 0;
00168         normals[i * 3] = 0;
00169         normals[i * 3 + 1] = 0;
00170         normals[i * 3 + 2] = 0;
00171     }
00172 
00173     for (i = 1; i < nRings - 1; i++)
00174     {
00175         for (int j = 0; j <= nSlices; j++)
00176         {
00177             int vertex = i * (nSlices + 1) + j;
00178             faceCounts[vertex] = 4;
00179 
00180             int face = (i - 1) * nSlices + j % nSlices;
00181             normals[vertex * 3]     += faceNormals[face].x;
00182             normals[vertex * 3 + 1] += faceNormals[face].y;
00183             normals[vertex * 3 + 2] += faceNormals[face].z;
00184             face = (i - 1) * nSlices + (j + nSlices - 1) % nSlices;
00185             normals[vertex * 3]     += faceNormals[face].x;
00186             normals[vertex * 3 + 1] += faceNormals[face].y;
00187             normals[vertex * 3 + 2] += faceNormals[face].z;
00188             face = i * nSlices + (j + nSlices - 1) % nSlices;
00189             normals[vertex * 3]     += faceNormals[face].x;
00190             normals[vertex * 3 + 1] += faceNormals[face].y;
00191             normals[vertex * 3 + 2] += faceNormals[face].z;
00192             face = i * nSlices + j % nSlices;
00193             normals[vertex * 3]     += faceNormals[face].x;
00194             normals[vertex * 3 + 1] += faceNormals[face].y;
00195             normals[vertex * 3 + 2] += faceNormals[face].z;
00196         }
00197     }
00198 
00199     // Compute normals at the poles
00200     for (i = 0; i <= nSlices; i++)
00201     {
00202         int vertex = i;
00203         int j;
00204         faceCounts[vertex] = nSlices;
00205         for (j = 0; j < nSlices; j++)
00206         {
00207             int face = j;
00208             normals[vertex * 3]     += faceNormals[face].x;
00209             normals[vertex * 3 + 1] += faceNormals[face].y;
00210             normals[vertex * 3 + 2] += faceNormals[face].z;
00211         }
00212 
00213         vertex = (nRings - 1) * (nSlices + 1) + i;
00214         faceCounts[vertex] = nSlices;
00215         for (j = 0; j < nSlices; j++)
00216         {
00217             int face = nQuads - j - 1;
00218             normals[vertex * 3]     += faceNormals[face].x;
00219             normals[vertex * 3 + 1] += faceNormals[face].y;
00220             normals[vertex * 3 + 2] += faceNormals[face].z;
00221         }
00222     }
00223 
00224     for (i = 0; i < nVertices; i++)
00225     {
00226         if (faceCounts[i] > 0)
00227         {
00228             float s = 1.0f / (float) faceCounts[i];
00229             float nx = normals[i * 3] * s;
00230             float ny = normals[i * 3 + 1] * s;
00231             float nz = normals[i * 3 + 2] * s;
00232             float length = (float) sqrt(nx * nx + ny * ny + nz * nz);
00233             if (length > 0)
00234             {
00235                 length = 1 / length;
00236                 normals[i * 3]     = nx * length;
00237                 normals[i * 3 + 1] = ny * length;
00238                 normals[i * 3 + 2] = nz * length;
00239             }
00240         }
00241     }
00242 
00243     delete[] faceCounts;
00244     delete[] faceNormals;
00245 }

void SphereMesh::scale Vec3f   )  [private]
 

Definition at line 269 of file spheremesh.cpp.

References Vector3< T >::normalize(), normals, nVertices, vertices, Vector3< T >::x, Vector3< T >::y, and Vector3< T >::z.

Referenced by SphereMesh().

00270 {
00271     int i;
00272     for (i = 0; i < nVertices; i++)
00273     {
00274         vertices[i * 3]     *= s.x;
00275         vertices[i * 3 + 1] *= s.y;
00276         vertices[i * 3 + 2] *= s.z;
00277     }
00278 
00279     // Modify the normals
00280     if (normals != NULL)
00281     {
00282         // TODO: Make a fast special case for uniform scale factors, where
00283         // renormalization is not required.
00284         Vec3f is(1.0f / s.x, 1.0f / s.y, 1.0f / s.z);
00285         for (i = 0; i < nVertices; i++)
00286         {
00287             int n = i * 3;
00288             Vec3f normal(normals[n] * is.x, normals[n + 1] * is.y, normals[n + 2] * is.z);
00289             normal.normalize();
00290             normals[n]     = normal.x;
00291             normals[n + 1] = normal.y;
00292             normals[n + 2] = normal.z;
00293         }
00294     }
00295 }


Member Data Documentation

unsigned short* SphereMesh::indices [private]
 

Definition at line 56 of file spheremesh.h.

Referenced by createSphere(), and ~SphereMesh().

int SphereMesh::nIndices [private]
 

Definition at line 55 of file spheremesh.h.

Referenced by createSphere().

float* SphereMesh::normals [private]
 

Definition at line 52 of file spheremesh.h.

Referenced by convertToMesh(), createSphere(), displace(), fixNormals(), generateNormals(), scale(), and ~SphereMesh().

int SphereMesh::nRings [private]
 

Definition at line 48 of file spheremesh.h.

Referenced by convertToMesh(), createSphere(), displace(), fixNormals(), and generateNormals().

int SphereMesh::nSlices [private]
 

Definition at line 49 of file spheremesh.h.

Referenced by convertToMesh(), createSphere(), displace(), fixNormals(), and generateNormals().

int SphereMesh::nVertices [private]
 

Definition at line 50 of file spheremesh.h.

Referenced by convertToMesh(), createSphere(), generateNormals(), and scale().

float* SphereMesh::tangents [private]
 

Definition at line 54 of file spheremesh.h.

Referenced by createSphere().

float* SphereMesh::texCoords [private]
 

Definition at line 53 of file spheremesh.h.

Referenced by convertToMesh(), createSphere(), and ~SphereMesh().

float* SphereMesh::vertices [private]
 

Definition at line 51 of file spheremesh.h.

Referenced by convertToMesh(), createSphere(), displace(), generateNormals(), scale(), and ~SphereMesh().


The documentation for this class was generated from the following files:
Generated on Sat Jan 14 22:33:36 2006 for Celestia by  doxygen 1.4.1