view Orchestland/Assets/Scripts/TerrainDeformation.cs @ 1:f7675884f2a1

Add Orchestland project
author Daiki OYAKAWA <e135764@ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2015 23:09:20 +0900
parents
children
line wrap: on
line source

using UnityEngine;
using System.Collections;

public class TerrainDeformation : MonoBehaviour {
	public Terrain terrain;
	public bool doAll = false;
	public float randomSizeMain = 0.1f;
	public float randomSizeSub = 0.5f;
	public float mountainRadius = 0.2f;

	TerrainData terrain_data;
	float move = 0f;
	int terrain_width;
	int terrain_height;
	float[,] map_height;
	float[,] map_effect;
	float[,] map_alpha;
	// Use this for initialization
	void Start () {
		terrain_data = terrain.terrainData;
		terrain_width = terrain_data.heightmapWidth;
		terrain_height = terrain_data.heightmapHeight;
		map_height = new float[terrain_height, terrain_width];
		map_effect = new float[terrain_height, terrain_width];
		map_alpha = new float[terrain_height-1,terrain_width-1];

		BuildTerrainBase ();
		ReloadTerrain ();
	}
	
	// Update is called once per frame
	void Update () {
		//ReloadTerrain ();
	}

	// Random base height
	void BuildTerrainBase(){
		// Terrain height
		int width = terrain_data.heightmapWidth;
		int height = terrain_data.heightmapHeight;
		for (int iy = 0; iy < width; iy++) {
			for (int jx = 0; jx < height; jx++) {
				float h1 = Mathf.PerlinNoise ((float)iy * randomSizeMain, (float)jx * randomSizeMain);
				float h2 = Mathf.PerlinNoise ((float)iy * randomSizeSub, (float)jx * randomSizeSub);
				map_height [iy, jx] = (h1 + h2*h2) / 2f;
			}
		}
		// Terrain texture
		width = terrain_data.alphamapWidth;
		height = terrain_data.alphamapHeight;
		for (int iy = 0; iy < width; iy++) {
			for (int jx = 0; jx < height; jx++) {
				float color = map_height [iy, jx];
				map_alpha [iy, jx] = 0;
			}
		}
	}

	void ReloadTerrain(){
		// Terrain height
		float[,] heights = new float[terrain_height,terrain_width];
		for (int iy = 0; iy < terrain_width; iy++) {
			for (int jx = 0; jx < terrain_height; jx++) {
				heights [iy, jx] = map_height [iy, jx] * map_effect [iy, jx];
			}
		}
		terrain_data.SetHeights (0, 0, heights);
		// Terrain texture
		int width = terrain_data.alphamapWidth;
		int height = terrain_data.alphamapHeight;
		float[,,] alphas = terrain_data.GetAlphamaps(0, 0, width, height);
		for (int iy = 0; iy < width; iy++) {
			for (int jx = 0; jx < height; jx++) {
				float alpha = map_alpha [iy, jx];// * map_effect [iy, jx];
				alphas [iy, jx, 0] = alpha;
				alphas [iy, jx, 1] = 1f - alpha;
			}
		}
		terrain_data.SetAlphamaps (0, 0, alphas);
	}

	public void HeapMap(float x, float y, float height){
		if (x < 0 || x > 1 || y < 0 || y > 1) {
			Debug.LogError ("Value of x , y is between 0.0f and 1.0f.");
		}
		// set start,goal point
		int s_x = Mathf.FloorToInt((float)terrain_width * Mathf.Max(0,x-mountainRadius));
		int s_y = Mathf.FloorToInt((float)terrain_height * Mathf.Max(0,y-mountainRadius));
		int g_x = Mathf.FloorToInt((float)(terrain_width-1) * Mathf.Min(0.999f,x+mountainRadius));
		int g_y = Mathf.FloorToInt((float)(terrain_height-1) * Mathf.Min(0.999f,y+mountainRadius));
		for (int iy = s_y; iy < g_y; iy++) {
			for (int jx = s_x; jx < g_x; jx++) {
				float my = ((float)iy - (float)s_y) / ((float)g_y - (float)s_y);
				float mx = ((float)jx - (float)s_x) / ((float)g_x - (float)s_x);
				float multiple = 1f-(Vector2.Distance (new Vector2 (x, y), new Vector2 (mx, my)) / mountainRadius);
				multiple = Mathf.Max (0, multiple);
				map_effect [iy, jx] += height * multiple;
				map_effect [iy, jx] = Mathf.Min (1f, map_effect [iy, jx]);
				if (multiple > 0.01f) {
					map_alpha [iy, jx] = 1f;
				}
			}
		}
		ReloadTerrain ();
	}

	public Vector3 WorldToMap(Vector3 position){
		Vector3 local_position = position - transform.position;
		local_position.x = local_position.x / terrain_data.size.x;
		local_position.y = local_position.y / terrain_data.size.y;
		local_position.z = local_position.z / terrain_data.size.z;
		return local_position;
	}
}