void AnalyzeEntry(int i)
{
var entityCollidable = broadPhaseEntries[i] as EntityCollidable;
if (entityCollidable != null && entityCollidable.IsActive && entityCollidable.entity.isDynamic && CollisionRules.collisionRuleCalculator(this, entityCollidable) <= CollisionRule.Normal)
{
bool keepGoing = false;
foreach (var tri in surfaceTriangles)
{
//Don't need to do anything if the entity is outside of the water.
if (Toolbox.IsPointInsideTriangle(ref tri[0], ref tri[1], ref tri[2], ref entityCollidable.worldTransform.Position))
{
keepGoing = true;
break;
}
}
if (!keepGoing)
return;
//The entity is submerged, apply buoyancy forces.
float submergedVolume;
Vector3 submergedCenter;
GetBuoyancyInformation(entityCollidable, out submergedVolume, out submergedCenter);
if (submergedVolume > 0)
{
float fractionSubmerged = submergedVolume / entityCollidable.entity.volume;
//Divide the volume by the density multiplier if present.
float densityMultiplier;
if (DensityMultipliers.TryGetValue(entityCollidable.entity, out densityMultiplier))
{
submergedVolume /= densityMultiplier;
}
Vector3 force;
Vector3.Multiply(ref upVector, -gravity * Density * dt * submergedVolume, out force);
entityCollidable.entity.ApplyImpulse(ref submergedCenter, ref force);
//Flow
if (FlowForce != 0)
{
float dot = Math.Max(Vector3.Dot(entityCollidable.entity.linearVelocity, flowDirection), 0);
if (dot < MaxFlowSpeed)
{
force = Math.Min(FlowForce, (MaxFlowSpeed - dot) * entityCollidable.entity.mass) * dt * fractionSubmerged * FlowDirection;
entityCollidable.entity.ApplyLinearImpulse(ref force);
}
}
//Damping
entityCollidable.entity.ModifyLinearDamping(fractionSubmerged * LinearDamping);
entityCollidable.entity.ModifyAngularDamping(fractionSubmerged * AngularDamping);
}
}
}