package game import "core:fmt" import lg "core:math/linalg" import "game:physics/collision" import "game:ui" import rl "libs:raylib" update_editor :: proc(es: ^Editor_State, dt: f32) { free_camera_update(&es.camera) did_undo_redo := false if rl.IsKeyPressed(.Z) && rl.IsKeyDown(.LEFT_CONTROL) { world_stack_pop(&es.world_stack) did_undo_redo = true } if !did_undo_redo { switch es.track_edit_state { case .Select: { if rl.IsKeyPressed(.F) { world_stack_push(&es.world_stack) 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) } } 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) { track := &world_stack_current(&es.world_stack).track selected_count := 0 es.move_initial_pos = 0 for k in es.point_selection { es.move_initial_pos += track.points[k] selected_count += 1 } if selected_count > 0 { es.move_initial_pos /= f32(selected_count) es.track_edit_state = .Move es.move_axis = .None es.total_movement_world = {} world_stack_push(&es.world_stack) } } } } 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_pos := rl.GetMousePosition() prev_mouse_pos := es.prev_mouse_pos prev_ray := rl.GetScreenToWorldRay(prev_mouse_pos, camera) ray := rl.GetScreenToWorldRay(mouse_pos, camera) 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 if len(axes) == 2 { normal := lg.normalize0(lg.cross(axes[0], axes[1])) plane := collision.plane_from_point_normal(es.move_initial_pos, normal) _, pos1 := collision.intersect_ray_plane( prev_ray.position, prev_ray.direction, plane, ) _, pos2 := collision.intersect_ray_plane( ray.position, ray.direction, plane, ) world_delta := pos2 - pos1 world_delta -= lg.dot(world_delta, plane.normal) * plane.normal movement_world += world_delta } else if len(axes) == 1 { for axis in axes { tangent := lg.cross(es.move_initial_pos - camera.position, axis) normal := lg.normalize0(lg.cross(axis, tangent)) plane := collision.plane_from_point_normal(es.move_initial_pos, normal) _, pos1 := collision.intersect_ray_plane( prev_ray.position, prev_ray.direction, plane, ) _, pos2 := collision.intersect_ray_plane( ray.position, ray.direction, plane, ) world_delta := pos2 - pos1 movement_world += lg.dot(axis, world_delta) * axis } } for k in es.point_selection { get_world().track.points[k] += movement_world } es.total_movement_world += movement_world } } } } es.prev_mouse_pos = rl.GetMousePosition() ui_ctx := &g_mem.ui_context if ui.window(ui_ctx, "Editor", ui.Rect{x = 500, y = 0, w = 500, h = 600}) { cnt := ui.get_current_container(ui_ctx) cnt.rect.w = max(cnt.rect.w, 500) cnt.rect.h = max(cnt.rect.h, 600) if .ACTIVE in ui.header(ui_ctx, "Details", {.EXPANDED}) { ui.layout_row(ui_ctx, {100, -1}) ui.label(ui_ctx, "mov") ui.label(ui_ctx, fmt.tprintf("%v", es.move_initial_pos)) } } world := world_stack_current(&es.world_stack) config := World_Update_Config { commit_physics = false, } update_world(world, dt, config) }