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