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 } immediate_engine :: proc( scene: ^Scene, state: ^Solver_State, id: u32, config: Engine_Config, ) -> ( handle: Engine_Handle, ) { sim_state := get_sim_state(scene) if id in state.immediate_engines { engine := &state.immediate_engines[id] if engine.last_ref != state.simulation_frame { engine.last_ref = state.simulation_frame state.num_referenced_engines += 1 } handle = engine.handle update_engine_from_config(sim_state, get_engine(sim_state, handle), config) } else { state.num_referenced_engines += 1 handle = add_engine(sim_state, config) state.immediate_engines[id] = { handle = handle, last_ref = state.simulation_frame, } } return } prune_immediate :: proc(scene: ^Scene, state: ^Solver_State) { tracy.Zone() prune_immediate_bodies(scene, state) prune_immediate_suspension_constraints(scene, state) prune_immediate_engines(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) } } prune_immediate_engines :: proc(scene: ^Scene, state: ^Solver_State) { if int(state.num_referenced_engines) == len(state.immediate_engines) { return } num_unreferenced_engines := len(state.immediate_engines) - int(state.num_referenced_engines) assert(num_unreferenced_engines >= 0) engines_to_remove := make([]u32, num_unreferenced_engines, context.temp_allocator) i := 0 for k, &v in state.immediate_engines { if v.last_ref != state.simulation_frame { engines_to_remove[i] = k i += 1 } } assert(i == len(engines_to_remove)) for k in engines_to_remove { handle := state.immediate_engines[k].handle delete_key(&state.immediate_engines, k) remove_engine(get_sim_state(scene), handle) } }