int MFFileNative_Open(MFFile *pFile, MFOpenData *pOpenData)
{
	MFCALLSTACK;

	MFDebug_Assert(pOpenData->cbSize == sizeof(MFOpenDataNative), "Incorrect size for MFOpenDataNative structure. Invalid pOpenData.");
	MFOpenDataNative *pNative = (MFOpenDataNative*)pOpenData;

	MFDebug_Assert(pOpenData->openFlags & (MFOF_Read|MFOF_Write), "Neither MFOF_Read nor MFOF_Write specified.");
	MFDebug_Assert((pNative->openFlags & (MFOF_Text|MFOF_Binary)) != (MFOF_Text|MFOF_Binary), "MFOF_Text and MFOF_Binary are mutually exclusive.");

	const char *pFilename = pNative->pFilename;
#if defined(MF_XBOX) || defined(MF_X360)
	pFilename = FixXBoxFilename(pFilename);
#endif

	if(pOpenData->openFlags & MFOF_CreateDirectory)
		MFFileNative_CreateDirectory(MFStr_GetFilePath(pFilename));

	DWORD access = 0, create = 0;

	// set the access flags and create mode
	if(pOpenData->openFlags & MFOF_Read)
		access |= GENERIC_READ;
	if(pOpenData->openFlags & (MFOF_Write|MFOF_Append))
	{
		if(pNative->openFlags & MFOF_Append)
			access |= FILE_APPEND_DATA;
		else
			access |= GENERIC_WRITE;

		if(pNative->openFlags & MFOF_Truncate)
			create = CREATE_ALWAYS;
		else
			create = OPEN_ALWAYS;
	}
	else
		create = OPEN_EXISTING;

	pFile->pFilesysData = CreateFile(MFString_UFT8AsWChar(pFilename), access, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL);

	if(pFile->pFilesysData == INVALID_HANDLE_VALUE)
	{
		pFile->pFilesysData = 0;
		return -1;
	}

	LARGE_INTEGER size;
	if(!GetFileSizeEx(pFile->pFilesysData, &size))
	{
		MFDebug_Warn(2, MFStr("Call: MFFileNative_Open() - Error: Couldn't get size for file '%s'.", pNative->pFilename));
		CloseHandle(pFile->pFilesysData);
		pFile->pFilesysData = 0;
		return -1;
	}

	pFile->createFlags = pOpenData->openFlags;
	pFile->offset = 0;
	pFile->length = size.QuadPart;

	MFString_Copy(pFile->fileIdentifier, pNative->pFilename);

	return 0;
}
void HKStringEntryLogic::Update()
{
	bool shiftL = !!MFInput_Read(Key_LShift, IDD_Keyboard);
	bool shiftR = !!MFInput_Read(Key_RShift, IDD_Keyboard);
	bool ctrlL = !!MFInput_Read(Key_LControl, IDD_Keyboard);
	bool ctrlR = !!MFInput_Read(Key_RControl, IDD_Keyboard);

	int keyPressed = 0;

	bool shift = shiftL || shiftR;
	bool ctrl = ctrlL || ctrlR;

#if defined(MF_WINDOWS)
	if(ctrl && MFInput_WasPressed(Key_C, IDD_Keyboard) && selectionStart != selectionEnd)
	{
		BOOL opened = OpenClipboard(apphWnd);

		if(opened)
		{
			int selMin = MFMin(selectionStart, selectionEnd);
			int selMax = MFMax(selectionStart, selectionEnd);

			int numChars = selMax-selMin;

			HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, numChars + 1);
			char *pString = (char*)GlobalLock(hData);

			MFString_Copy(pString, GetRenderString().SubStr(selMin, numChars).CStr());

			GlobalUnlock(hData);

			EmptyClipboard();
			SetClipboardData(CF_TEXT, hData);

			CloseClipboard();
		}
	}
	else if(ctrl && MFInput_WasPressed(Key_X, IDD_Keyboard) && selectionStart != selectionEnd)
	{
		BOOL opened = OpenClipboard(apphWnd);

		if(opened)
		{
			int selMin = MFMin(selectionStart, selectionEnd);
			int selMax = MFMax(selectionStart, selectionEnd);

			int numChars = selMax-selMin;

			HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, numChars + 1);
			char *pString = (char*)GlobalLock(hData);

			MFString_Copy(pString, GetRenderString().SubStr(selMin, numChars).CStr());

			GlobalUnlock(hData);

			EmptyClipboard();
			SetClipboardData(CF_TEXT, hData);

			CloseClipboard();

			ClearSelection();
		}
	}
	else if(ctrl && MFInput_WasPressed(Key_V, IDD_Keyboard))
	{
		BOOL opened = OpenClipboard(apphWnd);

		if(opened)
		{
			int selMin = MFMin(selectionStart, selectionEnd);
			int selMax = MFMax(selectionStart, selectionEnd);

			int numChars = selMax-selMin;

			HANDLE hData = GetClipboardData(CF_TEXT);
			MFString paste((const char*)GlobalLock(hData), true);

			buffer.Replace(selMin, numChars, paste);

			GlobalUnlock(hData);

			cursorPos = selMin + paste.NumBytes();
			selectionStart = selectionEnd = cursorPos;

			GlobalUnlock(hData);

			CloseClipboard();

			if((numChars || cursorPos != selMin) && changeCallback)
				changeCallback(buffer.CStr());
		}
	}
	else
#endif
	{
		// check for new keypresses
		for(int a=0; a<255; a++)
		{
			if(MFInput_WasPressed(a, IDD_Keyboard))
			{
				keyPressed = a;
				holdKey = a;
				repeatDelay = gRepeatDelay;
				break;
			}
		}

		// handle repeat keys
		if(holdKey && MFInput_Read(holdKey, IDD_Keyboard))
		{
			repeatDelay -= MFSystem_TimeDelta();
			if(repeatDelay <= 0.f)
			{
				keyPressed = holdKey;
				repeatDelay += gRepeatRate;
			}
		}
		else
			holdKey = 0;

		// if there was a new key press
		if(keyPressed)
		{
			switch(keyPressed)
			{
				case Key_Backspace:
				case Key_Delete:
				{
					if(selectionStart != selectionEnd)
					{
						ClearSelection();
					}
					else
					{
						if(keyPressed == Key_Backspace && cursorPos > 0)
						{
							buffer.ClearRange(--cursorPos, 1);
							selectionStart = selectionEnd = cursorPos;

							if(changeCallback)
								changeCallback(buffer.CStr());
						}
						else if(keyPressed == Key_Delete && cursorPos < buffer.NumBytes())
						{
							buffer.ClearRange(cursorPos, 1);
							selectionStart = selectionEnd = cursorPos;

							if(changeCallback)
								changeCallback(buffer.CStr());
						}
					}
					break;
				}

				case Key_Left:
				case Key_Right:
				case Key_Home:
				case Key_End:
				{
					if(ctrl)
					{
						if(keyPressed == Key_Left)
						{
							while(cursorPos && MFIsWhite(buffer[cursorPos-1]))
								--cursorPos;
							if(MFIsAlphaNumeric(buffer[cursorPos-1]))
							{
								while(cursorPos && MFIsAlphaNumeric(buffer[cursorPos-1]))
									--cursorPos;
							}
							else if(cursorPos)
							{
								--cursorPos;
								while(cursorPos && buffer[cursorPos-1] == buffer[cursorPos])
									--cursorPos;
							}
						}
						else if(keyPressed == Key_Right)
						{
							while(cursorPos < buffer.NumBytes() && MFIsWhite(buffer[cursorPos]))
								++cursorPos;
							if(MFIsAlphaNumeric(buffer[cursorPos]))
							{
								while(cursorPos < buffer.NumBytes() && MFIsAlphaNumeric(buffer[cursorPos]))
									++cursorPos;
							}
							else if(cursorPos < buffer.NumBytes())
							{
								++cursorPos;
								while(cursorPos < buffer.NumBytes() && buffer[cursorPos] == buffer[cursorPos-1])
									++cursorPos;
							}
						}
						else if(keyPressed == Key_Home)
							cursorPos = 0;
						else if(keyPressed == Key_End)
							cursorPos = buffer.NumBytes();
					}
					else
					{
						if(keyPressed == Key_Left)
							cursorPos = (!shift && selectionStart != selectionEnd ? MFMin(selectionStart, selectionEnd) : MFMax(cursorPos-1, 0));
						else if(keyPressed == Key_Right)
							cursorPos = (!shift && selectionStart != selectionEnd ? MFMax(selectionStart, selectionEnd) : MFMin(cursorPos+1, buffer.NumBytes()));
						else if(keyPressed == Key_Home)
							cursorPos = 0;	// TODO: if multiline, go to start of line..
						else if(keyPressed == Key_End)
							cursorPos = buffer.NumBytes();	// TODO: if multiline, go to end of line...
					}

					if(shift)
						selectionEnd = cursorPos;
					else
						selectionStart = selectionEnd = cursorPos;

					break;
				}

				default:
				{
					bool caps = MFInput_GetKeyboardStatusState(KSS_CapsLock);
					int ascii = MFInput_KeyToAscii(keyPressed, shift, caps);

					if(ascii && (!maxLen || buffer.NumBytes() < maxLen-1))
					{
						// check character exclusions
						if(MFIsNewline(ascii) && type != ST_MultiLine)
							break;
						if(ascii == '\t' && type != ST_MultiLine)
							break;
						if(type == ST_Numeric && !MFIsNumeric(ascii))
							break;
						if(include)
						{
							if(include.FindChar(ascii) < 0)
								break;
						}
						if(exclude)
						{
							if(exclude.FindChar(ascii) >= 0)
								break;
						}

						int selMin = MFMin(selectionStart, selectionEnd);
						int selMax = MFMax(selectionStart, selectionEnd);
						int selRange = selMax - selMin;

						const uint16 wstr[] = { (uint16)ascii, 0 };
						char insert[5];
						MFString_CopyUTF16ToUTF8(insert, wstr);
						buffer.Replace(selMin, selRange, insert);
						cursorPos = selMin + 1;

						selectionStart = selectionEnd = cursorPos;

						if(changeCallback)
							changeCallback(buffer.CStr());
					}
					break;
				}
			}
		}
	}
}
Example #3
0
void ParseOBJFile(const char *pFilePtr)
{
	const char *pToken = GetNextToken(pFilePtr);

	while(*pToken != 0)
	{
		if(!MFString_CaseCmp(pToken, "o"))
		{
			const char *pName = GetRestOfLine(pFilePtr);

			MFString_Copy(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];
				MFString_Copy(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];
				MFString_Copy(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 = 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 = verts.size() - posid;
				else
					posid = posid - 1;

				if(texid < 0)
					texid = uvs.size() - texid;
				else
					texid = texid - 1;

				if(normid < 0)
					normid = 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 = sub.matSubobjects[matSub].vertices.size();
				int f = vi - firstVert;

				F3DVertex &vert = sub.matSubobjects[matSub].vertices[firstVert + f];
				vert.position = posid;
				vert.uv1 = texid;
				vert.normal = normid;

				// add a triangle if we are up to the third vert or beyond
				if(f >= 2)
				{
					int curVert = sub.matSubobjects[matSub].vertices.size() - 1;

					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);
	}
}
Example #4
0
int ReadMesh(char** buf, int frmcount, float scale, uint32 flags)
{
	if(!*buf) return 1;

	MEMesh2 *mesh=(MEMesh2*)*buf;
	MEMD2_VERTEX *vb;

	if(!scale) scale=1.0f;

	*buf+=sizeof(MEMesh2);

	if(!mesh->vcount || !mesh->icount) return 1;

	mesh->Scale.x=65525.0f/mesh->Scale.x;
	mesh->Scale.y=65525.0f/mesh->Scale.y;
	mesh->Scale.z=65525.0f/mesh->Scale.z;

	mesh->UVScale.x=65525.0f/mesh->UVScale.x;
	mesh->UVScale.y=65525.0f/mesh->UVScale.y;

	F3DSubObject &sub = pModel->GetMeshChunk()->subObjects.push();
	MFString_Copy(sub.name, mesh->Name);
	sub.matSubobjects[0].materialIndex = mesh->MaterialID;

	// read vertex data
	for(int a=0; a<frmcount; a++)
	{
		vb=(MEMD2_VERTEX*)*buf;

		if(a == 0) // only first frame for now...
		{
			for(int b=0; b<mesh->vcount; b++)
			{
				UnpackVertex(&vb[b], mesh, scale, sub);
			}
		}

		*buf+=sizeof(MEMD2_VERTEX)*mesh->vcount;
	}

	// read triangles
	MFDebug_Assert(mesh->icount % 3 == 0, "Incorrect number of indices...");

	F3DMaterialSubobject &msub = sub.matSubobjects[0];

	uint16 *pI = (uint16*)*buf;
	int tris =0;
	int v = 0;

	for(int a=0; a<mesh->icount; a++)
	{
		msub.triangles[tris].v[v] = pI[a];

		++v;
		if(v>=3)
		{
			v = 0;
			++tris;
		}
	}

	*buf+=sizeof(unsigned short)*mesh->icount;

	return 0;
}
Example #5
0
MF_API MFModel* MFModel_Create(const char *pFilename)
{
	const char* pOriginalFilename = pFilename;

	// see if it's already loaded
	MFModelPool::Iterator it = gModelBank.Get(pOriginalFilename);
	MFModelTemplate *pTemplate = it ? *it : NULL;

	if(!pTemplate)
	{
		char *pTemplateData = NULL;

		MFFile *hFile = MFFileSystem_Open(MFStr("%s.mdl", pFilename), MFOF_Read|MFOF_Binary);
		if(hFile)
		{
			int64 size = MFFile_GetSize(hFile);

			if(size > 0)
			{
				// allocate memory and load file
				pTemplateData = (char*)MFHeap_Alloc((size_t)size + MFString_Length(pFilename) + 1);
				MFFile_Read(hFile, pTemplateData, (size_t)size);
				MFFile_Close(hFile);

				MFString_Copy(&pTemplateData[size], pFilename);
				pFilename = &pTemplateData[size];
			}
		}
		else
		{
#if defined(ALLOW_LOAD_FROM_SOURCE_DATA)
			// try to load from source data
			const char * const pExt[] = { ".f3d", ".dae", ".x", ".ase", ".obj", ".md2", ".md3", ".me2", NULL };
			const char * const *ppExt = pExt;
			MFIntModel *pIM = NULL;
			while(!pIM && *ppExt)
			{
				MFString tempFilename = MFString::Format("%s%s", pFilename, *ppExt);
				pIM = MFIntModel_CreateFromFile(tempFilename.CStr());
				if(pIM)
				{
					pFilename = MFString_Copy((char*)MFHeap_Alloc(tempFilename.NumBytes()+1), tempFilename.CStr());
					break;
				}
				++ppExt;
			}

			if(pIM)
			{
				MFIntModel_Optimise(pIM);

				size_t size;
				MFIntModel_CreateRuntimeData(pIM, (void**)&pTemplateData, &size, MFSystem_GetCurrentPlatform());

				MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s.mdl", pOriginalFilename), MFOF_Write | MFOF_Binary);
				if(pFile)
				{
					MFFile_Write(pFile, pTemplateData, size, false);
					MFFile_Close(pFile);
				}

				MFIntModel_Destroy(pIM);
			}
#endif
		}

		if(!pTemplateData)
			return NULL;

		// check ID string
		MFDebug_Assert(*(uint32*)pTemplateData == MFMAKEFOURCC('M', 'D', 'L', '2'), "Incorrect MFModel version.");

		// store filename for later reference
		pTemplate = (MFModelTemplate*)pTemplateData;
		pTemplate->pFilename = pFilename;

		gModelBank.Add(pOriginalFilename, pTemplate);

		MFModel_FixUp(pTemplate, true);

		MFModelDataChunk *pChunk = MFModel_GetDataChunk(pTemplate, MFChunkType_SubObjects);

		if(pChunk)
		{
			MFModelSubObject *pSubobjects = (MFModelSubObject*)pChunk->pData;

			for(int a=0; a<pChunk->count; a++)
			{
//				pSubobjects[a].pMaterial = MFMaterial_Create((char*)pSubobjects[a].pMaterial);

				for(int b=0; b<pSubobjects[a].numMeshChunks; b++)
				{
					MFModel_CreateMeshChunk(MFModel_GetMeshChunkInternal(pTemplate, a, b));
				}
			}
		}
	}

	MFModel *pModel;
	pModel = (MFModel*)MFHeap_Alloc(sizeof(MFModel));

	pModel->worldMatrix = MFMatrix::identity;
	pModel->modelColour = MFVector::one;
	pModel->pTemplate = pTemplate;
	pModel->pAnimation = NULL;

	++pTemplate->refCount;

	return pModel;
}
Example #6
0
void ParseMEMD2File(char *pBuffer)
{
	char *buf;
	int a;
	MEHeader *head;
	MEMaterial2 *material;

	bool bWriteOutImage = false;

	buf=pBuffer;
	head=(MEHeader*)pBuffer;

	if(head->ID!=MEMD_ID)
	{
		return;
	}

	if(!(head->Version>=200 && head->Version<300))
	{
		return;
	}

	CalcNormTable();

	MFString_Copy(pModel->name, head->Name);
	MFString_Copy(pModel->author, head->Creator);

	if(head->SequenceCount)
	{
		MESequence2 *pSequences = (MESequence2*)(pBuffer+head->SequenceStart);

		// do some shit for each one
	}

	if(head->MaterialCount)
	{
		buf=pBuffer+head->MaterialStart;
		material=(MEMaterial2*)buf;

		for(a=0; a<head->MaterialCount; a++)
		{
			F3DMaterial &mat = pModel->GetMaterialChunk()->materials.push();

			// material name
//			MFString_Copy(mat.name, material->Name);

			// use texture name instead of material name
			char *pTex = material->TextureFileName;
			pTex += MFString_Length(pTex);

			while(pTex > material->TextureFileName && pTex[-1] != '/' && pTex[-1] != '\\')
			{
				--pTex;
			}

			pTex[MFString_Length(pTex) - 4] = NULL;

			MFString_Copy(mat.name, pTex);

			// material parameters
			mat.specularLevel = material->matPower;
			mat.ambient.x = material->matColours[0].r;
			mat.ambient.y = material->matColours[0].g;
			mat.ambient.z = material->matColours[0].b;
			mat.ambient.w = material->matColours[0].a;

 			buf += 64 + sizeof(v4[4]) + sizeof(float) + sizeof(int);

			if(material->TextureCount)
			{
				buf+=260;

				if(material->ImageLen)
				{
#if 0
					if(bWriteOutImage)
					{
						FILE *pFile = fopen(material->TextureFileName, "wb");
						if(pFile)
						{
							fwrite(material->ImageBuffer, 1, material->ImageLen, pFile);
							fclose(pFile);
						}
					}
#endif

					buf+=material->ImageLen;
				}
			}

			buf+=8;

			material=(MEMaterial2*)buf;
		}

	}

	if(head->FrameCount&&head->MeshCount)
	{
		buf=pBuffer+head->FrameStart;

		for(a=0; a<head->MeshCount; a++)
		{
			ReadMesh(&buf, head->FrameCount, 1.0f, 0);
		}
	}

	return;
}
Example #7
0
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;
}
Example #8
0
const char *ParseMesh(const char *pText, const MFMatrix &mat, const char *pFrameName)
{
	// read name
	char meshName[64];
	const char *pMeshName = GetNextToken(pText, &pText, meshName);

	if(!MFString_Compare(pMeshName, "{"))
		pMeshName = pFrameName;
	else
		SkipToken(pText, "{");

	if(MFString_CaseCmpN(pMeshName, "m_", 2))
	{
		// not a mesh!
		SkipSection(pText);
		return pText;
	}

	F3DMeshChunk *pMesh = pModel->GetMeshChunk();
	F3DSubObject &sub = pMesh->subObjects.push();

	MFString_Copy(sub.name, pMeshName);

	// get num positions
	int numPositions = GetInt(pText, &pText);

	sub.positions.resize(numPositions);

	// read positions
	for(int a=0; a<numPositions; a++)
	{
		sub.positions[a].x = GetFloat(pText, &pText);
		sub.positions[a].y = GetFloat(pText, &pText);
		sub.positions[a].z = GetFloat(pText, &pText);

		sub.positions[a] = ApplyMatrixH(sub.positions[a], mat);

		if(a < numPositions-1)
			SkipToken(pText, ",");
	}
	SkipToken(pText, ";");

	// get num faces
	int numFaces = GetInt(pText, &pText);

	// see if we have a material face mapping
	int *pMatFaces = ParseMaterialList(pText, sub, numFaces);

	// read faces
	int face[16], numVerts[16], numTris[16];
	MFZeroMemory(numVerts, sizeof(numVerts));
	MFZeroMemory(numTris, sizeof(numTris));
	for(int a=0; a<numFaces; a++)
	{
		int matSub = pMatFaces ? pMatFaces[a] : 0;
		F3DMaterialSubobject &matsub = sub.matSubobjects[matSub];

		int numPoints = GetInt(pText, &pText);
		MFDebug_Assert(numPoints < 16, "Exceeded maximum 16 points per face...");
		GetIntArray(pText, face, numPoints, &pText);

		int firstVert = numVerts[matSub];
		numVerts[matSub] += numPoints;
		if(matsub.vertices.size() < numVerts[matSub])
			matsub.vertices.resize(numVerts[matSub]);

		int firstTri = numTris[matSub];
		numTris[matSub] += numPoints-2;
		if(matsub.triangles.size() < numTris[matSub])
			matsub.triangles.resize(numTris[matSub]);

		for(int b=0; b<numPoints; b++)
			matsub.vertices[firstVert+b].position = face[b];

		for(int b=0; b<numPoints-2; b++)
		{
			matsub.triangles[firstTri+b].v[0] = firstVert+0;
			matsub.triangles[firstTri+b].v[1] = firstVert+b+1;
			matsub.triangles[firstTri+b].v[2] = firstVert+b+2;
		}

		if(a < numFaces-1)
			SkipToken(pText, ",");
	}
	SkipToken(pText, ";");

	const char *pTok = GetNextToken(pText, &pText);

	while(MFString_Compare(pTok, "}"))
	{
		if(!MFString_Compare(pTok, "MeshMaterialList"))
		{
			SkipSection(pText);
		}
		else if(!MFString_Compare(pTok, "MeshNormals"))
		{
			pText = ParseNormals(pText, sub, mat, numFaces, pMatFaces);
		}
		else if(!MFString_Compare(pTok, "MeshTextureCoords"))
		{
			pText = ParseTexCoords(pText, sub, numPositions);
		}
		else if(!MFString_Compare(pTok, "MeshVertexColors"))
		{
			pText = ParseColours(pText, sub, numPositions);
		}
		else if(!MFString_Compare(pTok, "XSkinMeshHeader"))
		{
			SkipToken(pText, "{");

			// get num positions
			int nMaxSkinWeightsPerVertex = GetInt(pText, &pText);
			int nMaxSkinWeightsPerFace = GetInt(pText, &pText);
			int nBones = GetInt(pText, &pText);

			// not yet sure how this helps...
/*
			for(int m=0; m<sub.matSubobjects.size(); m++)
			{
				sub.matSubobjects[m].numBones = nBones;
			}
*/

			SkipToken(pText, "}");
		}
		else if(!MFString_Compare(pTok, "SkinWeights"))
		{
			pText = ParseSkinWeights(pText, sub, numPositions);
		}
		else if(!MFString_Compare(pTok, "DeclData"))
		{
			SkipSection(pText);
		}
		else
		{
			MFDebug_Warn(4, MFStr("Unknown token '%s'\n", pTok));
			SkipSection(pText);
		}

		pTok = GetNextToken(pText, &pText);
	}

	// we should order the bone weights into the most to least weighting.

	return pText;
}
Example #9
0
int* ParseMaterialList(const char *pText, F3DSubObject &sub, int numFaces)
{
	int *pMatFaces = NULL;

	const char *pMatList = FindSectionInScope(pText, "MeshMaterialList");

	if(pMatList)
	{
		SkipToken(pMatList, "MeshMaterialList");
		SkipToken(pMatList, "{");

		int numMats = GetInt(pMatList, &pMatList);
		MFDebug_Assert(numMats < 16, "Exceeded maximum 16 materials per subobject...");
		int numMatFaces = GetInt(pMatList, &pMatList);
		MFDebug_Assert(numMatFaces == numFaces, "Number of material faces does not match number of mesh faces");

		pMatFaces = (int*)MFHeap_Alloc(sizeof(int)*numMatFaces);
		GetIntArray(pMatList, pMatFaces, numMatFaces, &pMatList);

		// process materials...
		const char *pToken = GetNextToken(pMatList, &pMatList);
//		MFDebug_Assert(!MFString_Compare(pToken, ";"), "Value is not terminated with a semicolon.\n");

		if(!MFString_Compare(pToken, ";"))
			pToken = GetNextToken(pMatList, &pMatList);

		while(MFString_Compare(pToken, "}"))
		{
			if(!MFString_Compare(pToken, "Material"))
			{
				const char *pMatName = GetNextToken(pMatList, &pToken);

				if(MFString_Compare(pMatName, "{"))
					pMatList = pToken;
				else
					pMatName = "Unknown Material";

				int matID = pModel->GetMaterialChunk()->GetMaterialIndexByName(pMatName);

				F3DMaterialSubobject &matSub = sub.matSubobjects.push();

				if(matID != -1)
				{
					matSub.materialIndex = matID;
					SkipSection(pMatList);
				}
				else
				{
					matSub.materialIndex = pModel->GetMaterialChunk()->materials.size();
					F3DMaterial &mat = pModel->GetMaterialChunk()->materials.push();
					MFString_CopyN(mat.name, pMatName, 64);

					SkipToken(pMatList, "{");

					mat.diffuse.x = GetFloat(pMatList, &pMatList);
					mat.diffuse.y = GetFloat(pMatList, &pMatList);
					mat.diffuse.z = GetFloat(pMatList, &pMatList);
					mat.diffuse.w = GetFloat(pMatList, &pMatList);
					SkipToken(pMatList, ";");

					mat.specularLevel = GetFloat(pMatList, &pMatList);

					mat.specular.x = GetFloat(pMatList, &pMatList);
					mat.specular.y = GetFloat(pMatList, &pMatList);
					mat.specular.z = GetFloat(pMatList, &pMatList);
					mat.diffuse.w = 0.0f;
					SkipToken(pMatList, ";");

					mat.emissive.x = GetFloat(pMatList, &pMatList);
					mat.emissive.y = GetFloat(pMatList, &pMatList);
					mat.emissive.z = GetFloat(pMatList, &pMatList);
					mat.emissive.w = 0.0f;
					SkipToken(pMatList, ";");

					// any textures...
					pToken = GetNextToken(pMatList, &pMatList);

					while(MFString_Compare(pToken, "}"))
					{
						if(!MFString_Compare(pToken, "TextureFilename"))
						{
							SkipToken(pMatList, "{");
							MFString_Copy(mat.maps[0], GetString(pMatList, &pMatList));
							SkipToken(pMatList, "}");
						}
						else
						{
							MFDebug_Warn(4, MFStr("Unknown token '%s'\n", pToken));
						}

						pToken = GetNextToken(pMatList, &pMatList);
					}
				}
			}
			else if(!MFString_Compare(pToken, "{"))
			{
				// read material name
				const char *pMatName = GetNextToken(pMatList, &pMatList);

				int matID = pModel->GetMaterialChunk()->GetMaterialIndexByName(pMatName);

				F3DMaterialSubobject &matSub = sub.matSubobjects.push();

				if(matID != -1)
				{
					matSub.materialIndex = matID;
				}
				else
				{
					matSub.materialIndex = pModel->GetMaterialChunk()->materials.size();
					F3DMaterial &mat = pModel->GetMaterialChunk()->materials.push();
					MFString_CopyN(mat.name, pMatName, 64);
				}

				pToken = GetNextToken(pMatList, &pMatList);
				MFDebug_Assert(!MFString_Compare(pToken, "}"), "Scope not closed.\n");
			}
			else
			{
				MFDebug_Warn(4, MFStr("Unknown token '%s'\n", pToken));
			}

			pToken = GetNextToken(pMatList, &pMatList);
		}
	}

	return pMatFaces;
}
Example #10
0
	static XMeshChunk Create(const MFMatrix &_mat, const char *_pMesh, const char *pFrameName) { XMeshChunk mc; mc.mat = _mat; mc.pMesh = _pMesh; MFString_Copy(mc.frameName, pFrameName); return mc; }