Archived

This topic is now archived and is closed to further replies.

BrianDra2

Slopes just plain confuse me...

Recommended Posts

BrianDra2    122
Okay, here we go! I`ve created a simple 3D landscape that I would like my character(not a vechicle, but a living, breathing polygonal thing)to walk across. The problem is, the landscape isn''t just flat, there''s hills! But my character just walks right through the hills as if they''re not even there! So my main question is how do I get my character to climb up(and down) the hills. Now onto the fun stuff... I`ve got access to all the faces in the landscape, and all the vertices the faces are made up of. I`ve also got access to the normals of the vertices. (I`m using direct3d retained mode, if anybody cares) I`ve got access to the position of the character, and which face he''s standing on. So with that information, what can I do to tell my character to move up or down the hill? Are there any tutorials, websites, books, or anything at all that will help me understand how to do this? I know I probably have to use the slope formula, but I don''t see what to do once I have the results of the formula. Thanks, Brian Draeger briandra2@aol.com

Share this post


Link to post
Share on other sites
SiCrane    11839
You really don''t need a slope formula per se. Just take the desired velocity vector of your character, and when it intersects a polygon, adjust it''s real velocity to become the projection of the original vector onto the plane formed by the polygon (which should be trivial as you have the normal of the polygon.

Share this post


Link to post
Share on other sites
3dModelMan    204
Here''s one way of doing the sums;

take 1 vertex of the face
get a distance between that vertex and the player (xdis & zdist)
player height = vertex.y + (xdist * xnormal) + (zdist * znormal)

Something like that anyway

Cheers

Matt



Share this post


Link to post
Share on other sites
BrianDra2    122
Thanks for the answers:
SiCrane - Your answer is beyond my intelligence. Maybe if I take some more math courses I`ll understand what your trying to say. Thanks anyway.

3DModelMan - I tired out your formula and it works! My little character now happily climbs up a hill with ease. However, when the character trys to climb down a hill, he falls about 5 feet and then continues to climb downwards. This is probably a problem in my code, but if you have any ideas please tell me.

Thanks,
Brian Draeger
briandra2@aol.com

Share this post


Link to post
Share on other sites
3dModelMan    204
Thanks for asking Chris, the truth is IT DOESN''T WORK!! Your question made me go back to write an explanation!

My terrain code was the first thing I tackled for my project and I was still experimenting A LOT. For a start I was normalising the surface normals incorrectly. Something I realised a long time ago, but never went back to fix it, if I had I would have found this problem sooner.

I was dividing by the larget component, to make one of the values 1.0 and the rest a product of it;

(12, 18, 7) became (0.6666, 1, 0.38888) - divide by 18

My solution currently *approximates* the result at best. I never really noticed much error because my ground faces are quite small, so I think this is why it still looked ok even on 45 degree faces.

Sorry if I''ve led anyone astray.

I''m about to start a complete bounding box collision detection system for my vehicle so I''ll need to fix it!

Bye

Matt



Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
I don''t use D3D... but I''m having the same problem with my app. What is "xnormal" and "znormal"?

Share this post


Link to post
Share on other sites
BrianDra2    122
Anonymous Poster:
xnormal and znormal are the normals of a face - assumably the face your character is standing on. Most SDK''s have functions that will find the normal of a face. I don''t know how to find a normal of a face otherwise..

Share this post


Link to post
Share on other sites
Sydan    122
I''m having the same problem.. it really astonishes me that there is no "tried and true" formula for doing this. It seems like everyone and their dog would be making a simple terrain for someone to walk over.

I can get the normals for a face from a built in function based on three coordinates. But to be honest I have no idea what the heck they mean. I know a normal runs perpendicular to my face... but what do the xyz of that vector point to? A point in space? From my experiments they seem to point the opposite way and barely move no matter what direction the face is pointing.

Sigh. I''ll never figure this out.

Share this post


Link to post
Share on other sites
monkeyman    253
Smooth collision detection isn''t really so bad when you get a few things working..there are many ways you could optimize terrain collision, but here''s a general all purpose method of smooth collision detection that should work in several implementations..

First of all you have to determine which surface you are near enough to clip against..then clip the model position against that surface in 3d space..(you will have to add some height offset to the model unless the origin is at the bottom)..

Let''s assume that the model position is a single vertex(you can easily use this same code for multiple vertices)..
You would also need to determine minimum_clipping_distance..this is how close you can get to a surface before it ''pushes back''..this distance should be slightly larger than the model''s average movement per frame...

Here''s how you would clip against a surface and make it smooth:

Get the distance from the vertex to the plane of the surface..let''s call this distance_from_plane..
If distance_from_plane is greater than your minimum_clipping_distance, there is no collision necessary..
IF NOT
You need to find out how far into this clipping region you are..let''s call this distance_inside_clipping_zone..

distance_inside_clipping_zone = (minimum_clipping_distance-distance_from_the_plane)

that was easy..
now that we know how far into the clipping region we are, we just need to relocate the model..

model.x += surface.xnormal*distance_inside_clipping_zone;
model.y += surface.ynormal*distance_inside_clipping_zone;
model.z += surface.znormal*distance_inside_clipping_zone;

WARNING!!
(you may have to -= if you are colliding with the back of a surface..front/back test is easy to check, just subtract values instead of adding)..
////////////////////////////////////////
WHY THIS IS COOL

No matter how you come at a surface, it will always push you out a consistent distance..add a constant gravity drop and the model will actually slide down ramps on it''s own..when moving forward up a ramp, your forward motion is hampered depending on the angle of the surface..when you walk into a wall you will slide smoothly along..

The math isn''t so bad either..assuming you''ve already got normals for your surfaces, here''s all you have to do:

Calculate the distance from a point to a plane..
Subtract that from the minimum_clipping_distance..
To the model vertex, add the surface normal multiplied by the distance inside the clipping region..

If you need help with any of the math feel free to email me
Enjoy,
-MM


"Like all good things, it starts with a monkey.."

Share this post


Link to post
Share on other sites
BrianDra2    122
>Get the distance from the vertex to the plane of the >surface..let''s call this distance_from_plane..

I need this clairifed a little more(like actual code would help alot)


Thanks,
Brian Draeger
briandra2@aol.com

Share this post


Link to post
Share on other sites
fenrir    122
Here is what I used

double ret = 0.0f ;

double x1, x2, x3, y1, y2, y3, z1, z2, z3;
x1 = map[Fi][Fj].x; y1 = map[Fi][Fj].y; z1 = map[Fi][Fj].z;
x2 = map[Ci][Fj].x; y2 = map[Ci][Fj].y; z2 = map[Ci][Fj].z;
x3 = map[Ci][Cj].x; y3 = map[Ci][Cj].y; z3 = map[Ci][Cj].z;
double a,c,d,e,f,g,h,i;
a = x - x1;
c = z - z1;
d = x1 -x2;
e = y1 -y2;
f = z1 -z2;
g = x1 -x3;
h = y1- y3;
i = z1 -z3;
ret = (g*e*c +a*h*f - a*e*i - d*h*c)/(g*f - d*i) + y1;
return ret;



Better explain a little
You say you know what face you are on, so you just put the 3 vertices from that face in x1, y1, z1, ...
From there I calculate the plane that face is on, and I check at wich point it intersects wih a line going straight through the point x, z from (a = x - x1;c = z - z1
y goes up in my landscape engine
This is probably the wordst explanation ever but I hope it helps

Share this post


Link to post
Share on other sites
JizzRoy    122
Heheh .. if you''re using a height map.. which I''m sure you are.. compare the coordinates where YOU are at to the ones in the heightmap and adjust your height accordingly.. NOW you have a VERY crude walking system.

Simply put.. CHEAP and ugly. though it can be refined easily by looking at where you are inside the quad for the terrain (two tris rather). then running some distance and weighting calculations


If you need some more help..
email me at jizzroy@hotmail.com

good luck

Share this post


Link to post
Share on other sites
Sydan    122
I figured out a quick solution to this about a month ago after beefing up my multi-variable calculus

The plane formula does work if you use it correctly. I wasn''t.

The formula Ax+By+Cz=0 is a simplification of the formula A(x0-x1)+B(y0-y1)+C(z0-z1)=0. In other words if you''re just plugging in values for x,y and z into the first formula you''re going to go wrong every time unless they are relative to zero.

If, on the other hand, you use the non-simplified formula, you get the results you want: x0, y0, z0 is the coordinate of any known point on the plane (just use any vertex of the plane you''re on), and x1,y1,z1 is the point you are looking for (use algebra to modify the formula to find y1).

I''ve been using the plane formula successfully for 4 weeks now and it is smooth as silk on landscapes. It also doubles as a very fast method for projectile/landscape collision detection.





Share this post


Link to post
Share on other sites