flModelMD2.c

Go to the documentation of this file.
00001 #include "flGlobal.h"
00002 #if FL_MODEL_MD2 != 0
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <psprtc.h>
00006 
00007 #if FL_INCLUDE_ALL_C == 0
00008 #include "flModelMD2.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 typedef struct {
00024      char md2Ident[4];
00025      int  md2Version;
00026      int  md2SkinWidth;
00027      int  md2SkinHeight;
00028      int  md2FrameSize;
00029      
00030      int  md2TextureCount;
00031      int  md2VertCount;
00032      int  md2TexVertCount;
00033      int  md2TriCount;
00034      int  md2GlCmdCount;
00035      int  md2FrameCount;
00036 
00037      int  md2TextureOffset;
00038      int  md2TexVertOffset;
00039      int  md2TriOffset;
00040      int  md2FrameOffset;
00041      int  md2GlCmdOffset;
00042      int  md2EndOffset;
00043 } md2Header;
00044 
00045 typedef struct {
00046      char md2TextureName[64];
00047 } md2Texture;
00048 
00049 typedef struct {
00050      s16 md2TexVertU;
00051      s16 md2TexVertV;
00052 } md2TexVert;
00053 
00054 typedef struct {
00055      u16 md2TriVerts[3];
00056      u16 md2TriTexVerts[3];
00057 } md2Tri;
00058 
00059 typedef struct {
00060      u8 md2VertexPos[3];
00061      u8 md2VertexNormal;
00062 } md2Vertex;
00063 
00064 typedef struct {
00065      vect3f     md2FrameScale;
00066      vect3f     md2FrameTranslate;
00067      char       md2FrameName[16];
00068      md2Vertex* md2FrameVerts;
00069 } md2Frame;
00070 
00071 typedef struct {
00072      u32         md2TextureCount;
00073      u32         md2TexVertCount;
00074      u32         md2VertCount;
00075      u32         md2TriCount;
00076      u32         md2FrameCount;
00077      
00078      Texture**   md2Textures;
00079      md2TexVert* md2TexVerts;
00080      md2Tri*     md2Tris;
00081      md2Frame*   md2Frames;
00082 } Model3dAnimatedMD2;
00083 
00084 Model3dAnimated* mdl3dAnimLoadMD2(char* inPath) {
00085      Model3dAnimatedMD2* tempModel = (Model3dAnimatedMD2*)memAlloc(sizeof(Model3dAnimatedMD2));
00086      if(!tempModel) {
00087           #if FL_DEBUG_WARNING != 0
00088           debugWarning("Can't create md2 model struct.\nProbably out of memory.");
00089           #endif
00090           return NULL;
00091      }
00092      Model3dAnimated* tempOut = (Model3dAnimated*)memAlloc(sizeof(Model3dAnimated));
00093      if(!tempOut) {
00094           memFree(tempModel);
00095           #if FL_DEBUG_WARNING != 0
00096           debugWarning("Can't create model struct.\nProbably out of memory.");
00097           #endif
00098           return NULL;
00099      }
00100      tempOut->mdlType = MODEL_ANIM_TYPE_MD2;
00101      tempOut->mdlData = (void*)tempModel;
00102      
00103      
00104      md2Header tempHeader;
00105      int i, j;
00106      
00107      #if FL_FILE != 0
00108      File* tempFile = fileOpen(inPath, FILE_MODE_READ | FILE_MODE_BINARY);
00109      #else
00110      FILE* tempFile = fopen(inPath, "rb");
00111      #endif
00112      
00113      fileRead(tempHeader.md2Ident, 4, tempFile);
00114      fileRead(&tempHeader.md2Version, 4, tempFile);
00115      if(strncmp(tempHeader.md2Ident, "IDP2", 4) || (tempHeader.md2Version != 8)) {
00116           fileClose(tempFile);
00117           memFree(tempModel);
00118           memFree(tempOut);
00119           #if FL_DEBUG_WARNING != 0
00120           debugWarning("Only IDP2 version 8 md2 files are supported.");
00121           #endif
00122           return NULL;
00123      }
00124      fileRead(&tempHeader.md2SkinWidth, 4, tempFile);
00125      fileRead(&tempHeader.md2SkinHeight, 4, tempFile);
00126      fileRead(&tempHeader.md2FrameSize, 4, tempFile);
00127      fileRead(&tempHeader.md2TextureCount, 4, tempFile);
00128      fileRead(&tempHeader.md2VertCount, 4, tempFile);
00129      fileRead(&tempHeader.md2TexVertCount, 4, tempFile);
00130      fileRead(&tempHeader.md2TriCount, 4, tempFile);
00131      fileRead(&tempHeader.md2GlCmdCount, 4, tempFile);
00132      fileRead(&tempHeader.md2FrameCount, 4, tempFile);
00133      fileRead(&tempHeader.md2TextureOffset, 4, tempFile);
00134      fileRead(&tempHeader.md2TexVertOffset, 4, tempFile);
00135      fileRead(&tempHeader.md2TriOffset, 4, tempFile);
00136      fileRead(&tempHeader.md2FrameOffset, 4, tempFile);
00137      fileRead(&tempHeader.md2GlCmdOffset, 4, tempFile);
00138      fileRead(&tempHeader.md2EndOffset, 4, tempFile);
00139      
00140      tempModel->md2TextureCount = tempHeader.md2TextureCount;
00141      tempModel->md2TexVertCount = tempHeader.md2TexVertCount;
00142      tempModel->md2VertCount = tempHeader.md2VertCount;
00143      tempModel->md2TriCount = tempHeader.md2TriCount;
00144      tempModel->md2FrameCount = tempHeader.md2FrameCount;
00145      
00146      u32 tempSize = (sizeof(Texture*) * tempHeader.md2TextureCount);
00147      tempSize += (sizeof(md2TexVert) * tempHeader.md2TexVertCount);
00148      tempSize += (sizeof(md2Tri) * tempHeader.md2TriCount);
00149      tempSize += (sizeof(md2Frame) * tempHeader.md2FrameCount);
00150      tempSize += (sizeof(md2Vertex) * tempHeader.md2VertCount * tempHeader.md2FrameCount);
00151      void* tempBlockAlloc = memAlloc(tempSize);
00152      if(!tempBlockAlloc) {
00153           memFree(tempOut);
00154           memFree(tempModel);
00155           fileClose(tempFile);
00156           #if FL_DEBUG_WARNING != 0
00157           debugWarning("Can't allocate memory for model data.\nProbably out of memory.");
00158           #endif
00159           return NULL;
00160      }
00161      
00162      tempModel->md2Textures = (Texture**)tempBlockAlloc;
00163      u32 tempOffset = (sizeof(Texture*) * tempHeader.md2TextureCount);
00164      tempModel->md2TexVerts = (md2TexVert*)((u32)tempBlockAlloc + tempOffset);
00165      tempOffset += (sizeof(md2TexVert) * tempHeader.md2TexVertCount);
00166      tempModel->md2Tris = (md2Tri*)((u32)tempBlockAlloc + tempOffset);
00167      tempOffset += (sizeof(md2Tri) * tempHeader.md2TexVertCount);
00168      tempModel->md2Frames = (md2Frame*)((u32)tempBlockAlloc + tempOffset);
00169      tempOffset += (sizeof(md2Frame) * tempHeader.md2FrameCount);
00170 
00171      char tempTexPath[64];     
00172      fileSeek(tempFile, tempHeader.md2TextureOffset, FILE_SEEK_SET);
00173      for(i = 0; i < tempHeader.md2TextureCount; i++) {
00174           fileRead(tempTexPath, 64, tempFile);
00175           tempModel->md2Textures[i] = texLoad(tempTexPath);
00176           if(!tempModel->md2Textures[i]) {
00177                mdl3dAnimFree(tempOut);
00178                fileClose(tempFile);
00179                #if FL_DEBUG_WARNING != 0
00180                debugWarning("Can't open texture file in MD2.");
00181                #endif
00182                return NULL;
00183           }
00184      }
00185      
00186      fileSeek(tempFile, tempHeader.md2TexVertOffset, FILE_SEEK_SET);
00187      for(i = 0; i < tempHeader.md2TexVertCount; i++) {
00188           fileRead(&tempModel->md2TexVerts[i].md2TexVertU, 2, tempFile);
00189           fileRead(&tempModel->md2TexVerts[i].md2TexVertV, 2, tempFile);
00190      }
00191      
00192      fileSeek(tempFile, tempHeader.md2TriOffset, FILE_SEEK_SET);
00193      for(i = 0; i < tempHeader.md2TriCount; i++) {
00194           for(j = 0; j < 3; j++)
00195                fileRead(&tempModel->md2Tris[i].md2TriVerts[j], 2, tempFile);
00196           for(j = 0; j < 3; j++)
00197                fileRead(&tempModel->md2Tris[i].md2TriTexVerts[j], 2, tempFile);
00198      }
00199 
00200      fileSeek(tempFile, tempHeader.md2FrameOffset, FILE_SEEK_SET);
00201      for(i = 0; i < tempHeader.md2FrameCount; i++) {
00202           fileRead(&tempModel->md2Frames[i].md2FrameScale.x, 4, tempFile);
00203           fileRead(&tempModel->md2Frames[i].md2FrameScale.y, 4, tempFile);
00204           fileRead(&tempModel->md2Frames[i].md2FrameScale.z, 4, tempFile);
00205           fileRead(&tempModel->md2Frames[i].md2FrameTranslate.x, 4, tempFile);
00206           fileRead(&tempModel->md2Frames[i].md2FrameTranslate.x, 4, tempFile);
00207           fileRead(&tempModel->md2Frames[i].md2FrameTranslate.x, 4, tempFile);
00208           fileRead(tempModel->md2Frames[i].md2FrameName, 16, tempFile);
00209           tempModel->md2Frames[i].md2FrameVerts = (md2Vertex*)((u32)tempBlockAlloc + tempOffset);
00210           tempOffset += (sizeof(md2Vertex) * tempHeader.md2VertCount);
00211           for(j = 0; j < tempHeader.md2VertCount; j++) {
00212                fileRead(tempModel->md2Frames[i].md2FrameVerts[j].md2VertexPos, 3, tempFile);
00213                fileRead(&tempModel->md2Frames[i].md2FrameVerts[j].md2VertexNormal, 1, tempFile);
00214           }
00215      }
00216      
00217      fileClose(tempFile);
00218      
00219      return tempOut;
00220 }
00221 
00222 void mdl3dAnimDrawMD2(void* inModel, float inFrame) {
00223      if(!inModel) {
00224           #if FL_DEBUG_WARNING != 0
00225           debugWarning("Trying to draw NULL md2.");
00226           #endif
00227           return;
00228      }
00229 
00230      Model3dAnimatedMD2* tempModel = (Model3dAnimatedMD2*)inModel;
00231 
00232      while(inFrame >= (float)tempModel->md2FrameCount)
00233           inFrame -= (float)tempModel->md2FrameCount;
00234      
00235      int tempFrames[2] = { (int)inFrame, (int)(inFrame + 1.0f) };
00236      if(tempFrames[1] >= tempModel->md2FrameCount)
00237           tempFrames[1] -= tempModel->md2FrameCount;
00238      float tempFract = (inFrame - (float)tempFrames[0]);
00239 
00240      vect3f tempScale = vect3f_Mulf(tempModel->md2Frames[tempFrames[0]].md2FrameScale, (1.0f - tempFract));
00241      tempScale = vect3f_Add(tempScale, vect3f_Mulf(tempModel->md2Frames[tempFrames[1]].md2FrameScale, tempFract));
00242      vect3f tempTranslate = vect3f_Mulf(tempModel->md2Frames[tempFrames[0]].md2FrameTranslate, (1.0f - tempFract));
00243      tempTranslate = vect3f_Add(tempTranslate, vect3f_Mulf(tempModel->md2Frames[tempFrames[1]].md2FrameTranslate, tempFract));
00244 
00245      texBind(tempModel->md2Textures[0]);
00246 
00247      sceGumPushMatrix();
00248      sceGumScale(&tempScale);
00249      sceGumTranslate(&tempTranslate);
00250 
00251      int i, j;
00252      vertTsVf* tempVerts = (vertTsVf*)sceGuGetMemory(sizeof(vertTsVf) * (tempModel->md2TriCount * 3));
00253      for(i = 0; i < tempModel->md2TriCount; i++) {
00254           for(j = 0; j < 3; j++) {
00255                tempVerts[(i * 3) + j].vertX = (float)tempModel->md2Frames[tempFrames[0]].md2FrameVerts[tempModel->md2Tris[i].md2TriVerts[j]].md2VertexPos[0] * (1.0f - tempFract);
00256                tempVerts[(i * 3) + j].vertX += (float)tempModel->md2Frames[tempFrames[1]].md2FrameVerts[tempModel->md2Tris[i].md2TriVerts[j]].md2VertexPos[0] * tempFract;
00257                tempVerts[(i * 3) + j].vertY = (float)tempModel->md2Frames[tempFrames[0]].md2FrameVerts[tempModel->md2Tris[i].md2TriVerts[j]].md2VertexPos[1] * (1.0f - tempFract);
00258                tempVerts[(i * 3) + j].vertY += (float)tempModel->md2Frames[tempFrames[1]].md2FrameVerts[tempModel->md2Tris[i].md2TriVerts[j]].md2VertexPos[1] * tempFract;
00259                tempVerts[(i * 3) + j].vertZ = (float)tempModel->md2Frames[tempFrames[0]].md2FrameVerts[tempModel->md2Tris[i].md2TriVerts[j]].md2VertexPos[2] * (1.0f - tempFract);
00260                tempVerts[(i * 3) + j].vertZ += (float)tempModel->md2Frames[tempFrames[1]].md2FrameVerts[tempModel->md2Tris[i].md2TriVerts[j]].md2VertexPos[2] * tempFract;
00261                tempVerts[(i * 3) + j].vertU += tempModel->md2TexVerts[tempModel->md2Tris[i].md2TriTexVerts[j]].md2TexVertU;
00262                tempVerts[(i * 3) + j].vertV += tempModel->md2TexVerts[tempModel->md2Tris[i].md2TriTexVerts[j]].md2TexVertV;
00263           }
00264      }
00265      sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_16BIT | GU_VERTEX_32BITF | GU_TRANSFORM_3D, (tempModel->md2TriCount * 3), 0, tempVerts);
00266      sceGumPopMatrix();
00267 }
00268 
00269 bool mdl3dAnimSaveMD2(char* inPath, Model3dAnimated* inModel) {
00270      #if FL_DEBUG_DEVWARNING != 0
00271      debugDevWarning("MD2 saving is not yet implemented.");
00272      #endif
00273      return false;
00274 }
00275 
00276 #endif

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