Exemple #1
0
    public static LakePolygon CreatePolygon(Material material, List <Vector3> positions = null)
    {
        GameObject   gameobject   = new GameObject("Lake Polygon");
        LakePolygon  polygon      = gameobject.AddComponent <LakePolygon>();
        MeshRenderer meshRenderer = gameobject.AddComponent <MeshRenderer>();

        meshRenderer.receiveShadows    = false;
        meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;

        if (material != null)
        {
            meshRenderer.sharedMaterial = material;
        }

        if (positions != null)
        {
            for (int i = 0; i < positions.Count; i++)
            {
                polygon.AddPoint(positions[i]);
            }
        }

        return(polygon);
    }
    protected virtual void OnSceneGUI()
    {
        if (lakePolygon == null)
        {
            lakePolygon = (LakePolygon)target;
        }

        Color baseColor = Handles.color;
        int   controlId = GUIUtility.GetControlID(FocusType.Passive);



        if (lakePolygon != null)
        {
            if (lakePolygon.lockHeight)
            {
                for (int i = 1; i < lakePolygon.points.Count; i++)
                {
                    Vector3 vec = lakePolygon.points[i];
                    vec.y = lakePolygon.points[0].y;
                    lakePolygon.points[i] = vec;
                }
            }
        }
        {
            Vector3[] points = new Vector3[lakePolygon.splinePoints.Count];


            for (int i = 0; i < lakePolygon.splinePoints.Count; i++)
            {
                points[i] = lakePolygon.splinePoints[i] + lakePolygon.transform.position;
            }


            Handles.color = Color.white;
            Handles.DrawPolyLine(points);

            if (Event.current.commandName == "UndoRedoPerformed")
            {
                lakePolygon.GeneratePolygon();
                return;
            }

            if (selectedPosition >= 0 && selectedPosition < lakePolygon.points.Count)
            {
                Handles.color = Color.red;
                Handles.SphereHandleCap(0, (Vector3)lakePolygon.points[selectedPosition] + lakePolygon.transform.position, Quaternion.identity, 1, EventType.Repaint);
            }


            int controlPointToDelete = -1;

            for (int j = 0; j < lakePolygon.points.Count; j++)
            {
                EditorGUI.BeginChangeCheck();

                Vector3 handlePos = (Vector3)lakePolygon.points[j] + lakePolygon.transform.position;

                GUIStyle style = new GUIStyle();
                style.normal.textColor = Color.red;

                Vector3 screenPoint = Camera.current.WorldToScreenPoint(handlePos);

                if (screenPoint.z > 0)
                {
                    Handles.Label(handlePos + Vector3.up * HandleUtility.GetHandleSize(handlePos), "Point: " + j.ToString(), style);
                }

                if (Event.current.control && Event.current.shift)
                {
                    int id = GUIUtility.GetControlID(FocusType.Passive);



                    if (HandleUtility.nearestControl == id)
                    {
                        Handles.color = Color.white;
                        if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
                        {
                            controlPointToDelete = j;
                        }
                    }
                    else
                    {
                        Handles.color = Handles.xAxisColor;
                    }

                    float size = 0.6f;
                    size = HandleUtility.GetHandleSize(handlePos) * size;
                    if (Event.current.type == EventType.Repaint)
                    {
                        Handles.SphereHandleCap(id, (Vector3)lakePolygon.points[j] + lakePolygon.transform.position, Quaternion.identity, size, EventType.Repaint);
                    }
                    else if (Event.current.type == EventType.Layout)
                    {
                        Handles.SphereHandleCap(id, (Vector3)lakePolygon.points[j] + lakePolygon.transform.position, Quaternion.identity, size, EventType.Layout);
                    }
                }
                else if (Tools.current == Tool.Move)
                {
                    float size = 0.6f;
                    size = HandleUtility.GetHandleSize(handlePos) * size;

                    Handles.color = Handles.xAxisColor;
                    Vector3 pos = Handles.Slider((Vector3)lakePolygon.points[j] + lakePolygon.transform.position, Vector3.right, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position;
                    if (!lakePolygon.lockHeight)
                    {
                        Handles.color = Handles.yAxisColor;

                        pos = Handles.Slider((Vector3)pos + lakePolygon.transform.position, Vector3.up, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position;
                    }
                    Handles.color = Handles.zAxisColor;
                    pos           = Handles.Slider((Vector3)pos + lakePolygon.transform.position, Vector3.forward, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position;

                    Vector3 halfPos = (Vector3.right + Vector3.forward) * size * 0.3f;
                    Handles.color = Handles.yAxisColor;
                    pos           = Handles.Slider2D((Vector3)pos + lakePolygon.transform.position + halfPos, Vector3.up, Vector3.right, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - lakePolygon.transform.position - halfPos;
                    halfPos       = (Vector3.right + Vector3.up) * size * 0.3f;

                    if (!lakePolygon.lockHeight)
                    {
                        Handles.color = Handles.zAxisColor;
                        pos           = Handles.Slider2D((Vector3)pos + lakePolygon.transform.position + halfPos, Vector3.forward, Vector3.right, Vector3.up, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - lakePolygon.transform.position - halfPos;
                        halfPos       = (Vector3.up + Vector3.forward) * size * 0.3f;
                        Handles.color = Handles.xAxisColor;
                        pos           = Handles.Slider2D((Vector3)pos + lakePolygon.transform.position + halfPos, Vector3.right, Vector3.up, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - lakePolygon.transform.position - halfPos;
                    }

                    lakePolygon.points[j] = pos;
                }


                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(lakePolygon, "Change Position");
                    lakePolygon.GeneratePolygon();
#if VEGETATION_STUDIO
                    RegenerateVegetationMask();
#endif
#if VEGETATION_STUDIO_PRO
                    RegenerateBiomMask();
#endif
                }
            }

            if (controlPointToDelete >= 0)
            {
                Undo.RecordObject(lakePolygon, "Remove point");
                Undo.RecordObject(lakePolygon.transform, "Remove point");


                lakePolygon.RemovePoint(controlPointToDelete);

                lakePolygon.GeneratePolygon();

                GUIUtility.hotControl = controlId;
                Event.current.Use();
                HandleUtility.Repaint();
                controlPointToDelete = -1;
            }

            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.control)
            {
                Ray        ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    Undo.RecordObject(lakePolygon, "Add point");
                    Undo.RecordObject(lakePolygon.transform, "Add point");

                    Vector3 position = hit.point - lakePolygon.transform.position;
                    lakePolygon.AddPoint(position);

                    lakePolygon.GeneratePolygon();

#if VEGETATION_STUDIO
                    RegenerateVegetationMask();
#endif
#if VEGETATION_STUDIO_PRO
                    RegenerateBiomMask();
#endif

                    GUIUtility.hotControl = controlId;
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
            }

            if (!Event.current.control && Event.current.shift)
            {
                Ray        ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    int   idMin       = -1;
                    float distanceMin = float.MaxValue;

                    for (int j = 0; j < lakePolygon.points.Count; j++)
                    {
                        Vector3 handlePos = (Vector3)lakePolygon.points[j] + lakePolygon.transform.position;

                        float pointDist = Vector3.Distance(hit.point, handlePos);
                        if (pointDist < distanceMin)
                        {
                            distanceMin = pointDist;
                            idMin       = j;
                        }
                    }

                    Vector3 posOne = (Vector3)lakePolygon.points[idMin] + lakePolygon.transform.position;
                    Vector3 posTwo;



                    Vector3 posPrev = (Vector3)lakePolygon.points[lakePolygon.ClampListPos(idMin - 1)] + lakePolygon.transform.position;
                    Vector3 posNext = (Vector3)lakePolygon.points[lakePolygon.ClampListPos(idMin + 1)] + lakePolygon.transform.position;

                    if (Vector3.Distance(hit.point, posPrev) > Vector3.Distance(hit.point, posNext))
                    {
                        posTwo = posNext;
                    }
                    else
                    {
                        posTwo = posPrev;
                        idMin  = lakePolygon.ClampListPos(idMin - 1);
                    }



                    Handles.color = Handles.xAxisColor;
                    Handles.DrawLine(hit.point, posOne);
                    Handles.DrawLine(hit.point, posTwo);

                    if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
                    {
                        Undo.RecordObject(lakePolygon, "Add point");
                        Undo.RecordObject(lakePolygon.transform, "Add point");

                        Vector4 position = hit.point - lakePolygon.transform.position;
                        lakePolygon.AddPointAfter(idMin);
                        lakePolygon.ChangePointPosition(idMin + 1, position);

                        lakePolygon.GeneratePolygon();

                        GUIUtility.hotControl = controlId;
                        Event.current.Use();
                        HandleUtility.Repaint();
                    }
                }
            }


            if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.control)
            {
                GUIUtility.hotControl = 0;
            }
            if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.shift)
            {
                GUIUtility.hotControl = 0;
            }
        }
    }
    public override void OnInspectorGUI()
    {
        if (lakePolygon == null)
        {
            lakePolygon = (LakePolygon)target;
        }
        EditorGUILayout.Space();
        EditorGUILayout.HelpBox("Add Point  - CTRL + Left Mouse Button Click \n" +
                                "Add point between existing points - SHIFT + Left Button Click \n" +
                                "Remove point - CTRL + SHIFT + Left Button Click", MessageType.Info);

        EditorGUILayout.Space();
        lakePolygon.currentProfile = (LakePolygonProfile)EditorGUILayout.ObjectField("Lake profile", lakePolygon.currentProfile, typeof(LakePolygonProfile), false);

        if (GUILayout.Button("Create profile from settings"))
        {
            LakePolygonProfile asset = ScriptableObject.CreateInstance <LakePolygonProfile>();

            MeshRenderer ren = lakePolygon.GetComponent <MeshRenderer>();
            asset.lakeMaterial      = ren.sharedMaterial;
            asset.terrainCarve      = lakePolygon.terrainCarve;
            asset.distSmooth        = lakePolygon.distSmooth;
            asset.uvScale           = lakePolygon.uvScale;
            asset.distSmoothStart   = lakePolygon.distSmoothStart;
            asset.terrainPaintCarve = lakePolygon.terrainPaintCarve;
            asset.currentSplatMap   = lakePolygon.currentSplatMap;

            asset.maximumTriangleSize = lakePolygon.maximumTriangleSize;
            asset.traingleDensity     = lakePolygon.traingleDensity;



            string path = EditorUtility.SaveFilePanelInProject("Save new spline profile", lakePolygon.gameObject.name + ".asset", "asset", "Please enter a file name to save the spline profile to");

            if (!string.IsNullOrEmpty(path))
            {
                AssetDatabase.CreateAsset(asset, path);
                AssetDatabase.SaveAssets();
                lakePolygon.currentProfile = asset;
            }
        }

        if (lakePolygon.currentProfile != null && GUILayout.Button("Save profile from settings"))
        {
            MeshRenderer ren = lakePolygon.GetComponent <MeshRenderer>();

            lakePolygon.currentProfile.lakeMaterial = ren.sharedMaterial;

            lakePolygon.currentProfile.terrainCarve      = lakePolygon.terrainCarve;
            lakePolygon.currentProfile.distSmooth        = lakePolygon.distSmooth;
            lakePolygon.currentProfile.uvScale           = lakePolygon.uvScale;
            lakePolygon.currentProfile.distSmoothStart   = lakePolygon.distSmoothStart;
            lakePolygon.currentProfile.terrainPaintCarve = lakePolygon.terrainPaintCarve;
            lakePolygon.currentProfile.currentSplatMap   = lakePolygon.currentSplatMap;

            lakePolygon.currentProfile.maximumTriangleSize = lakePolygon.maximumTriangleSize;
            lakePolygon.currentProfile.traingleDensity     = lakePolygon.traingleDensity;


            AssetDatabase.SaveAssets();
        }


        if (lakePolygon.currentProfile != null && lakePolygon.currentProfile != lakePolygon.oldProfile)
        {
            ResetToProfile();
            EditorUtility.SetDirty(lakePolygon);
        }

        if (CheckProfileChange())
        {
            EditorGUILayout.HelpBox("Profile data changed.", MessageType.Info);
        }

        if (lakePolygon.currentProfile != null && GUILayout.Button("Reset to profile"))
        {
            ResetToProfile();
        }

        EditorGUILayout.Space();
        EditorGUILayout.Space();
        EditorGUI.BeginChangeCheck();


        pointsFolded = EditorGUILayout.Foldout(pointsFolded, "Points:");
        EditorGUI.indentLevel++;
        if (pointsFolded)
        {
            PointsUI();
        }

        lakePolygon.lockHeight = EditorGUILayout.Toggle("Lock height", lakePolygon.lockHeight);

        EditorGUILayout.BeginHorizontal();
        lakePolygon.height = EditorGUILayout.FloatField(lakePolygon.height);
        if (GUILayout.Button("Set heights"))
        {
            for (int i = 0; i < lakePolygon.points.Count; i++)
            {
                Vector3 point = lakePolygon.points[i];
                point.y = lakePolygon.height - lakePolygon.transform.position.y;
                lakePolygon.points[i] = point;
            }
            lakePolygon.GeneratePolygon();
        }

        EditorGUILayout.EndHorizontal();

        lakePolygon.yOffset = EditorGUILayout.FloatField("Y offset mesh", lakePolygon.yOffset);
        EditorGUI.indentLevel--;
        EditorGUILayout.Space();


        GUILayout.Label("Mesh settings:", EditorStyles.boldLabel);
        EditorGUI.indentLevel++;
        string meshResolution = "Triangles density" + "(" + lakePolygon.trianglesGenerated + " tris)";

        EditorGUILayout.LabelField(meshResolution);

        lakePolygon.maximumTriangleSize = EditorGUILayout.FloatField("Maximum triangle size", lakePolygon.maximumTriangleSize);
        lakePolygon.traingleDensity     = 1 / (float)EditorGUILayout.IntSlider("Spline density", (int)(1 / (float)lakePolygon.traingleDensity), 1, 100);
        lakePolygon.uvScale             = EditorGUILayout.FloatField("UV scale", lakePolygon.uvScale);

        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(lakePolygon, "Lake changed");
            lakePolygon.GeneratePolygon();
        }

        EditorGUI.indentLevel--;
        EditorGUILayout.Space();

        if (GUILayout.Button("Generate polygon"))
        {
            lakePolygon.GeneratePolygon();
        }
        EditorGUI.BeginChangeCheck();

        EditorGUILayout.Space();

        Terrain terrain = Terrain.activeTerrain;

        GUILayout.Label("Terrain carve:", EditorStyles.boldLabel);

        if (terrain != null)
        {
            EditorGUI.indentLevel++;
            lakePolygon.terrainCarve    = EditorGUILayout.CurveField("Terrain carve", lakePolygon.terrainCarve);
            lakePolygon.distSmooth      = EditorGUILayout.FloatField("Smooth distance", lakePolygon.distSmooth);
            lakePolygon.distSmoothStart = EditorGUILayout.FloatField("Smooth start distance", lakePolygon.distSmoothStart);
            EditorGUI.indentLevel--;

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(lakePolygon, "Lake curve changed");
            }

            if (GUILayout.Button("Carve Terrain"))
            {
                TerrainCarve();
            }

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.Space();
            EditorGUI.indentLevel++;

            lakePolygon.terrainPaintCarve = EditorGUILayout.CurveField("Terrain paint", lakePolygon.terrainPaintCarve);

            int splatNumber = terrain.terrainData.splatPrototypes.Length;
            if (splatNumber > 0)
            {
                string[] options = new string[splatNumber];
                for (int i = 0; i < splatNumber; i++)
                {
                    options[i] = i + " - ";
                    if (terrain.terrainData.splatPrototypes[i].texture != null)
                    {
                        options[i] += terrain.terrainData.splatPrototypes[i].texture.name;
                    }
                }

                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("    Splat id:");
                lakePolygon.currentSplatMap = EditorGUILayout.Popup(lakePolygon.currentSplatMap, options);
                EditorGUILayout.EndHorizontal();

                EditorGUI.indentLevel--;

                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(lakePolygon, "Lake curve changed");
                }

                if (GUILayout.Button("Paint Terrain"))
                {
                    TerrainPaint();
                }
            }
            else
            {
                EditorGUILayout.Space();
                EditorGUILayout.HelpBox("Terrain has no splatmaps.", MessageType.Info);
            }
        }
        else
        {
            EditorGUILayout.Space();
            EditorGUILayout.HelpBox("No Terrain On Scene.", MessageType.Info);
        }
#if VEGETATION_STUDIO
        EditorGUILayout.Space();
        GUILayout.Label("Vegetation Studio: ", EditorStyles.boldLabel);
        EditorGUI.indentLevel++;
        EditorGUI.BeginChangeCheck();
        lakePolygon.vegetationMaskResolution = EditorGUILayout.Slider("Mask Resolution", lakePolygon.vegetationMaskResolution, 0.1f, 1);
        lakePolygon.vegetationMaskPerimeter  = EditorGUILayout.FloatField("Vegetation Mask Perimeter", lakePolygon.vegetationMaskPerimeter);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(lakePolygon, "Lake curve changed");
            RegenerateVegetationMask();
        }
        EditorGUI.indentLevel--;
        if (lakePolygon.vegetationMaskArea == null && GUILayout.Button("Add Vegetation Mask Area"))
        {
            lakePolygon.vegetationMaskArea = lakePolygon.gameObject.AddComponent <VegetationMaskArea>();
            RegenerateVegetationMask();
        }
        if (lakePolygon.vegetationMaskArea != null && GUILayout.Button("Calculate hull outline"))
        {
            RegenerateVegetationMask();
        }
#endif

#if VEGETATION_STUDIO_PRO
        EditorGUILayout.Space();
        GUILayout.Label("Vegetation Studio Pro: ", EditorStyles.boldLabel);

        EditorGUI.BeginChangeCheck();
        lakePolygon.vegetationBlendDistance = EditorGUILayout.FloatField("Vegetation Blend Distance", lakePolygon.vegetationBlendDistance);
        lakePolygon.biomMaskResolution      = EditorGUILayout.Slider("Mask Resolution", lakePolygon.biomMaskResolution, 0.1f, 1);

        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(lakePolygon, "Lake curve changed");
            RegenerateBiomMask();
        }
        if (lakePolygon.biomeMaskArea != null)
        {
            lakePolygon.refreshMask = EditorGUILayout.Toggle("Auto Refresh Biome Mask", lakePolygon.refreshMask);
        }

        if (GUILayout.Button("Add Vegetation Biom Mask Area"))
        {
            lakePolygon.GeneratePolygon();

            if (lakePolygon.biomeMaskArea == null)
            {
                GameObject maskObject = new GameObject("MyMask");
                maskObject.transform.SetParent(lakePolygon.transform);
                maskObject.transform.localPosition = Vector3.zero;

                lakePolygon.biomeMaskArea = maskObject.AddComponent <BiomeMaskArea>();
            }

            if (lakePolygon.biomeMaskArea == null)
            {
                return;
            }

            RegenerateBiomMask(false);
        }
#endif
    }
 static public void CreatelakePolygon()
 {
     Selection.activeGameObject = LakePolygon.CreatePolygon(AssetDatabase.GetBuiltinExtraResource <Material>("Default-Diffuse.mat")).gameObject;
 }
Exemple #5
0
        public void CreateLake(BiomeMaskArea mask, string gameObjectName, List <Vector3> nodes)
        {
#if RAM_2019
            LakePolygon lakePolygon = RamLakeCreator.CreateLakePolygon(editor.extension.lakeSettings, mask, mask.transform.gameObject, gameObjectName, nodes);
#endif
        }
Exemple #6
0
        /// <summary>
        /// Create a lake and re-parent the mask so that the lake becomes the child of the container and the mask the child of the lake.
        ///
        /// Note: the lake uses a bezier curve on the points, so the lake most likely won't be 100% in line with the mask.
        /// </summary>
        /// <param name="maskGameObject"></param>
        /// <param name="gameObjectName"></param>
        /// <param name="nodes"></param>
        public static LakePolygon CreateLakePolygon(LakeSettings lakeSettings, BiomeMaskArea mask, GameObject maskGameObject, string gameObjectName, List <Vector3> nodes)
        {
            GameObject maskParentGameObject = maskGameObject.transform.parent.gameObject;
            Vector3    maskPosition         = maskGameObject.transform.position;

            // lake
            LakePolygon lakePolygon = LakePolygon.CreatePolygon(AssetDatabase.GetBuiltinExtraResource <Material>("Default-Diffuse.mat"));

            // apply profile
            lakePolygon.currentProfile = lakeSettings.lakeProfile;

            // apply gameobject data
            lakePolygon.transform.localPosition = Vector3.zero;
            lakePolygon.name = "Lake " + gameObjectName;

            // add biome nodes
            if (lakeSettings.ramInternalLakeCreation)
            {
                // apply settings
                lakePolygon.angleSimulation            = lakeSettings.angleSimulation;
                lakePolygon.closeDistanceSimulation    = lakeSettings.closeDistanceSimulation;
                lakePolygon.checkDistanceSimulation    = lakeSettings.checkDistanceSimulation;
                lakePolygon.removeFirstPointSimulation = lakeSettings.removeFirstPointSimulation;

                // add point
                lakePolygon.AddPoint(maskPosition);

                // start simulation
                lakePolygon.Simulation();
            }
            // use mask shape
            else
            {
                foreach (Vector3 node in nodes)
                {
                    lakePolygon.AddPoint(maskParentGameObject.transform.InverseTransformPoint(node));
                }
            }


            // generate the lake
            lakePolygon.GeneratePolygon();

            // re-parent the mask to the lake and the lake to the parent
            GameObjectUtility.SetParentAndAlign(lakePolygon.gameObject, maskParentGameObject);
            GameObjectUtility.SetParentAndAlign(maskGameObject, lakePolygon.gameObject);

            // adjust the lake position
            lakePolygon.transform.position = maskPosition;

            // reset the mask position, it's now a child of the lake
            if (lakeSettings.ramInternalLakeCreation)
            {
                maskGameObject.transform.position = Vector3.zero;

                List <Vector3> newPoints = new List <Vector3>();

                foreach (Vector3 node in lakePolygon.points)
                {
                    newPoints.Add(lakePolygon.transform.TransformPoint(node));
                }

                // set the lake's polygon as new mask nodes
                SetMaskNodes(mask, newPoints);

                // put move handle into the center of the polygon
                BiomeMaskUtils.CenterMainHandle(mask);
            }

            // re-apply the material so that the water becomes immediately visible
            MeshRenderer meshRenderer = lakePolygon.GetComponent <MeshRenderer>();

            meshRenderer.sharedMaterial = lakePolygon.currentProfile.lakeMaterial;

            /* carving is disabled for now
             * if ( extension.lakeSettings.carveTerrain)
             * {
             *  Debug.Log("Start carve");
             *  lakePolygon.terrainSmoothMultiplier = 2f;
             *  lakePolygon.distSmooth = 10f;
             *  lakePolygon.TerrainCarve();
             * }
             */

            // EditorUtility.SetDirty(lakePolygon);

            return(lakePolygon);
        }