Jump to content
  • Advertisement
Sign in to follow this  
mind in a box

Jumpy raycast-vehicle

This topic is 2584 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'm currently trying to get the ships for our game Pulsedrive to hover. For this I'm using a raycast-vehicle-style function which shoots a ray for each of the 4 corners to the bottom to calculate the forces.
That works quite well so far, the problem is just that my ships won't stop to jump up and down.

I read something about the Damping, and even implemented it into the code, but it doesn't seem to help. I used this page as a reference:
http://www.digitalrune.com/Support/Blog/tabid/719/EntryId/91/Car-Physics-for-3D-Games.aspx

The function for calculating the rays goes like this:


float DoRaycastPhysics(float PrevCompression, vector3 Point, float DeltaTime)
{
const float SHIP_SUSPENSION_STIFFNESS = 20.0f;
const float SHIP_DAMPING = 0.15f;

vector3 Pos = Ship.GetLocation();
vector3 Susp = Ship.TransformDirection(Point); // Rotate wheel location

float Susp_Length = 2.0; // Rest length
float TireRad = 2.0f; // Tire radius

vector3 RayOrigin = Pos + Susp;
float RayLength = Susp_Length + TireRad;

// Shoot the ray
vector3 Nrm;
float Dist = World.TraceEx(RayOrigin, vector3(0,-1,0), 1000, Nrm);
vector3 HitPos = (vector3(0,-1,0)*Dist); // Local

float Compression;
if(Dist < RayLength)
{
Compression = Dist - TireRad; // Ray hit something, calculate the Compression
}else
{
Compression = Susp_Length; // Didn't hit, set the compression to "rested"-state
}

// Calculate the SuspensionForce --- (Problem here?)
float SuspensionForce = SHIP_SUSPENSION_STIFFNESS * (Susp_Length - Compression) + SHIP_DAMPING * (PrevCompression - Compression) * DeltaTime;

// Apply the force from the hit location in local space
Ship.ApplyForce(vector3(0,SuspensionForce,0), HitPos);

return Compression;
}


Does anyone see what my problem could be?

Share this post


Link to post
Share on other sites
Advertisement
This one here seemed very good:
http://www.gamedev.net/topic/394292-demosource-of-marco-monsters-car-physics-tutorial/

You can also look at Box2D and Bullet. They both have some examples of raycast vehicles if I remember correctly

Share this post


Link to post
Share on other sites
If the ship keeps jumping up and down, then there might be a problem with your damping. The line

float SuspensionForce = SHIP_SUSPENSION_STIFFNESS * (Susp_Length - Compression) + SHIP_DAMPING * (PrevCompression - Compression) * DeltaTime;

looks a lot like a Hookes law damped spring. The problem might be with the second term:

+ SHIP_DAMPING * (PrevCompression - Compression) * DeltaTime;


where the term

(PrevCompression - Compression) * DeltaTime;

should represent the ships vertical velocity, but probably doesnt since the equation looks wrong. Try to replace it with this algorithm:

(Compression - PrevCompression) / DeltaTime;

Which calculates the velocity based on the mean value theorem. If it doesn't work, try changing the sign or change the SHIP_DAMPING value.

Cheers,
Mike

Share this post


Link to post
Share on other sites
Thanks for the reply! Unfortunately your solution doesn't seem to help. Or I am simply using the wrong values.

I have changed the function to this:

float DoRaycastPhysics(float PrevCompression, vector3 Point, float DeltaTime)
{
vector3 Pos = Ship.GetLocation();
vector3 Susp = Ship.TransformDirection(Point); // Rotate wheel location

float Susp_Length = 4.0; // Rest length
float TireRad = 0.5f; // Tire radius
float RestLength = Susp_Length; // Resting length

vector3 RayOrigin = Pos + Susp;
float RayLength = Susp_Length + TireRad;

// Shoot the ray
vector3 Nrm;
float Dist = abs(World.TraceEx(RayOrigin, vector3(0,-1,0), 1000, Nrm));
vector3 HitPos = Susp+(vector3(0,-1,0)*Dist);

float Compression=Susp_Length;
if(Dist < RayLength)
{
Compression = Dist - TireRad; // Ray hit something, calculate the Compression
}

float SuspensionForce;
if( Ship.GetLinearVelocity().y > 0)
{
// Extending
SuspensionForce = SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Compression - PrevCompression) / DeltaTime;
}else
{
// Compressing
SuspensionForce = SuspensionStiffness * (RestLength - Compression) + CompressDamping * (Compression - PrevCompression) / DeltaTime;
}

// Apply the force from the hit location in local space
Ship.ApplyForce(vector3(0,SuspensionForce,0), HitPos);

return Compression;
}


My vehicle is still jumping around.

Maybe I am using the wrong values?
SuspensionStiffness = 30
ExtendDamping = 2.3
CompressDamping = 4.4

I tried others, sure, but none seem to work out.

What works, at least a bit, is to multiply the SuspensionStiffness of the "Extending"-branch with 0.01f, but that doesn't seem a very "right" solution I guess.

Share this post


Link to post
Share on other sites
First, this code doesn't seem to make any sense. The force should always be applied, not only when vertical velocity is positive. Also, the two equations are identical.

if( Ship.GetLinearVelocity().y > 0)
{
// Extending
SuspensionForce = SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Compression - PrevCompression) / DeltaTime;
}else
{
// Compressing
SuspensionForce = SuspensionStiffness * (RestLength - Compression) + CompressDamping * (Compression - PrevCompression) / DeltaTime;
}


Instead of all the above, simply write:

SuspensionForce = -(SuspensionStiffness * (RestLength - Compression) + ExtendDamping * Ship.GetLinearVelocity().y);


If it still doesn't work, try changing signs and coefficient values.
Cheers,
Mike

Share this post


Link to post
Share on other sites
Wow, it works! Thank you, Mike!

Still, I had to change the sign:

SuspensionForce = abs(SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Ship.GetLinearVelocity().y));


Again, thank you! :)

Share this post


Link to post
Share on other sites
You're welcome, always glad to help. :-)

The abs() does seem a little strange to me though, and if it only works with it, I think there may be a bug hiding somewhere else in your code. Have you tried this:

SuspensionForce = -SuspensionStiffness * (RestLength - Compression) - ExtendDamping * Ship.GetLinearVelocity().y;

Notice there are two signs you can change independently of each other, suspension force and damping force. Good bug huntin'

Cheers,
Mike

Share this post


Link to post
Share on other sites
Ah, I forgot to take the "abs()" out when editing my post.

This is what's in my code:
SuspensionForce = (SuspensionStiffness * (RestLength - Compression) + ExtendDamping * (Ship.GetLinearVelocity().y));


Works like a charm.

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!