示例#1
0
            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);
                }
            }