예제 #1
0
float CCollision::SweepAABB(CBox box1, CBox box2, CDirection &normalX, CDirection &normalY, float frameTime)
{
	float xInvEntry, yInvEntry;
	float xInvExit, yInvExit;

	if (box1.Velocity.x > 0.0f)
	{
		xInvEntry = box2.Position.x - (box1.Position.x + box1.Size.x);
		xInvExit = (box2.Position.x + box2.Size.x) - box1.Position.x;
	}
	else
	{
		xInvEntry = (box2.Position.x + box2.Size.x) - box1.Position.x;
		xInvExit = box2.Position.x - (box1.Position.x + box1.Size.x);
	}

	if (box1.Velocity.y > 0.0f)
	{
		yInvEntry = (box2.Position.y - box2.Size.y) - box1.Position.y;
		yInvExit = box2.Position.y - (box1.Position.y - box1.Size.y);
	}
	else
	{
		yInvEntry = box2.Position.y - (box1.Position.y - box1.Size.y);
		yInvExit = (box2.Position.y - box2.Size.y) - box1.Position.y;
	}

	float xEntry, xExit;
	float yEntry, yExit;

	if (box1.Velocity.x == 0.0f)
	{
		xEntry = -std::numeric_limits<float>::infinity();
		xExit = std::numeric_limits<float>::infinity();
	}
	else
	{
		xEntry = xInvEntry / box1.Velocity.x;
		xExit = xInvExit / box1.Velocity.x;
	}

	if (box1.Velocity.y == 0.0f)
	{
		yEntry = -std::numeric_limits<float>::infinity();
		yExit = std::numeric_limits<float>::infinity();
	}
	else
	{
		yEntry = yInvEntry / box1.Velocity.y;
		yExit = yInvExit / box1.Velocity.y;
	}

	float entryTime, exitTime;

	entryTime = __max(xEntry, yEntry);
	exitTime = __min(xExit, yExit);

#pragma region Xét va chạm với các trường hợp còn lại
	if (entryTime > exitTime || xEntry<0.0f&&yEntry<0.0f || xEntry>frameTime || yEntry>frameTime)
	{
		normalX = CDirection::NONE_DIRECT;
		normalY = CDirection::NONE_DIRECT;

		if (box1.IsIntersectedWith(box2))
		{
			if (fabsf(box1.Position.y - box1.Size.y - box2.Position.y) <= 2.0f
				&& !(box1.Position.x + box1.Size.x <= box2.Position.x || box1.Position.x >= box2.Position.x + box2.Size.x))
				normalY = CDirection::ON_DOWN;

			else if (fabsf(box1.Position.y - (box2.Position.y - box2.Size.y)) <= 2.0f
				&& !(box1.Position.x + box1.Size.x <= box2.Position.x || box1.Position.x >= box2.Position.x + box2.Size.x))
				normalY = CDirection::ON_UP;

			else if (fabsf(box1.Position.x + box1.Size.x - box2.Position.x) <= 2.0f
				&& !(box1.Position.y - box1.Size.y >= box2.Position.y || box1.Position.y <= box2.Position.y - box2.Size.y))
				normalX = CDirection::ON_RIGHT;

			else if (fabsf(box1.Position.x - (box2.Position.x + box2.Size.x)) <= 2.0f
				&& !(box1.Position.y - box1.Size.y >= box2.Position.y || box1.Position.y <= box2.Position.y - box2.Size.y))
				normalX = CDirection::ON_LEFT;

			else if (!(box1.Position.y - box1.Size.y >= box2.Position.y
				|| box1.Position.y <= box2.Position.y - box2.Size.y
				|| box1.Position.x + box1.Size.x <= box2.Position.x
				|| box1.Position.x >= box2.Position.x + box2.Size.x))
				normalX = normalY = CDirection::INSIDE;
		}
		return 0;
	}
#pragma  endregion
#pragma region Nếu có va chạm xảy ra
	else
	{
		if (xEntry > yEntry)
		{
			if (box1.Velocity.x > 0.0f)
			{
				if (!(box1.Position.y - box1.Size.y >= box2.Position.y || box1.Position.y <= box2.Position.y - box2.Size.y))
				{
					normalX = CDirection::ON_RIGHT;
					normalY = CDirection::NONE_DIRECT;
				}
				else
				{
					if (fabsf(box1.Position.y - box1.Size.y - box2.Position.y) <= 2.0f)
					{
						normalX = CDirection::NONE_DIRECT;
						normalY = CDirection::ON_DOWN;
						entryTime = 0.0f;
					}
					else if (fabsf(box1.Position.y - (box2.Position.y - box2.Size.y) <= 2.0f))
					{
						normalX = CDirection::NONE_DIRECT;
						normalY = CDirection::ON_UP;
						entryTime = 0.0f;
					}
				}
			}
			else
			{
				if (!(box1.Position.y - box1.Size.y >= box2.Position.y || box1.Position.y <= box2.Position.y - box2.Size.y))
				{
					normalX = CDirection::ON_LEFT;
					normalY = CDirection::NONE_DIRECT;
				}
				else
				{
					if (fabsf(box1.Position.y - box1.Size.y - box2.Position.y) <= 2.0f)
					{
						normalX = CDirection::NONE_DIRECT;
						normalY = CDirection::ON_DOWN;
						entryTime = 0.0f;
					}
					else if (fabsf(box1.Position.y - (box2.Position.y - box2.Size.y)) <= 2.0f)
					{
						normalX = CDirection::NONE_DIRECT;
						normalY = CDirection::ON_UP;
						entryTime = 0.0f;
					}
				}
			}
		}
		else
		{
			if (box1.Velocity.y > 0.0f)
			{
				if (!(box1.Position.x + box1.Size.x <= box2.Position.x || box1.Position.x >= box2.Position.x + box2.Size.x))
				{
					normalY = CDirection::ON_UP;
					normalX = CDirection::NONE_DIRECT;
				}
				else
				{
					if (fabsf(box1.Position.x + box1.Size.x - box2.Position.x) <= 2.0f)
					{
						normalY = CDirection::NONE_DIRECT;
						normalX = CDirection::ON_RIGHT;
						entryTime = 0.0f;
					}
					else if (fabsf(box1.Position.x - (box2.Position.x + box2.Size.x)) < 2.0f)
					{
						normalY = CDirection::NONE_DIRECT;
						normalX = CDirection::ON_LEFT;
						entryTime = 0.0f;
					}
				}
			}
			else
			{
				if (!(box1.Position.x + box1.Size.x <= box2.Position.x || box1.Position.x >= box2.Position.x + box2.Size.x))
				{
					normalY = CDirection::ON_DOWN;
					normalX = CDirection::NONE_DIRECT;
				}
				else
				{
					if (fabsf(box1.Position.x + box1.Size.x - box2.Position.x) <= 2.0f)
					{
						normalY = CDirection::NONE_DIRECT;
						normalX = CDirection::ON_RIGHT;
						entryTime = 0.0f;
					}
					else if (fabsf(box1.Position.x - (box2.Position.x + box2.Size.x)) < 2.0f)
					{
						normalY = CDirection::NONE_DIRECT;
						normalX = CDirection::ON_LEFT;
						entryTime = 0.0f;
					}
				}
			}
		}
		return entryTime;
	}
#pragma endregion
}
예제 #2
0
bool CCollision::AABBCheck(CBox box1, CBox box2)
{
	return box1.IsIntersectedWith(box2);
}