public void RemoveShip(SpaceShip ship) { if (ship.OctTreeNode == null) { return; } //// See if ship fits in current node //Vector3 shipCenter = ship.CollisionSphere.Center, nodeCenter = ship.OctTreeNode.Center; //float shipRadius = ship.CollisionSphere.Radius, nodeRadius = ship.OctTreeNode.HalfSize; //bool straddling = Math.Abs(nodeCenter.X) + nodeRadius < Math.Abs(shipCenter.X) + shipRadius // || Math.Abs(nodeCenter.Y) + nodeRadius < Math.Abs(shipCenter.Y) + shipRadius // || Math.Abs(nodeCenter.Z) + nodeRadius < Math.Abs(shipCenter.Z) + shipRadius; //////var delta = ship.CollisionSphere.Center - ship.OctTreeNode.Center; //////float radius = ship.CollisionSphere.Radius + ship.OctTreeNode.HalfSize; //////bool straddling = Math.Abs(delta.X) < radius ////// || Math.Abs(delta.Y) < radius ////// || Math.Abs(delta.Z) < radius; //var delta = ship.CollisionSphere.Center - ship.OctTreeNode.Center; //float distSquared = Vector3.Dot(delta, delta); //bool straddling = distSquared <= ship.CollisionSphere.Radius * ship.CollisionSphere.Radius; //if (!straddling && ship.OctTreeNode == _root) //{ // So many failed algorithms, ended up using none at all ='[ ship.OctTreeNode.Ships.Remove(ship.ShipNode); ship.OctTreeNode = null; //} }
public bool Collides(SpaceShip that) { // Avoid testing collsion against self if (this == that) { return(false); } // if we have collision on the sphere if (this.CollisionSphere.Intersects(that.CollisionSphere)) { CollisionSphere.Color = Color.Red.ToVector3(); //if sphear intersects show balls //run GJK on HULLs foreach (var thisHull in this.ShipHulls) { foreach (var thatHull in that.ShipHulls) { if (GJKAlgorithm.Process(thisHull, thatHull)) { this._collingMeshIndex = thisHull.IndexNo; that._collingMeshIndex = thatHull.IndexNo; this.Colored = true; that.Colored = true; return(true); } } } } return(false); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. _spriteBatch = new SpriteBatch(GraphicsDevice); _random = new Random(); // Camera _camera = new Camera(); // Outer bouding cube _boundinghCube = new BoundingCube(this, OuterBoundarySize); // Spaceships _spaceShips = new SpaceShip[NumberOfShips]; float shipSpacing = 0; for (int i = 0; i < NumberOfShips; i++) { Vector3 position = new Vector3( (i & 1) != 0 ? shipSpacing : -shipSpacing, (i & 2) != 0 ? shipSpacing : -shipSpacing, (i & 4) != 0 ? shipSpacing : -shipSpacing); _spaceShips[i] = new SpaceShip(this, position); if (i % 8 == 0) { shipSpacing += ShipSpacing; } } _octTree = new Octree(GraphicsDevice, OuterBoundarySize, _spaceShips); // Text that displays FPS on upper left coner _fpsFont = Content.Load <SpriteFont>("Models\\Font"); base.LoadContent(); }
public BoundingBall(CollisionDetection cd, Vector3[] vertices, SpaceShip ship) { _ship = ship; // Find the most separated point pair defining the encompassing AABB var mostDistantPoints = MostSeparatedPointsOnAABB(vertices); int min = mostDistantPoints.Item1, max = mostDistantPoints.Item2; // Set up sphere to just encompass these two points Center = (vertices[min] + vertices[max]) * 0.5f; Radius = (float)Math.Sqrt(Vector3.Dot(vertices[max] - Center, vertices[max] - Center)); // Grow sphere to include all points for (int i = 0; i < vertices.Length; i++) { SphereOfSphereAndPt(vertices[i]); } // Loading the sphere's model and saving the bone transform to make it easier to draw _model = cd.Content.Load <Model>("Models\\Sphere"); _transforms = new Matrix[_model.Bones.Count]; Center = _ship.Position; // Ship is slightly off center, but radius is good Color = Vector3.One; }
public void AddShip(SpaceShip ship) { _root.AddShip(ship, _root); }
internal void AddShip(SpaceShip ship, OctreeNode parent) { //// Wallace's hack: if center point of the node //// is contained in the sphere it will straddle with the children //// therefore we want to keep it on current node //var delta = ship.CollisionSphere.Center - this.Center; //float distSquared = Vector3.Dot(delta, delta); //bool straddling = distSquared <= ship.CollisionSphere.Radius * ship.CollisionSphere.Radius; var nodeTop = Math.Abs(this.Center.Y) + HalfSize; var nodeBottom = Math.Abs(this.Center.Y) - HalfSize; var nodeLeft = Math.Abs(this.Center.X) - HalfSize; var nodeRight = Math.Abs(this.Center.X) + HalfSize; var nodeFront = Math.Abs(this.Center.Z) + HalfSize; var nodeBack = Math.Abs(this.Center.Z) - HalfSize; var sphereTop = Math.Abs(ship.CollisionSphere.Center.Y) + ship.CollisionSphere.Radius; var sphereBottom = Math.Abs(ship.CollisionSphere.Center.Y) - ship.CollisionSphere.Radius; var sphereLeft = Math.Abs(ship.CollisionSphere.Center.X) - ship.CollisionSphere.Radius; var sphereRight = Math.Abs(ship.CollisionSphere.Center.X) + ship.CollisionSphere.Radius; var sphereFront = Math.Abs(ship.CollisionSphere.Center.Z) + ship.CollisionSphere.Radius; var sphereBack = Math.Abs(ship.CollisionSphere.Center.Z) - ship.CollisionSphere.Radius; bool straddles = sphereTop >= nodeTop || sphereBottom <= nodeBottom || sphereLeft <= nodeLeft || sphereRight >= nodeRight || sphereFront >= nodeFront || sphereBack <= nodeBack; //// Usefull for debug //_vertices[22] = new VertexPositionColor(ship.CollisionSphere.Center, Color.Black); //_vertices[23] = new VertexPositionColor(ship.CollisionSphere.Center + new Vector3(0, -ship.CollisionSphere.Radius, 0), Color.Black); //var center = Vector3.Transform(Center, //Matrix.CreateTranslation(ship.CollisionSphere.Center)); // Fully contained in existing child node; insert in that subtree if (!straddles && _depth > 0) { int childOctant = 0; var delta = ship.CollisionSphere.Center - this.Center; if (delta.X > 0.0f) { childOctant += 1; } if (delta.Y > 0.0f) { childOctant += 2; } if (delta.Z > 0.0f) { childOctant += 4; } Children[childOctant].AddShip(ship, this); } else if (straddles) // Straddles { ship.OctTreeNode = parent; ship.ShipNode = parent.Ships.AddLast(ship); } else // no children left { ship.OctTreeNode = this; ship.ShipNode = Ships.AddLast(ship); } }