buoyancy effect, determine volume under water

Post Reply
gdlk
Posts: 62
Joined: Fri Oct 24, 2014 7:01 pm

buoyancy effect, determine volume under water

Post by gdlk »

Hi!

I want to achieve the buoyancy effect to objects in the water, however I am having problem resolving how much the object volume is under the water.

In the height field water column model (http://matthias-mueller-fischer.ch/talks/GDC2008.pdf), I could send raycast by every column to determine the contact points, but I think is too costly to real time performance (too many raycast by tick). Could be another way to determine it? (also the water has a ghost object to detect when something contact it (actually a btGhostPairCallback, but again, I can't determine the object volume inside the water with that info)).

Regards!!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: buoyancy effect, determine volume under water

Post by drleviathan »

One simple approximate method that occurs to me would be to compute the depth of the corners of the object's local bounding box, and then apply point forces at each submerged corner.

In more detail:

(1) Figure out the four lowest corners of your box. These are the corners that will be under the water and they can be used to compute the area of the box's bottom-most face.

(2) For each corner of local bounding box under the water: compute its depth.

(3) For the corners under the water (note: there will be 4 or less): sum them up and divide by 4 (always by 4, not by the number of points). This represents the approximate submerged depth of the box:

Code: Select all

totalDepth = sum(pointDepths); // save this value for later
avgDepth = sum(totalDepth) / 4;
(4) Estimate the volume displaced by the box:

Code: Select all

displacedVolumeOfBox = min(bottomMostAreaOfBox * avgDepth, volumeOfBox);
(5) The volume displaced by your object is a product of the displacedVolume and a ratio (assuming your object is not actually a box and has a different volume):

Code: Select all

displacedVolumeOfObject = displacedVolumeOfBox * (volumeOfObject / volumeOfBox);
(6) The displaced volume can be used to determine the total upward force on your object:

Code: Select all

totalForce = displacedVolume * densityOfWater * accelerationOfGravity;
(7) But this force is distributed among the submerged points using a "weight" of pointDepth/totalDepth:

Code: Select all

for (point in submergedPoints) {
    relativePosition = point - objectPosition; // relative to object, but using world-frame basis
    force = (totalForce * pointDepth / totalDepth) * (upDirection); // force is a btVector3
    body->applyForce(force, relativePosition);
}
(8) Put that logic in BuoyancyAction::applyAction() which derives from btActionInterface and which you've added to the world such that those forces are applied for each object in the water.

(9) Some final advice: don't apply force on a body that is inactive. Check that it is active and if not: either activate it, or don't apply any forces at all, else you'll accumulate force and the inactive body and it will shoot into the sky when it is finally activated.
gdlk
Posts: 62
Joined: Fri Oct 24, 2014 7:01 pm

Re: buoyancy effect, determine volume under water

Post by gdlk »

Sounds very good the steps 3, 4, 5, thanks!! I will try it

Regards!!
Post Reply