//--- Non Standard Singleton Methods
std::shared_ptr<Collision> Collider::IsColliding(Collider* const a_pOther)
{
	float dist = glm::distance(GetCenter(), a_pOther->GetCenter());
	if (dist > (GetRadius() + a_pOther->GetRadius())) {
		return nullptr;
	}

	if (type != a_pOther->type) {
		Collider* box = type == ColliderType::OBB ? this : a_pOther;
		Collider* sphere = type == ColliderType::Sphere ? this : a_pOther;

		vector3 axes[] = {
			box->obb.r,
			box->obb.s,
			box->obb.t
		};

		vector3 closestPt = box->obb.c;
		vector3 disp = sphere->GetCenter() - box->obb.c;

		for (int i = 0; i < 3; i++) {
			float dist = glm::dot(disp, glm::normalize(axes[i]));

			float extent = glm::length(axes[i]) / 2.0f;
			if (dist > extent)
				dist = extent;

			if (dist < -extent)
				dist = -extent;

			closestPt += dist * glm::normalize(axes[i]);	
		}

		//MeshManagerSingleton::GetInstance()->AddSphereToQueue(glm::translate(closestPt) * glm::scale(vector3(0.1f)), REYELLOW, SOLID);

		vector3 toSphereCenter = closestPt - sphere->GetCenter();
		bool colliding = glm::dot(toSphereCenter, toSphereCenter) <= sphere->GetRadius() * sphere->GetRadius();

		if (colliding) {
			std::shared_ptr<Collision> collision(new Collision());
			collision->colliding = true;

			vector3 penetration = vector3(0);
			if(glm::length2(toSphereCenter) > 0)
				penetration = (sphere->GetRadius() - glm::distance(closestPt, sphere->GetCenter())) * glm::normalize(toSphereCenter);

			collision->penetrationVector = type == ColliderType::OBB ? penetration : -penetration;

			vector3 toSphereEdge = vector3(0);
			if (glm::length2(penetration) > 0)
				toSphereEdge = glm::normalize(penetration) * sphere->GetRadius();

			vector3 sphereEdgePt = sphere->GetCenter() + toSphereEdge;
			vector3 obbEdgePt = closestPt;
			collision->intersectPoint1 = type == ColliderType::OBB ? obbEdgePt : sphereEdgePt;
			collision->intersectPoint2 = type == ColliderType::OBB ? sphereEdgePt : obbEdgePt;
			return collision;
		}
		
		return nullptr;
	}
	//If they are both circles, we have already checked their radii
	else if (type == ColliderType::Sphere) {
		std::shared_ptr<Collision> collision(new Collision());
		collision->colliding = true;
		return collision;
	}
	else {

		vector3 r1 = obb.r;
		vector3 s1 = obb.s;
		vector3 t1 = obb.t;

		OBB obb2 = a_pOther->obb;
		vector3 r2 = obb2.r;
		vector3 s2 = obb2.s;
		vector3 t2 = obb2.t;

		vector3 axes[] = {
			//Normals of OBB1
			glm::cross(r1, s1),
			glm::cross(r1, t1),
			glm::cross(s1, t1),
			//Normals of OBB2
			glm::cross(r2, s2),
			glm::cross(r2, t2),
			glm::cross(s2, t2),
			//Normals between OBB1 & 2
			glm::cross(r1, r2),
			glm::cross(r1, s2),
			glm::cross(r1, t2),
			glm::cross(s1, r2),
			glm::cross(s1, s2),
			glm::cross(s1, t2),
			glm::cross(t1, r2),
			glm::cross(t1, s2),
			glm::cross(t1, t2),
		};

		for (int i = 0; i < 15; i++) {
			if (glm::length(axes[i]) == 0)
				continue;

			Projection proj1 = Projection(obb.GetWorldVerts(), axes[i]); 
			Projection proj2 = Projection(a_pOther->obb.GetWorldVerts(), axes[i]);

			lastCollision = (obb.c + a_pOther->obb.c) / 2.0f;
			if (!proj1.Overlaps(proj2)) {
				return nullptr;
			}
		}

		std::shared_ptr<Collision> collision(new Collision());
		//TODO: SAT penetration vector
		collision->colliding = true;
		return collision;
	}

	
}