Exemple #1
0
        /// <summary>
        /// Add this node to the terrain's batch.
        /// </summary>
        /// <param name="fullyContained">Whether this node is known to be fully contained within the clipping frustums, in which case it and its children do not need to check clipping against it.</param>
        /// <param name="viewPoint">The position that this node is being viewed from.</param>
        /// <param name="distance">Equal to the distance from the <paramref name="viewPoint"/> to the nearest point on this node. This is needed by parent nodes for sorting, so it is calculated there and then passed down.</param>
        public void Batch(bool fullyContained, ref Vector3d viewPoint, double distance)
        {
            if (!CheckClip(ref fullyContained))
            {
                return;
            }

            double lodBlend = LodBlend(distance);

            if (lodBlend >= 1 && !IsLeaf)
            {
                TerrainTreeNode a = ChildTopLeft, b = ChildTopRight, c = ChildBottomLeft, d = ChildBottomRight;
                double          ad = ChildTopLeft.DistanceTo(ref viewPoint);
                double          bd = ChildTopRight.DistanceTo(ref viewPoint);
                double          cd = ChildBottomLeft.DistanceTo(ref viewPoint);
                double          dd = ChildBottomRight.DistanceTo(ref viewPoint);

                SortByDepth(ref ad, ref bd, ref cd, ref dd, ref a, ref b, ref c, ref d);

                a.Batch(fullyContained, ref viewPoint, ad);
                b.Batch(fullyContained, ref viewPoint, bd);
                c.Batch(fullyContained, ref viewPoint, cd);
                d.Batch(fullyContained, ref viewPoint, dd);
                return;
            }

            Terrain.AddInstanceArray(TexelCorner.X, TexelCorner.Y, Lod + lodBlend, TexelSize);
        }
        internal PlanarTerrainBlock(PlanarTerrain terrain, Vector2i blockIndex)
        {
            this.terrain    = terrain;
            this.blockIndex = blockIndex;

            int size = terrain.BlockSize;

            //heightTexture = new Texture2D(device, size, size, true, Format.Single, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);
            //heightBackBuffer = new Texture2D(device, size, size, true, Format.Single, DepthFormat.None, 0, RenderTargetUsage.PlatformContents);

            treeRoot      = new TerrainTreeNode(this, new Vector2i(0, 0), size, terrain.DeepestLod);
            DirtyTreeArea = new Box2i(0, 0, size, size);
        }
Exemple #3
0
        /// <summary>
        /// Generate the tree node.
        /// </summary>
        /// <param name="terrainBlock">The terrain this is a node within.</param>
        /// <param name="corner">The integer coordinates of the top-left corner of the tree node.</param>
        /// <param name="size">The size in cells of this tree node.</param>
        /// <param name="lod">The level of detail of this node. This decreases for each step down into the terrain until it reaches zero.</param>
        public TerrainTreeNode(PlanarTerrainBlock terrainBlock, Vector2i corner, int size, int lod)
        {
            if (size < TerrainBlockSize)
            {
                throw new Exception("Invalid terrain size - must be a power of 2 greater than " + TerrainBlockSize + ".");
            }

            this.terrainBlock = terrainBlock;
            pLod          = lod;
            pTexelCorner  = new Vector2d(corner.X, corner.Y) / Terrain.BlockSize;
            pTexelSize    = size / (double)Terrain.BlockSize;
            pBox.Min      = new Vector3d(corner.X, 0, corner.Y);
            pBox.Max      = new Vector3d(corner.X + size, 0, corner.Y + size);
            pVertexCorner = new Vector2i(corner.X / TerrainBlockSize, corner.Y / TerrainBlockSize);

            if (size > TerrainBlockSize)
            {
                var hsize = size / 2;
                pChildTopLeft     = new TerrainTreeNode(terrainBlock, corner, hsize, lod - 1);
                pChildTopRight    = new TerrainTreeNode(terrainBlock, new Vector2i(corner.X + hsize, corner.Y), hsize, lod - 1);
                pChildBottomLeft  = new TerrainTreeNode(terrainBlock, new Vector2i(corner.X, corner.Y + hsize), hsize, lod - 1);
                pChildBottomRight = new TerrainTreeNode(terrainBlock, new Vector2i(corner.X + hsize, corner.Y + hsize), hsize, lod - 1);
            }
        }
Exemple #4
0
 /// <summary>
 /// Return how much to blend between this LOD level and the next less detailed one.
 /// If this returns 1, then the node should be divided if possible.
 /// </summary>
 /// <param name="node"></param>
 /// <param name="distance"></param>
 /// <returns></returns>
 public virtual double NodeLodBlend(TerrainTreeNode node, double distance)
 {
     throw new NotImplementedException();
 }
Exemple #5
0
 /// <summary>
 /// Return whether the node is contained in this module's clipping range.
 /// If this returns <see cref="Containment.Contains"/>, then any node with a smaller
 /// box must also be contained.
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public virtual Containment NodeClip(TerrainTreeNode node)
 {
     throw new NotImplementedException();
 }
Exemple #6
0
        /// <summary>Sort the parameters so that smaller values are first. <paramref name="ad"/> is paired to <paramref name="a"/> and so on.</summary>
        static void SortByDepth(ref double ad, ref double bd, ref double cd, ref double dd, ref TerrainTreeNode a, ref TerrainTreeNode b, ref TerrainTreeNode c, ref TerrainTreeNode d)
        {
            if (bd < ad && bd < cd && bd < dd)
            {
                Extensions.Swap(ref ad, ref bd);
                Extensions.Swap(ref a, ref b);
            }
            else if (cd < ad && cd < bd && cd < dd)
            {
                Extensions.Swap(ref ad, ref cd);
                Extensions.Swap(ref a, ref c);
            }
            else if (dd < ad && dd < bd && dd < cd)
            {
                Extensions.Swap(ref ad, ref dd);
                Extensions.Swap(ref a, ref d);
            }

            if (cd < bd && cd < dd)
            {
                Extensions.Swap(ref bd, ref cd);
                Extensions.Swap(ref b, ref c);
            }
            else if (dd < bd && dd < cd)
            {
                Extensions.Swap(ref bd, ref dd);
                Extensions.Swap(ref b, ref d);
            }

            if (cd < dd)
            {
                Extensions.Swap(ref cd, ref dd);
                Extensions.Swap(ref c, ref d);
            }
        }