Example #1
0
///
//Frees resuorces allocated by an Asset Buffer
//Deletes data being held in buffer!!
//
//PArameters:
//	buffer: pointer to The buffer to free
static void AssetManager_FreeBuffer(AssetBuffer* buffer)
{
	for (int i = 0; i < buffer->meshMap->data->capacity; i++)
	{
		//Mesh_Free((Mesh*)buffer->meshMap->data[i]->data);
		Mesh* m = *(Mesh**)DynamicArray_Index(buffer->meshMap->data, i);
		if(m != NULL)
		{
			Mesh_Free(m);
		}
	}
	HashMap_Free(buffer->meshMap);

	//for (int i = 0; i < buffer->textureMap->size; i++)
	for (int i = 0; i < buffer->textureMap->data->capacity; i++)
	{
		//Texture_Free((Texture*)buffer->meshMap->data[i]->data);
		Texture* t = *(Texture**)DynamicArray_Index(buffer->textureMap->data, i);
		if(t != NULL)
		{
			Texture_Free(t);
		}
	}

	HashMap_Free(buffer->textureMap);
}
Example #2
0
///
//Frees resuorces allocated by an Asset Buffer
//Deletes data being held in buffer!!
//
//PArameters:
//	buffer: pointer to The buffer to free
static void AssetManager_FreeBuffer(AssetBuffer* buffer)
{
	for (unsigned int i = 0; i < buffer->meshMap->data->capacity; i++)
	{
		struct HashMap_KeyValuePair* pair = *(struct HashMap_KeyValuePair**)DynamicArray_Index(buffer->meshMap->data, i);
		if(pair != NULL)
		{
			Mesh* m = (Mesh*)pair->data;
			Mesh_Free(m);
			//Following line will be done by HashMap_Free
			//HashMap_KeyValuePair_Free(pair);
		}
	}
	printf("Meshes freed\n");
	HashMap_Free(buffer->meshMap);
	printf("MeshMap freed\n");

	for (unsigned int i = 0; i < buffer->textureMap->data->capacity; i++)
	{
		struct HashMap_KeyValuePair* pair = *(struct HashMap_KeyValuePair**)DynamicArray_Index(buffer->textureMap->data, i);
		if(pair != NULL)
		{
			Texture* t = (Texture*)pair->data;
			Texture_Free(t);
		}
	}
	printf("Textures freed.\n");
	HashMap_Free(buffer->textureMap);

	printf("Texture Map Freed.\n");
}
Example #3
0
///
//Frees data allocated by an oct tree node
//
//Parameters:
//	tree: A pointer to the oct tree which the node being freed is apart of
//	node: A pointer to the oct tree node to free
static void OctTree_Node_Free(OctTree* tree, struct OctTree_Node* node)
{
	//If this node has children
	if(node->children != NULL)
	{
		for(int i = 0; i < 8; i++)
		{
			//Free the children!
			OctTree_Node_Free(tree, node->children + i);
		}
		//Free the children container...
		free(node->children);
	}
	else
	{
		//TODO: Figure out the proper way to deal with the freeing of the tree's hashmap.
		//Loop through the occupants of this list
		for(unsigned int i = 0; i < node->data->size; i++)
		{
			GObject* occupant = *(GObject**)DynamicArray_Index(node->data, i);
			//If the occupant still has a log in the hashmap
			if(HashMap_Contains(tree->map, &occupant, sizeof(GObject*)))
			{
				//Get the log of the occupant from the hashmap
				DynamicArray* log = (DynamicArray*)HashMap_LookUp(tree->map, &occupant, sizeof(GObject*))->data;	
				//Find this node in the log
				struct OctTree_NodeStatus* status = NULL;
				for(unsigned int j = 0; j < log->size; j++)
				{
					status = (struct OctTree_NodeStatus*)DynamicArray_Index(log, j);
					
					if(status->node == node)
					{
						//When we find it, remove this node from the log.
						DynamicArray_RemoveAndReposition(log, j);
						//If there is no other nodes logged, delete the log.
						if(log->size == 0)
						{
							HashMap_Remove(tree->map, &occupant, sizeof(GObject*));
							DynamicArray_Free(log);
						}

						//Stop looping
						break;
					}
				}
			}
			
		}
	}

	//Free the data contained within this tree
	DynamicArray_Free(node->data);

	//The parent node does the following, we must only free the root at the end.
	//Free this node
	//free(node);
}
Example #4
0
///
//Takes an existing key value pair and re-hashes and re-adds it to the hashmap
//To be used when a hashmap is growing in size
//
//Parameters:
//	map: THe hashmap the existing pair is being added to
//	pair: THe pair to add
static void HashMap_AddPair(HashMap* map, struct HashMap_KeyValuePair* pair)
{
	unsigned int hash = map->Hash(pair->key, pair->keyLength);
	unsigned int index = hash % map->data->capacity;

	while(*(struct HashMap_KeyValuePair**)DynamicArray_Index(map->data, index) != NULL)
	{
		index = (index + 1) % map->data->capacity;
	}

	*(struct HashMap_KeyValuePair**)DynamicArray_Index(map->data, index) = pair;
	map->data->size++;
}
Example #5
0
///
//Checks if a key is contained within the hashmap
//
//Parameters:
//	map: The map to search
//	key: The key to search for
//	keyLength: The length of the key in bytes
unsigned char HashMap_Contains(HashMap* map, void* key, unsigned int keyLength)
{
	unsigned int index = (map->Hash(key, keyLength) % map->data->capacity);
	struct HashMap_KeyValuePair* pair = NULL;
	for(unsigned int i = 0; i < map->data->capacity; i++)
	{
		pair = *(struct HashMap_KeyValuePair**)DynamicArray_Index(map->data, (index + i) % map->data->capacity);


		if(pair == NULL)
		{
			//This cannot be assumed because what if there is a collision, then the object which initially caused the collision is removed
			//And we search for the object which was subject to the collision.
			//break;
		}
		else
		{
			if(keyLength == pair->keyLength)
			{
				if(memcmp(key, pair->key, pair->keyLength) == 0) return 1;
			}
		}
	}
	return 0;
}
Example #6
0
///
//Adds data to a hashmap
//
//Parameters:
//	map: Map to add to
//	key: Key to retrieve data later
//	data: pointer to The data being added
//	keyLength: The size of the key in bytes
void HashMap_Add(HashMap* map, void* key, void* data, unsigned int keyLength)
{
	struct HashMap_KeyValuePair* pair = HashMap_KeyValuePair_Allocate();
	HashMap_KeyValuePair_Initialize(pair, key, data, keyLength);

	unsigned int index = map->Hash(key, keyLength) % map->data->capacity;
	while(*(struct HashMap_KeyValuePair**)DynamicArray_Index(map->data, index) != NULL)
	{
		index = (index + 1) % map->data->capacity;
	}

	*(struct HashMap_KeyValuePair**)DynamicArray_Index(map->data, index) = pair;
	map->data->size++;

	//If the array needs to grow
	if(map->data->size == map->data->capacity)
	{
		HashMap_Grow(map);
	}
}
Example #7
0
///
//Looks up a key and returns the related data
//
//Parameters:
//	map: The HashMap to lookup data in
//	key: The key related to the data
//	keyLength: The size of the key in bytes
//
//Returns:
//	Pointer to data
struct HashMap_KeyValuePair* HashMap_LookUp(HashMap* map, void* key, unsigned int keyLength)
{
	unsigned int index = (map->Hash(key, keyLength) % map->data->capacity);
	struct HashMap_KeyValuePair* pair = 0;
	for (unsigned int i = 0; i < map->data->capacity; i++)
	{
		pair = *(struct HashMap_KeyValuePair**)DynamicArray_Index(map->data, (index + i) % map->data->capacity);
		if (pair != NULL)
			if(keyLength == pair->keyLength)
				if (memcmp(key, pair->key, pair->keyLength) == 0) 	return pair;

	}

	return NULL;

}
Example #8
0
///
//Subdivides an oct tree node into 8 child nodes, re-adding all occupants to the oct tree
//Also removes the corresponding log entry for the parent node from the occupants,
//And adds the necessary child node log entries
//
//Parameters:
//	tree: A pointer to the oct tree inw hcihc this node lives
//	node: A pointer to the node being subdivided
static void OctTree_Node_SubdivideAndLog(OctTree*tree, struct OctTree_Node* node)
{
	//Allocate this nodes children
	node->children = OctTree_Node_AllocateChildren();

	//Initialize this nodes children
	OctTree_Node_InitializeChildren(tree, node);

	unsigned int numOccupants = node->data->size;
	//Create a temporary list of occupants
	GObject** occupants = (GObject**)malloc(sizeof(GObject**) * numOccupants);

	//Copy occupants from node into temporary list
	memcpy(occupants, node->data->data, sizeof(GObject**) * numOccupants);

	//Clear the node's data
	DynamicArray_Clear(node->data);

	//re-add all contents to the node
	GObject* current;
	for(unsigned int i = 0; i < numOccupants; i++)
	{
		//Get the GObject* at index i
		current = occupants[i];

		//Get this log of this object
		DynamicArray* log = (DynamicArray*)HashMap_LookUp(tree->map, &current, sizeof(GObject*))->data;
		//Find parent node in the log
		for(unsigned int j = 0; j < log->size; j++)
		{
			if(((struct OctTree_NodeStatus*)DynamicArray_Index(log, j))->node == node)
			{
				//And remove it
				DynamicArray_RemoveAndReposition(log, j);
				break;
			}
		}

		//Add the GObject* back into the node
		OctTree_Node_AddAndLog(tree, node, current);
	}

	//Free the temporary list of occupants
	free(occupants);
}
Example #9
0
///
//Frees a hashmap
//Does not free data!! Delete prior to this! OR have other references!!!
//
//Parameters:
//	map: The Hashmap to free
void HashMap_Free(HashMap* map)
{
	//for (unsigned int i = 0; i < map->size; i++)
	for(unsigned int i = 0; i < map->data->capacity; i++)
	{
		HashMap_KeyValuePair* pair = NULL;
		if((pair = *(HashMap_KeyValuePair**)DynamicArray_Index(map->data, i)) != NULL)
		{
			HashMap_KeyValuePair_Free(pair);
			DynamicArray_Remove(map->data, i);
		}

	}

	//free(map->data);
	DynamicArray_Free(map->data);
	free(map);
}
Example #10
0
///
//Removes an entry from the hashmap
//Does not delete data!
//
//Parameters:
//	map: Map to remove entry from
//	key: Key relating to data to be removed
//	keyLength: The size of the key in bytes
void* HashMap_Remove(HashMap* map, void* key, unsigned int keyLength)
{
	unsigned short found = 0;

	unsigned int index = (map->Hash(key, keyLength) % map->data->capacity);
	struct HashMap_KeyValuePair* pairToRemove = 0;
	//for (unsigned int i = 0; i < map->capacity; i++)
	for(unsigned int i = 0; i < map->data->capacity; i++)
	{
		pairToRemove = *(HashMap_KeyValuePair**)DynamicArray_Index(map->data, (index + i) % map->data->capacity);
		
		if(pairToRemove == NULL)
		{
			//printf("Pair NULL..\n");
		}
		else if(keyLength == pairToRemove->keyLength)
		{
			if (memcmp(key, pairToRemove->key, pairToRemove->keyLength) == 0)
			{
				index = (index + i) % map->data->capacity;
				found = 1;
				break;
			}
		}
	}
	void* data = NULL;
	if (found == 1)
	{
		data = pairToRemove->data;
		HashMap_KeyValuePair_Free(pairToRemove);
		//DynamicArray_Remove(map->data, index);
		memset((char*)map->data->data + index * map->data->dataSize, 0, map->data->dataSize);
		map->data->size--;
	}
	return data;
}
Example #11
0
///
//adds a game object to a node of the oct tree and logs all nodes in which it is contained.
//
//Parameters:
//	tree: A pointer to the oct tree the object is being added to
//	node: A pointer to the node the object is being added to
//	obj: A pointer to the game object being added to the tree
void OctTree_Node_AddAndLog(OctTree* tree, struct OctTree_Node* node, GObject* obj)
{
	//If this node has children, determine which children the object collides with
	if(node->children != NULL)
	{
		for(int i = 0; i < 8; i++)
		{
			unsigned char collisionStatus = OctTree_Node_DoesObjectCollide(node->children + i, obj);
			//If the object is fully contained in this node
			if(collisionStatus == 2)
			{
				//Add the nobject to this node & stop looping
				OctTree_Node_AddAndLog(tree, node->children + i, obj);
				break;
			}
			//Else if the object is partially contained in this node
			else  if(collisionStatus == 1)
			{
				//Add the object to this node & keep looping
				OctTree_Node_AddAndLog(tree, node->children + i, obj);
			}
		}
	}
	//If this node has no children
	else
	{
		//Can we hold another object? or are we too deep to subdivide?
		if(node->data->size <= tree->maxOccupancy || node->depth >= tree->maxDepth)
		{
			//Make sure we aren't already holding a pointer to the object...
			if(DynamicArray_ContainsWithin(node->data, &obj, node->data->size) == 0)
			{
				//Add the object!
				DynamicArray_Append(node->data, &obj);

				//Find the entry for this object in the treemap
				DynamicArray* log = NULL;

				//Is this object already contained in the map?
				if(HashMap_Contains(tree->map, &obj, sizeof(GObject*)) == 1)
				{
					log = (DynamicArray*)HashMap_LookUp(tree->map, &obj, sizeof(GObject*))->data;
				}
				else
				{
					//Add this object to the tree map
					log = DynamicArray_Allocate();
					DynamicArray_Initialize(log, sizeof(struct OctTree_NodeStatus));

					HashMap_Add(tree->map, &obj, log, sizeof(GObject*));
				}

				//Add this node to the log of the object
				//Get the containment status!
				unsigned char status = OctTree_Node_DoesObjectCollide(node, obj);
				//create a Nodestatus struct
				struct OctTree_NodeStatus entry;
				entry.node = node;
				entry.collisionStatus = status;

				//Log the entry!
				DynamicArray_Append(log, &entry);
			}
			//Else, it is already contained
			else
			{
				//Check if the status of containment in this node has changed
				//Get the object's log
				DynamicArray* log = (DynamicArray*)HashMap_LookUp(tree->map, &obj, sizeof(GObject*))->data;
				//Find the entry of this node in the log
				struct OctTree_NodeStatus* entry = NULL;
				for(unsigned int i = 0; i < log->size; i++)
				{
					struct OctTree_NodeStatus* mightBeTheEntry = (struct OctTree_NodeStatus*)DynamicArray_Index(log, i);
					//If we find it
					if(mightBeTheEntry->node == node)
					{
						entry = mightBeTheEntry;
						break;		
					}
				}

				//If this object is logged as being in this node
				if(entry != NULL)
				{

					//Compare the status of the entry to the current status
					unsigned char status = OctTree_Node_DoesObjectCollide(node, obj);
					if(entry->collisionStatus !=  status)
					{
						//Update the status
						entry->collisionStatus = status;
					}
				}
				//This object is not logged as being in this node
				else
				{
					//Create an entry
					//Get the containment status!
					unsigned char status = OctTree_Node_DoesObjectCollide(node, obj);
					//create a Nodestatus struct
					struct OctTree_NodeStatus entry;
					entry.node = node;
					entry.collisionStatus = status;

					//Log the entry!
					DynamicArray_Append(log, &entry);
				}
			}
		}
		//Else, we are out of room and can subdivide!
		else
		{
			OctTree_Node_SubdivideAndLog(tree, node);
			//Finally, recall this function to add the object to one of the children
			OctTree_Node_AddAndLog(tree, node, obj);
		}
	}
}
Example #12
0
///
//Updates the position of all gameobjects within the oct tree
//
//Parameters:
//	tree: A pointer to the oct tree to update
//	gameObjects: A linked list of all game objects currently in the simulation
void OctTree_Update(OctTree* tree, LinkedList* gameObjects)
{
	struct LinkedList_Node* current = gameObjects->head;

	while(current != NULL)
	{
		GObject* gameObj = (GObject*)current->data;
		//Find all gameObjects which have entries in the octtree (& treemap)
		if(gameObj->collider != NULL)
		{
			//Get the treemap entry
			DynamicArray* log = (DynamicArray*)HashMap_LookUp(tree->map, &gameObj, sizeof(GObject*))->data;

			if(log->size <= 0)
			{
				//printf("Not contained in any tree..\n");
				//OctTree_AddAndLog(tree, gameObj);
			}

			//For each OctTree_Node the game object was in
			for(unsigned int i = 0; i < log->size; i++)
			{
				struct OctTree_NodeStatus* nodeStatus = (struct OctTree_NodeStatus*)DynamicArray_Index(log, i);
				//get it's current status for this node
				unsigned char currentStatus = OctTree_Node_DoesObjectCollide(nodeStatus->node, gameObj);

				//If the status has remained the same, continue to the next one
				if(nodeStatus->collisionStatus == currentStatus) continue;

				//If the current status says that the object is no longer in the node
				if(currentStatus == 0)
				{

					printf("Object left node\n");

					//Remove the object from this node
					OctTree_Node_Remove(nodeStatus->node, gameObj);
					//Find where it moved
					struct OctTree_Node* containingNode = OctTree_SearchUp(nodeStatus->node, gameObj);
					//If it is still in a node
					if(containingNode != NULL)
					{
						//Add it to that node!
						OctTree_Node_AddAndLog(tree, containingNode, gameObj);
					}
					else
					{
						printf("No node found to relocate\n");
					}
					//Remove the ith nodeStatus from the log
					DynamicArray_RemoveAndReposition(log, i);
				}
				//Object was fully contained, and now it is not
				else if(currentStatus == 1)
				{
					printf("Object leaving node\n");

					//Update the status
					nodeStatus->collisionStatus = currentStatus;
					//Find where it moved
					struct OctTree_Node* containingNode = OctTree_SearchUp(nodeStatus->node, gameObj);
					//If it is even in a node anymore
					if(containingNode != NULL)
					{
						//Add it to that node!
						OctTree_Node_AddAndLog(tree, containingNode, gameObj);
					}
					else
					{
						printf("No node found to relocate\n");
					}
				}
				//Object was partially contained and now it is fully contained!
				else
				{
					printf("Object entered node\n");

					//Update the status
					nodeStatus->collisionStatus = currentStatus;
				}
			}
		}
		//Move to next object in linked list
		current = current->next;
	}

}
Example #13
0
///
//Loads and parses a .OBJ file constructing and returning
//the Mesh it defines
//
//TODO: Put in code for parsing materials and groups
//
//Parameters:
//	fPath: The filepath of the .obj file to load
//
//Returns:
//	A pointer to a newly allocated Mesh following the specifications of the given .OBJ file
Mesh* Loader_LoadOBJFile(const char* fPath)
{
	//Open file in read mode
	FILE* fp = fopen(fPath, "r");

	//MAke sure file is open
	if (fp == NULL)
	{
		printf("Error opening file %s.\n", fPath);
		return NULL;
	}

	//File opened correctly, begin parsing
	//Create struct to wrap 3 component attributes
	struct VertexAttr3
	{
		GLfloat x, y, z;
	};
	//Create struct to wrap 2 component attributes
	struct VertexAttr2
	{
		GLfloat x, y;
	};

	DynamicArray* vertices = DynamicArray_Allocate();		//Vertex coordinates
	DynamicArray* texCoords = DynamicArray_Allocate();		//Texture coordinates
	DynamicArray* normals = DynamicArray_Allocate();		//Normal Vectors
	DynamicArray* triangles = DynamicArray_Allocate();		//Complete Triangles

	DynamicArray_Initialize(vertices, sizeof(struct VertexAttr3));
	DynamicArray_Initialize(texCoords, sizeof(struct VertexAttr2));
	DynamicArray_Initialize(normals, sizeof(struct VertexAttr3));
	DynamicArray_Initialize(triangles, sizeof(struct Triangle));

	//Create a Cstring to hold each line of text
	char type[3];
	//char line[100];

	//Loop until we reach the end of the file
	while (!feof(fp))
	{
		//Get first (max 3) letters indicating information we are parsing
		//if(fscanf_s(fp, "%s", type, 3) == EOF) break;	//Break if we read past the end of the file (less than 3 characters were left)

		if(fscanf(fp, "%s", type) == EOF) break;

		//If we are reading Vertices, Texture Coordinates, or Normals
		if (type[0] == 'v')
		{
			//Normals
			if (type[1] == 'n')
			{
				struct VertexAttr3 vn;
				fscanf(fp, " %f %f %f", &vn.x, &vn.y, &vn.z);
				DynamicArray_Append(normals, &vn);
			}
			//Texture coordinates
			else if (type[1] == 't')
			{
				struct VertexAttr2 vt;
				fscanf(fp, " %f %f", &vt.x, &vt.y);
				DynamicArray_Append(texCoords, &vt);
			}
			//Vertices
			else
			{
				struct VertexAttr3 v;
				fscanf(fp, " %f %f %f", &v.x, &v.y, &v.z);
				DynamicArray_Append(vertices, &v);
			}
		}
		//Else if we are reading Face information
		else if (type[0] == 'f')
		{
			int indices[3];
			struct Triangle t;
			struct Vertex v;
			struct VertexAttr3* vAtt3;
			struct VertexAttr2* vAtt2;

			//For each vertex in the triangle
			for (int i = 0; i < 3; i++)
			{
				//Get the face info & the amount of info given
				int infoCount = fscanf(fp, " %d/%d/%d", indices, indices + 1, indices + 2);

				switch (infoCount)
				{
				case 3:		//Grabbing normals if present
					vAtt3 = (struct VertexAttr3*)DynamicArray_Index(normals, (indices[2] - 1));
					v.nx = vAtt3->x;
					v.ny = vAtt3->y;
					v.nz = vAtt3->z;
				case 2:		//Grabbing texture coords if present
					vAtt2 = (struct VertexAttr2*)DynamicArray_Index(texCoords, (indices[1] - 1));
					v.tx = vAtt2->x;
					v.ty = vAtt2->y;
				case 1:		//Grabbing vertex position
					vAtt3 = (struct VertexAttr3*)DynamicArray_Index(vertices, (indices[0] - 1));
					v.x = vAtt3->x;
					v.y = vAtt3->y;
					v.z = vAtt3->z;
				}

				//Store vertex in triangle t
				*(&(t.a) + i) = v;

			}
			//And add to triangles array
			DynamicArray_Append(triangles, &t);
		}
		//Else if we are reading a comment
		else if (type[0] == '#')
		{
			//REad until you get to a new line
			char c = '0';
			while (c != '\n' && c != '\r')
			{
				c = fgetc(fp);
			}
		}
		//Else if we don't know what we're reading
		else
		{
			//Read until the next line
			char c = '0';

			while (c != '\n' && c != '\r')
			{
				c = fgetc(fp);
			}
		}
	}//End of file reached
	
	fclose(fp);

	//File parsed, creating mesh
	
	Mesh* parsed = Mesh_Allocate();
	Mesh_Initialize(parsed, (struct Triangle*)triangles->data, triangles->size, GL_STATIC_DRAW);
	DynamicArray_Free(vertices);
	DynamicArray_Free(normals);
	DynamicArray_Free(texCoords);
	DynamicArray_Free(triangles);

	return parsed;
}