/// <summary> /// Counts how many objects are overlapping with a given ColliderShape. If trackObjects are true, you can /// use OverlappedWith to check if another PhysicsComponent was part of the overlapping objects /// </summary> /// <param name="shape">ColliderShape to check for overlaps with</param> /// <param name="position">Position to move the ColliderShape, in addition to its LocalOffset</param> /// <param name="myGroup">What collision group is the ColliderShape in?</param> /// <param name="overlapsWith">What collision groups does the ColliderShape overlap with?</param> /// <param name="contactTest">If true, contact test overlapping objects. See ContactResults for output. Defaults to false</param> /// <param name="stopAfterFirstContact">If contact testing, should we stop contact testing after our first contact was found?</param> /// <returns>Number of overlapping objects</returns> public static int PerformOverlapTest(ColliderShape shape, Xenko.Core.Mathematics.Vector3?position = null, CollisionFilterGroups myGroup = CollisionFilterGroups.DefaultFilter, CollisionFilterGroupFlags overlapsWith = CollisionFilterGroupFlags.AllFilter, bool contactTest = false, bool stopAfterFirstContact = false) { // doesn't support multithreading if (mySimulation.simulationLocker != null) { throw new InvalidOperationException("Overlap testing not supported with multithreaded physics"); } if (ghostObject == null) { ghostObject = new BulletSharp.PairCachingGhostObject { ContactProcessingThreshold = 1e18f, UserObject = shape }; ghostObject.CollisionFlags |= BulletSharp.CollisionFlags.NoContactResponse; internalResults = new OverlapCallback(); NativeOverlappingObjects = new HashSet <object>(); } ghostObject.CollisionShape = shape.InternalShape; ghostObject.WorldTransform = Matrix.Transformation(shape.Scaling, shape.LocalRotation, position.HasValue ? position.Value + shape.LocalOffset : shape.LocalOffset); mySimulation.collisionWorld.AddCollisionObject(ghostObject, (BulletSharp.CollisionFilterGroups)myGroup, (BulletSharp.CollisionFilterGroups)overlapsWith); int overlapCount = ghostObject.NumOverlappingObjects; NativeOverlappingObjects.Clear(); for (int i = 0; i < overlapCount; i++) { NativeOverlappingObjects.Add(ghostObject.OverlappingPairs[i]); } if (contactTest) { internalResults.Clear(); internalResults.CollisionFilterGroup = (int)myGroup; internalResults.CollisionFilterMask = (int)overlapsWith; foreach (object nativeobj in NativeOverlappingObjects) { mySimulation.collisionWorld.ContactPairTest(ghostObject, (BulletSharp.CollisionObject)nativeobj, internalResults); if (stopAfterFirstContact && internalResults.Contacts.Count > 0) { break; } } } mySimulation.collisionWorld.RemoveCollisionObject(ghostObject); return(overlapCount); }
// should add support for muliple types eventually // perhaps it would be better for types to nest themselves? // also, the map should really contain multiple layers, // all of which are expressed / exposed through these interfaces void OverlapCheck(OverlapCallback fn, RLCharacter.RLTypes ta, RLCharacter.RLTypes tb) { if (objects.Count > 0) { for (int i = objects.Count - 1; i >= 0; i--) { if (objects.Count > i && objects [i].hasTypes.Contains(ta)) { for (int j = i; j >= 0; j--) { if (objects.Count >= j && objects.Count >= i) { if (i != j && objects.Count > j && objects [j].hasTypes.Contains(tb) && objects [i].positionI.Equals(objects [j].positionI)) { fn(objects [i], objects [j]); } } } } } } }
// should add support for muliple types eventually // perhaps it would be better for types to nest themselves? // also, the map should really contain multiple layers, // all of which are expressed / exposed through these interfaces void OverlapCheck(OverlapCallback fn, RLCharacter.RLTypes ta, RLCharacter.RLTypes tb) { if (objects.Count > 0) { for (int i = objects.Count - 1; i >= 0; i--) { if (objects.Count > i && objects [i].hasTypes.Contains (ta)) { for (int j = i; j >= 0; j--) { if (objects.Count >= j && objects.Count >= i) { if (i != j && objects.Count > j && objects [j].hasTypes.Contains (tb) && objects [i].positionI.Equals (objects [j].positionI)) { fn (objects [i], objects [j]); } } } } } } }