- Home /
Question by
siaran · Apr 25, 2015 at 09:29 AM ·
terrainheightmapterraindata
Raise a *circle* on a terrain
I'm trying to do some runtime terrain deformation. Now, I can raise (or lower) a square on the terrain easily enough, but I cannot figure out how to get a (smooth) circle.
Here is my code:
Terrain terrain;
TerrainData tData;
int heightmapWidth;
int heightmapHeigth;
public float radius;
public float maxHeight = 0.03f;
float currentHeight;
float[,] originalHeights;
// Use this for initialization
void Start () {
terrain = Terrain.activeTerrain;
tData = terrain.terrainData;
heightmapHeigth = tData.heightmapHeight;
heightmapWidth = tData.heightmapWidth;
originalHeights = tData.GetHeights(0,0, heightmapWidth, heightmapHeigth);
}
void OnDestroy(){
tData.SetHeights(0,0,originalHeights);
}
// Update is called once per frame
void Update () {
if(currentHeight < maxHeight) {
Vector3 relPos = (transform.position - terrain.transform.position);
Vector3 coord = new Vector3(relPos.x/tData.size.x, relPos.y/tData.size.y, relPos.z/tData.size.z);
int terrainX = (int) (coord.x * heightmapWidth);
int terrainY = (int) (coord.z * heightmapHeigth);
Debug.Log(terrainY);
int size = 10;
int offset = size/2;
/*
* This raises a square
*
float[,] heights = tData.GetHeights(terrainX-offset, terrainY-offset, size, size);
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
heights[i,j] = Mathf.Max(heights[i,j], currentHeight);
}
}
tData.SetHeights(terrainX-offset, terrainY-offset, heights);
*/
//raise a circle. sort of.
float[,] heights = tData.GetHeights(0,0, heightmapWidth, heightmapHeigth);
for(int x = terrainX - offset; x < terrainX + offset; x++){
for(int y = terrainY - offset; y < terrainY+offset; y++){
if(( new Vector2(terrainX, terrainY)-new Vector2(x,y) ).sqrMagnitude < 25){
heights[y,x] = currentHeight;
}
}
}
tData.SetHeights(0, 0, heights);
currentHeight += 0.03f * Time.deltaTime;
}
}
When I use this, though, my circle is very, ah, blocky. How would I get a smooth one?
Comment
Best Answer
Answer by siaran · Apr 25, 2015 at 03:38 PM
Ok, figured it out. mostly it involves not raising the very edges of the area I raise but interpolating it a bit.
updated code snip:
float[,] heights = tData.GetHeights(0,0, heightmapWidth, heightmapHeigth);
for(int x = terrainX - offset; x < terrainX + offset; x++){
for(int y = terrainY - offset; y < terrainY+offset; y++){
float currentRadiusSqr = (new Vector2(terrainX, terrainY)-new Vector2(x,y) ).sqrMagnitude ;
if( currentRadiusSqr < offset*offset){
heights[y,x] = currentHeight * (1 - currentRadiusSqr/(offset*offset));
}
}
}
Now, time to see about updating textures! And also maybe making this a bit more efficient.