gutter_runner/game/editor.odin

154 lines
3.6 KiB
Odin

package game
import lg "core:math/linalg"
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_world(&es.world, dt, false)
update_free_look_camera(es)
switch es.track_edit_state {
case .Select:
{
if rl.IsKeyPressed(.F) {
add_track_spline_point()
}
if is_point_selected() {
if rl.IsKeyPressed(.X) {
if len(es.point_selection) <= 1 {
for i in es.point_selection {
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 = {}
// 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
}
}
// 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
}
}
}
}