| /****************************************************************************** | 
 |  | 
 |  @File         PVRTFixedPoint.cpp | 
 |  | 
 |  @Title        PVRTFixedPoint | 
 |  | 
 |  @Version       | 
 |  | 
 |  @Copyright    Copyright (c) Imagination Technologies Limited. | 
 |  | 
 |  @Platform     Independant | 
 |  | 
 |  @Description  Converts MAX exported meshes to fixed point objects for use with | 
 |                opengles lite. | 
 |  | 
 | ******************************************************************************/ | 
 | #include <math.h> | 
 | #include <string.h> | 
 | #include "PVRTContext.h" | 
 | #include "PVRTFixedPoint.h" | 
 |  | 
 | /******************************************************** | 
 | ** Most of the code only applies to CommonLite profile ** | 
 | ********************************************************/ | 
 | #ifdef PVRT_FIXED_POINT_ENABLE | 
 |  | 
 | /*!*************************************************************************** | 
 |  @Function		CreateFixedObjectMesh | 
 |  @Input			mesh	The mesh to create the fixed point version from | 
 |  @Returns		A fixed point version of mesh | 
 |  @Description	Converts model floating point data to fixed point | 
 | *****************************************************************************/ | 
 | HeaderStruct_Fixed_Mesh *CreateFixedObjectMesh(HeaderStruct_Mesh *mesh) | 
 | { | 
 | 	HeaderStruct_Fixed_Mesh *new_mesh = new HeaderStruct_Fixed_Mesh; | 
 |  | 
 | 	new_mesh->fCenter[0] = PVRTF2X(mesh->fCenter[0]); | 
 | 	new_mesh->fCenter[1] = PVRTF2X(mesh->fCenter[1]); | 
 | 	new_mesh->fCenter[2] = PVRTF2X(mesh->fCenter[2]); | 
 |  | 
 |  | 
 | 	new_mesh->nNumVertex = mesh->nNumVertex; | 
 | 	new_mesh->nNumFaces = mesh->nNumFaces; | 
 | 	new_mesh->nNumStrips = mesh->nNumStrips; | 
 | 	new_mesh->nMaterial = mesh->nMaterial; | 
 |  | 
 | 	if(mesh->nNumVertex) | 
 | 	{ | 
 | 		new_mesh->pVertex = new VERTTYPE[mesh->nNumVertex*3]; | 
 | 		for(unsigned int i = 0; i < mesh->nNumVertex*3; i++)		// each vertex is 3 floats | 
 | 			new_mesh->pVertex[i] = PVRTF2X(mesh->pVertex[i]); | 
 | 	} | 
 | 	else | 
 | 	{ | 
 | 		new_mesh->pVertex = 0; | 
 | 		new_mesh->nNumVertex = 0; | 
 | 	} | 
 |  | 
 | 	if(mesh->pUV) | 
 | 	{ | 
 | 		new_mesh->pUV = new VERTTYPE[mesh->nNumVertex*2]; | 
 | 		for(unsigned int i = 0; i < mesh->nNumVertex*2; i++)		// UVs come in pairs of floats | 
 | 			new_mesh->pUV[i] = PVRTF2X(mesh->pUV[i]); | 
 | 	} | 
 | 	else | 
 | 		new_mesh->pUV = 0; | 
 |  | 
 | 	if(mesh->pNormals) | 
 | 	{ | 
 | 		new_mesh->pNormals = new VERTTYPE[mesh->nNumVertex*3]; | 
 | 		for(unsigned int i = 0; i < mesh->nNumVertex*3; i++)		// each normal is 3 floats | 
 | 			new_mesh->pNormals[i] = PVRTF2X(mesh->pNormals[i]); | 
 | 	} | 
 | 	else | 
 | 	{ | 
 | 		new_mesh->pNormals = 0; | 
 | 	} | 
 |  | 
 | 	/* | 
 | 	 * Format of packedVerts is | 
 | 	 *		Position | 
 | 	 *		Normal / Colour | 
 | 	 *		UVs | 
 | 	 */ | 
 |  | 
 | #define MF_NORMALS 1 | 
 | #define MF_VERTEXCOLOR 2 | 
 | #define MF_UV 3 | 
 |  | 
 | 	if(mesh->pPackedVertex) | 
 | 	{ | 
 | 		unsigned int nPackedVertSize = mesh->nNumVertex * 3 + | 
 | 					(mesh->nFlags & MF_NORMALS		? mesh->nNumVertex * 3 : 0) + | 
 | 					(mesh->nFlags & MF_VERTEXCOLOR	? mesh->nNumVertex * 3 : 0) + | 
 | 					(mesh->nFlags & MF_UV			? mesh->nNumVertex * 2 : 0); | 
 |  | 
 | 		new_mesh->pPackedVertex = new VERTTYPE[nPackedVertSize]; | 
 | 		for(unsigned int i = 0; i < nPackedVertSize; i++) | 
 | 			new_mesh->pPackedVertex[i] = PVRTF2X(mesh->pPackedVertex[i]); | 
 | 	} | 
 | 	else | 
 | 		new_mesh->pPackedVertex = 0; | 
 |  | 
 | 	// simply copy reference to all properties which do not need conversion (indicies) | 
 |  | 
 | 	new_mesh->pVertexColor				= mesh->pVertexColor; | 
 | 	new_mesh->pVertexMaterial			= mesh->pVertexMaterial; | 
 | 	new_mesh->pFaces					= mesh->pFaces; | 
 | 	new_mesh->pStrips					= mesh->pStrips; | 
 | 	new_mesh->pStripLength				= mesh->pStripLength; | 
 |  | 
 | 	// we're leaving the patch stuff alone | 
 |  | 
 | 	new_mesh->Patch.nType				= mesh->Patch.nType; | 
 | 	new_mesh->Patch.nNumPatches			= mesh->Patch.nNumPatches; | 
 | 	new_mesh->Patch.nNumVertices		= mesh->Patch.nNumVertices; | 
 | 	new_mesh->Patch.nNumSubdivisions	= mesh->Patch.nNumSubdivisions; | 
 | 	new_mesh->Patch.pControlPoints		= mesh->Patch.pControlPoints; | 
 | 	new_mesh->Patch.pUVs				= mesh->Patch.pUVs; | 
 |  | 
 | 	return new_mesh; | 
 | } | 
 |  | 
 | /*!*************************************************************************** | 
 |  @Function		FreeFixedObjectMesh | 
 |  @Input			mesh	The mesh to delete | 
 |  @Description	Release memory allocated in CreateFixedObjectMesh() | 
 | *****************************************************************************/ | 
 | void FreeFixedObjectMesh(HeaderStruct_Fixed_Mesh* mesh) | 
 | { | 
 |  | 
 | 	delete[] mesh->pVertex; | 
 | 	delete[] mesh->pUV; | 
 | 	delete[] mesh->pNormals; | 
 | 	delete[] mesh->pPackedVertex; | 
 |  | 
 | 	delete mesh; | 
 | } | 
 |  | 
 | #endif | 
 |  | 
 | /*!*************************************************************************** | 
 |  @Function		PVRTLoadHeaderObject | 
 |  @Input			headerObj			Pointer to object structure in the header file | 
 |  @Return		directly usable geometry in fixed or float format as appropriate | 
 |  @Description	Converts the data exported by MAX to fixed point when used in OpenGL | 
 | 				ES common-lite profile. | 
 | *****************************************************************************/ | 
 | HeaderStruct_Mesh_Type *PVRTLoadHeaderObject(const void *headerObj) | 
 | { | 
 | #ifdef PVRT_FIXED_POINT_ENABLE | 
 | 	return (HeaderStruct_Mesh_Type*) CreateFixedObjectMesh((HeaderStruct_Mesh *) headerObj); | 
 | #else | 
 | 	HeaderStruct_Mesh_Type *new_mesh = new HeaderStruct_Mesh_Type; | 
 | 	memcpy (new_mesh,headerObj,sizeof(HeaderStruct_Mesh_Type)); | 
 | 	return (HeaderStruct_Mesh_Type*) new_mesh; | 
 | #endif | 
 | } | 
 |  | 
 | /*!*************************************************************************** | 
 |  @Function		PVRTUnloadHeaderObject | 
 |  @Input			headerObj			Pointer returned by LoadHeaderObject | 
 |  @Description	Releases memory allocated by LoadHeaderObject when geometry no longer | 
 | 				needed. | 
 | *****************************************************************************/ | 
 | void PVRTUnloadHeaderObject(HeaderStruct_Mesh_Type* headerObj) | 
 | { | 
 | #ifdef PVRT_FIXED_POINT_ENABLE | 
 | 	FreeFixedObjectMesh(headerObj); | 
 | #else | 
 | 	delete headerObj; | 
 | #endif | 
 | } | 
 |  | 
 | /***************************************************************************** | 
 |  End of file (PVRTFixedPoint.cpp) | 
 | *****************************************************************************/ | 
 |  |