Archived

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

Rotate Vehicle to Terrain Angle

This topic is 5814 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

I''ve been having trouble getting my vehicle to sit right on the terrain poly. I think I''m getting an accurate terrain height for any given coordinate. I''m doing so for the 4 corners of the vehicle, and rotating according to those points, but the result is unsatifactory. Any advice on order of operations, etc? Can anyone give me the best algorithm for this?

Share this post


Link to post
Share on other sites
Hehe, funny you should bring that up. My evening's game development task is to solve the same problem.

I'm working with a 2d matrix of floats representing the height of each terrain vertex. My function prototype is as follows:


// ______________________________________________________________________________________
void CTerrain::GetPitchRollHeight(const float& x, const float& z,
const float& Yaw, const float& Length,
const float& Width, float& Pitch,
float& Roll, float& Height)


Pitch, Roll and Height are the outputs, obviously.

Maybe the function can be useful to you somehow. I'll post it here when I'm done.


Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.

The Battlezone Launch Pad

Edited by - BS-er on January 12, 2002 5:50:04 PM

Share this post


Link to post
Share on other sites
Ok here are my functions. They give a decent orientation based on terrain. The functions actually calculate orientation as if there's one wheel in front, one in back, one on the left and one on the right, rather than at the four corners. However it's realistic enough for what I'm doing.

      
______________________________________________________________________________________
void CTerrain::GetPitchRollHeight(const float& x, const float& z, const float& Yaw, const float& Length,
const float& Width, float& Pitch, float& Roll, float& Height)
{
float cosYaw = (float)cos(Yaw);
float sinYaw = (float)sin(Yaw);

float Xf = x + Width * sinYaw * 0.5f; // Front X

float Zf = z + Length * cosYaw * 0.5f; // Front Z

float Yf = GetHeight(Xf, Zf); // Front Y


float Xb = x - Width * sinYaw * 0.5f; // Back X

float Zb = z - Length * cosYaw * 0.5f; // Back Z

float Yb = GetHeight(Xb, Zb); // Back Y


float Xl = x - Width * cosYaw * 0.5f; // Left X

float Zl = z + Length * sinYaw * 0.5f; // Left Z

float Yl = GetHeight(Xl, Zl); // Left Y


float Xr = x + Width * cosYaw * 0.5f; // Right X

float Zr = z - Length * sinYaw * 0.5f; // Right Z

float Yr = GetHeight(Xr, Zr); // Right Y


Pitch = asin((Yb - Yf)/Length);
Roll = asin((Yr - Yl)/Width);
Height = (Yf + Yb + Yl + Yr) * 0.25f;
}


// ______________________________________________________________________________________

float CTerrain::GetHeight(const float& x, const float& z)
{
float BaseHeight = 0.0f;
float Height;
float LocalX = x + m_Scale * 1.5f;
float LocalZ = z + m_Scale * 1.5f;

float dx = LocalX - (float)((int)(LocalX * m_OverScale)) * m_Scale;
float dz = LocalZ - (float)((int)(LocalZ * m_OverScale)) * m_Scale;
float dy_x;
float dy_z;

if (dx < 0)
{
dx = m_Scale + dx;
}

if (dz < 0)
{
dz = m_Scale + dz;
}

int xi = int(LocalX * m_OverScale + (float)(VERTEX_COUNT/2));
int zi = int(LocalZ * m_OverScale + (float)(VERTEX_COUNT/2));

if
(
(xi < VERTEX_COUNT) &&
(xi > 0) &&
(zi < VERTEX_COUNT) &&
(zi > 0)
)
{

// Check if the position is on the lower trangle or upper triangle

if ((dx + dz) <= m_Scale)
{
BaseHeight = m_Height[zi-1][xi-1];
dy_x = m_Height[zi-1][xi] - BaseHeight;
dy_z = m_Height[zi][xi-1] - BaseHeight;
}
else // Upper triangle

{
BaseHeight = m_Height[zi][xi];
dx = m_Scale - dx;
dz = m_Scale - dz;
dy_x = m_Height[zi][xi-1] - BaseHeight;
dy_z = m_Height[zi-1][xi] - BaseHeight;
}

Height = BaseHeight + m_OverScale * (dy_x * dx +
dy_z * dz );
}
else
{
Height = 0;
}

return Height;
}


Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.

The Battlezone Launch Pad

Edited by - BS-er on January 12, 2002 6:51:01 PM

Share this post


Link to post
Share on other sites
maybe your problem is that you take 4 corners of vehicle instead 4 points where wheels are placed?

With best regards,
Mirek Czerwiñski
http://kris.top.pl/~kherin/

Share this post


Link to post
Share on other sites
The best way to orient the vehicle to the terrain is to actually do the physics, nomatter how you do the angles it never ends up being quite right.

That is unless you really want the vehicle to act in the angled that way.

Share this post


Link to post
Share on other sites
Ive been researching car info, such as physics, for my future project. The answer for more realistic results is to place springs on each of the wheels. From what I gather, attaching springs to the wheels, attached to the car, then calculating collisions and physics for the car will result in a car that follows the terrain just like a real car...cool! As i said, i havnt done this, so someone with real experience can back me up or not.

Share this post


Link to post
Share on other sites
Specifically, I rotate on the y, then take heights from the corners, do the trig for the x and z rotations and apply.

However, the vehicles don''t align with the terrain polys very well. It seems to me that the height readings I get after rotating on the y could be altered drammatically by the rotation on the x (for example) leading to a faulty z rotation. Perhaps I should take heights again after rotating on the x axis.

B-Ser''s algorithm seems to have the same limitation. Is this correct? Any advice on what order I should do the operations?

Share this post


Link to post
Share on other sites