SMFLoader.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:13k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // SMFLoader.cpp: implementation of the CSMFLoader class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include <stdio.h>
  6. #include "SMFLoader.h"
  7. #include "Texture.h"
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. CSMFLoader::CSMFLoader()
  12. {
  13. glCommands=NULL;
  14. pVertexData=NULL;
  15. pTempFrame=NULL;
  16. startPointer=NULL;
  17. endPointer=NULL;
  18. pAction=NULL;
  19. }
  20. CSMFLoader::~CSMFLoader()
  21. {
  22. if(glCommands)
  23. delete [] glCommands;
  24. if(pVertexData)
  25. delete [] pVertexData;
  26. if(pTempFrame)
  27. delete [] pTempFrame;
  28. if(pAction)
  29. delete [] pAction;
  30. }
  31. bool CSMFLoader::LoadModel(char* filename)
  32. {
  33. FILE* file;
  34. if((file= fopen(filename, "rb"))==NULL)
  35. return false;
  36. char id[20];
  37. fread(id, sizeof(char), 20, file);
  38. if ( strncmp( id, "SimpleModelFile001", 18 ) != 0 )
  39. MessageBox(NULL,"id error","ERROR",MB_OK|MB_ICONEXCLAMATION);
  40. fclose(file);
  41. return false; // "Not a valid Milkshape3D model file."
  42. }
  43. ///////////read info
  44. fread(&numVertices, sizeof(int), 1, file);
  45. fread(&numFrames,   sizeof(int), 1, file);
  46. fread(&frameSize,   sizeof(int), 1, file);
  47. fread(&numAction,   sizeof(int), 1, file);
  48.     ////////// read action info
  49.     pAction=new SMF_ACTION [numAction];
  50. fread(pAction,   sizeof(SMF_ACTION),numAction, file);
  51. /////////////////////////////////
  52. unsigned char *frames;
  53. frames= new unsigned char[frameSize*numFrames];
  54. //Check to see if it allocated correctly
  55. if(frames==NULL)
  56. return false;
  57. //Zoom to the correct spot in the file
  58. fread(frames, sizeof(unsigned char),frameSize*numFrames, file);
  59. pVertexData=new SMF_VERTEX[numVertices*numFrames];
  60. if(pVertexData ==NULL)return false;
  61. float temp;
  62.     for(int i=0;i<numFrames;i++)
  63. {
  64. SMF_FRAME *currentFrame= (SMF_FRAME*) (frames+frameSize*i);
  65. for(int j=0;j<numVertices;j++)
  66. {
  67.             pVertexData[i*numVertices+j].x=currentFrame->vertices[j].vertex[0]* 
  68.            currentFrame->scale[0]+ 
  69.            currentFrame->translate[0];
  70.             pVertexData[i*numVertices+j].z=currentFrame->vertices[j].vertex[1]* 
  71.            currentFrame->scale[1]+ 
  72.            currentFrame->translate[1];
  73.             pVertexData[i*numVertices+j].y=currentFrame->vertices[j].vertex[2]* 
  74.                currentFrame->scale[2]+ 
  75.            currentFrame->translate[2];
  76.             pVertexData[i*numVertices+j].x=pVertexData[i*numVertices+j].x*scale;
  77.             pVertexData[i*numVertices+j].y=pVertexData[i*numVertices+j].y*scale;
  78.             pVertexData[i*numVertices+j].z=-pVertexData[i*numVertices+j].z*scale;
  79.         //////////////rotate 90
  80.             temp=pVertexData[i*numVertices+j].x;
  81. pVertexData[i*numVertices+j].x=pVertexData[i*numVertices+j].z;
  82. pVertexData[i*numVertices+j].z= -temp;
  83.             pVertexData[i*numVertices+j].normalIndex=currentFrame->vertices[j].lightNormalIndex;
  84. }
  85. }
  86. delete [] frames;
  87. //Create space for the GL command information (whether or not to use tri strips, or tri fans)
  88. fread(&numGlCommands,   sizeof(int), 1, file);
  89. glCommands= new long [numGlCommands];
  90. if(glCommands==NULL)
  91. return false;
  92. fread(glCommands, sizeof(long), numGlCommands,file);
  93.     /////////////////////read keyIndex
  94. fread(keyIndex, sizeof(int), 4,file);
  95. for( i=0;i<4;i++)
  96. if(keyIndex[i]>(numVertices-1))keyIndex[i]=0;
  97. //Close 'da friggin file mon
  98. fclose(file);
  99.     pTempFrame =new SMF_TEMPVERTEX [numVertices];
  100. if(pTempFrame ==NULL)return false;
  101. return true;
  102. }
  103. bool CSMFLoader::InitSMFLoader(char* Model,unsigned int texid,float nscale)
  104. {
  105. scale=nscale;
  106. if(Model==NULL)return false;
  107. if(!LoadModel(Model))return false;
  108.     textureID=texid;
  109.     PreProcess();
  110. return true;
  111. }
  112. void CSMFLoader::PreProcess()
  113.     for(int i=0;i<numVertices;i++)
  114. {
  115. if(pVertexData[i].x>m_boundary.maxx)m_boundary.maxx=pVertexData[i].x;
  116. if(pVertexData[i].x<m_boundary.minx)m_boundary.minx=pVertexData[i].x;
  117. if(pVertexData[i].y>m_boundary.maxy)m_boundary.maxy=pVertexData[i].y;
  118. if(pVertexData[i].y<m_boundary.miny)m_boundary.miny=pVertexData[i].y;
  119. if(pVertexData[i].z>m_boundary.maxz)m_boundary.maxz=pVertexData[i].z;
  120. if(pVertexData[i].z<m_boundary.minz)m_boundary.minz=pVertexData[i].z;
  121. }
  122. /////////
  123. startPointer=pVertexData;
  124. endPointer=pVertexData;
  125. }
  126. VERTEX CSMFLoader::GetPos(int posIndex,float percent)
  127. {
  128. if(posIndex>3 || posIndex<0)posIndex=0;
  129. if(percent>1  || percent<0 )percent=0;
  130. VERTEX pos;
  131. pos.xpos=(1-percent)*startPointer[keyIndex[posIndex]].x+percent*endPointer[keyIndex[posIndex]].x;
  132. pos.ypos=(1-percent)*startPointer[keyIndex[posIndex]].y+percent*endPointer[keyIndex[posIndex]].y;
  133. pos.zpos=(1-percent)*startPointer[keyIndex[posIndex]].z+percent*endPointer[keyIndex[posIndex]].z;
  134. return pos;
  135. }
  136. //------------------------------------------------------------------//
  137. //- void Render(int) -----------------------------------------------//
  138. //------------------------------------------------------------------//
  139. //- Description: This function renders an .SMF model with the given-//
  140. //-  frame of animation.    -//
  141. //------------------------------------------------------------------//
  142. //- Ok, now I really owe Justin a big one for this... His code     -//
  143. //- seems to be the only one that took advantage of the gl commands-//
  144. //- that are within the SMF file (for speed)!    -//
  145. //------------------------------------------------------------------//
  146. void CSMFLoader::RenderOneFrame(int numFrame)
  147. if(numFrame>(numFrames-1))numFrame=numFrames-1;
  148. if(numFrame<0)numFrame=0;
  149.     SMF_VERTEX *pCurFrame=pVertexData+numFrame*numVertices;
  150. long* command;
  151. int vertIndex;
  152. int type;
  153. int numVertex;
  154.     //Get the current frame and gl command information
  155. command = glCommands;
  156. //////////////////////////////////////////////
  157.     glBindTexture(GL_TEXTURE_2D, textureID);
  158.     glEnable(GL_TEXTURE_2D);
  159. glCullFace(GL_FRONT);
  160. //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
  161. while((*command)!=0)
  162. {
  163. if(*command>0) //This is a triangle strip
  164. {
  165. numVertex= *command; 
  166. command++; 
  167. type= 0;
  168. }
  169. else //This is a triangle fan
  170. {
  171. numVertex= - *command; 
  172. command++; 
  173. type= 1;
  174. }
  175. if(numVertex<0)numVertex= -numVertex;
  176. //Fill the vertex list information
  177. glColor3f(0,1,0);
  178. for(int loop=0; loop<numVertex; loop++)
  179. {
  180.             pTempFrame[loop].texcoord[0]=*((float*)command); 
  181. command++;
  182.             pTempFrame[loop].texcoord[1]=*((float*)command); 
  183. command++;
  184. vertIndex= *command; 
  185. command++;
  186. pTempFrame[loop].vertex[0]=pCurFrame[vertIndex].x;
  187. pTempFrame[loop].vertex[1]=pCurFrame[vertIndex].y;
  188. pTempFrame[loop].vertex[2]=pCurFrame[vertIndex].z;
  189. pTempFrame[loop].startNormalIndex=pCurFrame[vertIndex].normalIndex; 
  190.             /////////////////now draw normal line
  191. /* glColor3f(1,1,1);
  192. glDisable(GL_TEXTURE_2D);
  193.             glBegin(GL_LINES);
  194.     glVertex3fv(pTempFrame[loop].vertex);
  195. glVertex3f(m_SMFNormal.m_pSMFNormal[pTempFrame[loop].normalIndex*3]+pTempFrame[loop].vertex[0],
  196. m_SMFNormal.m_pSMFNormal[pTempFrame[loop].normalIndex*3+1]+pTempFrame[loop].vertex[1],
  197. m_SMFNormal.m_pSMFNormal[pTempFrame[loop].normalIndex*3+2]+pTempFrame[loop].vertex[2]);
  198. glEnd();
  199. glEnable(GL_TEXTURE_2D);*/
  200. }
  201. glColor3f(1,1,1);
  202. //If the .SMF was optimized for use with triangle strips...
  203. if(type==0)
  204. {
  205. glBegin(GL_TRIANGLE_STRIP);
  206. for(loop=0; loop<numVertex; loop++)
  207. {
  208. glNormal3fv(&m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]);
  209.      glTexCoord2fv(pTempFrame[loop].texcoord);
  210. glVertex3fv(pTempFrame[loop].vertex);
  211. }
  212. glEnd();
  213. }
  214. else//If the .SMF was made for use with triangle fans...
  215. {
  216. glBegin(GL_TRIANGLE_FAN);
  217. for(loop=0; loop<numVertex; loop++)
  218. {
  219. glNormal3fv(&m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]);
  220.      glTexCoord2fv(pTempFrame[loop].texcoord);
  221. glVertex3fv(pTempFrame[loop].vertex);
  222. }
  223. glEnd();
  224. }
  225. }
  226.     glCullFace(GL_BACK);
  227. }
  228. //------------------------------------------------------------------//
  229. //- void Animate( float) ----------------------------------//
  230. void CSMFLoader::Animate(int startFrame,int endFrame,float percent)
  231. {
  232.     //////////////////////////////////////////////////////
  233. long* command;
  234. int vertIndex;
  235. int type;
  236. int numVertex;
  237.     startPointer=pVertexData+startFrame*numVertices;
  238.     endPointer=pVertexData+endFrame*numVertices;
  239.     //Get the current frame and gl command information
  240. command = glCommands;
  241. //////////////////////////////////////////////
  242.     glBindTexture(GL_TEXTURE_2D, textureID);
  243. glEnable(GL_TEXTURE_2D);
  244.     glCullFace(GL_FRONT);
  245. //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
  246. while((*command)!=0)
  247. {
  248. if(*command>0) //This is a triangle strip
  249. {
  250. numVertex= *command; 
  251. command++; 
  252. type= 0;
  253. }
  254. else //This is a triangle fan
  255. {
  256. numVertex= - *command; 
  257. command++; 
  258. type= 1;
  259. }
  260. if(numVertex<0)numVertex= -numVertex;
  261. //Fill the vertex list information
  262. for(int loop=0; loop<numVertex; loop++)
  263. {
  264.             pTempFrame[loop].texcoord[0]=*((float*)command); 
  265. command++;
  266.             pTempFrame[loop].texcoord[1]=*((float*)command); 
  267. command++;
  268. vertIndex= *command; 
  269. command++;
  270. pTempFrame[loop].vertex[0]=(1-percent)*startPointer[vertIndex].x+
  271.                           percent*endPointer[vertIndex].x;
  272. pTempFrame[loop].vertex[1]=(1-percent)*startPointer[vertIndex].y+
  273.                           percent*endPointer[vertIndex].y;
  274. pTempFrame[loop].vertex[2]=(1-percent)*startPointer[vertIndex].z+
  275.                           percent*endPointer[vertIndex].z;
  276. pTempFrame[loop].startNormalIndex=startPointer[vertIndex].normalIndex; 
  277. pTempFrame[loop].endNormalIndex=endPointer[vertIndex].normalIndex; 
  278. }
  279.         
  280. //If the .SMF was optimized for use with triangle strips...
  281. float tempNormal[3];
  282. if(type==0)
  283. {
  284. glBegin(GL_TRIANGLE_STRIP);
  285. for(loop=0; loop<numVertex; loop++)
  286. {
  287. tempNormal[0]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]+
  288.               percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3];
  289. tempNormal[1]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+1]+
  290.               percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+1];
  291. tempNormal[2]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+2]+
  292.               percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+2];
  293. glNormal3fv(tempNormal);
  294.      glTexCoord2fv(pTempFrame[loop].texcoord);
  295. glVertex3fv(pTempFrame[loop].vertex);
  296. }
  297. glEnd();
  298. }
  299. else//If the .SMF was made for use with triangle fans...
  300. {
  301. glBegin(GL_TRIANGLE_FAN);
  302. for(loop=0; loop<numVertex; loop++)
  303. {
  304. tempNormal[0]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]+
  305.               percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3];
  306. tempNormal[1]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+1]+
  307.               percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+1];
  308. tempNormal[2]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+2]+
  309.               percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+2];
  310. glNormal3fv(tempNormal);
  311.      glTexCoord2fv(pTempFrame[loop].texcoord);
  312. glVertex3fv(pTempFrame[loop].vertex);
  313. }
  314. glEnd();
  315. }
  316. }
  317.     glCullFace(GL_BACK);
  318. //  DrawSMFBoundary();
  319. }
  320. void CSMFLoader::DrawSMFBoundary()
  321. {
  322. glDisable(GL_TEXTURE_2D);
  323. glColor3f(1,1,1);
  324. glBegin(GL_LINE_STRIP);
  325.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
  326.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
  327.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
  328.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
  329.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
  330.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
  331.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
  332.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
  333.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
  334.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
  335. glEnd();
  336. glBegin(GL_LINES);
  337.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
  338.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
  339.     glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
  340.     glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
  341.     glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
  342.     glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
  343. glEnd();
  344. glColor3f(1,1,1);
  345. }