Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/static_model_data.cc @ 10669

Last change on this file since 10669 was 10147, checked in by patrick, 18 years ago

merged the mount_point branche back to trunk to use the new std::* based obj file importer

File size: 23.6 KB
Line 
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   2005-07-06: (Patrick) added new function buildTriangleList()
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
19
20#include "static_model_data.h"
21
22#include "debug.h"
23#include <stdarg.h>
24#include <algorithm>
25
26
27
28////////////////////
29/// SUB-Elements ///
30////////////////////
31/**
32 * @brief creates a new ModelFaceElement
33 */
34StaticModelData::FaceElement::FaceElement()
35{
36  this->vertexNumber = -1;
37  this->normalNumber = -1;
38  this->texCoordNumber = -1;
39}
40
41
42/**
43 * @brief creates a new ModelFace
44 */
45StaticModelData::Face::Face()
46{
47  this->_material = NULL;
48}
49
50/**
51 * @brief Creates a new ModelGroup
52 */
53StaticModelData::Group::Group()
54{
55  PRINTF(4)("Adding new Group\n");
56  this->name = "";
57  this->faceMode = -1;
58  this->listNumber = 0;
59  this->indices = NULL;
60}
61
62/**
63 * @brief deletes a ModelGroup
64 */
65StaticModelData::Group::~Group()
66{
67  PRINTF(5)("Cleaning up group\n");
68  // deleting the glList
69  if (this->listNumber != 0)
70    glDeleteLists(this->listNumber, 1);
71}
72
73/**
74 * @brief cleans up a ModelGroup
75 *
76 * actually does the same as the delete Operator, but does not delete the predecessing group
77 */
78void StaticModelData::Group::cleanup()
79{
80  PRINTF(5)("Cleaning up group\n");
81  this->_faces.clear();
82}
83
84
85
86
87/////////////
88/// MODEL ///
89/////////////
90ObjectListDefinition(StaticModelData);
91
92/**
93 * @brief Creates a 3D-Model.
94 *
95 * assigns it a Name and a Type
96 */
97StaticModelData::StaticModelData(const std::string& modelName)
98{
99  this->registerObject(this, StaticModelData::_objectList);
100  PRINTF(4)("new 3D-Model is being created\n");
101  this->setName(modelName);
102
103  this->finalized = false;
104
105  // setting the start group;
106  this->_modelGroups.push_back(Group());
107  this->faceCount = 0;
108
109  this->scaleFactor = 1.0f;
110}
111
112/**
113 * @brief deletes an Model.
114 *
115 * Looks if any from model allocated space is still in use, and if so deleted it.
116 */
117StaticModelData::~StaticModelData()
118{
119  PRINTF(4)("Deleting Model %s\n", this->getCName());
120  this->cleanup();
121}
122
123/**
124 * @brief Finalizes an Object. This can be done outside of the Class.
125 */
126void StaticModelData::finalize()
127{
128  // this creates the display List.
129  this->importToDisplayList();
130  this->buildTriangleList();
131
132  this->finalized = true;
133}
134
135/**
136 * @brief rebuild the Model from the Information we got.
137 */
138void StaticModelData::rebuild()
139{
140  PRINTF(3)("Rebuilding Model '%s'\n", this->getCName());
141  this->finalize();
142}
143
144//////////
145// DRAW //
146//////////
147/**
148 * @brief Draws the Models of all Groups.
149 *
150 * It does this by just calling the Lists that must have been created earlier.
151 */
152void StaticModelData::draw () const
153{
154  PRINTF(4)("drawing the 3D-Models\n");
155
156  for(unsigned int i = 0; i < _modelGroups.size(); ++i )
157  {
158    PRINTF(5)("Drawing model %s\n", _modelGroups[i].name.c_str());
159    glCallList (_modelGroups[i].listNumber);
160  }
161}
162
163
164/**
165 * @brief Draws the Model number groupNumber
166 * @param groupNumber The number of the group that will be displayed.
167 *
168 * It does this by just calling the List that must have been created earlier.
169 */
170void StaticModelData::draw (unsigned int groupNumber) const
171{
172  if (unlikely(groupNumber >= _modelGroups.size()))
173  {
174    PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, _modelGroups.size());
175    return;
176  }
177  else
178  {
179    PRINTF(4)("Drawing model number %i named %s\n", groupNumber, _modelGroups[groupNumber].name.c_str());
180    glCallList (_modelGroups[groupNumber].listNumber);
181  }
182}
183
184
185/**
186 * @brief Draws the Model with a specific groupName
187 * @param groupName The name of the group that will be displayed.
188 *
189 * It does this by just calling the List that must have been created earlier.
190 */
191void StaticModelData::draw (const std::string& groupName) const
192{
193  PRINTF(4)("drawing the requested 3D-Models if found.\n");
194  std::vector<Group>::const_iterator it = std::find(_modelGroups.begin(), _modelGroups.end(), groupName);
195
196  if (it != _modelGroups.end())
197  {
198    PRINTF(4)("Drawing model %s\n", (*it).name.c_str());
199    glCallList ((*it).listNumber);
200  }
201  else
202  {
203    PRINTF(2)("Model Named %s in %s not Found.\n", groupName.c_str(), this->getCName());
204  }
205}
206
207//////////
208// INIT //
209//////////
210
211/**
212 * @brief finalizes an Model.
213 *
214 * This funcion is needed, to delete all the Lists, and arrays that are no more
215 * needed because they are already imported into openGL.
216 * This will be applied at the end of the importing Process.
217*/
218bool StaticModelData::cleanup()
219{
220  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
221  for (unsigned int i = 0; i < _modelGroups.size(); ++i)
222    _modelGroups[i].cleanup();
223  return true;
224}
225
226//////////
227// MESH //
228//////////
229/**
230 * @brief adds a new Material to the Material List
231 * @param material the Material to add
232 * @returns the added material
233 *
234 * this also tells this Model, that all the Materials are handled externally
235 * with this option set the Materials will not be deleted with the Model.
236 */
237Material* StaticModelData::addMaterial(const Material& material)
238{
239  this->materialList.push_back(material);
240  return &materialList.back();
241}
242
243/**
244 * @brief adds a new Material to the Material List
245 * @param materialName the name of the Material to add
246 * @returns the added material
247 */
248Material* StaticModelData::addMaterial(const std::string& materialName)
249{
250  // adding material to the List of materials
251  this->materialList.push_back(Material(materialName));
252  return &materialList.back();
253}
254
255/**
256 * @brief finds a Material by its name and returns it
257 * @param materialName the Name of the material to search for.
258 * @returns the Material if found, NULL otherwise
259 */
260Material* StaticModelData::findMaterialByName(const std::string& materialName)
261{
262  std::list<Material>::iterator it = std::find(materialList.begin(), materialList.end(), materialName);
263  if (it != materialList.end())
264    return &(*it);
265  else
266    return NULL;
267}
268
269/**
270 * @brief parses a group String
271 * @param groupString the new Group to create
272 *
273 * This function initializes a new Group.
274 * With it you should be able to create Models with more than one SubModel inside
275 */
276bool StaticModelData::addGroup(const std::string& groupString)
277{
278  PRINTF(4)("Read Group: %s.\n", groupString.c_str());
279  if (!_modelGroups.empty() && !_modelGroups.back()._faces.empty())
280    _modelGroups.push_back(Group());
281
282  _modelGroups.back().name = groupString;
283  return true;
284}
285
286/**
287 * @brief parses a vertex-String
288 * @param vertexString The String that will be parsed.
289 *
290 *  If a vertex line is found this function will inject it into the vertex-Array
291 */
292bool StaticModelData::addVertex (const std::string& vertexString)
293{
294  float subbuffer1;
295  float subbuffer2;
296  float subbuffer3;
297  sscanf (vertexString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
298  this->vertices.push_back(subbuffer1*scaleFactor);
299  this->vertices.push_back(subbuffer2*scaleFactor);
300  this->vertices.push_back(subbuffer3*scaleFactor);
301  return true;
302}
303
304/**
305 * @brief parses a vertex-String
306 * @param x the X-coordinate of the Vertex to add.
307 * @param y the Y-coordinate of the Vertex to add.
308 * @param z the Z-coordinate of the Vertex to add.
309 */
310bool StaticModelData::addVertex(float x, float y, float z)
311{
312  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
313  this->vertices.push_back(x*scaleFactor);
314  this->vertices.push_back(y*scaleFactor);
315  this->vertices.push_back(z*scaleFactor);
316  return true;
317}
318
319/**
320 * @brief parses a vertexNormal-String
321 * @param normalString The String that will be parsed.
322 *
323 * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
324 */
325bool StaticModelData::addVertexNormal (const std::string& normalString)
326{
327  float subbuffer1;
328  float subbuffer2;
329  float subbuffer3;
330  sscanf (normalString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
331  this->normals.push_back(subbuffer1);
332  this->normals.push_back(subbuffer2);
333  this->normals.push_back(subbuffer3);
334  return true;
335}
336
337/**
338 * @brief adds a VertexNormal.
339 * @param x The x coordinate of the Normal.
340 * @param y The y coordinate of the Normal.
341 * @param z The z coordinate of the Normal.
342 *
343 * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
344 */
345bool StaticModelData::addVertexNormal(float x, float y, float z)
346{
347  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
348  this->normals.push_back(x);
349  this->normals.push_back(y);
350  this->normals.push_back(z);
351  return true;
352}
353
354/**
355 * @brief parses a vertexTextureCoordinate-String
356 * @param vTextureString The String that will be parsed.
357 *
358 * If a vertexTextureCoordinate line is found,
359 * this function will inject it into the vertexTexture-Array
360 *
361 * !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
362 */
363bool StaticModelData::addVertexTexture (const std::string& vTextureString)
364{
365  float subbuffer1;
366  float subbuffer2;
367  sscanf (vTextureString.c_str(), "%f %f", &subbuffer1, &subbuffer2);
368  this->vTexture.push_back(subbuffer1);
369  this->vTexture.push_back(1 - subbuffer2);
370  return true;
371}
372
373/**
374 * @brief adds a Texture Coordinate
375 * @param u The u coordinate of the TextureCoordinate.
376 * @param v The y coordinate of the TextureCoordinate.
377 *
378 * If a TextureCoordinate line is found this function will
379 *  inject it into the TextureCoordinate-Array
380 */
381bool StaticModelData::addVertexTexture(float u, float v)
382{
383  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
384  this->vTexture.push_back(u);
385  this->vTexture.push_back(v);
386  return true;
387}
388
389/**
390 * @brief parses a face-string
391 * @param faceString The String that will be parsed.
392 *
393 * If a face line is found this function will add it to the glList.
394 *
395 * String is different from the argument addFace,
396 * in this, that the first Vertex/Normal/Texcoord is 1 instead of 0
397 *
398 * @TODO make it std::string conform
399 */
400bool StaticModelData::addFace (const std::string& faceStringInput)
401{
402  const char* faceString = faceStringInput.c_str();
403  Face newFace;
404
405  while(strcmp (faceString, "\0"))
406  {
407    FaceElement newElem;
408
409    char tmpValue [50];
410    int tmpLen;
411    char* vertex = NULL;
412    char* texture = NULL;
413    char* normal = NULL;
414
415    sscanf (faceString, "%s", tmpValue);
416    tmpLen = strlen(tmpValue);
417    vertex = tmpValue;
418
419    if ((texture = strstr (vertex, "/")) != NULL)
420    {
421      texture[0] = '\0';
422      texture ++;
423
424      if ((normal = strstr (texture, "/")) !=NULL)
425      {
426        normal[0] = '\0';
427        normal ++;
428      }
429    }
430    if (vertex)
431      newElem.vertexNumber = atoi(vertex)-1;
432    if (texture)
433      newElem.texCoordNumber = atoi(texture)-1;
434    if (normal)
435      newElem.normalNumber = atoi(normal)-1;
436
437    faceString += tmpLen;
438    if (strcmp (faceString, "\0"))
439      faceString++;
440
441    newFace._elements.push_back(newElem);
442  }
443
444  //this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
445  _modelGroups.back()._faces.push_back(newFace);
446  this->faceCount += newFace._elements.size() - 2;
447  return true;
448}
449
450/**
451 * @brief adds a new Face
452 * @param faceElemCount the number of Vertices to add to the Face.
453 * @param type The information Passed with each Vertex
454*/
455bool StaticModelData::addFace(int faceElemCount, VERTEX_FORMAT type, va_list args)
456{
457  Face newFace;
458
459  for (int i = 0; i < faceElemCount; i++)
460  {
461    FaceElement newElem;
462
463    newElem.vertexNumber = va_arg (args, int);
464    if (type & TEXCOORD)
465      newElem.texCoordNumber = va_arg (args, int);
466    if (type & NORMAL)
467      newElem.normalNumber = va_arg(args, int);
468
469    newFace._elements.push_back(newElem);
470  }
471
472  //this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
473  _modelGroups.back()._faces.push_back(newFace);
474  this->faceCount += newFace._elements.size() - 2;
475  return true;
476}
477
478/**
479 * Function that selects a material, if changed in the obj file.
480 * @param matString the Material that will be set.
481*/
482bool StaticModelData::setMaterial(const std::string& matString)
483{
484  Face matFace;
485  matFace._material = this->findMaterialByName(matString);
486  _modelGroups.back()._faces.push_back(matFace);
487
488  return true;
489}
490
491/**
492 * Function that selects a material, if changed in the obj file.
493 * @param mtl the Material that will be set.
494*/
495bool StaticModelData::setMaterial(Material* mtl)
496{
497  Face matFace;
498  matFace._material = mtl;
499  _modelGroups.back()._faces.push_back(matFace);
500
501  return true;
502}
503
504/**
505 * @brief A routine that is able to create normals.
506 *
507 * The algorithm does the following:
508 * 1. It calculates creates Vectors for each normale, and sets them to zero.
509 * 2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
510 * 3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
511 * 4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
512 */
513bool StaticModelData::buildVertexNormals ()
514{
515  PRINTF(4)("Normals are being calculated.\n");
516
517  Vector* normArray = new Vector [vertices.size()/3];
518  for (unsigned int i=0; i<vertices.size()/3;i++)
519    normArray[i] = Vector(.0,.0,.0);
520
521  Vector prevV;
522  Vector nextV;
523  Vector curV;
524
525  for (std::vector<Group>::iterator group = _modelGroups.begin();
526       group != _modelGroups.end();
527       ++group)
528  {
529    for (std::vector<Face>::iterator face = (*group)._faces.begin();
530         face != (*group)._faces.end();
531         ++face)
532    {
533      if (!(*face)._elements.empty())
534      {
535        std::vector<FaceElement>::iterator firstElem = (*face)._elements.begin();
536        std::vector<FaceElement>::iterator prevElem;
537        std::vector<FaceElement>::iterator curElem = firstElem;
538        std::vector<FaceElement>::iterator nextElem;
539        std::vector<FaceElement>::iterator lastElem;
540
541        // find last Element of the Chain.
542        while (curElem != (*face)._elements.end())
543        {
544          prevElem = curElem;
545          ++curElem;
546        }
547        lastElem = prevElem;
548
549        curElem = firstElem;
550        for (unsigned int j = 0; j < (*face)._elements.size(); j++)
551        {
552          nextElem = curElem;
553          nextElem++;
554          if (nextElem == (*face)._elements.end())
555            nextElem = firstElem;
556          (*curElem).normalNumber = (*curElem).vertexNumber;
557
558          curV = Vector (this->vertices[(*curElem).vertexNumber*3],
559                         this->vertices[(*curElem).vertexNumber*3+1],
560                         this->vertices[(*curElem).vertexNumber*3+2]);
561
562          prevV = Vector (this->vertices[(*prevElem).vertexNumber*3],
563                          this->vertices[(*prevElem).vertexNumber*3+1],
564                          this->vertices[(*prevElem).vertexNumber*3+2]) - curV;
565
566          nextV = Vector (this->vertices[(*nextElem).vertexNumber*3],
567                          this->vertices[(*nextElem).vertexNumber*3+1],
568                          this->vertices[(*nextElem).vertexNumber*3+2]) - curV;
569          normArray[(*curElem).vertexNumber] = normArray[(*curElem).vertexNumber] + nextV.cross(prevV);
570
571          prevElem = curElem;
572          ++curElem;
573        }
574      }
575    }
576  }
577
578  for (unsigned int i=0; i < this->vertices.size()/3;i++)
579  {
580    normArray[i].normalize();
581    PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
582
583    this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
584
585  }
586  delete[] normArray;
587  return true;
588}
589
590////////////
591// openGL //
592////////////
593/**
594 *  reads and includes the Faces/Materials into the openGL state Machine
595*/
596bool StaticModelData::importToDisplayList()
597{
598  // finalize the Arrays
599  if (normals.size() == 0) // vertices-Array must be built for this
600    this->buildVertexNormals();
601
602  for (std::vector<Group>::iterator group = _modelGroups.begin();
603       group != _modelGroups.end();
604       ++group)
605  {
606
607    // creating a glList for the Group
608    if (((*group).listNumber = glGenLists(1)) == 0)
609    {
610      PRINTF(2)("glList could not be created for this Model\n");
611      return false;
612    }
613    glNewList ((*group).listNumber, GL_COMPILE);
614
615    // Putting Faces to GL
616    for (std::vector<Face>::const_iterator face = (*group)._faces.begin();
617         face != (*group)._faces.end();
618         ++face)
619    {
620      if ((*face)._elements.empty() && (*face)._material != NULL)
621      {
622        if ((*group).faceMode != -1)
623          glEnd();
624        (*group).faceMode = 0;
625        if ((*face)._material != NULL)
626        {
627          (*face)._material->select();
628          PRINTF(5)("using material %s for coming Faces.\n", (*face)._material->getCName());
629        }
630      }
631
632      else if ((*face)._elements.size() == 3)
633      {
634        if ((*group).faceMode != 3)
635        {
636          if ((*group).faceMode != -1)
637            glEnd();
638          glBegin(GL_TRIANGLES);
639        }
640
641        (*group).faceMode = 3;
642        PRINTF(5)("found triag.\n");
643      }
644
645      else if ((*face)._elements.size() == 4)
646      {
647        if ((*group).faceMode != 4)
648        {
649          if ((*group).faceMode != -1)
650            glEnd();
651          glBegin(GL_QUADS);
652        }
653        (*group).faceMode = 4;
654        PRINTF(5)("found quad.\n");
655      }
656
657      else if ((*face)._elements.size() > 4)
658      {
659        if ((*group).faceMode != -1)
660          glEnd();
661        glBegin(GL_POLYGON);
662        PRINTF(5)("Polygon with %i faces found.", (*face)._elements.size());
663        (*group).faceMode = (*face)._elements.size();
664      }
665
666      for (std::vector<FaceElement>::const_iterator elem = (*face)._elements.begin();
667           elem != (*face)._elements.end();
668           ++elem)
669      {
670        //      PRINTF(2)("%s\n", (*elem).value);
671        this->addGLElement(*elem);
672      }
673    }
674    glEnd();
675    glEndList();
676
677  }
678  return true;
679}
680
681
682/**
683 *  builds an array of triangles, that can later on be used for obb separation and octree separation
684 */
685bool StaticModelData::buildTriangleList()
686{
687  if( unlikely(!this->triangles.empty()))
688    return true;
689  /* make sure, that all the arrays are finalized */
690  if( normals.size() == 0) // vertices-Array must be built for this
691    this->buildVertexNormals();
692
693  int                index = 0;                   //!< the counter for the triangle array
694  unsigned int numTriangles = 0;
695  bool warned = false;
696
697  /* count the number of triangles */
698  /* now iterate through all groups and build up the triangle list */
699  for (std::vector<Group>::iterator group = _modelGroups.begin();
700       group != _modelGroups.end();
701       ++group)
702  {
703    for (std::vector<Face>::const_iterator face = (*group)._faces.begin();
704         face != (*group)._faces.end();
705         ++face)
706    {
707      /* if its a triangle just add it to the list */
708      if( (*face)._elements.size() == 3)
709      {
710        ++numTriangles;
711      } /* if the polygon is a quad */
712      else if((*face)._elements.size() == 4)
713      {
714        numTriangles += 2;
715      }
716      else if( (*face)._elements.size() > 4)
717      {
718        if (!warned)
719        {
720          PRINTF(2)("This model (%s) got over 4 vertices per face <=> conflicts in the CD engine!\n", this->getCName());
721          warned = true;
722        }
723      }
724    }
725  }
726
727  PRINTF(3)("got %i triangles, %i vertices\n", numTriangles, this->vertices.size());
728
729
730  /* write MODELINFO structure */
731
732  /* allocate memory for the new triangle structures */
733  this->triangles.resize(numTriangles);
734
735  /* now iterate through all groups and build up the triangle list */
736  for (std::vector<Group>::iterator group = _modelGroups.begin();
737       group != _modelGroups.end();
738       ++group)
739  {
740    for (std::vector<Face>::const_iterator face = (*group)._faces.begin();
741         face != (*group)._faces.end();
742         ++face)
743    {
744      /* if its a triangle just add it to the list */
745      if( (*face)._elements.size() == 3)
746      {
747        unsigned int j = 0;
748        for (std::vector<FaceElement>::const_iterator elem = (*face)._elements.begin();
749             elem != (*face)._elements.end();
750             ++elem)
751        {
752          this->triangles[index].indexToVertices[j] = (unsigned int)(*elem).vertexNumber * 3;
753          this->triangles[index].indexToNormals[j] = (unsigned int)(*elem).normalNumber * 3;
754          this->triangles[index].indexToTexCoor[j] = (unsigned int)(*elem).texCoordNumber * 3;
755          ++j;
756        }
757        ++index;
758      } /* if the polygon is a quad */
759
760      else if( (*face)._elements.size() == 4)
761      {
762        std::vector<FaceElement>::const_iterator elem = (*face)._elements.begin();
763
764        this->triangles[index].indexToVertices[0] = (unsigned int)(*elem).vertexNumber * 3;
765        this->triangles[index].indexToNormals[0] = (unsigned int)(*elem).normalNumber * 3;
766        this->triangles[index].indexToTexCoor[0] = (unsigned int)(*elem).texCoordNumber * 3;
767
768        this->triangles[index + 1].indexToVertices[0] = (unsigned int)(*elem).vertexNumber * 3;
769        this->triangles[index + 1].indexToNormals[0] = (unsigned int)(*elem).normalNumber * 3;
770        this->triangles[index + 1].indexToTexCoor[0] = (unsigned int)(*elem).texCoordNumber * 3;
771        ++elem;
772
773        this->triangles[index].indexToVertices[1] = (unsigned int)(*elem).vertexNumber * 3;
774        this->triangles[index].indexToNormals[1] = (unsigned int)(*elem).normalNumber * 3;
775        this->triangles[index].indexToTexCoor[1] = (unsigned int)(*elem).texCoordNumber * 3;
776        ++elem;
777
778        this->triangles[index].indexToVertices[2] = (unsigned int)(*elem).vertexNumber * 3;
779        this->triangles[index].indexToNormals[2] = (unsigned int)(*elem).normalNumber * 3;
780        this->triangles[index].indexToTexCoor[2] = (unsigned int)(*elem).texCoordNumber * 3;
781
782        this->triangles[index + 1].indexToVertices[2] = (unsigned int)(*elem).vertexNumber * 3;
783        this->triangles[index + 1].indexToNormals[2] = (unsigned int)(*elem).normalNumber * 3;
784        this->triangles[index + 1].indexToTexCoor[2] = (unsigned int)(*elem).texCoordNumber * 3;
785        ++elem;
786
787        this->triangles[index + 1].indexToVertices[1] = (unsigned int)(*elem).vertexNumber * 3;
788        this->triangles[index + 1].indexToNormals[1] = (unsigned int)(*elem).normalNumber * 3;
789        this->triangles[index + 1].indexToTexCoor[1] = (unsigned int)(*elem).texCoordNumber * 3;
790
791        index += 2;
792      }
793    }
794  }
795  return true;
796}
797
798
799/**
800 *  Adds a Face-element (one vertex of a face) with all its information.
801 * @param elem The FaceElement to add to the OpenGL-environment.
802
803   It does this by searching:
804   1. The Vertex itself
805   2. The VertexNormale
806   3. The VertexTextureCoordinate
807   merging this information, the face will be drawn.
808*/
809bool StaticModelData::addGLElement (const FaceElement& elem)
810{
811  PRINTF(5)("importing grafical Element to openGL.\n");
812
813  if (elem.texCoordNumber > -1)
814  {
815    if (likely((unsigned int)elem.texCoordNumber < this->vTexture.size()))
816      glTexCoord2fv(&this->vTexture[0] + elem.texCoordNumber * 2);
817    else
818      PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
819                elem.texCoordNumber, this->vTexture.size());
820  }
821  if (elem.normalNumber > -1)
822  {
823    if (likely((unsigned int)elem.normalNumber < this->normals.size()))
824      glNormal3fv(&this->normals[0] + elem.normalNumber * 3);
825    else
826      PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
827                elem.normalNumber, this->normals.size());
828  }
829  if (elem.vertexNumber > -1)
830  {
831    if (likely((unsigned int)elem.vertexNumber < this->vertices.size()))
832      glVertex3fv(&this->vertices[0]+ elem.vertexNumber * 3);
833    else
834      PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
835                elem.vertexNumber, this->vertices.size());
836  }
837
838  return true;
839}
Note: See TracBrowser for help on using the repository browser.