Esempio n. 1
0
        /// <summary>
        /// Find all the quads in a terrain that need to be drawn. If a quad is a leaf and is visible it should
        /// be drawn. If that quads tile is not ready the first ready parent is drawn
        /// NOTE - because of the current set up all task are run on the frame they are generated so
        /// the leaf quads will always have tiles that are ready to be drawn
        /// </summary>
        private void FindDrawableQuads(TerrainQuad quad, List <TileSampler> samplers)
        {
            quad.Drawable = false;

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

            if (quad.IsLeaf)
            {
                for (int i = 0; i < samplers.Count; ++i)
                {
                    TileProducer p  = samplers[i].Producer;
                    int          l  = quad.Level;
                    int          tx = quad.Tx;
                    int          ty = quad.Ty;

                    if (p.HasTile(l, tx, ty) && p.FindTile(l, tx, ty, false, true) == null)
                    {
                        return;
                    }
                }
            }
            else
            {
                int nDrawable = 0;
                for (int i = 0; i < 4; ++i)
                {
                    FindDrawableQuads(quad.GetChild(i), samplers);
                    if (quad.GetChild(i).Drawable)
                    {
                        ++nDrawable;
                    }
                }

                if (nDrawable < 4)
                {
                    for (int i = 0; i < samplers.Count; ++i)
                    {
                        TileProducer p  = samplers[i].Producer;
                        int          l  = quad.Level;
                        int          tx = quad.Tx;
                        int          ty = quad.Ty;

                        if (p.HasTile(l, tx, ty) && p.FindTile(l, tx, ty, false, true) == null)
                        {
                            return;
                        }
                    }
                }
            }

            quad.Drawable = true;
        }
        /// <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>
        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.NeedTile = 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.NeedTile && tree.Tile == null)
            {
                tree.Tile = Producer.GetTile(quad.Level, quad.Tx, quad.Ty);

                if (!tree.Tile.IsDone)
                {
                    tree.Tile.CreateTile();
                }
            }

            if (!quad.IsLeaf && Producer.HasChildren(quad.Level, quad.Tx, quad.Ty))
            {
                for (int i = 0; i < 4; ++i)
                {
                    GetTiles(tree, ref tree.Children[i], quad.GetChild(i));
                }
            }
        }
        /// <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>
        protected virtual void PutTiles(QuadTree tree, TerrainQuad quad)
        {
            if (tree == null)
            {
                return;
            }

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

            if (!tree.NeedTile && 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 (int i = 0; i < 4; ++i)
                {
                    PutTiles(tree.Children[i], quad.GetChild(i));
                }
            }
        }
Esempio n. 4
0
        private void DrawQuad(TerrainNode node, TerrainQuad quad, List <TileSampler> samplers)
        {
            if (!quad.IsVisible)
            {
                return;
            }

            if (!quad.Drawable)
            {
                return;
            }

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

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

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

                //Draw the mesh
                Graphics.DrawMesh(m_quadMesh, Matrix4x4.identity, node.Material, 0, Camera.main, 0, m_propertyBlock);
            }
            else
            {
                //draw quads in a order based on distance to camera
                int[]  order = new int[4];
                double ox    = node.LocalCameraPos.x;
                double oy    = node.LocalCameraPos.y;

                double cx = quad.Ox + quad.Length / 2.0;
                double cy = quad.Oy + quad.Length / 2.0;

                if (oy < cy)
                {
                    if (ox < cx)
                    {
                        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 (ox < cx)
                    {
                        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;
                    }
                }

                int done = 0;
                for (int i = 0; i < 4; ++i)
                {
                    if (quad.GetChild(order[i]).Visible == FRUSTUM_VISIBILTY.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 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

                    m_propertyBlock.Clear();

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

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

                    //Draw the mesh.
                    Graphics.DrawMesh(m_quadMesh, Matrix4x4.identity, node.Material, 0, Camera.main, 0, m_propertyBlock);
                }
            }
        }