///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { box = entryA as ConvexCollidable<BoxShape>; sphere = entryB as ConvexCollidable<SphereShape>; if (box == null || sphere == null) { box = entryB as ConvexCollidable<BoxShape>; sphere = entryA as ConvexCollidable<SphereShape>; if (box == null || sphere == null) { throw new Exception("Inappropriate types used to initialize pair."); } } //Reorder the entries so that the guarantee that the normal points from A to B is satisfied. broadPhaseOverlap.entryA = box; broadPhaseOverlap.entryB = sphere; base.Initialize(entryA, entryB); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { instancedMesh = entryA as InstancedMesh; convex = entryB as ConvexCollidable; if (instancedMesh == null || convex == null) { instancedMesh = entryB as InstancedMesh; convex = entryA as ConvexCollidable; if (instancedMesh == null || convex == null) throw new Exception("Inappropriate types used to initialize pair."); } //Contact normal goes from A to B. broadPhaseOverlap.entryA = convex; broadPhaseOverlap.entryB = instancedMesh; UpdateMaterialProperties(convex.entity != null ? convex.entity.material : null, instancedMesh.material); base.Initialize(entryA, entryB); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { mobileMesh = entryA as MobileMeshCollidable; convex = entryB as ConvexCollidable; if (mobileMesh == null || convex == null) { mobileMesh = entryB as MobileMeshCollidable; convex = entryA as ConvexCollidable; if (mobileMesh == null || convex == null) throw new Exception("Inappropriate types used to initialize pair."); } //Contact normal goes from A to B. broadPhaseOverlap.entryA = convex; broadPhaseOverlap.entryB = mobileMesh; //It's possible that the convex does not have an entity if it is a proxy for a non-entity collidable. //Similarly, the mesh could be a query object. UpdateMaterialProperties(convex.entity != null ? convex.entity.material : null, mobileMesh.entity != null ? mobileMesh.entity.material : null); base.Initialize(entryA, entryB); }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); boxA = null; boxB = null; }
public override void CleanUp() { base.CleanUp(); convex = null; checkContainment = true; }
/// <summary> /// Constructs the query manager for a character. /// </summary> /// <param name="character">Character to manage queries for.</param> public QueryManager(CylinderCharacterController character) { this.character = character; //We can share the real shape with the 'current' query object. queryObject = new ConvexCollidable<CylinderShape>(character.Body.CollisionInformation.Shape); //Share the collision rules between the main body and its query objects. That way, the character's queries return valid results. queryObject.CollisionRules = character.Body.CollisionInformation.CollisionRules; SupportRayFilter = SupportRayFilterFunction; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); convexA = null; convexB = null; }
public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { base.Initialize(entryA, entryB); convex = entryA as ConvexCollidable; if (convex == null) { convex = entryB as ConvexCollidable; if (convex == null) { throw new Exception("Incorrect types passed to pair handler."); } } }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { boxA = entryA as ConvexCollidable<BoxShape>; boxB = entryB as ConvexCollidable<BoxShape>; if (boxA == null || boxB == null) { throw new Exception("Inappropriate types used to initialize pair."); } base.Initialize(entryA, entryB); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { convexInfo = entryA as ConvexCollidable; if (convexInfo == null) { convexInfo = entryB as ConvexCollidable; if (convexInfo == null) { throw new Exception("Inappropriate types used to initialize pair."); } } base.Initialize(entryA, entryB); }
///<summary> /// Initializes the pair handler. ///</summary> ///<param name="entryA">First entry in the pair.</param> ///<param name="entryB">Second entry in the pair.</param> public override void Initialize(BroadPhaseEntry entryA, BroadPhaseEntry entryB) { triangle = entryA as ConvexCollidable<TriangleShape>; convex = entryB as ConvexCollidable; if (triangle == null || convex == null) { triangle = entryB as ConvexCollidable<TriangleShape>; convex = entryA as ConvexCollidable; if (triangle == null || convex == null) throw new Exception("Inappropriate types used to initialize pair."); } //Contact normal goes from A to B. broadPhaseOverlap.entryA = convex; broadPhaseOverlap.entryB = triangle; base.Initialize(entryA, entryB); }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); terrain = null; convex = null; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); instancedMesh = null; convex = null; }
///<summary> /// Initializes the manifold. ///</summary> ///<param name="newCollidableA">First collidable.</param> ///<param name="newCollidableB">Second collidable.</param> ///<exception cref="Exception">Thrown when the collidables being used are not of the proper type.</exception> public override void Initialize(Collidable newCollidableA, Collidable newCollidableB) { box = newCollidableA as ConvexCollidable<BoxShape>; sphere = newCollidableB as ConvexCollidable<SphereShape>; if (box == null || sphere == null) { box = newCollidableB as ConvexCollidable<BoxShape>; sphere = newCollidableA as ConvexCollidable<SphereShape>; if (box == null || sphere == null) { throw new Exception("Inappropriate types used to initialize pair."); } } }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); box = null; sphere = null; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); triangle = null; convex = null; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); mobileMesh = null; convex = null; }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); sphereA = null; sphereB = null; }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public StaticGroupDemo(DemosGame game) : base(game) { //Creating a bunch of separate StaticMeshes or kinematic Entity objects for an environment can pollute the broad phase. //This is because the broad phase implementation doesn't have guarantees about what elements can collide, so it has to //traverse the acceleration structure all the way down to pairs to figure it out. That can get expensive! //Individual objects, like StaticMeshes, can have very complicated geometry without hurting the broad phase because the broad phase //has no knowledge of the thousands of triangles in the mesh. The StaticMesh itself knows that the triangles within the mesh //never need to collide, so it never needs to test them against each other. //Similarly, the StaticGroup can be given a bunch of separate collidables. The broad phase doesn't directly know about these child collidables- //it only sees the StaticGroup. The StaticGroup knows that the things inside it can't ever collide with each other, so no tests are needed. //This avoids the performance problem! //To demonstrate, we'll be creating a set of static objects and giving them to a group to manage. List<Collidable> collidables = new List<Collidable>(); //Start with a whole bunch of boxes. These are entity collidables, but without entities! float xSpacing = 6; float ySpacing = 6; float zSpacing = 6; //NOTE: You might notice this demo takes a while to start, especially on the Xbox360. Do not fear! That's due to the creation of the graphics data, not the physics. //The physics can handle over 100,000 static objects pretty easily. The graphics, not so much :) //Try disabling the game.ModelDrawer.Add() lines and increasing the number of static objects. int xCount = 15; int yCount = 7; int zCount = 15; var random = new Random(); for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { for (int k = 0; k < zCount; k++) { //Create a transform and the instance of the mesh. var collidable = new ConvexCollidable<BoxShape>(new BoxShape((float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f)); //This EntityCollidable isn't associated with an entity, so we must manually tell it where to sit by setting the WorldTransform. //This also updates its bounding box. collidable.WorldTransform = new RigidTransform( new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + 3, k * zSpacing - zCount * zSpacing * .5f), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100)); collidables.Add(collidable); game.ModelDrawer.Add(collidable); } } } //Now create a bunch of instanced meshes too. xSpacing = 6; ySpacing = 6; zSpacing = 6; xCount = 10; yCount = 2; zCount = 10; Vector3[] vertices; int[] indices; TriangleMesh.GetVerticesAndIndicesFromModel(game.Content.Load<Model>("fish"), out vertices, out indices); var meshShape = new InstancedMeshShape(vertices, indices); for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { for (int k = 0; k < zCount; k++) { //Create a transform and the instance of the mesh. var transform = new AffineTransform( new Vector3((float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f, (float)random.NextDouble() * 6 + .5f), Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), (float)random.NextDouble() * 100), new Vector3(i * xSpacing - xCount * xSpacing * .5f, j * ySpacing + 50, k * zSpacing - zCount * zSpacing * .5f)); var mesh = new InstancedMesh(meshShape, transform); //Making the triangles one-sided makes collision detection a bit more robust, since the backsides of triangles won't try to collide with things //and 'pull' them back into the mesh. mesh.Sidedness = TriangleSidedness.Counterclockwise; collidables.Add(mesh); game.ModelDrawer.Add(mesh); } } } StaticGroup group = new StaticGroup(collidables); Space.Add(group); //Create a bunch of dynamic boxes to drop on the staticswarm. xCount = 8; yCount = 3; zCount = 8; xSpacing = 3f; ySpacing = 5f; zSpacing = 3f; for (int i = 0; i < xCount; i++) for (int j = 0; j < zCount; j++) for (int k = 0; k < yCount; k++) { Space.Add(new Box(new Vector3( xSpacing * i - (xCount - 1) * xSpacing / 2f, 100 + k * (ySpacing), 2 + zSpacing * j - (zCount - 1) * zSpacing / 2f), 1, 1, 1, 10)); } Box ground = new Box(new Vector3(0, -3f, 0), 200, 1, 200); Space.Add(ground); game.Camera.Position = new Vector3(0, 60, 90); }
///<summary> /// Initializes the pair tester. ///</summary> ///<param name="shapeA">First shape in the pair.</param> ///<param name="shapeB">Second shape in the pair.</param> public void Initialize(Collidable shapeA, Collidable shapeB) { collidableA = (ConvexCollidable)shapeA; collidableB = (ConvexCollidable)shapeB; cachedSimplex = new CachedSimplex { State = SimplexState.Point };// new CachedSimplex(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform); }
///<summary> /// Cleans up the pair handler. ///</summary> public override void CleanUp() { base.CleanUp(); convexInfo = null; }
///<summary> /// Initializes the manifold. ///</summary> ///<param name="newCollidableA">First collidable.</param> ///<param name="newCollidableB">Second collidable.</param> public override void Initialize(Collidable newCollidableA, Collidable newCollidableB) { collidableA = newCollidableA as ConvexCollidable; collidableB = newCollidableB as ConvexCollidable; pairTester.Initialize(newCollidableA, newCollidableB); if (collidableA == null || collidableB == null) { throw new Exception("Inappropriate types used to initialize pair tester."); } }
///<summary> /// Cleans up the manifold. ///</summary> public override void CleanUp() { contacts.Clear(); boxA = null; boxB = null; base.CleanUp(); }
///<summary> /// Initializes the manifold. ///</summary> ///<param name="newCollidableA">First collidable.</param> ///<param name="newCollidableB">Second collidable.</param> ///<exception cref="Exception">Thrown when the collidables being used are not of the proper type.</exception> public override void Initialize(Collidable newCollidableA, Collidable newCollidableB) { boxA = (ConvexCollidable<BoxShape>)newCollidableA; boxB = (ConvexCollidable<BoxShape>)newCollidableB; if (boxA == null || boxB == null) { throw new Exception("Inappropriate types used to initialize pair tester."); } }
public override void Initialize(Collidable newCollidableA, Collidable newCollidableB) { convex = newCollidableA as ConvexCollidable; triangle = newCollidableB as ConvexCollidable<TriangleShape>; if (convex == null || triangle == null) { convex = newCollidableB as ConvexCollidable; triangle = newCollidableA as ConvexCollidable<TriangleShape>; if (convex == null || triangle == null) throw new Exception("Inappropriate types used to initialize contact manifold."); } pairTester.Initialize(convex.Shape, localTriangleShape); }
///<summary> /// Cleans up the pair tester. ///</summary> public void CleanUp() { state = CollisionState.Separated; previousState = CollisionState.Separated; cachedSimplex = new CachedSimplex(); localSeparatingAxis = new Vector3(); collidableA = null; collidableB = null; }
///<summary> /// Cleans up the manifold. ///</summary> public override void CleanUp() { contacts.Clear(); box = null; sphere = null; previouslyColliding = false; base.CleanUp(); }
///<summary> /// Cleans up the manifold. ///</summary> public override void CleanUp() { supplementData.Clear(); contacts.Clear(); collidableA = null; collidableB = null; pairTester.CleanUp(); base.CleanUp(); }
public override void CleanUp() { supplementData.Clear(); contacts.Clear(); convex = null; triangle = null; pairTester.CleanUp(); base.CleanUp(); }