Changeset 9830 in orxonox.OLD for branches/new_class_id/src/lib/graphics/importer/static_model.cc
- Timestamp:
- Sep 26, 2006, 2:54:38 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/new_class_id/src/lib/graphics/importer/static_model.cc
r9715 r9830 26 26 27 27 28 ////////////////////29 /// SUB-Elements ///30 ////////////////////31 /**32 * @brief creates a new ModelFaceElement33 */34 ModelFaceElement::ModelFaceElement()35 {36 this->vertexNumber = -1;37 this->normalNumber = -1;38 this->texCoordNumber = -1;39 40 this->next = NULL;41 }42 43 /**44 * @brief destroys a ModelFaceElement45 */46 ModelFaceElement::~ModelFaceElement()47 {48 if (this->next)49 delete this->next;50 }51 52 /**53 * @brief creates a new ModelFace54 */55 ModelFace::ModelFace()56 {57 this->vertexCount = 0;58 59 this->firstElem = NULL;60 61 this->material = NULL;62 63 this->next = NULL;64 }65 66 /**67 * deletes a ModelFace68 */69 ModelFace::~ModelFace()70 {71 PRINTF(5)("Cleaning up Face\n");72 73 if (this->firstElem != NULL)74 delete this->firstElem;75 76 if (this->next != NULL)77 delete this->next;78 }79 80 /**81 * @brief Creates a new ModelGroup82 */83 ModelGroup::ModelGroup()84 {85 PRINTF(4)("Adding new Group\n");86 this->name = "";87 this->faceMode = -1;88 this->faceCount = 0;89 this->next = NULL;90 this->listNumber = 0;91 this->indices = NULL;92 93 this->firstFace = new ModelFace;94 this->currentFace = this->firstFace;95 }96 97 /**98 * @brief deletes a ModelGroup99 */100 ModelGroup::~ModelGroup()101 {102 PRINTF(5)("Cleaning up group\n");103 if (this->firstFace != NULL)104 delete this->firstFace;105 106 // deleting the glList107 if (this->listNumber != 0)108 glDeleteLists(this->listNumber, 1);109 110 if (this->next !=NULL)111 delete this->next;112 113 }114 115 /**116 * @brief cleans up a ModelGroup117 *118 * actually does the same as the delete Operator, but does not delete the predecessing group119 */120 void ModelGroup::cleanup()121 {122 PRINTF(5)("Cleaning up group\n");123 if (this->firstFace)124 delete this->firstFace;125 this->firstFace = NULL;126 if (this->next)127 this->next->cleanup();128 }129 130 131 132 133 28 ///////////// 134 29 /// MODEL /// … … 142 37 */ 143 38 StaticModel::StaticModel(const std::string& modelName) 39 : data(new StaticModelData(modelName)) 144 40 { 145 41 this->registerObject(this, StaticModel::_objectList); 146 42 PRINTF(4)("new 3D-Model is being created\n"); 147 43 this->setName(modelName); 148 149 this->finalized = false;150 151 // setting the start group;152 this->currentGroup = this->firstGroup = new ModelGroup;153 this->groupCount = 0;154 this->faceCount = 0;155 156 this->scaleFactor = 1.0f;157 44 } 158 45 … … 165 52 { 166 53 PRINTF(4)("Deleting Model "); 167 if (!this->getName().empty())168 {169 PRINT(4)("%s\n", this->getCName());170 }171 else172 {173 PRINT(4)("\n");174 }175 this->cleanup();176 177 PRINTF(5)("Deleting display Lists.\n");178 delete this->firstGroup;179 180 // deleting the MaterialList181 PRINTF(5)("Deleting Materials.\n");182 183 //! @todo do we really have to delete this material??184 std::list<ModelMaterial*>::iterator modMat;185 for(modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)186 {187 if (!(*modMat)->external)188 delete (*modMat)->material;189 delete (*modMat);190 }191 54 192 55 // mark this stuff as beeing deleted … … 194 57 this->pModelInfo.pNormals = NULL; 195 58 this->pModelInfo.pTexCoor = NULL; 59 this->pModelInfo.pTriangles = NULL; 196 60 } 197 61 … … 201 65 void StaticModel::finalize() 202 66 { 203 // this creates the display List. 204 this->importToDisplayList(); 205 this->buildTriangleList(); 67 data->finalize(); 206 68 207 69 // write out the modelInfo data used for the collision detection! 208 this->pModelInfo.pVertices = &this->vertices[0]; 209 this->pModelInfo.pNormals = &this->normals[0]; 210 this->pModelInfo.pTexCoor = &this->vTexture[0]; 70 this->pModelInfo.pVertices = &this->data->getVertices()[0]; 71 this->pModelInfo.numVertices = this->data->getVertices().size(); 72 this->pModelInfo.pNormals = &this->data->getNormals()[0]; 73 this->pModelInfo.numNormals = this->data->getNormals().size(); 74 this->pModelInfo.pTexCoor = &this->data->getTexCoords()[0]; 75 this->pModelInfo.numTexCoor = this->data->getTexCoords().size(); 211 76 212 this->finalized = true; 213 } 214 215 /** 216 * @brief rebuild the Model from the Information we got. 217 */ 218 void StaticModel::rebuild() 219 { 220 PRINTF(3)("Rebuilding Model '%s'\n", this->getCName()); 221 this->finalize(); 222 } 223 224 ////////// 225 // DRAW // 226 ////////// 227 /** 228 * @brief Draws the Models of all Groups. 229 * 230 * It does this by just calling the Lists that must have been created earlier. 231 */ 232 void StaticModel::draw () const 233 { 234 PRINTF(4)("drawing the 3D-Models\n"); 235 ModelGroup* tmpGroup = this->firstGroup; 236 while (tmpGroup != NULL) 237 { 238 PRINTF(5)("Drawing model %s\n", tmpGroup->name.c_str()); 239 glCallList (tmpGroup->listNumber); 240 tmpGroup = tmpGroup->next; 241 } 242 } 243 244 245 /** 246 * @brief Draws the Model number groupNumber 247 * @param groupNumber The number of the group that will be displayed. 248 * 249 * It does this by just calling the List that must have been created earlier. 250 */ 251 void StaticModel::draw (int groupNumber) const 252 { 253 if (unlikely(groupNumber >= this->groupCount)) 254 { 255 PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount); 256 return; 257 } 258 PRINTF(4)("drawing the requested 3D-Models if found.\n"); 259 ModelGroup* tmpGroup = this->firstGroup; 260 int counter = 0; 261 while (tmpGroup != NULL) 262 { 263 if (counter == groupNumber) 264 { 265 PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name.c_str()); 266 glCallList (tmpGroup->listNumber); 267 return; 268 } 269 ++counter; 270 tmpGroup = tmpGroup->next; 271 } 272 PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getCName()); 273 return; 274 } 275 276 277 /** 278 * @brief Draws the Model with a specific groupName 279 * @param groupName The name of the group that will be displayed. 280 * 281 * It does this by just calling the List that must have been created earlier. 282 */ 283 void StaticModel::draw (const std::string& groupName) const 284 { 285 PRINTF(4)("drawing the requested 3D-Models if found.\n"); 286 ModelGroup* tmpGroup = this->firstGroup; 287 while (tmpGroup != NULL) 288 { 289 if (tmpGroup->name == groupName) 290 { 291 PRINTF(4)("Drawing model %s\n", tmpGroup->name.c_str()); 292 glCallList (tmpGroup->listNumber); 293 return; 294 } 295 tmpGroup = tmpGroup->next; 296 } 297 PRINTF(2)("Model Named %s in %s not Found.\n", groupName.c_str(), this->getCName()); 298 return; 299 } 300 301 ////////// 302 // INIT // 303 ////////// 304 305 /** 306 * @brief finalizes an Model. 307 * 308 * This funcion is needed, to delete all the Lists, and arrays that are no more 309 * needed because they are already imported into openGL. 310 * This will be applied at the end of the importing Process. 311 */ 312 bool StaticModel::cleanup() 313 { 314 PRINTF(4)("cleaning up the 3D-Model to save Memory.\n"); 315 this->firstGroup->cleanup(); 316 return true; 317 } 318 319 ////////// 320 // MESH // 321 ////////// 322 /** 323 * @brief adds a new Material to the Material List 324 * @param material the Material to add 325 * @returns the added material 326 * 327 * this also tells this Model, that all the Materials are handled externally 328 * with this option set the Materials will not be deleted with the Model. 329 */ 330 Material* StaticModel::addMaterial(Material* material) 331 { 332 if (material == NULL) 333 return NULL; 334 ModelMaterial* modMat = new ModelMaterial; 335 modMat->external = true; 336 modMat->material = material; 337 this->materialList.push_back(modMat); 338 return modMat->material; 339 } 340 341 /** 342 * @brief adds a new Material to the Material List 343 * @param materialName the name of the Material to add 344 * @returns the added material 345 */ 346 Material* StaticModel::addMaterial(const std::string& materialName) 347 { 348 ModelMaterial* modMat = new ModelMaterial; 349 modMat->external = false; 350 modMat->material = new Material(materialName); 351 352 // adding material to the List of materials 353 this->materialList.push_back(modMat); 354 return modMat->material; 355 } 356 357 /** 358 * @brief finds a Material by its name and returns it 359 * @param materialName the Name of the material to search for. 360 * @returns the Material if found, NULL otherwise 361 */ 362 Material* StaticModel::findMaterialByName(const std::string& materialName) 363 { 364 std::list<ModelMaterial*>::iterator modMat; 365 for (modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++) 366 if (materialName == (*modMat)->material->getName()) 367 return (*modMat)->material; 368 return NULL; 369 } 370 371 /** 372 * @brief parses a group String 373 * @param groupString the new Group to create 374 * 375 * This function initializes a new Group. 376 * With it you should be able to create Models with more than one SubModel inside 377 */ 378 bool StaticModel::addGroup(const std::string& groupString) 379 { 380 PRINTF(5)("Read Group: %s.\n", groupString.c_str()); 381 if (this->groupCount != 0 && this->currentGroup->faceCount > 0) 382 { 383 // finalizeGroup(currentGroup); 384 this->currentGroup = this->currentGroup->next = new ModelGroup; 385 } 386 // setting the group name if not default. 387 if (groupString == "default") 388 { 389 this->currentGroup->name = groupString; 390 } 391 ++this->groupCount; 392 return true; 393 } 394 395 /** 396 * @brief parses a vertex-String 397 * @param vertexString The String that will be parsed. 398 * 399 * If a vertex line is found this function will inject it into the vertex-Array 400 */ 401 bool StaticModel::addVertex (const std::string& vertexString) 402 { 403 float subbuffer1; 404 float subbuffer2; 405 float subbuffer3; 406 sscanf (vertexString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3); 407 this->vertices.push_back(subbuffer1*scaleFactor); 408 this->vertices.push_back(subbuffer2*scaleFactor); 409 this->vertices.push_back(subbuffer3*scaleFactor); 410 this->pModelInfo.numVertices++; 411 return true; 412 } 413 414 /** 415 * @brief parses a vertex-String 416 * @param x the X-coordinate of the Vertex to add. 417 * @param y the Y-coordinate of the Vertex to add. 418 * @param z the Z-coordinate of the Vertex to add. 419 */ 420 bool StaticModel::addVertex(float x, float y, float z) 421 { 422 PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z); 423 this->vertices.push_back(x*scaleFactor); 424 this->vertices.push_back(y*scaleFactor); 425 this->vertices.push_back(z*scaleFactor); 426 this->pModelInfo.numVertices++; 427 return true; 428 } 429 430 /** 431 * @brief parses a vertexNormal-String 432 * @param normalString The String that will be parsed. 433 * 434 * If a vertexNormal line is found this function will inject it into the vertexNormal-Array 435 */ 436 bool StaticModel::addVertexNormal (const std::string& normalString) 437 { 438 float subbuffer1; 439 float subbuffer2; 440 float subbuffer3; 441 sscanf (normalString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3); 442 this->normals.push_back(subbuffer1); 443 this->normals.push_back(subbuffer2); 444 this->normals.push_back(subbuffer3); 445 this->pModelInfo.numNormals++; 446 return true; 447 } 448 449 /** 450 * @brief adds a VertexNormal. 451 * @param x The x coordinate of the Normal. 452 * @param y The y coordinate of the Normal. 453 * @param z The z coordinate of the Normal. 454 * 455 * If a vertexNormal line is found this function will inject it into the vertexNormal-Array 456 */ 457 bool StaticModel::addVertexNormal(float x, float y, float z) 458 { 459 PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z); 460 this->normals.push_back(x); 461 this->normals.push_back(y); 462 this->normals.push_back(z); 463 this->pModelInfo.numNormals++; 464 return true; 465 } 466 467 /** 468 * @brief parses a vertexTextureCoordinate-String 469 * @param vTextureString The String that will be parsed. 470 * 471 * If a vertexTextureCoordinate line is found, 472 * this function will inject it into the vertexTexture-Array 473 * 474 * !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !! 475 */ 476 bool StaticModel::addVertexTexture (const std::string& vTextureString) 477 { 478 float subbuffer1; 479 float subbuffer2; 480 sscanf (vTextureString.c_str(), "%f %f", &subbuffer1, &subbuffer2); 481 this->vTexture.push_back(subbuffer1); 482 this->vTexture.push_back(1 - subbuffer2); 483 this->pModelInfo.numTexCoor++; 484 return true; 485 } 486 487 /** 488 * @brief adds a Texture Coordinate 489 * @param u The u coordinate of the TextureCoordinate. 490 * @param v The y coordinate of the TextureCoordinate. 491 * 492 * If a TextureCoordinate line is found this function will 493 * inject it into the TextureCoordinate-Array 494 */ 495 bool StaticModel::addVertexTexture(float u, float v) 496 { 497 PRINTF(5)("found vertex-Texture %f, %f\n", u, v); 498 this->vTexture.push_back(u); 499 this->vTexture.push_back(v); 500 this->pModelInfo.numTexCoor++; 501 return true; 502 } 503 504 /** 505 * @brief parses a face-string 506 * @param faceString The String that will be parsed. 507 * 508 * If a face line is found this function will add it to the glList. 509 * 510 * String is different from the argument addFace, 511 * in this, that the first Vertex/Normal/Texcoord is 1 instead of 0 512 * 513 * @TODO make it std::string conform 514 */ 515 bool StaticModel::addFace (const std::string& faceStringInput) 516 { 517 const char* faceString = faceStringInput.c_str(); 518 if (this->currentGroup->faceCount >0) 519 this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace; 520 521 ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement; 522 tmpElem->next = NULL; 523 while(strcmp (faceString, "\0")) 524 { 525 if (this->currentGroup->currentFace->vertexCount>0) 526 tmpElem = tmpElem->next = new ModelFaceElement; 527 tmpElem->next = NULL; 528 529 char tmpValue [50]; 530 int tmpLen; 531 char* vertex = NULL; 532 char* texture = NULL; 533 char* normal = NULL; 534 535 sscanf (faceString, "%s", tmpValue); 536 tmpLen = strlen(tmpValue); 537 vertex = tmpValue; 538 539 if ((texture = strstr (vertex, "/")) != NULL) 540 { 541 texture[0] = '\0'; 542 texture ++; 543 544 if ((normal = strstr (texture, "/")) !=NULL) 545 { 546 normal[0] = '\0'; 547 normal ++; 548 } 549 } 550 if (vertex) 551 tmpElem->vertexNumber = atoi(vertex)-1; 552 if (texture) 553 tmpElem->texCoordNumber = atoi(texture)-1; 554 if (normal) 555 tmpElem->normalNumber = atoi(normal)-1; 556 557 faceString += tmpLen; 558 if (strcmp (faceString, "\0")) 559 faceString++; 560 this->currentGroup->currentFace->vertexCount++; 561 } 562 563 this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2; 564 this->faceCount += this->currentGroup->currentFace->vertexCount -2; 565 return true; 77 this->pModelInfo.pTriangles = this->data->getTrianglesExt(); 78 this->pModelInfo.numTriangles = this->data->getTriangles().size(); 566 79 } 567 80 … … 573 86 bool StaticModel::addFace(int faceElemCount, VERTEX_FORMAT type, ...) 574 87 { 575 if (this->currentGroup->faceCount > 0)576 this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;577 578 ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;579 580 88 va_list itemlist; 581 89 va_start (itemlist, type); 582 583 for (int i = 0; i < faceElemCount; i++) 584 { 585 if (this->currentGroup->currentFace->vertexCount > 0) 586 tmpElem = tmpElem->next = new ModelFaceElement; 587 588 tmpElem->vertexNumber = va_arg (itemlist, int); 589 if (type & TEXCOORD) 590 tmpElem->texCoordNumber = va_arg (itemlist, int); 591 if (type & NORMAL) 592 tmpElem->normalNumber = va_arg(itemlist, int); 593 this->currentGroup->currentFace->vertexCount++; 594 } 90 bool retVal = this->data->addFace(faceElemCount, type, itemlist); 595 91 va_end(itemlist); 596 597 this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2; 598 this->faceCount += this->currentGroup->currentFace->vertexCount -2; 599 return true; 600 } 601 602 /** 603 * Function that selects a material, if changed in the obj file. 604 * @param matString the Material that will be set. 605 */ 606 bool StaticModel::setMaterial(const std::string& matString) 607 { 608 if (this->currentGroup->faceCount > 0) 609 this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace; 610 611 this->currentGroup->currentFace->material = this->findMaterialByName(matString); 612 613 if (this->currentGroup->faceCount == 0) 614 this->currentGroup->faceCount++; 615 return true; 616 } 617 618 /** 619 * Function that selects a material, if changed in the obj file. 620 * @param mtl the Material that will be set. 621 */ 622 bool StaticModel::setMaterial(Material* mtl) 623 { 624 if (this->currentGroup->faceCount > 0) 625 this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace; 626 627 this->currentGroup->currentFace->material = mtl; 628 629 if (this->currentGroup->faceCount == 0) 630 this->currentGroup->faceCount++; 631 return true; 632 } 633 634 /** 635 * @brief A routine that is able to create normals. 636 * 637 * The algorithm does the following: 638 * 1. It calculates creates Vectors for each normale, and sets them to zero. 639 * 2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements 640 * 3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal. 641 * 4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array. 642 */ 643 bool StaticModel::buildVertexNormals () 644 { 645 PRINTF(4)("Normals are being calculated.\n"); 646 647 Vector* normArray = new Vector [vertices.size()/3]; 648 for (unsigned int i=0; i<vertices.size()/3;i++) 649 normArray[i] = Vector(.0,.0,.0); 650 651 Vector prevV; 652 Vector nextV; 653 Vector curV; 654 655 ModelGroup* tmpGroup = firstGroup; 656 while (tmpGroup != NULL) 657 { 658 ModelFace* tmpFace = tmpGroup->firstFace; 659 while (tmpFace != NULL) 660 { 661 if (tmpFace->firstElem != NULL) 662 { 663 ModelFaceElement* firstElem = tmpFace->firstElem; 664 ModelFaceElement* prevElem; 665 ModelFaceElement* curElem = firstElem; 666 ModelFaceElement* nextElem; 667 ModelFaceElement* lastElem; 668 // find last Element of the Chain. !! IMPORTANT:the last Element of the Chain must point to NULL, or it will resolv into an infinity-loop. 669 while (curElem != NULL) 670 { 671 prevElem = curElem; 672 curElem = curElem->next; 673 } 674 lastElem = prevElem; 675 676 curElem = firstElem; 677 for (unsigned int j = 0; j < tmpFace->vertexCount; j++) 678 { 679 if (!(nextElem = curElem->next)) 680 nextElem = firstElem; 681 curElem->normalNumber = curElem->vertexNumber; 682 683 curV = Vector (this->vertices[curElem->vertexNumber*3], 684 this->vertices[curElem->vertexNumber*3+1], 685 this->vertices[curElem->vertexNumber*3+2]); 686 687 prevV = Vector (this->vertices[prevElem->vertexNumber*3], 688 this->vertices[prevElem->vertexNumber*3+1], 689 this->vertices[prevElem->vertexNumber*3+2]) - curV; 690 691 nextV = Vector (this->vertices[nextElem->vertexNumber*3], 692 this->vertices[nextElem->vertexNumber*3+1], 693 this->vertices[nextElem->vertexNumber*3+2]) - curV; 694 normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV); 695 696 prevElem = curElem; 697 curElem = curElem->next; 698 } 699 } 700 tmpFace = tmpFace->next; 701 } 702 tmpGroup = tmpGroup->next; 703 } 704 705 for (unsigned int i=0; i < this->vertices.size()/3;i++) 706 { 707 normArray[i].normalize(); 708 PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z); 709 710 this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z); 711 712 } 713 delete[] normArray; 714 return true; 715 } 716 717 //////////// 718 // openGL // 719 //////////// 720 /** 721 * reads and includes the Faces/Materials into the openGL state Machine 722 */ 723 bool StaticModel::importToDisplayList() 724 { 725 // finalize the Arrays 726 if (normals.size() == 0) // vertices-Array must be built for this 727 this->buildVertexNormals(); 728 729 this->currentGroup = this->firstGroup; 730 731 while (this->currentGroup != NULL) 732 { 733 734 // creating a glList for the Group 735 if ((this->currentGroup->listNumber = glGenLists(1)) == 0) 736 { 737 PRINTF(2)("glList could not be created for this Model\n"); 738 return false; 739 } 740 glNewList (this->currentGroup->listNumber, GL_COMPILE); 741 742 // Putting Faces to GL 743 ModelFace* tmpFace = this->currentGroup->firstFace; 744 while (tmpFace != NULL) 745 { 746 if (tmpFace->vertexCount == 0 && tmpFace->material != NULL) 747 { 748 if (this->currentGroup->faceMode != -1) 749 glEnd(); 750 this->currentGroup->faceMode = 0; 751 if (tmpFace->material != NULL) 752 { 753 tmpFace->material->select(); 754 PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getCName()); 755 } 756 } 757 758 else if (tmpFace->vertexCount == 3) 759 { 760 if (this->currentGroup->faceMode != 3) 761 { 762 if (this->currentGroup->faceMode != -1) 763 glEnd(); 764 glBegin(GL_TRIANGLES); 765 } 766 767 this->currentGroup->faceMode = 3; 768 PRINTF(5)("found triag.\n"); 769 } 770 771 else if (tmpFace->vertexCount == 4) 772 { 773 if (this->currentGroup->faceMode != 4) 774 { 775 if (this->currentGroup->faceMode != -1) 776 glEnd(); 777 glBegin(GL_QUADS); 778 } 779 this->currentGroup->faceMode = 4; 780 PRINTF(5)("found quad.\n"); 781 } 782 783 else if (tmpFace->vertexCount > 4) 784 { 785 if (this->currentGroup->faceMode != -1) 786 glEnd(); 787 glBegin(GL_POLYGON); 788 PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount); 789 this->currentGroup->faceMode = tmpFace->vertexCount; 790 } 791 792 ModelFaceElement* tmpElem = tmpFace->firstElem; 793 while (tmpElem != NULL) 794 { 795 // PRINTF(2)("%s\n", tmpElem->value); 796 this->addGLElement(tmpElem); 797 tmpElem = tmpElem->next; 798 } 799 tmpFace = tmpFace->next; 800 } 801 glEnd(); 802 glEndList(); 803 804 this->currentGroup = this->currentGroup->next; 805 } 806 return true; 807 } 808 809 810 /** 811 * builds an array of triangles, that can later on be used for obb separation and octree separation 812 */ 813 bool StaticModel::buildTriangleList() 814 { 815 if( unlikely(this->pModelInfo.pTriangles != NULL)) 816 return true; 817 /* make sure, that all the arrays are finalized */ 818 if( normals.size() == 0) // vertices-Array must be built for this 819 this->buildVertexNormals(); 820 821 int index = 0; //!< the counter for the triangle array 822 ModelFaceElement* tmpElem; //!< the temporary faceelement reference 823 ModelFace* tmpFace; //!< the temporary face referece 824 825 bool warned = false; 826 827 this->pModelInfo.numTriangles = 0; 828 829 /* count the number of triangles */ 830 /* now iterate through all groups and build up the triangle list */ 831 this->currentGroup = this->firstGroup; 832 while( this->currentGroup != NULL) 833 { 834 tmpFace = this->currentGroup->firstFace; 835 while( tmpFace != NULL) 836 { 837 /* if its a triangle just add it to the list */ 838 if( tmpFace->vertexCount == 3){ 839 ++this->pModelInfo.numTriangles; 840 } /* if the polygon is a quad */ 841 else if( tmpFace->vertexCount == 4) { 842 this->pModelInfo.numTriangles += 2; 843 } 844 else if( tmpFace->vertexCount > 4) { 845 if (!warned) { 846 PRINTF(2)("This model (%s) got over 4 vertices per face <=> conflicts in the CD engine!\n", this->getCName()); 847 warned = true; 848 } 849 } 850 tmpFace = tmpFace->next; 851 } 852 this->currentGroup = this->currentGroup->next; 853 } 854 855 PRINTF(3)("got %i triangles, %i vertices\n", this->pModelInfo.numTriangles, this->pModelInfo.numVertices); 856 857 858 /* write MODELINFO structure */ 859 860 /* allocate memory for the new triangle structures */ 861 if( (this->pModelInfo.pTriangles = new sTriangleExt[this->pModelInfo.numTriangles]) == NULL) 862 { 863 PRINTF(1)("Could not allocate memory for triangle list\n"); 864 return false; 865 } 866 867 /* now iterate through all groups and build up the triangle list */ 868 this->currentGroup = this->firstGroup; 869 while( this->currentGroup != NULL) 870 { 871 tmpFace = this->currentGroup->firstFace; 872 while( tmpFace != NULL) 873 { 874 tmpElem = tmpFace->firstElem; 875 876 /* if its a triangle just add it to the list */ 877 if( tmpFace->vertexCount == 3) 878 { 879 for( int j = 0; j < 3; ++j) 880 { 881 this->pModelInfo.pTriangles[index].indexToVertices[j] = (unsigned int)tmpElem->vertexNumber * 3 ; 882 this->pModelInfo.pTriangles[index].indexToNormals[j] = (unsigned int)tmpElem->normalNumber * 3 ; 883 this->pModelInfo.pTriangles[index].indexToTexCoor[j] = (unsigned int)tmpElem->texCoordNumber * 3 ; 884 tmpElem = tmpElem->next; 885 886 } 887 ++index; 888 } /* if the polygon is a quad */ 889 else if( tmpFace->vertexCount == 4) 890 { 891 892 this->pModelInfo.pTriangles[index].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber * 3; 893 this->pModelInfo.pTriangles[index].indexToNormals[0] = (unsigned int)tmpElem->normalNumber * 3; 894 this->pModelInfo.pTriangles[index].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber * 3; 895 896 this->pModelInfo.pTriangles[index + 1].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber * 3; 897 this->pModelInfo.pTriangles[index + 1].indexToNormals[0] = (unsigned int)tmpElem->normalNumber * 3; 898 this->pModelInfo.pTriangles[index + 1].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber * 3; 899 tmpElem = tmpElem->next; 900 901 this->pModelInfo.pTriangles[index].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber * 3; 902 this->pModelInfo.pTriangles[index].indexToNormals[1] = (unsigned int)tmpElem->normalNumber * 3; 903 this->pModelInfo.pTriangles[index].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber * 3; 904 tmpElem = tmpElem->next; 905 906 this->pModelInfo.pTriangles[index].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber * 3; 907 this->pModelInfo.pTriangles[index].indexToNormals[2] = (unsigned int)tmpElem->normalNumber * 3; 908 this->pModelInfo.pTriangles[index].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber * 3; 909 910 this->pModelInfo.pTriangles[index + 1].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber * 3; 911 this->pModelInfo.pTriangles[index + 1].indexToNormals[2] = (unsigned int)tmpElem->normalNumber * 3; 912 this->pModelInfo.pTriangles[index + 1].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber * 3; 913 tmpElem = tmpElem->next; 914 915 this->pModelInfo.pTriangles[index + 1].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber * 3; 916 this->pModelInfo.pTriangles[index + 1].indexToNormals[1] = (unsigned int)tmpElem->normalNumber * 3; 917 this->pModelInfo.pTriangles[index + 1].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber * 3; 918 919 index += 2; 920 } 921 tmpFace = tmpFace->next; 922 } 923 this->currentGroup = this->currentGroup->next; 924 } 925 return true; 926 } 927 928 929 /** 930 * Adds a Face-element (one vertex of a face) with all its information. 931 * @param elem The FaceElement to add to the OpenGL-environment. 932 933 It does this by searching: 934 1. The Vertex itself 935 2. The VertexNormale 936 3. The VertexTextureCoordinate 937 merging this information, the face will be drawn. 938 */ 939 bool StaticModel::addGLElement (ModelFaceElement* elem) 940 { 941 PRINTF(5)("importing grafical Element to openGL.\n"); 942 943 if (elem->texCoordNumber > -1) 944 { 945 if (likely((unsigned int)elem->texCoordNumber < this->pModelInfo.numTexCoor)) 946 glTexCoord2fv(&this->vTexture[0] + elem->texCoordNumber * 2); 947 else 948 PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n", 949 elem->texCoordNumber, this->pModelInfo.numTexCoor); 950 } 951 if (elem->normalNumber > -1) 952 { 953 if (likely((unsigned int)elem->normalNumber < this->pModelInfo.numNormals)) 954 glNormal3fv(&this->normals[0] + elem->normalNumber * 3); 955 else 956 PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete", 957 elem->normalNumber, this->pModelInfo.numNormals); 958 } 959 if (elem->vertexNumber > -1) 960 { 961 if (likely((unsigned int)elem->vertexNumber < this->pModelInfo.numVertices)) 962 glVertex3fv(&this->vertices[0]+ elem->vertexNumber * 3); 963 else 964 PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete", 965 elem->vertexNumber, this->pModelInfo.numVertices); 966 } 967 968 return true; 92 return retVal; 969 93 } 970 94 971 95 /** 972 96 * Includes a default model 973 974 975 */97 * 98 * This will inject a Cube, because this is the most basic model. 99 */ 976 100 void StaticModel::cubeModel() 977 101 {
Note: See TracChangeset
for help on using the changeset viewer.