Пример #1
0
        private void StitchSeamLOD(GSubDivisionTree tree, HashSet <Vector2> seamVertices)
        {
            Stack <GSubDivisionTree.Node> dirtyNode = new Stack <GSubDivisionTree.Node>();

            tree.ForEachLeaf(n =>
            {
                dirtyNode.Push(n);
            });

            HashSet <Vector2> newVertices = new HashSet <Vector2>();

            while (dirtyNode.Count > 0)
            {
                GSubDivisionTree.Node n = dirtyNode.Pop();
                if (!seamVertices.Contains(n.V01) && !seamVertices.Contains(n.V12) && !seamVertices.Contains(n.V20))
                {
                    continue;
                }

                n.Split();
                newVertices.Add(n.V12);
                dirtyNode.Push(n.LeftNode);
                dirtyNode.Push(n.RightNode);
            }

            dirtyNode.Clear();
            tree.ForEachLeaf(n =>
            {
                dirtyNode.Push(n);
            });
            while (dirtyNode.Count > 0)
            {
                GSubDivisionTree.Node n = dirtyNode.Pop();
                if (!newVertices.Contains(n.V01) && !newVertices.Contains(n.V12) && !newVertices.Contains(n.V20))
                {
                    continue;
                }

                n.Split();
                dirtyNode.Push(n.LeftNode);
                dirtyNode.Push(n.RightNode);
            }
        }
Пример #2
0
        private bool StitchGeometrySeamsOnSubDivTree(HashSet <Vector2> vertexPool, GSubDivisionTree tree)
        {
#if UNITY_EDITOR
            //canRunStitchSeamInBackground = true;
#endif

            bool isNewVertexCreated             = false;
            Stack <GSubDivisionTree.Node> nodes = new Stack <GSubDivisionTree.Node>();

            int baseResolution = Terrain.TerrainData.Geometry.MeshBaseResolution;
            int resolution     = Terrain.TerrainData.Geometry.MeshResolution;
            int maxLevel       = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GCommon.SUB_DIV_STEP), resolution - baseResolution);
            //Stitching triangle between tiles
            tree.ForEachLeaf(n =>
            {
                if (n.Level >= maxLevel)
                {
                    return;
                }
                nodes.Push(n);
            });

            while (nodes.Count > 0)
            {
                GSubDivisionTree.Node n = nodes.Pop();

                bool validV01 = vertexPool.Contains(n.V01); // && GUtilities.IsRectContainPointExclusive(uvRange, n.V01);
                bool validV12 = vertexPool.Contains(n.V12); // && GUtilities.IsRectContainPointExclusive(uvRange, n.V12);
                bool validV20 = vertexPool.Contains(n.V20); // && GUtilities.IsRectContainPointExclusive(uvRange, n.V20);

                if (!validV01 && !validV12 && !validV20)
                {
                    continue;
                }
                n.Split();
                if (!vertexPool.Contains(n.V12))
                {
                    vertexPool.Add(n.V12);
                    isNewVertexCreated = true;
                }
                nodes.Push(n.LeftNode);
                nodes.Push(n.RightNode);
            }

            //Sub division for triangle connectivity
            HashSet <Vector2> verts = new HashSet <Vector2>();
            nodes.Clear();
            tree.ForEachLeaf(n =>
            {
                verts.Add(n.V0);
                verts.Add(n.V1);
                verts.Add(n.V2);
                if (n.Level < maxLevel)
                {
                    nodes.Push(n);
                }
            });

            while (nodes.Count > 0)
            {
                GSubDivisionTree.Node n = nodes.Pop();
                if (!verts.Contains(n.V01) && !verts.Contains(n.V12) && !verts.Contains(n.V20))
                {
                    continue;
                }
                n.Split();
                if (!verts.Contains(n.V12))
                {
                    verts.Add(n.V12);
                    isNewVertexCreated = true;
                }
                nodes.Push(n.LeftNode);
                nodes.Push(n.RightNode);
            }

            return(isNewVertexCreated);
        }
Пример #3
0
        internal void Internal_CreateSubDivTree()
        {
            Rect uvRange = GetUvRange();

            subDivTree = GSubDivisionTree.Rect(uvRange);

            int firstPassResolution = Terrain.TerrainData.Geometry.PolygonDistribution == GPolygonDistributionMode.Dynamic ?
                                      Terrain.TerrainData.Geometry.MeshBaseResolution :
                                      Terrain.TerrainData.Geometry.MeshResolution;

            //Subdiv for base resolution
            for (int i = 0; i < firstPassResolution; ++i)
            {
                subDivTree.ForEachLeaf(n =>
                {
                    n.Split();
                });
            }

            if (Terrain.TerrainData.Geometry.PolygonDistribution != GPolygonDistributionMode.Dynamic)
            {
                return;
            }

            Texture2D subdivMap = null;

            if (GCommon.IsMainThread)
            {
                subdivMap = Terrain.TerrainData.Geometry.Internal_SubDivisionMap;
            }
            GGeometryGenerationContext context = null;

            if (!GCommon.IsMainThread)
            {
                context = Terrain.GenerationContext;
            }

            Stack <GSubDivisionTree.Node> nodes0 = new Stack <GSubDivisionTree.Node>();
            Stack <GSubDivisionTree.Node> nodes1;

            subDivTree.ForEachLeaf(n =>
            {
                nodes0.Push(n);
            });

            //Additional sub division based on the sub div map
            int baseResolution = Terrain.TerrainData.Geometry.MeshBaseResolution;
            int resolution     = Terrain.TerrainData.Geometry.MeshResolution;
            int maxLevel       = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GCommon.SUB_DIV_STEP), resolution - baseResolution);

            float r0   = 0;
            float r1   = 0;
            float r2   = 0;
            float rc   = 0;
            float rMax = 0;
            float subDivLevel;

            for (int i = baseResolution; i <= resolution; ++i)
            {
                nodes1 = new Stack <GSubDivisionTree.Node>();
                while (nodes0.Count > 0)
                {
                    GSubDivisionTree.Node n = nodes0.Pop();
                    if (n.Level >= maxLevel)
                    {
                        continue;
                    }
                    if (GCommon.IsMainThread)
                    {
                        r0 = subdivMap.GetPixelBilinear(n.V0.x, n.V0.y).r;
                        r1 = subdivMap.GetPixelBilinear(n.V1.x, n.V1.y).r;
                        r2 = subdivMap.GetPixelBilinear(n.V2.x, n.V2.y).r;
                        rc = subdivMap.GetPixelBilinear(n.VC.x, n.VC.y).r;
                    }
                    else
                    {
                        r0 = context.GetSubdivData(n.V0).r;
                        r1 = context.GetSubdivData(n.V1).r;
                        r2 = context.GetSubdivData(n.V2).r;
                        rc = context.GetSubdivData(n.VC).r;
                    }
                    rMax = Mathf.Max(r0, r1, r2, rc);

                    subDivLevel = baseResolution + (int)(rMax / GCommon.SUB_DIV_STEP);
                    if (subDivLevel <= n.Level)
                    {
                        continue;
                    }
                    n.Split();
                    nodes1.Push(n.LeftNode);
                    nodes1.Push(n.RightNode);
                }

                nodes0 = nodes1;
            }
        }