示例#1
0
        /// <summary>
        /// Get a position and angle along the biome mask's edge.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="angle"></param>
        private void GetRandomBiomeEdgePosition(out Vector3 position, out float angle)
        {
            BiomeMaskArea mask = editor.extension.lineSettings.biomeMaskArea;

            // parameter consistency check
            if (mask == null)
            {
                Debug.LogError("No mask defined");

                position = Vector3.zero;
                angle    = 0;
                return;
            }

            List <Vector3> positions = BiomeMaskUtils.GetPositions(mask);

            // sort clockwise, so that the pick algorithm works
            // if this were counterclockwise, then the angle would make the lines face inwards
            PolygonUtils.SortClockWise(positions);

            // get from node index
            int nodeIndexFrom = Random.Range(0, positions.Count); // note: int is exclusive last

            // get to node index, consider overlap
            int nodeIndexTo = nodeIndexFrom + 1;

            if (nodeIndexTo >= mask.Nodes.Count)
            {
                nodeIndexTo = 0;
            }

            // get nodes
            Vector3 positionFrom = mask.transform.position + positions[nodeIndexFrom];
            Vector3 positionTo   = mask.transform.position + positions[nodeIndexTo];

            // having the lines flip inwards into the biome is just a matter of changing the access order of the nodes
            // leaving this here, maybe we find a use case later
            bool flipAngle = editor.extension.lineSettings.attachedAngleFlip;

            if (flipAngle)
            {
                Vector3 tmp = positionFrom;
                positionFrom = positionTo;
                positionTo   = tmp;
            }

            float   distance  = (positionTo - positionFrom).magnitude;
            Vector3 direction = (positionTo - positionFrom).normalized;

            // the position along the edge. 0=from, 0.5=center, 1=to
            float relativePosition = Random.Range(0f, 1f);

            // calculate the position
            position = positionFrom + direction * distance * relativePosition;

            // calculate the angle 90 degrees to the from-to points and convert to degrees
            angle = Mathf.Atan2(positionTo.z - positionFrom.z, positionTo.x - positionFrom.x) * Mathf.Rad2Deg;
        }
        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            serializedObject.Update();

            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Center", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.CenterMainHandle(mask);
            }
            else if (GUILayout.Button("Grow", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.Grow(mask, resizeFactor);
            }
            else if (GUILayout.Button("Shrink", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.Shrink(mask, -resizeFactor);
            }

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Circle", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.CreateCircle(mask);
            }
            else if (GUILayout.Button("Hexagon", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.CreateHexagon(mask);
            }
            else if (GUILayout.Button("Convex Hull", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.ConvexHull(mask);
            }

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            if (GUILayout.Button("Subdivide", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.Subdivide(mask);
            }
            else if (GUILayout.Button("Unsubdivide", GUILayout.MaxWidth(buttonMaxWidth)))
            {
                BiomeMaskUtils.Unsubdivide(mask);
            }

            GUILayout.EndHorizontal();

            serializedObject.ApplyModifiedProperties();
        }
示例#3
0
        private void ShrinkAll()
        {
            // get all biome mask area gameobjects of this gameobject
            GameObject parentGo = editor.extension.transform.gameObject;

            BiomeMaskArea[] masks = parentGo.GetComponentsInChildren <BiomeMaskArea>();

            foreach (BiomeMaskArea mask in masks)
            {
                BiomeMaskUtils.Shrink(mask, resizeFactor);
            }
        }
        public void CreateBiomeMaskArea(string gameObjectName, string maskName, Vector3 position, List <Vector3> nodes, float blendDistance)
        {
            GameObject parentGameObject = extension.transform.gameObject;

            // create new gameobject
            GameObject biomeGameObject = new GameObject(gameObjectName);

            // add this component
            biomeGameObject.AddComponent <BiomeMaskAreaExtension>();

            // ensure gameobject gets reparented if this was a context click (otherwise does nothing)
            GameObjectUtility.SetParentAndAlign(biomeGameObject, parentGameObject);

            // set position
            biomeGameObject.transform.position = position; // that's actually not necessary, we call CenterMainHandle after the mask nodes were created

            // modify created biome
            BiomeMaskArea mask = biomeGameObject.GetComponent <BiomeMaskArea>();

            mask.BiomeType = extension.biomeSettings.biomeType;

            // blend distance
            mask.BlendDistance = blendDistance;

            // create nodes
            mask.MaskName = maskName;

            // grow/shrink mask
            nodes = PolygonUtils.Resize(nodes, extension.shapeSettings.resizeFactor);

            // random shape inside bounds
            SetMaskNodes(mask, nodes);

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

            #region Lake Polygon
            // create a lake and re-parent the biome to it
            if (extension.lakeSettings.createLake)
            {
                lakeModule.CreateLake(mask, gameObjectName, nodes);
            }
            #endregion Lake Polygon

            // tegister the creation in the undo system
            Undo.RegisterCreatedObjectUndo(biomeGameObject, "Create " + biomeGameObject.name);
        }
示例#5
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);
        }