static protected bool AABBVSOBB(AABBHull AABB, OBBHull OBB) { Vector2 AABBMinTransform = OBB.transform.InverseTransformPoint(AABB.min + AABB.center); Vector2 AABBMaxTransform = OBB.transform.InverseTransformPoint(AABB.max + AABB.center); //Debug.DrawLine(AABBMinTransform, AABBMaxTransform, Color.red); //Debug.DrawLine(OBB.min, OBB.max, Color.green); //Debug.DrawLine(AABB.center, OBB.center, Color.yellow); if (AABB.max.x + AABB.center.x >= OBB.min.x + OBB.center.x && OBB.max.x + OBB.center.x >= AABB.min.x + AABB.center.x) { if (AABB.max.y + AABB.center.y >= OBB.min.y + OBB.center.y && OBB.max.y + OBB.center.y >= AABB.min.y + AABB.center.y) { /*if (obbMinTransform.x > obbMaxTransform.x && obbMinTransform.y > obbMaxTransform.y) * { * Vector2 temp = obbMinTransform; * obbMinTransform = obbMaxTransform; * obbMaxTransform = temp; * }*/ if (AABBMaxTransform.x + AABB.center.x >= OBB.min.x + OBB.center.x && OBB.max.x + OBB.center.x >= AABBMinTransform.x + AABB.center.x) { if (AABBMaxTransform.y + AABB.center.y >= OBB.min.x + OBB.center.y && OBB.max.x + OBB.center.y >= AABBMinTransform.y + AABB.center.y) { return(true); } } } } return(false); }
static protected CollisionInfo AABBVSAABB(AABBHull AABB1, AABBHull AABB2) { Vector3 AtoB = AABB2.center - AABB1.center; float x_overlap = AABB1.halfExtends.x + AABB2.halfExtends.x - Mathf.Abs(AtoB.x); if (x_overlap > 0.0f) { float y_overlap = AABB1.halfExtends.y + AABB2.halfExtends.y - Mathf.Abs(AtoB.y); if (y_overlap > 0.0f) { float z_overlap = AABB1.halfExtends.z + AABB2.halfExtends.z - Mathf.Abs(AtoB.z); { if (z_overlap > 0.0f) { float minOverlap = Mathf.Min(x_overlap, y_overlap, z_overlap); if (minOverlap == x_overlap) { return(new CollisionInfo(AABB1, AABB2, AtoB.x < 0.0f ? -Vector3.right : Vector3.right, x_overlap)); } else if (minOverlap == y_overlap) { return(new CollisionInfo(AABB1, AABB2, AtoB.y < 0.0f ? -Vector3.up : Vector3.up, y_overlap)); } else if (minOverlap == z_overlap) { return(new CollisionInfo(AABB1, AABB2, AtoB.y < 0.0f ? -Vector3.forward : Vector3.forward, z_overlap)); } } } } } return(null); }
public static HullCollision CircleAABBCollision(CircleHull circleHull, AABBHull boxHull) { Particle2D A = boxHull.GetComponent <Particle2D>(); Particle2D B = circleHull.GetComponent <Particle2D>(); Vector3 closestPoint = new Vector3(0.0f, 0.0f); Vector3 range = (circleHull.transform.position + circleHull.offset) - (boxHull.transform.position + boxHull.offset); closestPoint = new Vector3(Mathf.Clamp(range.x, -boxHull.halfX, boxHull.halfX), Mathf.Clamp(range.y, -boxHull.halfY, boxHull.halfY)); HullCollision col = new HullCollision(); col.a = boxHull; col.b = circleHull; Vector3 closingVel = B.velocity - A.velocity; Vector3 penetration = range - (closestPoint - circleHull.transform.position + circleHull.offset); col.closingVelocity = closingVel; col.penetration = penetration; HullCollision.Contact con0 = new HullCollision.Contact(); con0.point = closestPoint; con0.restitution = Mathf.Min(boxHull.restitution, circleHull.restitution); Vector3 collisionNormal = new Vector3(); if ((range - closestPoint).magnitude - circleHull.radius < 0) { if (con0.point.x == boxHull.halfX)//added mathf { collisionNormal = new Vector3(1.0f, 0.0f); } if (con0.point.x == -boxHull.halfX)//added mathf { collisionNormal = new Vector3(-1.0f, 0.0f); } if (con0.point.y == boxHull.halfY) { collisionNormal = new Vector3(0.0f, 1.0f); } if (con0.point.y == -boxHull.halfY) { collisionNormal = new Vector3(0.0f, -1.0f); } con0.normal = collisionNormal; col.status = true; col.contacts[0] = con0; } else { col.status = false; } return(col); }
static public bool AABBVSAABB(AABBHull AABB1, AABBHull AABB2) { if (AABB1.max.x >= AABB2.min.x && AABB1.max.y >= AABB2.min.y && AABB2.max.x >= AABB1.min.x && AABB2.max.x >= AABB1.min.y) { return(true); } return(false); }
static protected bool AABBVSAABB(AABBHull AABB1, AABBHull AABB2) { if (AABB1.max.x + AABB1.center.x >= AABB2.min.x + AABB2.center.x && AABB1.max.y + AABB1.center.y >= AABB2.min.y + AABB2.center.y && AABB2.max.x + AABB2.center.x >= AABB1.min.x + AABB1.center.x && AABB2.max.y + AABB2.center.y >= AABB1.min.y + AABB1.center.y) { return(true); } return(false); }
protected static CollisionInfo CircleVSAABB(CircleHull circle, AABBHull AABB) { Vector3 circleBox = new Vector3(Mathf.Max(AABB.min.x + AABB.center.x, Mathf.Min(circle.GetCenter().x, AABB.max.x + AABB.center.x)), Mathf.Max(AABB.min.y + AABB.center.y, Mathf.Min(circle.GetCenter().y, AABB.max.y + AABB.center.y)), Mathf.Max(AABB.min.z + AABB.center.z, Mathf.Min(circle.GetCenter().z, AABB.max.z + AABB.center.z))); Vector3 distanceVec = circle.GetCenter() - circleBox; float distanceSQ = Vector3.Dot(distanceVec, distanceVec); if (distanceSQ > (circle.radius * circle.radius)) { return null; } float distance = Mathf.Sqrt(distanceSQ); return new CollisionInfo(circle, AABB, -distanceVec.normalized, circle.radius - distance, circleBox); }
static protected bool CircleVSAABB(CircleHull circle, AABBHull AABB) { Vector2 circleBox = new Vector2(Mathf.Max(AABB.min.x + AABB.center.x, Mathf.Min(circle.GetCenter().x, AABB.max.x + AABB.center.x)), Mathf.Max(AABB.min.y + AABB.center.y, Mathf.Min(circle.GetCenter().y, AABB.max.y + AABB.center.y))); Vector2 distance = circle.GetCenter() - circleBox; float distanceSQ = Vector2.Dot(distance, distance); if (distanceSQ <= (circle.radius * circle.radius)) { return(true); } return(false); }
static protected CollisionInfo AABBVSAABB(AABBHull AABB1, AABBHull AABB2) { Vector2 AtoB = AABB2.center - AABB1.center; float x_overlap = AABB1.halfExtends.x + AABB2.halfExtends.x - Mathf.Abs(AtoB.x); if (x_overlap > 0.0f) { float y_overlap = AABB1.halfExtends.y + AABB2.halfExtends.y - Mathf.Abs(AtoB.y); if (y_overlap > 0.0f) { if (x_overlap < y_overlap) { return(new CollisionInfo(AABB1, AABB2, AtoB.x < 0.0f ? -Vector2.right : Vector2.right, x_overlap)); } else { return(new CollisionInfo(AABB1, AABB2, AtoB.y < 0.0f ? -Vector2.up : Vector2.up, y_overlap)); } } } return(null); }
static protected CollisionInfo AABBVSOBB(AABBHull AABB, OBBHull OBB) { List <Vector2> allAxis = new List <Vector2>(); allAxis.AddRange(AABB.NormalAxis); allAxis.AddRange(OBB.NormalAxis); foreach (var axis in allAxis) { float AABBMin = float.MaxValue; float AABBMax = float.MinValue; foreach (var vert in AABB.Vertices) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < AABBMin) { AABBMin = dotValue; } if (dotValue > AABBMax) { AABBMax = dotValue; } } float OBBMin = float.MaxValue; float OBBMax = float.MinValue; foreach (var vert in OBB.Vertices) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < OBBMin) { OBBMin = dotValue; } if (dotValue > OBBMax) { OBBMax = dotValue; } } if (!(AABBMax < OBBMin && OBBMax < AABBMin)) { Vector2 OBBExtend = (OBB.RotMax - OBB.RotMin) / 2f; Vector2 AtoB = OBB.center - AABB.center; float x_overlap = AABB.halfExtends.x + OBBExtend.x - Mathf.Abs(AtoB.x); if (x_overlap > 0.0f) { float y_overlap = AABB.halfExtends.y + OBBExtend.y - Mathf.Abs(AtoB.y); if (y_overlap > 0.0f) { if (x_overlap < y_overlap) { return(new CollisionInfo(AABB, OBB, AtoB.x < 0.0f ? -Vector2.right : Vector2.right, x_overlap)); } else { return(new CollisionInfo(AABB, OBB, AtoB.y < 0.0f ? -Vector2.up : Vector2.up, y_overlap)); } } } } } return(null); }
protected static CollisionInfo AABBVSOBB(AABBHull AABB, OBBHull OBB) { Vector3 toCenter = AABB.center - OBB.center; return boxTest(AABB, OBB, toCenter, AABB.halfExtends, OBB.halfExtends); }
public static HullCollision AABBOBBCollision(AABBHull AABBHull, OBBHull OBBHull) { Particle2D A = AABBHull.GetComponent <Particle2D>(); Particle2D B = OBBHull.GetComponent <Particle2D>(); Vector3[] shape1Corners; Vector3[] shape2Corners; shape1Corners = new Vector3[4]; shape2Corners = new Vector3[4]; Vector3[] normals = new Vector3[4]; float[] shape1MinMax = new float[2]; float[] shape2MinMax = new float[2]; shape1Corners[0] = AABBHull.transform.position - new Vector3(AABBHull.halfX, AABBHull.halfY) + AABBHull.offset; shape1Corners[1] = AABBHull.transform.position - new Vector3(AABBHull.halfX, -AABBHull.halfY) + AABBHull.offset; shape1Corners[2] = AABBHull.transform.position + new Vector3(AABBHull.halfX, AABBHull.halfY) + AABBHull.offset; shape1Corners[3] = AABBHull.transform.position + new Vector3(AABBHull.halfX, -AABBHull.halfY) + AABBHull.offset; shape2Corners = getRotatedCorners(OBBHull); normals[0] = new Vector3(0.0f, 1.0f, 0.0f); normals[1] = new Vector3(1.0f, 0.0f, 0.0f); normals[2] = getUpNormal(-OBBHull.currentRotation); normals[3] = getRightNormal(-OBBHull.currentRotation); HullCollision col = new HullCollision(); col.a = AABBHull; col.b = OBBHull; Vector3 range = (OBBHull.transform.position + OBBHull.offset) - (AABBHull.transform.position + AABBHull.offset); //float xOverlap = boxHull1.halfX + boxHull2.halfX - Mathf.Abs(range.x); //float yOverlap = boxHull1.halfY + boxHull2.halfY - Mathf.Abs(range.y); //TRANSPORTATION //col.penetration = new Vector3(xOverlap, yOverlap); //Vector3 closingVel = A.velocity - B.velocity; Vector3 closingVel = B.velocity - A.velocity; col.closingVelocity = closingVel; HullCollision.Contact con0 = new HullCollision.Contact(); con0.point = new Vector3(Mathf.Clamp(range.x, -AABBHull.halfX, AABBHull.halfX), Mathf.Clamp(range.y, -AABBHull.halfY, AABBHull.halfY)); con0.restitution = Mathf.Min(AABBHull.restitution, OBBHull.restitution); con0.normal = range.normalized; for (int i = 0; i < normals.Length; i++) { //Debug.Log("testing corner" + i); shape1MinMax = SatTest(normals[i], shape1Corners); shape2MinMax = SatTest(normals[i], shape2Corners); if (!Overlap(shape1MinMax[0], shape1MinMax[1], shape2MinMax[0], shape2MinMax[1])) { //Debug.Log("falure"); col.status = false; return(col); } } col.status = true; col.contacts[0] = con0; return(col); }
public static HullCollision AABBAABBCollision(AABBHull boxHull1, AABBHull boxHull2) { Vector3 min0, max0, min1, max1; Vector3 b1Offset = boxHull1.offset; Vector3 b2Offset = boxHull2.offset; Particle2D A = boxHull1.GetComponent <Particle2D>(); Particle2D B = boxHull2.GetComponent <Particle2D>(); min0 = boxHull1.transform.position - new Vector3(boxHull1.halfX, boxHull1.halfY) + b1Offset; max0 = boxHull1.transform.position + new Vector3(boxHull1.halfX, boxHull1.halfY) + b1Offset; min1 = boxHull2.transform.position - new Vector3(boxHull2.halfX, boxHull2.halfY) + b2Offset; max1 = boxHull2.transform.position + new Vector3(boxHull2.halfX, boxHull2.halfY) + b2Offset; Vector3 range = (boxHull2.transform.position + b2Offset) - (boxHull1.transform.position + b1Offset); // make sure offsets arent screwing things up HullCollision col = new HullCollision(); col.a = boxHull1; col.b = boxHull2; float xOverlap = boxHull1.halfX + boxHull2.halfX - Mathf.Abs(range.x); float yOverlap = boxHull1.halfY + boxHull2.halfY - Mathf.Abs(range.y); //TRANSPORTATION col.penetration = new Vector3(xOverlap, yOverlap); //Vector3 closingVel = A.velocity - B.velocity; Vector3 closingVel = B.velocity - A.velocity; col.closingVelocity = closingVel; HullCollision.Contact con0 = new HullCollision.Contact(); con0.point = new Vector3(Mathf.Clamp(range.x, -boxHull1.halfX, boxHull1.halfX), Mathf.Clamp(range.y, -boxHull1.halfY, boxHull1.halfY)); con0.restitution = Mathf.Min(boxHull1.restitution, boxHull2.restitution); if (max0.x >= min1.x && max1.x >= min0.x) { if (max0.y >= min1.y && max1.y >= min0.y) { Vector3 collisionNormal = new Vector3(); if (con0.point.x == boxHull1.halfX)//added mathf { collisionNormal = new Vector3(1.0f, 0.0f); } if (con0.point.x == -boxHull1.halfX)//added mathf { collisionNormal = new Vector3(-1.0f, 0.0f); } if (con0.point.y == boxHull1.halfY) { collisionNormal = new Vector3(0.0f, 1.0f); } if (con0.point.y == -boxHull1.halfY) { collisionNormal = new Vector3(0.0f, -1.0f); } con0.normal = collisionNormal; col.status = true; } } else { col.status = false; } col.contacts[0] = con0; return(col); }
public static void AABBAABBCollision(CollisionManager.HullCollision col) { Vector3 min0, max0, min1, max1; AABBHull A = col.a.GetComponent <AABBHull>(); AABBHull B = col.b.GetComponent <AABBHull>(); min0 = A.transform.position - A.halfSize + A.localCenter; max0 = A.transform.position + A.halfSize + A.localCenter; min1 = B.transform.position - B.halfSize + B.localCenter; max1 = B.transform.position + B.halfSize + B.localCenter; Vector3 range = (B.transform.position + B.localCenter) - (A.transform.position + A.localCenter); // make sure offsets arent screwing things up float xOverlap = A.halfSize.x + B.halfSize.x - Mathf.Abs(range.x); float yOverlap = A.halfSize.y + B.halfSize.y - Mathf.Abs(range.y); float zOverlap = A.halfSize.z + B.halfSize.z - Mathf.Abs(range.z); // was math.abs col.penetration = new Vector3(xOverlap, yOverlap); //Vector3 closingVel = A.velocity - B.velocity; Vector3 closingVel = B.GetComponent <Particle3D>().velocity - A.GetComponent <Particle3D>().velocity; col.closingVelocity = closingVel; CollisionManager.HullCollision.Contact con0 = new CollisionManager.HullCollision.Contact(); con0.point = new Vector3(Mathf.Clamp(range.x, -A.halfSize.x, A.halfSize.x), Mathf.Clamp(range.y, -A.halfSize.y, A.halfSize.y), Mathf.Clamp(range.z, -A.halfSize.z, A.halfSize.z)); con0.restitution = Mathf.Min(A.restitution, B.restitution); if (max0.x >= min1.x && max1.x >= min0.x) { if (max0.y >= min1.y && max1.y >= min0.y) { Vector3 collisionNormal = new Vector3(); if (con0.point.x == A.halfSize.x)//added mathf { collisionNormal = new Vector3(1.0f, 0.0f, 0.0f); } if (con0.point.x == -A.halfSize.x)//added mathf { collisionNormal = new Vector3(-1.0f, 0.0f, 0.0f); } if (con0.point.y == A.halfSize.y) { collisionNormal = new Vector3(0.0f, 1.0f, 0.0f); } if (con0.point.y == -A.halfSize.y) { collisionNormal = new Vector3(0.0f, -1.0f, 0.0f); } if (con0.point.z == A.halfSize.z) { collisionNormal = new Vector3(0.0f, 0.0f, 1.0f); } if (con0.point.z == -A.halfSize.z) { collisionNormal = new Vector3(0.0f, 0.0f, -1.0f); } con0.normal = collisionNormal; col.status = true; } } else { col.status = false; } col.contacts[0] = con0; }