/// <summary> /// Finds contacts between the query object and any intersected objects within the character's bounding box. /// </summary> /// <param name="queryObject">Collidable to query for contacts with.</param> /// <param name="tractionContacts">Output contacts that would provide traction.</param> /// <param name="supportContacts">Output contacts that would provide support.</param> /// <param name="sideContacts">Output contacts on the sides of the query object.</param> /// <param name="headContacts">Output contacts on the head of the query object.</param> public void QueryContacts(EntityCollidable queryObject, ref QuickList <CharacterContact> tractionContacts, ref QuickList <CharacterContact> supportContacts, ref QuickList <CharacterContact> sideContacts, ref QuickList <CharacterContact> headContacts) { var downDirection = characterBody.orientationMatrix4.Down; tractionContacts.Clear(); supportContacts.Clear(); sideContacts.Clear(); headContacts.Clear(); foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables) { //The query object is assumed to have a valid bounding box. if (collidable.BoundingBox.Intersects(queryObject.BoundingBox)) { var pair = new CollidablePair(collidable, queryObject); var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair); if (pairHandler.CollisionRule == CollisionRule.Normal) { pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); pairHandler.SuppressEvents = false; contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection, ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts); } //TODO: It would be nice if this was a bit easier. //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving. //No one would ever just guess this correctly. //At least hide it behind a NarrowPhaseHelper function. pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); } } }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : unmanaged, IContactManifold <TManifold> { pairMaterial.FrictionCoefficient = this.FrictionCoefficient; pairMaterial.MaximumRecoveryVelocity = this.MaximumRecoveryVelocity; pairMaterial.SpringSettings = this.ContactSpringiness; return(true); }
protected void TryToAdd(Collidable a, Collidable b, Material materialA, Material materialB) { CollisionRule rule; if ((rule = CollisionRules.collisionRuleCalculator(a, b)) < CollisionRule.NoNarrowPhasePair) { //Clamp the rule to the parent's rule. Always use the more restrictive option. //Don't have to test for NoNarrowPhasePair rule on the parent's rule because then the parent wouldn't exist! if (rule < CollisionRule) { rule = CollisionRule; } var pair = new CollidablePair(a, b); if (!subPairs.ContainsKey(pair)) { var newPair = NarrowPhaseHelper.GetPairHandler(ref pair, rule); if (newPair != null) { newPair.UpdateMaterialProperties(materialA, materialB); //Override the materials, if necessary. newPair.Parent = this; subPairs.Add(pair, newPair); } } containedPairs.Add(pair); } }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { pairMaterial.FrictionCoefficient = 1; pairMaterial.MaximumRecoveryVelocity = 2f; pairMaterial.SpringSettings = new SpringSettings(30, 1); return(true); }
public bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { //The IContactManifold parameter includes functions for accessing contact data regardless of what the underlying type of the manifold is. //If you want to have direct access to the underlying type, you can use the manifold.Convex property and a cast like Unsafe.As<TManifold, ConvexContactManifold or NonconvexContactManifold>(ref manifold). //The engine does not define any per-body material properties. Instead, all material lookup and blending operations are handled by the callbacks. //For the purposes of this demo, we'll use the same settings for all pairs. //(Note that there's no bounciness property! See here for more details: https://github.com/bepu/bepuphysics2/issues/3) pairMaterial.FrictionCoefficient = 1f; pairMaterial.MaximumRecoveryVelocity = 2f; pairMaterial.SpringSettings = new SpringSettings(30, 1); //For the purposes of the demo, contact constraints are always generated. try { OnCollision(pair.A, pair.B); } catch (Exception e) { Console.WriteLine(e); } return(false); }
public bool AllowContactGeneration(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB) { //This is similar to the top level broad phase callback above. It's called by the narrow phase before generating //subpairs between children in parent shapes. //This only gets called in pairs that involve at least one shape type that can contain multiple children, like a Compound. return(true); }
/// <summary> /// Finds contacts between the query object and any intersected objects within the character's bounding capsule. /// </summary> /// <param name="queryObject">Collidable to query for contacts with.</param> /// <param name="tractionContacts">Output contacts that would provide traction.</param> /// <param name="supportContacts">Output contacts that would provide support.</param> /// <param name="sideContacts">Output contacts on the sides of the query object.</param> /// <param name="headContacts">Output contacts on the head of the query object.</param> /// <param name="forceStandardPairsToBeQueries">An extremely hacky control parameter that makes any mesh-cylinder pair treat the mesh as double sided. Useful for not going through the ceiling when changing stances.</param> public void QueryContacts(EntityCollidable queryObject, ref QuickList <CharacterContact> tractionContacts, ref QuickList <CharacterContact> supportContacts, ref QuickList <CharacterContact> sideContacts, ref QuickList <CharacterContact> headContacts, bool forceStandardPairsToBeQueries = false) { var downDirection = characterBody.orientationMatrix.Down; tractionContacts.Clear(); supportContacts.Clear(); sideContacts.Clear(); headContacts.Clear(); foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables) { //The query object is assumed to have a valid bounding capsule. if (collidable.BoundingBox.Intersects(queryObject.BoundingBox)) { var pair = new CollidablePair(collidable, queryObject); var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair); if (pairHandler.CollisionRule == CollisionRule.Normal) { if (forceStandardPairsToBeQueries) { //TODO: This is a massive hack that assumes a fixed set of collidable types. This won't work in the long run. //The only reason it's here is that it was the easiest solution, combined with the fact that the character has to be rewritten for v2 anyway. //Hopefully no one gets bit by this before the replacement is available. //The core reason it exists is that one sided meshes don't generate contacts on their backside. That means a query shape can end up above a ceiling //and it won't detect the ceiling. A better solution would be to let the caller choose whether or not to filter the contacts, and then use a //direct test rather than stateful pair to perform the query here. Still some type-related annoyance to deal with, but a bit better. var standardPair = pairHandler as StandardPairHandler; if (standardPair != null) { standardPair.ContactManifold.IsQuery = true; } } pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); pairHandler.SuppressEvents = false; if (forceStandardPairsToBeQueries) { //TODO: Again, superhack! Avoid this in v2. var standardPair = pairHandler as StandardPairHandler; if (standardPair != null) { standardPair.ContactManifold.IsQuery = false; } } contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection, ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts); } //TODO: It would be nice if this was a bit easier. //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving. //No one would ever just guess this correctly. //At least hide it behind a NarrowPhaseHelper function. pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); } } }
public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB, ref ConvexContactManifold manifold) { if (manifold.Count > 0) { Console.WriteLine($"SUBPAIR: {pair.A} child {childIndexA} versus {pair.B} child {childIndexB}"); } return(true); }
public unsafe bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ConvexContactManifold *manifold, out PairMaterialProperties pairMaterial) { GetMaterial(out pairMaterial); //Console.WriteLine("ConfigureContactManifold2"); //Console.WriteLine(pair.A.Handle); //Console.WriteLine(pair.B.Handle); return(true); }
public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ContactManifold *manifold, out PairMaterialProperties pairMaterial) { pairMaterial.FrictionCoefficient = 1; pairMaterial.MaximumRecoveryVelocity = float.MaxValue; pairMaterial.SpringSettings.NaturalFrequency = MathHelper.Pi * 30; pairMaterial.SpringSettings.DampingRatio = 100f;// 100000; return(true); }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { pairMaterial = new PairMaterialProperties { FrictionCoefficient = 1, MaximumRecoveryVelocity = 2, SpringSettings = new SpringSettings(30, 1) }; Characters.TryReportContacts(pair, ref manifold, workerIndex, ref pairMaterial); return(true); }
public unsafe bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ConvexContactManifold *manifold, out PairMaterialProperties pairMaterial) { if (manifold->Count > 0) { Console.WriteLine($"CONVEX PAIR: {pair.A} versus {pair.B}"); } ConfigureMaterial(out pairMaterial); return(true); }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { //For the purposes of this demo, we'll use multiplicative blending for the friction and choose spring properties according to which collidable has a higher maximum recovery velocity. var a = CollidableMaterials[pair.A]; var b = CollidableMaterials[pair.B]; pairMaterial.FrictionCoefficient = a.FrictionCoefficient * b.FrictionCoefficient; pairMaterial.MaximumRecoveryVelocity = MathF.Max(a.MaximumRecoveryVelocity, b.MaximumRecoveryVelocity); pairMaterial.SpringSettings = pairMaterial.MaximumRecoveryVelocity == a.MaximumRecoveryVelocity ? a.SpringSettings : b.SpringSettings; return(true); }
public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB, ref ConvexContactManifold manifold) { BepuPhysicsComponent A = getFromReference(pair.A); BepuPhysicsComponent B = getFromReference(pair.B); if (((uint)A.CanCollideWith & (uint)B.CollisionGroup) != 0) { RecordContact(A, B, ref manifold); return(!A.GhostBody && !B.GhostBody); } return(false); }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { pairMaterial.FrictionCoefficient = Properties[pair.A.Handle].Friction; if (pair.B.Mobility != CollidableMobility.Static) { //If two bodies collide, just average the friction. pairMaterial.FrictionCoefficient = (pairMaterial.FrictionCoefficient + Properties[pair.B.Handle].Friction) * 0.5f; } pairMaterial.MaximumRecoveryVelocity = 2f; pairMaterial.SpringSettings = new SpringSettings(30, 1); return(true); }
//Note that this does not check collision rules. /// <summary> /// Tests the pair of collidables for intersection without regard for collision rules. /// </summary> /// <param name="pair">Pair to test.</param> /// <returns>Whether or not the pair is intersecting.</returns> public static bool Intersecting(ref CollidablePair pair) { var pairHandler = GetPairHandler(ref pair); pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); bool toReturn = pairHandler.ContactCount > 0; pairHandler.SuppressEvents = false; pairHandler.CleanUp(); (pairHandler as NarrowPhasePair).Factory.GiveBack(pairHandler); return(toReturn); }
public World CreateWorld() { int conver = Point3D.vectortrans; World place = new World((Width / conver) + 1, 1, (Height / conver) + 1); for (int x = 0; x < place.Right; x++) { for (int y = 0; y < place.Top; y++) { for (int z = 0; z < place.Back; z++) { BoundingBox box = new BoundingBox(new Vector3(x * conver, minheight + 5, z * conver), new Vector3(((x + 1) * conver) - 1, minheight + 25, ((z + 1) * conver) - 1)); List <BroadPhaseEntry> list = new List <BroadPhaseEntry>(); game.Space.BroadPhase.QueryAccelerator.GetEntries(box, list); Ray ray; if (list.Count > 0) { for (int k = 0; k < list.Count; k++) { StaticMesh temp = list[k] as StaticMesh; var pair = new CollidablePair(temp, new Box(new Vector3(x * conver, minheight + 5, z * conver), conver, 25, conver).CollisionInformation); var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair); pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); pairHandler.SuppressEvents = false; if (pairHandler.Colliding) { place.MarkPosition(new Point3D(x, y, z), true); break; } pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); } } //prevent the starting square from being blocked /*if ((x + y + z) % 3 == 0 && (x + y + z) != 0) * { * place.MarkPosition(new Point3D(x, y, z), true); * }*/ } } } return(place); }
private void QueryContacts(Vector3 position, EntityCollidable queryObject) { this.ClearContacts(); //Update the position and orientation of the query object. RigidTransform transform; transform.Position = position; transform.Orientation = this.character.Body.Orientation; queryObject.UpdateBoundingBoxForTransform(ref transform, 0); foreach (var collidable in this.character.Body.CollisionInformation.OverlappedCollidables) { if (collidable.BoundingBox.Intersects(queryObject.BoundingBox)) { var pair = new CollidablePair(collidable, queryObject); var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair); if (pairHandler.CollisionRule == CollisionRule.Normal) { pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); pairHandler.SuppressEvents = false; foreach (var contact in pairHandler.Contacts) { //Must check per-contact collision rules, just in case //the pair was actually a 'parent pair.' if (contact.Pair.CollisionRule == CollisionRule.Normal) { ContactData contactData; contactData.Position = contact.Contact.Position; contactData.Normal = contact.Contact.Normal; contactData.Id = contact.Contact.Id; contactData.PenetrationDepth = contact.Contact.PenetrationDepth; this.contacts.Add(contactData); } } } //TODO: It would be nice if this was a bit easier. //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving. //No one would ever just guess this correctly. //At least hide it behind a NarrowPhaseHelper function. pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); } } this.CategorizeContacts(ref position); }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { BepuPhysicsComponent a = getFromReference(pair.A); BepuPhysicsComponent b = getFromReference(pair.B); pairMaterial.FrictionCoefficient = a.FrictionCoefficient * b.FrictionCoefficient; pairMaterial.MaximumRecoveryVelocity = (a.MaximumRecoveryVelocity + b.MaximumRecoveryVelocity) * 0.5f; pairMaterial.SpringSettings.AngularFrequency = (a.SpringSettings.AngularFrequency + b.SpringSettings.AngularFrequency) * 0.5f; pairMaterial.SpringSettings.TwiceDampingRatio = (a.SpringSettings.TwiceDampingRatio + b.SpringSettings.TwiceDampingRatio) * 0.5f; if (((uint)a.CanCollideWith & (uint)b.CollisionGroup) != 0) { RecordContact(a, b, ref manifold); return(!a.GhostBody && !b.GhostBody); } return(false); }
/// <summary> /// Tests the pair of collidables for intersection without regard for collision rules. /// </summary> /// <param name="pair">Pair to test.</param> /// <returns>Whether or not the pair is intersecting.</returns> public static bool Intersecting(ref CollidablePair pair) { var pairHandler = GetPairHandler(ref pair); if (pairHandler == null) { return(false); } pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); bool toReturn = pairHandler.Colliding; pairHandler.SuppressEvents = false; pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); return(toReturn); }
/// <summary> /// Tests the pair of collidables for intersection without regard for collision rules. /// </summary> /// <param name="pair">Pair to test.</param> /// <returns>Whether or not the pair is intersecting.</returns> public static bool Intersecting(ref CollidablePair pair) { var pairHandler = GetPairHandler(ref pair); pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); //Technically, contacts with negative depth do not count. //The current implementation of collision detection does not generate //negative depths on the first execution of UpdateCollision, though, //so we don't need to worry about that- yet. bool toReturn = pairHandler.ContactCount > 0; pairHandler.SuppressEvents = false; pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); return(toReturn); }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { if (manifold.Count > 0) { if (manifold.Convex) { Console.WriteLine($"CONVEX PAIR: {pair.A} versus {pair.B}"); } else { Console.WriteLine($"NONCONVEX PAIR: {pair.A} versus {pair.B}"); } } pairMaterial.FrictionCoefficient = 1f; pairMaterial.MaximumRecoveryVelocity = 2f; pairMaterial.SpringSettings = new SpringSettings(30, 1); return(true); }
protected void TryToAdd(int index) { var entry = new TriangleEntry { Index = index }; if (!subPairs.ContainsKey(entry)) { var collidablePair = new CollidablePair(CollidableA, entry.Collidable = GetOpposingCollidable(index)); var newPair = (MobileMeshPairHandler)NarrowPhaseHelper.GetPairHandler(ref collidablePair); if (newPair != null) { newPair.CollisionRule = CollisionRule; newPair.UpdateMaterialProperties(MaterialA, MaterialB); //Override the materials, if necessary. Meshes don't currently support custom materials but.. newPair.Parent = this; subPairs.Add(entry, newPair); } } containedPairs.Add(entry); }
///<summary> /// Determines whether or not an entity is intersecting the triangle shell of a detector volume. ///</summary> ///<param name="entity">Entity to test.</param> /// <param name="intersectedTriangleIndices">First indices of intersected triangles in the index buffer.</param> ///<returns>Whether or not the entity is intersecting the shell.</returns> public bool IsEntityIntersectingShell(Entity entity, IList <int> intersectedTriangleIndices) { TriangleMesh.Tree.GetOverlaps(entity.CollisionInformation.BoundingBox, intersectedTriangleIndices); foreach (int i in intersectedTriangleIndices) { Vector3 v1, v2, v3; triangleMesh.Data.GetTriangle(i, out v1, out v2, out v3); var triangle = Resources.GetTriangleCollidable(ref v1, ref v2, ref v3); //TODO: Test a TRIANGLE against ANYTHING ELSE. //Requires BOOLEAN tests initially for: //Triangle-Convex //Triangle-CompoundShape var pair = new CollidablePair(entity.CollisionInformation, triangle); if (NarrowPhaseHelper.Intersecting(ref pair)) { Resources.GiveBack(triangle); return(true); } Resources.GiveBack(triangle); } return(false); }
///<summary> /// Determines whether or not an entity is intersecting the triangle shell of a detector volume. ///</summary> ///<param name="entity">Entity to test.</param> /// <param name="intersectedTriangleIndices">First indices of intersected triangles in the index buffer.</param> ///<returns>Whether or not the entity is intersecting the shell.</returns> public bool IsEntityIntersectingShell(Entity entity, IList<int> intersectedTriangleIndices) { TriangleMesh.Tree.GetOverlaps(entity.CollisionInformation.BoundingBox, intersectedTriangleIndices); foreach (int i in intersectedTriangleIndices) { Vector3 v1, v2, v3; triangleMesh.Data.GetTriangle(i, out v1, out v2, out v3); var triangle = Resources.GetTriangleCollidable(ref v1, ref v2, ref v3); //TODO: Test a TRIANGLE against ANYTHING ELSE. //Requires BOOLEAN tests initially for: //Triangle-Convex //Triangle-CompoundShape var pair = new CollidablePair(entity.CollisionInformation, triangle); if (NarrowPhaseHelper.Intersecting(ref pair)) { Resources.GiveBack(triangle); return true; } Resources.GiveBack(triangle); } return false; }
/// <summary> /// Tests the pair of collidables for intersection without regard for collision rules. /// </summary> /// <param name="pair">Pair to test.</param> /// <returns>Whether or not the pair is intersecting.</returns> public static bool Intersecting(ref CollidablePair pair) { var pairHandler = GetPairHandler(ref pair); if (pairHandler == null) return false; pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); //Technically, contacts with negative depth do not count. //The current implementation of collision detection does not generate //negative depths on the first execution of UpdateCollision, though, //so we don't need to worry about that- yet. bool toReturn = pairHandler.ContactCount > 0; pairHandler.SuppressEvents = false; pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); return toReturn; }
/// <summary> /// Gets a collidable pair handler for a pair of collidables. /// </summary> /// <param name="pair">Pair of collidables to use to create the pair handler.</param> /// <returns>CollidablePairHandler for the pair.</returns> public static CollidablePairHandler GetPairHandler(ref CollidablePair pair) { var overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB); return GetPairHandler(ref overlap) as CollidablePairHandler; }
protected void TryToAdd(Collidable a, Collidable b, Material materialA, Material materialB) { CollisionRule rule; if ((rule = CollisionRules.collisionRuleCalculator(a, b)) < CollisionRule.NoNarrowPhasePair) { //Clamp the rule to the parent's rule. Always use the more restrictive option. //Don't have to test for NoNarrowPhasePair rule on the parent's rule because then the parent wouldn't exist! if (rule < CollisionRule) rule = CollisionRule; var pair = new CollidablePair(a, b); if (!subPairs.ContainsKey(pair)) { var newPair = NarrowPhaseHelper.GetPairHandler(ref pair, rule); if (newPair != null) { newPair.UpdateMaterialProperties(materialA, materialB); //Override the materials, if necessary. newPair.Parent = this; subPairs.Add(pair, newPair); } } containedPairs.Add(pair); } }
public bool ConfigureContactManifold(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB, ref ConvexContactManifold manifold) { return(true); }
/// <summary> /// Gets a collidable pair handler for a pair of collidables. /// </summary> /// <param name="pair">Pair of collidables to use to create the pair handler.</param> /// <param name="rule">Collision rule governing the pair.</param> /// <returns>CollidablePairHandler for the pair.</returns> public static CollidablePairHandler GetPairHandler(ref CollidablePair pair, CollisionRule rule) { BroadPhaseOverlap overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB, rule); return GetPair(ref overlap) as CollidablePairHandler; }
//Note that this does not check collision rules. /// <summary> /// Tests the pair of collidables for intersection without regard for collision rules. /// </summary> /// <param name="pair">Pair to test.</param> /// <returns>Whether or not the pair is intersecting.</returns> public static bool Intersecting(ref CollidablePair pair) { var pairHandler = GetPairHandler(ref pair); pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); bool toReturn = pairHandler.ContactCount > 0; pairHandler.SuppressEvents = false; pairHandler.CleanUp(); (pairHandler as NarrowPhasePair).Factory.GiveBack(pairHandler); return toReturn; }
public unsafe bool ConfigureContactManifold <TManifold>(int workerIndex, CollidablePair pair, ref TManifold manifold, out PairMaterialProperties pairMaterial) where TManifold : struct, IContactManifold <TManifold> { pairMaterial = new PairMaterialProperties(); return(false); }
public bool AllowContactGeneration(int workerIndex, CollidablePair pair, int childIndexA, int childIndexB) { return(true); }
/// <summary> /// Tests the pair of collidables for intersection without regard for collision rules. /// </summary> /// <param name="pair">Pair to test.</param> /// <returns>Whether or not the pair is intersecting.</returns> public static bool Intersecting(ref CollidablePair pair) { var pairHandler = GetPairHandler(ref pair); if (pairHandler == null) return false; pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); bool toReturn = pairHandler.Colliding; pairHandler.SuppressEvents = false; pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); return toReturn; }
public void OnContactAdded <TManifold>(CollidableReference eventSource, CollidablePair pair, ref TManifold contactManifold, in System.Numerics.Vector3 contactOffset, in System.Numerics.Vector3 contactNormal, float depth, int featureId, int contactIndex, int workerIndex) where TManifold : struct, IContactManifold <TManifold>
/// <summary> /// Gets a collidable pair handler for a pair of collidables. /// </summary> /// <param name="pair">Pair of collidables to use to create the pair handler.</param> /// <returns>CollidablePairHandler for the pair.</returns> public static CollidablePairHandler GetPairHandler(ref CollidablePair pair) { var overlap = new BroadPhaseOverlap(pair.collidableA, pair.collidableB); return(GetPairHandler(ref overlap) as CollidablePairHandler); }
void QueryContacts(Vector3 position, EntityCollidable queryObject) { ClearContacts(); //Update the position and orientation of the query object. RigidTransform transform; transform.Position = position; transform.Orientation = character.Body.Orientation; queryObject.UpdateBoundingBoxForTransform(ref transform, 0); foreach (var collidable in character.Body.CollisionInformation.OverlappedCollidables) { if (collidable.BoundingBox.Intersects(queryObject.BoundingBox)) { var pair = new CollidablePair(collidable, queryObject); var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair); if (pairHandler.CollisionRule == CollisionRule.Normal) { pairHandler.UpdateCollision(0); foreach (var contact in pairHandler.Contacts) { //Must check per-contact collision rules, just in case //the pair was actually a 'parent pair.' if (contact.Pair.CollisionRule == CollisionRule.Normal) { ContactData contactData; contactData.Position = contact.Contact.Position; contactData.Normal = contact.Contact.Normal; contactData.Id = contact.Contact.Id; contactData.PenetrationDepth = contact.Contact.PenetrationDepth; contacts.Add(contactData); } } } //TODO: It would be nice if this was a bit easier. //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving. //No one would ever just guess this correctly. //At least hide it behind a NarrowPhaseHelper function. pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); } } CategorizeContacts(ref position); }
/// <summary> /// Finds contacts between the query object and any intersected objects within the character's bounding box. /// </summary> /// <param name="queryObject">Collidable to query for contacts with.</param> /// <param name="tractionContacts">Output contacts that would provide traction.</param> /// <param name="supportContacts">Output contacts that would provide support.</param> /// <param name="sideContacts">Output contacts on the sides of the query object.</param> /// <param name="headContacts">Output contacts on the head of the query object.</param> public void QueryContacts(EntityCollidable queryObject, ref QuickList<CharacterContact> tractionContacts, ref QuickList<CharacterContact> supportContacts, ref QuickList<CharacterContact> sideContacts, ref QuickList<CharacterContact> headContacts) { var downDirection = characterBody.orientationMatrix.Down; tractionContacts.Clear(); supportContacts.Clear(); sideContacts.Clear(); headContacts.Clear(); foreach (var collidable in characterBody.CollisionInformation.OverlappedCollidables) { //The query object is assumed to have a valid bounding box. if (collidable.BoundingBox.Intersects(queryObject.BoundingBox)) { var pair = new CollidablePair(collidable, queryObject); var pairHandler = NarrowPhaseHelper.GetPairHandler(ref pair); if (pairHandler.CollisionRule == CollisionRule.Normal) { pairHandler.SuppressEvents = true; pairHandler.UpdateCollision(0); pairHandler.SuppressEvents = false; contactCategorizer.CategorizeContacts(pairHandler, characterBody.CollisionInformation, ref downDirection, ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts); } //TODO: It would be nice if this was a bit easier. //Having to remember to clean up AND give it back is a bit weird, especially with the property-diving. //No one would ever just guess this correctly. //At least hide it behind a NarrowPhaseHelper function. pairHandler.CleanUp(); pairHandler.Factory.GiveBack(pairHandler); } } }
public unsafe bool ConfigureContactManifold(int workerIndex, CollidablePair pair, ConvexContactManifold *manifold, out PairMaterialProperties pairMaterial) { GetMaterial(out pairMaterial); return(true); }