private static bool IsOverlappingABB(Vector3 normal, AxisAlignBoundingBoxHull2D other, ObjectBoundingBoxHull2D self) { bool isOverlapping = false; //Project the corners of rectangle 1 onto the normal float dot1 = Vector3.Dot(normal, other.upLeft); float dot2 = Vector3.Dot(normal, other.upRight); float dot3 = Vector3.Dot(normal, other.botLeft); float dot4 = Vector3.Dot(normal, other.botRight); //Find the range float min1 = Mathf.Min(dot1, Mathf.Min(dot2, Mathf.Min(dot3, dot4))); float max1 = Mathf.Max(dot1, Mathf.Max(dot2, Mathf.Max(dot3, dot4))); //Project the corners of rectangle 2 onto the normal float dot5 = Vector3.Dot(normal, self.topLeftAxis); float dot6 = Vector3.Dot(normal, self.topLeftAxis); float dot7 = Vector3.Dot(normal, self.botLeftAxis); float dot8 = Vector3.Dot(normal, self.botRightAxis); //Find the range float min2 = Mathf.Min(dot5, Mathf.Min(dot6, Mathf.Min(dot7, dot8))); float max2 = Mathf.Max(dot5, Mathf.Max(dot6, Mathf.Max(dot7, dot8))); //Are the ranges overlapping? if (min1 <= max2 && min2 <= max1) { isOverlapping = true; } return(isOverlapping); }
private bool IsIntersectingAABB_OBB(AxisAlignBoundingBoxHull2D other) { bool isIntersecting = false; Vector2 otherTL = other.upLeft; Vector2 otherTR = other.upRight; Vector2 otherBL = other.botLeft; Vector2 otherBR = other.botRight; Vector2 thisTL = topLeftAxis; Vector2 thisTR = topRightAxis; Vector2 thisBL = botLeftAxis; Vector2 thisBR = botRightAxis; //Find the min/max values for the AABB algorithm float r1_minX = Mathf.Min(otherTL.x, Mathf.Min(otherTR.x, Mathf.Min(otherBL.x, otherBR.x))); float r1_maxX = Mathf.Max(otherTL.x, Mathf.Max(otherTR.x, Mathf.Max(otherBL.x, otherBR.x))); float r2_minX = Mathf.Min(thisTL.x, Mathf.Min(thisTR.x, Mathf.Min(thisBL.x, thisBR.x))); float r2_maxX = Mathf.Max(thisTL.x, Mathf.Max(thisTR.x, Mathf.Max(thisBL.x, thisBR.x))); float r1_minY = Mathf.Min(otherTL.y, Mathf.Min(otherTR.y, Mathf.Min(otherBL.y, otherBR.y))); float r1_maxY = Mathf.Max(otherTL.y, Mathf.Max(otherTR.y, Mathf.Max(otherBL.y, otherBR.y))); float r2_minY = Mathf.Min(thisTL.y, Mathf.Min(thisTR.y, Mathf.Min(thisBL.y, thisBR.y))); float r2_maxY = Mathf.Max(thisTL.y, Mathf.Max(thisTR.y, Mathf.Max(thisBL.y, thisBR.y))); if (IsIntersectingAABB(r1_minX, r1_maxX, r1_minY, r1_maxY, r2_minX, r2_maxX, r2_minY, r2_maxY)) { isIntersecting = true; } return(isIntersecting); }
//Find out if 2 rectangles with orientation are intersecting by using the SAT algorithm private bool SATRectangleRectangle(AxisAlignBoundingBoxHull2D other) { bool isIntersecting = false; //We have just 4 normals because the other 4 normals are the same but in another direction //So we only need a maximum of 4 tests if we have rectangles //It is enough if one side is not overlapping, if so we know the rectangles are not intersecting Vector2 otherTL = other.upLeft; Vector2 otherTR = other.upRight; Vector2 otherBL = other.botLeft; Vector2 otherBR = other.botRight; Vector2 thisTL = topLeftAxis; Vector2 thisTR = topRightAxis; Vector2 thisBL = botLeftAxis; Vector2 thisBR = botRightAxis; //Test 1 Vector3 normal1 = GetNormal(otherBL, otherTL); if (!IsOverlappingABB(normal1, other, this)) { //No intersection is possible! return(isIntersecting); } //Test 2 Vector3 normal2 = GetNormal(otherTL, otherTR); if (!IsOverlappingABB(normal2, other, this)) { return(isIntersecting); } //Test 3 Vector3 normal3 = GetNormal(thisBL, thisTL); if (!IsOverlappingABB(normal3, other, this)) { return(isIntersecting); } //Test 4 Vector3 normal4 = GetNormal(thisTL, thisTR); if (!IsOverlappingABB(normal4, other, this)) { return(isIntersecting); } //If we have come this far, then we know all sides are overlapping //So the rectangles are intersecting! isIntersecting = true; return(isIntersecting); }
public override bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c) { // calculate closest point by clamping circle center on each dimension // Find the vector2 distance between box & circle // Normalize that vector // multiply the vector by the radius to get the closest point on the circumference // Check if closest point is within box bounds // pass if closest point vs. circle passes return(other.TestCollisionVSCircle(this, ref c)); }
public override bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c) { // Same as OBB vs OBB, but only project to ABB up and right normal // check the points bool isIntersecting = false; //Find out if the rectangles are intersecting by approximating them with rectangles //with no rotation and then use AABB intersection //Will make it faster if the probability that the rectangles are intersecting is low if (!IsIntersectingAABB_OBB(other)) { return(isIntersecting); } //Find out if the rectangles are intersecting by using the Separating Axis Theorem (SAT) isIntersecting = SATRectangleRectangle(other); return(isIntersecting); }
public override bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c) { // for each dimension, max extent of A greater than min extent of B // position - 1/2(length or width) for min point in x or y float thisXMin = position.x - width * 0.5f; // position + 1/2(length or width) for max point in x or y float thisXMax = position.x + width * 0.5f; // position - 1/2(length or width) for min point in x or y float thisYMin = position.y - height * 0.5f; // position + 1/2(length or width) for max point in x or y float thisYMax = position.y + height * 0.5f; // position - 1/2(length or width) for min point in x or y float otherXMin = other.position.x - width * 0.5f; // position + 1/2(length or width) for max point in x or y float otherXMax = other.position.x + width * 0.5f; // position - 1/2(length or width) for min point in x or y float otherYMin = other.position.y - height * 0.5f; // position + 1/2(length or width) for max point in x or y float otherYMax = other.position.y + height * 0.5f; // check which min is greater, greater min becomes the one, other becomes other // if one max.x < other max.x && one max.x > other min.x if (otherXMin < thisXMax && thisXMax < otherXMax) { // if this passes, check same thing with y if (otherYMin < thisYMax && thisYMax < otherYMax) { return(true); } else if (otherYMin < thisYMin && thisYMin < otherYMax) { return(true); } } // check which min is greater, greater min becomes the one, other becomes other // if one min.x < other max.x && one min.x > other min.x if (otherXMin < thisXMin && thisXMin < otherXMax) { // if this passes, check same thing with y if (otherYMin < thisYMax && thisYMax < otherYMax) { return(true); } else if (otherYMin < thisYMin && thisYMin < otherYMax) { return(true); } } return(false); }
public abstract bool TestCollisionVSAABB(AxisAlignBoundingBoxHull2D other, ref Collision c);