move TerrainControllerData class into Assembly - UnityScript where it is needed. the only reason it was originally separated into a dll was because aub wanted faster c# 3d arrays. so it can come back since we are in c# now
		
			
				
	
	
		
			157 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
using System.Collections.Generic;
 | 
						|
 | 
						|
public class TerrainControllerData
 | 
						|
{
 | 
						|
    public float[, ,] alphaMap;
 | 
						|
 | 
						|
    public float[,] heightMap;
 | 
						|
}
 | 
						|
 | 
						|
[Serializable]
 | 
						|
public class TerrainController : MonoBehaviour
 | 
						|
{
 | 
						|
    public WhirldObject whirldObject;
 | 
						|
    public Terrain trn;
 | 
						|
    public TerrainData trnDat;
 | 
						|
    public float updateTime = -1;
 | 
						|
    public float seaLevel;
 | 
						|
 | 
						|
    public TerrainControllerData dat;
 | 
						|
 | 
						|
    public void OnSceneGenerated()
 | 
						|
    {
 | 
						|
        if (!trnDat) Destroy(this);
 | 
						|
        trn = (Terrain)GetComponent(typeof(Terrain));
 | 
						|
 | 
						|
        //Find WhirldObject
 | 
						|
        whirldObject = (WhirldObject)gameObject.GetComponent(typeof(WhirldObject));
 | 
						|
        if (!whirldObject ||
 | 
						|
            whirldObject.parameters == null ||
 | 
						|
            whirldObject.parameters["SeaFloorTexture"] == null)
 | 
						|
        {
 | 
						|
            Destroy(this);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        whirldObject.Activate();    //Just in case it hasn't yet activated...
 | 
						|
 | 
						|
        //Init SplatMap Array
 | 
						|
        SplatPrototype[] splatsOld = trnDat.splatPrototypes;
 | 
						|
        SplatPrototype[] splatsNew = new SplatPrototype[trnDat.splatPrototypes.Length + 1];
 | 
						|
 | 
						|
        //Copy Data to New SplatMap Array
 | 
						|
        for (int i = 0; i < trnDat.splatPrototypes.Length; i++)
 | 
						|
        {
 | 
						|
            splatsNew[i] = splatsOld[i];
 | 
						|
        }
 | 
						|
 | 
						|
        //Add SeaFloorTexture Splat Channel to TerrainData Object
 | 
						|
        splatsNew[splatsNew.Length - 1] = new SplatPrototype();
 | 
						|
        splatsNew[splatsNew.Length - 1].texture = (Texture2D)whirldObject.parameters["SeaFloorTexture"];
 | 
						|
        splatsNew[splatsNew.Length - 1].tileSize = new Vector2(15.0f, 15.0f);
 | 
						|
        trnDat.splatPrototypes = splatsNew;
 | 
						|
 | 
						|
        //Prepare to Regenerate SeaFloor AlphaMap Channel
 | 
						|
        dat = new TerrainControllerData();
 | 
						|
        dat.alphaMap = trnDat.GetAlphamaps(0,
 | 
						|
            0,
 | 
						|
            trnDat.alphamapResolution,
 | 
						|
            trnDat.alphamapResolution);
 | 
						|
        dat.heightMap = trnDat.GetHeights(0,
 | 
						|
            0,
 | 
						|
            trnDat.heightmapWidth,
 | 
						|
            trnDat.heightmapHeight);
 | 
						|
 | 
						|
        ReSplat();
 | 
						|
    }
 | 
						|
 | 
						|
    public IEnumerator OnPrefsUpdated()
 | 
						|
    {
 | 
						|
        if (!World.sea ||
 | 
						|
            seaLevel == World.sea.position.y)
 | 
						|
        {
 | 
						|
            yield break;
 | 
						|
        }
 | 
						|
 | 
						|
        if (updateTime == -1)
 | 
						|
        {
 | 
						|
            updateTime = Time.time + 3;
 | 
						|
            while (Time.time < updateTime) yield return null;
 | 
						|
            ReSplat();
 | 
						|
        }
 | 
						|
        else
 | 
						|
        { 
 | 
						|
            //We are just bumping the execution of this coroutine farther into the future
 | 
						|
            updateTime = Time.time + 3;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public void ReSplat()
 | 
						|
    {
 | 
						|
        updateTime = -1;
 | 
						|
        if (World.sea) seaLevel = World.sea.position.y;
 | 
						|
        else if (GameObject.Find("Sea"))
 | 
						|
        {
 | 
						|
            seaLevel = GameObject.Find("Sea").transform.position.y;
 | 
						|
        }
 | 
						|
        else return;
 | 
						|
 | 
						|
        //Create new 3D array to work with - JS nD array support is just about nonexistent...
 | 
						|
        var alphaMap = trnDat.GetAlphamaps(0,
 | 
						|
            0,
 | 
						|
            trnDat.alphamapResolution,
 | 
						|
            trnDat.alphamapResolution);
 | 
						|
 | 
						|
        //Synthesize SeaFloor channel based upon raycasts to check for water
 | 
						|
        for (int y = 0; y < trnDat.alphamapResolution; y++)
 | 
						|
        {
 | 
						|
            for (int x = 0; x < trnDat.alphamapResolution; x++)
 | 
						|
            { 
 | 
						|
                //Check if this pixel is submerged
 | 
						|
                bool submerged = false;
 | 
						|
                float trnAlt = transform.position.y +
 | 
						|
                    dat.heightMap[
 | 
						|
                        (int)((float)x /
 | 
						|
                            (float)trnDat.alphamapResolution *
 | 
						|
                            (float)trnDat.heightmapWidth),
 | 
						|
                        (int)((float)y /
 | 
						|
                            (float)trnDat.alphamapResolution *
 | 
						|
                            (float)trnDat.heightmapHeight)
 | 
						|
                    ] * trnDat.size.y;
 | 
						|
                if (trnAlt < seaLevel)
 | 
						|
                {
 | 
						|
                    submerged = true;
 | 
						|
                    float depth = seaLevel + trnAlt;
 | 
						|
                }
 | 
						|
 | 
						|
                //Update AlphaMap Array
 | 
						|
                for (int z = 0; z < trnDat.alphamapLayers; z++)
 | 
						|
                {
 | 
						|
                    if (submerged)
 | 
						|
                    {
 | 
						|
                        alphaMap[x, y, z] = (z == trnDat.alphamapLayers - 1 ?
 | 
						|
                            1 :
 | 
						|
                            0);
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        alphaMap[x, y, z] = (z == trnDat.alphamapLayers - 1 ?
 | 
						|
                            0 :
 | 
						|
                            dat.alphaMap[x, y, z]);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        //Assign regenerated AlphaMap to Terrain
 | 
						|
        trnDat.SetAlphamaps(0, 0, alphaMap);
 | 
						|
 | 
						|
        //Recalculate Basemap
 | 
						|
        trn.terrainData = trnDat;
 | 
						|
        trnDat.SetBaseMapDirty();
 | 
						|
        trnDat.RefreshPrototypes();
 | 
						|
        trn.Flush();
 | 
						|
    }
 | 
						|
} |