137 lines
3.3 KiB
Odin
137 lines
3.3 KiB
Odin
package physics
|
|
|
|
import "core:log"
|
|
import "libs:tracy"
|
|
|
|
_ :: log
|
|
|
|
Body_Config_Inertia_Mode :: enum {
|
|
From_Shape,
|
|
Explicit,
|
|
}
|
|
|
|
immediate_body :: proc(
|
|
scene: ^Scene,
|
|
state: ^Solver_State,
|
|
id: u32,
|
|
config: Body_Config,
|
|
) -> (
|
|
handle: Body_Handle,
|
|
) {
|
|
sim_state := get_sim_state(scene)
|
|
if id in state.immedate_bodies {
|
|
body := &state.immedate_bodies[id]
|
|
if body.last_ref != state.simulation_frame {
|
|
body.last_ref = state.simulation_frame
|
|
state.num_referenced_bodies += 1
|
|
}
|
|
handle = body.handle
|
|
update_body_from_config(sim_state, get_body(sim_state, handle), config)
|
|
} else {
|
|
state.num_referenced_bodies += 1
|
|
handle = add_body(sim_state, config)
|
|
state.immedate_bodies[id] = {
|
|
handle = handle,
|
|
last_ref = state.simulation_frame,
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
immediate_suspension_constraint :: proc(
|
|
scene: ^Scene,
|
|
state: ^Solver_State,
|
|
id: u32,
|
|
config: Suspension_Constraint_Config,
|
|
) -> (
|
|
handle: Suspension_Constraint_Handle,
|
|
) {
|
|
if id in state.immediate_suspension_constraints {
|
|
constraint := &state.immediate_suspension_constraints[id]
|
|
if constraint.last_ref != state.simulation_frame {
|
|
constraint.last_ref = state.simulation_frame
|
|
state.num_referenced_suspension_constraints += 1
|
|
}
|
|
handle = constraint.handle
|
|
} else {
|
|
state.num_referenced_suspension_constraints += 1
|
|
handle = add_suspension_constraint(get_sim_state(scene), {})
|
|
state.immediate_suspension_constraints[id] = {
|
|
handle = handle,
|
|
last_ref = state.simulation_frame,
|
|
}
|
|
}
|
|
|
|
update_suspension_constraint_from_config(
|
|
get_suspension_constraint(get_sim_state(scene), handle),
|
|
config,
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
prune_immediate :: proc(scene: ^Scene, state: ^Solver_State) {
|
|
tracy.Zone()
|
|
prune_immediate_bodies(scene, state)
|
|
prune_immediate_suspension_constraints(scene, state)
|
|
}
|
|
|
|
// TODO: Generic version
|
|
prune_immediate_bodies :: proc(scene: ^Scene, state: ^Solver_State) {
|
|
if int(state.num_referenced_bodies) == len(state.immedate_bodies) {
|
|
return
|
|
}
|
|
|
|
num_unreferenced_bodies := len(state.immedate_bodies) - int(state.num_referenced_bodies)
|
|
assert(num_unreferenced_bodies >= 0)
|
|
|
|
bodies_to_remove := make([]u32, num_unreferenced_bodies, context.temp_allocator)
|
|
|
|
i := 0
|
|
for k, &v in state.immedate_bodies {
|
|
if v.last_ref != state.simulation_frame {
|
|
bodies_to_remove[i] = k
|
|
i += 1
|
|
}
|
|
}
|
|
|
|
assert(i == len(bodies_to_remove))
|
|
|
|
for k in bodies_to_remove {
|
|
handle := state.immedate_bodies[k].handle
|
|
delete_key(&state.immedate_bodies, k)
|
|
remove_body(get_sim_state(scene), handle)
|
|
}
|
|
}
|
|
|
|
prune_immediate_suspension_constraints :: proc(scene: ^Scene, state: ^Solver_State) {
|
|
if int(state.num_referenced_suspension_constraints) ==
|
|
len(state.immediate_suspension_constraints) {
|
|
return
|
|
}
|
|
|
|
num_unreferenced_constraints :=
|
|
len(state.immediate_suspension_constraints) -
|
|
int(state.num_referenced_suspension_constraints)
|
|
assert(num_unreferenced_constraints >= 0)
|
|
|
|
constraints_to_remove := make([]u32, num_unreferenced_constraints, context.temp_allocator)
|
|
|
|
i := 0
|
|
for k, &v in state.immediate_suspension_constraints {
|
|
if v.last_ref != state.simulation_frame {
|
|
constraints_to_remove[i] = k
|
|
i += 1
|
|
}
|
|
}
|
|
|
|
assert(i == len(constraints_to_remove))
|
|
|
|
for k in constraints_to_remove {
|
|
handle := state.immediate_suspension_constraints[k].handle
|
|
delete_key(&state.immediate_suspension_constraints, k)
|
|
remove_suspension_constraint(get_sim_state(scene), handle)
|
|
}
|
|
}
|