Example #1
0
    public void RiverErode()
    {
        int   fn    = 10;                       // furthest neighbor count (how much this affects other pixels)
        float scale = 0.001f;                   // global river erosion factor (heuristic)

        bool[,] hit    = new bool[xRes, zRes];
        float[,] prevH = thisTerrain.terrainData.GetHeights(0, 0, xRes, zRes);

        for (int l = waterSpots.Count, i = 0; i < l; i++)
        {
            WaterSeed ws = waterSpots[i];
            if (ws.erosionStrength <= 0)
            {
                continue;                                       //
            }
            int basinHitCount = 0;
            for (int ll = ws.basinVertices.Count, j = 0; j < ll; j++)
            {
                int I = 0, J = 0;
                terrainUVToPixel(ws.basinVertices[j].uv, ref I, ref J);

                if (hit[I, J])
                {
                    continue;
                }

                hit[I, J] = true;
                basinHitCount++;

                // Compute neighbour# and strength based on steepness and relative length run
                int   N        = (int)(ws.basinVertices[j].normal.y * fn * (basinHitCount / 10)) + 1;         // affect more neighbors if flatter
                float strength = ws.erosionStrength * (1 - ws.basinVertices[j].normal.y);                     // erode less if flatter

                // Center
                prevH[J, I] -= scale * strength;

                for (int u = -N; u <= N; u++)
                {
                    if (I + u < 0 || I + u > xRes)
                    {
                        continue;                                                               // if outside terrain heightmap pixels
                    }
                    for (int v = -N; v <= N; v++)
                    {
                        if (J + v < 0 || J + v > zRes)
                        {
                            continue;                                                           // if outside terrain heightmap pixels
                        }
                        prevH[J + v, I + u] -= scale * strength
                                               - scale * strength * Mathf.Clamp01((u * u + v * v) / (N * N));       // note flipped i,j here
                    }
                }
            }
            ws.erosionStrength -= 0.1f;
        }

        thisTerrain.terrainData.SetHeights(0, 0, prevH);
    }
Example #2
0
 /******************************
 * DEBUG GIZMO DISPLAY
 ******************************/
 void OnDrawGizmos()
 {
     if (riverGizmos)
     {
         Gizmos.color = Color.blue;
         for (int i = 0; i < waterSpots.Count; i++)
         {
             WaterSeed ws = waterSpots[i];
             for (int j = 0; j < ws.basinVertices.Count; j++)
             {
                 BasinVertex bv = ws.basinVertices[j];
                 Gizmos.DrawLine(bv.position, bv.position + 10 * bv.normal);
             }
         }
     }
 }
Example #3
0
//	██╗   ██╗██████╗ ██████╗  █████╗ ████████╗███████╗
//	██║   ██║██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██╔════╝
//	██║   ██║██████╔╝██║  ██║███████║   ██║   █████╗
//	██║   ██║██╔═══╝ ██║  ██║██╔══██║   ██║   ██╔══╝
//	╚██████╔╝██║     ██████╔╝██║  ██║   ██║   ███████╗
//	 ╚═════╝ ╚═╝     ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ╚══════╝
    // Update is called once per frame
    void Update()
    {
        // Pre-update state-based vars
        frame++;

        // KEYBOARD INTERACTION
        if (Input.GetKeyDown(KeyCode.G))
        {
            riverGizmos = !riverGizmos;
        }
        // Toggle geological time scale on right mouse click
        if (Input.GetKeyDown(KeyCode.T))
        {
            toggleGeoTime();
            if (geoTimeScale)
            {
                storeCurrentPosition();
                enableCursor(false);
            }
            else
            {
                resetPrevPosition();
                enableCursor(true);
            }
            toggleMainCamera();
        }
        // Change to Terraform mode
        if (Input.GetKeyDown(KeyCode.P))
        {
            cursorMode = TERRAFORM;
        }
        // Change to Mountain mode
        if (Input.GetKeyDown(KeyCode.M))
        {
            cursorMode = MOUNTAIN;
        }
        // Change to Water mode
        if (Input.GetKeyDown(KeyCode.F))
        {
            cursorMode = WATER;
        }
        // Force Erode
        if (Input.GetKey(KeyCode.E))
        {
            switch (ErosionType)
            {
            case (ET.steepness):
                SteepnessErode();
                break;

            case (ET.wind):
                WindErode();
                break;

            case (ET.gradientDescent):
                GradientErode();
                break;
            }
        }
        // Recompute textures on ErodeUP
        if (Input.GetKeyUp(KeyCode.E))
        {
            applyTexture();
        }

        // MOUSE INTERACTIONS
        // Perform human actions if applicable (disabled for geotime mode)
        if (humanActions && !geoTimeScale)
        {
            // Calculate terrain cursor position
            RaycastHit hit;
            Ray        ray    = Camera.main.ScreenPointToRay(Input.mousePosition);
            bool       wasHit = Physics.Raycast(ray, out hit);

            Vector3 targetPos = new Vector3(hit.point.x, hit.point.y + 5f, hit.point.z);

            cursorProjector.transform.position = targetPos;

            // MOUSE BUTTON DOWN
            if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
            {
                switch (cursorMode)
                {
                // set mountain seeds
                case MOUNTAIN:
                    MountainSeed ms = new MountainSeed(this, hit.point, pullRadius);
                    if (wasHit)
                    {
                        mountainSpots.Add(ms);
                    }
                    if (debugLogs)
                    {
                        Debug.Log(ms.ToString());
                    }
                    break;

                case WATER:
                    WaterSeed ws = new WaterSeed(this, hit.point, pullRadius);
                    if (wasHit)
                    {
                        waterSpots.Add(ws);
                    }
                    if (debugLogs)
                    {
                        Debug.Log(ws.ToString());
                    }
                    break;
                }
            }

            // MOUSE BUTTON HELD DOWN
            // If any mouse button is pressed, perform actions based on cursorMode
            if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
            {
                switch (cursorMode)
                {
                // push/pull terrain
                case TERRAFORM:
                    if (wasHit)
                    {
                        humanPullTerrain(hit.point, Input.GetMouseButton(0));
                    }
                    break;
                }
            }
            // Apply textures on human terraforming mouse up
            if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1))
            {
                switch (cursorMode)
                {
                // push/pull terrain
                case TERRAFORM:
                    if (wasHit)
                    {
                        //applyTexture();
                    }
                    break;
                }
            }


            // If scrollwheel, update pullRadius and cursorProjector
            float wheel = Input.GetAxis("Mouse ScrollWheel");
            if (wheel != 0)
            {
                pullRadius *= wheel > 0 ? wheelIncrement : (1 / wheelIncrement);
                cursorProjector.orthographicSize = pullRadius;
            }
        }


        // If on geoTimeScale, what to do
        if (geoTimeScale)
        {
            year += 1000;

            // Update GUI elements
            labelContent.text = "Year " + year.ToString() + "...";

            // Call the main function with terrain modifications for this mode
            geoTimeTerrainMod();
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            resetTerrain();
        }
    }
    //    ██╗   ██╗██████╗ ██████╗  █████╗ ████████╗███████╗
    //    ██║   ██║██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██╔════╝
    //    ██║   ██║██████╔╝██║  ██║███████║   ██║   █████╗
    //    ██║   ██║██╔═══╝ ██║  ██║██╔══██║   ██║   ██╔══╝
    //    ╚██████╔╝██║     ██████╔╝██║  ██║   ██║   ███████╗
    //     ╚═════╝ ╚═╝     ╚═════╝ ╚═╝  ╚═╝   ╚═╝   ╚══════╝
    // Update is called once per frame
    void Update()
    {
        // Pre-update state-based vars
        frame++;

        // KEYBOARD INTERACTION
        if (Input.GetKeyDown (KeyCode.G)) {
            riverGizmos = !riverGizmos;
        }
        // Toggle geological time scale on right mouse click
        if (Input.GetKeyDown(KeyCode.T)) {
            toggleGeoTime();
            if (geoTimeScale) {
                storeCurrentPosition();
                enableCursor(false);
            } else {
                resetPrevPosition();
                enableCursor(true);
            }
            toggleMainCamera();
        }
        // Change to Terraform mode
        if (Input.GetKeyDown (KeyCode.P)) {
            cursorMode = TERRAFORM;
        }
        // Change to Mountain mode
        if (Input.GetKeyDown (KeyCode.M)) {
            cursorMode = MOUNTAIN;
        }
        // Change to Water mode
        if (Input.GetKeyDown (KeyCode.F)) {
            cursorMode = WATER;
        }
        // Force Erode
        if (Input.GetKey(KeyCode.E)){
            switch(ErosionType) {

            case(ET.steepness):
                SteepnessErode();
                break;

            case(ET.wind):
                WindErode();
                break;

            case(ET.gradientDescent):
                GradientErode();
                break;
            }
        }
        // Recompute textures on ErodeUP
        if (Input.GetKeyUp(KeyCode.E)) {
            applyTexture ();
        }

        // MOUSE INTERACTIONS
        // Perform human actions if applicable (disabled for geotime mode)
        if (humanActions && !geoTimeScale) {

            // Calculate terrain cursor position
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            bool wasHit = Physics.Raycast(ray, out hit);

            Vector3 targetPos = new Vector3(hit.point.x, hit.point.y + 5f, hit.point.z);

            cursorProjector.transform.position = targetPos;

            // MOUSE BUTTON DOWN
            if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) {
                switch(cursorMode) {
                // set mountain seeds
                case MOUNTAIN:
                    MountainSeed ms = new MountainSeed(this, hit.point, pullRadius);
                    if (wasHit) mountainSpots.Add(ms);
                    if (debugLogs) Debug.Log(ms.ToString());
                    break;
                case WATER:
                    WaterSeed ws = new WaterSeed(this, hit.point, pullRadius);
                    if (wasHit) waterSpots.Add(ws);
                    if (debugLogs) Debug.Log(ws.ToString());
                    break;
                }
            }

            // MOUSE BUTTON HELD DOWN
            // If any mouse button is pressed, perform actions based on cursorMode
            if (Input.GetMouseButton(0) || Input.GetMouseButton (1)) {
                switch(cursorMode) {
                // push/pull terrain
                case TERRAFORM:
                    if(wasHit) {
                        humanPullTerrain(hit.point, Input.GetMouseButton(0));
                    }
                    break;
                }
            }
            // Apply textures on human terraforming mouse up
            if (Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp (1)) {
                switch(cursorMode) {
                // push/pull terrain
                case TERRAFORM:
                    if(wasHit) {
                        //applyTexture();
                    }
                    break;
                }
            }

            // If scrollwheel, update pullRadius and cursorProjector
            float wheel = Input.GetAxis("Mouse ScrollWheel");
            if (wheel != 0) {
                pullRadius *= wheel > 0 ? wheelIncrement : ( 1/ wheelIncrement);
                cursorProjector.orthographicSize = pullRadius;
            }

        }

        // If on geoTimeScale, what to do
        if (geoTimeScale) {
            year += 1000;

            // Update GUI elements
            labelContent.text = "Year " + year.ToString() + "...";

            // Call the main function with terrain modifications for this mode
            geoTimeTerrainMod();
        }

        if (Input.GetKeyDown (KeyCode.R)) {
            resetTerrain();
        }
    }