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); }
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); }
protected static CollisionInfo CircleVSCircle(CircleHull circle1, CircleHull circle2) { float radiusSum = circle1.radius + circle2.radius; float totalRadius = (circle1.radius + circle2.radius) * (circle1.radius + circle2.radius); Vector3 centerDiff = (circle2.GetCenter() - circle1.GetCenter()); float distanceSQ = Vector3.Dot(centerDiff, centerDiff); if (distanceSQ > totalRadius) { return null; } float distance = Mathf.Sqrt(distanceSQ); return new CollisionInfo(circle1, circle2, centerDiff / distance, radiusSum - distance,(circle1.GetCenter() + centerDiff * 0.5f)); }
static public bool CircleVSCircle(CircleHull circle1, CircleHull circle2) { float totalRadius = (circle1.radius + circle2.radius); //* (circle1.radius + circle2.radius); Vector2 distance = (circle2.GetCenter() - circle1.GetCenter()); if (Vector2.Dot(distance, distance) <= totalRadius) { return(true); } else { 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 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 }
public static HullCollision CircleCircleCollision(CircleHull circleHull1, CircleHull circleHull2) { // *IMPORTANT* for circle and square the collision only wirks with obejct1 - object 2 and not viceversa, must be a prob in clollision resolution Vector3 c1Offset = circleHull1.offset; Vector3 c2Offset = circleHull2.offset; Vector3 range = (circleHull2.transform.position + c2Offset) - (circleHull1.transform.position + c1Offset); // make sure offsets arent screwing things up float overlap = (circleHull2.radius + circleHull1.radius) - range.magnitude; HullCollision col = new HullCollision(); col.a = circleHull1; col.b = circleHull2; col.penetration = range * overlap; HullCollision.Contact con0 = new HullCollision.Contact(); con0.point = (range.normalized * circleHull1.radius); con0.point += new Vector3(circleHull1.transform.position.x, circleHull1.transform.position.y); con0.normal = range.normalized; con0.restitution = Mathf.Min(circleHull1.restitution, circleHull2.restitution); col.contacts[0] = con0; Particle2D c1 = circleHull1.GetComponentInParent <Particle2D>(); Particle2D c2 = circleHull2.GetComponentInParent <Particle2D>(); Vector3 closingVel = c2.velocity - c1.velocity; // started as c1 -c2 col.closingVelocity = closingVel; if (overlap > 0) { col.status = true; return(col); } else { col.status = false; return(col); } }
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 }