public static HullCollision OBBOBBCollision(OBBHull boxHull1, OBBHull boxHull2) { Particle2D A = boxHull1.GetComponent <Particle2D>(); Particle2D B = boxHull2.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 = getRotatedCorners(boxHull1); shape2Corners = getRotatedCorners(boxHull2); normals[0] = getUpNormal(-boxHull1.currentRotation); normals[1] = getRightNormal(-boxHull1.currentRotation); normals[2] = getUpNormal(-boxHull2.currentRotation); normals[3] = getRightNormal(-boxHull2.currentRotation); HullCollision col = new HullCollision(); col.a = boxHull1; col.b = boxHull2; Vector3 range = (boxHull2.transform.position + boxHull2.offset) - (boxHull1.transform.position + boxHull1.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, -boxHull1.halfX, boxHull1.halfX), Mathf.Clamp(range.y, -boxHull1.halfY, boxHull1.halfY)); con0.restitution = Mathf.Min(boxHull1.restitution, boxHull2.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); }
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 Vector3[] getRotatedCorners(OBBHull newHull) { Vector3[] returnPoints = new Vector3[4]; returnPoints[0] = getRotatedPoint(new Vector3(newHull.transform.position.x - newHull.halfX, newHull.transform.position.y - newHull.halfY), newHull.transform.position, newHull.currentRotation); returnPoints[1] = getRotatedPoint(new Vector3(newHull.transform.position.x - newHull.halfX, newHull.transform.position.y + newHull.halfY), newHull.transform.position, newHull.currentRotation); returnPoints[2] = getRotatedPoint(new Vector3(newHull.transform.position.x + newHull.halfX, newHull.transform.position.y - newHull.halfY), newHull.transform.position, newHull.currentRotation); returnPoints[3] = getRotatedPoint(new Vector3(newHull.transform.position.x + newHull.halfX, newHull.transform.position.y + newHull.halfY), newHull.transform.position, newHull.currentRotation); return(returnPoints); }
public static HullCollision CircleOBBCollision(CircleHull circleHull, OBBHull OBBHull) { Particle2D A = circleHull.GetComponent <Particle2D>(); Particle2D B = OBBHull.GetComponent <Particle2D>(); Vector3[] OBBCorners; OBBCorners = new Vector3[2];//was 4 Vector3[] normals = new Vector3[2]; float[] OBBMinMax = new float[2]; float[] circleMinMax = new float[2]; OBBCorners = getRotatedCorners(OBBHull); normals[0] = getUpNormal(-OBBHull.currentRotation); normals[1] = getRightNormal(-OBBHull.currentRotation); //normals[2] = getUpNormal(-OBBHull2.currentRotation); //normals[3] = getRightNormal(-boxHull2.currentRotation); HullCollision col = new HullCollision(); col.a = circleHull; col.b = OBBHull; Vector3 range = (OBBHull.transform.position + OBBHull.offset) - (circleHull.transform.position + circleHull.offset); Vector3 rotatedRange = getRotatedPoint(range, new Vector3(0.0f, 0.0f), -OBBHull.currentRotation);// 2 circleHull.transform.position Vector3 point = new Vector3(Mathf.Clamp(rotatedRange.x, -OBBHull.halfX, OBBHull.halfX), Mathf.Clamp(rotatedRange.y, -OBBHull.halfY, OBBHull.halfY)); //Debug.Log("range " + range); //Debug.Log("rotrange " + rotatedRange); //float xOverlap = boxHull1.halfX + boxHull2.halfX - Mathf.Abs(range.x); //float yOverlap = boxHull1.halfY + boxHull2.halfY - Mathf.Abs(range.y); //col.penetration = new Vector3(xOverlap, yOverlap); Vector3 closingVel = B.velocity - A.velocity; col.closingVelocity = closingVel; HullCollision.Contact con0 = new HullCollision.Contact(); con0.point = new Vector3(Mathf.Clamp(range.x, -OBBHull.halfX, OBBHull.halfX), Mathf.Clamp(range.y, -OBBHull.halfY, OBBHull.halfY)); con0.restitution = Mathf.Min(OBBHull.restitution, circleHull.restitution); con0.normal = range.normalized; //Debug.Log("point " + point); col.status = false; if ((rotatedRange - point).magnitude - circleHull.radius < 0) { col.status = true; col.contacts[0] = con0; } return(col); }
static protected bool OBBVSOBB(OBBHull OBB1, OBBHull OBB2) { List <Vector2> allAxis = new List <Vector2>(); allAxis.AddRange(OBB1.NormalAxis); allAxis.AddRange(OBB2.NormalAxis); foreach (var axis in allAxis) { float OBB1Min = float.MaxValue; float OBB1Max = float.MinValue; foreach (var vert in OBB1.Vertices) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < OBB1Min) { OBB1Min = dotValue; } if (dotValue > OBB1Max) { OBB1Max = dotValue; } } float OBB2Min = float.MaxValue; float OBB2Max = float.MinValue; foreach (var vert in OBB2.Vertices) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < OBB2Min) { OBB2Min = dotValue; } if (dotValue > OBB2Max) { OBB2Max = dotValue; } } if (!(OBB1Max >= OBB2Min && OBB2Max >= OBB1Min)) { return(false); } } return(true); }
static protected bool CircleVSOBB(CircleHull circle, OBBHull OBB) { Vector2 halfExtend = (OBB.max - OBB.min) / 2; Vector2 circleInOBB = OBB.transform.InverseTransformPoint(circle.GetCenter()); Vector2 circleBox = new Vector2(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)), Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y))); Vector2 distance = circleInOBB - circleBox; float distanceSQ = Vector2.Dot(distance, distance); if (distanceSQ <= (circle.radius * circle.radius)) { return(true); } return(false); }
static protected CollisionInfo CircleVSOBB(CircleHull circle, OBBHull OBB) { Vector2 halfExtend = (OBB.max - OBB.min) / 2; Vector2 circleInOBB = OBB.transform.InverseTransformPoint(circle.GetCenter()); Vector2 circleBox = new Vector2(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)), Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y))); Vector2 distanceVec = circleInOBB - circleBox; float distanceSQ = Vector2.Dot(distanceVec, distanceVec); if (distanceSQ > (circle.radius * circle.radius)) { return(null); } float distance = Mathf.Sqrt(distanceSQ); return(new CollisionInfo(circle, OBB, OBB.transform.TransformVector(-distanceVec).normalized, circle.radius - distance)); }
protected static CollisionInfo CircleVSOBB(CircleHull circle, OBBHull OBB) { Vector3 halfExtend = OBB.halfExtends; Vector3 circleInOBB = OBB.GetComponent<Particle3D>().getWorldToObject().MultiplyPoint(circle.GetCenter()); Vector3 circleBox = new Vector3(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)), Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y)), Mathf.Max(-halfExtend.z, Mathf.Min(circleInOBB.z, halfExtend.z))); Vector3 distanceVec = circleInOBB - circleBox; float distanceSQ = Vector3.Dot(distanceVec, distanceVec); if (distanceSQ > (circle.radius * circle.radius)) { return null; } Vector3 closestPt = new Vector3(0f,0f,0f); float dist; // Clamp each coordinate to the box. dist = circleInOBB.x; if (dist > OBB.halfExtends.x) dist = OBB.halfExtends.x; if (dist < -OBB.halfExtends.x) dist = -OBB.halfExtends.x; closestPt.x = dist; dist = circleInOBB.y; if (dist > OBB.halfExtends.y) dist = OBB.halfExtends.y; if (dist < -OBB.halfExtends.y) dist = -OBB.halfExtends.y; closestPt.y = dist; dist = circleInOBB.z; if (dist > OBB.halfExtends.z) dist = OBB.halfExtends.z; if (dist < -OBB.halfExtends.z) dist = -OBB.halfExtends.z; closestPt.z = dist; // Check to see if we’re in contact. dist = (closestPt - circleInOBB).sqrMagnitude; if (dist > circle.radius * circle.radius) return null; // Compile the contact. Vector3 closestPtWorld = OBB.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(closestPt); //place contact point in world space float distance = Mathf.Sqrt(distanceSQ); //Debug.LogError(closestPtWorld); return new CollisionInfo(circle, OBB, (-distanceVec).normalized, (circle.radius - distance),closestPtWorld); //OBB.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(-distanceVec).normalized this failed to work, removing it fixed it }
static protected CollisionInfo CircleVSOBB(CircleHull circle, OBBHull OBB) { Vector3 halfExtend = OBB.halfExtends; Vector3 circleInOBB = OBB.GetComponent <Particle3D>().getWorldToObject().MultiplyPoint(circle.GetCenter()); Vector3 circleBox = new Vector3(Mathf.Max(-halfExtend.x, Mathf.Min(circleInOBB.x, halfExtend.x)), Mathf.Max(-halfExtend.y, Mathf.Min(circleInOBB.y, halfExtend.y)), Mathf.Max(-halfExtend.z, Mathf.Min(circleInOBB.z, halfExtend.z))); Vector3 distanceVec = circleInOBB - circleBox; float distanceSQ = Vector3.Dot(distanceVec, distanceVec); if (distanceSQ > (circle.radius * circle.radius)) { return(null); } //place contact point in world space float distance = Mathf.Sqrt(distanceSQ); return(new CollisionInfo(circle, OBB, (-distanceVec).normalized, (circle.radius - distance))); //OBB.GetComponent<Particle3D>().getObjectToWorld().MultiplyPoint(-distanceVec).normalized this failed to work, removing it fixed it }
static protected CollisionInfo OBBVSOBB(OBBHull OBB1, OBBHull OBB2) { List <Vector2> allAxis = new List <Vector2>(); allAxis.AddRange(OBB1.NormalAxis); allAxis.AddRange(OBB2.NormalAxis); foreach (var axis in allAxis) { float OBB1Min = float.MaxValue; float OBB1Max = float.MinValue; foreach (var vert in OBB1.Vertices) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < OBB1Min) { OBB1Min = dotValue; } if (dotValue > OBB1Max) { OBB1Max = dotValue; } } float OBB2Min = float.MaxValue; float OBB2Max = float.MinValue; foreach (var vert in OBB2.Vertices) { float dotValue = (vert.x * axis.x + vert.y * axis.y); if (dotValue < OBB2Min) { OBB2Min = dotValue; } if (dotValue > OBB2Max) { OBB2Max = dotValue; } } if (!(OBB1Max < OBB2Min && OBB2Max < OBB1Min)) { Vector2 AtoB = OBB2.center - OBB1.center; float x_overlap = OBB1.halfExtends.x + OBB2.halfExtends.x - Mathf.Abs(AtoB.x); if (x_overlap > 0.0f) { float y_overlap = OBB1.halfExtends.y + OBB2.halfExtends.y - Mathf.Abs(AtoB.y); if (y_overlap > 0.0f) { if (x_overlap < y_overlap) { return(new CollisionInfo(OBB1, OBB2, AtoB.x < 0.0f ? -Vector2.right : Vector2.right, x_overlap)); } else { return(new CollisionInfo(OBB1, OBB2, 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); }
// Start is called before the first frame update void Start() { thrust = GetComponent <Particle2D>(); hull = GetComponent <OBBHull>(); bulletPrefab = Resources.Load("Bullet") as GameObject; }
protected static CollisionInfo AABBVSOBB(AABBHull AABB, OBBHull OBB) { Vector3 toCenter = AABB.center - OBB.center; return boxTest(AABB, OBB, toCenter, AABB.halfExtends, OBB.halfExtends); }
protected static CollisionInfo OBBVSOBB(OBBHull OBB1, OBBHull OBB2) { Vector3 toCenter = OBB1.center - OBB2.center; return boxTest(OBB1,OBB2, toCenter,OBB1.halfExtends,OBB2.halfExtends); }
static public bool OBBVSOBB(OBBHull OBB1, OBBHull OBB2) { //project onto both axis, get new min and max for both, then aabb test return(false); }