MF_API MFMaterial* MFMaterial_Create(const char *pName) { MFCALLSTACK; MFMaterial *pMat = MFMaterial_Find(pName); if(!pMat) { pMat = (MFMaterial*)MFHeap_AllocAndZero(sizeof(MFMaterial) + MFString_Length(pName) + 1); pName = MFString_Copy((char*)&pMat[1], pName); MFResource_AddResource(pMat, MFRT_Material, MFUtil_HashString(pName) ^ 0x0a7e01a1, pName); // TODO: how to determine size? pMat->pMaterialState = MFStateBlock_Create(256); pMat->bStateDirty = true; MaterialDefinition *pDef = pDefinitionRegistry; while(pDef) { MFIniLine *pLine = pDef->pIni->GetFirstLine()->FindEntry("section",pName); if (pLine) { MaterialInternal_InitialiseFromDefinition(pDef->pIni, pMat, pName); break; } pDef = pDef->pNextDefinition; } if(!pDef) { // assign material type pMat->pType = MaterialInternal_GetMaterialType("Standard"); pMat->pInstanceData = MFHeap_AllocAndZero(pMat->pType->instanceDataSize); pMat->pType->materialCallbacks.pCreateInstance(pMat); // set diffuse map parameter MFMaterial_SetParameterS(pMat, MFMatStandard_Texture, MFMatStandard_Tex_DifuseMap, pName); } } return pMat; }
MF_API MFAnimation* MFAnimation_Create(const char *pFilename, MFModel *pModel) { MFAnimationTemplate *pTemplate = MFAnimation_FindTemplate(pFilename); if(!pTemplate) { size_t size = 0; pTemplate = (MFAnimationTemplate*)MFModelInternal_PendingAnimationTemplate(&size); if(!pTemplate) { MFFile *hFile = MFFileSystem_Open(MFStr("%s.anm", pFilename), MFOF_Read|MFOF_Binary); if(hFile) { size = (size_t)MFFile_GetSize(hFile); if(size > 0) { char *pTemplateData; // allocate memory and load file pTemplateData = (char*)MFHeap_Alloc(size + MFString_Length(pFilename) + 1); MFFile_Read(hFile, pTemplateData, size); pTemplate = (MFAnimationTemplate*)pTemplateData; // check ID string MFDebug_Assert(pTemplate->hash == MFMAKEFOURCC('A', 'N', 'M', '2'), "Incorrect MFAnimation version."); } MFFile_Close(hFile); } } if(!pTemplate) return NULL; pFilename = MFString_Copy((char*)pTemplate + size, pFilename); MFAnimation_FixUp(pTemplate, true); MFResource_AddResource(pTemplate, MFRT_AnimationTemplate, MFUtil_HashString(pFilename) ^ 0xA010A010, pFilename); } // get the model bone chunk MFModelDataChunk *pBoneChunk = MFModel_GetDataChunk(pModel->pTemplate, MFChunkType_Bones); MFDebug_Assert(pBoneChunk, "Cant apply animation to a model with no skeleton!"); // create and init instance MFAnimation *pAnimation; size_t bytes = MFALIGN16(sizeof(MFAnimation)) + sizeof(MFMatrix)*pBoneChunk->count + sizeof(int)*pBoneChunk->count + sizeof(MFAnimationCurrentFrame)*pBoneChunk->count; pAnimation = (MFAnimation*)MFHeap_Alloc(bytes); pAnimation->pModel = pModel; pAnimation->pTemplate = pTemplate; // add animation to model animation list pModel->pAnimation = pAnimation; // get bones pointer from model (for convenience) pAnimation->pBones = (MFModelBone*)pBoneChunk->pData; pAnimation->numBones = pBoneChunk->count; // set matrices to identity pAnimation->pMatrices = (MFMatrix*)MFALIGN16(&pAnimation[1]); for(int a=0; a<pBoneChunk->count; a++) { pAnimation->pMatrices[a] = MFMatrix::identity; } MFStateConstant_AnimationMatrices animMats; animMats.pMatrices = pAnimation->pMatrices; animMats.numMatrices = pAnimation->numBones; MFStateBlock_SetAnimMatrices(pModel->pEntityState, animMats); // build bone to animation stream mapping pAnimation->pBoneMap = (int*)MFALIGN16(&pAnimation->pMatrices[pBoneChunk->count]); for(int a=0; a<pBoneChunk->count; a++) { const char *pBoneName = MFModel_GetBoneName(pModel, a); // find bone in animation pAnimation->pBoneMap[a] = -1; for(uint32 b=0; b<pTemplate->numBones; b++) { if(!MFString_CaseCmp(pBoneName, pTemplate->pBones[b].pBoneName)) { pAnimation->pBoneMap[a] = b; break; } } } pAnimation->pCustomMatrices = NULL; pAnimation->blendLayer.frameTime = pAnimation->pTemplate->startTime; pAnimation->blendLayer.pCurFrames = (MFAnimationCurrentFrame*)&pAnimation->pBoneMap[pBoneChunk->count]; MFZeroMemory(pAnimation->blendLayer.pCurFrames, sizeof(MFAnimationCurrentFrame)*pBoneChunk->count); return pAnimation; }
MFAnimationTemplate* MFAnimation_FindTemplate(const char *pName) { return (MFAnimationTemplate*)MFResource_Find(MFUtil_HashString(pName) ^ 0xA010A010); }
MF_API MFMaterial* MFMaterial_Find(const char *pName) { return (MFMaterial*)MFResource_Find(MFUtil_HashString(pName) ^ 0x0a7e01a1); }