using UnityEngine;
using System.Collections; public class terrainTest : MonoBehaviour
{
public int terrainDeformationTextureNum = ;
private Terrain terr; // terrain to modify
protected int hmWidth; // heightmap width
protected int hmHeight; // heightmap height
protected int alphaMapWidth;
protected int alphaMapHeight;
protected int numOfAlphaLayers;
protected const float DEPTH_METER_CONVERT = 0.05f;
protected const float TEXTURE_SIZE_MULTIPLIER = 1.25f;
private float[,] heightMapBackup;
private float[, ,] alphaMapBackup; void Start()
{
terr = this.GetComponent<Terrain>();
hmWidth = terr.terrainData.heightmapWidth;
hmHeight = terr.terrainData.heightmapHeight;
alphaMapWidth = terr.terrainData.alphamapWidth;
alphaMapHeight = terr.terrainData.alphamapHeight;
numOfAlphaLayers = terr.terrainData.alphamapLayers;
if (Debug.isDebugBuild)
{
heightMapBackup = terr.terrainData.GetHeights(, , hmWidth, hmHeight);
alphaMapBackup = terr.terrainData.GetAlphamaps(, , alphaMapWidth, alphaMapHeight);
}
} //this has to be done because terrains for some reason or another terrains don't reset after you run the app
void OnApplicationQuit()
{
if (Debug.isDebugBuild)
{
terr.terrainData.SetHeights(, , heightMapBackup);
terr.terrainData.SetAlphamaps(, , alphaMapBackup);
}
} public void DestroyTerrain(Vector3 pos, float craterSizeInMeters)
{
DeformTerrain(pos, craterSizeInMeters);
TextureDeformation(pos, craterSizeInMeters * 1.5f);
} public void DeformTerrain(Vector3 pos, float craterSizeInMeters)
{
//get the heights only once keep it and reuse, precalculate as much as possible
Vector3 terrainPos = GetRelativeTerrainPositionFromPos(pos, terr, hmWidth, hmHeight);//terr.terrainData.heightmapResolution/terr.terrainData.heightmapWidth
int heightMapCraterWidth = (int)(craterSizeInMeters * (hmWidth / terr.terrainData.size.x));
int heightMapCraterLength = (int)(craterSizeInMeters * (hmHeight / terr.terrainData.size.z));
int heightMapStartPosX = (int)(terrainPos.x - (heightMapCraterWidth / ));
int heightMapStartPosZ = (int)(terrainPos.z - (heightMapCraterLength / )); float[,] heights = terr.terrainData.GetHeights(heightMapStartPosX, heightMapStartPosZ, heightMapCraterWidth, heightMapCraterLength);
float circlePosX;
float circlePosY;
float distanceFromCenter;
float depthMultiplier; float deformationDepth = (craterSizeInMeters / 3.0f) / terr.terrainData.size.y; // we set each sample of the terrain in the size to the desired height
for (int i = ; i < heightMapCraterLength; i++) //width
{
for (int j = ; j < heightMapCraterWidth; j++) //height
{ circlePosX = (j - (heightMapCraterWidth / )) / (hmWidth / terr.terrainData.size.x);
circlePosY = (i - (heightMapCraterLength / )) / (hmHeight / terr.terrainData.size.z);
distanceFromCenter = Mathf.Abs(Mathf.Sqrt(circlePosX * circlePosX + circlePosY * circlePosY));
//convert back to values without skew if (distanceFromCenter < (craterSizeInMeters / 2.0f))
{
depthMultiplier = ((craterSizeInMeters / 2.0f - distanceFromCenter) / (craterSizeInMeters / 2.0f)); depthMultiplier += 0.1f;
depthMultiplier += Random.value * .1f; depthMultiplier = Mathf.Clamp(depthMultiplier, , ); if(heights[i,j] <0.1) heights[i, j] = Mathf.Clamp(heights[i, j] +deformationDepth * depthMultiplier, , ); }
}
} // set the new height
terr.terrainData.SetHeights(heightMapStartPosX, heightMapStartPosZ, heights);
} public void TextureDeformation(Vector3 pos, float craterSizeInMeters)
{
Vector3 alphaMapTerrainPos = GetRelativeTerrainPositionFromPos(pos, terr, alphaMapWidth, alphaMapHeight);
int alphaMapCraterWidth = (int)(craterSizeInMeters * (alphaMapWidth / terr.terrainData.size.x));
int alphaMapCraterLength = (int)(craterSizeInMeters * (alphaMapHeight / terr.terrainData.size.z)); int alphaMapStartPosX = (int)(alphaMapTerrainPos.x - (alphaMapCraterWidth / ));
int alphaMapStartPosZ = (int)(alphaMapTerrainPos.z - (alphaMapCraterLength / )); float[, ,] alphas = terr.terrainData.GetAlphamaps(alphaMapStartPosX, alphaMapStartPosZ, alphaMapCraterWidth, alphaMapCraterLength); float circlePosX;
float circlePosY;
float distanceFromCenter; for (int i = ; i < alphaMapCraterLength; i++) //width
{
for (int j = ; j < alphaMapCraterWidth; j++) //height
{
circlePosX = (j - (alphaMapCraterWidth / )) / (alphaMapWidth / terr.terrainData.size.x);
circlePosY = (i - (alphaMapCraterLength / )) / (alphaMapHeight / terr.terrainData.size.z); //convert back to values without skew
distanceFromCenter = Mathf.Abs(Mathf.Sqrt(circlePosX * circlePosX + circlePosY * circlePosY)); if (distanceFromCenter < (craterSizeInMeters / 2.0f))
{
for (int layerCount = ; layerCount < numOfAlphaLayers; layerCount++)
{
//could add blending here in the future
if (layerCount == terrainDeformationTextureNum)
{
alphas[i, j, layerCount] = ;
}
else
{
alphas[i, j, layerCount] = ;
}
}
}
}
} terr.terrainData.SetAlphamaps(alphaMapStartPosX, alphaMapStartPosZ, alphas);
} protected Vector3 GetNormalizedPositionRelativeToTerrain(Vector3 pos, Terrain terrain)
{
//code based on: http://answers.unity3d.com/questions/3633/modifying-terrain-height-under-a-gameobject-at-runtime
// get the normalized position of this game object relative to the terrain
Vector3 tempCoord = (pos - terrain.gameObject.transform.position);
Vector3 coord;
coord.x = tempCoord.x / terr.terrainData.size.x;
coord.y = tempCoord.y / terr.terrainData.size.y;
coord.z = tempCoord.z / terr.terrainData.size.z; return coord;
} protected Vector3 GetRelativeTerrainPositionFromPos(Vector3 pos, Terrain terrain, int mapWidth, int mapHeight)
{
Vector3 coord = GetNormalizedPositionRelativeToTerrain(pos, terrain);
// get the position of the terrain heightmap where this game object is
return new Vector3((coord.x * mapWidth), , (coord.z * mapHeight));
}
}

u3d change terrain textrue&height的更多相关文章

  1. how to change the AlexNet into FCNs ?

    How to change the AlexNet into FCNs ? FCNs is a network that only contain convolution layers and no ...

  2. ArcGIS空间分析工具

    1. 3D分析 1.1. 3D Features toolset 工具 工具 描述 3D Features toolset (3D 要素工具集) Add Z Information 添加 Z 信息 添 ...

  3. KVC 和 KVO

    KVC 键值编码    全称是Key-value coding,翻译成键值编码.它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制.        1.通过key(成员变量的名称)设置 ...

  4. VC CComboBox用法总结

    VC每日一练,虽然简单,不动手试一下不能真正记住. 大气象 CComboBox *comboBox=(CComboBox*)GetDlgItem(IDC_COMBO1); comboBox->I ...

  5. JAVA生成图片缩略图、JAVA截取图片局部内容

    package com.ares.image.test; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; ...

  6. overlay-3

    if(typeof Shadowbox=="undefined"){ throw"Unable to load Shadowbox, no base library ad ...

  7. Web 在线文件管理器学习笔记与总结(2)显示文件列表(名称,类型,大小,可读,可写,可执行,创建时间,修改时间,访问时间)

    主要函数: filetype() 判断文件类型 filesize() 得到文件大小(字节) is_readable() 判断文件是否可读 is_writeable() 判断文件是否可写 is_exec ...

  8. unity3d 基于物理渲染的问题解决

    最近1个月做了unity 次世代开发的一些程序方面的支持工作,当然也是基于物理渲染相关的,主要还是skyshop marmoset的使用吧,他算是unity4.x版本 PBR的优秀方案之一了但在使用以 ...

  9. v4l2采集视频和图片源码

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h&g ...

随机推荐

  1. C++防止头文件反复包括

    两种方法: (1)#pragma once. (2)ifndef/define/endif 差别: (1)#pragma once是编译器相关的.有的编译器支持,有的编译器不支持: (2)#ifnde ...

  2. Android开发之控制摄像头拍照

    如今的手机一般都会提供相机功能,有些相机的镜头甚至支持1300万以上像素,有些甚至支持独立对焦.光学变焦这些仅仅有单反才有的功能,甚至有些手机直接宣传能够拍到星星.能够说手机已经变成了专业数码相机.为 ...

  3. JBoss DataGrid的集群部署与訪问

    集群部署 JDG的缓存模式包含本地(Local)模式和集群(Clustered)模式.本项目採用多节点的Clustered模式部署.数据在多个节点的子集间进行复制.而不是同步拷贝到全部的节点. 使用子 ...

  4. js获取当前页面url网址等信息

    使用js获取当前页面的url网址信息. 1.设置或获取整个 URL 为字符串: window.location.href 2.设置或获取与 URL 关联的端口号码: window.location.p ...

  5. Javascript玩转继承(一)

    Javascript究竟是一门面向对象的语言,还是一门支持对象的语言,我想每个人都有着自己的看法.那些Javascript忠实的Fans一定讲Javascript是一门面向对象的语言,像<Jav ...

  6. 简单好用的hash表-----uthash

    在软件开发中,不可不免的会使用到hash表,hash表的优点这里就不说了,以下介绍一个hash表的C实现, uthash是用宏实现的,使用的时候非常方便,只用包含uthash.h即可. Uthash的 ...

  7. Spark大师之路:广播变量(Broadcast)源码分析

    概述 最近工作上忙死了……广播变量这一块其实早就看过了,一直没有贴出来. 本文基于Spark 1.0源码分析,主要探讨广播变量的初始化.创建.读取以及清除. 类关系 BroadcastManager类 ...

  8. gulp的使用以及Gulp新手入门教程

    Gulp新手入门教程 原文  http://w3ctrain.com/2015/12/22/gulp-for-beginners/ Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 搭 ...

  9. 我对C++的一些疑问

    我对C++的一些疑问,最近使用C++,总感觉有些东西自己没有抓住,也可能是自己基础学的不是很扎实,所以对一些基本的东西理解不够透彻导致的.因为自己在学校也学过C#和java,C#它是一个完全的面向对象 ...

  10. Logstash5.3借助临时字段修改@timestamp为北京时间,方便按天生成output文件

    $more config/first-pipeline.conf input { beats { port => " } } filter { if [type] == "s ...