| 1 | /* | 
|---|
| 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
| 3 |  | 
|---|
| 4 |    Copyright (C) 2004 orx | 
|---|
| 5 |  | 
|---|
| 6 |    This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |    it under the terms of the GNU General Public License as published by | 
|---|
| 8 |    the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 9 |    any later version. | 
|---|
| 10 |  | 
|---|
| 11 |    ### File Specific: | 
|---|
| 12 |    main-programmer: Benjamin Grauer | 
|---|
| 13 |    co-programmer: ... | 
|---|
| 14 | */ | 
|---|
| 15 |  | 
|---|
| 16 | #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER | 
|---|
| 17 |  | 
|---|
| 18 | #include "vertex_array_model.h" | 
|---|
| 19 |  | 
|---|
| 20 | #include "stdlibincl.h" | 
|---|
| 21 | #include <stdarg.h> | 
|---|
| 22 |  | 
|---|
| 23 | #include "tc.h" | 
|---|
| 24 |  | 
|---|
| 25 | using namespace std; | 
|---|
| 26 |  | 
|---|
| 27 | ///////////// | 
|---|
| 28 | /// MODEL /// | 
|---|
| 29 | ///////////// | 
|---|
| 30 | /** | 
|---|
| 31 |  * @brief Creates a 3D-VertexArrayModel. | 
|---|
| 32 |  * | 
|---|
| 33 |  * assigns it a Name and a Type | 
|---|
| 34 |  */ | 
|---|
| 35 | VertexArrayModel::VertexArrayModel() | 
|---|
| 36 | { | 
|---|
| 37 |   this->setClassID(CL_MODEL, "VertexArrayModel"); | 
|---|
| 38 |  | 
|---|
| 39 |   this->newStripe(); | 
|---|
| 40 | } | 
|---|
| 41 |  | 
|---|
| 42 | /** | 
|---|
| 43 |  * @brief special copy constructor for converting Models to VertexArray-Stripes | 
|---|
| 44 |  * @param model the Model to produce a VertexArray model from. | 
|---|
| 45 |  * | 
|---|
| 46 |  * Code that uses Brad Granthams | 
|---|
| 47 |  * excelent TC-code for generating stripes out of a mix of ModelCoordinates. | 
|---|
| 48 |  */ | 
|---|
| 49 | VertexArrayModel::VertexArrayModel(const Model& model) | 
|---|
| 50 | { | 
|---|
| 51 |   this->setClassID(CL_MODEL, "VertexArrayModel"); | 
|---|
| 52 |  | 
|---|
| 53 |   // importing the data to the new Model. | 
|---|
| 54 |   this->newStripe(); | 
|---|
| 55 |  | 
|---|
| 56 |   for (unsigned int i = 0; i < model.getVertexCount()*3; i+=3) | 
|---|
| 57 |     this->addVertex(model.getVertexArray()[i], model.getVertexArray()[i+1], model.getVertexArray()[i+2]); | 
|---|
| 58 |   for (unsigned int i = 0; i < model.getVertexCount()*3; i+=3) | 
|---|
| 59 |     this->addColor((float)i / (float)model.getVertexCount(), 0, 0); | 
|---|
| 60 |  | 
|---|
| 61 |   for (unsigned int i = 0; i < model.getNormalsCount()*3; i+=3) | 
|---|
| 62 |      this->addNormal(model.getNormalsArray()[i], model.getNormalsArray()[i+1], model.getNormalsArray()[i+2]); | 
|---|
| 63 |   for (unsigned int i = 0; i < model.getTexCoordCount(); i+=2) | 
|---|
| 64 |      this->addTexCoor(model.getTexCoordArray()[i], model.getTexCoordArray()[i+1]); | 
|---|
| 65 |  | 
|---|
| 66 |  | 
|---|
| 67 |   // The acTC object generating this Model. // | 
|---|
| 68 |   ACTCData *tc; | 
|---|
| 69 |   tc = actcNew(); | 
|---|
| 70 |   if(tc == NULL) { | 
|---|
| 71 |     /* memory allocation failed */ | 
|---|
| 72 |     /* print error here and exit or whatever */ | 
|---|
| 73 |   } | 
|---|
| 74 |  | 
|---|
| 75 |   // inputing the data of model to the tc | 
|---|
| 76 |   actcBeginInput(tc); | 
|---|
| 77 |   for(unsigned int i = 0; i < model.getTriangleCount(); i++) | 
|---|
| 78 |   { | 
|---|
| 79 |       actcAddTriangle(tc, | 
|---|
| 80 |                       model.getTriangles()[i].indexToVertices[0], | 
|---|
| 81 |                       model.getTriangles()[i].indexToVertices[1], | 
|---|
| 82 |                       model.getTriangles()[i].indexToVertices[2]); | 
|---|
| 83 |   } | 
|---|
| 84 |   actcEndInput(tc); | 
|---|
| 85 |  | 
|---|
| 86 |  | 
|---|
| 87 |  | 
|---|
| 88 |   int prim; | 
|---|
| 89 |   unsigned int v1, v2, v3; | 
|---|
| 90 |  | 
|---|
| 91 |   actcBeginOutput(tc); | 
|---|
| 92 |   while((prim = actcStartNextPrim(tc, &v1, &v2) != ACTC_DATABASE_EMPTY)) | 
|---|
| 93 |   { | 
|---|
| 94 |     this->newStripe(); | 
|---|
| 95 |  | 
|---|
| 96 |     this->addIndice(v1); | 
|---|
| 97 |     this->addIndice(v2); | 
|---|
| 98 |     /* start a primitive of type "prim" with v1 and v2 */ | 
|---|
| 99 |     while(actcGetNextVert(tc, &v3) != ACTC_PRIM_COMPLETE) | 
|---|
| 100 |     { | 
|---|
| 101 |       /* continue primitive using v3 */ | 
|---|
| 102 |       this->addIndice(v3); | 
|---|
| 103 |     } | 
|---|
| 104 |   } | 
|---|
| 105 |   actcEndOutput(tc); | 
|---|
| 106 |  | 
|---|
| 107 |   this->finalize(); | 
|---|
| 108 | } | 
|---|
| 109 |  | 
|---|
| 110 |  | 
|---|
| 111 | /** | 
|---|
| 112 |  * @brief deletes a VertexArrayModel. | 
|---|
| 113 |  * | 
|---|
| 114 |  * Looks if any from model allocated space is still in use, and if so deleted it. | 
|---|
| 115 |  */ | 
|---|
| 116 | VertexArrayModel::~VertexArrayModel() | 
|---|
| 117 | { | 
|---|
| 118 |   PRINTF(4)("Deleting VertexArrayModel "); | 
|---|
| 119 |   if (this->getName()) | 
|---|
| 120 |   { | 
|---|
| 121 |     PRINT(4)("%s\n", this->getName()); | 
|---|
| 122 |   } | 
|---|
| 123 |   else | 
|---|
| 124 |   { | 
|---|
| 125 |     PRINT(4)("\n"); | 
|---|
| 126 |   } | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 |  | 
|---|
| 130 | /** | 
|---|
| 131 |  * @brief Draws the VertexArrayModels of all Groups. | 
|---|
| 132 |  * | 
|---|
| 133 |  * It does this by just calling the Lists that must have been created earlier. | 
|---|
| 134 |  */ | 
|---|
| 135 | void VertexArrayModel::draw() const | 
|---|
| 136 | { | 
|---|
| 137 |   PRINTF(4)("drawing 3D-VertexArrayModel %s\n", this->getName()); | 
|---|
| 138 |   glEnableClientState(GL_VERTEX_ARRAY ); | 
|---|
| 139 |   glEnableClientState(GL_TEXTURE_COORD_ARRAY ); | 
|---|
| 140 |   glEnableClientState(GL_NORMAL_ARRAY ); | 
|---|
| 141 |   glEnableClientState(GL_COLOR_ARRAY ); | 
|---|
| 142 |  | 
|---|
| 143 |  | 
|---|
| 144 |   glVertexPointer(3, GL_FLOAT, 0, &this->vertices[0]); | 
|---|
| 145 |   glNormalPointer(GL_FLOAT, 0, &this->normals[0]); | 
|---|
| 146 |   glTexCoordPointer(2, GL_FLOAT, 0, &this->texCoords[0]); | 
|---|
| 147 |   glColorPointer(3, GL_FLOAT, 0, &this->colors[0]); | 
|---|
| 148 |  | 
|---|
| 149 |   for (GLuint i = 1; i < this->stripes.size(); ++i) | 
|---|
| 150 |     { | 
|---|
| 151 |       glDrawElements( GL_TRIANGLE_STRIP, | 
|---|
| 152 |                       this->stripes[i] - this->stripes[i-1], | 
|---|
| 153 |                       GL_UNSIGNED_INT, | 
|---|
| 154 |                       &this->indices[this->stripes[i-1]] ); | 
|---|
| 155 |     } | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 |  | 
|---|
| 159 | ////////// | 
|---|
| 160 | // MESH // | 
|---|
| 161 | ////////// | 
|---|
| 162 | /** | 
|---|
| 163 |  * @brief generates a new Stripe in this Model | 
|---|
| 164 |  */ | 
|---|
| 165 | void VertexArrayModel::newStripe() | 
|---|
| 166 | { | 
|---|
| 167 |   // no stripes of size 0 | 
|---|
| 168 |   if (this->stripes.empty() || this->indices.size() != this->stripes.back()) | 
|---|
| 169 |     this->stripes.push_back(this->indices.size()); | 
|---|
| 170 | } | 
|---|
| 171 |  | 
|---|
| 172 |  | 
|---|
| 173 | /** | 
|---|
| 174 |  * @brief parses a vertex-String | 
|---|
| 175 |  * @param x the X-coordinate of the Vertex to add. | 
|---|
| 176 |  * @param y the Y-coordinate of the Vertex to add. | 
|---|
| 177 |  * @param z the Z-coordinate of the Vertex to add. | 
|---|
| 178 |  */ | 
|---|
| 179 | void VertexArrayModel::addVertex(float x, float y, float z) | 
|---|
| 180 | { | 
|---|
| 181 |   this->vertices.push_back(Vector(x,y,z)); | 
|---|
| 182 |   this->pModelInfo.numVertices++; | 
|---|
| 183 | } | 
|---|
| 184 |  | 
|---|
| 185 |  | 
|---|
| 186 | /** | 
|---|
| 187 |  * @brief adds a VertexNormal. | 
|---|
| 188 |  * @param x The x coordinate of the Normal. | 
|---|
| 189 |  * @param y The y coordinate of the Normal. | 
|---|
| 190 |  * @param z The z coordinate of the Normal. | 
|---|
| 191 |  * | 
|---|
| 192 |  * If a vertexNormal line is found this function will inject it into the vertexNormal-Array | 
|---|
| 193 |  */ | 
|---|
| 194 | void VertexArrayModel::addNormal(float x, float y, float z) | 
|---|
| 195 | { | 
|---|
| 196 |   this->normals.push_back(Vector(x,y,z)); | 
|---|
| 197 |   this->pModelInfo.numNormals++; | 
|---|
| 198 | } | 
|---|
| 199 |  | 
|---|
| 200 |  | 
|---|
| 201 | /** | 
|---|
| 202 |  * @brief adds a Texture Coordinate | 
|---|
| 203 |  * @param u The u coordinate of the TextureCoordinate. | 
|---|
| 204 |  * @param v The y coordinate of the TextureCoordinate. | 
|---|
| 205 |  * | 
|---|
| 206 |  *  If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array | 
|---|
| 207 |  */ | 
|---|
| 208 | void VertexArrayModel::addTexCoor(float u, float v) | 
|---|
| 209 | { | 
|---|
| 210 |   this->texCoords.push_back(Vector2D(u,v)); | 
|---|
| 211 |   this->pModelInfo.numTexCoor++; | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | /** | 
|---|
| 215 |  * @brief adds a new Color | 
|---|
| 216 |  * @param r the Red Component of the VertexColor to add. | 
|---|
| 217 |  * @param g the Green Component of the VertexColor to add. | 
|---|
| 218 |  * @param b the Blue of the VertexColor to add. | 
|---|
| 219 |  */ | 
|---|
| 220 | void VertexArrayModel::addColor(float r, float g, float b) | 
|---|
| 221 | { | 
|---|
| 222 |   this->colors.push_back(Vector(r,g,b)); | 
|---|
| 223 |   // FIXME | 
|---|
| 224 | } | 
|---|
| 225 |  | 
|---|
| 226 |  | 
|---|
| 227 | /** | 
|---|
| 228 |  *  adds a new Face | 
|---|
| 229 |  * @param faceElemCount the number of Vertices to add to the Face. | 
|---|
| 230 |  * @param type The information Passed with each Vertex | 
|---|
| 231 | */ | 
|---|
| 232 | void VertexArrayModel::addIndice(GLuint indice) | 
|---|
| 233 | { | 
|---|
| 234 |   this->indices.push_back(indice); | 
|---|
| 235 | } | 
|---|
| 236 |  | 
|---|
| 237 |  | 
|---|
| 238 | /** | 
|---|
| 239 |  * @brief Finalizes an Object. This can be done outside of the Class. | 
|---|
| 240 |  */ | 
|---|
| 241 | void VertexArrayModel::finalize() | 
|---|
| 242 | { | 
|---|
| 243 |   // finalize the Arrays | 
|---|
| 244 |   this->newStripe(); | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 |  | 
|---|
| 248 |  | 
|---|
| 249 |  | 
|---|
| 250 | ///////////// | 
|---|
| 251 | // TESTING // | 
|---|
| 252 | ///////////// | 
|---|
| 253 | /** | 
|---|
| 254 | * @brief Includes a default model | 
|---|
| 255 | * | 
|---|
| 256 | * This will inject a Cube, because this is the most basic model. | 
|---|
| 257 | */ | 
|---|
| 258 | void VertexArrayModel::planeModel(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY) | 
|---|
| 259 | { | 
|---|
| 260 |   GLuint i, j; | 
|---|
| 261 |   for (i = 0; i < resolutionY; i++) | 
|---|
| 262 |     { | 
|---|
| 263 |       for (j = 0; j < resolutionX; j++) | 
|---|
| 264 |         { | 
|---|
| 265 |           this->addVertex( ((float)i - (float)resolutionX/2.0)/(float)resolutionX * sizeX, | 
|---|
| 266 |                             0.0, | 
|---|
| 267 |                             ((float)j - (float)resolutionY/2.0)/(float)resolutionY * sizeY); | 
|---|
| 268 |           this->addNormal(0.0, 1, 0.0); | 
|---|
| 269 |           this->addTexCoor((float)i/(float)resolutionX, (float)j/(float)resolutionY); | 
|---|
| 270 |           this->addColor(1.0, 1.0, 1.0); | 
|---|
| 271 |         } | 
|---|
| 272 |     } | 
|---|
| 273 |  | 
|---|
| 274 |   for (i = 0; i < resolutionY-1; i++) | 
|---|
| 275 |   { | 
|---|
| 276 |     for (j = 0; j < resolutionX; j++) | 
|---|
| 277 |     { | 
|---|
| 278 |       this->addIndice( resolutionY*i + j ); | 
|---|
| 279 |       this->addIndice( resolutionY*(i+1) + j ); | 
|---|
| 280 |     } | 
|---|
| 281 |     this->newStripe(); | 
|---|
| 282 |   } | 
|---|
| 283 | } | 
|---|
| 284 |  | 
|---|
| 285 | #include <cmath> | 
|---|
| 286 |  | 
|---|
| 287 | /** | 
|---|
| 288 |  * @brief builds a Triangle Stripped sphere | 
|---|
| 289 |  * @param radius: radius | 
|---|
| 290 |  * @param loops: the count of loops | 
|---|
| 291 |  * @param segmentsPerLoop how many Segments per loop | 
|---|
| 292 |  */ | 
|---|
| 293 | void VertexArrayModel::spiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop) | 
|---|
| 294 | { | 
|---|
| 295 |   for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber) | 
|---|
| 296 |   { | 
|---|
| 297 |     float theta = 0; | 
|---|
| 298 |     float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop; | 
|---|
| 299 |     float sinTheta = std::sin(theta); | 
|---|
| 300 |     float sinPhi = std::sin(phi); | 
|---|
| 301 |     float cosTheta = std::cos(theta); | 
|---|
| 302 |     float cosPhi = std::cos(phi); | 
|---|
| 303 |     this->addVertex(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta); | 
|---|
| 304 |     this->addNormal(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta); | 
|---|
| 305 |     this->addTexCoor(0,0); /// FIXME | 
|---|
| 306 |     this->addColor(.125,.436,.246); ///FIXME | 
|---|
| 307 |   } | 
|---|
| 308 |  | 
|---|
| 309 |   for (unsigned int loopNumber = 0; loopNumber <= loops; ++loopNumber) | 
|---|
| 310 |   { | 
|---|
| 311 |     for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber) | 
|---|
| 312 |     { | 
|---|
| 313 |       float theta = (loopNumber * PI / loops) + ((PI * loopSegmentNumber) / (segmentsPerLoop * loops)); | 
|---|
| 314 |       if (loopNumber == loops) | 
|---|
| 315 |       { | 
|---|
| 316 |         theta = PI; | 
|---|
| 317 |       } | 
|---|
| 318 |       float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop; | 
|---|
| 319 |       float sinTheta = std::sin(theta); | 
|---|
| 320 |       float sinPhi = std::sin(phi); | 
|---|
| 321 |       float cosTheta = std::cos(theta); | 
|---|
| 322 |       float cosPhi = std::cos(phi); | 
|---|
| 323 |       this->addVertex(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta); | 
|---|
| 324 |       this->addNormal(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta); | 
|---|
| 325 |       this->addTexCoor(0,0); //FIXME | 
|---|
| 326 |       this->addColor(.125,.436,.246); | 
|---|
| 327 |  | 
|---|
| 328 |     } | 
|---|
| 329 |   } | 
|---|
| 330 |  | 
|---|
| 331 |   for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber) | 
|---|
| 332 |   { | 
|---|
| 333 |     this->addIndice(loopSegmentNumber); | 
|---|
| 334 |     this->addIndice(segmentsPerLoop + loopSegmentNumber); | 
|---|
| 335 |   } | 
|---|
| 336 |  | 
|---|
| 337 |   for (unsigned int loopNumber = 0; loopNumber < loops; ++loopNumber) | 
|---|
| 338 |   { | 
|---|
| 339 |     for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber) | 
|---|
| 340 |     { | 
|---|
| 341 |       this->addIndice( ((loopNumber + 1) * segmentsPerLoop) + loopSegmentNumber); | 
|---|
| 342 |       this->addIndice( ((loopNumber + 2) * segmentsPerLoop) + loopSegmentNumber); | 
|---|
| 343 |     } | 
|---|
| 344 |   } | 
|---|
| 345 | } | 
|---|
| 346 |  | 
|---|
| 347 |  | 
|---|
| 348 | /** | 
|---|
| 349 |  * @brief print out some nice debug information about this VertexArrayModel. | 
|---|
| 350 |  */ | 
|---|
| 351 | void VertexArrayModel::debug() const | 
|---|
| 352 | { | 
|---|
| 353 |   PRINT(0)("VertexArrayModel (%s): debug\n", this->getName()); | 
|---|
| 354 |   PRINT(0)("Stripes: %d; Indices: %d; Vertices: %d; Normals %d; TextCoords %d; Colors %d\n", | 
|---|
| 355 |             this->stripes.size(), | 
|---|
| 356 |             this->indices.size(), | 
|---|
| 357 |             this->vertices.size(), | 
|---|
| 358 |             this->normals.size(), | 
|---|
| 359 |             this->texCoords.size(), | 
|---|
| 360 |             this->colors.size() ); | 
|---|
| 361 |   for (GLuint i = 1; i < this->stripes.size(); ++i) | 
|---|
| 362 |   { | 
|---|
| 363 |     PRINT(0)("Stripe-%d (s:%d:e:%d):: ", i, this->stripes[i-1], this->stripes[i]); | 
|---|
| 364 |     for (GLuint j = this->stripes[i-1] ; j < this->stripes[i]; j++) | 
|---|
| 365 |     { | 
|---|
| 366 |       PRINT(0)("->%d", this->indices[j]); | 
|---|
| 367 |     } | 
|---|
| 368 |     PRINT(0)("\n"); | 
|---|
| 369 |   } | 
|---|
| 370 | } | 
|---|