Archived

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

JulianSpillane

Incline Rotation and Height-Based Positioning

Recommended Posts

Hey guys. I''ve got a problem (..don''t we all. XD). I''m working on a kart-style racing game, and I''ve come to a roadblock in my coding. For my worlds, I''m using a 3DS format exported base and adding my interactive objects separately through an editor. Now, I can collide with the separate objects easily (bounding box), but I''m not sure how to go about positioning my main "kart" object based on the height of the level and rotating it based on the incline. Now, I can do it when it comes to terrain (since I have a heightmap), but the only solution I can think of for my problem is to compare the y position of the vertex corresponding with the object''s position and positioning the object at that height, but that involves sorting through the entire world''s vertices each frame and won''t help me with incline rotation at all. Sorry if this question''s been asked before, I just really didn''t know what to search for. ^^; Any help would be greatly appreciated. Many Thanks, Julian Spillane

Share this post


Link to post
Share on other sites
The solution to your problem requires a damn a lot of math code but i believe your capable if you''ve written a half game.Here is how to do it:collide each of the kart wheels with the terrain separately.Then rotate and invert the kart so it can fit the wheels.That''s it!

"You losers better learn...NOONE CONTROLS OUR GOD DAMN LIFE!!!" - MANOWAR

Share this post


Link to post
Share on other sites
Thanks for replying, but the problem is, my terrain isn''t done through heightmap, it''s in fact done through a modeling program, so the hard part for me is finding the correct height to collide with.

I''ll continue to mess around. Hopefully I''ll find something. Thanks anyways.

Share this post


Link to post
Share on other sites
Hi JulianSpillane,

you can cast a ray (0, -1, 0) from the Center of Mass or simply from the position of your kart.
Then you''ll have to check which triangle it hits on your road; the intersection point is the new position of your car.

To orientate your car get the triangle collider normal and orientate your car defined with normal vector(0, 1, 0) taking the cross-product of these two vectors. You''ll get the axis of rotation. a little dot product between the triangle normal and (0, 1, 0), you get the angle of rotation. voila

The ray-triangle test can be done easily in two steps:
- intersection ray-plane

bool intersectLinePlane(Vector rayStart, Vector rayEnd,
Vector vertex, Vector triangleNormal, Vector *intersection){

Vector direction, L1;
float rayLength, distFromPlane, percentage;

//calculate the ray''s direction vector

direction = rayEnd - rayStart;

Vector normDir = direction;
normDir.Normalize();

//this gives us the ray length

rayLength = direction.Dot(normal);

//check it does not = 0 with tolerance for floating point rounding errors

if (fabsf(rayLength) < 0.00001)
{
return false; //0 means the ray is parallel to the plane so can not intersect it

}

L1 = vertex - rayStart;

//gives the distance from the plane

distFromPlane = L1.Dot(normal);

//how far from RayStart, intersection is as a percentage of 0 to 1

percentage = distFromPlane / rayLength;

if(percentage < 0)
{ //the plane is behind the start of the line

return false;
}
else if(percentage > 1)
{ //the line does not reach the plane

return false;
}

//add the percentage of the ray to ray start

intersection->x1 = rayStart.x1 + direction.x1 * percentage;
intersection->x2 = rayStart.x2 + direction.x2 * percentage;
intersection->x3 = rayStart.x3 + direction.x3 * percentage;

return true; //we have hit a plane;

}

- point in triangle

bool pointInTriangle(Vector point, Vector triangle[3])
{
Vector Lines[3];
float total_angles;

//loop through all the vertices in triangle

for (int i = 0; i < 3; i++)
{
//get direction Vector from intersection to vertex[a]

Lines[i] = point - triangle[i];
Lines[i].Normalize();
}

double ang1 = acos(Lines[0].Dot(Lines[1]));
double ang2 = acos(Lines[1].Dot(Lines[2]));
double ang3 = acos(Lines[2].Dot(Lines[0]));

if(ang1 < 0 || ang2 < 0 || ang3 < 0)
return false;

float ang1deg = (float)RAD_TO_DEG(ang1);
float ang2deg = (float)RAD_TO_DEG(ang2);
float ang3deg = (float)RAD_TO_DEG(ang3);

total_angles = (float)(ang1 + ang2 + ang3);

//lets take 6.28 radians(360 degrees) away from total_angles

//if its Zero (with tolerence) we''ve hit it

if (fabsf(total_angles - PI_2X) < 0.00001f)
{
return true;
}
} }
return false; //we have not hit the polygon

}


Cheers

Share this post


Link to post
Share on other sites
Of course, that''s just part of it. To save time, you might want to have a subset of just the polys that you can actually drive on. Also you''ll want to have collision detect for running into walls and trees and stuff.

Good luck!

Share this post


Link to post
Share on other sites
Thanks a lot guys. That actually seems a lot more sound than the method a bunch of us came up with tonight at my local IGDA meeting. I didn''t even THINK of casting a ray. ^_^ Thanks a lot!

I''ll tell y''all if I get it running nicely. ^_-

Thanks a lot,
Julian

Share this post


Link to post
Share on other sites
I''ve been wondering about this for a while now.
Would you have to test for a collision from the center of the mass, or every single wheel and then take the average of the reflected normals?

Share this post


Link to post
Share on other sites
I guess it depends on the terrain. With a plain road one ray should be ok. If the terrain is too rough and detailed, orienting the kart based on the triangle normals of the terrain will make it bounce around like hell... I''d probably take 4 ground samples at each tire, orient the car above the average plane through these points, and adjust the height of the wheels so they actually all touch the ground (shock absorbers). That of course still doesn''t work if you are hanging over a cliff with part of your car

Share this post


Link to post
Share on other sites
Hey all,
Sorry for the late reply. I''ve been working and as such, been exhausted.

I finally got around to toying with this code, but I''ve run into some theoretical problems.

To obtain the axis of rotation you cross the triangle''s normal vector with (0,1,0), correct? So:

Axis of Rotation = V1 x V2

And the angle of rotation is equal to the triangle''s normal dot (0,1,0)?

Angle of Rotation = V1.V2

So if my kart is traveling along and hits a triangle at an angle, who''s normal is (0.5,0.5,0), the following should be true:

Axis of Rotation = V1 x V2
AoR.x = ((1 * 0) - (0 * 1))
AoR.x = 0 - 0
AoR.x = 0
AoR.y = ((0*0.5) - (0*0))
AoR.y = 0 - 0
AoR.y = 0
AoR.z = ((0 * 0.5) - (1 * 0.5))
AoR.z = 0 - 0.5
AoR.z = -0.5

Angle of Rotation = V1.V2
AxoR = (0*0.5)+(1*0.5)+(0*0)
AxoR = 0+0.5+0
AxoR = 0.5

For some reason that doesn''t seem right. Am I doing something wrong?

Sorry to be a bother. >_<

Share this post


Link to post
Share on other sites