flModelOBJ.c

Go to the documentation of this file.
00001 #include "flGlobal.h"
00002 #if FL_MODEL_OBJ != 0
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <psprtc.h>
00006 
00007 #if FL_INCLUDE_ALL_C == 0
00008 #include "flModelOBJ.h"
00009 #include "flModel.h"
00010 #include "flMemory.h"
00011 #include "flMath.h"
00012 #include "flColor.h"
00013 #include "flFile.h"
00014 #include "flString.h"
00015 
00016 #include "flTexture.h"
00017 
00018 #if FL_DEBUG != 0
00019 #include "flDebug.h"
00020 #endif
00021 #endif
00022 
00023 bool mdl3dStatLoadOBJ_faceRead(u8* inFaceStr, Model3dStaticFace* inFacePtr, Model3dStatic* inModel, Texture* inCurTexture, int inVertPtr, int inTexVertPtr, int inNormPtr) {
00024      u8* tempLinePtr = inFaceStr;
00025      inFacePtr->mdlfVertCount = 0;
00026      while((tempLinePtr[0] != '\n') && (tempLinePtr[0] != 0)) {
00027           while((tempLinePtr[0] == ' ') || (tempLinePtr[0] == ASCII_TAB))
00028                tempLinePtr++;
00029           if((tempLinePtr[0] == '\n') || (tempLinePtr[0] == 0) || (tempLinePtr[0] == '\r'))
00030                break;
00031           inFacePtr->mdlfVertCount++;
00032           while((tempLinePtr[0] != ' ') && (tempLinePtr[0] != ASCII_TAB) && (tempLinePtr[0] != '\n') && (tempLinePtr[0] != 0))
00033                tempLinePtr++;
00034      }
00035      u8* tempBlockAlloc = memAlloc(sizeof(vect3f*) * inFacePtr->mdlfVertCount * 3);
00036      if(!tempBlockAlloc) {
00037           #if FL_DEBUG_WARNING != 0
00038           debugWarning("Couldn't read OBJ face data.\nProbably out of memory.");
00039           #endif
00040           return false;
00041      }
00042      memClear(tempBlockAlloc, (sizeof(vect3f*) * inFacePtr->mdlfVertCount * 3));
00043      inFacePtr->mdlfVerts = (vect3f**)&tempBlockAlloc[0]; //(vect3f**)tempBlockAlloc;
00044      inFacePtr->mdlfTexVerts = (vect2f**)&tempBlockAlloc[sizeof(vect3f*) * inFacePtr->mdlfVertCount]; //(vect2f**)((u32)tempBlockAlloc + (sizeof(vect3f*) * inFacePtr->mdlfVertCount));
00045      inFacePtr->mdlfNormals = (vect3f**)&tempBlockAlloc[(sizeof(vect3f*) << 1) * inFacePtr->mdlfVertCount]; //(vect3f**)((u32)tempBlockAlloc + ((sizeof(vect3f*) << 1) * inFacePtr->mdlfVertCount));
00046      tempLinePtr = inFaceStr;
00047      int i, tempIndex;
00048      for(i = (inFacePtr->mdlfVertCount - 1); i >= 0 ; i--) {
00049           while((tempLinePtr[0] == ' ') || (tempLinePtr[0] == ASCII_TAB) || (tempLinePtr[0] == '\r'))
00050                tempLinePtr++;
00051           if(tempLinePtr[0] == 0)
00052                return false;
00053           tempIndex = strToInt(tempLinePtr);
00054           if(tempLinePtr[0] == '-') {
00055                tempIndex += inVertPtr;
00056                tempLinePtr++;
00057           } else if(tempLinePtr[0] == '+') {
00058                tempIndex += (inVertPtr - 1);
00059                tempLinePtr++;
00060           } else {
00061                tempIndex -= 1;
00062           }
00063           if(tempIndex < 0) {
00064                #if FL_DEBUG_WARNING != 0
00065                debugWarning("Invalid obj file, contains reference to vertex < 1.");
00066                #endif
00067                return false;
00068           }
00069           inFacePtr->mdlfVerts[i] = &inModel->mdlVerts[tempIndex];
00070           while((tempLinePtr[0] >= '0') && (tempLinePtr[0] <= '9'))
00071                tempLinePtr++;
00072           if(tempLinePtr[0] == '/') {
00073                tempLinePtr++;
00074                if(tempLinePtr[0] != '/') {
00075                     tempIndex = strToInt(tempLinePtr);
00076                     if(tempLinePtr[0] == '-') {
00077                          tempIndex += inTexVertPtr;
00078                          tempLinePtr++;
00079                     } else if(tempLinePtr[0] == '+') {
00080                          tempIndex += (inTexVertPtr - 1);
00081                          tempLinePtr++;
00082                     } else {
00083                          tempIndex -= 1;
00084                     }
00085                     if(tempIndex < 0) {
00086                          #if FL_DEBUG_WARNING != 0
00087                          debugWarning("Invalid obj file, contains reference to texture vert < 1.");
00088                          #endif
00089                          return false;
00090                     }
00091                     inFacePtr->mdlfTexVerts[i] = &inModel->mdlTexVerts[tempIndex];
00092                     while((tempLinePtr[0] >= '0') && (tempLinePtr[0] <= '9'))
00093                          tempLinePtr++;
00094                } else { 
00095                     inFacePtr->mdlfTexVerts[i] = NULL;
00096                }
00097                if(tempLinePtr[0] == '/') {
00098                     tempLinePtr++;
00099                     tempIndex = strToInt(tempLinePtr);
00100                     if(tempLinePtr[0] == '-') {
00101                          tempIndex += inNormPtr;
00102                          tempLinePtr++;
00103                     } else if(tempLinePtr[0] == '+') {
00104                          tempIndex += (inNormPtr - 1);
00105                          tempLinePtr++;
00106                     } else {
00107                          tempIndex -= 1;
00108                     }
00109                     if(tempIndex < 0) {
00110                          #if FL_DEBUG_WARNING != 0
00111                          debugWarning("Invalid obj file, contains reference to normal < 1.");
00112                          #endif
00113                          return false;
00114                     }
00115                     inFacePtr->mdlfNormals[i] = &inModel->mdlNormals[tempIndex];
00116                     while((tempLinePtr[0] >= '0') && (tempLinePtr[0] <= '9'))
00117                          tempLinePtr++;
00118                     while(tempLinePtr[0] == '/') {
00119                          if((tempLinePtr[0] == '-') || (tempLinePtr[0] == '+'))
00120                               tempLinePtr++;                         
00121                          while((tempLinePtr[0] >= '0') && (tempLinePtr[0] <= '9'))
00122                               tempLinePtr++;
00123                     }
00124                } else {
00125                     inFacePtr->mdlfNormals[i] = NULL;
00126                }
00127           } else {
00128                inFacePtr->mdlfTexVerts[i] = NULL;
00129                inFacePtr->mdlfNormals[i] = NULL;
00130           }
00131      }
00132      inFacePtr->mdlfTexture = inCurTexture;
00133      return true;
00134 }
00135 
00136 Model3dStatic* mdl3dStatLoadOBJ(char* inPath) {
00137      if(!inPath || !fileExists(inPath)) {
00138           #if FL_DEBUG_WARNING != 0
00139           debugWarning("Cannot open OBJ file.");
00140           #endif
00141           return NULL;
00142      }
00143      
00144      #if FL_FILE != 0
00145      File* tempFile = fileOpen(inPath, FILE_MODE_READ);
00146      #else
00147      FILE* tempFile = fopen(inPath, "r");
00148      #endif
00149      
00150      Model3dStatic* tempOut = memAlloc(sizeof(Model3dStatic));
00151      if(!tempOut) {
00152           fileClose(tempFile);
00153           #if FL_DEBUG_WARNING != 0
00154           debugWarning("Couldn't create model struct.\nProbably out of memory.");
00155           #endif
00156           return NULL;
00157      }
00158      tempOut->mdlOptimized = false;
00159      tempOut->mdlTexVertCount = 0;
00160      tempOut->mdlVertCount = 0;
00161      tempOut->mdlTextureCount = 0;
00162      tempOut->mdlTexVertCount = 0;
00163      tempOut->mdlNormalCount = 0;
00164      tempOut->mdlFaceCount = 0;
00165      
00166      u8 tempLine[256];
00167      u8* tempLinePtr;
00168      
00169      while(fileGets((char*)tempLine, 256, tempFile)) {
00170           tempLinePtr = tempLine;
00171           while((tempLinePtr[0] == ' ') || (tempLinePtr[0] == ASCII_TAB))
00172                tempLinePtr++;
00173           if(strncmp((char*)tempLinePtr, "vt", 2) == 0)
00174                tempOut->mdlTexVertCount++;
00175           else if(strncmp((char*)tempLinePtr, "vn", 2) == 0)
00176                tempOut->mdlNormalCount++;
00177           else if(tempLinePtr[0] == 'v')
00178                tempOut->mdlVertCount++;
00179           else if(tempLinePtr[0] == 'f')
00180                tempOut->mdlFaceCount++;
00181           else if(strncmp((char*)tempLinePtr, "usemtl", 6) == 0)
00182                tempOut->mdlTextureCount++;
00183      }
00184      
00185      u32 tempSize = (sizeof(vect3f) * tempOut->mdlVertCount); 
00186      tempSize += (sizeof(vect2f) * tempOut->mdlTexVertCount);
00187      tempSize += (sizeof(vect3f) * tempOut->mdlNormalCount);
00188      tempSize += (sizeof(Model3dStaticFace) * tempOut->mdlFaceCount);
00189      tempSize += (sizeof(Texture*) * tempOut->mdlTextureCount);
00190      
00191      u8* tempAllocBlock = memAlloc(tempSize);
00192      if(!tempAllocBlock) {
00193           fileClose(tempFile);
00194           mdl3dStatFree(tempOut);
00195           #if FL_DEBUG_WARNING != 0
00196           debugWarning("Couldn't allocate model data.\nProbably out of memory.");
00197           #endif
00198           return NULL;
00199      }
00200      
00201      u32 tempOffset = 0;
00202      tempOut->mdlVerts = (vect3f*)&tempAllocBlock[tempOffset]; //(vect3f*)(tempAllocBlock);
00203      tempOffset += (sizeof(vect3f) * tempOut->mdlVertCount);
00204      tempOut->mdlTexVerts = (vect2f*)&tempAllocBlock[tempOffset]; //(vect2f*)((u32)(tempAllocBlock) + tempOffset);
00205      tempOffset += (sizeof(vect2f) * tempOut->mdlTexVertCount);
00206      tempOut->mdlNormals = (vect3f*)&tempAllocBlock[tempOffset]; //(vect3f*)((u32)(tempAllocBlock) + tempOffset);
00207      tempOffset += (sizeof(vect3f) * tempOut->mdlNormalCount);
00208      tempOut->mdlFaces = (Model3dStaticFace*)&tempAllocBlock[tempOffset]; //(Model3dStaticFace*)((u32)(tempAllocBlock) + tempOffset);
00209      tempOffset += (sizeof(Model3dStaticFace) * tempOut->mdlFaceCount);     
00210      tempOut->mdlTextures = (Texture**)&tempAllocBlock[tempOffset]; //(Texture**)((u32)(tempAllocBlock) + tempOffset);
00211      
00212      fileSeek(tempFile, 0, FILE_SEEK_SET);
00213      
00214      u32 tempVertPtr = 0;
00215      u32 tempTexVertPtr = 0;
00216      u32 tempNormPtr = 0;
00217      u32 tempFacePtr = 0;
00218      u32 tempTexPtr = 0;
00219      
00220      Texture* tempCurTexture = NULL;
00221      
00222      int tempLineNum = 0;
00223      while(fileGets((char*)tempLine, 256, tempFile)) {
00224           tempLineNum++;
00225           tempLinePtr = tempLine;
00226           while((tempLinePtr[0] == ' ') || (tempLinePtr[0] == ASCII_TAB))
00227                tempLinePtr++;
00228           if(strncmp((char*)tempLinePtr, "vt", 2) == 0) {
00229                tempLinePtr += 2;
00230                tempOut->mdlTexVerts[tempTexVertPtr] = strToVect2f(tempLinePtr);
00231                tempTexVertPtr++;
00232           } else if(strncmp((char*)tempLinePtr, "vn", 2) == 0) {
00233                tempLinePtr += 2;
00234                tempOut->mdlNormals[tempNormPtr] = strToVect3f(tempLinePtr);
00235                tempNormPtr++;
00236           } else if(tempLinePtr[0] == 'v') {
00237                tempLinePtr++;
00238                tempOut->mdlVerts[tempVertPtr] = strToVect3f(tempLinePtr);
00239                tempVertPtr++;
00240           } else if(tempLinePtr[0] == 'f') {
00241                tempLinePtr++;
00242                if(!mdl3dStatLoadOBJ_faceRead(tempLinePtr, &tempOut->mdlFaces[tempFacePtr],tempOut, tempCurTexture, (int)tempVertPtr, (int)tempTexVertPtr, (int)tempNormPtr)) {
00243                     fileClose(tempFile);
00244                     mdl3dStatFree(tempOut);
00245                     #if FL_DEBUG_WARNING != 0
00246                     char tempString[256];
00247                     sprintf(tempString, "Error reading face data on line %i while loading OBJ.", tempLineNum);
00248                     debugWarning(tempString);
00249                     #endif
00250                     return NULL;
00251                }
00252                tempFacePtr++;
00253           } else if(strncmp((char*)tempLinePtr, "usemtl", 6) == 0) {
00254                tempLinePtr += 6;
00255                while((tempLinePtr[0] == ' ') || (tempLinePtr[0] == ASCII_TAB))
00256                     tempLinePtr++;
00257                tempLine[strlen((char*)tempLine) - 1] = 0;
00258                tempOut->mdlTextures[tempTexPtr] = texLoad((char*)tempLinePtr);
00259                if(!tempOut->mdlTextures[tempTexPtr]) {
00260                     fileClose(tempFile);
00261                     mdl3dStatFree(tempOut);
00262                     #if FL_DEBUG_WARNING != 0
00263                     char tempString[256];
00264                     sprintf(tempString, "Error reading texture data on line %i while loading OBJ.", tempLineNum);
00265                     debugWarning(tempString);
00266                     #endif
00267                     return NULL;
00268                }
00269                tempLine[strlen((char*)tempLine) - 1] = '\n';
00270                tempCurTexture = tempOut->mdlTextures[tempTexPtr];
00271                tempTexPtr++;
00272           }
00273      }
00274 
00275      return tempOut;
00276 }
00277 
00278 bool mdl3dStatSaveOBJ(char* inPath, Model3dStatic* inModel) {
00279      #if FL_FILE != 0
00280      File* tempFile = fileOpen(inPath, FILE_MODE_WRITE);
00281      #else
00282      FILE* tempFile = fopen(inPath, "w");
00283      #endif
00284      
00285      if(!tempFile) {
00286           #if FL_DEBUG_WARNING != 0
00287           debugWarning("Couldn't open obj file for saving.");
00288           #endif
00289           return false;
00290      }
00291      
00292      char tempString[256];
00293      int i, j, k;
00294      pspTime tempTime;
00295      sceRtcGetCurrentClockLocalTime(&tempTime);
00296      
00297      #if FL_DEBUG_DATEFORMAT_AMERICAN != 0
00298      sprintf(tempString, "# Created by funcLib on %02i/%02i/%04i at %02i:%02i:%02i\n", tempTime.month, tempTime.day, tempTime.year, tempTime.hour, tempTime.minutes, tempTime.seconds);
00299      #else
00300      sprintf(tempString, "# Created by funcLib on %02i/%02i/%04i at %02i:%02i:%02i\n", tempTime.day, tempTime.month, tempTime.year, tempTime.hour, tempTime.minutes, tempTime.seconds);
00301      #endif
00302      filePuts(tempString, tempFile);
00303      sprintf(tempString, "# Verts: %i\n", (int)inModel->mdlVertCount);
00304      filePuts(tempString, tempFile);
00305      sprintf(tempString, "# TexCoords: %i\n", (int)inModel->mdlTexVertCount);
00306      filePuts(tempString, tempFile);
00307      sprintf(tempString, "# Normals: %i\n", (int)inModel->mdlNormalCount);
00308      filePuts(tempString, tempFile);
00309      sprintf(tempString, "# Materials: %i\n", (int)inModel->mdlTextureCount);
00310      filePuts(tempString, tempFile);
00311      sprintf(tempString, "# Faces: %i\n", (int)inModel->mdlFaceCount);
00312      filePuts(tempString, tempFile);
00313      j = 0;
00314      for(i = 0; i < inModel->mdlFaceCount; i++)
00315           j += (inModel->mdlFaces[i].mdlfVertCount - 2);
00316      sprintf(tempString, "# Triangles: %i\n", j);
00317      filePuts(tempString, tempFile);
00318 
00319      sprintf(tempString, "\n# Verteces\n");
00320      filePuts(tempString, tempFile);
00321      for(i = 0; i < inModel->mdlVertCount; i++) {
00322           sprintf(tempString, "v %f %f %f\n", inModel->mdlVerts[i].x, inModel->mdlVerts[i].y, inModel->mdlVerts[i].z);
00323           filePuts(tempString, tempFile);
00324      }
00325      
00326      sprintf(tempString, "\n# TexCoords\n");
00327      filePuts(tempString, tempFile);
00328      for(i = 0; i < inModel->mdlTexVertCount; i++) {
00329           sprintf(tempString, "vt %f %f\n", inModel->mdlTexVerts[i].x, inModel->mdlTexVerts[i].y);
00330           filePuts(tempString, tempFile);
00331      }
00332      
00333      sprintf(tempString, "\n# Normals\n");
00334      filePuts(tempString, tempFile);
00335      for(i = 0; i < inModel->mdlNormalCount; i++) {
00336           sprintf(tempString, "vn %f %f %f\n", inModel->mdlNormals[i].x, inModel->mdlNormals[i].y, inModel->mdlNormals[i].z);
00337           filePuts(tempString, tempFile);
00338      }
00339      
00340      sprintf(tempString, "\n# Faces\n");
00341      filePuts(tempString, tempFile);
00342      char tempStringAdd[256];
00343      u32 tempCurTexture = 0;
00344      for(i = 0; i < inModel->mdlFaceCount; i++) {
00345           if(inModel->mdlTextureCount > 0) {
00346                if(!tempCurTexture || (tempCurTexture != (unsigned int)inModel->mdlFaces[i].mdlfTexture)) {
00347                     sprintf(tempString, "usemtl %s\n", texPath(inModel->mdlFaces[i].mdlfTexture));
00348                     tempCurTexture = (unsigned int)inModel->mdlFaces[i].mdlfTexture;
00349                     filePuts(tempString, tempFile);
00350                }
00351           }
00352           tempString[0] = 'f';
00353           tempString[1] = 0;
00354           for(j = (inModel->mdlFaces[i].mdlfVertCount - 1); j >= 0 ; j--) {
00355                for(k = 0; k < inModel->mdlVertCount; k++) {
00356                     if(vect3f_Cmp(*inModel->mdlFaces[i].mdlfVerts[j], inModel->mdlVerts[k])) {
00357                          sprintf(tempStringAdd, " %i", (k + 1));
00358                          strcat(tempString, tempStringAdd);
00359                          break;
00360                     }
00361                }
00362                if(inModel->mdlFaces[i].mdlfTexVerts[j]) {
00363                     for(k = 0; k < inModel->mdlTexVertCount; k++) {
00364                          if(vect2f_Cmp(*inModel->mdlFaces[i].mdlfTexVerts[j], inModel->mdlTexVerts[k])) {
00365                               sprintf(tempStringAdd, "/%i", (k + 1));
00366                               strcat(tempString, tempStringAdd);
00367                               break;
00368                          }
00369                     }
00370                }
00371                if(inModel->mdlFaces[i].mdlfNormals[j]) {
00372                     if(!inModel->mdlFaces[i].mdlfTexVerts[j]) {
00373                          sprintf(tempStringAdd, "/");
00374                          strcat(tempString, tempStringAdd);
00375                     }
00376                     for(k = 0; k < inModel->mdlNormalCount; k++) {
00377                          if(vect2f_Cmp(*inModel->mdlFaces[i].mdlfNormals[j], inModel->mdlNormals[k])) {
00378                               sprintf(tempStringAdd, "/%i", (k + 1));
00379                               strcat(tempString, tempStringAdd);
00380                               break;
00381                          }
00382                     }
00383                }
00384           }
00385           filePuts(tempString, tempFile);
00386           filePuts("\n", tempFile);
00387      }
00388      
00389      sprintf(tempString, "\n# End of OBJ\n");
00390      filePuts(tempString, tempFile);
00391      
00392      fileClose(tempFile);
00393      
00394      return true;
00395 }
00396 
00397 #endif

Generated on Wed Sep 5 19:04:00 2007 for funcLib by  doxygen 1.5.1