bool MyBoundingObjectClass::IsColliding(MyBoundingObjectClass* pOther)
{
	// check for sphere collision
	// magnitude
	vector3 distance = pOther->GetCenterGlobal() - GetCenterGlobal();
	float magnitude = distance.x * distance.x + distance.y * distance.y + distance.z * distance.z;
	magnitude = sqrt(magnitude);

	if ((fRadius + pOther->fRadius) > (magnitude))
	{ 
		std::cout << "colliding";
		isColliding = true;
		return isColliding; //don't do this because we need to check AABB
	}
	else
	{
		isColliding = false;
		return isColliding; // exits if no collision
	}

	//// if you reach this point, check for AABB collision

	////Get all vectors in global space
	//vector3 v3Min = vector3(m_m4ToWorld * vector4(m_v3Min, 1.0f));
	//vector3 v3Max = vector3(m_m4ToWorld * vector4(m_v3Max, 1.0f));

	//vector3 v3MinO = vector3(pOther->m_m4ToWorld * vector4(pOther->m_v3Min, 1.0f));
	//vector3 v3MaxO = vector3(pOther->m_m4ToWorld * vector4(pOther->m_v3Max, 1.0f));

	///*
	//Are they colliding?
	//For boxes we will assume they are colliding, unless at least one of the following conditions is not met
	//*/
	//bool bColliding = true;

	////Check for X
	//if (m_v3MaxG.x < pOther->m_v3MinG.x)
	//	bColliding = false;
	//if (m_v3MinG.x > pOther->m_v3MaxG.x)
	//	bColliding = false;

	////Check for Y
	//if (m_v3MaxG.y < pOther->m_v3MinG.y)
	//	bColliding = false;
	//if (m_v3MinG.y > pOther->m_v3MaxG.y)
	//	bColliding = false;

	////Check for Z
	//if (m_v3MaxG.z < pOther->m_v3MinG.z)
	//	bColliding = false;
	//if (m_v3MinG.z > pOther->m_v3MaxG.z)
	//	bColliding = false;

	//isColliding = bColliding;

	//return bColliding;

}
Exemplo n.º 2
0
/////////////////////////////////////////////////////////////////////
//USAGE: Determines the collision with an incoming object using the SAT
// ARGUMENTS :
//- MyBOClass* const a_pOther->Other object to check collision with
//OUTPUT : result of the collision
/////////////////////////////////////////////////////////////////////
bool MyBOClass::SAT(MyBOClass* const a_pOther)
{
	// Get the information of this object
	vector3 v3CenterGlobalA = GetCenterGlobal();
	matrix4 mToWorldA = GetModelMatrix();
	vector3 v3RotationA[3];
	v3RotationA[0] = vector3(mToWorldA[0][0], mToWorldA[0][1], mToWorldA[0][2]);
	v3RotationA[1] = vector3(mToWorldA[1][0], mToWorldA[1][1], mToWorldA[1][2]);
	v3RotationA[2] = vector3(mToWorldA[2][0], mToWorldA[2][1], mToWorldA[2][2]);

	//Get the information of the other object
	vector3 v3CenterGlobalB = a_pOther->GetCenterGlobal();
	matrix4 mToWorldB = a_pOther->GetModelMatrix();
	vector3 v3RotationB[3];
	v3RotationB[0] = vector3(mToWorldB[0][0], mToWorldB[0][1], mToWorldB[0][2]);
	v3RotationB[1] = vector3(mToWorldB[1][0], mToWorldB[1][1], mToWorldB[1][2]);
	v3RotationB[2] = vector3(mToWorldB[2][0], mToWorldB[2][1], mToWorldB[2][2]);

	float fCenterAToMiddle, fCenterBToMiddle;
	glm::mat3 m3Rotation, m3RotationAbs;

	// Compute rotation matrix expressing b in a's coordinate frame
	for (int i = 0; i < 3; i++)
	for (int j = 0; j < 3; j++)
		m3Rotation[i][j] = glm::dot(v3RotationA[i], v3RotationB[j]);

	// Compute translation vector v3Distance (this is the distance between both centers)
	vector3 v3Distance = v3CenterGlobalB - v3CenterGlobalA; //distance in global space
	// Bring translation into a's coordinate frame
	v3Distance = vector3(glm::dot(v3Distance, v3RotationA[0]), glm::dot(v3Distance, v3RotationA[1]), glm::dot(v3Distance, v3RotationA[2])); //distance in A's local
	// their cross product is (near) null (see the orange book for details)
	for (int i = 0; i < 3; i++)
	for (int j = 0; j < 3; j++)
		m3RotationAbs[i][j] = std::abs(m3Rotation[i][j]) + 0.0001f;

	// Test axes L = AX <- 0
	fCenterAToMiddle = m_v3HalfWidth.x;
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[0][0] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[0][1] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[0][2];
	if (std::abs(v3Distance.x) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center;
		matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld);
		if (m_v3CenterG.x < a_pOther->m_v3CenterG.x)
		{
			vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA;
		}
		else
		{
			vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA;
		}
		v3Center /= 2.0f;

		matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center) * glm::rotate(IDENTITY_M4, 90.0f, REAXISY);
		m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), RERED);
#endif
		return false;
	}

	// Test axes L = AY <- 1
	fCenterAToMiddle = m_v3HalfWidth.y;
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[1][0] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[1][1] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[1][2];
	if (std::abs(v3Distance.y) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center;
		matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld);
		if (m_v3CenterG.y < a_pOther->m_v3CenterG.y)
		{
			vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA;
		}
		else
		{
			vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA;
		}
		v3Center /= 2.0f;
		matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center) * glm::rotate(IDENTITY_M4, 90.0f, REAXISX);
		m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REGREEN);
#endif
		return false;
	}

	// Test axes L = AZ <- 2
	fCenterAToMiddle = m_v3HalfWidth.z;
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[2][0] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[2][1] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[2][2];
	if (std::abs(v3Distance.z) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center;
		matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld);
		if (m_v3CenterG.z < a_pOther->m_v3CenterG.z)
		{
			vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA;
		}
		else
		{
			vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA;
		}
		v3Center /= 2.0f;
		matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center);
		m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REBLUE);
#endif
		return false;
	}

	// Test axes L = BX <- 3
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[0][0] + m_v3HalfWidth.y * m3RotationAbs[1][0] + m_v3HalfWidth.z * m3RotationAbs[2][0];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x;
	if (std::abs(v3Distance.x * m3Rotation[0][0] + v3Distance.y * m3Rotation[1][0] + v3Distance.z * m3Rotation[2][0]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		matrix4 m4Space = glm::translate(IDENTITY_M4, a_pOther->m_v3CenterG) * glm::rotate(IDENTITY_M4, 90.0f, REAXISY);
		m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), RERED * 0.33f);
#endif
		return false;
	}

	// Test axes L = BY <- 4
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[0][1] + m_v3HalfWidth.y * m3RotationAbs[1][1] + m_v3HalfWidth.z * m3RotationAbs[2][1];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.y;
	if (std::abs(v3Distance.x * m3Rotation[0][1] + v3Distance.y * m3Rotation[1][1] + v3Distance.z * m3Rotation[2][1]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		matrix4 m4Space = glm::translate(IDENTITY_M4, a_pOther->m_v3CenterG) * glm::rotate(IDENTITY_M4, 90.0f, REAXISX);
		m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REGREEN * 0.33f);
#endif
		return false;
	}

	// Test axes L = BZ <- 5
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[0][2] + m_v3HalfWidth.y * m3RotationAbs[1][2] + m_v3HalfWidth.z * m3RotationAbs[2][2];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.z;
	if (std::abs(v3Distance.x * m3Rotation[0][2] + v3Distance.y * m3Rotation[1][2] + v3Distance.z * m3Rotation[2][2]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		matrix4 m4Space = glm::translate(IDENTITY_M4, a_pOther->m_v3CenterG);
		m_pMeshMngr->AddPlaneToQueue(m4Space * glm::scale(vector3(5.0f)), REBLUE * 0.33f);
#endif
		return false;
	}

	// Test axis L = AX x BX <- 6
	fCenterAToMiddle = m_v3HalfWidth.y * m3RotationAbs[2][0] + m_v3HalfWidth.z * m3RotationAbs[1][0];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.y * m3RotationAbs[0][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[0][1];
	if (std::abs(v3Distance.z * m3Rotation[1][0] - v3Distance.y * m3Rotation[2][0]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center;
		matrix4 m4WorldToLocal = glm::inverse(m_m4ToWorld);
		if (m_v3CenterG.z < a_pOther->m_v3CenterG.z)
		{
			vector3 v3OtherMinInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MinG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MaxG, 1.0f)) + v3OtherMinInA;
		}
		else
		{
			vector3 v3OtherMaxInA = vector3(m4WorldToLocal * vector4(a_pOther->m_v3MaxG, 1.0f));
			v3Center = vector3(m4WorldToLocal * vector4(m_v3MinG, 1.0f)) + v3OtherMaxInA;
		}
		v3Center /= 2.0f;
		matrix4 m4Space = glm::translate(m_m4ToWorld, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AX x BY <- 7
	fCenterAToMiddle = m_v3HalfWidth.y * m3RotationAbs[2][1] + m_v3HalfWidth.z * m3RotationAbs[1][1];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[0][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[0][0];
	if (std::abs(v3Distance.z * m3Rotation[1][1] - v3Distance.y * m3Rotation[2][1]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AX x BZ <- 8
	fCenterAToMiddle = m_v3HalfWidth.y * m3RotationAbs[2][2] + m_v3HalfWidth.z * m3RotationAbs[1][2];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[0][1] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[0][0];
	if (std::abs(v3Distance.z * m3Rotation[1][2] - v3Distance.y * m3Rotation[2][2]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AY x BX <- 9
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[2][0] + m_v3HalfWidth.z * m3RotationAbs[0][0];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.y * m3RotationAbs[1][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[1][1];
	if (std::abs(v3Distance.x * m3Rotation[2][0] - v3Distance.z * m3Rotation[0][0]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AY x BY <- 10
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[2][1] + m_v3HalfWidth.z * m3RotationAbs[0][1];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[1][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[1][0];
	if (std::abs(v3Distance.x * m3Rotation[2][1] - v3Distance.z * m3Rotation[0][1]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AY x BZ <- 11
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[2][2] + m_v3HalfWidth.z * m3RotationAbs[0][2];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[1][1] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[1][0];
	if (std::abs(v3Distance.x * m3Rotation[2][2] - v3Distance.z * m3Rotation[0][2]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AZ x BX <- 12
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[1][0] + m_v3HalfWidth.y * m3RotationAbs[0][0];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.y * m3RotationAbs[2][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[2][1];
	if (std::abs(v3Distance.y * m3Rotation[0][0] - v3Distance.x * m3Rotation[1][0]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AZ x BY <- 13
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[1][1] + m_v3HalfWidth.y * m3RotationAbs[0][1];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[2][2] + a_pOther->m_v3HalfWidth.z * m3RotationAbs[2][0];
	if (std::abs(v3Distance.y * m3Rotation[0][1] - v3Distance.x * m3Rotation[1][1]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Test axis L = AZ x BZ <- 14
	fCenterAToMiddle = m_v3HalfWidth.x * m3RotationAbs[1][2] + m_v3HalfWidth.y * m3RotationAbs[0][2];
	fCenterBToMiddle = a_pOther->m_v3HalfWidth.x * m3RotationAbs[2][1] + a_pOther->m_v3HalfWidth.y * m3RotationAbs[2][0];
	if (std::abs(v3Distance.y * m3Rotation[0][2] - v3Distance.x * m3Rotation[1][2]) > fCenterAToMiddle + fCenterBToMiddle)
	{
#ifdef SHOWPLANES
		vector3 v3Center = (m_v3CenterG + a_pOther->m_v3CenterG) / 2.0f;
		matrix4 m4Space = glm::translate(IDENTITY_M4, v3Center);
		m_pMeshMngr->AddSphereToQueue(m4Space * glm::scale(vector3(0.10f)), REYELLOW, SOLID);
#endif
		return false;
	}

	// Since no separating axis found, the OBBs must a_pOther->m_v3HalfWidth intersecting
	return true;
}