Jump to content
  • Advertisement
Sign in to follow this  
Chirieac

Custom ball physics - velocities after bounce

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

Hi,

I'm trying to write my own physics for a soccer ball in Unreal Engine 4. I can't use PhysX because I need to predict the ball future location taking drag and other factors into account, and UE doesn't use a fixed timestep which would make the physics more deterministic. Having my own simulation for it I can advance it easily in the future.

Without angular velocity, I have the ball bouncing correctly using a restitution coefficient and coming to a rest properly. What gives me issues is the angular velocity. The ball should rotate after impact collision and the spin of the ball should modify the bounce direction if it was rotating really fast. For example, if you put a back spin to the ball and through it in front of you, the ball should come back to you.

I've searched around and tried different solutions but nothing worked properly. My latest try was to implement Coulomb friction based on Glenn Fiedler's article: http://gafferongames.com/virtual-go/collision-response-and-coulomb-friction/

Using those formulas I actually made the ball change direction after impact based on its angular velocity. The problem is that the angular velocity is not changed properly after impact, so with each bounce the ball jumps further and further way, adding more energy to the linear velocity. If I set angular velocity to 0 after first bounce, the ball seems to bounce as expected.

This is my code:

FTransform T = FTransform(InertiaTensor);
FVector InertiaTensorWorld = (T * Root->GetComponentTransform()).GetLocation();

FVector vCollisionPoint = HitResult.ImpactPoint - Data.CurrentLocation;
FVector r = vCollisionPoint;
FVector velocityAtPoint = Data.LinearVelocity + (-Data.AngularVelocity ^ vCollisionPoint);

const float vn = FMath::Min(0.0f, velocityAtPoint | HitResult.ImpactNormal);
const float k = Data.InverseMass + ((r ^ HitResult.ImpactNormal) | ((r ^ HitResult.ImpactNormal) / InertiaTensorWorld));
const float j = -(1 + Restitution) * vn / k;

Data.LinearVelocity += (j * HitResult.ImpactNormal) * Data.InverseMass;
Data.AngularVelocity += (j * (r ^ HitResult.ImpactNormal)) / InertiaTensorWorld;

// friction
velocityAtPoint = Data.LinearVelocity + (-Data.AngularVelocity ^ vCollisionPoint);
FVector tangentVelocity = velocityAtPoint - HitResult.ImpactNormal * (velocityAtPoint | HitResult.ImpactNormal);
FVector tangent = tangentVelocity.GetSafeNormal();

float u = 0.2f;
const float vt = (velocityAtPoint | tangent);
const float kt = Data.InverseMass + ((r ^ tangent) | ((r ^ tangent) / InertiaTensorWorld));
const float jt = FMath::Clamp(-vt / kt, -u * j, u * j);

Data.LinearVelocity += (jt * tangent) * Data.InverseMass;
Data.AngularVelocity += (jt * (r ^ tangent)) / InertiaTensorWorld;
//Data.AngularVelocity = FVector::ZeroVector;

Sorry it's kinda messy, but I've just copied as is from the examples I could find to make it easier to convert to unreal.

Is there a better way to handle the bouncing of a ball knowing that it just need to collide with the ground and walls?

Edited by Chirieac

Share this post


Link to post
Share on other sites
Advertisement

no matter what you'll end up writing: once per frame, (ball is in motion even when vel is 0) you iterate with drag equation and motion till you hit something this is your hit pos/

 

basically: each frame you find new hitposition, then you do your stuff

Edited by WiredCat

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!