More tyre tweaks, chase camera like in GTA 5, basic rigid body interpolation so rendering can run faster than physics and still see everything smoothly
This commit is contained in:
parent
82e9022c73
commit
a6cbfaf88c
@ -1,12 +1,12 @@
|
|||||||
a
|
a
|
||||||
1.1
|
1.1
|
||||||
-180
|
-200
|
||||||
1500
|
1700
|
||||||
2000
|
2000
|
||||||
10
|
10
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
-1
|
-0.5
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
b
|
b
|
||||||
1.4
|
1.2
|
||||||
-120
|
-200
|
||||||
1700
|
1400
|
||||||
0
|
20
|
||||||
300
|
1
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
|
|
10
common/emath/math.odin
Normal file
10
common/emath/math.odin
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// "Engine" math, to avoid aliasing with core:math
|
||||||
|
package emath
|
||||||
|
|
||||||
|
import "core:math"
|
||||||
|
|
||||||
|
_ :: math
|
||||||
|
|
||||||
|
exp_smooth :: proc "contextless" (target: $T, pos: T, speed: f32, dt: f32) -> T {
|
||||||
|
return pos + ((target - pos) * (1.0 - math.exp_f32(-speed * dt)))
|
||||||
|
}
|
167
game/game.odin
167
game/game.odin
@ -15,6 +15,7 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import "assets"
|
import "assets"
|
||||||
|
import "common:emath"
|
||||||
import "common:name"
|
import "common:name"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:log"
|
import "core:log"
|
||||||
@ -27,6 +28,8 @@ import "libs:raylib/rlgl"
|
|||||||
import "libs:tracy"
|
import "libs:tracy"
|
||||||
import "ui"
|
import "ui"
|
||||||
|
|
||||||
|
_ :: emath
|
||||||
|
|
||||||
PIXEL_WINDOW_HEIGHT :: 360
|
PIXEL_WINDOW_HEIGHT :: 360
|
||||||
|
|
||||||
Track :: struct {
|
Track :: struct {
|
||||||
@ -115,6 +118,8 @@ World :: struct {
|
|||||||
player_pos: rl.Vector3,
|
player_pos: rl.Vector3,
|
||||||
track: Track,
|
track: Track,
|
||||||
physics_scene: physics.Scene,
|
physics_scene: physics.Scene,
|
||||||
|
// How much time passed in physics scene, can be 0 when paused
|
||||||
|
physics_dt: f32,
|
||||||
pause: bool,
|
pause: bool,
|
||||||
car_handle: physics.Body_Handle,
|
car_handle: physics.Body_Handle,
|
||||||
engine_handle: physics.Engine_Handle,
|
engine_handle: physics.Engine_Handle,
|
||||||
@ -149,8 +154,7 @@ Runtime_World :: struct {
|
|||||||
camera_yaw_pitch: rl.Vector2,
|
camera_yaw_pitch: rl.Vector2,
|
||||||
camera_speed: f32,
|
camera_speed: f32,
|
||||||
camera: rl.Camera3D,
|
camera: rl.Camera3D,
|
||||||
orbit_camera: Orbit_Camera,
|
game_camera: Game_Camera,
|
||||||
camera_mode: Camera_Mode,
|
|
||||||
dt: f32,
|
dt: f32,
|
||||||
rewind_simulation: bool,
|
rewind_simulation: bool,
|
||||||
commit_simulation: bool,
|
commit_simulation: bool,
|
||||||
@ -206,11 +210,6 @@ Game_Memory :: struct {
|
|||||||
free_cam: bool,
|
free_cam: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera_Mode :: enum {
|
|
||||||
Orbit,
|
|
||||||
Hood,
|
|
||||||
}
|
|
||||||
|
|
||||||
Track_Edit_State :: enum {
|
Track_Edit_State :: enum {
|
||||||
// Point selection
|
// Point selection
|
||||||
Select,
|
Select,
|
||||||
@ -354,7 +353,7 @@ camera_forward_vec :: proc() -> rl.Vector3 {
|
|||||||
|
|
||||||
game_camera_3d :: proc() -> rl.Camera3D {
|
game_camera_3d :: proc() -> rl.Camera3D {
|
||||||
if g_mem.editor || g_mem.free_cam {
|
if g_mem.editor || g_mem.free_cam {
|
||||||
return free_camera_to_rl(&g_mem.es.camera)
|
return free_camera_to_rl(g_mem.es.camera)
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_runtime_world().camera
|
return get_runtime_world().camera
|
||||||
@ -557,7 +556,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
|||||||
u32(box_name),
|
u32(box_name),
|
||||||
physics.Body_Config {
|
physics.Body_Config {
|
||||||
name = box_name,
|
name = box_name,
|
||||||
initial_pos = {-5 + f32(y) * 1.01, 1, f32(x) * 1.01 + -11.5},
|
initial_pos = {5 + f32(y) * 1.01, 1, f32(x) * 1.01 + -11.5},
|
||||||
initial_rot = linalg.QUATERNIONF32_IDENTITY,
|
initial_rot = linalg.QUATERNIONF32_IDENTITY,
|
||||||
shapes = {
|
shapes = {
|
||||||
{
|
{
|
||||||
@ -709,7 +708,8 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
|||||||
|
|
||||||
DRIVE_IMPULSE :: 3000
|
DRIVE_IMPULSE :: 3000
|
||||||
BRAKE_IMPULSE :: 10
|
BRAKE_IMPULSE :: 10
|
||||||
TURN_ANGLE :: -f32(50) * math.RAD_PER_DEG
|
TURN_ANGLE_AT_HIGH_SPEED :: f32(10) * math.RAD_PER_DEG
|
||||||
|
TURN_ANGLE_AT_LOW_SPEED :: f32(30) * math.RAD_PER_DEG
|
||||||
// 68% front, 32% rear
|
// 68% front, 32% rear
|
||||||
BRAKE_BIAS :: f32(0.68)
|
BRAKE_BIAS :: f32(0.68)
|
||||||
|
|
||||||
@ -745,7 +745,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
car_body := physics.get_body(sim_state, world.car_handle)
|
car_body := physics.get_body(sim_state, world.car_handle)
|
||||||
turn_vel_correction := clamp(4.0 / linalg.length(car_body.v), 0, 1)
|
turn_vel_correction := math.smoothstep(f32(90), f32(10), linalg.length(car_body.v) * 3.6)
|
||||||
|
|
||||||
turn_input := rl.GetGamepadAxisMovement(0, .LEFT_X)
|
turn_input := rl.GetGamepadAxisMovement(0, .LEFT_X)
|
||||||
if abs(turn_input) < GAMEPAD_DEADZONE {
|
if abs(turn_input) < GAMEPAD_DEADZONE {
|
||||||
@ -761,7 +761,10 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
|||||||
for wheel_handle in turn_wheels {
|
for wheel_handle in turn_wheels {
|
||||||
wheel := physics.get_suspension_constraint(sim_state, wheel_handle)
|
wheel := physics.get_suspension_constraint(sim_state, wheel_handle)
|
||||||
|
|
||||||
wheel.turn_angle = TURN_ANGLE * turn_vel_correction * turn_input
|
wheel.turn_angle =
|
||||||
|
TURN_ANGLE_AT_HIGH_SPEED +
|
||||||
|
(TURN_ANGLE_AT_LOW_SPEED - TURN_ANGLE_AT_HIGH_SPEED) * turn_vel_correction
|
||||||
|
wheel.turn_angle *= -turn_input
|
||||||
}
|
}
|
||||||
|
|
||||||
immediate_scene(world, &world.main_scene, "assets/blender/test_level_blend/Scene.scn")
|
immediate_scene(world, &world.main_scene, "assets/blender/test_level_blend/Scene.scn")
|
||||||
@ -788,7 +791,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
physics.simulate(
|
world.physics_dt = physics.simulate(
|
||||||
&world.physics_scene,
|
&world.physics_scene,
|
||||||
SOLVER_CONFIG,
|
SOLVER_CONFIG,
|
||||||
dt,
|
dt,
|
||||||
@ -816,7 +819,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) {
|
runtime_world_update :: proc(runtime_world: ^Runtime_World, dt: f32) {
|
||||||
cur_world := runtime_world_current_world(runtime_world)
|
cur_world := runtime_world_current_world(runtime_world)
|
||||||
|
|
||||||
runtime_world.dt = dt
|
runtime_world.dt = dt
|
||||||
@ -856,6 +859,24 @@ Orbit_Camera :: struct {
|
|||||||
distance: f32,
|
distance: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Car_Follow_Camera :: struct {
|
||||||
|
// Params
|
||||||
|
body: physics.Body_Handle,
|
||||||
|
com_offset: rl.Vector3,
|
||||||
|
distance: f32,
|
||||||
|
|
||||||
|
// State
|
||||||
|
pos: rl.Vector3,
|
||||||
|
target: rl.Vector3,
|
||||||
|
up: rl.Vector3,
|
||||||
|
}
|
||||||
|
|
||||||
|
Game_Camera :: union {
|
||||||
|
Free_Camera,
|
||||||
|
Orbit_Camera,
|
||||||
|
Car_Follow_Camera,
|
||||||
|
}
|
||||||
|
|
||||||
GAMEPAD_DEADZONE :: f32(0.07)
|
GAMEPAD_DEADZONE :: f32(0.07)
|
||||||
|
|
||||||
collect_camera_input :: proc() -> (delta: rl.Vector2, sense: f32) {
|
collect_camera_input :: proc() -> (delta: rl.Vector2, sense: f32) {
|
||||||
@ -929,6 +950,60 @@ orbit_camera_to_rl :: proc(camera: Orbit_Camera) -> rl.Camera3D {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
follow_camera_update :: proc(world: ^World, camera: ^Car_Follow_Camera, dt: f32) {
|
||||||
|
body := physics.get_interpolated_body(&world.physics_scene, SOLVER_CONFIG, camera.body)
|
||||||
|
|
||||||
|
camera.target = body.x + physics.Vec3{0, 2.5, 0}
|
||||||
|
|
||||||
|
// forward := physics.body_local_to_world_vec(body, physics.Vec3{0, 0, 1})
|
||||||
|
// up := physics.body_local_to_world_vec(body, physics.Vec3{0, 1, 0})
|
||||||
|
|
||||||
|
dir := linalg.normalize0(camera.pos - camera.target)
|
||||||
|
if dir == 0 {
|
||||||
|
dir = {0, 0, -1}
|
||||||
|
}
|
||||||
|
distance := f32(8)
|
||||||
|
pos_target := camera.target + dir * distance
|
||||||
|
log.debugf("pos_target: {}", pos_target)
|
||||||
|
|
||||||
|
camera.pos = emath.exp_smooth(pos_target, camera.pos, 40, dt)
|
||||||
|
}
|
||||||
|
|
||||||
|
follow_camera_to_rl :: proc(camera: Car_Follow_Camera) -> rl.Camera3D {
|
||||||
|
return rl.Camera3D {
|
||||||
|
position = camera.pos,
|
||||||
|
target = camera.target,
|
||||||
|
up = rl.Vector3{0, 1, 0},
|
||||||
|
fovy = 50,
|
||||||
|
projection = .PERSPECTIVE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
game_camera_update :: proc(world: ^World, camera: ^Game_Camera, dt: f32) {
|
||||||
|
switch &c in camera {
|
||||||
|
case Free_Camera:
|
||||||
|
free_camera_update(&c)
|
||||||
|
case Orbit_Camera:
|
||||||
|
orbit_camera_update(&c)
|
||||||
|
case Car_Follow_Camera:
|
||||||
|
follow_camera_update(world, &c, dt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
game_camera_to_rl :: proc(camera: Game_Camera) -> rl.Camera3D {
|
||||||
|
result: rl.Camera3D
|
||||||
|
switch c in camera {
|
||||||
|
case Free_Camera:
|
||||||
|
result = free_camera_to_rl(c)
|
||||||
|
case Orbit_Camera:
|
||||||
|
result = orbit_camera_to_rl(c)
|
||||||
|
case Car_Follow_Camera:
|
||||||
|
result = follow_camera_to_rl(c)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Matrix3 :: # row_major matrix[3, 3]f32
|
Matrix3 :: # row_major matrix[3, 3]f32
|
||||||
|
|
||||||
free_camera_rotation :: proc(camera: Free_Camera) -> linalg.Matrix3f32 {
|
free_camera_rotation :: proc(camera: Free_Camera) -> linalg.Matrix3f32 {
|
||||||
@ -971,8 +1046,8 @@ free_camera_update :: proc(camera: ^Free_Camera) {
|
|||||||
camera.pos += (input.x * right + input.y * forward) * camera.speed
|
camera.pos += (input.x * right + input.y * forward) * camera.speed
|
||||||
}
|
}
|
||||||
|
|
||||||
free_camera_to_rl :: proc(camera: ^Free_Camera) -> (result: rl.Camera3D) {
|
free_camera_to_rl :: proc(camera: Free_Camera) -> (result: rl.Camera3D) {
|
||||||
rotation := free_camera_rotation(camera^)
|
rotation := free_camera_rotation(camera)
|
||||||
forward := -rotation[2]
|
forward := -rotation[2]
|
||||||
|
|
||||||
result.position = camera.pos
|
result.position = camera.pos
|
||||||
@ -1008,16 +1083,6 @@ update :: proc() {
|
|||||||
// g_mem.es.world.player_pos = g_mem.runtime_world.camera.position
|
// g_mem.es.world.player_pos = g_mem.runtime_world.camera.position
|
||||||
}
|
}
|
||||||
|
|
||||||
if rl.IsKeyPressed(.F2) && !g_mem.free_cam {
|
|
||||||
cam_mode := &get_runtime_world().camera_mode
|
|
||||||
switch cam_mode^ {
|
|
||||||
case .Orbit:
|
|
||||||
cam_mode^ = .Hood
|
|
||||||
case .Hood:
|
|
||||||
cam_mode^ = .Orbit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dt := rl.GetFrameTime()
|
dt := rl.GetFrameTime()
|
||||||
|
|
||||||
// Debug BVH traversal
|
// Debug BVH traversal
|
||||||
@ -1056,33 +1121,25 @@ update :: proc() {
|
|||||||
if g_mem.editor {
|
if g_mem.editor {
|
||||||
update_editor(get_editor_state(), dt)
|
update_editor(get_editor_state(), dt)
|
||||||
} else {
|
} else {
|
||||||
update_runtime_world(get_runtime_world(), dt)
|
runtime_world_update(get_runtime_world(), dt)
|
||||||
world := runtime_world_current_world(get_runtime_world())
|
world := runtime_world_current_world(get_runtime_world())
|
||||||
|
|
||||||
if g_mem.free_cam {
|
if g_mem.free_cam {
|
||||||
free_camera_update(&g_mem.es.camera)
|
free_camera_update(&g_mem.es.camera)
|
||||||
} else {
|
} else {
|
||||||
switch get_runtime_world().camera_mode {
|
game_cam := &get_runtime_world().game_camera
|
||||||
case .Orbit:
|
if _, ok := game_cam.(Car_Follow_Camera); !ok {
|
||||||
orbit_camera_update(&get_runtime_world().orbit_camera)
|
game_cam^ = Car_Follow_Camera{}
|
||||||
get_runtime_world().camera = orbit_camera_to_rl(get_runtime_world().orbit_camera)
|
log.debugf("overwriting cam")
|
||||||
case .Hood:
|
|
||||||
car := physics.get_body(
|
|
||||||
physics.get_sim_state(&world.physics_scene),
|
|
||||||
world.car_handle,
|
|
||||||
)
|
|
||||||
|
|
||||||
cam: rl.Camera3D
|
|
||||||
cam.position = physics.body_local_to_world(car, physics.Vec3{0, 0.9, 2})
|
|
||||||
cam.target =
|
|
||||||
cam.position + physics.body_local_to_world_vec(car, physics.Vec3{0, 0, 1})
|
|
||||||
cam.up = physics.body_local_to_world_vec(car, physics.Vec3{0, 1, 0})
|
|
||||||
cam.fovy = 60
|
|
||||||
cam.projection = .PERSPECTIVE
|
|
||||||
|
|
||||||
|
|
||||||
get_runtime_world().camera = cam
|
|
||||||
}
|
}
|
||||||
|
car_follow_cam := &game_cam.(Car_Follow_Camera)
|
||||||
|
car_follow_cam.body = world.car_handle
|
||||||
|
|
||||||
|
if world.physics_dt == 0 {
|
||||||
|
log.debugf("phys dt == 0")
|
||||||
|
}
|
||||||
|
game_camera_update(world, &get_runtime_world().game_camera, dt)
|
||||||
|
get_runtime_world().camera = game_camera_to_rl(get_runtime_world().game_camera)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1125,7 +1182,11 @@ draw_world :: proc(world: ^World) {
|
|||||||
phys_debug_state: physics.Debug_State
|
phys_debug_state: physics.Debug_State
|
||||||
physics.init_debug_state(&phys_debug_state)
|
physics.init_debug_state(&phys_debug_state)
|
||||||
|
|
||||||
car_body := physics.get_body(sim_state, world.car_handle)
|
car_body := physics.get_interpolated_body(
|
||||||
|
&world.physics_scene,
|
||||||
|
SOLVER_CONFIG,
|
||||||
|
world.car_handle,
|
||||||
|
)
|
||||||
engine := physics.get_engine(sim_state, world.engine_handle)
|
engine := physics.get_engine(sim_state, world.engine_handle)
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1187,8 +1248,9 @@ draw_world :: proc(world: ^World) {
|
|||||||
|
|
||||||
|
|
||||||
car_matrix := rl.QuaternionToMatrix(car_body.q)
|
car_matrix := rl.QuaternionToMatrix(car_body.q)
|
||||||
car_matrix =
|
// TODO: figure out how to use helper funcs that take Body_Ptr for interpolated body which is just Body
|
||||||
(auto_cast linalg.matrix4_translate_f32(physics.body_get_shape_pos(car_body))) * car_matrix
|
car_pos := linalg.quaternion_mul_vector3(car_body.q, car_body.shape_offset) + car_body.x
|
||||||
|
car_matrix = (auto_cast linalg.matrix4_translate_f32(car_pos)) * car_matrix
|
||||||
|
|
||||||
// basic_shader := assets.get_shader(
|
// basic_shader := assets.get_shader(
|
||||||
// &g_mem.assetman,
|
// &g_mem.assetman,
|
||||||
@ -1532,7 +1594,10 @@ game_hot_reloaded :: proc(mem: rawptr) {
|
|||||||
render.init(&g_mem.assetman)
|
render.init(&g_mem.assetman)
|
||||||
ui.rl_init()
|
ui.rl_init()
|
||||||
|
|
||||||
g_mem.runtime_world.orbit_camera.distance = 6
|
orbit, ok := &g_mem.runtime_world.game_camera.(Orbit_Camera)
|
||||||
|
if ok {
|
||||||
|
orbit.distance = 6
|
||||||
|
}
|
||||||
log.debugf("hot reloaded")
|
log.debugf("hot reloaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,14 @@ package physics
|
|||||||
import "bvh"
|
import "bvh"
|
||||||
import "collision"
|
import "collision"
|
||||||
import "common:name"
|
import "common:name"
|
||||||
|
import "core:log"
|
||||||
import lg "core:math/linalg"
|
import lg "core:math/linalg"
|
||||||
import "game:assets"
|
import "game:assets"
|
||||||
import "game:container/spanpool"
|
import "game:container/spanpool"
|
||||||
import "libs:tracy"
|
import "libs:tracy"
|
||||||
|
|
||||||
|
_ :: log
|
||||||
|
|
||||||
MAX_CONTACTS :: 1024 * 16
|
MAX_CONTACTS :: 1024 * 16
|
||||||
|
|
||||||
Vec3 :: [3]f32
|
Vec3 :: [3]f32
|
||||||
@ -122,7 +125,7 @@ Sim_State :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEV_BUILD :: #config(DEV, false)
|
DEV_BUILD :: #config(DEV, false)
|
||||||
NUM_SIM_STATES :: 2 when DEV_BUILD else 1
|
NUM_SIM_STATES :: 2
|
||||||
|
|
||||||
Scene :: struct {
|
Scene :: struct {
|
||||||
assetman: ^assets.Asset_Manager,
|
assetman: ^assets.Asset_Manager,
|
||||||
@ -537,6 +540,40 @@ get_body :: proc(sim_state: ^Sim_State, handle: Body_Handle) -> Body_Ptr {
|
|||||||
return &sim_state.bodies_slice[index]
|
return &sim_state.bodies_slice[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_interpolated_body :: proc(
|
||||||
|
scene: ^Scene,
|
||||||
|
solver_config: Solver_Config,
|
||||||
|
handle: Body_Handle,
|
||||||
|
) -> Body {
|
||||||
|
prev_sim_state := get_prev_sim_state(scene)
|
||||||
|
sim_state := get_sim_state(scene)
|
||||||
|
|
||||||
|
prev_body := get_body(prev_sim_state, handle)
|
||||||
|
body := get_body(sim_state, handle)
|
||||||
|
|
||||||
|
result: Body = Body {
|
||||||
|
q = lg.QUATERNIONF32_IDENTITY,
|
||||||
|
}
|
||||||
|
|
||||||
|
if prev_body.alive && body.alive {
|
||||||
|
// interpolate
|
||||||
|
t := scene.solver_state.accumulated_time / solver_config.timestep
|
||||||
|
log.debugf("t = {}", t)
|
||||||
|
result = prev_body^
|
||||||
|
result.x = body.x * t + (1.0 - t) * prev_body.x
|
||||||
|
result.q = lg.quaternion_slerp_f32(prev_body.q, body.q, t)
|
||||||
|
result.v = lg.lerp(prev_body.v, body.v, t)
|
||||||
|
// I don't think that's right, but not going to be used anyway probably
|
||||||
|
result.w = lg.lerp(prev_body.w, body.w, t)
|
||||||
|
} else if prev_body.alive {
|
||||||
|
result = prev_body^
|
||||||
|
} else if body.alive {
|
||||||
|
result = body^
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
remove_shape :: proc(sim_state: ^Sim_State, idx: i32) {
|
remove_shape :: proc(sim_state: ^Sim_State, idx: i32) {
|
||||||
cur_idx := idx
|
cur_idx := idx
|
||||||
for {
|
for {
|
||||||
|
@ -696,6 +696,8 @@ simulate :: proc(
|
|||||||
dt: f32,
|
dt: f32,
|
||||||
commit := true, // commit = false is a special mode for debugging physics stepping to allow rerunning the same step each frame
|
commit := true, // commit = false is a special mode for debugging physics stepping to allow rerunning the same step each frame
|
||||||
step_mode := Step_Mode.Accumulated_Time,
|
step_mode := Step_Mode.Accumulated_Time,
|
||||||
|
) -> (
|
||||||
|
accumulated_dt: f32,
|
||||||
) {
|
) {
|
||||||
tracy.Zone()
|
tracy.Zone()
|
||||||
assert(config.timestep > 0)
|
assert(config.timestep > 0)
|
||||||
@ -704,31 +706,37 @@ simulate :: proc(
|
|||||||
|
|
||||||
prune_immediate(scene)
|
prune_immediate(scene)
|
||||||
|
|
||||||
copy_sim_state(get_next_sim_state(scene), get_sim_state(scene))
|
did_copy := false
|
||||||
sim_state := get_next_sim_state(scene)
|
sim_state := get_next_sim_state(scene)
|
||||||
|
|
||||||
// runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
||||||
|
|
||||||
sim_cache: Sim_Cache
|
sim_cache: Sim_Cache
|
||||||
sim_cache.level_geom_asset_bvh = make_map(
|
sim_cache.level_geom_asset_bvh = make_map(
|
||||||
map[Level_Geom_Handle]assets.Loaded_BVH,
|
map[Level_Geom_Handle]assets.Loaded_BVH,
|
||||||
context.temp_allocator,
|
context.temp_allocator,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
simulated_dt := f32(0)
|
||||||
|
|
||||||
num_steps := 0
|
num_steps := 0
|
||||||
switch step_mode {
|
switch step_mode {
|
||||||
case .Accumulated_Time:
|
case .Accumulated_Time:
|
||||||
state.accumulated_time += dt
|
state.accumulated_time += dt
|
||||||
|
|
||||||
for state.accumulated_time >= config.timestep {
|
for state.accumulated_time >= config.timestep {
|
||||||
|
if !did_copy {
|
||||||
|
did_copy = true
|
||||||
|
copy_sim_state(get_next_sim_state(scene), get_sim_state(scene))
|
||||||
|
}
|
||||||
num_steps += 1
|
num_steps += 1
|
||||||
state.accumulated_time -= config.timestep
|
state.accumulated_time -= config.timestep
|
||||||
|
simulated_dt += config.timestep
|
||||||
|
|
||||||
if num_steps < MAX_STEPS {
|
if num_steps < MAX_STEPS {
|
||||||
simulate_step(scene, sim_state, &sim_cache, config)
|
simulate_step(scene, sim_state, &sim_cache, config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .Single:
|
case .Single:
|
||||||
|
copy_sim_state(get_next_sim_state(scene), get_sim_state(scene))
|
||||||
simulate_step(scene, get_next_sim_state(scene), &sim_cache, config)
|
simulate_step(scene, get_next_sim_state(scene), &sim_cache, config)
|
||||||
num_steps += 1
|
num_steps += 1
|
||||||
}
|
}
|
||||||
@ -742,6 +750,8 @@ simulate :: proc(
|
|||||||
state.immediate_suspension_constraints.num_items = 0
|
state.immediate_suspension_constraints.num_items = 0
|
||||||
state.immediate_engines.num_items = 0
|
state.immediate_engines.num_items = 0
|
||||||
state.immediate_level_geoms.num_items = 0
|
state.immediate_level_geoms.num_items = 0
|
||||||
|
|
||||||
|
return simulated_dt
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBAL_PLANE :: collision.Plane {
|
GLOBAL_PLANE :: collision.Plane {
|
||||||
@ -1332,7 +1342,7 @@ pgs_solve_suspension :: proc(
|
|||||||
) *
|
) *
|
||||||
math.sign(lateral_to_longitudinal_relation)
|
math.sign(lateral_to_longitudinal_relation)
|
||||||
|
|
||||||
v.turn_assist = drift_amount * math.PI * 0.1
|
v.turn_assist = drift_amount * math.PI * 0.15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user