public static bool CheckCollision(Collider aa, Collider bb) { return Collision.CheckDispatch[(int)aa.shape.GetShapeType(), (int)bb.shape.GetShapeType()](aa, bb); }
public List<Collider> retrieve(Collider collider, int reach = -1) { //CountArray<Node>[,] nodes; //if (reach == -1) reach = cellReach; if (reach == -1) reach = 5; List<Collider> returnList = new List<Collider>(); Tuple<int, int> indexs = getIndexs(collider); int x = indexs.Item1; int y = indexs.Item2; //grid[indexs.Item1, indexs.Item2].Add(node); int xbegin, xend, ybegin, yend; xbegin = x - reach; xend = x + reach + 1; if (xbegin < 0) xbegin = 0; if (xend > cellsX) xend = cellsX; ybegin = y - reach; yend = y + reach + 1; if (ybegin < 0) ybegin = 0; if (yend > cellsY) yend = cellsY; //return box of slots /* for (int i = xbegin; i < xend; i++) { for (int j = ybegin; j < yend; j++) { //grid[i, j] = new List<Node>(); //returnList.AddRange(grid[i, j]); foreach (Node n in grid[i, j]) { returnList.Add(n); } } } */ //return circle of slots ///* //int cellsHit = 0; for (int i = xbegin; i < xend; i++) { for (int j = ybegin; j < yend; j++) { // Wow. Never use Math class >.< //double dist = Math.Pow(Math.Abs(x - i), 2) + Math.Pow(Math.Abs(y - j), 2); int xd = (x - i) * (x - i); if (xd < 0) xd *= -1; int yd = (y - j) * (y - j); if (yd < 0) yd *= -1; int dist = xd + yd; if (dist <= reach * reach) { returnList.AddRange(grid[i, j]); //foreach (Node n in grid[i, j]) //{ // returnList.Add(n); //} //cellsHit++; } } } //Console.WriteLine("Cells hit: {0}", cellsHit); ///* //Console.WriteLine("xbegin:{0} + xend:{1} + ybegin:{2} + yend:{3}", xbegin, xend, ybegin, yend); return returnList; }
public override void CheckCollisionCollider(Collider other) { //if (!active || !other.active) { return; } //if (exclusions.Contains(other)) return; //Manifold m = new Manifold(this, other); //m.Solve(); bool iscolliding = Collision.CheckCollision(this, other); if (iscolliding) { if (DoExclusionCheck(other)) return; if (other.HandlersEnabled) { //todo:add to handler list //if (OnCollisionStay != null) //{ // OnCollisionStay(parent, other.parent); //} //bool parentEnter = OnCollisionEnter != null; //if (parentEnter || OnCollisionExit != null || OnCollisionFirstEnter != null || OnCollisionAllExit != null) //{ // HashSet<Collider> lastframe = previousCollision; // HashSet<Collider> thisframe = currentCollision; // thisframe.Add(other); // if (!lastframe.Contains(other) && parentEnter) // { // OnCollisionEnter(parent, other.parent); // } //} if (other.OnCollisionStay != null) { other.OnCollisionStay(other.parent, parent); } bool otherEnter = other.OnCollisionEnter != null; if (otherEnter || other.OnCollisionExit != null || other.OnCollisionFirstEnter != null || other.OnCollisionAllExit != null) { //HashSet<Node> lastframe = other.collision.currentIsCol1 ? other.collision.collisions1 : other.collision.collisions2; //HashSet<Node> thisframe = !other.collision.currentIsCol1 ? other.collision.collisions1 : other.collision.collisions2; HashSet<Collider> lastframe = other.previousCollision; HashSet<Collider> thisframe = other.currentCollision; thisframe.Add(this); if (!lastframe.Contains(this) && otherEnter) { other.OnCollisionEnter(other.parent, parent); } } } } }
public virtual void CheckCollisionCollider(Collider other) { //bool iscolliding = Collision.CheckCollision(this, other); // //if (iscolliding) //{ // //todo:add to handler list // InvokeOnCollisionStay(other.parent); // // bool parentEnter = OnCollisionEnter != null; // if (parentEnter || OnCollisionExit != null || OnCollisionFirstEnter != null || OnCollisionAllExit != null) // { // HashSet<Collider> lastframe = previousCollision; // HashSet<Collider> thisframe = currentCollision; // thisframe.Add(other); // if (!lastframe.Contains(other) && parentEnter) // { // OnCollisionEnter(parent, other.parent); // } // } // // other.InvokeOnCollisionStay(parent); // // bool otherEnter = other.OnCollisionEnter != null; // if (otherEnter || other.OnCollisionExit != null || other.OnCollisionFirstEnter != null || other.OnCollisionAllExit != null) // { // //HashSet<Node> lastframe = other.collision.currentIsCol1 ? other.collision.collisions1 : other.collision.collisions2; // //HashSet<Node> thisframe = !other.collision.currentIsCol1 ? other.collision.collisions1 : other.collision.collisions2; // HashSet<Collider> lastframe = other.previousCollision; // HashSet<Collider> thisframe = other.currentCollision; // thisframe.Add(this); // if (!lastframe.Contains(this) && otherEnter) // { // other.OnCollisionEnter(other.parent, parent); // } // } // //} }
public void retrieveNew(Collider collider, float reachDistance, Action<Node> action) { int x = (int)collider.pos.X / cellWidth; int y = (int)collider.pos.Y / cellHeight; if (x < 0 || x >= cellsX || y < 0 || y >= cellsY) return; foreach(float dist in distToOffsets.Keys) { if (dist > reachDistance) break; foreach(var tuple in distToOffsets[dist]) { foreach (Collider c in grid[x + tuple.Item1, y + tuple.Item2]) { action(c.parent); } } } }
public void RemoveCollider(Collider collider) { if (CollisionSetCircle.Contains(collider)) CollisionSetCircle.Remove(collider); if (CollisionSetPolygon.Contains(collider)) CollisionSetPolygon.Remove(collider); }
public static bool PolygontoPolygonCheck(Collider a, Collider b) { Polygon A = (Polygon)a.shape; Polygon B = (Polygon)b.shape; //m.contact_count = 0; // Check for a separating axis with A's face planes int faceA = 0; double penetrationA = FindAxisLeastPenetration(ref faceA, A, B); if (penetrationA >= 0.0f) return false; // Check for a separating axis with B's face planes int faceB = 0; double penetrationB = FindAxisLeastPenetration(ref faceB, B, A); if (penetrationB >= 0.0f) return false; int referenceIndex; //bool flip; // Always point from a to b Polygon RefPoly; // Reference Polygon IncPoly; // Incident // Determine which shape contains reference face if (GMath.BiasGreaterThan(penetrationA, penetrationB)) { RefPoly = A; IncPoly = B; referenceIndex = faceA; //flip = false; } else { RefPoly = B; IncPoly = A; referenceIndex = faceB; //flip = true; } // World space incident face Vector2[] incidentFace = new Vector2[2]; FindIncidentFace(ref incidentFace, RefPoly, IncPoly, referenceIndex); // Setup reference face vertices Vector2 v1 = RefPoly.vertices[referenceIndex]; referenceIndex = referenceIndex + 1 == RefPoly.vertexCount ? 0 : referenceIndex + 1; Vector2 v2 = RefPoly.vertices[referenceIndex]; // Transform vertices to world space v1 = RefPoly.u * v1 + RefPoly.body.pos; v2 = RefPoly.u * v2 + RefPoly.body.pos; // Calculate reference face side normal in world space Vector2 sidePlaneNormal = (v2 - v1); VMath.NormalizeSafe(ref sidePlaneNormal); // Orthogonalize Vector2 refFaceNormal = new Vector2(sidePlaneNormal.Y, -sidePlaneNormal.X); // ax + by = c // c is distance from origin double refC = Vector2.Dot(refFaceNormal, v1); double negSide = -Vector2.Dot(sidePlaneNormal, v1); double posSide = Vector2.Dot(sidePlaneNormal, v2); // Clip incident face to reference face side planes if (Clip(-sidePlaneNormal, negSide, ref incidentFace) < 2) return false; // Due to floating point error, possible to not have required points if (Clip(sidePlaneNormal, posSide, ref incidentFace) < 2) return false; // Due to floating point error, possible to not have required points // Flip //m.normal = flip ? -refFaceNormal : refFaceNormal; // Keep points behind reference face int cp = 0; // clipped points behind reference face double separation = Vector2.Dot(refFaceNormal, incidentFace[0]) - refC; if (separation <= 0.0f) { //m.contacts[cp] = incidentFace[0]; //m.penetration = -separation; ++cp; } //else // m.penetration = 0; separation = Vector2.Dot(refFaceNormal, incidentFace[1]) - refC; if (separation <= 0.0f) { //m.contacts[cp] = incidentFace[1]; // //m.penetration += -separation; ++cp; // Average penetration //m.penetration /= (double)cp; } //m.contact_count = cp; return cp > 0; }
public void retrieveFromAllOffsets(Collider collider, float reachDistance, Action<Collider, Collider> action) { int x = (int)collider.pos.X / cellWidth; int y = (int)collider.pos.Y / cellHeight; if (x < 0 || x >= cellsX || y < 0 || y >= cellsY) return; int findcount = FindCount(reachDistance); for (int i = 0; i < findcount; i++) { foreach (var tuple in distToOffsets.ElementAt(i).Value) { int xx = tuple.Item1 + x; int yy = tuple.Item2 + y; if (xx < 0 || xx >= cellsX || yy < 0 || yy >= cellsY) continue; //foreach (Collider c in grid[tuple.Item1, tuple.Item2]) //{ // action(collider, c); //} IndexArray<Collider> buck = arrayGrid[xx][yy]; int count = buck.index; //if (count > 0) Console.WriteLine(count); for (int j = 0; j < count; j++) { Collider c = arrayGrid[xx][yy].array[j]; if (alreadyVisited.Contains(c) || collider == c) continue; action(collider, c); } } } }
public static bool PolygontoCircle(Manifold m, Collider a, Collider b) { bool ret = CircletoPolygon(m, b, a); m.normal = -m.normal; return ret; }
public static bool PolygontoCircleCheck(Collider a, Collider b) { return CircletoPolygonCheck(b, a); //m.normal = -m.normal; //return ret; }
public static bool CircletoPolygonCheck(Collider a, Collider b) { Circle A = (Circle)a.shape; Polygon B = (Polygon)b.shape; //m.contact_count = 0; // Transform circle center to Polygon model space Vector2 center = a.pos; center = B.u.Transpose() * (center - b.pos); // Find edge with minimum penetration // Exact concept as using support points in Polygon vs Polygon double separation = -float.MaxValue; int faceNormal = 0; for (int i = 0; i < B.vertexCount; ++i) { double s = Vector2.Dot(B.normals[i], center - B.vertices[i]); if (s > A.radius) { return false; } if (s > separation) { separation = s; faceNormal = i; } } // Grab face's vertices Vector2 v1 = B.vertices[faceNormal]; int i2 = faceNormal + 1 < B.vertexCount ? faceNormal + 1 : 0; Vector2 v2 = B.vertices[i2]; // Check to see if center is within polygon if (separation < GMath.EPSILON) { //m.contact_count = 1; //m.normal = -(B.u * B.normals[faceNormal]); //m.contacts[0] = VMath.MultVectDouble(m.normal, A.radius) + a.pos; //m.penetration = A.radius; return true; } // Determine which voronoi region of the edge center of circle lies within double dot1 = Vector2.Dot(center - v1, v2 - v1); double dot2 = Vector2.Dot(center - v2, v1 - v2); //m.penetration = A.radius - separation; // Closest to v1 if (dot1 <= 0.0f) { if (Vector2.DistanceSquared(center, v1) > A.radius * A.radius) { return false; } //m.contact_count = 1; //Vector2 n = v1 - center; //n = B.u * n; //n.Normalize(); //m.normal = n; //v1 = B.u * v1 + b.pos; //m.contacts[0] = v1; } // Closest to v2 else if (dot2 <= 0.0f) { if (Vector2.DistanceSquared(center, v2) > A.radius * A.radius) { return false; } //m.contact_count = 1; //Vector2 n = v2 - center; //v2 = B.u * v2 + b.pos; //m.contacts[0] = v2; //n = B.u * n; //n.Normalize(); //m.normal = n; } // Closest to face else { Vector2 n = B.normals[faceNormal]; if (Vector2.Dot(center - v1, n) > A.radius) { return false; } //n = B.u * n; //m.normal = -n; //m.contacts[0] = VMath.MultVectDouble(m.normal, A.radius) + a.pos; //m.contact_count = 1; } return true; }
////////FUCKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK public static bool CircletoCircleCheck(Collider a, Collider b) { Vector2 normal = b.pos - a.pos; float distSquared = normal.LengthSquared(); double radius = a.radius + b.radius; return distSquared < radius * radius; }
public static bool CircletoCircle(Manifold m, Collider a, Collider b) { Circle ca = (Circle)a.shape; Circle cb = (Circle)b.shape; Vector2 normal = b.pos - a.pos; float distSquared = normal.LengthSquared(); double radius = a.radius + b.radius; if (distSquared >= (float)(radius * radius)) { m.contact_count = 0; return false; } double distance = Math.Sqrt(distSquared); m.contact_count = 1; if (distance == 0) { m.penetration = ca.radius; m.normal = new Vector2(1, 0); m.contacts[0] = a.pos; } else { m.penetration = radius - distance; m.normal = VMath.MultVectDouble(normal, 1.0 / distance); //normal / distance; m.contacts[0] = VMath.MultVectDouble(m.normal, ca.radius) + a.pos; //m.normal * ca.radius + a.body.position; } return true; }
public IndexArray<IndexArray<Collider>> retrieveBucketBags(Collider collider) { int effectiveX = (int)(collider.pos.X - position.X); int effectiveY = (int)(collider.pos.Y - position.Y); if (effectiveX < 0 || effectiveY < 0) return null; int x = effectiveX / cellWidth; int y = effectiveY / cellHeight; if (x < 0 || x >= cellsX || y < 0 || y >= cellsY) return null; return bucketBags[x][y]; }
public void AddCollider(string key, Collider col) { int i = 0; while(colliders.ContainsKey(key)) { key = key + i++; } colliders.Add(key, col); col.parent = parent; if (active && parent != null && parent.group != null) { UpdateCollisionSet(); } }
public List<List<Collider>> retrieveBuckets(Collider collider, float reachDistance) { int x = (int)collider.pos.X / cellWidth; int y = (int)collider.pos.Y / cellHeight; if (x < 0 || x >= cellsX || y < 0 || y >= cellsY) { return null; } else { if (bucketLists[x, y] != null) { preexistingCounter++; return bucketLists[x, y]; } bucketLists[x, y] = new List<List<Collider>>(); int count = FindCount(reachDistance); var dict = offsetsArrayCollection[x, y]; if (dict.Count <= count) { throw new SystemException("Count too big exception"); } //int cellsHit = 0; for (int i = 0; i < count; i++) { List<Tuple<int, int>> tuples = dict.ElementAt(i).Value; foreach (var tuple in tuples) { bucketLists[x, y].Add(grid[tuple.Item1 + x, tuple.Item2 + y]); } } //Console.WriteLine(cellsHit); return bucketLists[x, y]; } }
public bool ContainsCollider(Collider collider) { for (int i = 0; i < cellsX; i++) { for (int j = 0; j < cellsY; j++) { if (grid[i, j].Contains(collider)) return true; } } return false; }
public void retrieveFromOptimizedOffsets(Collider collider, float reachDistance, Action<Node> action) { int x = (int)collider.pos.X / cellWidth; int y = (int)collider.pos.Y / cellHeight; if (x < 0 || x >= cellsX || y < 0 || y >= cellsY) return; int count = FindCount(reachDistance); var dict = offsetsArrayCollection[x, y]; if (dict.Count <= count) { throw new SystemException("Count too big exception"); } //int cellsHit = 0; for (int i = 0; i < count; i++) { foreach (var tuple in dict.ElementAt(i).Value) { foreach (Collider c in grid[tuple.Item1 + x, tuple.Item2 + y]) { action(c.parent); } //cellsHit++; } } //Console.WriteLine(cellsHit); }
public Tuple<int, int> getIndexs(Collider collider) { Vector2 pos = new Vector2(collider.pos.X, collider.pos.Y); int x = (int)collider.pos.X; int y = (int)collider.pos.Y; int gridx = (int)pos.X - ((int)pos.X % cellWidth); x = gridx / cellWidth; //if ((int)pos.X - gridx > gridx + cellwidth - (int)node.transform.radius) x++; int gridy = (int)pos.Y - ((int)pos.Y % cellHeight); y = gridy / cellHeight; //if ((int)pos.Y - gridy > gridy + cellheight - (int)node.transform.radius) y++; if (x > cellsX - 1) x = cellsX - 1; if (y > cellsY - 1) y = cellsY - 1; if (x < 0) x = 0; if (y < 0) y = 0; //Console.WriteLine("{0} + {1}", x, y); return new Tuple<int, int>(x, y); }
public void retrieveOffsetArraysCollision(Collider collider, Action<Collider, Collider> action, float distance) { int effectiveX = (int)(collider.pos.X - position.X); int effectiveY = (int)(collider.pos.Y - position.Y); int x = effectiveX / cellWidth; int y = effectiveY / cellHeight; if (x < 0 || x > cellsX || y < 0 || y > cellsY) return; int findcount = FindCount(distance); int lastIndex; //lastIndex = reachIndexs[reachCount]; lastIndex = reachIndexs[findcount]; for (int coordPointer = 0; coordPointer <= lastIndex; coordPointer += 2) { int xx = offsetArray[coordPointer] + x; int yy = offsetArray[coordPointer + 1] + y; if (xx < 0 || xx >= cellsX || yy < 0 || yy >= cellsY) continue; IndexArray<Collider> buck = arrayGrid[xx][yy]; int count = buck.index; for (int j = 0; j < count; j++) { Collider c = arrayGrid[xx][yy].array[j]; //if (room.ColorNodesInReach && collider.parent == room.targetNode) c.parent.body.color = Color.Purple; if (alreadyVisited.Contains(c) || collider == c) continue; action(collider, c); } } }
// gets the index of the node in the gridsystem, without correcting out of bounds nodes. public Tuple<int, int> getIndexsNew(Collider collider) { //int a = (int)node.body.pos.X / cellWidth; return new Tuple<int, int>((int)collider.pos.X / cellWidth, (int)collider.pos.Y / cellHeight); }
public void AddCollider(Collider collider) { if (collider.shape is Circle) CollisionSetCircle.Add(collider); else if (collider.shape is Polygon) CollisionSetPolygon.Add(collider); }
//static int largest = 0; public void insert(Collider collider) { Tuple<int, int> indexs = getIndexs(collider); //if (node == room.game.targetNode) Console.WriteLine("target indexs: {0} {1}",indexs.Item1,indexs.Item2); grid[indexs.Item1, indexs.Item2].Add(collider); //if (grid[indexs.Item1, indexs.Item2].Count > largest) //{ // largest = grid[indexs.Item1, indexs.Item2].Count; // //Console.WriteLine(largest); //} //grid[indexs.Item1, indexs.Item2].ToArray(); }
public void AddExclusionCheck(Collider other) { ExclusionCheck += (s, o) => { return o == other; }; other.ExclusionCheck += (s, o) => { return o == this; }; }
public void insertToBuckets(Collider collider, bool forceIntoGrid = true) { int effectiveX = (int)(collider.pos.X - position.X); int effectiveY = (int)(collider.pos.Y - position.Y); int x = effectiveX / cellWidth; int y = effectiveY / cellHeight; //if (x < 0 || x >= cellsX || y < 0 || y >= cellsY) return; if (x < 0) { if (forceIntoGrid) x = 0; else return; } else if (x >= cellsX) { if (forceIntoGrid) x = cellsX - 1; else return; } if (y < 0) { if (forceIntoGrid) y = 0; else return; } else if (y >= cellsY) { if (forceIntoGrid) y = cellsY - 1; else return; } arrayGrid[x][y].AddItem(collider); }
public bool DoExclusionCheckResolution(Collider other) { if (ExclusionCheckResolution != null) { foreach (Func<Collider, Collider, bool> del in ExclusionCheckResolution.GetInvocationList()) { if (del(this, other)) return true; } } return false; }
public void InitializePlayers() { for (int i = 0; i < 8; i++) { //Player p = Player.GetNew(i); Player p = new Player(i); if (p == null) break; Vector2 spawnPos = Vector2.Zero; double angle = Utils.random.NextDouble() * Math.PI * 2; angle -= Math.PI; float dist = 200; float x = dist * (float)Math.Cos(angle); float y = dist * (float)Math.Sin(angle); spawnPos = new Vector2(room.worldWidth / 2, room.worldHeight / 2) - new Vector2(x, y); //add //{ nodeE.position, spawnPos }, p.node = room.spawnNode(playerProps); p.node.name = "player" + p.playerIndex; p.node.Comp<Queuer>().queuecount = 100; Collider collider = new Collider(new Circle(25)); p.node.collision.AddCollider("trigger", collider); collider.OnCollisionEnter += onCollisionEnter; collider.OnCollisionExit += onCollisionExit; p.node.addComponent<Swap>(true); p.node.Comp<Swap>().OnSwapBefore += before; p.node.Comp<Swap>().OnSwapAfter += after; } }