/// <summary> /// Checks to see if the geom collides with the specified geom. /// </summary> /// <param name="geometry">The geometry.</param> /// <returns></returns> public bool Collide(Geom geometry) { //Check first if the AABB intersects the other geometry's AABB. If they //do not intersect, there can be no collision. if (AABB.Intersect(ref AABB, ref geometry.AABB)) { //Check each vertice (of self) against the provided geometry int count = worldVertices.Count; for (int i = 0; i < count; i++) { _tempVector = worldVertices[i]; if (geometry.FastCollide(ref _tempVector)) { return(true); } } //Check each vertice of the provided geometry, against itself count = geometry.worldVertices.Count; for (int i = 0; i < count; i++) { _tempVector = geometry.worldVertices[i]; if (FastCollide(ref _tempVector)) { return(true); } } } return(false); }
/// <summary> /// Test AABB collisions between two geometries. Tests include checking if the /// geometries are enabled, static, in the right collision categories, etc. /// </summary> /// <returns>Returns true if there is a collision, false otherwise</returns> public static bool DoCollision(Geom g1, Geom g2) { if (!g1.body.Enabled || !g2.body.Enabled) { return(false); } if ((g1.collisionGroup == g2.collisionGroup) && g1.collisionGroup != 0 && g2.collisionGroup != 0) { return(false); } if (!g1.collisionEnabled || !g2.collisionEnabled) { return(false); } if (g1.body.isStatic && g2.body.isStatic) { return(false); } if (g1.body == g2.body) { return(false); } if (((g1.collisionCategories & g2.collidesWith) == CollisionCategory.None) & ((g2.collisionCategories & g1.collidesWith) == CollisionCategory.None)) { return(false); } //TMP AABB aabb1 = new AABB(); AABB aabb2 = new AABB(); aabb1.min = g1.aabb.min; aabb1.max = g1.aabb.max; aabb2.min = g2.aabb.min; aabb2.max = g2.aabb.max; aabb1.min.X -= _floatTolerance; aabb1.min.Y -= _floatTolerance; aabb1.max.X += _floatTolerance; aabb1.max.Y += _floatTolerance; aabb2.min.X -= _floatTolerance; aabb2.min.Y -= _floatTolerance; aabb2.max.X += _floatTolerance; aabb2.max.Y += _floatTolerance; //NOTE: Changed from // if (AABB.Intersect(g1.aabb, g2.aabb) == false) // return false; // return true //TO: return(AABB.Intersect(aabb1, aabb2)); }
/// <summary> /// Test AABB collisions between two geometries. Tests include checking if the /// geometries are enabled, static, in the right collision categories, etc. /// </summary> /// <returns>Returns true if there is a collision, false otherwise</returns> public static bool DoCollision(Geom g1, Geom g2) { if (!g1.body.enabled || !g2.body.enabled) { return(false); } if ((g1.collisionGroup == g2.collisionGroup) && g1.collisionGroup != 0 && g2.collisionGroup != 0) { return(false); } if (!g1.collisionEnabled || !g2.collisionEnabled) { return(false); } if (g1.body.isStatic && g2.body.isStatic) { return(false); } if (g1.body == g2.body) { return(false); } if (((g1.collisionCategories & g2.collidesWith) == CollisionCategories.None) & ((g2.collisionCategories & g1.collidesWith) == CollisionCategories.None)) { return(false); } //TMP AABB aabb1 = new AABB(); AABB aabb2 = new AABB(); aabb1.min = g1.aabb.min; aabb1.max = g1.aabb.max; aabb2.min = g2.aabb.min; aabb2.max = g2.aabb.max; aabb1.min.X -= fTol; aabb1.min.Y -= fTol; aabb1.max.X += fTol; aabb1.max.Y += fTol; aabb2.min.X -= fTol; aabb2.min.Y -= fTol; aabb2.max.X += fTol; aabb2.max.Y += fTol; if (AABB.Intersect(aabb1, aabb2) == false) { return(false); } // if (AABB.Intersect(g1.aabb, g2.aabb) == false) // return false; return(true); }
private void RunHash() { _keysToRemove.Clear(); foreach (KeyValuePair <long, List <Geom> > pair in _hash) { // If there are no geometries in the list. Remove it. // If there are any geometries in the list, process them. List <Geom> list = pair.Value; if (list.Count == 0) { _keysToRemove.Add(pair.Key); } else { for (int i = 0; i < list.Count - 1; i++) { Geom geometryA = list[i]; for (int j = i + 1; j < list.Count; j++) { Geom geometryB = list[j]; if (!geometryA.body.Enabled || !geometryB.body.Enabled) { continue; } if ((geometryA.CollisionGroup == geometryB.CollisionGroup) && geometryA.CollisionGroup != 0 && geometryB.CollisionGroup != 0) { continue; } if (!geometryA.CollisionEnabled || !geometryB.CollisionEnabled) { continue; } if (geometryA.body.isStatic && geometryB.body.isStatic) { continue; } if (geometryA.body == geometryB.body) { continue; } if (((geometryA.CollisionCategories & geometryB.CollidesWith) == CollisionCategory.None) & ((geometryB.CollisionCategories & geometryA.CollidesWith) == CollisionCategory.None)) { continue; } if (geometryA.IsGeometryIgnored(geometryB) || geometryB.IsGeometryIgnored(geometryA)) { continue; } long key = PairID.GetId(geometryA.id, geometryB.id); if (!_filter.ContainsKey(key)) { _filter.Add(key, null); //Check if there is intersection bool intersection = AABB.Intersect(ref geometryA.AABB, ref geometryB.AABB); //User can cancel collision if (OnBroadPhaseCollision != null) { intersection = OnBroadPhaseCollision(geometryA, geometryB); } if (!intersection) { continue; } _physicsSimulator.ArbiterList.AddArbiterForGeomPair(_physicsSimulator, geometryA, geometryB); } } } list.Clear(); } } _filter.Clear(); //Remove all the empty lists from the hash for (int index = 0; index < _keysToRemove.Count; ++index) { _hash.Remove(_keysToRemove[index]); } }
public void MoveUnderConsiderationToOverlaps() { for (int i = 0; i < Count; i++) { if (this[i].UnderConsideration.Count == 0) { continue; } Geom geometryA = this[i].Geometry; // First transfer those under consideration to overlaps, // for, they have been considered... int startIndex = this[i].Overlaps.Count; this[i].Overlaps.AddRange(this[i].UnderConsideration); this[i].UnderConsideration.Clear(); for (int j = startIndex; j < this[i].Overlaps.Count; j++) { Geom geometryB = this[i].Overlaps[j]; // It is possible that we may test the same pair of geometries // for both extents (x and y), however, I'm banking on that // one of the extents has probably already been cached and // therefore, won't be checked. if (!geometryA.body.Enabled || !geometryB.body.Enabled) { continue; } if ((geometryA.CollisionGroup == geometryB.CollisionGroup) && geometryA.CollisionGroup != 0 && geometryB.CollisionGroup != 0) { continue; } if (!geometryA.CollisionEnabled || !geometryB.CollisionEnabled) { continue; } if (geometryA.body.isStatic && geometryB.body.isStatic) { continue; } if (geometryA.body == geometryB.body) { continue; } if (((geometryA.CollisionCategories & geometryB.CollidesWith) == CollisionCategory.None) & ((geometryB.CollisionCategories & geometryA.CollidesWith) == CollisionCategory.None)) { continue; } if (geometryA.IsGeometryIgnored(geometryB) || geometryB.IsGeometryIgnored(geometryA)) { continue; } //TMP AABB aabb1 = new AABB(); AABB aabb2 = new AABB(); aabb1.min = geometryA.AABB.min; aabb1.max = geometryA.AABB.max; aabb2.min = geometryB.AABB.min; aabb2.max = geometryB.AABB.max; aabb1.min.X -= _floatTolerance; aabb1.min.Y -= _floatTolerance; aabb1.max.X += _floatTolerance; aabb1.max.Y += _floatTolerance; aabb2.min.X -= _floatTolerance; aabb2.min.Y -= _floatTolerance; aabb2.max.X += _floatTolerance; aabb2.max.Y += _floatTolerance; if (!AABB.Intersect(ref aabb1, ref aabb2)) { continue; } //Call the OnBroadPhaseCollision event first. If the user aborts the collision //it will not create an arbiter if (Owner.OnBroadPhaseCollision != null) { if (Owner.OnBroadPhaseCollision(geometryA, geometryB)) { Owner.CollisionPairs.AddPair(geometryA, geometryB); } } else { Owner.CollisionPairs.AddPair(geometryA, geometryB); } } } }