public HeightField(Tile t)
            : base()
        {
            tile = t;

            Init(WorldManager.Instance.MetersPerSample(tile.Location));

            // generate the height map
            WorldManager.Instance.TerrainGenerator.GenerateHeightField(location, Size, metersPerSample,
                heightMap, out minHeight, out maxHeight);

            UpdateBounds();
        }
        /// <summary>
        /// Create a new heightField that is (equal or) lower LOD than the four sources,
        /// Height points are copied from the four sources.
        /// </summary>
        /// <param name="t"></param>
        /// <param name="srcNW"></param>
        /// <param name="srcNE"></param>
        /// <param name="srcSW"></param>
        /// <param name="srcSE"></param>
        public HeightField(Tile t, HeightField srcNW, HeightField srcNE, HeightField srcSW, HeightField srcSE )
            : base()
        {
            tile = t;

            Init(WorldManager.Instance.MetersPerSample(tile.Location));

            // copy from the source heightMap
            int halfSamples = numSamples/2;
            CopyHeightFieldScaleDown(srcSW.heightMap, metersPerSample / srcSW.metersPerSample, srcSW.numSamples, 0, halfSamples);
            CopyHeightFieldScaleDown(srcSE.heightMap, metersPerSample / srcSE.metersPerSample, srcSE.numSamples, halfSamples, halfSamples);
            CopyHeightFieldScaleDown(srcNW.heightMap, metersPerSample / srcNW.metersPerSample, srcNW.numSamples, 0, 0);
            CopyHeightFieldScaleDown(srcNE.heightMap, metersPerSample / srcNE.metersPerSample, srcNE.numSamples, halfSamples, 0);

            // update minHeight and maxHeight by taking the most extreme from the 4 sources.
            // this could result in a bounding box slightly larger than necessary, but its
            // not enough of an issue to warrant scanning the entire heightField looking for
            // the true min and max.
            minHeight = srcSW.minHeight;
            if ( srcSE.minHeight < minHeight )
            {
                minHeight = srcSE.minHeight;
            }
            if ( srcNW.minHeight < minHeight )
            {
                minHeight = srcNW.minHeight;
            }
            if ( srcNE.minHeight < minHeight )
            {
                minHeight = srcNE.minHeight;
            }

            maxHeight = srcSW.maxHeight;
            if ( srcSE.maxHeight > maxHeight )
            {
                maxHeight = srcSE.maxHeight;
            }
            if ( srcNW.maxHeight > maxHeight )
            {
                maxHeight = srcNW.maxHeight;
            }
            if ( srcNE.maxHeight > maxHeight )
            {
                maxHeight = srcNE.maxHeight;
            }
            UpdateBounds();
        }
Пример #3
0
        /// <summary>
        /// Page Constructor
        /// </summary>
        /// <param name="relativeLocation">The location of the page in world space, relative to the page containing the camera</param>
        /// <param name="indexX">index into the TerrainManager's page array</param>
        ///	<param name="indexZ">index into the TerrainManager's page array</param>
        public Page(Vector3 relativeLocation, int indexX, int indexZ)
        {
            size = TerrainManager.Instance.PageSize;
            this.relativeLocation = relativeLocation;
            this.indexX = indexX;
            this.indexZ = indexZ;

            // Figure out which page the camera is in
            PageCoord cameraPageCoord = new PageCoord(TerrainManager.Instance.VisPageRadius, TerrainManager.Instance.VisPageRadius);

            // compute the distance (in pages) from this page to the camera page
            pagesFromCamera = cameraPageCoord.Distance(new PageCoord(indexX, indexZ));

            // create a scene node for this page
            String nodeName = String.Format("Page[{0},{1}]", indexX, indexZ);
            sceneNode = TerrainManager.Instance.WorldRootSceneNode.CreateChildSceneNode(nodeName);

            sceneNode.Position = relativeLocation;

            // ask the world manager how many tiles we need in this page based on the distance from the camera
            numTiles = TerrainManager.Instance.TilesPerPage(pagesFromCamera);

            // compute size of a tile in sample space
            tileSize = size / numTiles;

            // allocate the array of tiles
            tiles = new Tile[numTiles,numTiles];

            // this is the size of the tile in "world space"
            float tileWorldSize = tileSize * TerrainManager.oneMeter;

            // create the tiles for this page
            for ( int tilex = 0; tilex < numTiles; tilex++ )
            {
                float tileWorldX = tilex * tileWorldSize + relativeLocation.x;

                for ( int tilez = 0; tilez < numTiles; tilez++ )
                {
                    float tileWorldZ = tilez * tileWorldSize + relativeLocation.z;

                    Tile t = new Tile(new Vector3(tileWorldX, 0, tileWorldZ), tileSize, this, tilex, tilez);
                    tiles[tilex, tilez] = t;
                }
            }
        }
        /// <summary>
        /// create a new heightField that has the same LOD as the source,
        /// and 1/4 the area of the source.  Height points are copied from one
        /// quadrant of the source.
        /// If the heightField needs to be higher LOD, it will be adjusted
        /// later and the required points will be generated.
        /// </summary>
        /// <param name="t"></param>
        /// <param name="src"></param>
        /// <param name="quad"></param>
        public HeightField(Tile t, HeightField src, Quadrant quad)
            : base()
        {
            tile = t;

            // in this case we will make the new heightField have the same LOD as
            // the source.  The LOD will be adjusted upward later if necessary.
            Init(src.metersPerSample);

            Debug.Assert((numSamples * metersPerSample * 2) == ( src.metersPerSample * src.numSamples), "creating heightfield from source that is not next lower LOD");

            int xoff = 0;
            int zoff = 0;

            switch ( quad )
            {
                case Quadrant.Northeast:
                    xoff = src.numSamples / 2;
                    zoff = 0;
                    break;
                case Quadrant.Northwest:
                    xoff = 0;
                    zoff = 0;
                    break;
                case Quadrant.Southeast:
                    xoff = src.numSamples / 2;
                    zoff = src.numSamples / 2;
                    break;
                case Quadrant.Southwest:
                    xoff = 0;
                    zoff = src.numSamples / 2;
                    break;
            }

            // copy from the source heightMap
            this.CopyHeightFieldScaleUp(src.heightMap, 1, xoff, zoff, src.numSamples);

            // compute the min and max extents of this heightField, since nobody else is
            // going to do it.
            // XXX - do we need to do this?
            minHeight = float.MaxValue;
            maxHeight = float.MinValue;
            foreach ( float h in heightMap )
            {
                if ( h < minHeight )
                {
                    minHeight = h;
                }
                if ( h > maxHeight )
                {
                    maxHeight = h;
                }
            }

            // generate the height points that were not filled in above
            //WorldManager.Instance.TerrainGenerator.GenerateHeightField(location, Size, metersPerSample,
            //	heightMap, out minHeight, out maxHeight, src.metersPerSample);

            UpdateBounds();
        }
Пример #5
0
        public void AttachNeighbors()
        {
            // Find Western neighbor
            if ( indexX == 0 )
            {
                Page nextPage = page.FindNeighbor(Direction.West);
                if ( nextPage == null )
                {
                    neighborWest1 = null;
                    neighborWest2 = null;
                }
                else
                {
                    if ( nextPage.NumTiles == page.NumTiles )
                    {
                        neighborWest1 = nextPage.LookupTile(nextPage.NumTiles - 1, indexZ);
                        neighborWest2 = null;
                    }
                    else if ( nextPage.NumTiles < page.NumTiles )
                    {
                        Debug.Assert(((nextPage.NumTiles * 2) == page.NumTiles), "Adjacent page numtiles not half");
                        neighborWest1 = nextPage.LookupTile(nextPage.NumTiles - 1, indexZ / 2);
                        neighborWest2 = null;
                    }
                    else
                    {
                        Debug.Assert((nextPage.NumTiles == ( page.NumTiles * 2)), "Adjacent page numtiles not double");
                        neighborWest1 = nextPage.LookupTile(nextPage.NumTiles - 1, indexZ * 2);
                        neighborWest2 = nextPage.LookupTile(nextPage.NumTiles - 1, ( indexZ * 2 ) + 1);
                    }
                }
            }
            else
            {
                neighborWest1 = page.LookupTile(indexX - 1, indexZ);
                neighborWest2 = null;
            }

            // Find Eastern neighbor
            if ( indexX == ( page.NumTiles - 1 ) )
            {
                Page nextPage = page.FindNeighbor(Direction.East);
                if ( nextPage == null )
                {
                    neighborEast1 = null;
                    neighborEast2 = null;
                }
                else
                {
                    if ( nextPage.NumTiles == page.NumTiles )
                    {
                        neighborEast1 = nextPage.LookupTile(0, indexZ);
                        neighborEast2 = null;
                    }
                    else if ( nextPage.NumTiles < page.NumTiles )
                    {
                        Debug.Assert(((nextPage.NumTiles * 2) == page.NumTiles), "Adjacent page numtiles not half");
                        neighborEast1 = nextPage.LookupTile(0, indexZ / 2);
                        neighborEast2 = null;
                    }
                    else
                    {
                        Debug.Assert((nextPage.NumTiles == ( page.NumTiles * 2)), "Adjacent page numtiles not double");
                        neighborEast1 = nextPage.LookupTile(0, indexZ * 2);
                        neighborEast2 = nextPage.LookupTile(0, ( indexZ * 2 ) + 1);
                    }
                }
            }
            else
            {
                neighborEast1 = page.LookupTile(indexX + 1, indexZ);
                neighborEast2 = null;
            }

            // Find Northern neighbor
            if ( indexZ == 0 )
            {
                Page nextPage = page.FindNeighbor(Direction.North);
                if ( nextPage == null )
                {
                    neighborNorth1 = null;
                    neighborNorth2 = null;
                }
                else
                {
                    if ( nextPage.NumTiles == page.NumTiles )
                    {
                        neighborNorth1 = nextPage.LookupTile(indexX, nextPage.NumTiles - 1);
                        neighborNorth2 = null;
                    }
                    else if ( nextPage.NumTiles < page.NumTiles )
                    {
                        Debug.Assert(((nextPage.NumTiles * 2) == page.NumTiles), "Adjacent page numtiles not half");
                        neighborNorth1 = nextPage.LookupTile(indexX / 2, nextPage.NumTiles - 1);
                        neighborNorth2 = null;
                    }
                    else
                    {
                        Debug.Assert((nextPage.NumTiles == ( page.NumTiles * 2)), "Adjacent page numtiles not double");
                        neighborNorth1 = nextPage.LookupTile(indexX * 2, nextPage.NumTiles - 1);
                        neighborNorth2 = nextPage.LookupTile( ( indexX * 2 ) + 1, nextPage.NumTiles - 1);
                    }
                }
            }
            else
            {
                neighborNorth1 = page.LookupTile(indexX, indexZ - 1);
                neighborNorth2 = null;
            }

            // Find Southern neighbor
            if ( indexZ == ( page.NumTiles - 1 ) )
            {
                Page nextPage = page.FindNeighbor(Direction.South);
                if ( nextPage == null )
                {
                    neighborSouth1 = null;
                    neighborSouth2 = null;
                }
                else
                {
                    if ( nextPage.NumTiles == page.NumTiles )
                    {
                        neighborSouth1 = nextPage.LookupTile(indexX, 0);
                        neighborSouth2 = null;
                    }
                    else if ( nextPage.NumTiles < page.NumTiles )
                    {
                        Debug.Assert(((nextPage.NumTiles * 2) == page.NumTiles), "Adjacent page numtiles not half");
                        neighborSouth1 = nextPage.LookupTile(indexX / 2, 0);
                        neighborSouth2 = null;
                    }
                    else
                    {
                        Debug.Assert((nextPage.NumTiles == ( page.NumTiles * 2)), "Adjacent page numtiles not double");
                        neighborSouth1 = nextPage.LookupTile(indexX * 2, 0);
                        neighborSouth2 = nextPage.LookupTile(( indexX * 2 ) + 1, 0);
                    }
                }
            }
            else
            {
                neighborSouth1 = page.LookupTile(indexX, indexZ + 1);
                neighborSouth2 = null;
            }
        }