void Scan(MFString path) { MFFindData fd; MFFind *pFind = MFFileSystem_FindFirst(MFStr("%s*", path.CStr()), &fd); if(pFind) { do { if(fd.attributes & MFFA_Directory) { Scan(MFString::Format("%s%s/", path.CStr(), fd.pFilename).CStr()); } else { MFString ext = MFString(fd.pFilename).GetExtension(); if(ext.Enumerate(ppFormats, sizeof(ppFormats) / sizeof(ppFormats[0])) > -1) models.push(MFString::Format("%s%s", path.CStr(), fd.pFilename)); } } while(MFFileSystem_FindNext(pFind, &fd)); MFFileSystem_FindClose(pFind); } }
void ParseOBJFile(const char *pFilePtr) { const char *pToken = GetNextToken(pFilePtr); while(*pToken != 0) { if(!MFString_CaseCmp(pToken, "o")) { const char *pName = GetRestOfLine(pFilePtr); pModel->name = pName; } else if(!MFString_CaseCmp(pToken, "g")) { const char *pName = GetRestOfLine(pFilePtr); if(!vertsInGroup) { // we'll just rename the current subobject, since theres nothing in it.. F3DSubObject &sub = pModel->GetMeshChunk()->subObjects[subObject]; sub.name = pName; } else { // probably wanna copy vertex data in at this point.. // and subtract the min from each of the components indices.. CopyDataIntoSubobject(subObject); ++subObject; matSub = 0; minVertIndex = -1; minUVIndex = -1; minNormIndex = -1; maxVertIndex = -1; maxUVIndex = -1; maxNormIndex = -1; vertsInGroup = false; vertsInMatSub = false; F3DSubObject &sub = pModel->GetMeshChunk()->subObjects[subObject]; sub.name = pName; } } else if(!MFString_CaseCmp(pToken, "v")) { const char *pX = GetNextToken(pFilePtr); const char *pY = GetNextToken(pFilePtr); const char *pZ = GetNextToken(pFilePtr); pFilePtr = MFSeekNewline(pFilePtr); MFVector v; v.x = (float)atof(pX); v.y = (float)atof(pY); v.z = (float)atof(pZ); v.w = 1.0f; verts.push(v); } else if(!MFString_CaseCmp(pToken, "vt")) { const char *pU = GetNextToken(pFilePtr); const char *pV = GetNextToken(pFilePtr); pFilePtr = MFSeekNewline(pFilePtr); MFVector v; v.x = (float)atof(pU); v.y = (float)atof(pV); v.z = 0.0f; v.w = 1.0f; uvs.push(v); } else if(!MFString_CaseCmp(pToken, "vn")) { const char *pX = GetNextToken(pFilePtr); const char *pY = GetNextToken(pFilePtr); const char *pZ = GetNextToken(pFilePtr); pFilePtr = MFSeekNewline(pFilePtr); MFVector v; v.x = (float)atof(pX); v.y = (float)atof(pY); v.z = (float)atof(pZ); v.w = 1.0f; normals.push(v); } else if(!MFString_CaseCmp(pToken, "f")) { vertsInGroup = true; vertsInMatSub = true; F3DSubObject &sub = pModel->GetMeshChunk()->subObjects[subObject]; const char *pRestOfLine = GetRestOfLine(pFilePtr); int firstVert = (int)sub.matSubobjects[matSub].vertices.size(); pToken = GetNextToken(pRestOfLine); while(*pToken) { const char *pPos = GetNextIndex(pToken); const char *pUV = GetNextIndex(pToken); const char *pNorm = GetNextIndex(pToken); int posid = atoi(pPos); int texid = atoi(pUV); int normid = atoi(pNorm); if(posid < 0) posid = (int)verts.size() - posid; else posid = posid - 1; if(texid < 0) texid = (int)uvs.size() - texid; else texid = texid - 1; if(normid < 0) normid = (int)normals.size() - normid; else normid = normid - 1; minVertIndex = minVertIndex == -1 ? posid : MFMin(minVertIndex, posid); minUVIndex = minUVIndex == -1 ? texid : MFMin(minUVIndex, texid); minNormIndex = minNormIndex == -1 ? normid : MFMin(minNormIndex, normid); maxVertIndex = minVertIndex == -1 ? posid : MFMax(maxVertIndex, posid); maxUVIndex = maxUVIndex == -1 ? texid : MFMax(maxUVIndex, texid); maxNormIndex = maxNormIndex == -1 ? normid : MFMax(maxNormIndex, normid); int vi = (int)sub.matSubobjects[matSub].vertices.size(); int f = vi - firstVert; F3DVertex &vert = sub.matSubobjects[matSub].vertices[firstVert + f]; vert.position = posid; vert.uv[0] = texid; vert.normal = normid; // add a triangle if we are up to the third vert or beyond if(f >= 2) { F3DTriangle &tri = sub.matSubobjects[matSub].triangles.push(); tri.v[0] = firstVert; tri.v[1] = vi-1; tri.v[2] = vi; } pToken = GetNextToken(pRestOfLine); } } else if(!MFString_CaseCmp(pToken, "usemtl")) { F3DSubObject &sub = pModel->GetMeshChunk()->subObjects[subObject]; if(vertsInGroup && vertsInMatSub) { ++matSub; vertsInMatSub = false; } const char *pName = GetRestOfLine(pFilePtr); sub.matSubobjects[matSub].materialIndex = GetMaterialID(pName); } else if(!MFString_CaseCmp(pToken, "mtllib")) { // load material info? //.. pFilePtr = MFSeekNewline(pFilePtr); } else if(pToken[0] == '#') { pFilePtr = MFSeekNewline(pFilePtr); } else { MFDebug_Warn(2, MFStr("Unknown token encountered in obj file '%s'!", pToken)); pFilePtr = MFSeekNewline(pFilePtr); } pToken = GetNextToken(pFilePtr); } // want to copy vertex data into the last subobject at this point... if(vertsInGroup) { CopyDataIntoSubobject(subObject); } }
void LoadTextXFile(const char *pText) { const char *pTok = GetNextToken(pText, &pText); while(pTok) { if(!MFString_Compare(pTok, "Header")) { SkipToken(pText, "{"); int maj = GetInt(pText, &pText); int min = GetInt(pText, &pText); int flag = GetInt(pText, &pText); // printf("XFile V%d.%d, 0x%X\n", maj, min, flag); pTok = GetNextToken(pText, &pText); while(MFString_Compare(pTok, "}")) { pTok = GetNextToken(pText, &pText); } } else if(!MFString_Compare(pTok, "Frame")) { pText = ParseFrame(pText, MFMatrix::identity, -1); } else if(!MFString_Compare(pTok, "Mesh")) { gMeshChunks.push(XMeshChunk::Create(MFMatrix::identity, pText, "")); SkipSection(pText); } else if(!MFString_Compare(pTok, "AnimationSet")) { gAnimSets.push(pText); SkipSection(pText); } else if(!MFString_Compare(pTok, "template")) { // const char *pName = GetNextToken(pText, &pText); SkipSection(pText); } else { MFDebug_Warn(4, MFStr("Unknown token '%s'\n", pTok)); SkipSection(pText); } pTok = GetNextToken(pText, &pText); } int a; for(a=0; a<gMeshChunks.size(); a++) { ParseMesh(gMeshChunks[a].pMesh, gMeshChunks[a].mat, gMeshChunks[a].frameName); } for(a=0; a<gAnimSets.size(); a++) { ParseAnimationSet(gAnimSets[a]); } gMeshChunks.clear(); }
const char *ParseFrame(const char *pText, const MFMatrix &mat, int parentID) { char frameName[64]; const char *pName = GetNextToken(pText, &pText, frameName); MFMatrix worldMatrix = mat; F3DBone *pBone = NULL; if(!MFString_CaseCmpN(pName, "bn_", 3) || !MFString_CaseCmpN(pName, "z_", 2)) { int boneID = pModel->GetSkeletonChunk()->bones.size(); pBone = &pModel->GetSkeletonChunk()->bones[boneID]; F3DBone *pParent = parentID == -1 ? NULL : &pModel->GetSkeletonChunk()->bones[parentID]; parentID = boneID; MFString_Copy(pBone->name, pName); MFString_Copy(pBone->parentName, pParent ? pParent->name : ""); pBone->worldMatrix = mat; } if(MFString_Compare(pName, "{")) SkipToken(pText, "{"); const char *pTok = GetNextToken(pText, &pText); while(MFString_Compare(pTok, "}")) { if(!MFString_Compare(pTok, "Frame")) { pText = ParseFrame(pText, worldMatrix, parentID); } else if(!MFString_Compare(pTok, "FrameTransformMatrix")) { SkipToken(pText, "{"); MFMatrix localMatrix; GetFloatArray(pText, (float*)&localMatrix, 16, &pText); worldMatrix.Multiply(localMatrix, worldMatrix); if(pBone) { pBone->boneMatrix = localMatrix; pBone->worldMatrix = worldMatrix; } SkipToken(pText, ";"); SkipToken(pText, "}"); } else if(!MFString_Compare(pTok, "Mesh")) { gMeshChunks.push(XMeshChunk::Create(worldMatrix, pText, pName)); SkipSection(pText); } else { MFDebug_Warn(4, MFStr("Unexpected token '%s'\n", pTok)); SkipSection(pText); } pTok = GetNextToken(pText, &pText); } return pText; }