Jump to content
  • Advertisement
Sign in to follow this  
MYSTIORI

How to create smooth terrain following in height map?

This topic is 2483 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,

I'm writing a 3D world game which consists of a terrain map (generated by brownian motion algorithm) and a simple avatar. My goal is to make the avatar move smoothly between points of different height. Originally, I simply translate from start location to stop location, then set the height of this point based on the height value of a pair (x, z). Unfortunately the movement is completely off. I searched online I found several algorithms to create a smooth movement but I was not able to put them together. I just started to lean graphics for a month, so sorry for my dull knowledge.

My height map size is 512 * 512, and the spacing between each vertex is 150. Base on these values, I create a square around my destination as follows:






/*
* A B
* --------------
* | |
* | x |
* | |
* | |
* --------------
* C D
*/

// build square ABCD around stopLocation
int x = (int)stopLocation.X / 150;
int z = (int)stopLocation.Z / 150;

Vector3 A = new Vector3(x * 150, stage.surfaceHeight(x * 150, z * 150), z * 150);
Vector3 B = new Vector3((x + 1) * 150, stage.surfaceHeight((x + 1) * 150, z * 150), z * 150);
Vector3 C = new Vector3(x * 150, stage.surfaceHeight(x * 150, (z + 1) * 150), (z + 1) * 150);
Vector3 D = new Vector3((x + 1) * 150, stage.surfaceHeight((x + 1) * 150, (z + 1) * 150), (z + 1) * 150);



I use a simple algorithm to determine my destination plane:



public bool isInUpperPlane(Vector3 A, Vector3 B, Vector3 C, Vector3 D, Vector3 point) {

/*
^ y
|
|
|
| A B
----------------------------> x
/ /
/ x /
C /_________ / D
/
/
/
v z
*/

// consider A as the origin
if (Math.Abs(point.X - A.X) + Math.Abs(point.Z - A.Z) >= 150)
return true;
return false;
}




Next I construct a plane the 3 vertices (either ABC or BCD):



Plane destPlane;
if (isInUpperPlane(A, B, C, D, stopLocation)) {
destPlane = new Plane(A, B, C);
}
else {
destPlane = new Plane(B, C, D);
}

Then I project this my start location to this plane normal, and translate my avatar to this location:


Vector3 normal = destPlane.Normal;
Vector3 r = projectVectorToPlane(startLocation, normal);
Orientation *= Matrix.CreateTranslation(startLocation);


But doing this make my avatar stays still. It's very very wrong, but I really don't know how it works. The 3D world is just too confusing at this moment. Could anyone walk me through this problem?
This is my original implementation, (not smooth following)


public void updateMovableObject() {
Vector3 startLocation = Translation;
Vector3 stopLocation = Translation;

Orientation *= Matrix.CreateTranslation(-1 * Translation); // move to origin
Orientation *= Matrix.CreateRotationY(yaw); // rotate
Orientation *= Matrix.CreateRotationX(pitch);
Orientation *= Matrix.CreateRotationZ(roll);

stopLocation += ((step * stepSize) * Forward); // move forward

// if collision, reset location and return
if (model.IsCollidable && collision(stopLocation)) {
Orientation *= Matrix.CreateTranslation(startLocation); // don't move
return;
}

// no collision test if move on terrain
if (stage.withinRange(this.Name, stopLocation)) {
Orientation *= Matrix.CreateTranslation(stopLocation); // move forward
}
else { // off terrain, reset location
Orientation *= Matrix.CreateTranslation(startLocation); // don't move
}
}

Share this post


Link to post
Share on other sites
Advertisement
So, ABCD are the heighmap samples.
I don't quite understand what [color=#000000][size=2]

isInUpperPlane

is supposed to do. Is it meant to tell the outer code is in the ABCD quad? Of course it is! It wouldn't have been fetched otherwise! No, it does not do that. I don't understand what it does really... checking if a point is in a plane would require at least a dot product I suppose.
But anyway, we have this thing which is used to build a [color=#000000][size=2]

destPlane

.
What I miss is the absolute lacking of understanding of the basic logic. What's the deal with those planes? I don't understand.

There's a problem I can see for real. Assuming this [color=#000000][size=2]

destPlane

selection makes any sense I don't get, then building it as you do mandates all triangles/quads are built using the same tassellation. Perhaps this is the case for you. It wouldn't be the case for me.

Share this post


Link to post
Share on other sites
I just wrote a lesson on kasper fauerby's paper about collision detection and response. You can use an ellpsoid to approximate your avatar, then convert everthing to ellipsoid space, where the ellipsoid is a unit sphere. a unit sphere will very smoothly slide across triangles and "roll" across hard edges. if your interested, you can find it here: (it's in dx11, but the idea is the exact same, all you'll have to do is change the functions to the math library your using)

http://braynzarsoft.net/index.php?p=D3D11SlidingCamera

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!