Builtin Library
README.md
buoyancy
Floats a rigid body on the water Physics.water answers for (a sea, a
Terrain's lakes and rivers, a Water component's pool, a body
Physics.defineWater declares) at the waterline a density relative to water
sets.
local buoyancy = require("@builtin::systems.oceans.modules.buoyancy")
buoyancy.attach(barrel, { density = 0.4 })
Or attach a Buoyancy component next to the entity's Physics body and author
density / damping / hull / sizeX / sizeY / sizeZ on it.
The forces act inside the physics step
attach hands the body to the physics step as a FluidForces it states for
it. Every step, the water's pressure acts on the part of the hull under the
surface, which sums to the weight of the water it displaces and pushes up
through the centre of what it displaces: the hull floats, rights itself when
tipped, pitches with a wave rolling under it, and is carried by a current. The
drag of the water it moves through and the damping of the waves it makes at the
surface settle it. Because all of it happens in the step, a hull floats at the
same waterline, and takes the same path there, whatever the frame rate.
The hull is the body's colliders
The hull is the body's own solid colliders: a box, a ball, a capsule, a cylinder, a convex hull, a closed mesh, or several of them on the body or its children. Colliders that overlap displace the space they fill together once, so a cabin box sunk into a hull box, or a ball inside a box, floats as the shape they make. What it draws plays no part, so an invisible collision proxy under detailed art floats by the proxy.
sizeX/sizeY/sizeZstate a box in place of the colliders, centred on the entity's origin, for a body whose colliders are not what should displace the water.hull = "model"takes the box around what the entity draws, in its own space and with its own centre, so a model drawn off its pivot displaces water where it draws. What an entity draws arrives over the frames after it is spawned, and the box is measured once it does.
A body with nothing to measure (no dynamic Physics body, a body whose
colliders are all sensors, a model hull that draws nothing) is waited for for a
second, then refused: apply warns once, naming the entity and the ways to give
it a hull, and leaves the body to the physics world. The float keeps watching
it, and floats it as soon as it has what the warning names.
Density sets the waterline
density is relative to water: that share of the hull rides under still
water, so the lower it is the higher the hull floats, and a body denser than
water sinks. buoyancy.restingY(waterY, height, density) gives the height an
upright box hull's centre rests at, and buoyancy.submergedFraction the share
of such a box under a given surface.
The water acts on the body as it would on a body of that density, whatever mass its rigid body was given and whatever density the water has: its pressure, its drag and the waves the hull makes all scale together, so a hull of a given shape and density floats, bobs and settles the same way at any mass.
Damping settles the bobbing
damping is the factor on the damping of the waves the hull makes moving
through the surface: 1 settles a dropped hull within a few swings, lower values
let it bob longer, and 0 leaves it bobbing. The water's drag acts on every
face that meets it besides.
What it reads
Every body of water Physics.water answers for, at the moment each step
reaches, so a hull rides the waves that are on screen. Pass ocean to read one
Ocean's water alone when a scene has several.
float:submersion() reads the share of the hull under water on the last
physics step, and float:waterline() the surface under the hull's centre when
apply last read it.
Cost
The step reads the water at each corner of the hull and splits each of its triangles at the surface: a box collider's hull is 48 triangles over 26 corners, and a hull is at most 512 triangles. It reads nothing while the hull stands more than its own size above the water.