示例#1
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);
}
示例#2
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);
}
示例#3
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);
		}
	}
}
示例#4
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;
	}

}
示例#5
0
///
//Looks up a texture from he asset manager's internal buffer
//
//Parameters
//	key: The name of the texture to lookup
//
//Returns:
//	Pointer to the requested texture, or NULL if the texture was not found
Texture* AssetManager_LookupTexture(char* key)
{
	return (Texture*)HashMap_LookUp(assetBuffer->textureMap, key, strlen(key))->data;
}
示例#6
0
///
//Looks up a mesh from the asset manager's internal buffer
//
//Parameters:
//	key: Name of the mesh to lookup
//
//Returns:
//	Pointer to the requested mesh, or NULL if mesh was not found
Mesh* AssetManager_LookupMesh(char* key)
{
	return (Mesh*)HashMap_LookUp(assetBuffer->meshMap, key, strlen(key))->data;
}