Jump to content

  • Log In with Google      Sign In   
  • Create Account

Garra

Member Since 18 Jan 2010
Offline Last Active Nov 30 2012 02:08 AM

Posts I've Made

In Topic: Debugging Game Deployment

02 December 2011 - 05:57 AM

alright I'll give it a try, thanks for the advice.

In Topic: UDP Client/Server help

20 November 2011 - 12:38 PM

well i haven't actually tried limiting how much I send a packet to update the game, but technically it seems like as long as it updates fast enough then there would be no problem limiting the update to a certain number of frames.

On a different note, I ended up having more issues with broadcasting a client's packet to other clients. When the client and server are on two different machines. The server receives the client's packet without issues and limited packet loss. However, when I try to make the server send that packet to all the other clients, the sendto() function is still returning SOCKET_ERROR and the server message "Unable to send to client" is being displayed. When both client and server are running on the same machine, the server seems to broadcast the packet to the other clients with limited packet loss. However, with the server receiving and broadcasting it is slowing it down greatly. I'm really confused about why the server isn't sending the received packets back out to the clients.

My server's loop
	while(true)
	{
		ZeroMemory(szBuffer, sizeof(szBuffer));
  		//iBytesRecv = c_Network.RecvChatPacket(szBuffer, sizeof(szBuffer)-1, 0);
		
		RecvPacket = c_Network.RecvPacket(RecvPacket);		
		
		if (c_Network.Clients.size() > 0)
		{
			sprintf(szBuffer, "x: %f y: %f z: %f\n", RecvPacket.x, RecvPacket.y, RecvPacket.z);
		}

		//if the packet is a knock packet
		if (RecvPacket.knock)
		{
			c_Network.Clients.push_back(c_Network.IncomingAddress);
		}
		else //if it is a normal packet
		{
			//broadcast it to all the clients
			for (int i = 0; i < c_Network.Clients.size(); i++)
			{
				c_Network.SendPacketToClient(c_Network.Clients.at(i), RecvPacket);
			}
		}

		printf(szBuffer);
	}

SendPacketToClient function
void CNetwork::SendPacketToClient(sockaddr_in client, Packet packet)
{
	BYTE sendBuffer[128];

	memcpy_s(&sendBuffer, 128, &packet, sizeof(packet));

	int sent_bytes = 0;
	int attempts = 0;
	int packet_size = 0;

	while (sent_bytes < sizeof(packet) /*&& attempts < 3*/)
	{
		packet_size = sizeof(packet) - sent_bytes;

		int send_err = sendto(skSocket, (char*)&sendBuffer[sent_bytes],
						  	packet_size, 0, (sockaddr*)&client, sizeof(sockaddr));
				
		if (send_err == SOCKET_ERROR)
		{
			printf("Unable to send to client\n");
		}

		sent_bytes += send_err;
	}
}

In Topic: UDP Client/Server help

19 November 2011 - 02:37 PM

another quick question, lets say I'm sending packets to update the player positions of a arena type fps. should I be sending the player position's to the server every single game frame?

In Topic: UDP Client/Server help

19 November 2011 - 11:11 AM

the issue is I'm trying to broadcast the packet received from the client with SendPacketToAll. However inside the SendPacketToAll function I'm calling sendto, which is always returning SOCKET_ERROR and therefore the packet is never broadcasted to the other clients. When I added in breakpoints, it seems like the IncomingAddress isn't being added to the ClientAddress array so I think the problem is here. Could you recommend a different way to handle the client addresses?

for (int i = 0; i < 8; i++)
{
	if (!(c_Network.ClientAddress[i].sin_family))
	{
    	c_Network.ClientAddress[i] = c_Network.IncomingAddress;
    	break;
	}
}			

EDIT: I changed my ClientAddress Array to a vector and that seemed to solve most of my issues. It would probably be better to use a list though to make removing clients easier.

if (RecvPacket.knock)
{
	c_Network.Clients.push_back(c_Network.IncomingAddress);

}

In Topic: Some AI advice needed

02 November 2011 - 07:32 PM

It's... very large. Why I didn't consider this being the problem sooner is beyond me. I was thinking of maybe calling it after so many frames instead of every frame.. or maybe redoing it completely. It basically does a line-triangle intersection test on triangles in the current node and then determines the height of the triangle. It's based from a tutorial on terrain quadtree's since I was learning them at the time.

Edit: Not calling it every frame seems to improve the performance considerably. I found a decent frame number to keep the position transition smooth and have a much higher frame rate. I still may do some work on the GetHeightAtPosition function though. Also, thanks for the info on the profiling, this thread was worth it just to learn about those. Sure was easy narrowing the problem down with Very Sleepy ;o

bool CQuadTree::GetHeightAtPosition(float positionX, float positionZ, float& height)
{
	float meshMinX, meshMaxX, meshMinZ, meshMaxZ;


	meshMinX = m_parentNode->positionX - (m_parentNode->width / 2.0f);
	meshMaxX = m_parentNode->positionX + (m_parentNode->width / 2.0f);

	meshMinZ = m_parentNode->positionZ - (m_parentNode->width / 2.0f);
	meshMaxZ = m_parentNode->positionZ + (m_parentNode->width / 2.0f);

	// Make sure the coordinates are actually over a polygon.
	if((positionX < meshMinX) || (positionX > meshMaxX) || (positionZ < meshMinZ) || (positionZ > meshMaxZ))
	{
		return false;
	}

	// Find the node which contains the polygon for this position.
	FindNode(m_parentNode, positionX, positionZ, height);
	
	return true;
}

void CQuadTree::FindNode(NodeType* node, float x, float z, float& height)
{
	float xMin, xMax, zMin, zMax;
	int count, i, index;
	float vertex1[3], vertex2[3], vertex3[3];
	bool foundHeight;


	// Calculate the dimensions of this node.
	xMin = node->positionX - (node->width / 2.0f);
	xMax = node->positionX + (node->width / 2.0f);

	zMin = node->positionZ - (node->width / 2.0f);
	zMax = node->positionZ + (node->width / 2.0f);

	// See if the x and z coordinate are in this node, if not then stop traversing this part of the tree.
	if((x < xMin) || (x > xMax) || (z < zMin) || (z > zMax))
	{
		return;
	}

	// If the coordinates are in this node then check first to see if children nodes exist.
	count = 0;

	for(i=0; i<4; i++)
	{
		if(node->nodes[i] != 0)
		{
			count++;
			FindNode(node->nodes[i], x, z, height);
		}
	}

	// If there were children nodes then return since the polygon will be in one of the children.
	if(count > 0)
	{
		return;
	}

	// If there were no children then the polygon must be in this node.  Check all the polygons in this node to find 
	// the height of which one the polygon we are looking for.
	for(i=0; i<node->triangleCount; i++)
	{
		index = i * 3;
		vertex1[0] = node->vertexArray[index].x;
		vertex1[1] = node->vertexArray[index].y;
		vertex1[2] = node->vertexArray[index].z;

		index++;
		vertex2[0] = node->vertexArray[index].x;
		vertex2[1] = node->vertexArray[index].y;
		vertex2[2] = node->vertexArray[index].z;

		index++;
		vertex3[0] = node->vertexArray[index].x;
		vertex3[1] = node->vertexArray[index].y;
		vertex3[2] = node->vertexArray[index].z;

		// Check to see if this is the polygon we are looking for.
		foundHeight = CheckHeightOfTriangle(x, z, height, vertex1, vertex2, vertex3);

		// If this was the triangle then quit the function and the height will be returned to the calling function.
		if(foundHeight)
		{
			return;
		}
	}

	return;
}


bool CQuadTree::CheckHeightOfTriangle(float x, float z, float& height, float v0[3], float v1[3], float v2[3])
{
	float startVector[3], directionVector[3], edge1[3], edge2[3], normal[3];
	float Q[3], e1[3], e2[3], e3[3], edgeNormal[3], temp[3];
	float magnitude, D, denominator, numerator, t, determinant;


	// Starting position of the ray that is being cast.
	startVector[0] = x;
	startVector[1] = 0.0f;
	startVector[2] = z;

	// The direction the ray is being cast.
	directionVector[0] =  0.0f;
	directionVector[1] = -1.0f;
	directionVector[2] =  0.0f;

	// Calculate the two edges from the three points given.
	edge1[0] = v1[0] - v0[0];
	edge1[1] = v1[1] - v0[1];
	edge1[2] = v1[2] - v0[2];

	edge2[0] = v2[0] - v0[0];
	edge2[1] = v2[1] - v0[1];
	edge2[2] = v2[2] - v0[2];

	// Calculate the normal of the triangle from the two edges.
	normal[0] = (edge1[1] * edge2[2]) - (edge1[2] * edge2[1]);
	normal[1] = (edge1[2] * edge2[0]) - (edge1[0] * edge2[2]);
	normal[2] = (edge1[0] * edge2[1]) - (edge1[1] * edge2[0]);

	magnitude = (float)sqrt((normal[0] * normal[0]) + (normal[1] * normal[1]) + (normal[2] * normal[2]));
	normal[0] = normal[0] / magnitude;
	normal[1] = normal[1] / magnitude;
	normal[2] = normal[2] / magnitude;

	// Find the distance from the origin to the plane.
	D = ((-normal[0] * v0[0]) + (-normal[1] * v0[1]) + (-normal[2] * v0[2]));

	// Get the denominator of the equation.
	denominator = ((normal[0] * directionVector[0]) + (normal[1] * directionVector[1]) + (normal[2] * directionVector[2]));

	// Make sure the result doesn't get too close to zero to prevent divide by zero.
	if(fabs(denominator) < 0.0001f)
	{
		return false;
	}

	// Get the numerator of the equation.
	numerator = -1.0f * (((normal[0] * startVector[0]) + (normal[1] * startVector[1]) + (normal[2] * startVector[2])) + D);

	// Calculate where we intersect the triangle.
	t = numerator / denominator;

	// Find the intersection vector.
	Q[0] = startVector[0] + (directionVector[0] * t);
	Q[1] = startVector[1] + (directionVector[1] * t);
	Q[2] = startVector[2] + (directionVector[2] * t);

	// Find the three edges of the triangle.
	e1[0] = v1[0] - v0[0];
	e1[1] = v1[1] - v0[1];
	e1[2] = v1[2] - v0[2];

	e2[0] = v2[0] - v1[0];
	e2[1] = v2[1] - v1[1];
	e2[2] = v2[2] - v1[2];

	e3[0] = v0[0] - v2[0];
	e3[1] = v0[1] - v2[1];
	e3[2] = v0[2] - v2[2];

	// Calculate the normal for the first edge.
	edgeNormal[0] = (e1[1] * normal[2]) - (e1[2] * normal[1]);
	edgeNormal[1] = (e1[2] * normal[0]) - (e1[0] * normal[2]);
	edgeNormal[2] = (e1[0] * normal[1]) - (e1[1] * normal[0]);

	// Calculate the determinant to see if it is on the inside, outside, or directly on the edge.
	temp[0] = Q[0] - v0[0];
	temp[1] = Q[1] - v0[1];
	temp[2] = Q[2] - v0[2];

	determinant = ((edgeNormal[0] * temp[0]) + (edgeNormal[1] * temp[1]) + (edgeNormal[2] * temp[2]));

	// Check if it is outside.
	if(determinant > 0.001f)
	{
		return false;
	}

	// Calculate the normal for the second edge.
	edgeNormal[0] = (e2[1] * normal[2]) - (e2[2] * normal[1]);
	edgeNormal[1] = (e2[2] * normal[0]) - (e2[0] * normal[2]);
	edgeNormal[2] = (e2[0] * normal[1]) - (e2[1] * normal[0]);

	// Calculate the determinant to see if it is on the inside, outside, or directly on the edge.
	temp[0] = Q[0] - v1[0];
	temp[1] = Q[1] - v1[1];
	temp[2] = Q[2] - v1[2];

	determinant = ((edgeNormal[0] * temp[0]) + (edgeNormal[1] * temp[1]) + (edgeNormal[2] * temp[2]));

	// Check if it is outside.
	if(determinant > 0.001f)
	{
		return false;
	}

	// Calculate the normal for the third edge.
	edgeNormal[0] = (e3[1] * normal[2]) - (e3[2] * normal[1]);
	edgeNormal[1] = (e3[2] * normal[0]) - (e3[0] * normal[2]);
	edgeNormal[2] = (e3[0] * normal[1]) - (e3[1] * normal[0]);

	// Calculate the determinant to see if it is on the inside, outside, or directly on the edge.
	temp[0] = Q[0] - v2[0];
	temp[1] = Q[1] - v2[1];
	temp[2] = Q[2] - v2[2];

	determinant = ((edgeNormal[0] * temp[0]) + (edgeNormal[1] * temp[1]) + (edgeNormal[2] * temp[2]));

	// Check if it is outside.
	if(determinant > 0.001f)
	{
		return false;
	}

	// Now we have our height.
	height = Q[1];

	return true;
}

PARTNERS