Many editor improvements
This commit is contained in:
parent
686d034b06
commit
aa0f945b0c
116
game/game.odin
116
game/game.odin
@ -15,6 +15,9 @@
|
||||
package game
|
||||
|
||||
import "assets"
|
||||
import "core:c"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:math"
|
||||
import "core:math/linalg"
|
||||
import rl "vendor:raylib"
|
||||
@ -62,6 +65,7 @@ Editor_State :: struct {
|
||||
point_selection: map[int]bool,
|
||||
track_edit_state: Track_Edit_State,
|
||||
move_axis: Move_Axis,
|
||||
total_movement_world: rl.Vector3,
|
||||
initial_point_pos: rl.Vector3,
|
||||
}
|
||||
|
||||
@ -218,17 +222,25 @@ update_editor :: proc() {
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
@ -297,6 +309,8 @@ update_editor :: proc() {
|
||||
for k in es.point_selection {
|
||||
get_world().track.points[k] += movement_world
|
||||
}
|
||||
|
||||
es.total_movement_world += movement_world
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,6 +394,12 @@ draw :: proc() {
|
||||
// road_uvs.allocator = context.temp_allocator
|
||||
// road_indices.allocator = context.temp_allocator
|
||||
|
||||
interpolated_points := calculate_spline_interpolated_points(
|
||||
points[:],
|
||||
context.temp_allocator,
|
||||
)
|
||||
|
||||
|
||||
{
|
||||
// Debug draw spline road
|
||||
{
|
||||
@ -388,11 +408,6 @@ draw :: proc() {
|
||||
|
||||
rlgl.Color3f(1, 0, 0)
|
||||
|
||||
interpolated_points := calculate_spline_interpolated_points(
|
||||
points[:],
|
||||
context.temp_allocator,
|
||||
)
|
||||
|
||||
debug_draw_spline(interpolated_points)
|
||||
debug_draw_spline_mesh(interpolated_points)
|
||||
}
|
||||
@ -432,6 +447,18 @@ draw :: proc() {
|
||||
|
||||
if g_mem.editor {
|
||||
rl.DrawText("Editor", 5, 5, 8, rl.ORANGE)
|
||||
|
||||
switch g_mem.es.track_edit_state {
|
||||
case .Select:
|
||||
case .Move:
|
||||
rl.DrawText(
|
||||
fmt.ctprintf("%v %v", g_mem.es.move_axis, g_mem.es.total_movement_world),
|
||||
5,
|
||||
16,
|
||||
8,
|
||||
rl.ORANGE,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,8 +468,67 @@ draw :: proc() {
|
||||
points := &get_world().track.points
|
||||
points_len := len(points)
|
||||
|
||||
if points_len > 0 {
|
||||
// Add point before first
|
||||
{
|
||||
tangent: rl.Vector3
|
||||
|
||||
if points_len > 1 {
|
||||
tangent = linalg.normalize0(points[1] - points[0])
|
||||
} else {
|
||||
tangent = rl.Vector3{-1, 0, 0}
|
||||
}
|
||||
|
||||
new_point_pos := points[0] - tangent * 4
|
||||
|
||||
if (spline_handle(
|
||||
new_point_pos,
|
||||
camera,
|
||||
false,
|
||||
rl.GuiIconName.ICON_TARGET_POINT,
|
||||
)) {
|
||||
inject_at(&get_world().track.points, 0, new_point_pos)
|
||||
log.debugf("add point before 0")
|
||||
}
|
||||
}
|
||||
|
||||
// Add point after last
|
||||
{
|
||||
tangent: rl.Vector3
|
||||
|
||||
if points_len > 1 {
|
||||
tangent = linalg.normalize0(points[points_len - 1] - points[points_len - 2])
|
||||
} else {
|
||||
tangent = rl.Vector3{-1, 0, 0}
|
||||
}
|
||||
|
||||
new_point_pos := points[points_len - 1] + tangent * 4
|
||||
|
||||
if (spline_handle(
|
||||
new_point_pos,
|
||||
camera,
|
||||
false,
|
||||
rl.GuiIconName.ICON_TARGET_POINT,
|
||||
)) {
|
||||
inject_at(&get_world().track.points, points_len - 1 + 1, new_point_pos)
|
||||
log.debugf("add point before 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selected_point := false
|
||||
for i in 0 ..< points_len {
|
||||
|
||||
if i < points_len - 1 {
|
||||
t := (f32(i) + 0.5) / f32(points_len)
|
||||
middle_pos := sample_spline(points[:], t)
|
||||
|
||||
if (spline_handle(middle_pos, camera, false, rl.GuiIconName.ICON_TARGET_POINT)) {
|
||||
inject_at(&get_world().track.points, i + 1, middle_pos)
|
||||
log.debugf("add point after %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
if spline_handle(get_world().track.points[i], camera, es.point_selection[i]) {
|
||||
if !rl.IsKeyDown(.LEFT_CONTROL) {
|
||||
clear(&g_mem.es.point_selection)
|
||||
@ -485,6 +571,8 @@ spline_handle :: proc(
|
||||
world_pos: rl.Vector3,
|
||||
camera: rl.Camera,
|
||||
selected: bool,
|
||||
icon := rl.GuiIconName.ICON_NONE,
|
||||
size := f32(20),
|
||||
) -> (
|
||||
clicked: bool,
|
||||
) {
|
||||
@ -492,18 +580,28 @@ spline_handle :: proc(
|
||||
return
|
||||
}
|
||||
pos := rl.GetWorldToScreen(world_pos, camera)
|
||||
size := rl.Vector2{10, 10}
|
||||
|
||||
min, max := pos - size, pos + size
|
||||
mouse_pos := rl.GetMousePosition()
|
||||
|
||||
is_hover :=
|
||||
mouse_pos.x >= min.x &&
|
||||
(mouse_pos.x >= min.x &&
|
||||
mouse_pos.y >= min.y &&
|
||||
mouse_pos.x <= max.x &&
|
||||
mouse_pos.y <= max.y
|
||||
mouse_pos.y <= max.y)
|
||||
|
||||
rl.DrawRectangleV(pos, size, selected ? rl.BLUE : (is_hover ? rl.ORANGE : rl.WHITE))
|
||||
|
||||
rl.DrawCircleV(pos, size / 2, selected ? rl.BLUE : (is_hover ? rl.ORANGE : rl.WHITE))
|
||||
if icon != .ICON_NONE {
|
||||
rl.GuiDrawIcon(
|
||||
icon,
|
||||
c.int(pos.x) - 7,
|
||||
c.int(pos.y) - 7,
|
||||
1,
|
||||
selected || is_hover ? rl.WHITE : rl.BLACK,
|
||||
)
|
||||
}
|
||||
// rl.DrawRectangleV(pos, size, selected ? rl.BLUE : (is_hover ? rl.ORANGE : rl.WHITE))
|
||||
|
||||
return rl.IsMouseButtonPressed(.LEFT) && is_hover
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package game
|
||||
|
||||
import "base:builtin"
|
||||
import "core:math"
|
||||
import lg "core:math/linalg"
|
||||
import rl "vendor:raylib"
|
||||
import "vendor:raylib/rlgl"
|
||||
@ -39,6 +41,39 @@ Interpolated_Point :: struct {
|
||||
normal: rl.Vector3,
|
||||
}
|
||||
|
||||
sample_spline :: proc(points: []rl.Vector3, t: f32) -> rl.Vector3 {
|
||||
points_len := len(points)
|
||||
if points_len >= 2 {
|
||||
t_mul_len := math.saturate(t) * f32(len(points))
|
||||
i := int(t_mul_len)
|
||||
frac_t := t_mul_len - f32(i)
|
||||
|
||||
extended_start := points[0] + (points[0] - points[1])
|
||||
extended_end := points[points_len - 1] + points[points_len - 1] - points[points_len - 2]
|
||||
extended_end2 := extended_end + points[points_len - 1] - points[points_len - 2]
|
||||
|
||||
prev := i > 0 ? points[i - 1] : extended_start
|
||||
current := points[i]
|
||||
next := i < points_len - 1 ? points[i + 1] : extended_end
|
||||
next2 := i < points_len - 2 ? points[i + 2] : extended_end2
|
||||
|
||||
a, b, c, d := catmull_rom_coefs(
|
||||
prev,
|
||||
current,
|
||||
next,
|
||||
next2,
|
||||
CATMULL_ROM_ALPHA,
|
||||
CATMULL_ROM_TENSION,
|
||||
)
|
||||
|
||||
return catmull_rom(a, b, c, d, frac_t)
|
||||
} else if len(points) == 1 {
|
||||
return points[0]
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
calculate_spline_interpolated_points :: proc(
|
||||
points: []rl.Vector3,
|
||||
allocator := context.allocator,
|
||||
@ -47,7 +82,6 @@ calculate_spline_interpolated_points :: proc(
|
||||
|
||||
ctrl_rotations := calculate_spline_ctrl_rotations(points, context.temp_allocator)
|
||||
|
||||
|
||||
if points_len >= 2 {
|
||||
interpolated_points := make(
|
||||
[]Interpolated_Point,
|
||||
|
Loading…
x
Reference in New Issue
Block a user