185 lines
4.6 KiB
Odin
185 lines
4.6 KiB
Odin
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)
|
|
}
|