/// <summary>
        ///		Intersection test with an <see cref="AxisAlignedBox"/>.
        /// </summary>
        /// <remarks>
        ///		May return false positives but will never miss an intersection.
        /// </remarks>
        /// <param name="box">Box to test.</param>
        /// <returns>True if interesecting, false otherwise.</returns>
        public bool Intersects(AxisAlignedBox box)
        {
            if(box.IsNull) {
                return false;
            }

            // If all points are on outside of any plane, we fail
            Vector3[] points = box.Corners;

            for (int i = 0; i < planes.Count; i++) {
                Plane plane = planes[i];

                // Test which side of the plane the corners are
                // Intersection fails when at all corners are on the
                // outside of one plane
                bool splittingPlane = true;
                for (int corner = 0; corner < 8; corner++) {
                    if (plane.GetSide(points[corner]) != outside) {
                        // this point is on the wrong side
                        splittingPlane = false;
                        break;
                    }
                }
                if (splittingPlane) {
                    // Found a splitting plane therefore return not intersecting
                    return false;
                }
            }

            // couldn't find a splitting plane, assume intersecting
            return true;
        }
        public OctreeSceneManager()
            : base("OcttreeSM")
        {
            Vector3 Min = new Vector3(-500f,-500f,-500f);
            Vector3 Max = new Vector3(500f,500f,500f);
            int depth = 5;

            AxisAlignedBox box = new AxisAlignedBox(Min, Max);

            Init(box, depth);
        }
 public Region(StaticGeometry parent, string name, SceneManager mgr, UInt32 regionID, Vector3 center)
 {
     this.parent = parent;
     this.name = name;
     this.sceneMgr = mgr;
     this.regionID = regionID;
     this.center = center;
     queuedSubMeshes = new List<QueuedSubMesh>();
     lodSquaredDistances = new List<float>();
     aabb = new AxisAlignedBox();
     lodBucketList = new List<LODBucket>();
     shadowRenderables = new ShadowRenderableList();
 }
        /// <summary>
        ///		Returns whether or not this box intersects another.
        /// </summary>
        /// <param name="box2"></param>
        /// <returns>True if the 2 boxes intersect, false otherwise.</returns>
        public bool Intersects(AxisAlignedBox box2)
        {
            // Early-fail for nulls
            if (this.IsNull || box2.IsNull)
            {
                return(false);
            }

            // Use up to 6 separating planes
            if (this.maxVector.x < box2.minVector.x)
            {
                return(false);
            }
            if (this.maxVector.y < box2.minVector.y)
            {
                return(false);
            }
            if (this.maxVector.z < box2.minVector.z)
            {
                return(false);
            }

            if (this.minVector.x > box2.maxVector.x)
            {
                return(false);
            }
            if (this.minVector.y > box2.maxVector.y)
            {
                return(false);
            }
            if (this.minVector.z > box2.maxVector.z)
            {
                return(false);
            }

            // otherwise, must be intersecting
            return(true);
        }
        /// <summary>
        ///		Intersection test with an <see cref="AxisAlignedBox"/>.
        /// </summary>
        /// <remarks>
        ///		May return false positives but will never miss an intersection.
        /// </remarks>
        /// <param name="box">Box to test.</param>
        /// <returns>True if interesecting, false otherwise.</returns>
        public bool Intersects(AxisAlignedBox box)
        {
            if (box.IsNull)
            {
                return(false);
            }

            // If all points are on outside of any plane, we fail
            Vector3[] points = box.Corners;

            for (int i = 0; i < planes.Count; i++)
            {
                Plane plane = planes[i];

                // Test which side of the plane the corners are
                // Intersection fails when at all corners are on the
                // outside of one plane
                bool splittingPlane = true;
                for (int corner = 0; corner < 8; corner++)
                {
                    if (plane.GetSide(points[corner]) != outside)
                    {
                        // this point is on the wrong side
                        splittingPlane = false;
                        break;
                    }
                }
                if (splittingPlane)
                {
                    // Found a splitting plane therefore return not intersecting
                    return(false);
                }
            }

            // couldn't find a splitting plane, assume intersecting
            return(true);
        }
        private void UpdateBounds()
        {
            // set bounding box
            box = new AxisAlignedBox(new Vector3(0 + offsetX, minHeight * yScale, 0 + offsetZ),
                new Vector3(width * xzScale + offsetX, maxHeight * yScale, height * xzScale + offsetZ));

            // set bounding sphere
            worldBoundingSphere.Center = box.Center;
            worldBoundingSphere.Radius = box.Maximum.Length;
        }
        /// <summary>
        ///    Tests an intersection between a ray and a box.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="box"></param>
        /// <returns>A Pair object containing whether the intersection occurred, and the distance between the 2 objects.</returns>
        public static IntersectResult Intersects(Ray ray, AxisAlignedBox box)
        {
            if (box.IsNull)
            {
                return(new IntersectResult(false, 0));
            }

            float   lowt = 0.0f;
            float   t;
            bool    hit = false;
            Vector3 hitPoint;
            Vector3 min = box.Minimum;
            Vector3 max = box.Maximum;

            // check origin inside first
            if (ray.origin > min && ray.origin < max)
            {
                return(new IntersectResult(true, 0.0f));
            }

            // check each face in turn, only check closest 3

            // Min X
            if (ray.origin.x < min.x && ray.direction.x > 0)
            {
                t = (min.x - ray.origin.x) / ray.direction.x;

                if (t > 0)
                {
                    // substitue t back into ray and check bounds and distance
                    hitPoint = ray.origin + ray.direction * t;

                    if (hitPoint.y >= min.y && hitPoint.y <= max.y &&
                        hitPoint.z >= min.z && hitPoint.z <= max.z &&
                        (!hit || t < lowt))
                    {
                        hit  = true;
                        lowt = t;
                    }
                }
            }

            // Max X
            if (ray.origin.x > max.x && ray.direction.x < 0)
            {
                t = (max.x - ray.origin.x) / ray.direction.x;

                if (t > 0)
                {
                    // substitue t back into ray and check bounds and distance
                    hitPoint = ray.origin + ray.direction * t;

                    if (hitPoint.y >= min.y && hitPoint.y <= max.y &&
                        hitPoint.z >= min.z && hitPoint.z <= max.z &&
                        (!hit || t < lowt))
                    {
                        hit  = true;
                        lowt = t;
                    }
                }
            }

            // Min Y
            if (ray.origin.y < min.y && ray.direction.y > 0)
            {
                t = (min.y - ray.origin.y) / ray.direction.y;

                if (t > 0)
                {
                    // substitue t back into ray and check bounds and distance
                    hitPoint = ray.origin + ray.direction * t;

                    if (hitPoint.x >= min.x && hitPoint.x <= max.x &&
                        hitPoint.z >= min.z && hitPoint.z <= max.z &&
                        (!hit || t < lowt))
                    {
                        hit  = true;
                        lowt = t;
                    }
                }
            }

            // Max Y
            if (ray.origin.y > max.y && ray.direction.y < 0)
            {
                t = (max.y - ray.origin.y) / ray.direction.y;

                if (t > 0)
                {
                    // substitue t back into ray and check bounds and distance
                    hitPoint = ray.origin + ray.direction * t;

                    if (hitPoint.x >= min.x && hitPoint.x <= max.x &&
                        hitPoint.z >= min.z && hitPoint.z <= max.z &&
                        (!hit || t < lowt))
                    {
                        hit  = true;
                        lowt = t;
                    }
                }
            }

            // Min Z
            if (ray.origin.z < min.z && ray.direction.z > 0)
            {
                t = (min.z - ray.origin.z) / ray.direction.z;

                if (t > 0)
                {
                    // substitue t back into ray and check bounds and distance
                    hitPoint = ray.origin + ray.direction * t;

                    if (hitPoint.x >= min.x && hitPoint.x <= max.x &&
                        hitPoint.y >= min.y && hitPoint.y <= max.y &&
                        (!hit || t < lowt))
                    {
                        hit  = true;
                        lowt = t;
                    }
                }
            }

            // Max Z
            if (ray.origin.z > max.z && ray.direction.z < 0)
            {
                t = (max.z - ray.origin.z) / ray.direction.z;

                if (t > 0)
                {
                    // substitue t back into ray and check bounds and distance
                    hitPoint = ray.origin + ray.direction * t;

                    if (hitPoint.x >= min.x && hitPoint.x <= max.x &&
                        hitPoint.y >= min.y && hitPoint.y <= max.y &&
                        (!hit || t < lowt))
                    {
                        hit  = true;
                        lowt = t;
                    }
                }
            }

            return(new IntersectResult(hit, lowt));
        }
Example #8
0
        public Tile()
        {
            info = new TileInfo();
            tileSceneNode = null;
            renderable = null;
            init = false;
            loaded = false;

            bounds = new AxisAlignedBox();
            boundsExt = new AxisAlignedBox();
            //worldBounds = new AxisAlignedBox();
            neighbors = new Tile[4];
        }
        private void UpdateBounds()
        {
            float minHeight;
            float maxHeight;

            // update heights from the heightmaps
            pageHeightMap.GetSubPageHeightBounds(0, 0, TerrainManager.Instance.PageSize, TerrainManager.Instance.PageSize, out minHeight, out maxHeight);

            // set bounding box
            box = new AxisAlignedBox(new Vector3(0, minHeight, 0),
                new Vector3(TerrainManager.Instance.PageSize * TerrainManager.oneMeter, maxHeight, TerrainManager.Instance.PageSize * TerrainManager.oneMeter));

            // set bounding sphere
            worldBoundingSphere.Center = box.Center;
            worldBoundingSphere.Radius = box.Maximum.Length;
        }
Example #10
0
        public Page(long TableX, long TableZ)
        {
            isLoaded = false;
            isPreLoaded = false;

            tableX = TableX;
            tableZ = TableZ;

            numTiles = (long) ((float) Options.Instance.PageSize / Options.Instance.TileSize);
            pageNode = null;

            long size = Options.Instance.PageSize - 1;
            // Boundaries of this page
            // the middle page is at world coordinates 0,0
            float factorX = size * Options.Instance.Scale.x;
            float factorZ = size * Options.Instance.Scale.z;
            iniX =  (tableX + tableX - Options.Instance.World_Width) / 2.0f * factorX ;
            iniZ =  (tableZ + tableZ - Options.Instance.World_Height) / 2.0f * factorZ ;
            float EndX = iniX + factorX;
            float EndZ = iniZ + factorZ;
            float MaxHeight = Data2DManager.Instance.GetMaxHeight(tableX, tableZ);
            float chgfactor = Options.Instance.Change_Factor;
            boundsExt = new AxisAlignedBox();
            boundsExt.SetExtents( new Vector3(( float )( iniX ),
                                    0,
                                ( float )( iniZ )),
                                new Vector3(( float )( EndX ),
                                MaxHeight,
                                ( float )( EndZ ) ));
            //Change Zone of this page
            boundsInt = new AxisAlignedBox();
            boundsInt.SetExtents( new Vector3(( float )( iniX + chgfactor ),
                                    0,
                                ( float )( iniZ + chgfactor )),
                                new Vector3(( float )( EndX - chgfactor ),
                                    MaxHeight,
                                    ( float )( EndZ - chgfactor )	));

            neighbors = new Page[4];
            for ( long i = 0; i < 4; i++ )
            {
                neighbors[ i ] = null;
            }
        }
 public OctreeSceneManager(string name, AxisAlignedBox box, int max_depth)
     : base(name)
 {
     Init(box, max_depth);
 }
        /*public void AddOctreeNode(OctreeNode node, Octree octree)
        {

        }*/
        /** Resizes the octree to the given size */
        public void Resize(AxisAlignedBox box)
        {
            List<SceneNode> nodes = new List<SceneNode>();

            FindNodes(this.octree.Box, nodes, null, true, this.octree);

            octree = new Octree(null);
            octree.Box = box;

            foreach (OctreeNode node in nodes) {
                node.Octant = null;
                UpdateOctreeNode(node);
            }
        }
        public MovableObject(string name)
        {
            this.Name = name;

            isVisible = true;
            // set default RenderQueueGroupID for this movable object
            renderQueueID = RenderQueueGroupID.Main;
            queryFlags = unchecked(0xffffffff);
            worldAABB = AxisAlignedBox.Null;
            castShadows = true;
        }
 public void FindObstaclesInBox(AxisAlignedBox box, 
                                CollisionTileManager.AddTreeObstaclesCallback callback)
 {
     foreach ( Boundary boundary in boundaries )
     {
         boundary.FindObstaclesInBox(box, callback);
     }
 }
        /// <summary>
        ///		Allows for merging two boxes together (combining).
        /// </summary>
        /// <param name="box">Source box.</param>
        public void Merge(AxisAlignedBox box)
        {
            // nothing to merge with in this case, just return
            if(box.IsNull) {
                return;
            }
            else if (isNull) {
                SetExtents(box.Minimum, box.Maximum);
            }
            else {
                Vector3 min = minVector;
                Vector3 max = maxVector;
                min.Floor(box.Minimum);
                max.Ceil(box.Maximum);

                SetExtents(min, max);
            }
        }
        /// <summary>
        ///		Returns whether or not this box intersects another.
        /// </summary>
        /// <param name="box2"></param>
        /// <returns>True if the 2 boxes intersect, false otherwise.</returns>
        public bool Intersects(AxisAlignedBox box2)
        {
            // Early-fail for nulls
            if (this.IsNull || box2.IsNull)
                return false;

            // Use up to 6 separating planes
            if (this.maxVector.x < box2.minVector.x)
                return false;
            if (this.maxVector.y < box2.minVector.y)
                return false;
            if (this.maxVector.z < box2.minVector.z)
                return false;

            if (this.minVector.x > box2.maxVector.x)
                return false;
            if (this.minVector.y > box2.maxVector.y)
                return false;
            if (this.minVector.z > box2.maxVector.z)
                return false;

            // otherwise, must be intersecting
            return true;
        }
Example #17
0
 /// <summary>
 ///		Returns whether or not this sphere interects a box.
 /// </summary>
 /// <param name="box"></param>
 /// <returns>True if the box intersects, false otherwise.</returns>
 public bool Intersects(AxisAlignedBox box)
 {
     return(MathUtil.Intersects(this, box));
 }
        /// <summary>
        ///		
        /// </summary>
        /// <param name="light"></param>
        /// <param name="extrusionDistance"></param>
        /// <returns></returns>
        public override AxisAlignedBox GetDarkCapBounds(Light light, float extrusionDistance)
        {
            // Extrude own light cap bounds
            // need a clone to avoid modifying the original bounding box
            worldDarkCapBounds = (AxisAlignedBox)GetLightCapBounds().Clone();

            ExtrudeBounds(worldDarkCapBounds, light.GetAs4DVector(), extrusionDistance);

            return worldDarkCapBounds;
        }
        public Intersection Intersect(Sphere sphere, AxisAlignedBox box)
        {
            intersect++;
            float Radius = sphere.Radius;
            Vector3 Center = sphere.Center;
            Vector3[] Corners = box.Corners;
            float s = 0;
            float d = 0;
            int i;
            bool Partial;

            Radius *= Radius;

            Vector3 MinDistance = (Corners[0] - Center);
            Vector3 MaxDistance = (Corners[4] - Center);

            if((MinDistance.LengthSquared < Radius) && (MaxDistance.LengthSquared < Radius)) {
                return Intersection.Inside;
            }

            //find the square of the distance
            //from the sphere to the box
            for(i=0;i<3;i++) {
                if ( Center[i] < Corners[0][i] ) {
                    s = Center[i] - Corners[0][i];
                    d += s * s;
                }

                else if ( Center[i] > Corners[4][i] ) {
                    s = Center[i] - Corners[4][i];
                    d += s * s;
                }
            }

            Partial = (d <= Radius);

            if(!Partial) {
                return Intersection.Outside;
            }
            else {
                return Intersection.Intersect;
            }
        }
        /// <summary>
        ///    Retrieves the axis-aligned bounding box for this object in world coordinates.
        /// </summary>
        /// <returns></returns>
        public override AxisAlignedBox GetWorldBoundingBox(bool derive)
        {
            if(derive && this.BoundingBox != null) {
                worldAABB = this.BoundingBox;
                worldAABB.Transform(this.ParentFullTransform);
                ComputeContainedWorldAABBs();
            }

            return worldAABB;
        }
        /// <summary>
        ///		Calculate the area of intersection of this box and another
        /// </summary>
        public AxisAlignedBox Intersection(AxisAlignedBox b2)
        {
            if (!Intersects(b2))
            {
                return(new AxisAlignedBox());
            }
            Vector3 intMin = Vector3.Zero;
            Vector3 intMax = Vector3.Zero;

            Vector3 b2max = b2.maxVector;
            Vector3 b2min = b2.minVector;

            if (b2max.x > maxVector.x && maxVector.x > b2min.x)
            {
                intMax.x = maxVector.x;
            }
            else
            {
                intMax.x = b2max.x;
            }
            if (b2max.y > maxVector.y && maxVector.y > b2min.y)
            {
                intMax.y = maxVector.y;
            }
            else
            {
                intMax.y = b2max.y;
            }
            if (b2max.z > maxVector.z && maxVector.z > b2min.z)
            {
                intMax.z = maxVector.z;
            }
            else
            {
                intMax.z = b2max.z;
            }

            if (b2min.x < minVector.x && minVector.x < b2max.x)
            {
                intMin.x = minVector.x;
            }
            else
            {
                intMin.x = b2min.x;
            }
            if (b2min.y < minVector.y && minVector.y < b2max.y)
            {
                intMin.y = minVector.y;
            }
            else
            {
                intMin.y = b2min.y;
            }
            if (b2min.z < minVector.z && minVector.z < b2max.z)
            {
                intMin.z = minVector.z;
            }
            else
            {
                intMin.z = b2min.z;
            }

            return(new AxisAlignedBox(intMin, intMax));
        }
        // This is the principle interface to the upper levels of the
        // // client.  When the client realizes that the center of the
        // // collision visibility circle has changed, it calls
        // SetCollisionArea // to let us know.
        //
        // Nearly always the collisionHorizon is the same as the original
        // collisionHorizon.  If it's not, we flush all collision counts and
        // rebuild everything.
        public void SetCollisionArea(Vector3 newTileWorldCenterValue, float newCollisionHorizon)
        {
            newTileWorldCenter = newTileWorldCenterValue;
            WorldToTileCoords(newTileWorldCenter, out newTileXCenter, out newTileZCenter);
            if (tiles == null || Math.Abs(newCollisionHorizon - collisionHorizon) > .0001) {
                // We need to start from scratch again
                if (MO.DoLog)
                    MO.Log("Horizon changed; flushing everything");
                FlushAllCollisionCounts();
                InitializeBasedOnCollisionHorizon(newCollisionHorizon);
            }
            else {

                if (newTileXCenter == tileXCenter && newTileZCenter == tileZCenter) {
                    // the tile center didn't change, so there is nothing
                    // to do put set the world center
                    tileWorldCenter = newTileWorldCenter;
                    return;
                }
                else {
                    if (MO.DoLog) {
                        MO.Log(string.Format("old center {0}[{1},{2}], new center {3}[{4},{5}], old horizon {6}, new horizon {7}",
                                             MO.MeterString(tileWorldCenter), tileXCenter, tileZCenter,
                                             MO.MeterString(newTileWorldCenter), newTileXCenter, newTileZCenter,
                                             MO.MeterString(collisionHorizon), MO.MeterString(newCollisionHorizon)));
                    }
                    ShiftTileArrayToNewCenter();
                }
            }
            // Now ask the WorldManager to iterate over boundary
            // objects, passing a box representing the world coords of
            // the new bounds of the entire tile array, and a callback
            // to actually add the objects

            // Choose a bound that is guaranteed to cover all the
            // trees in the tile array
            float bound = 2 * tileSize + collisionHorizon;
            Vector3 d = new Vector3(bound, 0.0f, bound);
            Vector3 min = newTileWorldCenter - d;
            Vector3 max = newTileWorldCenter + d;
            // Make the range of Y "infinitely" large
            min.y -= 10000.0f * MO.Meter;
            max.y += 10000.0f * MO.Meter;
            AxisAlignedBox b = new AxisAlignedBox(min, max);
            if (MO.DoLog)
                MO.Log(string.Format("Searching for obstacles in box min = {0}, max = {1}",
                                     MO.MeterString(min), MO.MeterString(max)));
            ObstacleFinder(b, AddTreeObstacles);

            // Finally, update the tileWorldCenter
            tileWorldCenter = newTileWorldCenter;
            tileXCenter = newTileXCenter;
            tileZCenter = newTileZCenter;
        }
Example #23
0
 /// Gets all the patches within an AABB in world coordinates as GeometryData structs
 public virtual void GetRenderOpsInBox( AxisAlignedBox box, ArrayList opList)
 {
     if ( MathUtil.Intersects(box, boundsExt ) != Intersection.None )
     {
         for ( long i = 0; i < numTiles; i++ )
         {
             for ( long j = 0; j < numTiles; j++ )
             {
                 tiles[ i ][ j].GetRenderOpsInBox( box, opList );
             }
         }
     }
 }
        /// <summary>
        ///		Sets the corners of the rectangle, in relative coordinates.
        /// </summary>
        /// <param name="left">Left position in screen relative coordinates, -1 = left edge, 1.0 = right edge.</param>
        /// <param name="top">Top position in screen relative coordinates, 1 = top edge, -1 = bottom edge.</param>
        /// <param name="right">Position in screen relative coordinates.</param>
        /// <param name="bottom">Position in screen relative coordinates.</param>
        public void SetCorners(float left, float top, float right, float bottom)
        {
            float[] data = new float[] {
                left, top, -1,
                left, bottom, -1,
                right, top, -1,
                right, bottom, -1
            };

            HardwareVertexBuffer buffer =
                vertexData.vertexBufferBinding.GetBuffer(POSITION);

            buffer.WriteData(0, buffer.Size, data, true);

            box = new AxisAlignedBox();
            box.SetExtents(new Vector3(left, top, 0), new Vector3(right, bottom, 0));
        }
 public WidgetSceneObject()
 {
     boundingBox = new AxisAlignedBox();
     boundingBox.IsNull = false;
 }
        private void ComputeBounds()
        {
            float minX = Single.MaxValue;
            float maxX = Single.MinValue;
            float minZ = Single.MaxValue;
            float maxZ = Single.MinValue;
            
            foreach (Vector2 point in points)
            {
                if (point.x > maxX)
                {
                    maxX = point.x;
                }
                if (point.x < minX)
                {
                    minX = point.x;
                }
                if (point.y > maxZ)
                {
                    maxZ = point.y;
                }
                if (point.y < minZ)
                {
                    minZ = point.y;
                }
            }

            bounds = new AxisAlignedBox(new Vector3(minX, 0, minZ), new Vector3(maxX, 0, maxZ));
        }
Example #27
0
 /// Gets all the patches within an AABB in world coordinates as GeometryData structs
 public virtual void GetRenderOpsInBox( AxisAlignedBox box, ArrayList opList)
 {
     if ( MathUtil.Intersects(box, bounds ) != Intersection.None )
     {
         RenderOperation rend = new RenderOperation();
         renderable.GetRenderOperation( rend );
         opList.Add( rend );
     }
 }
        public List<Triangle> Clip(AxisAlignedBox box)
        {
            Debug.Assert(closed, "Boundary not closed");
            // XXX

            return null;
        }
        protected void SetBounds(AxisAlignedBox box, float radius)
	    {
    		aab = box;
	    	boundingRadius = radius;
	    }
Example #30
0
 /// <summary>
 ///    Tests whether this ray intersects the given box.
 /// </summary>
 /// <param name="box"></param>
 /// <returns>
 ///		Struct containing info on whether there was a hit, and the distance from the
 ///		origin of this ray where the intersect happened.
 ///	</returns>
 public IntersectResult Intersects(AxisAlignedBox box)
 {
     return(MathUtil.Intersects(this, box));
 }
 private void UnClose()
 {
     touchedPages.Clear();
     tris = null;
     bounds = null;
     closed = false;
 }
        public void FindNodes(AxisAlignedBox box, List<SceneNode> sceneNodeList, SceneNode exclude, bool full, Octree octant)
        {
            System.Collections.ArrayList localList = new System.Collections.ArrayList();
            if(octant == null) {
                octant = this.octree;
            }

            if(!full) {
                AxisAlignedBox obox = octant.CullBounds;

                Intersection isect = this.Intersect(box,obox);

                if(isect == Intersection.Outside) {
                    return;
                }

                full = (isect == Intersection.Inside);
            }

            for(int i=0;i<octant.NodeList.Count;i++) {
                OctreeNode node = (OctreeNode)octant.NodeList[i];

                if(node != exclude) {
                    if(full) {
                        localList.Add(node);
                    }
                    else {
                        Intersection nsect = this.Intersect(box,node.WorldAABB);

                        if(nsect != Intersection.Outside) {
                            localList.Add(node);
                        }
                    }
                }
            }

            if ( octant.Children[0,0,0] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[0,0,0]);

            if ( octant.Children[1,0,0] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[1,0,0]);

            if ( octant.Children[0,1,0] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[0,1,0] );

            if ( octant.Children[1,1,0] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[1,1,0]);

            if ( octant.Children[0,0,1] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[0,0,1]);

            if ( octant.Children[1,0,1] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[1,0,1]);

            if ( octant.Children[0,1,1] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[0,1,1]);

            if ( octant.Children[1,1,1] != null ) FindNodes( box, sceneNodeList, exclude, full, octant.Children[1,1,1]);
        }
 public void FindObstaclesInBox(AxisAlignedBox box, 
                                CollisionTileManager.AddTreeObstaclesCallback callback)
 {
     Debug.Assert(bounds != null, "When calling FindObstaclesInBox, bounds must be non-null");
     if (bounds.Intersects(box)) {
         foreach (IBoundarySemantic semantic in semantics) {
             Forest f = semantic as Forest;
             if (f != null) {
                 f.FindObstaclesInBox(box, callback);
             }
         }
     }
 }
        public void Init(AxisAlignedBox box, int depth)
        {
            rootSceneNode = new OctreeNode(this, "SceneRoot");

            maxDepth = depth;

            octree = new Octree(null);

            octree.Box = box;

            Vector3 Min = box.Minimum;
            Vector3 Max = box.Maximum;

            octree.HalfSize = (Max - Min) / 2;

            numObjects = 0;

            Vector3 scalar = new Vector3(1.5f,1.5f,1.5f);

            scaleFactor.Scale = scalar;
        }
        public bool RayIntersection(Ray ray, out int x, out int z)
        {
            // generate a bounding box for the heightmap in its local space
            AxisAlignedBox axisAlignedBox = new AxisAlignedBox(new Vector3(0, minHeight, 0),
                    new Vector3(width, maxHeight, height));

            Vector3 rayLoc = new Vector3((ray.Origin.x - offsetX) / xzScale,
                                        ray.Origin.y / yScale,
                                        (ray.Origin.z - offsetZ) / xzScale);

            Vector3 rayDir = new Vector3(ray.Direction.x / xzScale, ray.Direction.y / yScale, ray.Direction.z / xzScale);
            rayDir.Normalize();

            // convert the ray to local heightmap space
            Ray tmpRay = new Ray(rayLoc, rayDir);

            // see if the ray intersects with the bounding box
            IntersectResult result = tmpRay.Intersects(axisAlignedBox);

            if (result.Hit)
            {
                // move rayLoc up to just before the point of intersection
                rayLoc = rayLoc + rayDir * ( result.Distance - 1 );

                //
                // deal with edge case where ray is coming from outside the heightmap
                // and is very near edge of map at intersection.
                //
                int insideCounter = 20;
                while ((!Inside(rayLoc)) && (insideCounter > 0))
                {
                    rayLoc += ( rayDir * 0.1f );
                    insideCounter--;
                }
                if (insideCounter == 0)
                {
                    x = 0;
                    z = 0;
                    return false;
                }

                x = (int)Math.Round(rayLoc.x);
                z = (int)Math.Round(rayLoc.z);

                if (x < 0)
                {
                    x = 0;
                }
                if (x >= width)
                {
                    x = width - 1;
                }
                if (z < 0)
                {
                    z = 0;
                }
                if (z >= height)
                {
                    z = height - 1;
                }

                bool above = rayLoc.y > heightData[x + z * width];

                while (Inside(rayLoc))
                {
                    // increment the ray
                    rayLoc += rayDir;

                    x = (int)Math.Round(rayLoc.x);
                    z = (int)Math.Round(rayLoc.z);

                    if (x < 0)
                    {
                        x = 0;
                    }
                    if (x >= width)
                    {
                        x = width - 1;
                    }
                    if (z < 0)
                    {
                        z = 0;
                    }
                    if (z >= height)
                    {
                        z = height - 1;
                    }

                    if (above != (rayLoc.y > heightData[x + z * width]))
                    {
                        // we found a hit
                        return true;
                    }
                }
            }
            x = 0;
            z = 0;
            return false;
        }
        public Intersection Intersect(AxisAlignedBox box1, AxisAlignedBox box2)
        {
            intersect++;
            Vector3[] outside = box1.Corners;
            Vector3[] inside = box2.Corners;

            if(inside[4].x < outside[0].x ||
                inside[4].y < outside[0].y ||
                inside[4].z < outside[0].z ||
                inside[0].x > outside[4].x ||
                inside[0].y > outside[4].y ||
                inside[0].z > outside[4].z ) {

                return Intersection.Outside;
            }

            if(inside[0].x > outside[0].x &&
                inside[0].y > outside[0].y &&
                inside[0].z > outside[0].z &&
                inside[4].x < outside[4].x &&
                inside[4].y < outside[4].y &&
                inside[4].z < outside[4].z ) {

                return Intersection.Inside;
            }
            else {
                return Intersection.Intersect;
            }
        }