Timestep independence, finally
This commit is contained in:
parent
e22e667e27
commit
e618ad9520
2
.nvim.lua
Normal file
2
.nvim.lua
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
vim.opt_global.makeprg = "./build_hot_reload.sh"
|
||||||
|
vim.opt.errorformat = "%f(%l:%c)\\ %m"
|
@ -62,7 +62,7 @@ Car :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SOLVER_CONFIG :: physics.Solver_Config {
|
SOLVER_CONFIG :: physics.Solver_Config {
|
||||||
timestep = 1.0 / 120,
|
timestep = 1.0 / 104,
|
||||||
gravity = rl.Vector3{0, -9.8, 0},
|
gravity = rl.Vector3{0, -9.8, 0},
|
||||||
substreps_minus_one = 4 - 1,
|
substreps_minus_one = 4 - 1,
|
||||||
}
|
}
|
||||||
@ -245,20 +245,20 @@ update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
car_body := physics.get_body(&world.physics_scene, runtime_world.car_handle)
|
// car_body := physics.get_body(&world.physics_scene, runtime_world.car_handle)
|
||||||
|
|
||||||
camera := &runtime_world.camera
|
camera := &runtime_world.camera
|
||||||
|
|
||||||
camera.up = rl.Vector3{0, 1, 0}
|
camera.up = rl.Vector3{0, 1, 0}
|
||||||
camera.fovy = 60
|
camera.fovy = 60
|
||||||
camera.projection = .PERSPECTIVE
|
camera.projection = .PERSPECTIVE
|
||||||
camera.position = physics.body_local_to_world(
|
// camera.position = physics.body_local_to_world(
|
||||||
car_body,
|
// car_body,
|
||||||
physics.body_world_to_local(
|
// physics.body_world_to_local(
|
||||||
car_body,
|
// car_body,
|
||||||
physics.body_local_to_world(car_body, rl.Vector3{1, 0, -2}),
|
// physics.body_local_to_world(car_body, rl.Vector3{1, 0, -2}),
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
camera.target = physics.get_body(&world.physics_scene, runtime_world.car_handle).x
|
camera.target = physics.get_body(&world.physics_scene, runtime_world.car_handle).x
|
||||||
if runtime_world.camera.position == {} {
|
if runtime_world.camera.position == {} {
|
||||||
runtime_world.camera.position = runtime_world.camera.target - rl.Vector3{10, 0, 10}
|
runtime_world.camera.position = runtime_world.camera.target - rl.Vector3{10, 0, 10}
|
||||||
@ -333,8 +333,8 @@ update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) {
|
|||||||
drive_wheels := []physics.Suspension_Constraint_Handle{wheel_rl, wheel_rr}
|
drive_wheels := []physics.Suspension_Constraint_Handle{wheel_rl, wheel_rr}
|
||||||
turn_wheels := []physics.Suspension_Constraint_Handle{wheel_fl, wheel_fr}
|
turn_wheels := []physics.Suspension_Constraint_Handle{wheel_fl, wheel_fr}
|
||||||
|
|
||||||
DRIVE_IMPULSE :: 1
|
DRIVE_IMPULSE :: 20
|
||||||
BRAKE_IMPULSE :: 2
|
BRAKE_IMPULSE :: 50
|
||||||
TURN_ANGLE :: -f32(30) * math.RAD_PER_DEG
|
TURN_ANGLE :: -f32(30) * math.RAD_PER_DEG
|
||||||
|
|
||||||
for wheel_handle in drive_wheels {
|
for wheel_handle in drive_wheels {
|
||||||
@ -520,7 +520,12 @@ draw :: proc() {
|
|||||||
car_matrix := rl.QuaternionToMatrix(car_body.q)
|
car_matrix := rl.QuaternionToMatrix(car_body.q)
|
||||||
car_model.transform = car_matrix
|
car_model.transform = car_matrix
|
||||||
|
|
||||||
rl.DrawModel(car_model, car_body.x + runtime_world.car_com, 1, rl.WHITE)
|
rl.DrawModel(
|
||||||
|
car_model,
|
||||||
|
physics.body_local_to_world(car_body, -runtime_world.car_com),
|
||||||
|
1,
|
||||||
|
rl.WHITE,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
if g_mem.draw_car {
|
if g_mem.draw_car {
|
||||||
rl.DrawModel(car_model, 0, 1, rl.WHITE)
|
rl.DrawModel(car_model, 0, 1, rl.WHITE)
|
||||||
@ -572,6 +577,8 @@ draw :: proc() {
|
|||||||
rl.BeginMode2D(ui_camera())
|
rl.BeginMode2D(ui_camera())
|
||||||
defer rl.EndMode2D()
|
defer rl.EndMode2D()
|
||||||
|
|
||||||
|
rl.DrawFPS(0, 0)
|
||||||
|
|
||||||
if g_mem.editor {
|
if g_mem.editor {
|
||||||
rl.DrawText("Editor", 5, 5, 8, rl.ORANGE)
|
rl.DrawText("Editor", 5, 5, 8, rl.ORANGE)
|
||||||
|
|
||||||
@ -782,7 +789,7 @@ game_init_window :: proc() {
|
|||||||
rl.InitWindow(1280, 720, "Odin + Raylib + Hot Reload template!")
|
rl.InitWindow(1280, 720, "Odin + Raylib + Hot Reload template!")
|
||||||
rl.SetExitKey(.KEY_NULL)
|
rl.SetExitKey(.KEY_NULL)
|
||||||
rl.SetWindowPosition(200, 200)
|
rl.SetWindowPosition(200, 200)
|
||||||
rl.SetTargetFPS(60)
|
rl.SetTargetFPS(120)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(export)
|
@(export)
|
||||||
|
@ -48,7 +48,7 @@ simulate :: proc(scene: ^Scene, state: ^Solver_State, config: Solver_Config, dt:
|
|||||||
state.accumulated_time += dt
|
state.accumulated_time += dt
|
||||||
|
|
||||||
num_steps := 0
|
num_steps := 0
|
||||||
for state.accumulated_time > config.timestep {
|
for state.accumulated_time >= config.timestep {
|
||||||
num_steps += 1
|
num_steps += 1
|
||||||
state.accumulated_time -= config.timestep
|
state.accumulated_time -= config.timestep
|
||||||
|
|
||||||
@ -135,17 +135,21 @@ simulate_step :: proc(scene: ^Scene, config: Solver_Config) {
|
|||||||
for _, i in scene.suspension_constraints {
|
for _, i in scene.suspension_constraints {
|
||||||
v := &scene.suspension_constraints_slice[i]
|
v := &scene.suspension_constraints_slice[i]
|
||||||
if v.alive {
|
if v.alive {
|
||||||
|
body_idx := int(v.body) - 1
|
||||||
body := get_body(scene, v.body)
|
body := get_body(scene, v.body)
|
||||||
|
|
||||||
if body.alive && v.hit {
|
if body.alive && v.hit {
|
||||||
|
prev_x, prev_q := body_states[body_idx].prev_x, body_states[body_idx].prev_q
|
||||||
|
|
||||||
wheel_world_pos := body_local_to_world(body, v.rel_pos)
|
wheel_world_pos := body_local_to_world(body, v.rel_pos)
|
||||||
|
prev_wheel_world_pos := prev_x + lg.quaternion_mul_vector3(prev_q, v.rel_pos)
|
||||||
|
|
||||||
|
vel_3d := (wheel_world_pos - prev_wheel_world_pos) * inv_dt
|
||||||
dir := body_local_to_world_vec(body, v.rel_dir)
|
dir := body_local_to_world_vec(body, v.rel_dir)
|
||||||
body_state := body_states[i32(v.body) - 1]
|
body_state := body_states[i32(v.body) - 1]
|
||||||
|
|
||||||
// Spring damping
|
// Spring damping
|
||||||
if true {
|
if true {
|
||||||
vel_3d := body_velocity_at_local_point(body, wheel_world_pos - body.x)
|
|
||||||
|
|
||||||
vel := lg.dot(vel_3d, dir)
|
vel := lg.dot(vel_3d, dir)
|
||||||
damping := -vel * min(v.damping * dt, 1)
|
damping := -vel * min(v.damping * dt, 1)
|
||||||
|
|
||||||
@ -166,8 +170,6 @@ simulate_step :: proc(scene: ^Scene, config: Solver_Config) {
|
|||||||
total_impulse := v.drive_impulse - v.brake_impulse
|
total_impulse := v.drive_impulse - v.brake_impulse
|
||||||
forward := body_local_to_world_vec(body, rl.Vector3{0, 0, 1})
|
forward := body_local_to_world_vec(body, rl.Vector3{0, 0, 1})
|
||||||
|
|
||||||
corr := total_impulse * forward * dt
|
|
||||||
|
|
||||||
apply_constraint_correction_unilateral(
|
apply_constraint_correction_unilateral(
|
||||||
dt,
|
dt,
|
||||||
body,
|
body,
|
||||||
@ -176,7 +178,6 @@ simulate_step :: proc(scene: ^Scene, config: Solver_Config) {
|
|||||||
forward,
|
forward,
|
||||||
wheel_world_pos,
|
wheel_world_pos,
|
||||||
)
|
)
|
||||||
apply_correction(body, corr, wheel_world_pos)
|
|
||||||
body_solve_velocity(body, body_state, inv_dt)
|
body_solve_velocity(body, body_state, inv_dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user