im currently working on a framework to create my own games and wanted to add buoyancy physics to it.
I understand the fundamentals, but still have problems to implement it the right way into my framework.
I calculated the resulting force on the object by subtracing the gravity force from the buoyancy and worked out the resultgin acceleration.
I know that the density of the water gets bigger as the object rises in the water, but i dont know when it gets lower...but these are only some problems...anyways ill post my code here(written in C#) and hope somebody will be able to help me creating realistic buoyancy physics. In the moment the object just accelerates up and never returns down -,-...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DextroEngine;
using DextroEngine.Physics;
using Tao.OpenGl;
namespace Shooter
{
class buoyancy_test:IGameObject
{
Renderer _renderer = new Renderer();
Sprite s = new Sprite();
Gravitation g = new Gravitation(9.81f);
double pK = 0.75f;//object density
double pFl = 1;//water density
double watervolume = 0;//amount of object in water
double YIncrement = 0;//amount to increase/decrease objects posítion
double buoyancy = 0;
double bodyforce = 0;
double _totaltimePassed;
float PercentInWater = 9f;
bool moveup = false;
bool movedown = false;
public buoyancy_test()
{
s.SetWidth(10);
s.SetHeight(10);
s.rigidbody.Density = pFl;
s.rigidbody.SetVolume(s.GetWidth(), s.GetHeight(),10);
CalculateMass();
Get_pFl();
}
public double CalculateMass()
{
bodyforce = pK* g.gravitation * s.rigidbody.GetVolume();
s.rigidbody.Mass = bodyforce / g.gravitation;
return s.rigidbody.Mass;
}
public double InWaterVolume()
{
watervolume = s.GetWidth() * s.GetHeight() * PercentInWater;
return watervolume;
}
public double Get_pFl()
{
double v_inWater = InWaterVolume();
pFl = (s.rigidbody.Volume * pK)/v_inWater;
return pFl;
}
public void UpdateMovement(double time)
{
_totaltimePassed += time;
buoyancy = pFl * g.gravitation * s.rigidbody.GetVolume();
double result_force = buoyancy - bodyforce;
double a = result_force / s.rigidbody.Mass;
if ((pFl > pK)&&(pFl < 1))
{
moveup = true;
movedown = false;
}
if ((pFl >1))
{
moveup = false;
movedown = true;
}
if (moveup)
{
YIncrement += (a * 0.5 * (_totaltimePassed * _totaltimePassed));
PercentInWater -= 0.1f;
if (PercentInWater > 7.5f)
{
Get_pFl();
}
}
if (movedown)
{
YIncrement -= (a * 0.5 * (_totaltimePassed * _totaltimePassed));
PercentInWater += 0.1f;
if (PercentInWater < 9.0f)
{
Get_pFl();
}
}
}
public void Update(double elapsedTime)
{
UpdateMovement(elapsedTime);
s.SetPosition(0, 0+YIncrement);
}
public void Render()
{
Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
_renderer.DrawSprite(s);
}
}
}