SMFLoader.cpp
上传用户:hkb425
上传日期:2007-06-16
资源大小:34191k
文件大小:13k
- // SMFLoader.cpp: implementation of the CSMFLoader class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include <stdio.h>
- #include "SMFLoader.h"
- #include "Texture.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CSMFLoader::CSMFLoader()
- {
- glCommands=NULL;
- pVertexData=NULL;
- pTempFrame=NULL;
- startPointer=NULL;
- endPointer=NULL;
- pAction=NULL;
- }
- CSMFLoader::~CSMFLoader()
- {
- if(glCommands)
- delete [] glCommands;
- if(pVertexData)
- delete [] pVertexData;
- if(pTempFrame)
- delete [] pTempFrame;
- if(pAction)
- delete [] pAction;
- }
- bool CSMFLoader::LoadModel(char* filename)
- {
- FILE* file;
- if((file= fopen(filename, "rb"))==NULL)
- return false;
- char id[20];
- fread(id, sizeof(char), 20, file);
- if ( strncmp( id, "SimpleModelFile001", 18 ) != 0 )
- {
- MessageBox(NULL,"id error","ERROR",MB_OK|MB_ICONEXCLAMATION);
- fclose(file);
- return false; // "Not a valid Milkshape3D model file."
- }
- ///////////read info
- fread(&numVertices, sizeof(int), 1, file);
- fread(&numFrames, sizeof(int), 1, file);
- fread(&frameSize, sizeof(int), 1, file);
- fread(&numAction, sizeof(int), 1, file);
- ////////// read action info
- pAction=new SMF_ACTION [numAction];
- fread(pAction, sizeof(SMF_ACTION),numAction, file);
- /////////////////////////////////
- unsigned char *frames;
- frames= new unsigned char[frameSize*numFrames];
- //Check to see if it allocated correctly
- if(frames==NULL)
- return false;
- //Zoom to the correct spot in the file
- fread(frames, sizeof(unsigned char),frameSize*numFrames, file);
- pVertexData=new SMF_VERTEX[numVertices*numFrames];
- if(pVertexData ==NULL)return false;
- float temp;
- for(int i=0;i<numFrames;i++)
- {
- SMF_FRAME *currentFrame= (SMF_FRAME*) (frames+frameSize*i);
- for(int j=0;j<numVertices;j++)
- {
- pVertexData[i*numVertices+j].x=currentFrame->vertices[j].vertex[0]*
- currentFrame->scale[0]+
- currentFrame->translate[0];
- pVertexData[i*numVertices+j].z=currentFrame->vertices[j].vertex[1]*
- currentFrame->scale[1]+
- currentFrame->translate[1];
- pVertexData[i*numVertices+j].y=currentFrame->vertices[j].vertex[2]*
- currentFrame->scale[2]+
- currentFrame->translate[2];
- pVertexData[i*numVertices+j].x=pVertexData[i*numVertices+j].x*scale;
- pVertexData[i*numVertices+j].y=pVertexData[i*numVertices+j].y*scale;
- pVertexData[i*numVertices+j].z=-pVertexData[i*numVertices+j].z*scale;
- //////////////rotate 90
- temp=pVertexData[i*numVertices+j].x;
- pVertexData[i*numVertices+j].x=pVertexData[i*numVertices+j].z;
- pVertexData[i*numVertices+j].z= -temp;
- pVertexData[i*numVertices+j].normalIndex=currentFrame->vertices[j].lightNormalIndex;
- }
- }
- delete [] frames;
- //Create space for the GL command information (whether or not to use tri strips, or tri fans)
- fread(&numGlCommands, sizeof(int), 1, file);
-
- glCommands= new long [numGlCommands];
- if(glCommands==NULL)
- return false;
- fread(glCommands, sizeof(long), numGlCommands,file);
- /////////////////////read keyIndex
- fread(keyIndex, sizeof(int), 4,file);
- for( i=0;i<4;i++)
- if(keyIndex[i]>(numVertices-1))keyIndex[i]=0;
- //Close 'da friggin file mon
- fclose(file);
-
- pTempFrame =new SMF_TEMPVERTEX [numVertices];
- if(pTempFrame ==NULL)return false;
- return true;
- }
- bool CSMFLoader::InitSMFLoader(char* Model,unsigned int texid,float nscale)
- {
- scale=nscale;
- if(Model==NULL)return false;
- if(!LoadModel(Model))return false;
- textureID=texid;
- PreProcess();
- return true;
- }
- void CSMFLoader::PreProcess()
- {
- for(int i=0;i<numVertices;i++)
- {
- if(pVertexData[i].x>m_boundary.maxx)m_boundary.maxx=pVertexData[i].x;
- if(pVertexData[i].x<m_boundary.minx)m_boundary.minx=pVertexData[i].x;
- if(pVertexData[i].y>m_boundary.maxy)m_boundary.maxy=pVertexData[i].y;
- if(pVertexData[i].y<m_boundary.miny)m_boundary.miny=pVertexData[i].y;
- if(pVertexData[i].z>m_boundary.maxz)m_boundary.maxz=pVertexData[i].z;
- if(pVertexData[i].z<m_boundary.minz)m_boundary.minz=pVertexData[i].z;
- }
- /////////
- startPointer=pVertexData;
- endPointer=pVertexData;
- }
- VERTEX CSMFLoader::GetPos(int posIndex,float percent)
- {
- if(posIndex>3 || posIndex<0)posIndex=0;
- if(percent>1 || percent<0 )percent=0;
- VERTEX pos;
- pos.xpos=(1-percent)*startPointer[keyIndex[posIndex]].x+percent*endPointer[keyIndex[posIndex]].x;
- pos.ypos=(1-percent)*startPointer[keyIndex[posIndex]].y+percent*endPointer[keyIndex[posIndex]].y;
- pos.zpos=(1-percent)*startPointer[keyIndex[posIndex]].z+percent*endPointer[keyIndex[posIndex]].z;
- return pos;
- }
- //------------------------------------------------------------------//
- //- void Render(int) -----------------------------------------------//
- //------------------------------------------------------------------//
- //- Description: This function renders an .SMF model with the given-//
- //- frame of animation. -//
- //------------------------------------------------------------------//
- //- Ok, now I really owe Justin a big one for this... His code -//
- //- seems to be the only one that took advantage of the gl commands-//
- //- that are within the SMF file (for speed)! -//
- //------------------------------------------------------------------//
- void CSMFLoader::RenderOneFrame(int numFrame)
- {
- if(numFrame>(numFrames-1))numFrame=numFrames-1;
- if(numFrame<0)numFrame=0;
- SMF_VERTEX *pCurFrame=pVertexData+numFrame*numVertices;
- long* command;
- int vertIndex;
- int type;
- int numVertex;
- //Get the current frame and gl command information
- command = glCommands;
- //////////////////////////////////////////////
- glBindTexture(GL_TEXTURE_2D, textureID);
- glEnable(GL_TEXTURE_2D);
- glCullFace(GL_FRONT);
- //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
- while((*command)!=0)
- {
- if(*command>0) //This is a triangle strip
- {
- numVertex= *command;
- command++;
- type= 0;
- }
- else //This is a triangle fan
- {
- numVertex= - *command;
- command++;
- type= 1;
- }
- if(numVertex<0)numVertex= -numVertex;
- //Fill the vertex list information
- glColor3f(0,1,0);
- for(int loop=0; loop<numVertex; loop++)
- {
- pTempFrame[loop].texcoord[0]=*((float*)command);
- command++;
- pTempFrame[loop].texcoord[1]=*((float*)command);
- command++;
- vertIndex= *command;
- command++;
- pTempFrame[loop].vertex[0]=pCurFrame[vertIndex].x;
- pTempFrame[loop].vertex[1]=pCurFrame[vertIndex].y;
- pTempFrame[loop].vertex[2]=pCurFrame[vertIndex].z;
- pTempFrame[loop].startNormalIndex=pCurFrame[vertIndex].normalIndex;
- /////////////////now draw normal line
- /* glColor3f(1,1,1);
- glDisable(GL_TEXTURE_2D);
- glBegin(GL_LINES);
- glVertex3fv(pTempFrame[loop].vertex);
- glVertex3f(m_SMFNormal.m_pSMFNormal[pTempFrame[loop].normalIndex*3]+pTempFrame[loop].vertex[0],
- m_SMFNormal.m_pSMFNormal[pTempFrame[loop].normalIndex*3+1]+pTempFrame[loop].vertex[1],
- m_SMFNormal.m_pSMFNormal[pTempFrame[loop].normalIndex*3+2]+pTempFrame[loop].vertex[2]);
- glEnd();
- glEnable(GL_TEXTURE_2D);*/
- }
- glColor3f(1,1,1);
- //If the .SMF was optimized for use with triangle strips...
- if(type==0)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for(loop=0; loop<numVertex; loop++)
- {
- glNormal3fv(&m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- else//If the .SMF was made for use with triangle fans...
- {
- glBegin(GL_TRIANGLE_FAN);
- for(loop=0; loop<numVertex; loop++)
- {
- glNormal3fv(&m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- }
- glCullFace(GL_BACK);
- }
- //------------------------------------------------------------------//
- //- void Animate( float) ----------------------------------//
- void CSMFLoader::Animate(int startFrame,int endFrame,float percent)
- {
- //////////////////////////////////////////////////////
- long* command;
- int vertIndex;
- int type;
- int numVertex;
- startPointer=pVertexData+startFrame*numVertices;
- endPointer=pVertexData+endFrame*numVertices;
- //Get the current frame and gl command information
- command = glCommands;
- //////////////////////////////////////////////
- glBindTexture(GL_TEXTURE_2D, textureID);
- glEnable(GL_TEXTURE_2D);
- glCullFace(GL_FRONT);
- //Make sure that the command doesn't equal 0, and if it doesn't lets start rendering!
- while((*command)!=0)
- {
- if(*command>0) //This is a triangle strip
- {
- numVertex= *command;
- command++;
- type= 0;
- }
- else //This is a triangle fan
- {
- numVertex= - *command;
- command++;
- type= 1;
- }
- if(numVertex<0)numVertex= -numVertex;
- //Fill the vertex list information
- for(int loop=0; loop<numVertex; loop++)
- {
- pTempFrame[loop].texcoord[0]=*((float*)command);
- command++;
- pTempFrame[loop].texcoord[1]=*((float*)command);
- command++;
- vertIndex= *command;
- command++;
- pTempFrame[loop].vertex[0]=(1-percent)*startPointer[vertIndex].x+
- percent*endPointer[vertIndex].x;
- pTempFrame[loop].vertex[1]=(1-percent)*startPointer[vertIndex].y+
- percent*endPointer[vertIndex].y;
- pTempFrame[loop].vertex[2]=(1-percent)*startPointer[vertIndex].z+
- percent*endPointer[vertIndex].z;
- pTempFrame[loop].startNormalIndex=startPointer[vertIndex].normalIndex;
- pTempFrame[loop].endNormalIndex=endPointer[vertIndex].normalIndex;
- }
-
- //If the .SMF was optimized for use with triangle strips...
- float tempNormal[3];
- if(type==0)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for(loop=0; loop<numVertex; loop++)
- {
- tempNormal[0]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]+
- percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3];
- tempNormal[1]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+1]+
- percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+1];
- tempNormal[2]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+2]+
- percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+2];
- glNormal3fv(tempNormal);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- else//If the .SMF was made for use with triangle fans...
- {
- glBegin(GL_TRIANGLE_FAN);
- for(loop=0; loop<numVertex; loop++)
- {
- tempNormal[0]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3]+
- percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3];
- tempNormal[1]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+1]+
- percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+1];
- tempNormal[2]=(1-percent)*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].startNormalIndex*3+2]+
- percent*m_SMFNormal.m_pSMFNormal[pTempFrame[loop].endNormalIndex*3+2];
- glNormal3fv(tempNormal);
- glTexCoord2fv(pTempFrame[loop].texcoord);
- glVertex3fv(pTempFrame[loop].vertex);
- }
- glEnd();
- }
- }
- glCullFace(GL_BACK);
- // DrawSMFBoundary();
- }
- void CSMFLoader::DrawSMFBoundary()
- {
- glDisable(GL_TEXTURE_2D);
- glColor3f(1,1,1);
- glBegin(GL_LINE_STRIP);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.minz);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.minz);
- glVertex3f(m_boundary.maxx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.maxx,m_boundary.maxy,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.miny,m_boundary.maxz);
- glVertex3f(m_boundary.minx,m_boundary.maxy,m_boundary.maxz);
- glEnd();
- glColor3f(1,1,1);
- }