00001 #include "VertexArrayObject.h"
00002 #include "Textures.h"
00003
00004 VertexArrayObject::VertexArrayObject ()
00005 {
00006
00007 vertex_pointer = NULL;
00008 num_vertices = 0;
00009 index_pointer = NULL;
00010 num_faces = 0;
00011 normal_pointer = NULL;
00012 texture_pointer = NULL;
00013
00014 bounding_volumes_computed = false;
00015 }
00016
00017 VertexArrayObject::~VertexArrayObject ()
00018 {
00019 if (vertex_pointer != NULL) delete vertex_pointer;
00020 if (index_pointer != NULL) delete index_pointer;
00021 if (normal_pointer != NULL) delete normal_pointer;
00022 if (texture_pointer != NULL) delete texture_pointer;
00023 }
00024
00025 void VertexArrayObject::SetVertexData (float * data, int num_vertices_)
00026 {
00027 vertex_pointer = data;
00028 num_vertices = num_vertices_;
00029 bounding_volumes_computed = false;
00030 }
00031
00032 void VertexArrayObject::SetVertexIndices (GLuint * indices, int num_faces_)
00033 {
00034 index_pointer = indices;
00035 num_faces = num_faces_;
00036 }
00037
00038 void VertexArrayObject::SetTextureCoordinates (float * data, GLuint texture_id_)
00039 {
00040 texture_pointer = data;
00041 texture_id = texture_id_;
00042 }
00043
00044 double VertexArrayObject::GetBoundingRadius ()
00045 {
00046 if (!bounding_volumes_computed)
00047 {ComputeBoundingVolumes ();}
00048
00049 return bounding_radius;
00050 }
00051
00052 BoundingBox VertexArrayObject::GetBoundingBox ()
00053 {
00054 if (!bounding_volumes_computed)
00055 {ComputeBoundingVolumes ();}
00056
00057 return bounding_box;
00058 }
00059
00060 void VertexArrayObject::Draw ()
00061 {
00062
00063 glEnableClientState (GL_VERTEX_ARRAY);
00064 if (normal_pointer != NULL) glEnableClientState (GL_NORMAL_ARRAY);
00065 if (texture_pointer != NULL) glEnableClientState (GL_TEXTURE_COORD_ARRAY);
00066
00067 glVertexPointer (3, GL_FLOAT, 0, vertex_pointer);
00068 if (normal_pointer != NULL) glNormalPointer (GL_FLOAT, 0 , normal_pointer);
00069 if (texture_pointer != NULL)
00070 {
00071 glEnable (GL_TEXTURE_2D);
00072 glBindTexture (GL_TEXTURE_2D, texture_id);
00073 glTexCoordPointer (2, GL_FLOAT, 0, texture_pointer);
00074 }
00075
00076
00077 glColor4fv (color);
00078 glDrawElements (GL_TRIANGLES, num_faces * 3, GL_UNSIGNED_INT, index_pointer);
00079
00080
00081 if (texture_pointer != NULL)
00082 {
00083 glDisable (GL_TEXTURE_2D);
00084 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
00085 }
00086 if (normal_pointer != NULL) glDisableClientState (GL_NORMAL_ARRAY);
00087 glDisableClientState (GL_VERTEX_ARRAY);
00088
00089 if (show_normals)
00090 {Draw_Normals ();}
00091 }
00092
00093 void VertexArrayObject::Draw_Normals ()
00094 {
00095 Point p2;
00096
00097 glColor3f (0.4f, 0.4f, 0.8f);
00098 glBegin (GL_LINES);
00099
00100 for (int index = 0; index < num_vertices; index++)
00101 {
00102 glVertex3f (vertex_pointer[3*index], vertex_pointer[3*index+1], vertex_pointer[3*index+2]);
00103 p2.x = vertex_pointer[3*index] + normal_pointer[3*index] * normal_length;
00104 p2.y = vertex_pointer[3*index+1] + normal_pointer[3*index+1] * normal_length;
00105 p2.z = vertex_pointer[3*index+2] + normal_pointer[3*index+2] * normal_length;
00106 glVertex3f (p2.x, p2.y, p2.z);
00107 }
00108
00109 glEnd ();
00110 }
00111
00112 void VertexArrayObject::ComputeNormals (bool clock_wise)
00113 {
00114 Point p1, p2, p3;
00115 Vector v1, v2;
00116 Vector cross_result;
00117 Vector normal;
00118 float weight;
00119 int base, i1, i2, i3;
00120
00121
00122 if (normal_pointer != NULL) delete [] normal_pointer;
00123
00124 normal_pointer = new float[num_vertices*3];
00125
00126 for (int curr_vertex = 0; curr_vertex < num_vertices; curr_vertex++)
00127 {
00128 normal.x = 0.0f;
00129 normal.y = 0.0f;
00130 normal.z = 0.0f;
00131
00132 for (int curr_index = 0; curr_index < num_faces*3; curr_index ++)
00133 {
00134 if (index_pointer[curr_index] == curr_vertex)
00135 {
00136 base = curr_index / 3;
00137 i1 = index_pointer[curr_index];
00138 i2 = index_pointer[3*base + (curr_index+1)%3];
00139 i3 = index_pointer[3*base + (curr_index+2)%3];
00140
00141 p1.x = vertex_pointer[3*i1];
00142 p1.y = vertex_pointer[3*i1 + 1];
00143 p1.z = vertex_pointer[3*i1 + 2];
00144
00145 p2.x = vertex_pointer[3*i2];
00146 p2.y = vertex_pointer[3*i2 + 1];
00147 p2.z = vertex_pointer[3*i2 + 2];
00148
00149 p3.x = vertex_pointer[3*i3];
00150 p3.y = vertex_pointer[3*i3 + 1];
00151 p3.z = vertex_pointer[3*i3 + 2];
00152
00153 v1.x = p3.x - p1.x;
00154 v1.y = p3.y - p1.y;
00155 v1.z = p3.z - p1.z;
00156
00157 v2.x = p2.x - p1.x;
00158 v2.y = p2.y - p1.y;
00159 v2.z = p2.z - p1.z;
00160
00161 cross_result = Geometry::CrossProduct (v1, v2);
00162 weight = Geometry::EnclosingAngle (v1, v2);
00163
00164 cross_result.x *= weight;
00165 cross_result.y *= weight;
00166 cross_result.z *= weight;
00167
00168 normal.x += cross_result.x;
00169 normal.y += cross_result.y;
00170 normal.z += cross_result.z;
00171 }
00172 }
00173
00174 Geometry::VectorNormalize (normal);
00175
00176 if (!clock_wise)
00177 {
00178 normal.x *= -1;
00179 normal.y *= -1;
00180 normal.z *= -1;
00181 }
00182
00183 normal_pointer[3*curr_vertex] = normal.x;
00184 normal_pointer[3*curr_vertex+1] = normal.y;
00185 normal_pointer[3*curr_vertex+2] = normal.z;
00186 }
00187 }
00188
00189 void VertexArrayObject::ComputeSphericalTextureCoordinates (GLuint texture_id_)
00190 {
00191 int curr_vertex;
00192
00193 if (normal_pointer == NULL) return;
00194
00195 if (texture_pointer != NULL) delete texture_pointer;
00196 texture_pointer = new float[2*num_vertices];
00197
00198 texture_id = texture_id_;
00199
00200 for (curr_vertex = 0; curr_vertex < num_vertices; curr_vertex++)
00201 {
00202 texture_pointer[2*curr_vertex] = asin (normal_pointer[3*curr_vertex]) / MY_PI + 0.5;
00203 texture_pointer[2*curr_vertex+1] = asin (normal_pointer[3*curr_vertex+1]) / MY_PI + 0.5;
00204 }
00205 }
00206
00207 void VertexArrayObject::ComputeBoundingVolumes ()
00208 {
00209 float x, y, z;
00210 float dist;
00211
00212
00213 bounding_radius = 0.0;
00214 bounding_box.xmin = 0.0;
00215 bounding_box.xmax = 0.0;
00216 bounding_box.ymin = 0.0;
00217 bounding_box.ymax = 0.0;
00218 bounding_box.zmin = 0.0;
00219 bounding_box.zmax = 0.0;
00220
00221 for (int curr_vertex = 0; curr_vertex < num_vertices; curr_vertex++)
00222 {
00223
00224 x = vertex_pointer[curr_vertex*3];
00225 y = vertex_pointer[curr_vertex*3+1];
00226 z = vertex_pointer[curr_vertex*3+2];
00227
00228 dist = x*x + y*y + z*z;
00229
00230 if ( dist > bounding_radius) bounding_radius = dist;
00231
00232 if (x > bounding_box.xmax) bounding_box.xmax = x;
00233 if (x < bounding_box.xmin) bounding_box.xmin = x;
00234 if (y > bounding_box.ymax) bounding_box.ymax = y;
00235 if (y < bounding_box.ymin) bounding_box.ymin = y;
00236 if (z > bounding_box.zmax) bounding_box.zmax = z;
00237 if (z < bounding_box.zmin) bounding_box.zmin = z;
00238 }
00239
00240 bounding_radius = sqrt (bounding_radius);
00241 bounding_volumes_computed = true;
00242 }
00243
00244 void VertexArrayObject::PrintToConsole ()
00245 {
00246 int index;
00247
00248 printf ("------------ Printing Vertex Data ---------------\n");
00249 for (index = 0; index < num_vertices; index++)
00250 {
00251 printf ("{%g, %g, %g}\n", vertex_pointer[3*index], vertex_pointer[3*index+1], vertex_pointer[3*index+2]);
00252 }
00253
00254 printf ("------------ Printing Vertex Indices --------------\n");
00255 for (index = 0; index < num_faces; index++)
00256 {
00257 printf ("{%u, %u, %u}\n", index_pointer[3*index], index_pointer[3*index+1], index_pointer[3*index+2]);
00258 }
00259 printf ("------------ Printing Faces --------------\n");
00260 for (index = 0; index < num_faces; index ++)
00261 {
00262 printf ("{%g, %g, %g}, ", vertex_pointer[index_pointer[3*index]*3], vertex_pointer[index_pointer[3*index]*3+1], vertex_pointer[index_pointer[3*index]*3+2]);
00263 printf ("{%g, %g, %g}, ", vertex_pointer[index_pointer[3*index+1]*3], vertex_pointer[index_pointer[3*index+1]*3+1], vertex_pointer[index_pointer[3*index+1]*3+2]);
00264 printf ("{%g, %g, %g}\n", vertex_pointer[index_pointer[3*index+2]*3], vertex_pointer[index_pointer[3*index+2]*3+1], vertex_pointer[index_pointer[3*index+2]*3+2]);
00265 }
00266
00267 if (normal_pointer != NULL)
00268 {
00269 printf ("------------ Printing Normals ---------------\n");
00270 for (index = 0; index < num_vertices; index++)
00271 {
00272 printf ("{%g, %g, %g}\n", normal_pointer[3*index], normal_pointer[3*index+1], normal_pointer[3*index+2]);
00273 }
00274 }
00275 else
00276 {printf ("------------ No Normals Detected ---------------\n");}
00277
00278 printf ("----------- End Of Vertex Array Component ---------------\n");
00279 }
00280
00281 bool VertexArrayObject::show_normals = false;
00282 float VertexArrayObject::normal_length = 3.0f;