Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Terrain Engine Math Problem

  1. #1
    Intern Contributor
    Join Date
    Jan 2001
    Location
    Germany
    Posts
    55

    Terrain Engine Math Problem

    I created a Terrain Engine which consists
    of Traingles in the following fashion:

    Code :
       h2__dist___h3
        |        /|
        |      /  |
    dist|    /    |dist
        |  /      |
        |/________|
       h1   dist  h4
    These Squares with the length 'dist' are
    put next to eachother. The amount of
    squares in x-Direction is 'xlength'.
    The amount in z-Direction is 'zlength'.
    Now the Terrain works perfectly so I
    will not go into the creation code.
    Here comes the Problem:
    I made an Algorithm that calculates the
    Height of the Terrain in any Point (x;z)
    but it doesn't seem to work perfectly.
    Heres the code maybe you can give me a
    better solution or correct mine:

    float GetHeightXZ(float x, float z)
    {
    int xx, zz;
    float halfx = (dist*xlength)/2;
    float halfz = (dist*zlength)/2;
    xx = (int)(xlength/2)+(x/dist);
    zz = (int)(zlength/2)+(z/dist);
    float xxw = x-((xx*dist)-halfx);
    float zzw = z-((zz*dist)-halfz);
    float h11, h33;
    if(zzw > xxw)
    {
    h11 = h1-h2;
    h33 = h3-h2;
    float prozent1 = h11/10000;
    float prozent2 = h33/10000;
    float prozent3 = dist/10000;
    x = h2+((((dist-zzw)/prozent3) *prozent1)+((xxw/prozent3)*prozent2));

    }
    else
    {
    h11 = h1-h4;
    h33 = h3-h4;
    float prozent1 = h11/10000;
    float prozent2 = h33/10000;
    float prozent3 = dist/10000;
    x = h4+(((zzw/prozent3)*prozent1)+(((dist-xxw)/prozent3)*prozent2));

    }
    return x;
    }

    Many thanks in advance.
    -Starnut

    [This message has been edited by Starnut coder (edited 12-30-2001).]

    [This message has been edited by Starnut coder (edited 12-30-2001).]

    [This message has been edited by Starnut coder (edited 12-30-2001).]
    -http://starnut.9ug.com
    Programming in Directx and Opengl

  2. #2
    Junior Member Regular Contributor
    Join Date
    Sep 2000
    Location
    Lubbock, TX, USA
    Posts
    197

    Re: Terrain Engine Math Problem

    Try this (i'll describe it only for the X axis and assume you're using a heightmap, rewriting it for getting the height from a mesh should be easy as long as you're on a regular grid).

    First, find out which square you're on (in other words, in between which vertices of your mesh or pixels of your heightmap you are). For example, if you have a 512 pixel wide heightmap that stretch from 0 to say 100 in world coordinates (playerX is your player's x position on that grid):

    xP = playerX*(512.0/100.0);

    then xp is your position on the map in pixels (i'll go with the heightmap 'cause it's easier to explain).

    now, you can find the heightmap pixel left and right of your player position with:

    left = (int)xP;
    right = left+1;

    then get the 2 heights from the heightmap

    hLeft = *(heightmap+left)
    hRight = *(heightmap+right)


    and then interpolate between these 2 positions depending on the position in between:

    i = (xP-left);
    playerHeightX = (1.0-i)*hLeft + i*hRight;

    of course you also have to consider the y axis of your heightmap but that's fairly easy to figure out

    Hope that helped

  3. #3
    Junior Member Regular Contributor
    Join Date
    Nov 2001
    Posts
    104

    Re: Terrain Engine Math Problem

    StarNut, you make the problem too complex for nothing. We've an even much more complex built landscape built of diamonds which can be made of 8, 4 or 2 tris depending on LOD, but we absolutely don't care about that on any heighttests and this works now since more than 2 years very fine, because the user anyway won't see any difference in general, if you check the exact triangles or not, so I think you make yourself much more work than needed. So simply use something like this:

    Code :
     
    float height(float fx,float fz)
    {
       float x2=x-floor(fx),z2=z-floor(fz);
       int x=(int) fx;
       int z=(int) fz;
       return (height[x,z]*(1-x2)+height[x+1,z]*x2)*(1-z2)+(height[x,z+1]*(1-x2)+height[x+1,z+1]*x2)*z2;
    };
     
    I think that should work. If you really want to test your triangles...hm...lemme see...something like (pseudocode)
     
    float height(float fx,float fz)
    {
       float x2=x-floor(fx),z2=z-floor(fz);
       int x=(int) fx;
       int z=(int) fz;
       cvector v1=vec(0,0,height[x,z]); //lower left
       cvector v2=vec(0,1,height[x,z+1]); //upper left
       cvector v3=vec(1,1,height[x+1,z+1]); //upper right
       cvector v4=vec(1,0,height[x+1,z]); //lower right
       cvector v5;
       if((x2+z2)<1) //lower left tri?
       {
          v5=StretchVec(VSumm(v1,v2),0.5); //middlepoint between upper right and lower left fieldcorner
          v4=VSumm(v2,StretchVec(VDiff(v5,v2),2)); //v4 now contains the 4th edge, if we had a flat quad using points v1,v2,v3 as first three points
          return (v1*(1-x2)+v4*x2)*(1-z2)+(v2*(1-x2)+v3*x2)*z2;
       }
       else
       {
          ...
       };
     
    VSumm = V+V2 //simple addition of all components
    VDiff = V2-V //vector from V2 -> V
    StretchVec = V*f //multiplication of all components with 2nd parameter
    I think this would work (in the case that a field had a width and depth of 1).

    Michael

    [This message has been edited by BlackJack (edited 12-31-2001).]

  4. #4
    Intern Contributor
    Join Date
    Jan 2001
    Location
    Germany
    Posts
    55

    Re: Terrain Engine Math Problem

    Thanks for your Answers Guys.
    Really appreciate it.
    -http://starnut.9ug.com
    Programming in Directx and Opengl

  5. #5
    Junior Member Regular Contributor
    Join Date
    Mar 2001
    Posts
    142

    Re: Terrain Engine Math Problem

    Hi!

    I was using this code in an old terrain engine. It was working perfectly.

    It is delphi code but should be easily readable.

    Code :
    function TTerrain.GetHeight(x, z: single): single;
    var
      gx, gy: integer;
      dx, dy: single;
      h1, h2, h3: single;
      xslope, yslope: single;
    begin
      Result := 0;
     
      gx := Trunc(x / 400); gy := Trunc(z / 400);
     
      if (gx < 0) or (gx > 1024) or (gy < 0) or (gy > 1024) then exit;
     
      dx := x - gx * 400; dy := z - gy * 400;
     
      h1 := HeightMap[gx, gy];
      h2 := HeightMap[gx + 1, gy + 1];
     
      if dx < dy then
      begin
        // left triangle
        h3 := HeightMap[gx, gy + 1];
        xslope := (h2 - h3) / 400;
        yslope := (h3 - h1) / 400;
     
        Result := h1 + (dx * xslope + dy * yslope);
      end
      else
      begin
        // right triangle    
    h3 := HeightMap[gx + 1, gy];
        xslope := (h3 - h1) / 400;
        yslope := (h2 - h3) / 400;
     
        Result := h1 + (dx * xslope + dy * yslope);
      end;
    end;

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •