I'm working on a compute shader that allows two-way physics interaction between a fluid particle engine (NVidia Flex) and a rigidbody physics engine (Unity3D Engine).
Basically for the compute shader I'm using 5 input buffers:
(float4) particle velocities / shape contact indices
(float4) shape centroids
(int) shape flags - dynamic vs static etc
(int) particle indices
(float4) particle positions and mass
and 2 output buffers:
(float3) velocity delta
(float3) rotational velocity delta
The functionality that I'm looking for is minimal and does not need to be accurate, it just needs to be somewhat believable, as I'm mostly just using this for visual effects. I know I can create rigidbody constraints with NVidia flex particles and use that, but in my case this would not be practical because my fluid simulation uses very small particles and medium-sized rigiddodies would use many more particles with the NVidia rigid constraints than the documentation says is recommended per body.
So anyway, I've gotten to the point where in my shader all I need is a physics formula to take in the origin point of a force in world space, the force vector, the shape's center of mass in world space, and I need it to give me both the net delta velocity of the shape (assuming uniform density), and the net rotational velocity of the shape. This function will be applied on each shape many times for each contact between itself and a particle.
Here is some psuedo code:
// The velocity of the particle at the time of contact
float4 contactVelocity;
// The index of the shape that the particle collided with
int shapeIndex;
// The particle's position in the world (which should be the same as the contact point)
float3 pos;
// The mass of the particle
float mass;
// The shape's center of mass
float3 shapeOrigin;
// TODO: define ApplyVelForce & ApplyRotForce
velDelta[shapeIndex] = velDelta[shapeIndex] + GetVelForce(shapeOrigin, contactVelocity * mass, pos);
rotVelDelta[shapeIndex] = rotVelDelta[shapeIndex] + GetRotForce(shapeOrigin, contactVelocity * mass, pos);
// function definitions
float3 GetVelForce(float3 shapeCentroid, float3 force, float3 forcePoint){ /* TODO define */ }
float3 GetRotForce(float3 shapeCentroid, float3 force, float3 forcePoint){ /* TODO define */ }
If anyone knows a relatively simple formula to calculate or even approximate these velocity and rotation forces reasonably efficiently, please let me know. I've scoured google but all the articles about this seem to be way over my head. I just don't think I've got enough experience and knowledge about kinematics yet to figure out formulas like these on my own.
What you want is in general underdetermined, given the information you want as input. In the general case, you need as input:
In general, the full description of a rigid body's position and orientation in world frame at any given moment of time is given by:
where
U
is 3 by 3 orthogonal matrix, whose columns are the coordinates of 3 unit vectors of a coordinate frame firmly attached to and moving with the rigid body with origin at the point x_c.Assume that some force is applied to a point
X_F
on the rigid body, where the coordinates ofX_F
are in the frame attached to the rigid body (not in the world system). In reasonable models we assume that he pointX_F
doesn't change with time in the body-fixed frame (of course it changes in the world frame). Let the vector of the force, in the frame attached to the body, beF
and the angular velocity expressed in the body-fixed frame beO
.Then, in world frame:
The equations of motion then are
where
So, a simple iterative scheme that produces the motion of a rigid body is
Somewhere there should be a function that calculates the force
F
in the body-fixed frame. It could be thatF
is simply a constant vector, it could be changing its magnitude and direction only with respect to timeF = F(t)
, or it could in general depend on the body position, orientation, velocity and even angular velocity, soF = F(x_c, v_c, U, O)
.