# Terrain editing question, how to make hills

This topic is 2152 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

hi all,

Ive been trying to make my terrain editor work, but i do not know on how to create a hills from it.

my current situation is I already got my terrain mesh and my picking working, it can pick a certain vertex in the terrain, and i Can raise the height of that vertex only. But it can only generate a stiff Cone (and an ugly one).

I dont know how to generate a beautifull hills out of it.

ive been searching google for some formula but havent had the luck.

IF you can point me to a sample or a tutorial on how to do its much better.

given: index of the vertex picked in my heightmap: pVertex array

hopefully someone can help me with this,

thanks,

Edited by cebugdev

##### Share on other sites

Select all other vertices within the desired range from the selected vertex and raise them. The amount by which you raise them would have to be some function of, for example, the radial distance from the selected vertex.

For example, if you want to make a smooth hill with height H and radius R, then select all vertices within a radius R from the selection. Then raise vertex n by H*(.5 + .5*cos(|pn-c|*pi/R)), where pn is the position of the point n and c is the center point. The cosine function makes the hill smooth, with height H at the center and falls of to zero at radius R.

There are plenty of different functions you can use to get different appearances and shapes.

##### Share on other sites
//******************************************************************************
void CHeightMap::liftSurface(float x, float y, float c, bool flatten){

int start_point_x =    static_cast_INT( (x - lift_radius) / SB_size) + 1;
int end_point_x =      static_cast_INT( (x + lift_radius) / SB_size);

int start_point_y =    static_cast_INT( (y - lift_radius) / SB_size) + 1;
int end_point_y =      static_cast_INT( (y + lift_radius) / SB_size);

start_point_x = CMathEA::limit_Int( start_point_x, 0, HM_point_count_x - 1);
end_point_x =   CMathEA::limit_Int( end_point_x,   0, HM_point_count_x - 1);

start_point_y = CMathEA::limit_Int( start_point_y, 0, HM_point_count_y - 1);
end_point_y =   CMathEA::limit_Int( end_point_y,   0, HM_point_count_y - 1);

if(
(end_point_x - start_point_x == 0) ||
(end_point_y - start_point_y == 0)
)
return;

for( int P_y = start_point_y; P_y <= end_point_y; ++P_y)
for( int P_x = start_point_x; P_x <= end_point_x; ++P_x){

float d_x = P_x * SB_size - x;
float d_y = P_y * SB_size - y;
float dist = sqrt( d_x * d_x + d_y * d_y);

if( current_amount < 0.0)
continue;

if( flatten)
current_amount = 1.0;
else
current_amount = current_amount * current_amount * (3 - 2*current_amount);      //Hermite interpolation.

liftPoint( static_cast_UINT( P_x), static_cast_UINT( P_y), c * current_amount, flatten);
}

updateNormals( start_point_x, start_point_y, end_point_x, end_point_y);

//******************************************************
if( start_point_x > 0) --start_point_x;
if( start_point_y > 0) --start_point_y;

UInt start_block_x =    static_cast_UINT( start_point_x / block_size_SB);
UInt end_block_x =      static_cast_UINT( end_point_x   / block_size_SB) + 1;

UInt start_block_y =    static_cast_UINT( start_point_y / block_size_SB);
UInt end_block_y =      static_cast_UINT( end_point_y   / block_size_SB) + 1;

if( end_block_x >= HM_size_BLOCKS_x) end_block_x = HM_size_BLOCKS_x;
if( end_block_y >= HM_size_BLOCKS_y) end_block_y = HM_size_BLOCKS_y;

for( UInt block_y = start_block_y; block_y < end_block_y; ++block_y){

refreshVertexArrays(    start_block_x, block_y, end_block_x, block_y, false, true, true);
}

}
//******************************************************************************
void CHeightMap::liftPoint(UInt P_x, UInt P_y, float c, bool flatten){

if( !flatten)
height_map[P_x][P_y] += c;
else
height_map[P_x][P_y] =  c;

}
static UInt limit_Int( int input,  int limit_min,  int limit_max)           {if( input < limit_min) return limit_min;   if( input > limit_max) return limit_max;    return input;}

SB_size is the actual size of a square from the heightmap.

The part after update normals is because my HM is divided to smaller blocks which is good when you dont want to update the whole buffer or dont want to draw all of it.

Hermite interpolation is what will make it look nice.

http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml

##### Share on other sites

Select all other vertices within the desired range from the selected vertex and raise them. The amount by which you raise them would have to be some function of, for example, the radial distance from the selected vertex.

For example, if you want to make a smooth hill with height H and radius R, then select all vertices within a radius R from the selection. Then raise vertex n by H*(.5 + .5*cos(|pn-c|*pi/R)), where pn is the position of the point n and c is the center point. The cosine function makes the hill smooth, with height H at the center and falls of to zero at radius R.

There are plenty of different functions you can use to get different appearances and shapes.

By selecting the vertices within the radius, do you mean those vertices square around the center point?

0     1    2    3    4

5     6     7    8   9

10  11   12  13  14

example above, if the selected vertex is 7 and we have a radius of 1, does it mean the vertices, 1,2,3,6,8,11,12,13?

##### Share on other sites

In my particular example, you would have to calculate the radial distance, so your selection would have to be circular. It all depends on what function you use and what you want to achieve in the end. That is just because the function I used as the example is only well behaved (as far as the hill-generation is concerned) within the radial distance R. There are plenty of ways to do it, and your selection and function are dependent on each other.

##### Share on other sites

In my particular example, you would have to calculate the radial distance, so your selection would have to be circular. It all depends on what function you use and what you want to achieve in the end. That is just because the function I used as the example is only well behaved (as far as the hill-generation is concerned) within the radial distance R. There are plenty of ways to do it, and your selection and function are dependent on each other.

can you give me an example of getting the vertex using the radial distance please? :)

##### Share on other sites

vector2 d = p[n] - c;

if(d.x*d.x + d.y*d.y < R*R) {
// point p[n] is inside the circle R units from the point c
} else {
// point p[n] is outside
}


##### Share on other sites
vector2 d = p[n] - c;

if(d.x*d.x + d.y*d.y < R*R) {
// point p[n] is inside the circle R units from the point c
} else {
// point p[n] is outside
}


thanks, i will try this.
I will post as soon as i have the result, this post can help others too.

Edited by cebugdev

##### Share on other sites

Select all other vertices within the desired range from the selected vertex and raise them. The amount by which you raise them would have to be some function of, for example, the radial distance from the selected vertex.

For example, if you want to make a smooth hill with height H and radius R, then select all vertices within a radius R from the selection. Then raise vertex n by H*(.5 + .5*cos(|pn-c|*pi/R)), where pn is the position of the point n and c is the center point. The cosine function makes the hill smooth, with height H at the center and falls of to zero at radius R.

There are plenty of different functions you can use to get different appearances and shapes.

i have another question, where did the 0.5 values came from?

im still getting a pointy hill and not a cone, ill post the logs in a while :(

##### Share on other sites

The function maps one half of a period of the cosine function from the range [-1, 1] to [0 1]. The function (.5 + .5*x) linearly maps x from the range [-1, 1] to the range [0 1].

Edited by Brother Bob

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 15
• 21
• 26
• 11