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. 在 Windows 8 中启用可匿名访问的共享

    就是不用输入用户名和密码,直接通过网上邻居可以访问的共享. 1.打开本地组策略编辑器(快捷键Win+R,打开运行,输入gpedit.msc,确定): 2.打开:"本地计算机策略->计算 ...

  2. 最简短的openvpn的设置方式

    这种方式对于测试能否连接到远程系统,十分的有用.尤其是国内复杂的网络环境下,检测一下,到底是服务器的原因,还是网络因素造成的,这是一个快捷的方式. 需要注意的是:这种方法是用明文连接.所有的加密措施都 ...

  3. [svc][op]磁盘MBR分区机制- inode/Block深入实战

    一 思路: 1,磁盘物理结构及大小计算 2,分区 MBR GPT知识 3,fdisk分区 挂载 自动挂载 4,格式化文件系统 5,inode block 6,软硬链接 查看磁盘: [root@moba ...

  4. 斯坦福IOS开发第五课(第二部分)

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/27845257 作者:小马 五 代码演示样例 上面讲到的知识点在这个演示样例都有涉及 ...

  5. linux系统信息查询及相关概念

    1.查看机器可以插几根内存条: /sbin/lspci  -v 或dmesg 或  dmidecode(需要root) 2.查看机器有几块盘,是否做raid: blkid 或 fdisk -l 或 s ...

  6. LeetCode 新题: Find Minimum in Rotated Sorted Array II 解题报告-二分法模板解法

    Find Minimum in Rotated Sorted Array II Follow up for "Find Minimum in Rotated Sorted Array&quo ...

  7. java web 中 读取windows图标并显示

    java web中读取windows对应文件名的 系统图标 ....显示 1.获取系统图标工具类 package utils;  import java.awt.Graphics;  import j ...

  8. redis使用redis-cli查看所有的keys及清空所有的数据

    redis_home:redis安装路径: cd %redis_home%/src ./redis-cli -h 127.0.0.1   127.0.0.1:6379> keys *   (em ...

  9. Android中自定义控件,三个构造函数

    自定义控件时,最好抽象得彻底,并且编写需严谨,因为可能程序中多处都会引用到它,或者提供给团队中的其他人使用. 其一般步骤为: 1.创建控件的类文件,定义其功能逻辑.一般继承自现有控件或者View 2. ...

  10. plsql 只能识别32位的oracle解决办法

    http://www.cnblogs.com/ymj126/p/3712727.html#undefined