Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/importer/model.cc @ 4682

Last change on this file since 4682 was 4677, checked in by bensch, 19 years ago

orxonox/trunk: possibility to return the count of faces of some Object

File size: 25.7 KB
RevLine 
[4577]1/*
[2823]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
[3590]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
17
[3360]18#include "model.h"
[3427]19
[3400]20#include <math.h>
[3418]21#include <stdarg.h>
[3398]22
[3473]23#include "vector.h"
[3911]24#include "list.h"
[3427]25
[3140]26using namespace std;
[2776]27
[4022]28
29////////////////////
30/// SUB-Elements ///
31////////////////////
[4023]32/**
33   \brief creates a new ModelFaceElement
34*/
[4022]35ModelFaceElement::ModelFaceElement()
[4038]36{
[4109]37  this->vertexNumber = -1;
38  this->normalNumber = -1;
[4577]39  this->texCoordNumber = -1;
[4109]40
[4038]41  this->next = NULL;
42}
[4022]43
[4023]44/**
45   \brief destroys a ModelFaceElement
46*/
[4022]47ModelFaceElement::~ModelFaceElement()
48{
[4038]49  if (this->next)
[4022]50    delete this->next;
51}
52
[4023]53/**
54   \brief creates a new ModelFace
55*/
[4022]56ModelFace::ModelFace()
57{
58  this->vertexCount = 0;
59
60  this->firstElem = NULL;
[4577]61
[4022]62  this->material = NULL;
[4577]63
[4022]64  this->next = NULL;
65
66}
67
[4023]68/**
69   \brief deletes a ModelFace
70*/
[4022]71ModelFace::~ModelFace()
72{
73  PRINTF(5)("Cleaning up Face\n");
74
75  if (this->firstElem != NULL)
[4038]76    delete this->firstElem;
[4577]77
[4022]78  if (this->next != NULL)
[4038]79    delete this->next;
[4022]80}
81
[4023]82/**
83   \brief Creates a new ModelGroup
84*/
[4022]85ModelGroup::ModelGroup()
86{
87  PRINTF(4)("Adding new Group\n");
88  this->name = "";
89  this->faceMode = -1;
[4577]90  this->faceCount = 0;
[4022]91  this->next = NULL;
[4577]92
[4022]93  this->firstFace = new ModelFace;
94  this->currentFace = this->firstFace;
95}
96
[4023]97/**
98   \brief deletes a ModelGroup
99*/
[4022]100ModelGroup::~ModelGroup()
101{
102  PRINTF(5)("Cleaning up group\n");
103  if (this->firstFace != NULL)
[4038]104    delete this->firstFace;
[4022]105
106  if (this->next !=NULL)
107    delete this->next;
108}
109
[4023]110/**
111   \brief cleans up a ModelGroup
112
113   actually does the same as the delete Operator, but does not delete the predecessing group
114*/
[4022]115void ModelGroup::cleanup(void)
116{
[4023]117  PRINTF(5)("Cleaning up group\n");
[4022]118  if (this->firstFace)
119    delete this->firstFace;
120  this->firstFace = NULL;
121  if (this->next)
122    this->next->cleanup();
123}
124
125
126/////////////
127/// MODEL ///
128/////////////
[2842]129/**
[4022]130   \brief Creates a 3D-Model.
131
132   assigns it a Name and a Type
[3398]133*/
[3916]134Model::Model(const char* modelName, MODEL_TYPE type)
[3398]135{
[4577]136  PRINTF(4)("new 3D-Model is being created\n");
[3398]137  this->setName(modelName);
[3916]138  this->type = type;
[3909]139
140  this->finalized = false;
141  // setting the start group;
[4022]142  this->currentGroup = this->firstGroup = new ModelGroup;
[3909]143  this->groupCount = 0;
[4106]144  this->vertexCount = 0;
145  this->normalCount = 0;
146  this->texCoordCount = 0;
[4677]147  this->faceCount = 0;
[4577]148
[3909]149  this->scaleFactor = 1;
150
[4579]151  this->vertices = new Array<GLfloat>();
152  this->vTexture = new Array<GLfloat>();
153  this->normals = new Array<GLfloat>();
[3909]154
[3911]155  this->materialList = new tList<Material>;
[3917]156
157  if (this->type == MODEL_VERTEX_ARRAY)
158    glEnableClientState(GL_VERTEX_ARRAY | GL_NORMAL_ARRAY | GL_TEXTURE_COORD_ARRAY);
[3398]159}
160
161/**
[3360]162   \brief deletes an Model.
[3186]163
[3360]164   Looks if any from model allocated space is still in use, and if so deleted it.
[2847]165*/
[3398]166Model::~Model(void)
[2847]167{
[3548]168  PRINTF(4)("Deleting Model ");
[4577]169  if (this->getName())
[3396]170    {
[4577]171      PRINT(4)("%s\n", this->getName());
[3396]172    }
173  else
[3548]174      PRINT(4)("\n");
[3396]175
[3911]176  PRINTF(5)("Deleting display Lists.\n");
[4038]177  delete this->firstGroup;
[3140]178
[4580]179  // deleting Arrays (if not allready done by finalize)
[3916]180  this->deleteArrays();
181
[3915]182  // deleting the MaterialList
[3911]183  PRINTF(5)("Deleting Materials.\n");
[3915]184  tIterator<Material>* tmpIt = this->materialList->getIterator();
185  Material* material = tmpIt->nextElement();
[4038]186
187  //! \todo do we really have to delete this material??
[3915]188  while(material)
189    {
190      delete material;
191      material = tmpIt->nextElement();
192    }
193  delete tmpIt;
[3911]194  delete materialList;
[2847]195}
196
[2842]197/**
[3398]198   \brief Finalizes an Object. This can be done outside of the Class.
199*/
200void Model::finalize(void)
201{
[3916]202  // this creates the display List.
203  this->importToDisplayList();
204
205  // deletes everything we allocated.
[4580]206  //if (this->type == MODEL_DISPLAY_LIST)
207    //this->deleteArrays();
[3398]208  this->cleanup();
209
210  this->finalized = true;
211}
212
[3912]213//////////
214// DRAW //
215//////////
[3398]216/**
[3360]217   \brief Draws the Models of all Groups.
[2851]218   It does this by just calling the Lists that must have been created earlier.
[2842]219*/
[3360]220void Model::draw (void) const
[2748]221{
[4577]222  PRINTF(4)("drawing the 3D-Models\n");
[4038]223  ModelGroup* tmpGroup = this->firstGroup;
224  while (tmpGroup != NULL)
[2850]225    {
[4038]226      PRINTF(5)("Drawing model %s\n", tmpGroup->name);
227      glCallList (tmpGroup->listNumber);
228      tmpGroup = tmpGroup->next;
[2850]229    }
[2748]230}
[2754]231
[2842]232/**
[3360]233   \brief Draws the Model number groupNumber
[3186]234   \param groupNumber The number of the group that will be displayed.
235
[2851]236   It does this by just calling the List that must have been created earlier.
237*/
[4577]238void Model::draw (int groupNumber) const
[2851]239{
[3195]240  if (groupNumber >= this->groupCount)
[2852]241    {
[3548]242      PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
[2852]243      return;
244    }
[4577]245  PRINTF(4)("drawing the requested 3D-Models if found.\n");
[4038]246  ModelGroup* tmpGroup = this->firstGroup;
[2851]247  int counter = 0;
[4038]248  while (tmpGroup != NULL)
[2851]249    {
250      if (counter == groupNumber)
[4577]251        {
252          PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name);
253          glCallList (tmpGroup->listNumber);
254          return;
255        }
[2851]256      ++counter;
[4038]257      tmpGroup = tmpGroup->next;
[2851]258    }
[4577]259  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getName());
[2851]260  return;
261
262}
[2852]263
264/**
[3360]265   \brief Draws the Model with a specific groupName
[3186]266   \param groupName The name of the group that will be displayed.
267
[2852]268   It does this by just calling the List that must have been created earlier.
269*/
[3360]270void Model::draw (char* groupName) const
[2851]271{
[4577]272  PRINTF(4)("drawing the requested 3D-Models if found.\n");
[4038]273  ModelGroup* tmpGroup = this->firstGroup;
274  while (tmpGroup != NULL)
[2851]275    {
[4038]276      if (!strcmp(tmpGroup->name, groupName))
[4577]277        {
278          PRINTF(4)("Drawing model %s\n", tmpGroup->name);
279          glCallList (tmpGroup->listNumber);
280          return;
281        }
[4038]282      tmpGroup = tmpGroup->next;
[2851]283    }
[4577]284  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->getName());
[2851]285  return;
286}
287
[3912]288//////////
289// INIT //
290//////////
[2851]291/**
[3916]292   \brief deletes all the arrays
[3066]293*/
[3916]294bool Model::deleteArrays(void)
[3066]295{
[3195]296  if (this->vertices)
297    delete this->vertices;
298  if (this->vTexture)
299    delete this->vTexture;
300  if (this->normals)
301    delete this->normals;
[4038]302
[3916]303  this->vertices = NULL;
304  this->vTexture = NULL;
305  this->normals = NULL;
306}
[3066]307
[3916]308/**
309   \brief finalizes an Model.
310   This funcion is needed, to delete all the Lists, and arrays that are no more needed because they are already imported into openGL. This will be applied at the end of the importing Process.
311*/
312bool Model::cleanup(void)
313{
314  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
[4022]315  this->firstGroup->cleanup();
[4577]316  return true;
[3066]317}
318
[3912]319//////////
320// MESH //
321//////////
[3068]322/**
[3913]323   \brief adds a new Material to the Material List
324   \param material the Material to add
325   \returns the added material
326
327   !! beware the Material will be deleted when the Model gets deleted
328*/
329Material* Model::addMaterial(Material* material)
330{
331  this->materialList->add(material);
332  return material;
333}
334
335/**
336   \brief adds a new Material to the Material List
[4023]337   \param materialName the name of the Material to add
[3913]338   \returns the added material
339*/
340Material* Model::addMaterial(const char* materialName)
341{
342  Material* newMat = new Material();
343  newMat->setName(materialName);
344
345  // adding material to the List of materials
[4577]346  this->materialList->add(newMat);
[3913]347  return newMat;
348}
349
[3914]350/**
351   \brief finds a Material by its name and returns it
352   \param materialName the Name of the material to search for.
353   \returns the Material if found, NULL otherwise
354*/
[3913]355Material* Model::findMaterialByName(const char* materialName)
356{
357  tIterator<Material>* tmpIt = this->materialList->getIterator();
358  Material* material = tmpIt->nextElement();
359  while(material)
360    {
361      if (!strcmp(material->getName(), materialName))
[4577]362        {
363          delete tmpIt;
364          return material;
365        }
[3913]366      material = tmpIt->nextElement();
367    }
368  delete tmpIt;
369  return NULL;
370}
371
372/**
[3066]373   \brief parses a group String
[3186]374   \param groupString the new Group to create
375
[4577]376   This function initializes a new Group.
[4022]377   With it you should be able to create Models with more than one SubModel inside
[3066]378*/
[4038]379bool Model::addGroup(const char* groupString)
[3066]380{
[3548]381  PRINTF(5)("Read Group: %s.\n", groupString);
[4022]382  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
[3066]383    {
384      //      finalizeGroup(currentGroup);
[4022]385      this->currentGroup = this->currentGroup->next = new ModelGroup;
[3066]386    }
[3140]387  // setting the group name if not default.
388  if (strcmp(groupString, "default"))
389    {
[3195]390      this->currentGroup->name = new char [strlen(groupString)+1];
391      strcpy(this->currentGroup->name, groupString);
[3140]392    }
[3195]393  ++this->groupCount;
[3066]394}
395
396/**
[2842]397   \brief parses a vertex-String
[3186]398   \param vertexString The String that will be parsed.
399
[2842]400   If a vertex line is found this function will inject it into the vertex-Array
401*/
[3909]402bool Model::addVertex (const char* vertexString)
[2767]403{
[3071]404  float subbuffer1;
405  float subbuffer2;
406  float subbuffer3;
407  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
[3548]408  PRINTF(5)("reading in a vertex: %f %f %f\n", &subbuffer1, &subbuffer2, &subbuffer3);
[3195]409  this->vertices->addEntry(subbuffer1*scaleFactor, subbuffer2*scaleFactor, subbuffer3*scaleFactor);
[4106]410  this->vertexCount++;
[2767]411  return true;
412}
413
[2842]414/**
[3400]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.
[4577]419
[3400]420*/
[3894]421bool Model::addVertex(float x, float y, float z)
[3400]422{
[3548]423  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
[3400]424  this->vertices->addEntry(x*scaleFactor, y*scaleFactor, z*scaleFactor);
[4106]425  this->vertexCount++;
[3400]426  return true;
427}
428
429/**
[3912]430   \brief parses a vertexNormal-String
431   \param normalString The String that will be parsed.
432
433   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
434*/
435bool Model::addVertexNormal (const char* normalString)
436{
437  float subbuffer1;
438  float subbuffer2;
439  float subbuffer3;
440  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
441  PRINTF(5)("found vertex-Normal %f, %f, %f\n", &subbuffer1,&subbuffer2,&subbuffer3);
442  this->normals->addEntry(subbuffer1, subbuffer2, subbuffer3);
[4106]443  this->normalCount++;
[3912]444  return true;
445}
446
447/**
448   \brief adds a VertexNormal.
449   \param x The x coordinate of the Normal.
450   \param y The y coordinate of the Normal.
451   \param z The z coordinate of the Normal.
452
453   If a vertexNormal line is found this function will inject it into the vertexNormal-Array
454*/
455bool Model::addVertexNormal(float x, float y, float z)
456{
457  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
458  this->normals->addEntry(x, y, z);
[4106]459  this->normalCount++;
460  return true;
[3912]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
[4357]469
470   !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
[3912]471*/
472bool Model::addVertexTexture (const char* vTextureString)
473{
474  float subbuffer1;
475  float subbuffer2;
476  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
477  PRINTF(5)("found vertex-Texture %f, %f\n", &subbuffer1, &subbuffer2);
478  this->vTexture->addEntry(subbuffer1);
[4357]479  this->vTexture->addEntry(1 - subbuffer2);
[4106]480  this->texCoordCount++;
[3912]481  return true;
482}
483
484/**
485   \brief adds a Texture Coordinate
486   \param u The u coordinate of the TextureCoordinate.
487   \param v The y coordinate of the TextureCoordinate.
488
489   If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
490*/
491bool Model::addVertexTexture(float u, float v)
492{
493  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
494  this->vTexture->addEntry(u);
495  this->vTexture->addEntry(v);
[4106]496  this->texCoordCount++;
497  return true;
[3912]498}
499
500/**
[2842]501   \brief parses a face-string
[3186]502   \param faceString The String that will be parsed.
503
[2842]504   If a face line is found this function will add it to the glList.
[4112]505
506   String is different from the argument addFace, in this that the first Vertex/Normal/Texcoord is 1 instead of 0
[2842]507*/
[3909]508bool Model::addFace (const char* faceString)
[2767]509{
[3195]510  if (this->currentGroup->faceCount >0)
[4022]511    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
[2767]512
[4022]513  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
[3068]514  tmpElem->next = NULL;
[2934]515  while(strcmp (faceString, "\0"))
[2767]516    {
[3195]517      if (this->currentGroup->currentFace->vertexCount>0)
[4577]518          tmpElem = tmpElem->next = new ModelFaceElement;
[2934]519      tmpElem->next = NULL;
520
[3064]521      char tmpValue [50];
[3072]522      int tmpLen;
523      char* vertex = NULL;
524      char* texture = NULL;
525      char* normal = NULL;
526
[3063]527      sscanf (faceString, "%s", tmpValue);
[3072]528      tmpLen = strlen(tmpValue);
529      vertex = tmpValue;
[2934]530
[3072]531      if ((texture = strstr (vertex, "/")) != NULL)
[4577]532        {
533          texture[0] = '\0';
534          texture ++;
535
536          if ((normal = strstr (texture, "/")) !=NULL)
537            {
538              normal[0] = '\0';
539              normal ++;
540            }
541        }
[3072]542      if (vertex)
[4577]543        tmpElem->vertexNumber = atoi(vertex)-1;
[3072]544      if (texture)
[4577]545        tmpElem->texCoordNumber = atoi(texture)-1;
[3072]546      if (normal)
[4577]547        tmpElem->normalNumber = atoi(normal)-1;
[3072]548
549      faceString += tmpLen;
[2934]550      if (strcmp (faceString, "\0"))
[4577]551        faceString++;
[3195]552      this->currentGroup->currentFace->vertexCount++;
[2934]553    }
554
[3195]555  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
[4677]556  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
[2754]557}
[2768]558
[2842]559/**
[3418]560   \brief adds a new Face
561   \param faceElemCount the number of Vertices to add to the Face.
[4112]562   \param type The information Passed with each Vertex
[3400]563*/
[3895]564bool Model::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
[3400]565{
[4022]566  if (this->currentGroup->faceCount > 0)
567    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
[4577]568
[4022]569  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
[4577]570
[3418]571  va_list itemlist;
572  va_start (itemlist, type);
573
574  for (int i = 0; i < faceElemCount; i++)
575    {
[4106]576      if (this->currentGroup->currentFace->vertexCount > 0)
[4577]577        tmpElem = tmpElem->next = new ModelFaceElement;
[3418]578
[4112]579      tmpElem->vertexNumber = va_arg (itemlist, int);
[3657]580      if (type & TEXCOORD)
[4577]581        tmpElem->texCoordNumber = va_arg (itemlist, int);
[3657]582      if (type & NORMAL)
[4577]583        tmpElem->normalNumber = va_arg(itemlist, int);
[3418]584      this->currentGroup->currentFace->vertexCount++;
585    }
586  va_end(itemlist);
587
588  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
[4677]589  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
[3400]590}
591
592/**
[3066]593   \brief Function that selects a material, if changed in the obj file.
594   \param matString the Material that will be set.
595*/
[3913]596bool Model::setMaterial(const char* matString)
[3063]597{
[3801]598  if (this->currentGroup->faceCount > 0)
[4022]599    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
[4577]600
[3914]601  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
[3801]602
603  if (this->currentGroup->faceCount == 0)
604    this->currentGroup->faceCount ++;
605}
606
607/**
608   \brief Function that selects a material, if changed in the obj file.
609   \param mtl the Material that will be set.
610*/
[3913]611bool Model::setMaterial(Material* mtl)
[3801]612{
613  if (this->currentGroup->faceCount > 0)
[4022]614    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
[4577]615
[3801]616  this->currentGroup->currentFace->material = mtl;
617
[3195]618  if (this->currentGroup->faceCount == 0)
619    this->currentGroup->faceCount ++;
[3063]620}
621
[3066]622/**
[3912]623   \brief A routine that is able to create normals.
624
625   The algorithm does the following:
626   1. It calculates creates Vectors for each normale, and sets them to zero.
627   2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
628   3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
629   4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
630*/
631bool Model::buildVertexNormals ()
[4577]632{
[3912]633  PRINTF(4)("Normals are being calculated.\n");
634
635  Vector* normArray = new Vector [vertices->getCount()/3];
636  for (int i=0; i<vertices->getCount()/3;i++)
637    normArray[i] = Vector(.0,.0,.0);
[4577]638
[3912]639  int firstTouch;
640  int secondTouch;
641  Vector prevV;
642  Vector nextV;
643  Vector curV;
644
[4022]645  ModelGroup* tmpGroup = firstGroup;
[3912]646  while (tmpGroup)
647    {
[4022]648      ModelFace* tmpFace = tmpGroup->firstFace;
[3912]649      while (tmpFace)
[4577]650        {
651          if (tmpFace->firstElem)
652            {
653              ModelFaceElement* firstElem = tmpFace->firstElem;
654              ModelFaceElement* prevElem;
655              ModelFaceElement* curElem = firstElem;
656              ModelFaceElement* nextElem;
657              ModelFaceElement* lastElem;
658              // 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.
659              while (curElem)
660                {
661                  prevElem = curElem;
662                  curElem = curElem->next;
663                }
664              lastElem = prevElem;
[3912]665
[4577]666              curElem = firstElem;
667              for (int j=0; j<tmpFace->vertexCount; j++)
668                {
669                  if (!(nextElem = curElem->next))
670                    nextElem = firstElem;
671                  curElem->normalNumber = curElem->vertexNumber;
672
673                  curV = Vector (vertices->getArray()[curElem->vertexNumber*3], vertices->getArray()[curElem->vertexNumber*3+1], vertices->getArray()[curElem->vertexNumber*3+2]);
674                  prevV = Vector (vertices->getArray()[prevElem->vertexNumber*3], vertices->getArray()[prevElem->vertexNumber*3+1], vertices->getArray()[prevElem->vertexNumber*3+2]) - curV;
675                  nextV = Vector (vertices->getArray()[nextElem->vertexNumber*3], vertices->getArray()[nextElem->vertexNumber*3+1], vertices->getArray()[nextElem->vertexNumber*3+2]) - curV;
676                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
677
678                  prevElem = curElem;
679                  curElem = curElem->next;
680                }
681            }
682          tmpFace = tmpFace->next;
683        }
[3912]684      tmpGroup = tmpGroup->next;
685    }
686
[4108]687  for (int i=0; i < vertices->getCount()/3;i++)
[3912]688    {
689      normArray[i].normalize();
690      PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
[4577]691
[4108]692      this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
[3912]693
694    }
[4577]695  delete []normArray;
[3912]696}
697
698////////////
699// openGL //
700////////////
701/**
[3066]702   \brief reads and includes the Faces/Materials into the openGL state Machine
703*/
[3916]704bool Model::importToDisplayList(void)
[3063]705{
706  // finalize the Arrays
[3195]707  this->vertices->finalizeArray();
708  this->vTexture->finalizeArray();
[3426]709  if (normals->getCount() == 0) // vertices-Array must be built for this
[3195]710    this->buildVertexNormals();
711  this->normals->finalizeArray();
[3063]712
[3195]713  this->currentGroup = this->firstGroup;
[3063]714
[3195]715  while (this->currentGroup != NULL)
[3063]716    {
717
718      // creating a glList for the Group
[3195]719      if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
[4577]720        {
721          PRINTF(2)("glList could not be created for this Model\n");
722          return false;
723        }
[3195]724      glNewList (this->currentGroup->listNumber, GL_COMPILE);
[3063]725
726      // Putting Faces to GL
[4022]727      ModelFace* tmpFace = this->currentGroup->firstFace;
[3063]728      while (tmpFace != NULL)
[4577]729        {
730          if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
731            {
732              if (this->currentGroup->faceMode != -1)
733                glEnd();
734              this->currentGroup->faceMode = 0;
735              Material* tmpMat;
736              if (tmpFace->material != NULL)
737                {
738                  tmpFace->material->select();
739                  PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getName());
740                }
741            }
[3065]742
[4577]743          else if (tmpFace->vertexCount == 3)
744            {
745              if (this->currentGroup->faceMode != 3)
746                {
747                  if (this->currentGroup->faceMode != -1)
748                    glEnd();
749                  glBegin(GL_TRIANGLES);
750                }
751
752              this->currentGroup->faceMode = 3;
753              PRINTF(5)("found triag.\n");
754            }
755
756          else if (tmpFace->vertexCount == 4)
757            {
758              if (this->currentGroup->faceMode != 4)
759                {
760                  if (this->currentGroup->faceMode != -1)
761                    glEnd();
762                  glBegin(GL_QUADS);
763                }
764              this->currentGroup->faceMode = 4;
765              PRINTF(5)("found quad.\n");
766            }
767
768          else if (tmpFace->vertexCount > 4)
769            {
770              if (this->currentGroup->faceMode != -1)
771                glEnd();
772              glBegin(GL_POLYGON);
773              PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
774              this->currentGroup->faceMode = tmpFace->vertexCount;
775            }
776
777          ModelFaceElement* tmpElem = tmpFace->firstElem;
778          while (tmpElem != NULL)
779            {
780              //      PRINTF(2)("%s\n", tmpElem->value);
781              this->addGLElement(tmpElem);
782              tmpElem = tmpElem->next;
783            }
784          tmpFace = tmpFace->next;
785        }
[3063]786      glEnd();
787      glEndList();
[3195]788
789      this->currentGroup = this->currentGroup->next;
[4577]790    }
[3063]791}
792
[3066]793/**
[3916]794   \brief reads and includes the Faces/Materials into the openGL state Machine
795*/
796bool Model::importToVertexArray(void)
797{
798  // finalize the Arrays
799  this->vertices->finalizeArray();
800  this->vTexture->finalizeArray();
801  if (normals->getCount() == 0) // vertices-Array must be built for this
802    this->buildVertexNormals();
803  this->normals->finalizeArray();
804
805  this->currentGroup = this->firstGroup;
[3917]806  glVertexPointer(3, GL_FLOAT, 0, this->vertices->getArray());
807  glNormalPointer(3, 0, this->normals->getArray());
808  glTexCoordPointer(2, GL_FLOAT, 0, this->vTexture->getArray());
[3916]809}
810
811
812
813/**
[4577]814   \brief Adds a Face-element (one vertex of a face) with all its information.
[3186]815   \param elem The FaceElement to add to the OpenGL-environment.
816
[3066]817   It does this by searching:
818   1. The Vertex itself
819   2. The VertexNormale
820   3. The VertexTextureCoordinate
821   merging this information, the face will be drawn.
[2842]822*/
[4022]823bool Model::addGLElement (ModelFaceElement* elem)
[2776]824{
[3548]825  PRINTF(5)("importing grafical Element to openGL.\n");
[3066]826
[3073]827  if (elem->texCoordNumber != -1)
[4108]828    {
[4109]829      if (likely(elem->texCoordNumber < this->texCoordCount))
[4577]830        glTexCoord2fv(this->vTexture->getArray() + elem->texCoordNumber * 2);
[4108]831      else
[4577]832        PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
833                  elem->texCoordNumber, this->texCoordCount);
[4108]834    }
[3073]835  if (elem->normalNumber != -1)
[4108]836    {
[4109]837    if (likely(elem->normalNumber < this->normalCount))
[4108]838      glNormal3fv(this->normals->getArray() + elem->normalNumber * 3);
839    else
[4577]840        PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
841                  elem->normalNumber, this->normalCount);
[4108]842    }
[3073]843  if (elem->vertexNumber != -1)
[4108]844    {
[4110]845      if (likely(elem->vertexNumber < this->vertexCount))
[4577]846          glVertex3fv(this->vertices->getArray() + elem->vertexNumber * 3);
[4108]847      else
[4577]848        PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
849                  elem->vertexNumber, this->vertexCount);
850    }
[4108]851
[2776]852}
853
[3079]854/**
[3360]855   \brief Includes a default model
[3186]856
[3360]857   This will inject a Cube, because this is the most basic model.
[2842]858*/
[3400]859void Model::cubeModel(void)
[2821]860{
[3656]861  this->addVertex (-0.5, -0.5, 0.5);
862  this->addVertex (0.5, -0.5, 0.5);
863  this->addVertex (-0.5, 0.5, 0.5);
864  this->addVertex (0.5, 0.5, 0.5);
865  this->addVertex (-0.5, 0.5, -0.5);
866  this->addVertex (0.5, 0.5, -0.5);
867  this->addVertex (-0.5, -0.5, -0.5);
868  this->addVertex (0.5, -0.5, -0.5);
[2967]869
[3656]870  this->addVertexTexture (0.0, 0.0);
871  this->addVertexTexture (1.0, 0.0);
872  this->addVertexTexture (0.0, 1.0);
873  this->addVertexTexture (1.0, 1.0);
874  this->addVertexTexture (0.0, 2.0);
875  this->addVertexTexture (1.0, 2.0);
876  this->addVertexTexture (0.0, 3.0);
877  this->addVertexTexture (1.0, 3.0);
878  this->addVertexTexture (0.0, 4.0);
879  this->addVertexTexture (1.0, 4.0);
880  this->addVertexTexture (2.0, 0.0);
881  this->addVertexTexture (2.0, 1.0);
882  this->addVertexTexture (-1.0, 0.0);
883  this->addVertexTexture (-1.0, 1.0);
[3081]884
[3656]885  this->addVertexNormal (0.0, 0.0, 1.0);
886  this->addVertexNormal (0.0, 0.0, 1.0);
887  this->addVertexNormal (0.0, 0.0, 1.0);
888  this->addVertexNormal (0.0, 0.0, 1.0);
889  this->addVertexNormal (0.0, 1.0, 0.0);
890  this->addVertexNormal (0.0, 1.0, 0.0);
891  this->addVertexNormal (0.0, 1.0, 0.0);
892  this->addVertexNormal (0.0, 1.0, 0.0);
893  this->addVertexNormal (0.0, 0.0, -1.0);
894  this->addVertexNormal (0.0, 0.0, -1.0);
895  this->addVertexNormal (0.0, 0.0, -1.0);
896  this->addVertexNormal (0.0, 0.0, -1.0);
897  this->addVertexNormal (0.0, -1.0, 0.0);
898  this->addVertexNormal (0.0, -1.0, 0.0);
899  this->addVertexNormal (0.0, -1.0, 0.0);
900  this->addVertexNormal (0.0, -1.0, 0.0);
901  this->addVertexNormal (1.0, 0.0, 0.0);
902  this->addVertexNormal (1.0, 0.0, 0.0);
903  this->addVertexNormal (1.0, 0.0, 0.0);
904  this->addVertexNormal (1.0, 0.0, 0.0);
905  this->addVertexNormal (-1.0, 0.0, 0.0);
906  this->addVertexNormal (-1.0, 0.0, 0.0);
907  this->addVertexNormal (-1.0, 0.0, 0.0);
908  this->addVertexNormal (-1.0, 0.0, 0.0);
[2821]909
[4112]910  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3);
911  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7);
912  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11);
913  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15);
914  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19);
915  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23);
[3081]916
[2821]917}
Note: See TracBrowser for help on using the repository browser.