Open SquirrelKiev opened 2 years ago
This may be due to missing air resistance. I wasn't quite sure how to implement that with Jolt.
I considered using ApplyBuoyancyImpulse
because it can do a drag factor and we use that for fluids, but I felt that was a big hammer to apply to everything and I was probably missing something really obvious.
Maybe @jrouwe would be able to give a pointer as to the best way to implement that here.
Air resistance is usually expressed through BodyCreationSettings::mLinearDamping / mAngularDamping.
I think that's too simple for what we want. We could implement our own proper drag.
We get a drag coefficient per-object + total orthographic area per-axis per-shape, and air density from the environment.
In theory we can calculate the drag basis for an object on each axis, and use that with the per-object drag coefficient to get the drag in any given direction and use that with the air density to calculate proper drag velocity to take off each step.
I guess the math isn't that complex here that we need assistance from Jolt to do it. I just thought I was missing stuff that allows for more complex drag implementations to be done.
(We could also maybe calculate this when parameters get updated and use mLinearDamping and mAngularDamping if Jolt offered these as Vector quantities that affect velocity in local-space instead of Scalar.)
I'm not sure if there are enough use cases for wanting linear/angular damping to be a vector. It's simple enough, but it will cost 4 floats extra per body and I don't know of any other physics engines that have implemented it that way.
What Jolt does internally for drag is basically: At the beginning of PhysicsSystem::Update, for every dynamic body call MotionProperties::ApplyForceTorqueAndDragInternal
and the interesting code is this:
mLinearVelocity *= max(0.0f, 1.0f - mLinearDamping * inDeltaTime);
mAngularVelocity *= max(0.0f, 1.0f - mAngularDamping * inDeltaTime);
So if you add this loop before you call PhysicsSystem::Update (or do it as a PhysicsStepListener) and convert your damping vector from local to world space and then do a component wise multiplication, I think you're done.
Note that if you have a drag coefficient, you may actually be better off applying the drag formula to the velocity directly instead of going through the damping formula. I'm not sure which one Source uses because there are multiple options, but the buoyancy code in Jolt uses this one:
Drag force = 0.5 Fluid Density (Velocity of fluid - Velocity of center of buoyancy)^2 Linear Drag Area Facing the Relative Fluid Velocity
Make sure you don't flip the velocity with your force.
Objects like
models/props_c17/fence01a.mdl
usually fall pretty slowly, however it falls as fast as every other object. The gravity gun is also able to pick up any object, no matter how big or small.