public static int AddNode(PartitionNode node) { int activationID = ActivatedNodes.Add(node); AllocatedNodes.Add(node); return(activationID); }
public static void UpdateObject(LSBody Body, bool repartition = true) { GetGridBounds(Body); if ( repartition == false || (Body.PastGridXMin != GridXMin || Body.PastGridXMax != GridXMax || Body.PastGridYMin != GridYMin || Body.PastGridYMax != GridYMax)) { //Remove from all partitions no longer located on for (int o = Body.PastGridXMin; o <= Body.PastGridXMax; o++) { for (int p = Body.PastGridYMin; p <= Body.PastGridYMax; p++) { PartitionNode node = GetNode(o, p); if (Body.Immovable) { node.RemoveImmovable(Body.ID); } else { node.Remove(Body.ID); } } } if (repartition) { PartitionObject(Body, true); } } }
public static void PartitionObject(LSBody Body, bool gridBoundsCalculated = false) { if (gridBoundsCalculated == false) { GetGridBounds(Body); } Body.PastGridXMin = GridXMin; Body.PastGridXMax = GridXMax; Body.PastGridYMin = GridYMin; Body.PastGridYMax = GridYMax; for (int i = GridXMin; i <= GridXMax; i++) { for (int j = GridYMin; j <= GridYMax; j++) { PartitionNode node = GetNode(i, j); Body.PartitionChanged = true; if (Body.Immovable) { node.AddImmovable(Body.ID); } else { node.Add(Body.ID); } } } }
public static IEnumerable <LSBody> RaycastAll(Vector2d start, Vector2d end) { _Version++; LSBody.PrepareAxisCheck(start, end); foreach (FractionalLineAlgorithm.Coordinate coor in GetRelevantNodeCoordinates(start, end)) { int indexX = coor.X; int indexY = coor.Y; if (!Partition.CheckValid(coor.X, coor.Y)) { break; } PartitionNode node = Partition.GetNode(indexX, indexY); for (int i = node.ContainedDynamicObjects.Count - 1; i >= 0; i--) { LSBody body = PhysicsManager.SimObjects [node.ContainedDynamicObjects [i]]; if (body.IsNotNull() && body.RaycastVersion != _Version) { if (Conditional.IsNull() || Conditional()) { body.RaycastVersion = _Version; if (body.Overlaps(bufferIntersectionPoints)) { yield return(body); } } } } } Conditional = null; yield break; }
public static PartitionNode GetNode(int indexX, int indexY) { PartitionNode node = Nodes [indexX, indexY]; if (node.IsNull()) { node = new PartitionNode(); Nodes [indexX, indexY] = node; } return(node); }
public static void CheckAndDistributeCollisions() { count = 0; _Version++; for (int i = ActivatedNodes.PeakCount - 1; i >= 0; i--) { if (ActivatedNodes.arrayAllocation [i]) { PartitionNode node = ActivatedNodes [i]; node.Distribute(); } } //Debug.Log (count + " pairs checked"); }
/// <summary> /// Finds all dynamic bodies touching a defined circle. /// </summary> /// <param name="radius">Radius.</param> /// <param name="output">Output.</param> public static void CircleCast(Vector2d position, long radius, FastList <LSBody> output) { long xMin = position.x - radius, xmax = position.x + radius; long yMin = position.y - radius, yMax = position.y + radius; //Find the partition tiles we have to search in first int gridXMin, gridXMax, gridYMin, gridYMax; Partition.GetGridBounds(xMin, xmax, yMin, yMax, out gridXMin, out gridXMax, out gridYMin, out gridYMax); for (int i = gridXMin; i <= gridXMax; i++) { for (int j = gridYMin; j <= gridYMax; j++) { PartitionNode node = Partition.GetNode(i, j); for (int k = node.ContainedDynamicObjects.Count - 1; k >= 0; k--) { var body = PhysicsManager.SimObjects [node.ContainedDynamicObjects [k]]; long minFastDist = body.Radius + radius; //unnormalized distance value for comparison minFastDist *= minFastDist; if (body.Position.FastDistance(position) <= minFastDist) { //Body touches circle! output.Add(body); } } for (int l = node.ContainedImmovableObjects.Count - 1; l >= 0; l--) { var body = PhysicsManager.SimObjects [node.ContainedImmovableObjects [l]]; long minFastDist = body.Radius + radius; //unnormalized distance value for comparison minFastDist *= minFastDist; if (body.Position.FastDistance(position) <= minFastDist) { //Body touches circle! output.Add(body); } } } } }