Jump to content
  • Advertisement
Sign in to follow this  
cebugdev

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.

If you intended to correct an error in the post then please contact us.

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.

Please help me on how to generate a hills, given the vertex coordinate picked by the mouse, raise value and radius.

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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);
            float current_amount = (lift_radius - dist) / lift_radius;
            
            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);
        updateSubData(          start_block_x, block_y, end_block_x, block_y);    
    }
    
}
//******************************************************************************
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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. smile.png
I will post as soon as i have the result, this post can help others too.

Edited by cebugdev

Share this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!