#include "md3test.h" #include "Renderer.h" #include "AnimatedModel.h" void abc(const char* str) { /* FILE *fp = fopen("output.txt", "a+"); fprintf(fp, "%s\n", str); fclose(fp); */ } /* void DbgTriangle(IDirect3DDevice8* pDevice, D3DXVECTOR3& a, D3DXVECTOR3& b, D3DXVECTOR3& c, DWORD colour) { struct TLVERTEX { float x, y, z; DWORD col; enum { FVF_TLVERTEX = D3DFVF_XYZ | D3DFVF_DIFFUSE }; }; pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); #if(0) // no lighting pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); #else g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); #endif TLVERTEX Vertex[4] = { // x y z colour { a.x, a.y, a.z, colour }, { b.x, b.y, b.z, colour }, { c.x, c.y, c.z, colour } }; #if(DIRECT3D_VERSION >= 0x0900) pDevice->SetFVF(TLVERTEX::FVF_TLVERTEX); #else pDevice->SetVertexShader(TLVERTEX::FVF_TLVERTEX); #endif // DIRECT3D_VERSION pDevice->SetTexture(0, NULL); pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); HRESULT hr = pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, Vertex, sizeof(TLVERTEX)); //g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); }*/ //--------------------------------------------------------------------- /* extern void TexSquareA(IDirect3DDevice8* pDevice, D3DXVECTOR3 pos, float w, float h );*/ class CMD3 { public: stM3DModel m_lower; stM3DModel m_upper; stM3DModel m_head; stM3DModel m_gun; stAnim m_Anim[26]; CMD3() { //m_startFrame = 0; //m_endFrame = 0; //m_currentframe = 0; //poll = 0; //m_lastUpdate = 0; } void Create(/* file names */) { /*for (int i = 0; i < MAX_TEXTURES; i++) { pTextures[i] = NULL; }*/ InitNormals(); LoadModel(&m_lower, SZ_MD3_LOWER_FILE); LoadSkin(&m_lower, SZ_MD3_LOWER_SKIN_FILE); LoadModel(&m_upper, SZ_MD3_UPPER_FILE); LoadSkin(&m_upper, SZ_MD3_UPPER_SKIN_FILE); LoadModel(&m_head, SZ_MD3_HEAD_FILE); LoadSkin(&m_head, SZ_MD3_HEAD_SKIN_FILE); LoadAnim(SZ_MD3_ANIM_FILE); LoadModel(&m_gun, "model\\railgun\\railgun.md3"); LoadSkin(&m_gun, "model\\railgun\\railgun.skin"); SetAnim(TORSO_STAND); SetAnim(LEGS_WALK); memset(m_head.m_pLinks, 0, sizeof(m_head.m_pLinks)); memset(m_upper.m_pLinks, 0, sizeof(m_upper.m_pLinks)); memset(m_lower.m_pLinks, 0, sizeof(m_lower.m_pLinks)); LinkModel(&m_lower, "tag_torso", &m_upper); LinkModel(&m_upper, "tag_head", &m_head); LinkModel(&m_upper, "tag_weapon", &m_gun); m_upper.m_currentframe = m_upper.m_startFrame; m_head.m_currentframe = m_head.m_startFrame; m_lower.m_currentframe = m_lower.m_startFrame; m_upper.m_poll = 0.0f; m_head.m_poll = 0.0f; m_lower.m_poll = 0.0f; } void Release() { ReleaseModel(&m_lower); ReleaseModel(&m_upper); ReleaseModel(&m_head); ReleaseModel(&m_gun); /* for (int i = 0; i < MAX_TEXTURES; i++) { if (pTextures[i]) { pTextures[i]->Release(); pTextures[i] = NULL; } }*/ } void Update(float time) { UpdateFrame(&m_lower, time); UpdateFrame(&m_upper, time); UpdateFrame(&m_head, time); } /* void Render() { D3DXMATRIX matCur, matNext; D3DXMatrixIdentity(&matCur); matNext = matCur; DrawSkeleton(&m_lower, &matCur, &matNext); DrawModel(&m_lower, &matCur, &matCur); }*/ ZL::AnimatedModel convertToAnimatedModel(); protected: void LinkModel(stM3DModel* from, const char* tagnameTo, stM3DModel* modelTo) { int numTags = from->m_md3Header.numTags; stTag* pTags = from->m_pTags; for (int i = 0; i < numTags; i++) { if (strcmp(pTags[i].Name, tagnameTo) == 0) { from->m_pLinks[i] = modelTo; } } } void UpdateFrame(stM3DModel* pMod, float time) { if (pMod->m_FPS > 0) { /* float deltaFPS = time - (1.0f/pMod->m_FPS); if ( deltaFPS < 0.0f ) { _asm { int 13 }; } pMod->m_poll += time + (time - 1.0f/pMod->m_FPS); */ pMod->m_poll += time; } else { pMod->m_poll += time; } if (pMod->m_poll > 1.0f) { pMod->m_poll = 0.0f; pMod->m_currentframe = pMod->m_nextFrame; pMod->m_nextFrame++; if (pMod->m_nextFrame > pMod->m_endFrame) { pMod->m_nextFrame = pMod->m_startFrame; } } } /* void DrawSkeleton(stM3DModel* pMod, D3DXMATRIX* matCur, D3DXMATRIX* matNext) { DrawModel(pMod, matCur, matNext); stM3DModel** pLinks = pMod->m_pLinks; stMD3Header* pModHeader = &pMod->m_md3Header; stTag* pTags = pMod->m_pTags; int currentFrame = pMod->m_currentframe; int nextFrame = pMod->m_nextFrame; //int startFrame = pMod->m_startFrame; for (int i = 0; i < pModHeader->numTags; i++) { if (pLinks[i] == NULL) { continue; } stM3DModel* childMod = pLinks[i]; //stMD3Header* pHeader = &childMod->m_md3Header; //stTag* pTags = childMod->m_pTags; float (*Rotation)[3]; Rotation = pTags[currentFrame * pModHeader->numTags + i].Rotation; //3x3 mat float* Position = pTags[currentFrame * pModHeader->numTags + i].Position; //vector3 char* tagName = pTags[currentFrame * pModHeader->numTags + i].Name; D3DXMATRIX m; m(0, 0) = Rotation[0][0]; m(0, 1) = Rotation[0][1]; m(0, 2) = Rotation[0][2]; m(0, 3) = 0; m(1, 0) = Rotation[1][0]; m(1, 1) = Rotation[1][1]; m(1, 2) = Rotation[1][2]; m(1, 3) = 0; m(2, 0) = Rotation[2][0]; m(2, 1) = Rotation[2][1]; m(2, 2) = Rotation[2][2]; m(2, 3) = 0; m(3, 0) = Position[0]; m(3, 1) = Position[1]; m(3, 2) = Position[2]; m(3, 3) = 1; float (*RotationNext)[3] = pTags[nextFrame * pModHeader->numTags + i].Rotation; //3x3 mat float* PositionNext = pTags[nextFrame * pModHeader->numTags + i].Position; //vector3 char* tagNameNext = pTags[nextFrame * pModHeader->numTags + i].Name; D3DXMATRIX mNext; mNext(0, 0) = RotationNext[0][0]; mNext(0, 1) = RotationNext[0][1]; mNext(0, 2) = RotationNext[0][2]; mNext(0, 3) = 0; mNext(1, 0) = RotationNext[1][0]; mNext(1, 1) = RotationNext[1][1]; mNext(1, 2) = RotationNext[1][2]; mNext(1, 3) = 0; mNext(2, 0) = RotationNext[2][0]; mNext(2, 1) = RotationNext[2][1]; mNext(2, 2) = RotationNext[2][2]; mNext(2, 3) = 0; mNext(3, 0) = PositionNext[0]; mNext(3, 1) = PositionNext[1]; mNext(3, 2) = PositionNext[2]; mNext(3, 3) = 1; //D3DXMATRIX world; //g_pD3DDevice->GetTransform(D3DTS_WORLD, &world); //D3DXMATRIX wrld = m * world; //g_pD3DDevice->SetTransform(D3DTS_WORLD, &wrld); m = m * (*matCur); mNext = mNext * (*matNext); DrawSkeleton(childMod, &m, &mNext); //g_pD3DDevice->SetTransform(D3DTS_WORLD, &world); } } void DrawModel(stM3DModel* pMod, D3DXMATRIX* matCur, D3DXMATRIX* matNext) { DrawModelInt(pMod, pMod->m_currentframe, pMod->m_nextFrame, matCur, matNext, pMod->m_poll); } IDirect3DVertexBuffer8* pVertexBuffer;*/ float aNorms[256][256][3]; void InitNormals() { for (int i = 0; i < 255; i++) { for (int j = 0; j < 255; j++) { float alpha = 2.0f * i * M_PI / 255; float beta = 2.0f * j * M_PI / 255; aNorms[i][j][0] = cosf(beta) * sinf(alpha); aNorms[i][j][1] = sinf(beta) * sinf(alpha); aNorms[i][j][2] = cosf(alpha); } } } /* void DrawModelInt(stM3DModel* pMod, const int currentFrame, const int nexFrame, D3DXMATRIX* matCur, D3DXMATRIX* matNext, float pol) { stMD3Header* pHeader = &pMod->m_md3Header; stMesh* pMeshes = pMod->m_pMeshes; struct TVERTEX { float x, y, z; float nx, ny, nz; float u, v; enum { FVF_TVERTEX = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 }; }; #if(0) // no lighting g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); #else g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); #endif g_pD3DDevice->SetTexture(0, NULL); for (int k = 0; k < pHeader->numMeshes; k++) { stMesh* currentMesh = &pMeshes[k]; //char* meshName = currentMesh->MeshHeader.Name; if (currentMesh->texID >= 0) { g_pD3DDevice->SetTexture(0, pTextures[currentMesh->texID]); } int currentOffsetVertex = currentFrame * currentMesh->MeshHeader.numVertexes; //interpolation int nextCurrentOffsetVertex = nexFrame * currentMesh->MeshHeader.numVertexes; int TriangleNum = currentMesh->MeshHeader.numTriangles; //TVERTEX * pVertices = new TVERTEX[TriangleNum * 3]; pVertexBuffer = NULL; g_pD3DDevice->CreateVertexBuffer(TriangleNum * 3 * sizeof(TVERTEX), D3DUSAGE_WRITEONLY, TVERTEX::FVF_TVERTEX, D3DPOOL_DEFAULT, &pVertexBuffer); TVERTEX* pVertices; pVertexBuffer->Lock(0, TriangleNum * 3 * sizeof(TVERTEX), (BYTE**)&pVertices, 0); int indx = 0; for (int i = 0; i < TriangleNum; i++) { //D3DXVECTOR3 tri[3]; for (int j = 0; j < 3; j++) { int currentVertex = currentMesh->pTriangle[i].Vertex[j]; D3DXVECTOR3 vA; vA.x = (currentMesh->pVertex[currentOffsetVertex + currentVertex].Vertex[0] / 64.0f); vA.y = (currentMesh->pVertex[currentOffsetVertex + currentVertex].Vertex[1] / 64.0f); vA.z = (currentMesh->pVertex[currentOffsetVertex + currentVertex].Vertex[2] / 64.0f); D3DXVECTOR3 nextVA; nextVA.x = (currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Vertex[0] / 64.0f); nextVA.y = (currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Vertex[1] / 64.0f); nextVA.z = (currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Vertex[2] / 64.0f); D3DXVec3TransformCoord(&vA, &vA, matCur); D3DXVec3TransformCoord(&nextVA, &nextVA, matNext); int normU, normV; normU = currentMesh->pVertex[currentOffsetVertex + currentVertex].Normal[0]; normV = currentMesh->pVertex[currentOffsetVertex + currentVertex].Normal[1]; D3DXVECTOR3 norm; norm[0] = aNorms[normU][normV][0]; norm[1] = aNorms[normU][normV][1]; norm[2] = aNorms[normU][normV][2]; normU = currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Normal[0]; normV = currentMesh->pVertex[nextCurrentOffsetVertex + currentVertex].Normal[1]; D3DXVECTOR3 normNext; normNext[0] = aNorms[normU][normV][0]; normNext[1] = aNorms[normU][normV][1]; normNext[2] = aNorms[normU][normV][2]; float u = currentMesh->pTexCoord[currentVertex].Coord[0]; float v = currentMesh->pTexCoord[currentVertex].Coord[1]; // Interplated value float nx = norm[0] + pol * (normNext[0] - norm[0]); float ny = norm[1] + pol * (normNext[1] - norm[1]); float nz = norm[2] + pol * (normNext[2] - norm[2]); float pA0 = vA[0] + pol * (nextVA[0] - vA[0]); float pA1 = vA[1] + pol * (nextVA[1] - vA[1]); float pA2 = vA[2] + pol * (nextVA[2] - vA[2]); //tri[j].x = pA0; //tri[j].y = pA1; //tri[j].z = pA2; pVertices[indx].x = pA0; pVertices[indx].y = pA1; pVertices[indx].z = pA2; pVertices[indx].nx = nx; pVertices[indx].ny = ny; pVertices[indx].nz = nz; pVertices[indx].u = u; pVertices[indx].v = v; indx++; } //DbgTriangle(g_pD3DDevice, tri[0], tri[1], tri[2], 0xff00ffff ); } pVertexBuffer->Unlock(); g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); g_pD3DDevice->SetVertexShader(TVERTEX::FVF_TVERTEX); g_pD3DDevice->SetStreamSource(0, pVertexBuffer, sizeof(TVERTEX)); g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, TriangleNum); pVertexBuffer->Release(); pVertexBuffer = NULL; } }*/ bool SetAnim(int ani) { if (ani >= 0 && ani <= 5) { m_lower.m_FPS = m_Anim[ani].FPS; m_upper.m_FPS = m_Anim[ani].FPS; m_lower.m_startFrame = m_Anim[ani].FirstFrame; m_upper.m_startFrame = m_Anim[ani].FirstFrame; //m_upper.m_currentframe = m_upper.m_startFrame; //m_lower.m_currentframe = m_lower.m_startFrame; m_lower.m_endFrame = m_Anim[ani].FirstFrame + m_Anim[ani].numFrames; m_upper.m_endFrame = m_Anim[ani].FirstFrame + m_Anim[ani].numFrames; m_lower.m_anim = ani; m_upper.m_anim = ani; } else if (ani >= 6 && ani <= 12) { m_upper.m_FPS = m_Anim[ani].FPS; m_upper.m_nextFrame = m_Anim[ani].FirstFrame; m_upper.m_startFrame = m_Anim[ani].FirstFrame; m_upper.m_endFrame = m_Anim[ani].FirstFrame + m_Anim[ani].numFrames; //m_upper.m_currentframe = m_upper.m_startFrame; m_upper.m_anim = ani; } else if (ani >= 13 && ani <= 24) { m_lower.m_FPS = m_Anim[ani].FPS; m_lower.m_nextFrame = m_Anim[ani].FirstFrame; m_lower.m_startFrame = m_Anim[ani].FirstFrame; m_lower.m_endFrame = m_Anim[ani].FirstFrame + m_Anim[ani].numFrames; //m_lower.m_currentframe = m_lower.m_startFrame; m_lower.m_anim = ani; } else { throw std::runtime_error("lol"); /*_asm { int 13; }*/ } return true; } bool LoadSkin(stM3DModel* pMod, const char* filename) { char buf[256]; char MeshName[256] = { 0 }; char ImageName[256] = { 0 }; FILE* fp = fopen(filename, "r"); if (fp == NULL) { abc("unable to open file"); return false; } //char firstWord[256]; char* val = NULL; int i = 0; do { memset(MeshName, 0, sizeof(MeshName)); val = fgets(buf, 256, fp); if (val == NULL) { break; } //sscanf(buf, "%s", firstWord); if (buf[strlen(buf) - 1] == '\n') { buf[strlen(buf) - 1] = NULL; } if (buf[strlen(buf) - 1] == ',') { strcpy(MeshName, buf); MeshName[strlen(MeshName) - 1] = NULL; } if (strncmp(buf, "tag_", 4) == 0) // tags dont have skins { continue; } char* pMeshNameEnd = strchr(buf, ','); int meshNameLen = (int)(pMeshNameEnd - buf); strncpy(MeshName, buf, meshNameLen); //char* pImageName = strstr(MeshName, ","); // get the full image and path name //strcpy(ImageName, pImageName); // get name from last / (i.e only filename) char* pName = strrchr(buf, '/'); strcpy(ImageName, pName + 1); for (int i = 0; i < pMod->m_md3Header.numMeshes; i++) { stMesh* pMesh = &pMod->m_pMeshes[i]; if (strcmp(pMesh->MeshHeader.Name, MeshName) == 0) { char TextureName[256]; strcpy(TextureName, SZ_MD3_TEXTURE_PATH); strcat(TextureName, ImageName); //D3DXCreateTextureFromFile(g_pD3DDevice, TextureName, &pTextures[g_NumLoadedTextures]); pMesh->texID = g_NumLoadedTextures; g_NumLoadedTextures++; } } // lose the starting / } while (val); return true; } bool LoadAnim(const char* filename) { char buf[256]; FILE* fp = fopen(filename, "r"); if (fp == NULL) { abc("unable to open file"); return false; } char firstWord[256]; char* val = NULL; int i = 0; do { strcpy(firstWord, "//"); val = fgets(buf, 256, fp); if (val == NULL) { break; } sscanf(buf, "%s", firstWord); if (strcmp("sex", firstWord) == NULL) { } else if (strcmp("headoffset", firstWord) == NULL) { } else if (strcmp("footsteps", firstWord) == NULL) { } else if (strcmp("", firstWord) == NULL) { } else if (strcmp("//", firstWord) == NULL) { } else { char words[4][256]; sscanf(buf, "%s %s %s %s", &words[0], &words[1], &words[2], &words[3]); // Extract the values of FirstFrame, numFrames, LoopingFrames, FPS from the String int FirstFrame = atoi(words[0]); int numFrames = atoi(words[1]); int loopingFrames = atoi(words[2]); int FPS = atoi(words[3]); m_Anim[i].FirstFrame = FirstFrame; m_Anim[i].numFrames = numFrames; m_Anim[i].LoopingFrames = loopingFrames; m_Anim[i].FPS = FPS; i++; } } while (val); int skip = m_Anim[LEGS_WALKCR].FirstFrame - m_Anim[TORSO_GESTURE].FirstFrame; for (int i = LEGS_WALKCR; i < MAX_ANIMATIONS; i++) { m_Anim[i].FirstFrame = m_Anim[i].FirstFrame - skip; } for (int i = 0; i < MAX_ANIMATIONS; i++) { if (m_Anim[i].numFrames > 0) { m_Anim[i].numFrames = m_Anim[i].numFrames - 1; } } fclose(fp); return true; } //----------------------------------------------------------------------- // // Loads model from a .md3 file // //----------------------------------------------------------------------- bool LoadModel(stM3DModel* pMod, const char* filename) { char buf[256]; FILE* fp = fopen(filename, "rb"); if (fp == NULL) { abc("unable to open file"); return false; } // Lets get the size of this md3 file int md3filesize = filesize(fp); fseek(fp, 0L, SEEK_SET); if (strlen(filename) > 255) { sprintf(buf, "filename is longer than %d", MAX_FILENAME_LENGTH); abc(buf); return false; } // copy name strcpy(pMod->m_md3FileName, filename); sprintf(buf, "MD3 FileName: %s", pMod->m_md3FileName); abc(buf); sprintf(buf, "FileSize: %d", md3filesize); abc(buf); abc("\n~~MD3 Header~~\n"); stMD3Header* pHeader = &pMod->m_md3Header; // read header fread(pHeader, 1, sizeof(stMD3Header), fp); /* // log debug information to file sprintf(buf, "ID %c%c%c%c", pHeader->ID[0], pHeader->ID[1], pHeader->ID[2], pHeader->ID[3]); abc(buf); sprintf(buf, "Version: %d", pHeader->Version); abc(buf); sprintf(buf, "FileName: %s", pHeader->Filename); abc(buf); sprintf(buf, "numBoneFrames: %d", pHeader->numBoneFrames); abc(buf); sprintf(buf, "numTags: %d", pHeader->numTags); abc(buf); sprintf(buf, "numMeshes: %d", pHeader->numMeshes); abc(buf); sprintf(buf, "numMaxSkins: %d", pHeader->numMaxSkins); abc(buf); sprintf(buf, "ofsFrames: %d", pHeader->ofsFrames); abc(buf); sprintf(buf, "ofsTagStart: %d", pHeader->ofsTagStart); abc(buf); sprintf(buf, "ofMeshSurfaces: %d", pHeader->ofMeshSurfaces); abc(buf); sprintf(buf, "ofEndOfFile (Filesize): %d", pHeader->ofEndOfFile); abc(buf); */ if (strcmp("IDP3", pHeader->ID) == NULL) { sprintf(buf, "Incorrect File Format 'Incorrect ID' ie. ('IDP3')"); abc(buf); } // Allocate memory for all or bones/tags/etc pMod->m_pBoneFrame = new stBoneFrame[pHeader->numBoneFrames]; pMod->m_pTags = new stTag[pHeader->numBoneFrames * pHeader->numTags]; pMod->m_pMeshes = new stMesh[pHeader->numMeshes]; stBoneFrame* pBoneFrame = pMod->m_pBoneFrame; stTag* pTags = pMod->m_pTags; stMesh* pMeshes = pMod->m_pMeshes; // Lets seek to the start of the bone frames & read boneframe fseek(fp, pHeader->ofsFrames, SEEK_SET); fread(pBoneFrame, 1, pHeader->numBoneFrames * sizeof(stBoneFrame), fp); /* sprintf(buf, "\n~~~~BoneFrames: %d~~~~~~", pHeader->numBoneFrames); abc(buf); for (int i=0; inumBoneFrames; i++) { abc("#"); sprintf(buf, "mins[%.1f,%.1f,%.1f]", m_pBoneFrame[i].mins[0], m_pBoneFrame[i].mins[1], m_pBoneFrame[i].mins[2]); abc(buf); sprintf(buf, "maxs[%.1f,%.1f,%.1f]", m_pBoneFrame[i].maxs[0], m_pBoneFrame[i].maxs[1], m_pBoneFrame[i].maxs[2]); abc(buf); sprintf(buf, "Position[%.1f,%.1f,%.1f]", m_pBoneFrame[i].Position[0], m_pBoneFrame[i].Position[1], m_pBoneFrame[i].Position[2]); abc(buf); sprintf(buf, "Scale[%.1f]", m_pBoneFrame[i].Scale); abc(buf); sprintf(buf, "Creator[%s]", m_pBoneFrame[i].Creator); abc(buf); } */ // Seek to start of tags and read them all in fseek(fp, pHeader->ofsTagStart, SEEK_SET); fread(pTags, 1, pHeader->numBoneFrames * pHeader->numTags * sizeof(stTag), fp); /* sprintf(buf, "\n~~~~Tags: %d~~~~~~", pHeader->numTags); abc(buf); for (int i=0; iofMeshSurfaces; for (int j = 0; j < pHeader->numMeshes; j++) { stMesh* pMesh = &pMeshes[j]; stMeshHeader* pMeshHeader = &(pMesh->MeshHeader); fseek(fp, meshOFS, SEEK_SET); // Seek to the start of the mesh data and read it all in fread(pMeshHeader, 1, sizeof(stMeshHeader), fp); // Read in all the sub parts of the mesh data { fseek(fp, meshOFS + pMeshHeader->ofsTriangles, SEEK_SET); pMesh->pTriangle = new stTriangle[pMeshHeader->numTriangles]; fread(pMesh->pTriangle, 1, pMeshHeader->numTriangles * sizeof(stTriangle), fp); fseek(fp, meshOFS + pMeshHeader->ofsSkins, SEEK_SET); pMesh->pSkins = new stSkin[pMeshHeader->numSkins]; fread(pMesh->pSkins, 1, pMeshHeader->numSkins * sizeof(stSkin), fp); fseek(fp, meshOFS + pMeshHeader->ofsTexVector, SEEK_SET); pMesh->pTexCoord = new stTexCoord[pMeshHeader->numVertexes]; fread(pMesh->pTexCoord, 1, pMeshHeader->numVertexes * sizeof(stTexCoord), fp); fseek(fp, meshOFS + pMeshHeader->ofsVertex, SEEK_SET); pMesh->pVertex = new stVertex[pMeshHeader->numVertexes * pMeshHeader->numMeshFrames]; fread(pMesh->pVertex, 1, pMeshHeader->numMeshFrames * pMeshHeader->numVertexes * sizeof(stVertex), fp); pMesh->texID = -1; } meshOFS += pMeshHeader->ofsEndMeshSize; }//End for meshes /* sprintf(buf, "\n~~~~Mesh Surfaces: %d~~~~~~", m_md3Header.numMeshes); abc(buf); for (int j=0; jMeshHeader); sprintf(buf, "ID [%c%c%c%c]", pMeshHeader->ID[0], pMeshHeader->ID[1], pMeshHeader->ID[2], pMeshHeader->ID[3]); abc(buf); sprintf(buf, "Name [%s]", pMeshHeader->Name); abc(buf); sprintf(buf, "flags [0x%.2X]", pMeshHeader->flags); abc(buf); sprintf(buf, "numMeshFrames [%d]", pMeshHeader->numMeshFrames); abc(buf); sprintf(buf, "numSkins [%d]", pMeshHeader->numSkins); abc(buf); sprintf(buf, "numVertexes [%d]", pMeshHeader->numVertexes); abc(buf); sprintf(buf, "numVertexes [%d]", pMeshHeader->numVertexes); abc(buf); sprintf(buf, "ofsTriangles [%d]", pMeshHeader->ofsTriangles); abc(buf); sprintf(buf, "ofsSkins [%d]", pMeshHeader->ofsSkins); abc(buf); sprintf(buf, "ofsTexVector [%d]", pMeshHeader->ofsTexVector); abc(buf); sprintf(buf, "ofsVertex [%d]", pMeshHeader->ofsVertex); abc(buf); sprintf(buf, "ofsEndMeshSize [%d]", pMeshHeader->ofsEndMeshSize); abc(buf); // Mesh Triangles for (int i=0; inumTriangles; i++) { stTriangle * pTri = &(pMesh->pTriangle[i]); sprintf(buf, "Triangle [%d,%d,%d]", pTri->Vertex[0], pTri->Vertex[1], pTri->Vertex[2]); abc(buf); } // Mesh Skins for (int i=0; inumSkins; i++) { stSkin * pSkin = &(pMesh->pSkins[i]); sprintf(buf, "Skin:Name [%s]", pSkin->Name); abc(buf); sprintf(buf, "Skin:Index [%d]", pSkin->index); abc(buf); } for (int i=0; inumVertexes; i++) { stTexCoord * pTex = &(pMesh->pTexCoord[i]); sprintf(buf, "TexCoord:Index [%.1f,%.1f]", pTex->Coord[0], pTex->Coord[1]); abc(buf); } for (int i=0; inumVertexes; i++) { stVertex* pVert = &(pMesh->pVertex[i]); sprintf(buf, "Vertice:Vertex [%d,%d,%d]", pVert->Vertex[0], pVert->Vertex[1], pVert->Vertex[2]); abc(buf); } } */ fclose(fp); /* for (int j=0; jpSkins; delete[] pMesh->pTexCoord; delete[] pMesh->pTriangle; delete[] pMesh->pVertex; pMesh->pSkins = NULL; pMesh->pTexCoord = NULL; pMesh->pTriangle = NULL; pMesh->pVertex = NULL; } delete[] m_pBoneFrame; delete[] m_pTags; delete[] m_pMeshes; m_pBoneFrame = NULL; m_pTags = NULL; m_pMeshes = NULL; */ return true; }// End LoadModel(..) bool ReleaseModel(stM3DModel* pMod) { stMD3Header* pHeader = &pMod->m_md3Header; stMesh* pMeshes = pMod->m_pMeshes; for (int j = 0; j < pHeader->numMeshes; j++) { stMesh* pMesh = &pMeshes[j]; delete[] pMesh->pSkins; delete[] pMesh->pTexCoord; delete[] pMesh->pTriangle; delete[] pMesh->pVertex; pMesh->pSkins = NULL; pMesh->pTexCoord = NULL; pMesh->pTriangle = NULL; pMesh->pVertex = NULL; } stBoneFrame* pBoneFrame = pMod->m_pBoneFrame; stTag* pTags = pMod->m_pTags; stMesh* pMshes = pMod->m_pMeshes; delete[] pBoneFrame; delete[] pTags; delete[] pMshes; pBoneFrame = NULL; pTags = NULL; pMshes = NULL; return true; } }; ZL::AnimatedModel CMD3::convertToAnimatedModel() { ZL::AnimatedModel result; result.parts.resize(3); std::array parts = { &this->m_head, &this->m_upper, &this->m_lower }; std::array, 3> textureNames = { //std::vector{"model/sarge/cigar.png", "model/sarge/band.png"}, std::vector{"model/sarge/band.png"}, std::vector{"model/sarge/band.png"}, std::vector{"model/sarge/band.png"} }; for (int m = 0; m < 3; m++) { int numMeshes = parts[m]->m_md3Header.numMeshes; result.parts[m].meshes.resize(numMeshes); for (int i = 0; i < textureNames[m].size(); i++) { std::string texName = textureNames[m][i]; //result.parts[m].textures.push_back(std::make_shared(ZL::CreateTextureDataFromPng(texName))); result.parts[m].textures.push_back(std::make_shared(ZL::CreateTextureDataFromBmp24("chair_01_Base_Color.bmp"))); } for (int n = 0; n < numMeshes; n++) { auto& pMesh = parts[m]->m_pMeshes[n]; auto& pMeshHeader = parts[m]->m_pMeshes[n].MeshHeader; for (int i = 0; i < pMeshHeader.numTriangles; i++) { stTriangle* pTri = &(pMesh.pTriangle[i]); stVertex* pVert0 = &(pMesh.pVertex[pTri->Vertex[0]]); stVertex* pVert1 = &(pMesh.pVertex[pTri->Vertex[1]]); stVertex* pVert2 = &(pMesh.pVertex[pTri->Vertex[2]]); ZL::Vector3f v0; v0.v[0] = pVert0->Vertex[0]; v0.v[1] = pVert0->Vertex[1]; v0.v[2] = pVert0->Vertex[2]; result.parts[m].meshes[n].PositionData.push_back(v0); ZL::Vector3f v1; v1.v[0] = pVert1->Vertex[0]; v1.v[1] = pVert1->Vertex[1]; v1.v[2] = pVert1->Vertex[2]; result.parts[m].meshes[n].PositionData.push_back(v1); ZL::Vector3f v2; v2.v[0] = pVert2->Vertex[0]; v2.v[1] = pVert2->Vertex[1]; v2.v[2] = pVert2->Vertex[2]; result.parts[m].meshes[n].PositionData.push_back(v2); stTexCoord* pTex0 = &(pMesh.pTexCoord[pTri->Vertex[0]]); stTexCoord* pTex1 = &(pMesh.pTexCoord[pTri->Vertex[1]]); stTexCoord* pTex2 = &(pMesh.pTexCoord[pTri->Vertex[2]]); ZL::Vector2f t0; t0.v[0] = pTex0->Coord[0]; t0.v[1] = pTex0->Coord[1]; result.parts[m].meshes[n].TexCoordData.push_back(t0); ZL::Vector2f t1; t1.v[0] = pTex1->Coord[0]; t1.v[1] = pTex1->Coord[1]; result.parts[m].meshes[n].TexCoordData.push_back(t1); ZL::Vector2f t2; t2.v[0] = pTex2->Coord[0]; t2.v[1] = pTex2->Coord[1]; result.parts[m].meshes[n].TexCoordData.push_back(t2); } } } return result; } ZL::AnimatedModel testLoadModel() { CMD3 md3; md3.Create(); ZL::AnimatedModel r = md3.convertToAnimatedModel(); r.RefreshRenderMeshes(); return r; }