//Is this side overlapping? private static bool IsOverlapping(Vector3 normal, ObjectBoundingBoxHull2D other, ObjectBoundingBoxHull2D self) { bool isOverlapping = false; //Project the corners of rectangle 1 onto the normal float dot1 = Vector3.Dot(normal, other.topLeftAxis); float dot2 = Vector3.Dot(normal, other.topRightAxis); float dot3 = Vector3.Dot(normal, other.botLeftAxis); float dot4 = Vector3.Dot(normal, other.botRightAxis); //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); }
public override bool TestCollisionVSOBB(ObjectBoundingBoxHull2D other, ref Collision c) { // Same as above, but first... // transform circle position by multiplying by box world matrix inverse // Find four points on circle, pos.x + cos(a), pos.x - cos(a), pos.y + sin(a), pos.y - sin(a) // Project four points on box normal, project box maxes and mins on circle normal // Run AABB test return(other.TestCollisionVSCircle(this, ref c)); }
public override bool TestCollisionVsOBB(ObjectBoundingBoxHull2D box, ref Collision c) { //AABB-OBB part 2 twice: //Second: transform this into OBB space, find max extents, repat AABB //1) transform into OBB space: //2) find max and min of [??] //3) Call testaabb again return(false); }
public override bool TestCollisionVSOBB(ObjectBoundingBoxHull2D other, ref Collision c) { // Same as above twive // first, test AABB vs max extents of OBB // then, multiply by OBB inverse matrix, do test again // Same as OBB vs OBB, but only project to ABB up and right normal // check the points return(other.TestCollisionVSAABB(this, ref c)); }
public override bool TestCollisionVSOBB(ObjectBoundingBoxHull2D other, ref Collision c) { // AABB-OBB part 2 twice // Call projection function four times, if even one fails, the collision fails // take each corner multiply by the non axis aligned box and 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 //Test 1 Vector2 normal1 = GetNormal(other.botLeftAxis, other.topLeftAxis); if (!IsOverlapping(normal1, other, this)) { //No intersection is possible! return(isIntersecting); } //Test 2 Vector2 normal2 = GetNormal(other.topLeftAxis, other.topRightAxis); if (!IsOverlapping(normal2, other, this)) { return(isIntersecting); } //Test 3 Vector2 normal3 = GetNormal(this.botLeftAxis, this.topLeftAxis); if (!IsOverlapping(normal3, other, this)) { return(isIntersecting); } //Test 4 Vector2 normal4 = GetNormal(this.topLeftAxis, this.topRightAxis); if (!IsOverlapping(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 TestCollisionVsOBB(ObjectBoundingBoxHull2D box, ref Collision c) { //same as above twice: //first: find max extents of OBB, do AABB vs this //call test aabb //Finding corners/Max-Min of box //bottom left float box_X = box.transform.position.x - box.length * 0.5f; float box_Y = box.transform.position.y - box.height * 0.5f; Vector2 box_bottomLeft = new Vector2(box_X, box_Y); //top right box_X = box.transform.position.x + box.length * 0.5f; box_Y = box.transform.position.y + box.height * 0.5f; Vector2 box_topRight = new Vector2(box_X, box_Y); //Finding corners of this //bottom left float this_X = transform.position.x - length * 0.5f; float this_Y = transform.position.y - height * 0.5f; Vector2 this_bottomLeft = new Vector2(this_X, this_Y); //top right this_X = transform.position.x + length * 0.5f; this_Y = transform.position.y + height * 0.5f; Vector2 this_topRight = new Vector2(this_X, this_Y); //TestCollisionVsAABB(); //box.TestCollisionVsAABB(this); //Second: transform this into OBB space, find max extents, repat AABB //1) transform into OBB space: //2) find max and min of [??] //3) Call testaabb again return(false); }
public abstract bool TestCollisionVsOBB(ObjectBoundingBoxHull2D box, ref Collision c);
public AxisAlignedBoundingBoxHull2D(ObjectBoundingBoxHull2D temp) : base(CollisionHullType2D.Hull_AABB) { length = temp.length; height = temp.height; this.transform.position = temp.transform.position; }
public override bool TestCollisionVsOBB(ObjectBoundingBoxHull2D box, ref Collision col) { //Same as above, but first: //move circle center into box space by * -world transform //1) this.position is now * -box.position //2) call testAABB with box Debug.Log("OBB v Circ Start"); //Vector2 circCenter = -box.transform.localToWorldMatrix.MultiplyVector(this.transform.position); //Vector2 circCenter = this.transform.position; //get the norms of the box float RotZOBB = box.transform.eulerAngles.z; //Vector2 xNormOBB = new Vector2(Mathf.Cos(RotZOBB), Mathf.Sin(RotZOBB)); //Vector2 yNormOBB = new Vector2(-Mathf.Sin(RotZOBB), Mathf.Cos(RotZOBB)); //just rotate the circle around the centerpoint of the box using the norm (or angle) of the box then call AABB // this is a copy over for AABB test (dont change these values, we just need to change the circle) // the box is rotated by the -RotZOBB in a way to get back to axis aligned, so we need to do the same for the circle //AxisAlignedBoundingBoxHull2D newBox = this.gameObject.AddComponent(typeof(AxisAlignedBoundingBoxHull2D)) as AxisAlignedBoundingBoxHull2D; //AxisAlignedBoundingBoxHull2D newBox = gameObject.AddComponent<AxisAlignedBoundingBoxHull2D>(); //CollisionHull2D newBox = null; //GameObject temp = new GameObject(); //AxisAlignedBoundingBoxHull2D newBox = temp.AddComponent<AxisAlignedBoundingBoxHull2D>(); //AxisAlignedBoundingBoxHull2D newBox = new AxisAlignedBoundingBoxHull2D(box); /* * AxisAlignedBoundingBoxHull2D newBox = new AxisAlignedBoundingBoxHull2D(); * newBox.length = box.length; * newBox.height = box.height; * newBox.transform.position = box.transform.position; * * //create a new circle to edit * CircleHull2D newCirc = new CircleHull2D(); * newCirc.radius = this.radius; * * //Rotate centerpoint of circ around the box pos point by the angle of the box * float subPosX = circCenter.x - box.transform.position.x; * float subPosY = circCenter.y - box.transform.position.y; * Vector2 newPos = new Vector2(Mathf.Cos(-RotZOBB) * (subPosX) - Mathf.Sin(-RotZOBB) * (subPosY) + box.transform.position.x, * Mathf.Sin(-RotZOBB) * (subPosX) + Mathf.Cos(-RotZOBB) * (subPosY) + box.transform.position.y); * * newCirc.transform.position = newPos; * * //a possible problem is that now that we have a new * //return newCirc.TestCollisionVsAABB(newBox, ref c); */ Vector2 circCenter = this.transform.position; Vector2 boxCenter = box.transform.position; float subPosX = circCenter.x - box.transform.position.x; float subPosY = circCenter.y - box.transform.position.y; Vector2 newPos = new Vector2(Mathf.Cos(-RotZOBB) * (subPosX) - Mathf.Sin(-RotZOBB) * (subPosY) + box.transform.position.x, Mathf.Sin(-RotZOBB) * (subPosX) + Mathf.Cos(-RotZOBB) * (subPosY) + box.transform.position.y); circCenter = newPos; float boxXMin = box.transform.position.x - (box.length * 0.5f); float boxYMin = box.transform.position.y - (box.height * 0.5f); float boxXMax = box.transform.position.x + (box.length * 0.5f); float boxYMax = box.transform.position.y + (box.height * 0.5f); float clampedX = Mathf.Clamp(circCenter.x, boxXMin, boxXMax); float clampedY = Mathf.Clamp(circCenter.y, boxYMin, boxYMax); Vector2 distance = new Vector2(circCenter.x - clampedX, circCenter.y - clampedY); float dSq = (distance.x * distance.x) + (distance.y * distance.y); if (dSq < (this.radius * this.radius)) { Debug.Log("OBB v C pass"); hitExplode = true; //Assign objects col.a = this; col.b = box; Vector2 clamped = new Vector2(clampedX, clampedY); //get the clamped combinded vector as the point to have norm from Vector2 Point = (clamped + (distance.normalized * this.radius)) * 0.5f; //take the centerpoint of the circle, subtract the point to get the norm (it may be point - circ) //Vector2 norm = (circCenter - Point).normalized; //(same as distance) //col.contacts[0].normal = norm; col.contacts[0].normal = distance.normalized; col.contacts[0].point = Point; //radius of the circle minus the distance to the original point of entry col.interpenDepth = (this.radius * this.radius) - dSq; //col.interpenDepth = ((this.radius + clamped.magnitude) * (this.radius + clamped.magnitude)) - dSq; //col.interpenDepth = (this.radius + clamped.magnitude) - distance.magnitude; return(true); } else { Debug.Log("OBB v C fail"); return(false); } /* * //bottom left * float x = box.transform.position.x - box.length * 0.5f; * float y = box.transform.position.y - box.height * 0.5f; * Vector2 bottomLeft = new Vector2(x, y); * * //bottom right * x = box.transform.position.x + box.length * 0.5f; * y = box.transform.position.y - box.height * 0.5f; * Vector2 bottomRight = new Vector2(x, y); * * //top left * x = box.transform.position.x + box.length * 0.5f; * y = box.transform.position.y - box.height * 0.5f; * Vector2 topLeft = new Vector2(x, y); * * //top right * x = box.transform.position.x + box.length * 0.5f; * y = box.transform.position.y + box.height * 0.5f; * Vector2 topRight = new Vector2(x, y); * * * //project all x valued (one for each corner, 4) vertices onto normal for x * //Vector2 xNormProjectedVertices = Vector3.Project( , xNormOBB); * Vector2 pointX1 = (bottomLeft * xNormOBB) * xNormOBB; * Vector2 pointX2 = (bottomRight * xNormOBB) * xNormOBB; * Vector2 pointX3 = (topLeft * xNormOBB) * xNormOBB; * Vector2 pointX4 = (topRight * xNormOBB) * xNormOBB; * * * //project all y valued (one for each corner, 4) vertices onto normal for y * Vector2 pointY1 = (bottomLeft * yNormOBB) * yNormOBB; * Vector2 pointY2 = (bottomRight * yNormOBB) * yNormOBB; * Vector2 pointY3 = (topLeft * yNormOBB) * yNormOBB; * Vector2 pointY4 = (topRight * yNormOBB) * yNormOBB; * */ /* * //bottom left * float x1 = box.transform.position.x - box.length * 0.5f; * float x2 = box.transform.position.x + box.length * 0.5f; * Vector2 bottomLeft = new Vector2(x1, x2); * * //top right * float y1 = box.transform.position.y - box.height * 0.5f; * float y2 = box.transform.position.y + box.height * 0.5f; * Vector2 topRight = new Vector2(y1, y2); * * //go to world space * Vector2 localToWorldX = box.transform.localToWorldMatrix.MultiplyVector(bottomLeft); * Vector2 localToWorldY = box.transform.localToWorldMatrix.MultiplyVector(topRight); * * * * //AxisAlignedBoundingBoxHull2D newBox = new AxisAlignedBoundingBoxHull2D(); * * * //AABB, finding corners(sides) in if() * bool colOnX = false; * bool colOnY = false; * * Debug.Log("circPos: " + circCenter + " localToWorldX: " + localToWorldX + " localToWorldY: " + localToWorldY); * * if (circCenter.x + radius >= localToWorldX.x && localToWorldX.y >= circCenter.x - radius) * { * colOnX = true; * } * * if (circCenter.y + radius >= localToWorldY.x && localToWorldY.y >= circCenter.y - radius) * { * colOnY = true; * } * * if (colOnY && colOnX) * { * updateCollision(ref c); * return true; * } * else * { * return false; * } */ //Assign objects //col.a = this; //col.b = box; // //return false; //return this.TestCollisionVsAABB(box, ref c); }
public abstract bool TestCollisionVSOBB(ObjectBoundingBoxHull2D other, ref Collision c);