public void Move(ClientPhysicsQuadTreeNode root, Matrix newPose) { if (actor == null) { throw new InvalidOperationException(); } // NOTE: IMPORTANT: this is actually a partial implementation of the algorithm itself Matrix oldPose = World; ClientPhysicsQuadTreeNode oldNode = Node; // Update location in quadtree world = newPose; root.OrdenObject(this); // Update dynamic object count Node.AddDynamicObjectToIntersectingNodes(this); // Add must come before remove to prevent overhead if (oldNode != null) { world = oldPose; // set old state oldNode.RemoveDynamicObjectFromIntersectingNodes(this); world = newPose; // set new state } }
public void Update(ClientPhysicsQuadTreeNode root) { if (sleeping && actor.IsSleeping) { return; } if (sleeping && !actor.IsSleeping) { // Make dynamic again! sleeping = false; Node.AddDynamicObjectToIntersectingNodes(this); } if (actor.IsSleeping && !sleeping) { // Disable dynamic, thus make static if (node != null) { node.RemoveDynamicObjectFromIntersectingNodes(this); } sleeping = true; if (node != null && node.PhysicsEnabled == false) { DisablePhysics(); // disable movement } return; } Move(root, actor.GlobalPose); }
public Microsoft.Xna.Framework.ContainmentType ContainedInNode(ClientPhysicsQuadTreeNode _node) { //TODO: make this the actual size of the controller BoundingBox bb = new BoundingBox(currentPosition + new Vector3(-0.5f, -0.5f, -0.5f), currentPosition + new Vector3(0.5f, 0.5f, 0.5f)); return(_node.NodeData.BoundingBox.xna().Contains(bb)); }
public MeshPhysicsElementFactory(PhysicsEngine engine, ClientPhysicsQuadTreeNode root) { Engine = engine; Root = root; MeshPhysicsPool = new MeshPhysicsPool(); actorBuilder = new MeshPhysicsActorBuilder(MeshPhysicsPool); }
public TestSphereShooter(IXNAGame game, PhysicsEngine engine, ClientPhysicsQuadTreeNode root, ICamera shooterCamera) { this.game = game; this.engine = engine; this.root = root; this.shooterCamera = shooterCamera; sphereMesh = new SphereMesh(0.3f, 20, Color.Green); }
public void TestTestSphereShooter() { var game = new XNAGame(); game.IsFixedTimeStep = false; //game.DrawFps = true; PhysicsEngine engine = new PhysicsEngine(); engine.Initialize(); var debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); game.AddXNAObject(debugRenderer); game.AddXNAObject(engine); ClientPhysicsQuadTreeNode root; int numNodes = 20; root = new ClientPhysicsQuadTreeNode( new BoundingBox( new Vector3(-numNodes * numNodes / 2f, -100, -numNodes * numNodes / 2f), new Vector3(numNodes * numNodes / 2f, 100, numNodes * numNodes / 2f))); QuadTree.Split(root, 5); var shooter = new TestSphereShooter(game, engine, root, game.SpectaterCamera); game.AddXNAObject(shooter); var visualizer = new QuadTreeVisualizerXNA(); game.DrawEvent += delegate { visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.PhysicsObjects.Count == 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Orange; return(node.PhysicsObjects.Count > 0); }); }; game.Run(); }
public static ClientPhysicsQuadTreeNode CreatePhysicsQuadtree(int numNodes, int numSplits) { TheWizards.Client.ClientPhysicsQuadTreeNode root; root = new ClientPhysicsQuadTreeNode( new BoundingBox( new Vector3(-numNodes * numNodes / 2f, -100, -numNodes * numNodes / 2f), new Vector3(numNodes * numNodes / 2f, 100, numNodes * numNodes / 2f))); QuadTree.Split(root, numSplits); return(root); }
public static ClientPhysicsQuadTreeNode CreateTestClientPhysicsQuadtree() { ClientPhysicsQuadTreeNode root = new ClientPhysicsQuadTreeNode( new BoundingBox( new Vector3(-100, -100, -100), new Vector3(100, 100, 100)) ); QuadTree.Split(root, 4); QuadTree.Merge(root.NodeData.LowerRight.NodeData.LowerRight.NodeData.UpperLeft); QuadTree.MergeRecursive(root.NodeData.LowerLeft.NodeData.UpperRight); QuadTree.MergeRecursive(root.NodeData.UpperRight); return(root); }
public PhysXSimulator() { data = TW.Data.GetSingleton <PhysXData>(); root = new ClientPhysicsQuadTreeNode( new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000)).xna()); QuadTree.Split(root, 6); data.RootNode = root; factory = new MeshPhysicsElementFactory(TW.Physics, root); factory.Initialize(); entityUpdater = new EntityPhysXUpdater(factory, root); DebugRenderer = new PhysicsDebugRenderer(TW.Graphics, TW.Physics.Scene); DebugRenderer.Initialize(); }
/// <summary> /// This updates the position of the client physics object to the controller's position, /// and updates the dynamicobjectscount in the Client Physics /// This uses the dynamic object trick /// </summary> public void Update(ClientPhysicsQuadTreeNode root) { // First adds count, then removes. This is simply to ensure that objects are not flicked on of this frame Vector3 oldPosition = currentPosition; Vector3 newPosition = controller.GlobalPosition; currentPosition = newPosition; ClientPhysicsQuadTreeNode oldNode = node; root.OrdenObject(this); node.AddDynamicObjectToIntersectingNodes(this); if (oldNode != null) { currentPosition = oldPosition; oldNode.RemoveDynamicObjectFromIntersectingNodes(this); currentPosition = newPosition; } }
public void Move(ClientPhysicsQuadTreeNode root, Vector3 newCenter) { // NOTE: IMPORTANT: this is actually a partial implementation of the algorithm itself Vector3 oldCenter = Center; ClientPhysicsQuadTreeNode oldNode = Node; // Update location in quadtree Center = newCenter; root.OrdenObject(this); // Update dynamic object count Node.AddDynamicObjectToIntersectingNodes(this); // Add must come before remove to prevent overhead if (oldNode != null) { Center = oldCenter; // set old state oldNode.RemoveDynamicObjectFromIntersectingNodes(this); Center = newCenter; // set new state } }
public Microsoft.Xna.Framework.ContainmentType ContainedInNode(ClientPhysicsQuadTreeNode _node) { return(_node.NodeData.BoundingBox.xna().Contains(boundingSphere)); }
public ContainmentType ContainedInNode(ClientPhysicsQuadTreeNode _node) { return(_node.NodeData.BoundingBox.xna().Contains(GetBoundingSphere().xna())); }
public void Update(ClientPhysicsQuadTreeNode root) { move(root, Matrix.Translation(controller.GlobalPosition.dx())); }
public MeshPhysicsFactoryXNA(PhysicsEngine engine, ClientPhysicsQuadTreeNode root) { Factory = new MeshPhysicsElementFactory(engine, root); }
public EntityPhysXUpdater(MeshPhysicsElementFactory factory, ClientPhysicsQuadTreeNode root) { this.factory = factory; this.root = root; }
public void TestOBJToRAMMeshConverterPerObjectVisual() { var c = new OBJToRAMMeshConverter(new RAMTextureFactory()); var importer = new ObjImporter(); importer.AddMaterialFileStream("Town001.mtl", new FileStream(TestFiles.TownMtl, FileMode.Open)); importer.ImportObjFile(TestFiles.TownObj); var meshes = c.CreateMeshesFromObjects(importer); var texturePool = new TexturePool(); var meshpartPool = new MeshPartPool(); var vertexDeclarationPool = new VertexDeclarationPool(); var renderer = new SimpleMeshRenderer(texturePool, meshpartPool, vertexDeclarationPool); vertexDeclarationPool.SetVertexElements <TangentVertex>(TangentVertex.VertexElements); var spheres = new List <ClientPhysicsTestSphere>(); var engine = new PhysicsEngine(); PhysicsDebugRendererXNA debugRenderer = null; var builder = new MeshPhysicsActorBuilder(new MeshPhysicsPool()); TheWizards.Client.ClientPhysicsQuadTreeNode root; int numNodes = 20; root = new ClientPhysicsQuadTreeNode( new BoundingBox( new Vector3(-numNodes * numNodes / 2f, -100, -numNodes * numNodes / 2f), new Vector3(numNodes * numNodes / 2f, 100, numNodes * numNodes / 2f))); QuadTree.Split(root, 5); var physicsElementFactoryXNA = new MeshPhysicsFactoryXNA(engine, root); var physicsElementFactory = physicsElementFactoryXNA.Factory; var physicsElements = new List <MeshStaticPhysicsElement>(); for (int i = 0; i < 0 * 100 + 1 * meshes.Count; i++) { var mesh = meshes[i]; var el = renderer.AddMesh(mesh); el.WorldMatrix = Matrix.CreateTranslation(Vector3.Right * 0 * 2 + Vector3.UnitZ * 0 * 2); var pEl = physicsElementFactory.CreateStaticElement(mesh, Matrix.Identity); physicsElements.Add(pEl); } var game = new XNAGame(); game.IsFixedTimeStep = false; game.DrawFps = true; game.SpectaterCamera.FarClip = 5000; game.Graphics1.PreparingDeviceSettings += delegate(object sender, PreparingDeviceSettingsEventArgs e) { DisplayMode displayMode = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode; e.GraphicsDeviceInformation.PresentationParameters.BackBufferFormat = displayMode.Format; e.GraphicsDeviceInformation.PresentationParameters.BackBufferWidth = displayMode.Width; e.GraphicsDeviceInformation.PresentationParameters.BackBufferHeight = displayMode.Height; game.SpectaterCamera.AspectRatio = displayMode.Width / (float)displayMode.Height; }; game.Graphics1.ToggleFullScreen(); var sphereMesh = new SphereMesh(0.3f, 20, Color.Green); var visualizer = new QuadTreeVisualizerXNA(); game.AddXNAObject(physicsElementFactoryXNA); game.AddXNAObject(texturePool); game.AddXNAObject(meshpartPool); game.AddXNAObject(vertexDeclarationPool); game.AddXNAObject(renderer); game.InitializeEvent += delegate { engine.Initialize(); debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); debugRenderer.Initialize(game); sphereMesh.Initialize(game); }; bool showPhysics = true; game.DrawEvent += delegate { if (game.Keyboard.IsKeyPressed(Keys.P)) { showPhysics = !showPhysics; } if (showPhysics) { debugRenderer.Render(game); } visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.PhysicsObjects.Count == 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Orange; return(node.PhysicsObjects.Count > 0); }); for (int i = 0; i < physicsElements.Count; i++) { var el = physicsElements[i]; //game.LineManager3D.AddBox(BoundingBox.CreateFromSphere( el.BoundingSphere), Color.Orange); } for (int i = 0; i < spheres.Count; i++) { sphereMesh.WorldMatrix = Matrix.CreateTranslation(spheres[i].Center); sphereMesh.Render(game); } }; game.UpdateEvent += delegate { engine.Update(game.Elapsed); sphereMesh.Update(game); if (game.Keyboard.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.F)) { var iSphere = new ClientPhysicsTestSphere(engine.Scene, game.SpectaterCamera.CameraPosition + game.SpectaterCamera.CameraDirection , 0.3f); iSphere.InitDynamic(); iSphere.Actor.LinearVelocity = game.SpectaterCamera.CameraDirection * 10; spheres.Add(iSphere); } for (int i = 0; i < spheres.Count; i++) { spheres[i].Update(root, game); } }; game.Run(); }
public void TestMeshPhysicsElementFactoryDynamic() { XNAGame game = new XNAGame(); RAMMesh mesh = createTwoBoxMesh(); BoundingBox bb = new BoundingBox(); PhysicsEngine engine = new PhysicsEngine(); PhysicsDebugRendererXNA debugRenderer = null; ClientPhysicsQuadTreeNode root = CreatePhysicsQuadtree(16, 4); var visualizer = new QuadTreeVisualizerXNA(); var meshes = new List <MeshDynamicPhysicsElement>(); var physicsElementFactoryXNA = new MeshPhysicsFactoryXNA(engine, root); var factory = physicsElementFactoryXNA.Factory; game.AddXNAObject(physicsElementFactoryXNA); game.InitializeEvent += delegate { engine.Initialize(); debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); debugRenderer.Initialize(game); }; game.DrawEvent += delegate { debugRenderer.Render(game); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.PhysicsObjects.Count == 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Orange; return(node.PhysicsObjects.Count > 0); }); }; game.UpdateEvent += delegate { if (game.Keyboard.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.F)) { var el = factory.CreateDynamicElement(mesh, Matrix.CreateTranslation(game.SpectaterCamera.CameraPosition + game.SpectaterCamera.CameraDirection)); el.Actor.LinearVelocity = game.SpectaterCamera.CameraDirection * 10; meshes.Add(el); } engine.Update(game.Elapsed); }; game.Run(); }
public void TestMeshDynamicPhysicsElement() { XNAGame game = new XNAGame(); var mesh = new RAMMesh(); var data = mesh.GetCollisionData(); var box = new MeshCollisionData.Box(); box.Dimensions = Vector3.One * 2; box.Orientation = Matrix.Identity; data.Boxes.Add(box); box = new MeshCollisionData.Box(); box.Dimensions = Vector3.One * 4; box.Orientation = Matrix.CreateTranslation(new Vector3(2, 2, 2)); data.Boxes.Add(box); BoundingBox bb = new BoundingBox(); PhysicsEngine engine = new PhysicsEngine(); PhysicsDebugRendererXNA debugRenderer = null; TheWizards.Client.ClientPhysicsQuadTreeNode root; root = new ClientPhysicsQuadTreeNode( new BoundingBox( new Vector3(-16 * 16 / 2f, -100, -16 * 16 / 2f), new Vector3(16 * 16 / 2f, 100, 16 * 16 / 2f))); QuadTree.Split(root, 4); var builder = new MeshPhysicsActorBuilder(new MeshPhysicsPool()); var visualizer = new QuadTreeVisualizerXNA(); float time = 0; var spheres = new List <MeshDynamicPhysicsElement>(); var meshes = new List <MeshStaticPhysicsElement>(); var physicsElementFactoryXNA = new MeshPhysicsFactoryXNA(engine, root); var factory = physicsElementFactoryXNA.Factory; game.AddXNAObject(physicsElementFactoryXNA); game.InitializeEvent += delegate { engine.Initialize(); debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); debugRenderer.Initialize(game); }; game.DrawEvent += delegate { debugRenderer.Render(game); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.PhysicsObjects.Count == 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Orange; return(node.PhysicsObjects.Count > 0); }); for (int i = 0; i < meshes.Count; i++) { game.LineManager3D.AddCenteredBox(meshes[i].BoundingSphere.Center, meshes[i].BoundingSphere.Radius * 2, Color.Black); } }; game.UpdateEvent += delegate { time += game.Elapsed; if (game.Keyboard.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.F)) { var dEl = new MeshDynamicPhysicsElement(mesh, Matrix.CreateTranslation( game.SpectaterCamera.CameraPosition + game.SpectaterCamera.CameraDirection), builder); dEl.InitDynamic(engine.Scene); dEl.Actor.LinearVelocity = game.SpectaterCamera.CameraDirection * 10; spheres.Add(dEl); } for (int i = 0; i < spheres.Count; i++) { spheres[i].Update(root); } engine.Update(game.Elapsed); }; game.Run(); }
public void TestEntityClientPhysis() { XNAGame game = new XNAGame(); Database.Database database = loadDatabaseServices(); EntityManagerService ems = new EntityManagerService(database); BoundingBox bb = new BoundingBox(); PhysicsEngine engine = new PhysicsEngine(); PhysicsDebugRendererXNA debugRenderer = null; TheWizards.Client.ClientPhysicsQuadTreeNode root; root = new ClientPhysicsQuadTreeNode( new BoundingBox( new Vector3(-16 * 16 / 2f, -100, -16 * 16 / 2f), new Vector3(16 * 16 / 2f, 100, 16 * 16 / 2f))); QuadTree.Split(root, 4); ClientPhysicsTestSphere sphere = new ClientPhysicsTestSphere(Vector3.Zero, 2); Curve3D curve1 = ClientTest.CreateTestObject1MovementCurve(); QuadTreeVisualizerXNA visualizer = new QuadTreeVisualizerXNA(); float time = 0; List <ClientPhysicsTestSphere> spheres = new List <ClientPhysicsTestSphere>(); List <EntityClientPhysics> entities = new List <EntityClientPhysics>(); game.InitializeEvent += delegate { engine.Initialize(); debugRenderer = new PhysicsDebugRendererXNA(game, engine.Scene); debugRenderer.Initialize(game); EntityFullData entityData; EntityClientPhysics entPhysics; entityData = CreatePyramidEntity(ems, 5); entityData.Transform = new Transformation( Vector3.One, Quaternion.Identity, new Vector3(10, 2, 20)); entPhysics = new EntityClientPhysics(entityData); entPhysics.LoadInClientPhysics(engine.Scene, root); entities.Add(entPhysics); entityData = CreatePyramidEntity(ems, 20); entityData.Transform = new Transformation( Vector3.One, Quaternion.Identity, new Vector3(-32, 0, -40)); entPhysics = new EntityClientPhysics(entityData); entPhysics.LoadInClientPhysics(engine.Scene, root); entities.Add(entPhysics); entityData = CreateTwoPyramidEntity(ems, 5, 3); entityData.ObjectFullData.Models[0].ObjectMatrix *= Matrix.CreateTranslation(new Vector3(-3, 0, 3)); entityData.ObjectFullData.Models[1].ObjectMatrix *= Matrix.CreateTranslation(new Vector3(3, 1, 2)); entityData.Transform = new Transformation( Vector3.One * 2, Quaternion.Identity, new Vector3(80, 0, -45)); entPhysics = new EntityClientPhysics(entityData); entPhysics.LoadInClientPhysics(engine.Scene, root); entities.Add(entPhysics); }; game.DrawEvent += delegate { debugRenderer.Render(game); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.PhysicsObjects.Count == 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Orange; return(node.PhysicsObjects.Count > 0); }); game.LineManager3D.AddCenteredBox(sphere.Center, sphere.Radius, Color.Red); for (int i = 0; i < entities.Count; i++) { game.LineManager3D.AddCenteredBox(entities[i].BoundingSphere.Center, entities[i].BoundingSphere.Radius * 2, Color.Black); } }; game.UpdateEvent += delegate { time += game.Elapsed; sphere.Move(root, curve1.Evaluate(time * (1 / 4f))); if (game.Keyboard.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.F)) { ClientPhysicsTestSphere iSphere = new ClientPhysicsTestSphere(engine.Scene, game.SpectaterCamera.CameraPosition + game.SpectaterCamera.CameraDirection , 1); iSphere.InitDynamic(); iSphere.Actor.LinearVelocity = game.SpectaterCamera.CameraDirection * 10; spheres.Add(iSphere); } for (int i = 0; i < spheres.Count; i++) { spheres[i].Update(root, game); } engine.Update(game.Elapsed); }; game.Run(); }
public void TestPhysicsQuadTreeOrdenObjects() { ClientPhysicsQuadTreeNode root = CreateTestClientPhysicsQuadtree(); List <ClientPhysicsTestSphere> spheres = new List <ClientPhysicsTestSphere>(); spheres.Add(new ClientPhysicsTestSphere(new Vector3(3, 0, 3), 1)); spheres.Add(new ClientPhysicsTestSphere(new Vector3(33, 0, -83), 1)); spheres.Add(new ClientPhysicsTestSphere(new Vector3(-25, 0, 40), 1)); spheres.Add(new ClientPhysicsTestSphere(new Vector3(-25, 0, -35), 1)); for (int i = 0; i < spheres.Count; i++) { root.OrdenObject(spheres[i]); } ClientPhysicsTestSphere movingSphere = new ClientPhysicsTestSphere(Vector3.Zero, 2); Curve3D curve = CreateTestObject1MovementCurve(); float time = 0; QuadTreeVisualizerXNA visualizer = new QuadTreeVisualizerXNA(); XNAGame game = new XNAGame(); game.UpdateEvent += delegate { time += game.Elapsed; movingSphere.Center = curve.Evaluate(time * (1 / 4f)); root.OrdenObject(movingSphere); }; game.DrawEvent += delegate { for (int i = 0; i < spheres.Count; i++) { game.LineManager3D.AddCenteredBox(spheres[i].Center, spheres[i].Radius, Color.Red); } game.LineManager3D.AddCenteredBox(movingSphere.Center, movingSphere.Radius, Color.Red); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.PhysicsObjects.Count == 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Orange; return(node.PhysicsObjects.Count > 0); }); }; game.Run(); }
public void LoadInClientPhysics(StillDesign.PhysX.Scene _scene, ClientPhysicsQuadTreeNode root) { scene = _scene; //root.OrdenObject(this); root.AddStaticObject(this); }
public void TestPhysicsEnableDisable() { List <ClientPhysicsTestSphere> spheres = new List <ClientPhysicsTestSphere>(); ClientPhysicsQuadTreeNode root = CreateTestClientPhysicsQuadtree(); spheres.Add(new ClientPhysicsTestSphere(new Vector3(0, 0, 0), 2)); Curve3D curve1 = CreateTestObject1MovementCurve(); float time = 0; bool progressTime = true; QuadTreeVisualizerXNA visualizer = new QuadTreeVisualizerXNA(); XNAGame game = new XNAGame(); game.UpdateEvent += delegate { if (game.Keyboard.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.P)) { progressTime = !progressTime; } if (progressTime) { time += game.Elapsed; } spheres[0].Move(root, curve1.Evaluate(time * (1 / 4f))); }; game.DrawEvent += delegate { for (int i = 0; i < spheres.Count; i++) { game.LineManager3D.AddCenteredBox(spheres[i].Center, spheres[i].Radius, Color.Red); } visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Green; return(node.DynamicObjectsCount == 0 && !node.PhysicsEnabled); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Red; return(node.DynamicObjectsCount == 0 && node.PhysicsEnabled); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Yellow; if (node.DynamicObjectsCount == 1) { col = Color.Orange; } return(node.DynamicObjectsCount > 0); }); visualizer.RenderNodeGroundBoundig(game, root, delegate(ClientPhysicsQuadTreeNode node, out Color col) { col = Color.Purple; return(node.DynamicObjectsCount < 0); }); }; game.Run(); }