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

vertexlist.cpp

Go to the documentation of this file.
00001 // vertexlist.cpp
00002 //
00003 // Copyright (C) 2001, Chris Laurel
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <algorithm>
00011 #include "gl.h"
00012 #include "glext.h"
00013 #include "vecgl.h"
00014 #include "vertexlist.h"
00015 
00016 using namespace std;
00017 
00018 
00019 VertexList::VertexList(uint32 _parts, uint32 initialVertexPoolSize) :
00020     parts(_parts),
00021     nVertices(0),
00022     maxVertices(0),
00023     vertices(NULL),
00024     diffuseColor(1.0f, 1.0f, 1.0f),
00025     specularColor(0.0f, 0.0f, 0.0f),
00026     shininess(0.0f),
00027     texture(InvalidResource),
00028     bbox()
00029 {
00030     if (initialVertexPoolSize > 0)
00031     {
00032         maxVertices = initialVertexPoolSize;
00033         vertices = new VertexPart[vertexSize * maxVertices];
00034     }
00035 
00036     vertexSize = 3;
00037     if ((parts & VertexNormal) != 0)
00038         vertexSize += 3;
00039     if ((parts & VertexColor0) != 0)
00040         vertexSize += 1;
00041     if ((parts & TexCoord0) != 0)
00042         vertexSize += 2;
00043     if ((parts & TexCoord1) != 0)
00044         vertexSize += 2;
00045 }
00046 
00047 
00048 VertexList::~VertexList()
00049 {
00050     // HACK: Don't delete the vertex data; the VertexList class as an intermediate
00051     // step in converting from 3DS models to Celestia models, and after the
00052     // conversion, the Celestia model will own the vertex data pointer.
00053 #if 0
00054     if (vertices != NULL)
00055         delete[] vertices;
00056 #endif
00057 }
00058 
00059 
00060 void VertexList::render()
00061 {
00062     GLsizei stride = sizeof(VertexPart) * vertexSize;
00063     uint32 start = 3;
00064 
00065     // Vertex points
00066     glEnableClientState(GL_VERTEX_ARRAY);
00067     glVertexPointer(3, GL_FLOAT, stride, static_cast<void*>(vertices));
00068     
00069     // Vertex normals
00070     if ((parts & VertexNormal) != 0)
00071     {
00072         glEnableClientState(GL_NORMAL_ARRAY);
00073         glNormalPointer(GL_FLOAT, stride, static_cast<void*>(&vertices[start]));
00074         start += 3;
00075     }
00076     else
00077     {
00078         glDisableClientState(GL_NORMAL_ARRAY);
00079     }
00080 
00081     // Vertex color
00082     if ((parts & VertexColor0) != 0)
00083     {
00084         glEnableClientState(GL_COLOR_ARRAY);
00085         glColorPointer(4, GL_UNSIGNED_BYTE, stride,
00086                        static_cast<void*>(&vertices[start]));
00087         start += 1;
00088     }
00089     else
00090     {
00091         glDisableClientState(GL_COLOR_ARRAY);
00092         glColor(diffuseColor);
00093     }
00094 
00095     // Texture coordinates
00096     if ((parts & TexCoord0) != 0)
00097     {
00098         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00099         glTexCoordPointer(2, GL_FLOAT, stride,
00100                           static_cast<void*>(&vertices[start]));
00101         start += 2;
00102     }
00103     else
00104     {
00105         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00106     }
00107 
00108     if ((parts & TexCoord1) != 0)
00109     {
00110         // glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00111         glTexCoordPointer(2, GL_FLOAT, stride,
00112                           static_cast<void*>(&vertices[start]));
00113         start += 2;
00114     }
00115 
00116     glDrawArrays(GL_TRIANGLES, 0, nVertices);
00117 }
00118 
00119 
00120 void VertexList::addVertex(const Vertex& v)
00121 {
00122     if (nVertices == maxVertices)
00123     {
00124         if (maxVertices == 0)
00125         {
00126             vertices = new VertexPart[16 * vertexSize];
00127             maxVertices = 16;
00128         }
00129         else
00130         {
00131             VertexPart* newVertices = new VertexPart[maxVertices * 2 * vertexSize];
00132             copy(vertices, vertices + nVertices * vertexSize, newVertices);
00133             delete[] vertices;
00134             vertices = newVertices;
00135             maxVertices *= 2;
00136         }
00137     }
00138 
00139     uint32 n = nVertices * vertexSize;
00140     vertices[n++].f = v.point.x;
00141     vertices[n++].f = v.point.y;
00142     vertices[n++].f = v.point.z;
00143     if ((parts & VertexNormal) != 0)
00144     {
00145         vertices[n++].f = v.normal.x;
00146         vertices[n++].f = v.normal.y;
00147         vertices[n++].f = v.normal.z;
00148     }
00149     if ((parts & VertexColor0) != 0)
00150     {
00151         vertices[n].c[0] = (int) (v.color.red() * 255.99f);
00152         vertices[n].c[1] = (int) (v.color.green() * 255.99f);
00153         vertices[n].c[2] = (int) (v.color.blue() * 255.99f);
00154         vertices[n].c[3] = (int) (v.color.alpha() * 255.99f);
00155         n++;
00156     }
00157     if ((parts & TexCoord0) != 0)
00158     {
00159         vertices[n++].f = v.texCoords[0].x;
00160         vertices[n++].f = v.texCoords[0].y;
00161     }
00162     if ((parts & TexCoord1) != 0)
00163     {
00164         vertices[n++].f = v.texCoords[1].x;
00165         vertices[n++].f = v.texCoords[1].y;
00166     }
00167 
00168     bbox.include(v.point);
00169 
00170     nVertices++;
00171 }
00172 
00173 
00174 AxisAlignedBox VertexList::getBoundingBox() const
00175 {
00176     return bbox;
00177 }
00178 
00179 
00180 Color VertexList::getDiffuseColor() const
00181 {
00182     return diffuseColor;
00183 }
00184 
00185 void VertexList::setDiffuseColor(Color color)
00186 {
00187     diffuseColor = color;
00188 }
00189 
00190 Color VertexList::getSpecularColor() const
00191 {
00192     return specularColor;
00193 }
00194 
00195 void VertexList::setSpecularColor(Color color)
00196 {
00197     specularColor = color;
00198 }
00199 
00200 float VertexList::getShininess() const
00201 {
00202     return shininess;
00203 }
00204 
00205 void VertexList::setShininess(float _shininess)
00206 {
00207     shininess = _shininess;
00208 }
00209 
00210 ResourceHandle VertexList::getTexture() const
00211 {
00212     return texture;
00213 }
00214 
00215 void VertexList::setTexture(ResourceHandle _texture)
00216 {
00217     texture = _texture;
00218 }
00219 
00220 
00221 // Apply a translation and uniform scale to the vertices
00222 void VertexList::transform(Vec3f translation, float scale)
00223 {
00224     for (uint32 i = 0; i < nVertices; i++)
00225     {
00226         uint32 n = i * vertexSize;
00227         Vec3f tv = (Vec3f(vertices[n].f, vertices[n + 1].f, vertices[n + 2].f) + translation) * scale;
00228         vertices[n    ].f = tv.x;
00229         vertices[n + 1].f = tv.y;
00230         vertices[n + 2].f = tv.z;
00231     }
00232 
00233     // Transform the bounding box
00234     Point3f mn = bbox.getMinimum();
00235     Point3f mx = bbox.getMaximum();
00236     Point3f tr(-translation.x, -translation.y, -translation.z);
00237     bbox = AxisAlignedBox(Point3f(0, 0, 0) + ((mn - tr) * scale),
00238                           Point3f(0, 0, 0) + ((mx - tr) * scale));
00239 }
00240 
00241 
00242 bool VertexList::pick(const Ray3d& ray, double& distance)
00243 {
00244     double maxDistance = 1.0e30;
00245     double closest = maxDistance;
00246 
00247     uint32 k = 0;
00248     for (uint32 i = 0; i < nVertices; i += 3)
00249     {
00250         // Get the triangle vertices v0, v1, and v2
00251         Point3d v0(vertices[k + 0].f, vertices[k + 1].f, vertices[k + 2].f);
00252         k += vertexSize;
00253         Point3d v1(vertices[k + 0].f, vertices[k + 1].f, vertices[k + 2].f);
00254         k += vertexSize;
00255         Point3d v2(vertices[k + 0].f, vertices[k + 1].f, vertices[k + 2].f);
00256         k += vertexSize;
00257 
00258         // Compute the edge vectors e0 and e1, and the normal n
00259         Vec3d e0 = v1 - v0;
00260         Vec3d e1 = v2 - v0;
00261         Vec3d n = e0 ^ e1;
00262 
00263         // c is the cosine of the angle between the ray and triangle normal
00264         double c = n * ray.direction;
00265 
00266         // If the ray is parallel to the triangle, it either misses the
00267         // triangle completely, or is contained in the triangle's plane.
00268         // If it's contained in the plane, we'll still call it a miss.
00269         if (c != 0.0)
00270         {
00271             double t = (n * (v0 - ray.origin)) / c;
00272             if (t < closest && t > 0.0)
00273             {
00274                 double m00 = e0 * e0;
00275                 double m01 = e0 * e1;
00276                 double m10 = e1 * e0;
00277                 double m11 = e1 * e1;
00278                 double det = m00 * m11 - m01 * m10;
00279                 if (det != 0.0)
00280                 {
00281                     Point3d p = ray.point(t);
00282                     Vec3d q = p - v0;
00283                     double q0 = e0 * q;
00284                     double q1 = e1 * q;
00285                     double d = 1.0 / det;
00286                     double s0 = (m11 * q0 - m01 * q1) * d;
00287                     double s1 = (m00 * q1 - m10 * q0) * d;
00288                     if (s0 >= 0.0 && s1 >= 0.0 && s0 + s1 <= 1.0)
00289                         closest = t;
00290                 }
00291             }
00292         }
00293     }
00294 
00295     if (closest != maxDistance)
00296     {
00297         distance = closest;
00298         return true;
00299     }
00300     else
00301     {
00302         return false;
00303     }
00304 }
00305 
00306 
00307 uint32 VertexList::getVertexParts() const
00308 {
00309     return parts;
00310 }
00311 
00312 
00313 void* VertexList::getVertexData() const
00314 {
00315     return reinterpret_cast<void*>(vertices);
00316 }
00317 
00318 
00319 uint32 VertexList::getVertexCount() const
00320 {
00321     return nVertices;
00322 }

Generated on Sat Jan 14 22:30:29 2006 for Celestia by  doxygen 1.4.1