Ejemplo n.º 1
0
        /// <summary>
        /// Updates the internal quadtree to make it identical to the given terrain quadtree.
        /// Collects the tasks necessary to create the missing texture tiles, corresponding to newly created quads.
        /// </summary>
        /// <param name="parent">Parent quadtree.</param>
        /// <param name="tree">Internal quadtree.</param>
        /// <param name="quad">Quad.</param>
        protected virtual void GetTiles(QuadTree parent, ref QuadTree tree, TerrainQuad quad)
        {
            // If tree not created, create a new tree and check if its tile is needed
            if (tree == null)
            {
                tree            = new QuadTree(parent);
                tree.IsNeedTile = NeedTile(quad);
            }

            // If this trees tile is needed get a tile and add its task to the schedular if the task is not already done
            if (tree.IsNeedTile && tree.Tile == null)
            {
                tree.Tile = Producer.GetTile(quad.Level, quad.Tx, quad.Ty);

                if (!tree.Tile.Task.IsDone)
                {
                    // If task not done schedule task
                    Schedular.Instance.Add(tree.Tile.Task);
                }
            }

            if (!quad.IsLeaf && Producer.HasChildren(quad.Level, quad.Tx, quad.Ty))
            {
                for (byte i = 0; i < 4; ++i)
                {
                    GetTiles(tree, ref tree.Children[i], quad.GetChild(i));
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Updates the internal quadtree to make it identical to the given terrain quadtree.
        /// This method releases the texture tiles corresponding to deleted quads.
        /// </summary>
        /// <param name="tree">Internal quadtree.</param>
        /// <param name="quad">Quad.</param>
        protected virtual void PutTiles(QuadTree tree, TerrainQuad quad)
        {
            if (tree == null)
            {
                return;
            }

            // Check if this tile is needed, if not put tile.
            tree.IsNeedTile = NeedTile(quad);

            if (!tree.IsNeedTile && tree.Tile != null)
            {
                Producer.PutTile(tree.Tile);

                tree.Tile = null;
            }

            // If this qiad is a leaf then all children of the tree are not needed
            if (quad.IsLeaf)
            {
                if (!tree.IsLeaf)
                {
                    tree.RecursiveDeleteChildren(this);
                }
            }
            else if (Producer.HasChildren(quad.Level, quad.Tx, quad.Ty))
            {
                for (byte i = 0; i < 4; ++i)
                {
                    PutTiles(tree.Children[i], quad.GetChild(i));
                }
            }
        }
Ejemplo n.º 3
0
        private void FindDrawableQuads(TerrainQuad quad, List <TileSampler> samplers)
        {
            quad.Drawable = false;

            if (!quad.IsVisible)
            {
                quad.Drawable = true;

                return;
            }

            if (quad.IsLeaf)
            {
                if (FindDrawableSamplers(quad, samplers))
                {
                    return;
                }
            }
            else
            {
                byte drawableCount = 0;

                for (byte i = 0; i < 4; ++i)
                {
                    FindDrawableQuads(quad.GetChild(i), samplers);

                    if (quad.GetChild(i).Drawable)
                    {
                        ++drawableCount;
                    }
                }

                if (drawableCount < 4)
                {
                    if (FindDrawableSamplers(quad, samplers))
                    {
                        return;
                    }
                }
            }

            quad.Drawable = true;
        }
Ejemplo n.º 4
0
        private void DrawQuad(TerrainNode node, TerrainQuad quad, List <TileSampler> samplers)
        {
            if (!quad.IsVisible)
            {
                return;
            }
            if (!quad.Drawable)
            {
                return;
            }

            if (quad.IsLeaf)
            {
                MPB.Clear();

                for (int i = 0; i < samplers.Count; ++i)
                {
                    // Set the unifroms needed to draw the texture for this sampler
                    samplers[i].SetTile(MPB, quad.Level, quad.Tx, quad.Ty);
                }

                // Set the uniforms unique to each quad
                node.SetPerQuadUniforms(quad, MPB);

                DrawNode(node);
            }
            else
            {
                // Draw quads in a order based on distance to camera
                var order = new byte[4];

                var cameraX = node.LocalCameraPosition.x;
                var cameraY = node.LocalCameraPosition.y;
                var quadX   = quad.Oy + quad.Length / 2.0;
                var quadY   = quad.Oy + quad.Length / 2.0;

                if (cameraY < quadY)
                {
                    if (cameraX < quadX)
                    {
                        order[0] = 0;
                        order[1] = 1;
                        order[2] = 2;
                        order[3] = 3;
                    }
                    else
                    {
                        order[0] = 1;
                        order[1] = 0;
                        order[2] = 3;
                        order[3] = 2;
                    }
                }
                else
                {
                    if (cameraX < quadX)
                    {
                        order[0] = 2;
                        order[1] = 0;
                        order[2] = 3;
                        order[3] = 1;
                    }
                    else
                    {
                        order[0] = 3;
                        order[1] = 1;
                        order[2] = 2;
                        order[3] = 0;
                    }
                }

                var done = 0;

                for (byte i = 0; i < 4; ++i)
                {
                    if (quad.GetChild(order[i]).Visibility == Frustum.VISIBILITY.INVISIBLE)
                    {
                        done |= (1 << order[i]);
                    }
                    else if (quad.GetChild(order[i]).Drawable)
                    {
                        DrawQuad(node, quad.GetChild(order[i]), samplers);

                        done |= (1 << order[i]);
                    }
                }

                if (done < 15)
                {
                    // If the a leaf quad needs to be drawn but its tiles are not ready then this will draw the next parent tile instead that is ready.
                    // Because of the current set up all tiles always have there tasks run on the frame they are generated so this section of code is never reached.

                    MPB.Clear();

                    for (int i = 0; i < samplers.Count; ++i)
                    {
                        // Set the unifroms needed to draw the texture for this sampler
                        samplers[i].SetTile(MPB, quad.Level, quad.Tx, quad.Ty);
                    }

                    // Set the uniforms unique to each quad
                    node.SetPerQuadUniforms(quad, MPB);

                    DrawNode(node);
                }
            }
        }