Beispiel #1
0
///
//Initializes an oct tree node to the given specifications
//
//Parameters:
//	node: A pointer to the oct tree node to initialize
//	tree: A pointer to the oct tree this node is part of
//	parent: A pointer to the parent node of this oct tree node
//	depth: The depth from the root node of this node in the oct tree
//	leftBound: The left bound of the octtree
//	rightBound: The right bound of the octtree
//	bottomBound: The bottom bound of the octtree
//	topBound: The top bound of the octtree
//	backBound: The back bound of the octtree
//	frontBound: The front bound of the octtree
static void OctTree_Node_Initialize(struct OctTree_Node* node, OctTree* tree, struct OctTree_Node* parent, unsigned int depth, float leftBound, float rightBound, float bottomBound, float topBound, float backBound, float frontBound)
{
	//Set relative nodes
	node->children = NULL;
	node->parent = parent;

	//Create data array
	node->data = DynamicArray_Allocate();
	//Set a max capacity of the dynamic array to the max occupancy of the oct tree
	node->data->capacity = tree->maxOccupancy;
	DynamicArray_Initialize(node->data, sizeof(GObject*));

	//Set depth
	node->depth = depth;

	//Set bounds
	node->left = leftBound;
	node->right = rightBound;
	node->bottom = bottomBound;
	node->top = topBound;
	node->back = backBound;
	node->front = frontBound;
}
Beispiel #2
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);
		}
	}
}
Beispiel #3
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;
}
///
//Initializes a HashMap
//
//Parameters:
//	map: Hashmap to initialize
void HashMap_Initialize(HashMap* map, unsigned int capacity)
{
	map->data = DynamicArray_Allocate();
	DynamicArray_Initialize(map->data, sizeof(struct HashMap_KeyValuePair*));
	map->Hash = Hash_SDBM;
}