public PixelLine Shift(Direction direction, float distance) { PixelLine pixelLine = new PixelLine(this); pixelLine.p1 = PixelPoint.Shift(this.p1, direction, distance); pixelLine.p2 = PixelPoint.Shift(this.p2, direction, distance); return(pixelLine); }
public static float DistanceOrthographic(PixelLine line, Vector2 pt) { float m = (line.p2.y - line.p1.y) / (line.p2.x - line.p1.x); // Slope of parallel lines float i1 = line.p1.y - line.p1.x * m; // Intercept 1 float i2 = pt.y - pt.x * m; // Intercept 2 float dist = (i2 - i1) / 2 / Mathf.Abs(m / Mathf.Sqrt(m * m + 1)); return(dist); }
public static float Distance(PixelLine l1, PixelLine l2) { float m = (l1.p2.y - l1.p1.y) / (l1.p2.x - l1.p1.x); // Slope of parallel lines float i1 = l1.p1.y - l1.p1.x * m; // Intercept 1 float i2 = l2.p1.y - l2.p1.x * m; // Intercept 2 float dist = (i2 - i1) / Mathf.Sqrt(m * m + 1); return(dist); }
// Within the body public bool WithinCollisionBody(Vector2 position, float margin = 0.0f) { if (PixelLine.DistanceOrthographic(lineNW, position) >= margin) { return(false); } if (PixelLine.DistanceOrthographic(lineNE, position) >= margin) { return(false); } if (PixelLine.DistanceOrthographic(lineSW, position) <= -margin) { return(false); } if (PixelLine.DistanceOrthographic(lineSE, position) <= -margin) { return(false); } return(true); }
public static PixelBoxComparison CompareTwoCollisionBodies(PixelBox a, PixelBox b, float margin = 0.0f, bool debug = false) { Vector2 atopWorld = a.top; Vector2 abottomWorld = a.bottom; Vector2 aleftWorld = a.left; Vector2 arightWorld = a.right; Vector2 btopWorld = b.top; Vector2 bbottomWorld = b.bottom; Vector2 bleftWorld = b.left; Vector2 brightWorld = b.right; PixelBoxComparison collisionBodyComparision = new PixelBoxComparison(); bool aTopLeft = PixelLine.DistanceOrthographic(a.lineNW, b.lineSE) >= -margin; bool aTopRight = PixelLine.DistanceOrthographic(a.lineNE, b.lineSW) >= -margin; bool aBottomRight = PixelLine.DistanceOrthographic(b.lineNW, a.lineSE) >= -margin; bool aBottomLeft = PixelLine.DistanceOrthographic(b.lineNE, a.lineSW) >= -margin; bool aTopRightWithin = PixelLine.DistanceOrthographic(b.lineNE, a.lineNE) <= margin; bool aTopLeftWithin = PixelLine.DistanceOrthographic(b.lineNW, a.lineNW) <= margin; bool aBottomLeftWithin = PixelLine.DistanceOrthographic(a.lineSW, b.lineSW) <= margin; bool aBottomRightWithin = PixelLine.DistanceOrthographic(a.lineSE, b.lineSE) <= margin; collisionBodyComparision.NEinside = aTopRightWithin; collisionBodyComparision.NWinside = aTopLeftWithin; collisionBodyComparision.SEinside = aBottomRightWithin; collisionBodyComparision.SWinside = aBottomLeftWithin; collisionBodyComparision.NEoutside = aBottomLeft; collisionBodyComparision.NWoutside = aBottomRight; collisionBodyComparision.SEoutside = aTopLeft; collisionBodyComparision.SWoutside = aTopRight; // Debugging Tools if (debug) { if (aTopRightWithin) { b.lineNE.Draw(Color.blue, 1.0f); } if (aTopLeftWithin) { b.lineNW.Draw(Color.blue, 1.0f); } if (aBottomLeftWithin) { b.lineSW.Draw(Color.blue, 1.0f); } if (aBottomRightWithin) { b.lineSE.Draw(Color.blue, 1.0f); } } // Sides Vertical if (aTopLeft) { collisionBodyComparision.NWvertical |= (aleftWorld.x < brightWorld.x && aleftWorld.y < brightWorld.y); } if (aTopRight) { collisionBodyComparision.NEvertical |= (arightWorld.x > bleftWorld.x && arightWorld.y < bleftWorld.y); } if (aBottomRight) { collisionBodyComparision.SEvertical |= (bleftWorld.x < arightWorld.x && bleftWorld.y < arightWorld.y); } if (aBottomLeft) { collisionBodyComparision.SWvertical |= (brightWorld.x > aleftWorld.x && brightWorld.y < aleftWorld.y); } // Corners Exclusive if (aTopLeft && aTopRight) { collisionBodyComparision.Nexclusive = true; } if (aTopLeft && aBottomLeft) { collisionBodyComparision.Wexclusive = true; } if (aBottomLeft && aBottomRight) { collisionBodyComparision.Sexclusive = true; } if (aBottomRight && aTopRight) { collisionBodyComparision.Eexclusive = true; } // Sides Inclusive if (aTopLeft && (aBottomLeftWithin || aTopRightWithin)) { collisionBodyComparision.NWinclusive = true; } if (aBottomRight && (aBottomLeftWithin || aTopRightWithin)) { collisionBodyComparision.SEinclusive = true; } if (aTopRight && (aTopLeftWithin || aBottomRightWithin)) { collisionBodyComparision.NEinclusive = true; } if (aBottomLeft && (aBottomRightWithin || aTopLeftWithin)) { collisionBodyComparision.SWinclusive = true; } // Sides Exclusive if (aTopLeft && !aTopRight && !aBottomLeft) { collisionBodyComparision.NWexclusive = true; } if (aTopRight && !aTopLeft && !aBottomRight) { collisionBodyComparision.NEexclusive = true; } if (aBottomLeft && !aBottomRight && !aTopLeft) { collisionBodyComparision.SEexclusive = true; } if (aBottomRight && !aBottomLeft && !aTopRight) { collisionBodyComparision.SWexclusive = true; } // Above and Below if (arightWorld.x < brightWorld.x && aleftWorld.x > bleftWorld.x && (aBottomLeftWithin && aBottomRightWithin)) { collisionBodyComparision.aAbove = true; } if (arightWorld.x < brightWorld.x && aleftWorld.x > bleftWorld.x && (aTopLeftWithin && aTopRightWithin)) { collisionBodyComparision.aBelow = true; } return(collisionBodyComparision); }
// Within Range of a collisionBody public bool WithinRange(PixelBox other, Direction direction, float distance = 0.4f, float negDistance = 2.0f) { PixelBoxComparison comparison = this.CompareWith(other); if (direction == Direction.NW) { if (PixelLine.DistanceOrthographic(lineNW, other.lineSE) < distance && PixelLine.DistanceOrthographic(lineNW, other.lineSE) > -negDistance && left.x < (other.right.x) && top.x > (other.bottom.x) && left.y < (other.right.y) && top.y > (other.bottom.y)) { return(true); } return(false); } else if (direction == Direction.NE) { if (PixelLine.DistanceOrthographic(lineNE, other.lineSW) < distance && PixelLine.DistanceOrthographic(lineNE, other.lineSW) > -negDistance && top.x < (other.bottom.x) && right.x > (other.left.x) && top.y > (other.bottom.y) && right.y < (other.left.y)) { return(true); } return(false); } else if (direction == Direction.SW) { if (PixelLine.DistanceOrthographic(lineSW, other.lineNE) > -distance && PixelLine.DistanceOrthographic(lineSW, other.lineNE) < negDistance && left.x < (other.right.x) && bottom.x > (other.top.x) && left.y > (other.right.y) && bottom.y < (other.top.y)) { return(true); } return(false); } else if (direction == Direction.SE) { if (PixelLine.DistanceOrthographic(lineSE, other.lineNW) > -distance && PixelLine.DistanceOrthographic(lineSE, other.lineNW) < negDistance && bottom.x < (other.top.x) && right.x > (other.left.x) && bottom.y < (other.top.y) && right.y > (other.left.y)) { return(true); } return(false); } else if (direction == Direction.All) { if (PixelLine.DistanceOrthographic(lineNW, other.lineSE) < distance && PixelLine.DistanceOrthographic(lineNW, other.lineSE) > -negDistance && left.x < (other.right.x) && top.x > (other.bottom.x) && left.y < (other.right.y) && top.y > (other.bottom.y)) { return(true); } if (PixelLine.DistanceOrthographic(lineNE, other.lineSW) < distance && PixelLine.DistanceOrthographic(lineNE, other.lineSW) > -negDistance && top.x < (other.bottom.x) && right.x > (other.left.x) && top.y > (other.bottom.y) && right.y < (other.left.y)) { return(true); } if (PixelLine.DistanceOrthographic(lineSW, other.lineNE) > -distance && PixelLine.DistanceOrthographic(lineSW, other.lineNE) < negDistance && left.x < (other.right.x) && bottom.x > (other.top.x) && left.y > (other.right.y) && bottom.y < (other.top.y)) { return(true); } if (PixelLine.DistanceOrthographic(lineSE, other.lineNW) > -distance && PixelLine.DistanceOrthographic(lineSE, other.lineNW) < negDistance && bottom.x < (other.top.x) && right.x > (other.left.x) && bottom.y < (other.top.y) && right.y > (other.left.y)) { return(true); } return(false); } return(false); }
public HashSet <WayPoint> GetNavigationalMesh(Vector2 startPosition, int stepSize = 0, float margin = 0.0f) { if (stepSize == 0) { stepSize = this.stepSize; } if (navigationMesh.Count != 0) { foreach (WayPoint w in navigationMesh) { w.distance = float.MaxValue; w.previous = null; } return(new HashSet <WayPoint>(navigationMesh)); } if (System.Math.Abs(margin) < 0.01f) { Character player = GameObject.Find("Player").GetComponent <Character>(); margin = player.GetComponentInChildren <PixelCollider>().navigationMargin; } if (top == Vector2.zero) { this.gameObject.SetActive(true); this.gameObject.SetActive(false); } Debug.Assert(top != Vector2.zero); Debug.Assert(bottom != Vector2.zero); Debug.Assert(left != Vector2.zero); Debug.Assert(right != Vector2.zero); // Should all be positive float topLeftDist = -PixelLine.DistanceOrthographic(collisionbodyWorld.lineNW, startPosition); float topRightDist = -PixelLine.DistanceOrthographic(collisionbodyWorld.lineNE, startPosition); float bottomLeftDist = PixelLine.DistanceOrthographic(collisionbodyWorld.lineSW, startPosition); float bottomRightDist = PixelLine.DistanceOrthographic(collisionbodyWorld.lineSE, startPosition); Debug.DrawLine(topWorld, leftWorld, Color.blue, 10.0f); Debug.DrawLine(leftWorld, bottomWorld, Color.blue, 10.0f); Debug.DrawLine(bottomWorld, rightWorld, Color.blue, 10.0f); Debug.DrawLine(rightWorld, topWorld, Color.blue, 10.0f); Vector2 topLeftPoint = startPosition + new Vector2(-topLeftDist / 2.23606f * 2, topLeftDist / 2.23606f); Vector2 topRightPoint = startPosition + new Vector2(topRightDist / 2.23606f * 2, topRightDist / 2.23606f); Vector2 bottomLeftPoint = startPosition + new Vector2(-bottomLeftDist / 2.23606f * 2, -bottomLeftDist / 2.23606f); Vector2 bottomRightPoint = startPosition + new Vector2(bottomRightDist / 2.23606f * 2, -bottomRightDist / 2.23606f); Debug.Assert(topLeftDist >= 0); Debug.Assert(topRightDist >= 0); Debug.Assert(bottomLeftDist >= 0); Debug.Assert(bottomRightDist >= 0); float stepSizeLength = (new Vector2(stepSize * 2, stepSize)).magnitude; int topLeftSteps = Mathf.FloorToInt((topLeftDist - margin) / stepSizeLength); int topRightSteps = Mathf.FloorToInt((topRightDist - margin) / stepSizeLength); int bottomLeftSteps = Mathf.FloorToInt((bottomLeftDist - margin) / stepSizeLength); int bottomRightSteps = Mathf.FloorToInt((bottomRightDist - margin) / stepSizeLength); topLeftSteps = topLeftSteps >= 0 ? topLeftSteps : 0; topRightSteps = topRightSteps >= 0 ? topRightSteps : 0; bottomLeftSteps = bottomLeftSteps >= 0 ? bottomLeftSteps : 0; bottomRightSteps = bottomRightSteps >= 0 ? bottomRightSteps : 0; WayPoint[,] wayPointArray = new WayPoint[bottomLeftSteps + topRightSteps + 1, bottomRightSteps + topLeftSteps + 1]; for (int i = -bottomLeftSteps; i <= topRightSteps; ++i) { for (int j = -bottomRightSteps; j <= topLeftSteps; ++j) { Vector2 point = startPosition + new Vector2(stepSize * 2, stepSize) * i + new Vector2(-stepSize * 2, stepSize) * j; WayPoint wayPoint = new WayPoint(point); wayPointArray[i + bottomLeftSteps, j + bottomRightSteps] = wayPoint; } } for (int i = -bottomLeftSteps; i <= topRightSteps; ++i) { for (int j = -bottomRightSteps; j <= topLeftSteps; ++j) { if (i != -bottomLeftSteps) { wayPointArray[i - 1 + bottomLeftSteps, j + bottomRightSteps].neighbours.Add(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps]); } if (i != topRightSteps) { wayPointArray[i + 1 + bottomLeftSteps, j + bottomRightSteps].neighbours.Add(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps]); } if (j != -bottomRightSteps) { wayPointArray[i + bottomLeftSteps, j - 1 + bottomRightSteps].neighbours.Add(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps]); } if (j != topLeftSteps) { wayPointArray[i + bottomLeftSteps, j + 1 + bottomRightSteps].neighbours.Add(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps]); } } } // Remove all waypoints with pixel colliders for (int c = 0; c < transform.childCount; ++c) { Transform t = transform.GetChild(c); // Remove all movable objects if (t.GetComponent <MovableObject>()) { continue; } PixelCollider[] pixelColliders = t.GetComponentsInChildren <PixelCollider>(); foreach (PixelCollider pixelCollider in pixelColliders) { if (pixelCollider != null && pixelCollider.isActiveAndEnabled) { List <WayPoint> badWayPoints = new List <WayPoint>(); for (int i = -bottomLeftSteps; i <= topRightSteps; ++i) { for (int j = -bottomRightSteps; j <= topLeftSteps; ++j) { if (wayPointArray[i + bottomLeftSteps, j + bottomRightSteps] == null) { continue; } if (pixelCollider.CheckForWithinCollider(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps].position, margin)) { foreach (WayPoint n in wayPointArray[i + bottomLeftSteps, j + bottomRightSteps].neighbours) { n.neighbours.Remove(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps]); } wayPointArray[i + bottomLeftSteps, j + bottomRightSteps] = null; } } } } } } for (int i = -bottomLeftSteps; i <= topRightSteps; ++i) { for (int j = -bottomRightSteps; j <= topLeftSteps; ++j) { if (wayPointArray[i + bottomLeftSteps, j + bottomRightSteps] != null) { navigationMesh.Add(wayPointArray[i + bottomLeftSteps, j + bottomRightSteps]); } } } return(new HashSet <WayPoint>(navigationMesh)); }
public PixelLine(PixelLine pixelLine) { this.p1 = pixelLine.p1; this.p2 = pixelLine.p2; }