public void Add(GGrassPrototype p)
 {
     if (p == null)
     {
         return;
     }
     if (p.Shape == GGrassShape.DetailObject)
     {
         if (p.Prefab == null)
         {
             return;
         }
         Texture t = AssetPreview.GetAssetPreview(p.Prefab);
         if (t != null)
         {
             Textures.Add(t);
             Colors.Add(Color.white);
         }
     }
     else
     {
         if (p.Texture == null)
         {
             return;
         }
         Textures.Add(p.Texture);
         Colors.Add(p.Color);
     }
 }
Пример #2
0
        private void DrawAddPrototypeGUI()
        {
            EditorGUILayout.GetControlRect(GUILayout.Height(1));
            Rect      r0 = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
            Texture2D t  = GEditorCommon.ObjectSelectorDragDrop <Texture2D>(r0, "Drop a Texture here!", "t:Texture2D");

            if (t != null)
            {
                GGrassPrototype g = GGrassPrototype.Create(t);
                instance.Prototypes.Add(g);
                RefreshInstanceList();
                EditorUtility.SetDirty(instance);
            }

            EditorGUILayout.GetControlRect(GUILayout.Height(1));
            Rect       r1     = EditorGUILayout.GetControlRect(GUILayout.Height(GEditorCommon.objectSelectorDragDropHeight));
            GameObject prefab = GEditorCommon.ObjectSelectorDragDrop <GameObject>(r1, "Drop a Game Object here!", "t:GameObject");

            if (prefab != null)
            {
                GGrassPrototype p = GGrassPrototype.Create(prefab);
                instance.Prototypes.Add(p);
                RefreshInstanceList();
                EditorUtility.SetDirty(instance);
            }
        }
Пример #3
0
        private void ConfirmAndRemovePrototypeAtIndex(int index)
        {
            GGrassPrototype p     = instance.Prototypes[index];
            string          label = p.Texture != null ? p.Texture.name : "Grass " + index;

            if (EditorUtility.DisplayDialog(
                    "Confirm",
                    "Remove " + label,
                    "OK", "Cancel"))
            {
                instance.Prototypes.RemoveAt(index);
            }
        }
Пример #4
0
        public static GGrassPrototype Create(GameObject prefab)
        {
            GGrassPrototype prototype = new GGrassPrototype();

            prototype.Shape          = GGrassShape.DetailObject;
            prototype.Prefab         = prefab;
            prototype.Size           = Vector3.one;
            prototype.Layer          = LayerMask.NameToLayer("Default");
            prototype.AlignToSurface = false;
            prototype.PivotOffset    = 0;
            prototype.BendFactor     = 1;
            prototype.Color          = Color.white;
            return(prototype);
        }
Пример #5
0
        private void DrawPrototypesListGUI()
        {
            for (int i = 0; i < instance.Prototypes.Count; ++i)
            {
                GGrassPrototype p = instance.Prototypes[i];

                string label = string.Empty;
                if (p.Shape != GGrassShape.DetailObject)
                {
                    label = p.Texture != null && !string.IsNullOrEmpty(p.Texture.name) ? p.Texture.name : "Grass " + i;
                }
                else
                {
                    label = p.Prefab != null && !string.IsNullOrEmpty(p.Prefab.name) ? p.Prefab.name : "Grass " + i;
                }
                string id = "grassprototype" + i + instance.GetInstanceID().ToString();

                int         index = i;
                GenericMenu menu  = new GenericMenu();
                menu.AddItem(
                    new GUIContent("Remove"),
                    false,
                    () => { ConfirmAndRemovePrototypeAtIndex(index); });

                GEditorCommon.Foldout(label, false, id, () =>
                {
                    if (p.Shape != GGrassShape.DetailObject)
                    {
                        p.Texture = EditorGUILayout.ObjectField("Texture", p.Texture, typeof(Texture2D), false) as Texture2D;
                        if (p.Shape == GGrassShape.CustomMesh)
                        {
                            p.CustomMesh = EditorGUILayout.ObjectField("Mesh", p.CustomMesh, typeof(Mesh), false) as Mesh;
                        }
                    }
                    else
                    {
                        DrawPreview(p.Prefab);
                        p.Prefab = EditorGUILayout.ObjectField("Prefab", p.Prefab, typeof(GameObject), false) as GameObject;
                    }
                    p.Color          = EditorGUILayout.ColorField("Color", p.Color);
                    p.Size           = GEditorCommon.InlineVector3Field("Size", p.Size);
                    p.BendFactor     = EditorGUILayout.FloatField("Bend Factor", p.BendFactor);
                    p.PivotOffset    = EditorGUILayout.Slider("Pivot Offset", p.PivotOffset, -1f, 1f);
                    p.Layer          = EditorGUILayout.LayerField("Layer", p.Layer);
                    p.Shape          = (GGrassShape)EditorGUILayout.EnumPopup("Shape", p.Shape);
                    p.AlignToSurface = EditorGUILayout.Toggle("Align To Surface", p.AlignToSurface);
                },
                                      menu);
            }
        }
        public static GGrassPrototype Create(Texture2D tex)
        {
            GGrassPrototype prototype = new GGrassPrototype();

            prototype.Shape          = GGrassShape.Quad;
            prototype.Texture        = tex;
            prototype.Size           = Vector3.one;
            prototype.Layer          = LayerMask.NameToLayer("Default");
            prototype.AlignToSurface = false;
            prototype.PivotOffset    = 0;
            prototype.BendFactor     = 1;
            prototype.Color          = Color.white;
            return(prototype);
        }
Пример #7
0
        private void DrawPrototypesListGUI()
        {
            for (int i = 0; i < instance.Prototypes.Count; ++i)
            {
                GGrassPrototype p = instance.Prototypes[i];

                string label = string.Empty;
                if (p.Shape != GGrassShape.DetailObject)
                {
                    label = p.Texture != null && !string.IsNullOrEmpty(p.Texture.name) ? p.Texture.name : "Grass " + i;
                }
                else
                {
                    label = p.Prefab != null && !string.IsNullOrEmpty(p.Prefab.name) ? p.Prefab.name : "Grass " + i;
                }
                string id = "grassprototype" + i + instance.GetInstanceID().ToString();

                int         index = i;
                GenericMenu menu  = new GenericMenu();
                menu.AddItem(
                    new GUIContent("Remove"),
                    false,
                    () => { ConfirmAndRemovePrototypeAtIndex(index); });

                GEditorCommon.Foldout(label, false, id, () =>
                {
                    EditorGUI.BeginChangeCheck();
                    if (p.Shape != GGrassShape.DetailObject)
                    {
                        p.Texture = EditorGUILayout.ObjectField("Texture", p.Texture, typeof(Texture2D), false) as Texture2D;
                        p.Shape   = (GGrassShape)EditorGUILayout.EnumPopup("Shape", p.Shape);
                        if (p.Shape == GGrassShape.CustomMesh)
                        {
                            p.CustomMesh = EditorGUILayout.ObjectField("Mesh", p.CustomMesh, typeof(Mesh), false) as Mesh;
                        }
                    }
                    else
                    {
                        DrawPreview(p.Prefab);
                        p.Shape     = (GGrassShape)EditorGUILayout.EnumPopup("Shape", p.Shape);
                        p.Prefab    = EditorGUILayout.ObjectField("Prefab", p.Prefab, typeof(GameObject), false) as GameObject;
                        GUI.enabled = false;
                        EditorGUILayout.ObjectField("Material", p.DetailMaterial, typeof(Material), false);
                        GUI.enabled = true;
                    }
                    p.Color = EditorGUILayout.ColorField("Color", p.Color);
                    if (EditorGUI.EndChangeCheck())
                    {
                        EditorUtility.SetDirty(instance);
                    }

                    EditorGUI.BeginChangeCheck();
                    p.Size        = GEditorCommon.InlineVector3Field("Size", p.Size);
                    p.PivotOffset = EditorGUILayout.DelayedFloatField("Pivot Offset", p.PivotOffset);
                    if (EditorGUI.EndChangeCheck())
                    {
                        ResetNativeArrays();
                        EditorUtility.SetDirty(instance);
                    }

                    p.BendFactor        = EditorGUILayout.FloatField("Bend Factor", p.BendFactor);
                    p.Layer             = EditorGUILayout.LayerField("Layer", p.Layer);
                    p.AlignToSurface    = EditorGUILayout.Toggle("Align To Surface", p.AlignToSurface);
                    p.ShadowCastingMode = (ShadowCastingMode)EditorGUILayout.EnumPopup("Cast Shadow", p.ShadowCastingMode);
                    p.ReceiveShadow     = EditorGUILayout.Toggle("Receive Shadow", p.ReceiveShadow);

                    if (p.Shape != GGrassShape.DetailObject)
                    {
                        p.IsBillboard = EditorGUILayout.Toggle("Billboard", p.IsBillboard);
                    }

                    if (p.Shape == GGrassShape.DetailObject)
                    {
                        EditorGUILayout.LabelField("Detail Object uses the first sub-mesh and material found in its prefab, and may NOT affected by wind.", GEditorCommon.WarningLabel);

                        if (!p.DetailMaterial.enableInstancing)
                        {
                            EditorGUILayout.LabelField("Prototype's material has GPU Instancing option turned off. This prototype will not be rendered.", GEditorCommon.WarningLabel);
                        }
                    }

                    if (p.Shape != GGrassShape.DetailObject && p.IsBillboard)
                    {
                        EditorGUILayout.LabelField("Billboard will not work if Interactive Grass is enabled.", GEditorCommon.WarningLabel);
                    }
                },
                                      menu);
            }
        }
Пример #8
0
        private static void RenderPreviewGrass(GStylizedTerrain t, Camera cam)
        {
            if (t.TerrainData.Foliage.Grasses == null ||
                t.TerrainData.Foliage.Grasses.Prototypes.Count == 0)
            {
                return;
            }

            List <GGrassPrototype> prototypes = t.TerrainData.Foliage.Grasses.Prototypes;
            Vector3 dimension = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            Vector3 localPos = Vector3.zero;
            Vector3 worldPos = Vector3.zero;
            Vector3 scale    = Vector3.zero;

            Material mat = GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassPreviewMaterial;

            Rect[]        dirtyRects = t.TerrainData.Foliage.GetGrassDirtyRegions();
            GGrassPatch[] patches    = t.TerrainData.Foliage.GrassPatches;
            bool[]        dirtyFlags = new bool[patches.Length];
            for (int p = 0; p < patches.Length; ++p)
            {
                dirtyFlags[p] = false;
                Rect uvRange = patches[p].GetUvRange();
                for (int r = 0; r < dirtyRects.Length; ++r)
                {
                    if (uvRange.Overlaps(dirtyRects[r]))
                    {
                        dirtyFlags[p] = true;
                        break;
                    }
                }
            }

            for (int pIndex = 0; pIndex < prototypes.Count; ++pIndex)
            {
                GGrassPrototype proto = prototypes[pIndex];
                //mat.SetTexture(MAINTEX_PROPERTY, proto.Texture);
                mat.SetPass(0);
                for (int p = 0; p < patches.Length; ++p)
                {
                    if (dirtyFlags[p] == false)
                    {
                        continue;
                    }

                    int instanceCount = patches[p].Instances.Count;
                    for (int j = 0; j < instanceCount; ++j)
                    {
                        GGrassInstance grass = patches[p].Instances[j];
                        if (grass.PrototypeIndex != pIndex)
                        {
                            continue;
                        }

                        localPos.Set(
                            dimension.x * grass.Position.x,
                            dimension.y * grass.Position.y,
                            dimension.z * grass.Position.z);
                        worldPos = t.transform.TransformPoint(localPos);
                        scale.Set(
                            prototypes[grass.PrototypeIndex].Size.x * grass.Scale.x,
                            prototypes[grass.PrototypeIndex].Size.y * grass.Scale.y,
                            prototypes[grass.PrototypeIndex].Size.z * grass.Scale.z);

                        Mesh mesh = prototypes[grass.PrototypeIndex].GetBaseMesh();
                        Graphics.DrawMeshNow(
                            mesh,
                            Matrix4x4.TRS(worldPos, grass.Rotation, scale));
                    }
                }
            }
        }
Пример #9
0
        private static void RenderGrass(GStylizedTerrain t, Camera cam)
        {
            if (t.TerrainData.Foliage.Grasses == null ||
                t.TerrainData.Foliage.Grasses.Prototypes.Count == 0)
            {
                return;
            }
            List <GGrassPrototype> prototypes = t.TerrainData.Foliage.Grasses.Prototypes;

            GGrassPatch[] patches = t.TerrainData.Foliage.GrassPatches;
            if (patches == null)
            {
                return;
            }

            float   grassDistance = t.TerrainData.Rendering.GrassDistance;
            Vector3 dimension     = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            float   patchWorldRadius = dimension.x * 0.5f / t.TerrainData.Foliage.PatchGridSize;
            Vector3 boundLocalPos    = Vector3.zero;
            Vector3 boundWorldPos    = Vector3.zero;

            int FLAG_CULLED  = 0;
            int FLAG_DIRTY   = 1;
            int FLAG_BATCHED = 2;

            int[]  flags     = new int[patches.Length];
            Rect[] dirtyRect = t.TerrainData.Foliage.GetGrassDirtyRegions();
            for (int i = 0; i < patches.Length; ++i)
            {
                Rect uvRect = patches[i].GetUvRange();
                boundLocalPos.Set(
                    uvRect.center.x * dimension.x,
                    0,
                    uvRect.center.y * dimension.z);
                boundWorldPos   = t.transform.TransformPoint(boundLocalPos);
                boundWorldPos.y = cam.transform.position.y;
                if (Vector3.Distance(boundWorldPos, cam.transform.position) - patchWorldRadius > grassDistance)
                {
                    flags[i] = FLAG_CULLED;
                    continue;
                }

                for (int r = 0; r < dirtyRect.Length; ++r)
                {
                    if (dirtyRect[r].Overlaps(uvRect))
                    {
                        flags[i] = FLAG_DIRTY;
                        break;
                    }
                }

                if (flags[i] == FLAG_DIRTY)
                {
                    continue;
                }

                flags[i] = FLAG_BATCHED;
            }

            Vector3 meshLocalPos = Vector3.zero;
            Vector3 meshWorldPos = Vector3.zero;

            grassMaterialPropertyBlock.Clear();
            if (t.TerrainData.Foliage.EnableInteractiveGrass)
            {
                grassMaterialPropertyBlock.SetTexture(VECTOR_FIELD_PROPERTY, t.GetGrassVectorFieldRenderTexture());
                grassMaterialPropertyBlock.SetMatrix(WORLD_TO_NORMALIZED_PROPERTY, t.GetWorldToNormalizedMatrix());
            }

            grassMaterialPropertyBlock.SetTexture(NOISETEX_PROPERTY, GGriffinSettings.Instance.DefaultNoiseTexture);
            IEnumerator <GWindZone> windZone = GWindZone.ActiveWindZones.GetEnumerator();

            if (windZone.MoveNext())
            {
                GWindZone w = windZone.Current;
                grassMaterialPropertyBlock.SetVector(WIND_PROPERTY, w.GetWindParams());
            }

            //draw batched
            //Material grassMat = GCommon.CurrentRenderPipeline == GRenderPipelineType.Lightweight ?
            //    GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterialLW :
            //    GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterial;
            Material grassMat = null;

            if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Builtin)
            {
                grassMat = t.TerrainData.Foliage.EnableInteractiveGrass ?
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassInteractiveMaterial :
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterial;
                if (grassMat == null)
                {
                    Debug.Log("Grass material missing. Try re-installing the Polaris V2 package.");
                }
            }
            else if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Lightweight)
            {
                grassMat = t.TerrainData.Foliage.EnableInteractiveGrass ?
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassInteractiveMaterialLWRP :
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterialLWRP;
                if (grassMat == null)
                {
                    Debug.Log("Grass material missing. Try installing the 'Lightweight Render Pipeline Support' extension from the Extension Window (Window>Griffin>Tools>Extension)");
                }
            }
            else if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Universal)
            {
                grassMat = t.TerrainData.Foliage.EnableInteractiveGrass ?
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassInteractiveMaterialURP :
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterialURP;
                if (grassMat == null)
                {
                    Debug.Log("Grass material missing. Try installing the 'Universal Render Pipeline Support' extension from the Extension Window (Window>Griffin>Tools>Extension)");
                }
            }

            if (grassMat == null)
            {
                return;
            }

            for (int i = 0; i < patches.Length; ++i)
            {
                if (flags[i] != FLAG_BATCHED)
                {
                    continue;
                }
                for (int p = 0; p < prototypes.Count; ++p)
                {
                    grassMaterialPropertyBlock.SetColor(COLOR_PROPERTY, prototypes[p].Color);
                    grassMaterialPropertyBlock.SetFloat(BEND_FACTOR_PROPERTY, prototypes[p].BendFactor);
                    if (prototypes[p].Shape != GGrassShape.DetailObject && prototypes[p].Texture != null)
                    {
                        grassMaterialPropertyBlock.SetTexture(MAINTEX_PROPERTY, prototypes[p].Texture);
                    }
                    Mesh mesh = patches[i].GetMesh(p);
                    if (mesh != null)
                    {
                        meshLocalPos = mesh.bounds.center;
                        meshWorldPos = t.transform.TransformPoint(meshLocalPos);
                        if (Vector3.Distance(meshWorldPos, cam.transform.position) - patchWorldRadius > grassDistance)
                        {
                            continue;
                        }

                        Graphics.DrawMesh(
                            mesh,
                            Matrix4x4.TRS(t.transform.position, Quaternion.identity, Vector3.one),
                            prototypes[p].Shape == GGrassShape.DetailObject ? prototypes[p].DetailMaterial : grassMat,
                            prototypes[p].Layer,
                            cam,
                            0,
                            prototypes[p].Shape == GGrassShape.DetailObject ? null : grassMaterialPropertyBlock,
                            prototypes[p].Shape == GGrassShape.DetailObject ? prototypes[p].ShadowCastingMode : ShadowCastingMode.On,
                            prototypes[p].Shape == GGrassShape.DetailObject ? prototypes[p].ReceiveShadow : true,
                            null,
                            LightProbeUsage.BlendProbes,
                            null);
                    }
                }
            }

            if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Builtin)
            {
                return;
            }

            Vector3 localPos = Vector3.zero;
            Vector3 worldPos = Vector3.zero;
            Vector3 scale    = Vector3.zero;

            Material previewMat = GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassPreviewMaterial;

            for (int pIndex = 0; pIndex < prototypes.Count; ++pIndex)
            {
                GGrassPrototype proto = prototypes[pIndex];
                //grassMaterialPropertyBlock.Clear();
                //grassMaterialPropertyBlock.SetTexture(MAINTEX_PROPERTY, proto.Texture);

                for (int i = 0; i < patches.Length; ++i)
                {
                    if (flags[i] != FLAG_DIRTY)
                    {
                        continue;
                    }
                    GGrassPatch patch         = patches[i];
                    int         instanceCount = patch.Instances.Count;
                    for (int j = 0; j < instanceCount; ++j)
                    {
                        GGrassInstance grass = patch.Instances[j];
                        if (grass.PrototypeIndex != pIndex)
                        {
                            continue;
                        }

                        localPos.Set(
                            dimension.x * grass.Position.x,
                            dimension.y * grass.Position.y,
                            dimension.z * grass.Position.z);
                        worldPos = t.transform.TransformPoint(localPos);
                        scale.Set(
                            prototypes[grass.PrototypeIndex].Size.x * grass.Scale.x,
                            prototypes[grass.PrototypeIndex].Size.y * grass.Scale.y,
                            prototypes[grass.PrototypeIndex].Size.z * grass.Scale.z);

                        Mesh mesh = prototypes[grass.PrototypeIndex].GetBaseMesh();
                        Graphics.DrawMesh(
                            mesh,
                            Matrix4x4.TRS(worldPos, grass.Rotation, scale),
                            previewMat,
                            prototypes[grass.PrototypeIndex].Layer,
                            cam,
                            0,
                            null,     //grassMaterialPropertyBlock
                            ShadowCastingMode.On,
                            true,
                            null,
                            LightProbeUsage.BlendProbes,
                            null);
                    }
                }
            }
        }
Пример #10
0
        public void UpdateMesh(int prototypeIndex)
        {
            if (Foliage.Grasses == null)
            {
                return;
            }
            if (prototypeIndex < 0 || prototypeIndex >= Foliage.Grasses.Prototypes.Count)
            {
                return;
            }

            StripInstances(prototypeIndex);
            string key = GetPatchMeshName(Index, prototypeIndex);
            Mesh   m   = Foliage.TerrainData.FoliageData.GetMesh(key);

            if (m != null && Foliage.TerrainData.Foliage.GrassInstanceCount == 0)
            {
                Foliage.TerrainData.FoliageData.DeleteMesh(key);
                return;
            }
            else if (m == null)
            {
                m = new Mesh();
                m.MarkDynamic();
                m.name = key;
                Foliage.TerrainData.FoliageData.SetMesh(key, m);
            }

            GGrassPrototype prototype   = Foliage.Grasses.Prototypes[prototypeIndex];
            Mesh            baseMesh    = prototype.GetBaseMesh();
            Vector3         terrainSize = new Vector3(
                Foliage.TerrainData.Geometry.Width,
                Foliage.TerrainData.Geometry.Height,
                Foliage.TerrainData.Geometry.Length);

            GCombineInfo meshTemplate = new GCombineInfo(baseMesh);

            List <Matrix4x4> transforms = new List <Matrix4x4>();
            Rect             uvRange    = GetUvRange();

            for (int i = 0; i < Instances.Count; ++i)
            {
                GGrassInstance grass = Instances[i];
                if (grass.PrototypeIndex != prototypeIndex)
                {
                    continue;
                }
                if (!uvRange.Contains(new Vector2(grass.Position.x, grass.Position.z)))
                {
                    continue;
                }

                Matrix4x4 t = Matrix4x4.TRS(
                    new Vector3(grass.Position.x * terrainSize.x, grass.Position.y * terrainSize.y + prototype.PivotOffset, grass.Position.z * terrainSize.z),
                    grass.Rotation,
                    new Vector3(prototype.Size.x * grass.Scale.x, prototype.Size.y * grass.Scale.y, prototype.Size.z * grass.Scale.z));
                transforms.Add(t);
            }

            int vertexCount = meshTemplate.Vertices.Length * transforms.Count;

            if (vertexCount > 65000)
            {
                string warning = string.Format("Failed to batch grass meshes at patch {0}, prototypeIndex {1} due to vertices limit (batch: {2}, limit: 65000). Consider removing some instances or increase Patch Grid Size and try again!", Index.ToString("0"), prototypeIndex, vertexCount);
                Debug.LogWarning(warning);
            }

            GJobSystem.RunOnBackground(() =>
            {
                GCombineInfo result = GCombiner.Combine(meshTemplate, transforms);
                System.Action task  = () =>
                {
                    if (result.Vertices.Length == 0)
                    {
                        Foliage.TerrainData.FoliageData.DeleteMesh(key);
                    }
                    else
                    {
                        m.Clear();
                        m.vertices = result.Vertices;
                        m.uv       = result.UVs;
                        //m.colors32 = result.Colors;
                        m.triangles = result.Triangles;
                        m.RecalculateBounds();

                        //Reduce mesh storage space
                        m.colors32 = null;
                        m.normals  = null;
                        m.tangents = null;
                        m.uv2      = null;
                        //m.RecalculateNormals();
                        //m.RecalculateTangents();

                        GCommon.SetDirty(m);
                        //System.GC.Collect(); ==>This line will cause the editor to hang soooooo long!
                    }
                };

                if (result.Vertices.Length < 1000)
                {
                    GJobSystem.RunOnMainThread(task);
                }
                else
                {
                    GJobSystem.ScheduleOnMainThread(task, 0);
                }
            });
        }