77 lines
3.2 KiB
Text
77 lines
3.2 KiB
Text
# state.ludic - the port, the kinds and layers, the facts, and what the world holds
|
|
# what the package asks the world: the water's surface under a point and the current there.
|
|
# Unbound there is no water.
|
|
export port PhysWater {
|
|
height: fn(float, float) -> float = fn ph_dry
|
|
current_x: fn(float, float) -> float = fn ph_still
|
|
current_z: fn(float, float) -> float = fn ph_still
|
|
}
|
|
function ph_dry(x: float, z: float) -> float { return PHYS_NONE }
|
|
function ph_still(x: float, z: float) -> float { return 0.0 }
|
|
|
|
export const PHYS_NONE: float = -1000000000.0 # no height: no water, nothing under a query
|
|
|
|
# what a query sees, as a mask: the ground, the still things on it, and what moves
|
|
export const PHYS_M_GROUND: int = 1
|
|
export const PHYS_M_STATIC: int = 2
|
|
export const PHYS_M_MOVING: int = 4
|
|
export const PHYS_M_SOLID: int = 3
|
|
export const PHYS_M_ALL: int = 7
|
|
|
|
# what happened
|
|
export const PHYS_HIT: int = 0 # two bodies met at least ph_hard metres a second apart
|
|
export const PHYS_SPLASH: int = 1 # a floating body reached the water
|
|
|
|
export property PhysFact {
|
|
what: int = 0
|
|
a: int = -1
|
|
b: int = -1
|
|
x: float = 0.0
|
|
y: float = 0.0
|
|
z: float = 0.0
|
|
speed: float = 0.0
|
|
}
|
|
|
|
export const PH_CAP: int = 512 # contacts drained a step, queries' buffers
|
|
|
|
export state PhysicsState {
|
|
ph_world: pointer = null
|
|
@max(262144) ph_shapes: []pointer = new []pointer # a shape id is its place here; null once freed
|
|
@max(262144) ph_spare: []int = new []int # the freed places, handed out again (shape_ids.ludic)
|
|
@max(262144) ph_own: []int = new []int # by a body's index: the shape it owns, freed with it (owned.ludic)
|
|
ph_step: float = 0.016666668 # seconds a step
|
|
ph_sub: int = 1 # collision steps in each
|
|
ph_max_steps: int = 4 # a slow frame catches up this far and no further
|
|
ph_acc: float = 0.0
|
|
ph_steps: int = 0
|
|
ph_gen: int = 0 # how many worlds have been opened: an id from an older one is stale
|
|
ph_hard: float = 2.0 # metres a second: a contact under this is not a fact
|
|
ph_floats: words = words(256) # buoyant bodies' ids, the first ph_nf of them
|
|
ph_float_k: floats = floats(256 * 4) # and theirs: buoyancy, linear drag, angular drag, wet
|
|
ph_nf: int = 0
|
|
ph_rx: float = 0.0 # where the last phys_resolve put a body
|
|
ph_rz: float = 0.0
|
|
@max(64) ph_walkers: []pointer = new []pointer # a walker id is its place here; null once removed
|
|
ph_ids: []int = words(PH_CAP * 2)
|
|
ph_vals: []float = floats(PH_CAP * 4)
|
|
ph_facts: Queue<PhysFact> = ph_facts__new()
|
|
@max(1024) ph_fpool: []PhysFact = ph_fpool_new() # every fact record made, reused once no drain holds it
|
|
@max(1024) ph_ffree: []PhysFact = ph_ffree_new()
|
|
ph_fnext: int = 0
|
|
}
|
|
|
|
# the facts, oldest first
|
|
export function phys_facts(physics_st: PhysicsState) -> Queue<PhysFact> {
|
|
return physics_st.ph_facts
|
|
}
|
|
|
|
function ph_buffers() -> void {
|
|
}
|
|
|
|
# a step's length, its collision steps, and how hard a contact must be to be a fact
|
|
export function phys_config(physics_st: mut PhysicsState, step: float, sub: int, hard: float) -> void {
|
|
physics_st.ph_step = step
|
|
physics_st.ph_sub = sub
|
|
physics_st.ph_hard = hard
|
|
}
|
|
function ph_facts__new() -> Queue<PhysFact> { return queue_new("physics.facts") }
|