Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / 3D Theory & Graphics / Direct3D Terrain Location Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
WantsToWalk

August 08, 1999, 11:46 PM

Alright, here is the problem I am having. I created a 3d polygonal landscape by loading a bitmap that had height data in it. It looks pretty cool and all, but I want to walk around it now, and have my view go up and down and such as I walk over the hills. But here's where the problem comes in. I have created the World, View, and Projection matrices, and so I can technically move around the land. But, I can't get the collision with the ground working correctly. I figure that if I'm going to do this, I have to get the coordinates of where I am viewing from. Like a 2d game, from an overhead view.
So first I set about calculating my turning angles. When I rotate, I simply Translate the X coordinate by 1.0 or -1.0. I made an angle variable, a float. I find that each rotation of 1.0 (or -1.0) is ~ 90/15.7 But of course this isn't incredibly acurate, because if you turn around enough times you discover that it's not truly a correct value. BTW, this is all out of 360 degrees. Anyway, It works fair enough for me to try what I need, you'd have to turn around about 50 times to see the problems. Well, I have a D3DVECTOR Velocity declared, and I update it each time I move forward by increasing the z value. I also have an X and Y value stored as the coordinates of my viewing point. so each time i update the position, I change them as follows:

x-=sin(0.0174532925*angle)*Velocity.z;
y-=cos(0.0174532925*angle)*Velocity.z;

that big float happens to be pi / 180. Now, this seems to work fine, but I decided to test it's accuracy by coloring the triangle I am standing on, and it's not accurate in the least! It's all driving me crazy, and I've decided to scrap that pile of junk and do it the right way. How do i do it the right way! I figure that I'll need to do it realistically, aka instead of incrementing a float each time I rotate, have the angle actually be directly related to the rotation. And I'm pretty sure I need to get those coordinates of the viewing point, so Is there a good way to do this? AHHH! This is all madenning!

 
Zinger

August 09, 1999, 11:00 PM

Seems like an easy solution. Maybe, I am missing something here. If you are using a bitmap to store your heightfield information then the collision calculations are easy.

Let's take a simple case where there are gradual changes in the terrain. Maybe there are a few hills. In this case there are no obstacles that could prevent you from traveling from point A to point B.

void Navigate::cameraPosition( const D3DVECTOR& delta )
{
// add delta to current camera position.
vectorAdd( &m_cameraPos, &m_cameraPos, &delta );

// calculate your height and set it! hfBitmapHeight basically just indexes into the bitmap
// and retrieves the height at position ( x, z ) to give you height ( y ).
m_cameraPos.y = Terrain::singleton().hfBitmapHeight( m_cameraPos.x, m_cameraPos.z );

// now you need to add your eye level here. Your eye level is not at ground level. :)
m_cameraPos.y += m_viewingHeight;
}

Obviously, this last method would allow you to walk over tall walls with sudden abrupt changes in y direction. So now you just need to modify it so that so you can check based on some delta whether you can go in that direction.

void Navigate::cameraPosition( const D3DVECTOR& delta )
{
// candidate position
D3DVECTOR pos = { m_cameraPos.x + delta.x,
m_cameraPos.y + delta.y,
m_cameraPos.z + delta.z };

// retrieve current height
float currentHeight = Terrain::singleton().hfBitmapHeight( m_cameraPos.x, m_cameraPos.z );
float candidateHeight = Terrain::singleton().hfBitmapHeight( pos.x, pos.z );

float dy = fabs( currentHeight - candidateHeight );

if ( dy > So first I set about calculating my turning angles. When I rotate, I simply Translate the X coordinate by 1.0 or -1.0. I made an angle variable, a float. I find that each rotation of 1.0 (or -1.0) is ~ 90/15.7 But of course this isn't incredibly acurate, because if you turn around enough times you discover that it's not truly a correct value. BTW, this is all out of 360 degrees. Anyway, It works fair enough for me to try what I need, you'd have to turn around about 50 times to see the problems. Well, I have a D3DVECTOR Velocity declared, and I update it each time I move forward by increasing the z value. I also have an X and Y value stored as the coordinates of my viewing point. so each time i update the position, I change them as follows:
>>
>> x-=sin(0.0174532925*angle)*Velocity.z;
>> y-=cos(0.0174532925*angle)*Velocity.z;
>>
>>that big float happens to be pi / 180. Now, this seems to work fine, but I decided to test it's accuracy by coloring the triangle I am standing on, and it's not accurate in the least! It's all driving me crazy, and I've decided to scrap that pile of junk and do it the right way. How do i do it the right way! I figure that I'll need to do it realistically, aka instead of incrementing a float each time I rotate, have the angle actually be directly related to the rotation. And I'm pretty sure I need to get those coordinates of the viewing point, so Is there a good way to do this? AHHH! This is all madenning!

 
WantsToWalk

August 10, 1999, 01:33 PM


>> m_cameraPos.y += m_viewingHeight;


well, yes, that would be easy enough, but how would I get my_cameraPos.y?! that's what I am asking, how do i get the coordinates of where I am viewing from?

 
Zinger

August 10, 1999, 11:49 PM

You said yourself that you had setup a few matrices. One of them was the view matrix. Just extrapolate the x, y, z from that matrix. That matrix should contain roll, pitch, yaw and your position.

So basically what I was saying was have a D3DVECTOR that represents your position. You would also have either a quaternion or some other representation of your camera's orientation. Then each render cycle you update the viewing matrix using those values.

Zinger

WantsToWalk wrote:
>>
>>>> m_cameraPos.y += m_viewingHeight;
>>
>>
>>well, yes, that would be easy enough, but how would I get my_cameraPos.y?! that's what I am asking, how do i get the coordinates of where I am viewing from?

 
WantsToWalk

August 11, 1999, 12:49 AM


Well, I went through every value of the matrix, and strangley enough, the only correct value i could get out was the y coordinate. it was here (it's Y):

? ? ? ?
? ? ? ?
? ? ? ?
? Y ? ?

All the other values either contain 1 or some value that has to do with the angle your viewing. I did find one I will use, at:

? ? ? ?
? ? ? ?
? ? H ?
? ? ? ?

This one seems to be the viewing angle exactly, from 1 at 360 degrees, zero and both right and left (90 and 270) and -1 at 180.

RGGH! So how do i get the x and z out of this? I notice that:

? ? ? ?
? ? ? ?
? ? ? ?
? ? H ?

seems to be related to both the viewing angle and the z coordinate.

I seem to be missing something from your answer. I am not making any camera, because I don't understand them all that well, but I figured that the viewing matrix basically was one.

I realized a way to do it in all of this. When you create the view matrix, you give it a "from" vector. So If I just stored x and y coordinates (2d talk again) and updated them, then created the new view matrix accordingly and set that viewmatrix in the device too, it would work. But I would have to do that every frame, and that seems like such a waste to do.

 
Zinger

August 11, 1999, 08:57 PM

The first thing that you might want to do is study up on 3D Transformations. One thing to watch out for are various different matrix notations.

In DirectX a point translation ( x, y, z ) is represented in row-major order as the following:
1 0 0 0
0 1 0 0
0 0 1 0
x y z 1

I prefer the following notation just because it is more widely used then the notation that Direct3D uses.
In OpenGL a point transformation ( x, y, z ) is represented in column-major order as the following:
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1

On another note, there are many ways of setting up a view matrix. In all cases the matrix needs to convey certain information about the camera's position and orientation relative to the world's coordinate system. The idea is for you to set up a matrix that works best for you. What I mean by that is, set the view matrix up in a way that you can easily obtain information from it.
One way that you could create a view matrix is to compose a translation, with a series of rotations about x, y, and z axis.

V = T * Rx * Ry * Rz

However, with this composited matrix there is a bit more math involved in obtaining your orientation.

Another way to setup the view matrix would be to take your direction and calculate your up and right vectors from this to give you the following matrix.

Ux Vx Nx 0
Uy Vy Ny 0
Uz Vz Nz 0
-U*C -V*C -N*C 1

U = [ Ux Uy Uz ] ---> Up vector
V = [Vx Vy Vz] ---> Right vector
N = [Nx Ny Nz] ---> Viewing direction vector
C = [ x y z ] ---> Position vector

This matrix is easier to read.

The most important point is that if you are unfamiliar with 3D transformations then read up on them, before trying to move onto other things. They are fundamental.

Zinger

WantsToWalk wrote:
>>
>>Well, I went through every value of the matrix, and strangley enough, the only correct value i could get out was the y coordinate. it was here (it's Y):
>>
>>? ? ? ?
>>? ? ? ?
>>? ? ? ?
>>? Y ? ?
>>
>>All the other values either contain 1 or some value that has to do with the angle your viewing. I did find one I will use, at:
>>
>>? ? ? ?
>>? ? ? ?
>>? ? H ?
>>? ? ? ?
>>
>>This one seems to be the viewing angle exactly, from 1 at 360 degrees, zero and both right and left (90 and 270) and -1 at 180.
>>
>>RGGH! So how do i get the x and z out of this? I notice that:
>>
>>? ? ? ?
>>? ? ? ?
>>? ? ? ?
>>? ? H ?
>>
>>seems to be related to both the viewing angle and the z coordinate.
>>
>>I seem to be missing something from your answer. I am not making any camera, because I don't understand them all that well, but I figured that the viewing matrix basically was one.
>>
>>I realized a way to do it in all of this. When you create the view matrix, you give it a "from" vector. So If I just stored x and y coordinates (2d talk again) and updated them, then created the new view matrix accordingly and set that viewmatrix in the device too, it would work. But I would have to do that every frame, and that seems like such a waste to do.

 
Helping Out

August 22, 1999, 02:44 AM


Sounds like you want to find out which polygon you are standing on from the terrain, and then find the height for a given X&Z on that polygon. Obviously just taking this information from the height map won't work - you can hack it but.. Easiest way is to write a quick "distance from point to plane" routine, all you'll need is a surface normal ( per polygon ), and one point on that surface/plane (XZ and Height from the height map will suffice).

Then, take your point X&Z with an Celling value for the Y, subtract this from the Point on the Plane/Surface, do a DotProduct with the result and surface normal, and this will give you the exact height. This assumes you know which polygon you are standing on.
;;

So----

vector_t dst_v; // Location you need the height for
vector_t temp_v; // temp Position
vector_t plane_v; // Point on the plane ( any one of the vectors of the triangle )

dst_v.x = YourCamera.x;
dst_v.y = 0;
dst_v.z = YourCamera.z;

temp_v = plane_v - dst_v;
dst_v.y = DotProduct ( temp_v, plane_normal );

;--------
You'll find the Y is in dst_v.y....









 
This thread contains 7 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.