Add undo redo for editor, refactor cameras a bit
This commit is contained in:
parent
df0fe56368
commit
f8b73786aa
237
game/editor.odin
237
game/editor.odin
@ -3,151 +3,122 @@ package game
|
|||||||
import lg "core:math/linalg"
|
import lg "core:math/linalg"
|
||||||
import rl "libs:raylib"
|
import rl "libs:raylib"
|
||||||
|
|
||||||
update_free_look_camera :: proc(es: ^Editor_State) {
|
|
||||||
input: rl.Vector2
|
|
||||||
|
|
||||||
if rl.IsKeyDown(.UP) || rl.IsKeyDown(.W) {
|
|
||||||
input.y -= 1
|
|
||||||
}
|
|
||||||
if rl.IsKeyDown(.DOWN) || rl.IsKeyDown(.S) {
|
|
||||||
input.y += 1
|
|
||||||
}
|
|
||||||
if rl.IsKeyDown(.LEFT) || rl.IsKeyDown(.A) {
|
|
||||||
input.x -= 1
|
|
||||||
}
|
|
||||||
if rl.IsKeyDown(.RIGHT) || rl.IsKeyDown(.D) {
|
|
||||||
input.x += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
should_capture_mouse := rl.IsMouseButtonDown(.RIGHT)
|
|
||||||
if es.mouse_captured != should_capture_mouse {
|
|
||||||
if should_capture_mouse {
|
|
||||||
rl.DisableCursor()
|
|
||||||
} else {
|
|
||||||
rl.EnableCursor()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
es.mouse_captured = should_capture_mouse
|
|
||||||
|
|
||||||
if es.mouse_captured {
|
|
||||||
get_runtime_world().camera_yaw_pitch += rl.GetMouseDelta().yx * -1 * 0.001
|
|
||||||
}
|
|
||||||
|
|
||||||
get_runtime_world().camera_speed += rl.GetMouseWheelMove() * 0.01
|
|
||||||
get_runtime_world().camera_speed = lg.clamp(get_runtime_world().camera_speed, 0.01, 10)
|
|
||||||
|
|
||||||
rotation_matrix := camera_rotation_matrix()
|
|
||||||
forward := -rotation_matrix[2]
|
|
||||||
right := lg.cross(rl.Vector3{0, 1, 0}, forward)
|
|
||||||
|
|
||||||
input = lg.normalize0(input)
|
|
||||||
get_world().player_pos +=
|
|
||||||
(input.x * right + input.y * forward) * get_runtime_world().camera_speed
|
|
||||||
}
|
|
||||||
|
|
||||||
update_editor :: proc(es: ^Editor_State, dt: f32) {
|
update_editor :: proc(es: ^Editor_State, dt: f32) {
|
||||||
update_world(&es.world, dt, false)
|
free_camera_update(&es.camera)
|
||||||
update_free_look_camera(es)
|
|
||||||
|
|
||||||
switch es.track_edit_state {
|
did_undo_redo := false
|
||||||
case .Select:
|
|
||||||
{
|
|
||||||
if rl.IsKeyPressed(.F) {
|
|
||||||
add_track_spline_point()
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_point_selected() {
|
if rl.IsKeyPressed(.Z) && rl.IsKeyDown(.LEFT_CONTROL) {
|
||||||
if rl.IsKeyPressed(.X) {
|
world_stack_pop(&es.world_stack)
|
||||||
|
did_undo_redo = true
|
||||||
|
}
|
||||||
|
|
||||||
if len(es.point_selection) <= 1 {
|
if !did_undo_redo {
|
||||||
for i in es.point_selection {
|
switch es.track_edit_state {
|
||||||
ordered_remove(&get_world().track.points, i)
|
case .Select:
|
||||||
}
|
{
|
||||||
} else {
|
if rl.IsKeyPressed(.F) {
|
||||||
#reverse for _, i in get_world().track.points {
|
world_stack_push(&es.world_stack)
|
||||||
if i in es.point_selection {
|
add_track_spline_point()
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_point_selected() {
|
||||||
|
if rl.IsKeyPressed(.X) {
|
||||||
|
world_stack_push(&es.world_stack)
|
||||||
|
if len(es.point_selection) <= 1 {
|
||||||
|
for i in es.point_selection {
|
||||||
ordered_remove(&get_world().track.points, i)
|
ordered_remove(&get_world().track.points, i)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
#reverse for _, i in get_world().track.points {
|
||||||
|
if i in es.point_selection {
|
||||||
|
ordered_remove(&get_world().track.points, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear(&es.point_selection)
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(.G) {
|
||||||
|
es.track_edit_state = .Move
|
||||||
|
es.move_axis = .None
|
||||||
|
es.total_movement_world = {}
|
||||||
|
world_stack_push(&es.world_stack)
|
||||||
|
// es.initial_point_pos = g_mem.track.points[es.selected_track_point]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .Move:
|
||||||
|
{
|
||||||
|
if rl.IsKeyPressed(.ESCAPE) {
|
||||||
|
es.track_edit_state = .Select
|
||||||
|
// g_mem.track.points[es.selected_track_point] = es.initial_point_pos
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rl.IsMouseButtonPressed(.LEFT)) {
|
||||||
|
es.track_edit_state = .Select
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if !es.mouse_captured {
|
||||||
|
// Blender style movement
|
||||||
|
if rl.IsKeyDown(.LEFT_SHIFT) {
|
||||||
|
if rl.IsKeyPressed(.X) {
|
||||||
|
es.move_axis = .YZ
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(.Y) {
|
||||||
|
es.move_axis = .XZ
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(.Z) {
|
||||||
|
es.move_axis = .XY
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if rl.IsKeyPressed(.X) {
|
||||||
|
es.move_axis = .X
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(.Y) {
|
||||||
|
es.move_axis = .Y
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(.Z) {
|
||||||
|
es.move_axis = .Z
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(&es.point_selection)
|
// log.debugf("Move axis %v", es.move_axis)
|
||||||
}
|
|
||||||
if rl.IsKeyPressed(.G) {
|
camera := game_camera_3d()
|
||||||
es.track_edit_state = .Move
|
|
||||||
es.move_axis = .None
|
mouse_delta := rl.GetMouseDelta() * 0.05
|
||||||
es.total_movement_world = {}
|
|
||||||
// es.initial_point_pos = g_mem.track.points[es.selected_track_point]
|
view_rotation := lg.transpose(rl.GetCameraMatrix(camera))
|
||||||
|
view_rotation[3].xyz = 0
|
||||||
|
view_proj := view_rotation * rl.MatrixOrtho(-1, 1, 1, -1, -1, 1)
|
||||||
|
|
||||||
|
axes_buf: [2]rl.Vector3
|
||||||
|
colors_buf: [2]rl.Color
|
||||||
|
axes, _ := get_movement_axes(es.move_axis, &axes_buf, &colors_buf)
|
||||||
|
|
||||||
|
movement_world: rl.Vector3
|
||||||
|
for axis in axes {
|
||||||
|
axis_screen := (rl.Vector4{axis.x, axis.y, axis.z, 1} * view_proj).xy
|
||||||
|
axis_screen = lg.normalize0(axis_screen)
|
||||||
|
|
||||||
|
movement_screen := lg.dot(axis_screen, mouse_delta) * axis_screen
|
||||||
|
movement_world +=
|
||||||
|
(rl.Vector4{movement_screen.x, movement_screen.y, 0, 1} * rl.MatrixInvert(view_proj)).xyz
|
||||||
|
}
|
||||||
|
|
||||||
|
for k in es.point_selection {
|
||||||
|
get_world().track.points[k] += movement_world
|
||||||
|
}
|
||||||
|
|
||||||
|
es.total_movement_world += movement_world
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .Move:
|
|
||||||
{
|
|
||||||
if rl.IsKeyPressed(.ESCAPE) {
|
|
||||||
es.track_edit_state = .Select
|
|
||||||
// g_mem.track.points[es.selected_track_point] = es.initial_point_pos
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rl.IsMouseButtonPressed(.LEFT)) {
|
|
||||||
es.track_edit_state = .Select
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if !es.mouse_captured {
|
|
||||||
// Blender style movement
|
|
||||||
if rl.IsKeyDown(.LEFT_SHIFT) {
|
|
||||||
if rl.IsKeyPressed(.X) {
|
|
||||||
es.move_axis = .YZ
|
|
||||||
}
|
|
||||||
if rl.IsKeyPressed(.Y) {
|
|
||||||
es.move_axis = .XZ
|
|
||||||
}
|
|
||||||
if rl.IsKeyPressed(.Z) {
|
|
||||||
es.move_axis = .XY
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if rl.IsKeyPressed(.X) {
|
|
||||||
es.move_axis = .X
|
|
||||||
}
|
|
||||||
if rl.IsKeyPressed(.Y) {
|
|
||||||
es.move_axis = .Y
|
|
||||||
}
|
|
||||||
if rl.IsKeyPressed(.Z) {
|
|
||||||
es.move_axis = .Z
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.debugf("Move axis %v", es.move_axis)
|
|
||||||
|
|
||||||
camera := game_camera_3d()
|
|
||||||
|
|
||||||
mouse_delta := rl.GetMouseDelta() * 0.05
|
|
||||||
|
|
||||||
view_rotation := lg.transpose(rl.GetCameraMatrix(camera))
|
|
||||||
view_rotation[3].xyz = 0
|
|
||||||
view_proj := view_rotation * rl.MatrixOrtho(-1, 1, 1, -1, -1, 1)
|
|
||||||
|
|
||||||
axes_buf: [2]rl.Vector3
|
|
||||||
colors_buf: [2]rl.Color
|
|
||||||
axes, _ := get_movement_axes(es.move_axis, &axes_buf, &colors_buf)
|
|
||||||
|
|
||||||
movement_world: rl.Vector3
|
|
||||||
for axis in axes {
|
|
||||||
axis_screen := (rl.Vector4{axis.x, axis.y, axis.z, 1} * view_proj).xy
|
|
||||||
axis_screen = lg.normalize0(axis_screen)
|
|
||||||
|
|
||||||
movement_screen := lg.dot(axis_screen, mouse_delta) * axis_screen
|
|
||||||
movement_world +=
|
|
||||||
(rl.Vector4{movement_screen.x, movement_screen.y, 0, 1} * rl.MatrixInvert(view_proj)).xyz
|
|
||||||
}
|
|
||||||
|
|
||||||
for k in es.point_selection {
|
|
||||||
get_world().track.points[k] += movement_world
|
|
||||||
}
|
|
||||||
|
|
||||||
es.total_movement_world += movement_world
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// world := world_stack_current(&es.world_stack)
|
||||||
|
// update_world(world, dt, false)
|
||||||
}
|
}
|
||||||
|
178
game/game.odin
178
game/game.odin
@ -157,14 +157,82 @@ Move_Axis :: enum {
|
|||||||
YZ,
|
YZ,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For undo/redo
|
||||||
|
World_Stack :: struct {
|
||||||
|
worlds: []World,
|
||||||
|
head, tail: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
world_stack_init :: proc(stack: ^World_Stack, num_snapshots: int, allocator := context.allocator) {
|
||||||
|
assert(num_snapshots > 0)
|
||||||
|
stack.worlds = make([]World, num_snapshots, allocator)
|
||||||
|
world_stack_push(stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
world_stack_destroy :: proc(stack: ^World_Stack, allocator := context.allocator) {
|
||||||
|
for &world in stack.worlds {
|
||||||
|
destroy_world(&world)
|
||||||
|
}
|
||||||
|
delete(stack.worlds, allocator)
|
||||||
|
}
|
||||||
|
|
||||||
|
world_stack_len :: proc(stack: ^World_Stack) -> int {
|
||||||
|
if stack.tail >= stack.head {
|
||||||
|
return stack.tail - stack.head
|
||||||
|
} else {
|
||||||
|
return (stack.tail + len(stack.worlds)) - stack.head
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
world_stack_current :: proc(stack: ^World_Stack) -> ^World {
|
||||||
|
if world_stack_len(stack) > 0 {
|
||||||
|
return &stack.worlds[(stack.tail - 1) %% len(stack.worlds)]
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
world_stack_push :: proc(stack: ^World_Stack) {
|
||||||
|
stack_len := world_stack_len(stack)
|
||||||
|
assert(stack_len <= len(stack.worlds))
|
||||||
|
|
||||||
|
if stack_len == len(stack.worlds) {
|
||||||
|
stack.head = (stack.head + 1) %% len(stack.worlds)
|
||||||
|
}
|
||||||
|
assert(world_stack_len(stack) < len(stack.worlds))
|
||||||
|
|
||||||
|
prev_world := world_stack_current(stack)
|
||||||
|
stack.tail = (stack.tail + 1) %% len(stack.worlds)
|
||||||
|
new_world := world_stack_current(stack)
|
||||||
|
|
||||||
|
if prev_world != nil {
|
||||||
|
copy_world(new_world, prev_world)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
world_stack_pop :: proc(stack: ^World_Stack) {
|
||||||
|
if world_stack_len(stack) > 1 {
|
||||||
|
stack.tail = (stack.tail - 1) %% len(stack.worlds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Editor_State :: struct {
|
Editor_State :: struct {
|
||||||
world: World,
|
world_stack: World_Stack,
|
||||||
mouse_captured: bool,
|
mouse_captured: bool,
|
||||||
point_selection: map[int]bool,
|
point_selection: map[int]bool,
|
||||||
track_edit_state: Track_Edit_State,
|
track_edit_state: Track_Edit_State,
|
||||||
move_axis: Move_Axis,
|
move_axis: Move_Axis,
|
||||||
total_movement_world: rl.Vector3,
|
total_movement_world: rl.Vector3,
|
||||||
initial_point_pos: rl.Vector3,
|
initial_point_pos: rl.Vector3,
|
||||||
|
camera: Free_Camera,
|
||||||
|
}
|
||||||
|
|
||||||
|
editor_state_init :: proc(es: ^Editor_State, num_snapshots: int) {
|
||||||
|
world_stack_init(&es.world_stack, num_snapshots)
|
||||||
|
}
|
||||||
|
|
||||||
|
editor_state_destroy :: proc(es: ^Editor_State) {
|
||||||
|
world_stack_destroy(&es.world_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_mem: ^Game_Memory
|
g_mem: ^Game_Memory
|
||||||
@ -175,7 +243,7 @@ get_runtime_world :: proc() -> ^Runtime_World {
|
|||||||
|
|
||||||
get_world :: proc() -> ^World {
|
get_world :: proc() -> ^World {
|
||||||
return(
|
return(
|
||||||
g_mem.editor ? &g_mem.es.world : &g_mem.runtime_world.world_snapshots[g_mem.runtime_world.current_world_index] \
|
g_mem.editor ? world_stack_current(&g_mem.es.world_stack) : &g_mem.runtime_world.world_snapshots[g_mem.runtime_world.current_world_index] \
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,13 +276,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 {
|
return free_camera_to_rl(&g_mem.es.camera)
|
||||||
position = get_world().player_pos,
|
|
||||||
up = {0, 1, 0},
|
|
||||||
fovy = 60,
|
|
||||||
target = get_world().player_pos + camera_forward_vec(),
|
|
||||||
projection = .PERSPECTIVE,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_runtime_world().camera
|
return get_runtime_world().camera
|
||||||
@ -234,9 +296,9 @@ is_point_selected :: proc() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add_track_spline_point :: proc() {
|
add_track_spline_point :: proc() {
|
||||||
forward := camera_rotation_matrix()[2]
|
forward := -free_camera_rotation(g_mem.es.camera)[2]
|
||||||
|
|
||||||
append(&get_world().track.points, get_world().player_pos + forward)
|
append(&get_world().track.points, g_mem.es.camera.pos + forward)
|
||||||
select_track_point(len(&get_world().track.points) - 1)
|
select_track_point(len(&get_world().track.points) - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,6 +638,12 @@ update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Free_Camera :: struct {
|
||||||
|
pos: rl.Vector3,
|
||||||
|
yaw, pitch: f32,
|
||||||
|
speed: f32,
|
||||||
|
}
|
||||||
|
|
||||||
Orbit_Camera :: struct {
|
Orbit_Camera :: struct {
|
||||||
target: rl.Vector3,
|
target: rl.Vector3,
|
||||||
yaw, pitch: f32,
|
yaw, pitch: f32,
|
||||||
@ -584,11 +652,7 @@ Orbit_Camera :: struct {
|
|||||||
|
|
||||||
GAMEPAD_DEADZONE :: f32(0.07)
|
GAMEPAD_DEADZONE :: f32(0.07)
|
||||||
|
|
||||||
orbit_camera_update :: proc(camera: ^Orbit_Camera) {
|
collect_camera_input :: proc() -> (delta: rl.Vector2, sense: f32) {
|
||||||
world := runtime_world_current_world(get_runtime_world())
|
|
||||||
camera.target =
|
|
||||||
physics.get_body(physics.get_sim_state(&world.physics_scene), world.car_handle).x
|
|
||||||
|
|
||||||
gamepad_delta := rl.Vector2 {
|
gamepad_delta := rl.Vector2 {
|
||||||
rl.GetGamepadAxisMovement(0, .RIGHT_X),
|
rl.GetGamepadAxisMovement(0, .RIGHT_X),
|
||||||
rl.GetGamepadAxisMovement(0, .RIGHT_Y),
|
rl.GetGamepadAxisMovement(0, .RIGHT_Y),
|
||||||
@ -615,19 +679,26 @@ orbit_camera_update :: proc(camera: ^Orbit_Camera) {
|
|||||||
MOUSE_SENSE :: 0.01
|
MOUSE_SENSE :: 0.01
|
||||||
GAMEPAD_SENSE :: 1
|
GAMEPAD_SENSE :: 1
|
||||||
|
|
||||||
final_sense: f32
|
|
||||||
delta: rl.Vector2
|
|
||||||
|
|
||||||
if linalg.length2(mouse_delta) > linalg.length2(gamepad_delta) {
|
if linalg.length2(mouse_delta) > linalg.length2(gamepad_delta) {
|
||||||
final_sense = MOUSE_SENSE
|
sense = MOUSE_SENSE
|
||||||
delta = mouse_delta
|
delta = mouse_delta
|
||||||
} else {
|
} else {
|
||||||
final_sense = GAMEPAD_SENSE * rl.GetFrameTime()
|
sense = GAMEPAD_SENSE * rl.GetFrameTime()
|
||||||
delta = gamepad_delta
|
delta = gamepad_delta
|
||||||
}
|
}
|
||||||
|
|
||||||
camera.yaw += delta.x * final_sense
|
return
|
||||||
camera.pitch += delta.y * final_sense
|
}
|
||||||
|
|
||||||
|
orbit_camera_update :: proc(camera: ^Orbit_Camera) {
|
||||||
|
world := runtime_world_current_world(get_runtime_world())
|
||||||
|
camera.target =
|
||||||
|
physics.get_body(physics.get_sim_state(&world.physics_scene), world.car_handle).x
|
||||||
|
|
||||||
|
delta, sense := collect_camera_input()
|
||||||
|
|
||||||
|
camera.yaw += delta.x * sense
|
||||||
|
camera.pitch += delta.y * sense
|
||||||
camera.pitch = math.clamp(camera.pitch, -math.PI / 2.0 + 0.0001, math.PI / 2.0 - 0.0001)
|
camera.pitch = math.clamp(camera.pitch, -math.PI / 2.0 + 0.0001, math.PI / 2.0 - 0.0001)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,6 +723,60 @@ orbit_camera_to_rl :: proc(camera: Orbit_Camera) -> rl.Camera3D {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Matrix3 :: # row_major matrix[3, 3]f32
|
||||||
|
|
||||||
|
free_camera_rotation :: proc(camera: Free_Camera) -> linalg.Matrix3f32 {
|
||||||
|
return(
|
||||||
|
linalg.matrix3_rotate_f32(camera.yaw, {0, 1, 0}) *
|
||||||
|
linalg.matrix3_rotate_f32(camera.pitch, {1, 0, 0}) \
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
free_camera_update :: proc(camera: ^Free_Camera) {
|
||||||
|
delta, sense := collect_camera_input()
|
||||||
|
|
||||||
|
camera.yaw -= delta.x * sense
|
||||||
|
camera.pitch -= delta.y * sense
|
||||||
|
camera.pitch = math.clamp(camera.pitch, -math.PI / 2.0 + 0.0001, math.PI / 2.0 - 0.0001)
|
||||||
|
|
||||||
|
input: rl.Vector2
|
||||||
|
|
||||||
|
if rl.IsKeyDown(.UP) || rl.IsKeyDown(.W) {
|
||||||
|
input.y += 1
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(.DOWN) || rl.IsKeyDown(.S) {
|
||||||
|
input.y -= 1
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(.LEFT) || rl.IsKeyDown(.A) {
|
||||||
|
input.x -= 1
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(.RIGHT) || rl.IsKeyDown(.D) {
|
||||||
|
input.x += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.speed += rl.GetMouseWheelMove() * 0.01
|
||||||
|
camera.speed = linalg.clamp(camera.speed, 0.01, 10)
|
||||||
|
|
||||||
|
rotation := free_camera_rotation(camera^)
|
||||||
|
forward := -rotation[2]
|
||||||
|
right := rotation[0]
|
||||||
|
|
||||||
|
input = linalg.normalize0(input)
|
||||||
|
camera.pos += (input.x * right + input.y * forward) * camera.speed
|
||||||
|
}
|
||||||
|
|
||||||
|
free_camera_to_rl :: proc(camera: ^Free_Camera) -> (result: rl.Camera3D) {
|
||||||
|
rotation := free_camera_rotation(camera^)
|
||||||
|
forward := -rotation[2]
|
||||||
|
|
||||||
|
result.position = camera.pos
|
||||||
|
result.target = camera.pos + forward
|
||||||
|
result.up = rl.Vector3{0, 1, 0}
|
||||||
|
result.fovy = 60
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
update :: proc() {
|
update :: proc() {
|
||||||
tracy.Zone()
|
tracy.Zone()
|
||||||
|
|
||||||
@ -666,7 +791,7 @@ update :: proc() {
|
|||||||
if rl.IsKeyPressed(.F1) {
|
if rl.IsKeyPressed(.F1) {
|
||||||
g_mem.free_cam = !g_mem.free_cam
|
g_mem.free_cam = !g_mem.free_cam
|
||||||
|
|
||||||
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 {
|
if rl.IsKeyPressed(.F2) && !g_mem.free_cam {
|
||||||
@ -721,7 +846,7 @@ update :: proc() {
|
|||||||
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 {
|
||||||
update_free_look_camera(get_editor_state())
|
free_camera_update(&g_mem.es.camera)
|
||||||
} else {
|
} else {
|
||||||
switch get_runtime_world().camera_mode {
|
switch get_runtime_world().camera_mode {
|
||||||
case .Orbit:
|
case .Orbit:
|
||||||
@ -1119,6 +1244,7 @@ game_init :: proc() {
|
|||||||
init_physifs_raylib_callbacks()
|
init_physifs_raylib_callbacks()
|
||||||
assets.assetman_init(&g_mem.assetman)
|
assets.assetman_init(&g_mem.assetman)
|
||||||
|
|
||||||
|
editor_state_init(&g_mem.es, 100)
|
||||||
runtime_world_init(&g_mem.runtime_world, 100)
|
runtime_world_init(&g_mem.runtime_world, 100)
|
||||||
|
|
||||||
g_mem.default_font = rl.GetFontDefault()
|
g_mem.default_font = rl.GetFontDefault()
|
||||||
@ -1135,7 +1261,7 @@ game_init :: proc() {
|
|||||||
@(export)
|
@(export)
|
||||||
game_shutdown :: proc() {
|
game_shutdown :: proc() {
|
||||||
assets.shutdown(&g_mem.assetman)
|
assets.shutdown(&g_mem.assetman)
|
||||||
destroy_world(&g_mem.es.world)
|
editor_state_destroy(&g_mem.es)
|
||||||
delete(g_mem.es.point_selection)
|
delete(g_mem.es.point_selection)
|
||||||
runtime_world_destroy(&g_mem.runtime_world)
|
runtime_world_destroy(&g_mem.runtime_world)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user