diff --git a/grid.odin b/grid.odin new file mode 100644 index 0000000..4da4174 --- /dev/null +++ b/grid.odin @@ -0,0 +1,48 @@ +package main + +import "core:math/linalg" +import rl "libraries/raylib" + +Grid :: struct { + cell_size: v2, + zoom_previous, zoom: v2, + world_position, world_size, offset: v2, +} + +draw_grid :: proc(grid: Grid, text_draw, text_clip: rect2) { + zoom_amount := grid_get_zoom_amount(grid.zoom) + world_to_grid_matrix := ( + mat3 { + 1, 0, 0, + 0, 1, 0, + grid.offset.x, grid.offset.y, 1, + } * + linalg.matrix3_scale(v3{**zoom_amount, 1.0})) + grid_to_world_matrix := linalg.inverse(world_to_grid_matrix) + grid_world_br := grid.world_position + grid.world_size + grid_color := rl.Color{64, 64, 64, 255} + + grid_tl := (v3{**grid.world_position, 1.0} * world_to_grid_matrix).xy + grid_tl = linalg.floor(grid_tl / grid.cell_size) * grid.cell_size + grid_br := (v3{**grid_world_br, 1.0} * world_to_grid_matrix).xy + + for x: f32 = grid_tl.x; x < grid_br.x; x += grid.cell_size.x { + world_position_x := (v3{x, 0.0, 1.0} * grid_to_world_matrix).x + p1 := v2{world_position_x, grid.world_position.y} + p2 := v2{world_position_x, grid_world_br.y} + rl.DrawLineV(p1, p2, grid_color) + if p1.x >= text_clip.x && p1.x < text_clip.x + text_clip.width { + draw_float_aligned(x, {world_position_x, text_draw.y}, program.font_style, .Middle, .Top, rl.GRAY) + } + } + + for y: f32 = grid_tl.y; y < grid_br.y; y += grid.cell_size.y { + world_position_y := (v3{0.0, y, 1.0} * grid_to_world_matrix).y + p1 := v2{grid.world_position.x, world_position_y} + p2 := v2{grid_world_br.x, world_position_y} + rl.DrawLineV(p1, p2, grid_color) + if p1.y >= text_clip.y && p1.y < text_clip.y + text_clip.height { + draw_float_aligned(y, {text_draw.x, world_position_y}, program.font_style, .Left, .Center, rl.GRAY) + } + } +} diff --git a/program.odin b/program.odin index c0d27ad..0b52ab2 100644 --- a/program.odin +++ b/program.odin @@ -218,12 +218,6 @@ AnimationState :: enum { Finished, } -Grid :: struct { - cell_size: v2, - zoom_previous, zoom: v2, - world_position, world_size, offset: v2, -} - float_slice_get_mat3 :: proc(floats: []f32, index: int) -> ^mat3 { return cast(^mat3)(&floats[index * 9]) } @@ -278,7 +272,7 @@ program_init :: proc(allocator := context.allocator) { program.font_style = { font = rl.GetFontDefault(), size = 16.0, - spacing = 1.0 + spacing = 2.0 } program.grid = { cell_size = 32.0, @@ -415,33 +409,10 @@ program_update :: proc() { } } - grid := program.grid - zoom_amount := grid_get_zoom_amount(grid.zoom) - world_to_grid_matrix := ( - mat3 { - 1, 0, 0, - 0, 1, 0, - grid.offset.x, grid.offset.y, 1, - } * - linalg.matrix3_scale(v3{**zoom_amount, 1.0})) - grid_to_world_matrix := linalg.inverse(world_to_grid_matrix) - grid_world_br := grid.world_position + grid.world_size - - grid_tl := (v3{**grid.world_position, 1.0} * world_to_grid_matrix).xy - grid_tl = linalg.floor(grid_tl / grid.cell_size) * grid.cell_size - grid_br := (v3{**grid_world_br, 1.0} * world_to_grid_matrix).xy - for x: f32 = grid_tl.x; x < grid_br.x; x += grid.cell_size.x { - world_position := (v3{x, 0.0, 1.0} * grid_to_world_matrix).x - p1 := v2{world_position, grid.world_position.y} - p2 := v2{world_position, grid_world_br.y} - rl.DrawLineV(p1, p2, {255, 255, 255, 128}) - } - for y: f32 = grid_tl.y; y < grid_br.y; y += grid.cell_size.y { - world_position := (v3{0.0, y, 1.0} * grid_to_world_matrix).y - p1 := v2{grid.world_position.x, world_position} - p2 := v2{grid_world_br.x, world_position} - rl.DrawLineV(p1, p2, {255, 255, 255, 128}) - } + top_bar_container_br := rect_get_br(rect2(top_bar_container.area)) + matrix_container_br := rect_get_br(rect2(matrix_container.area)) + grid_text_clip := rect_from_area(v2{matrix_container_br.x, top_bar_container_br.y}, v2{WINDOW_WIDTH, WINDOW_HEIGHT}) + draw_grid(program.grid, rect_grow(grid_text_clip, -4.0), rect_grow(grid_text_clip, -32.0)) if program.animation_state == .Playing { program.animation_matrix_progress += program.animation_speed * delta_time_fraction() diff --git a/utils.odin b/utils.odin index 5496a5f..5ca9c4f 100644 --- a/utils.odin +++ b/utils.odin @@ -30,16 +30,6 @@ draw_text :: proc(text: cstring, position: v2, style: FontStyle, color: rl.Color rl.DrawTextEx(style.font, text, position, style.size, style.spacing, color) } -draw_grid :: proc(area: rect2, line_interval: v2, color: rl.Color) { - br := rect_get_br(area) - for x := area.x; x < br.x; x += line_interval.x { - rl.DrawLineV({x, area.y}, {x, br.y}, color) - } - for y := area.y; y < br.y; y += line_interval.y { - rl.DrawLineV({area.x, y}, {br.x, y}, color) - } -} - TextHalign :: enum { Left, Middle, @@ -68,6 +58,19 @@ draw_text_aligned :: proc(text: cstring, position: v2, style: FontStyle, halign: draw_text(text, position, style, color) } +draw_float_aligned :: proc(value: f32, position: v2, style: FontStyle, halign: TextHalign, valign: TextValign, color: rl.Color) { + fractional := fract(value) + text: cstring + if fractional == 0.0 { + text = fmt.ctprintf("%.0f", value) + } else if fractional * 10.0 > 1.0 { + text = fmt.ctprintf("%.1f", value) + } else { + text = fmt.ctprintf("%.2f", value) + } + draw_text_aligned(text, position, style, halign, valign, color) +} + /// ### MATH ### /// fract :: proc(val: f32) -> f32 { return val - math.trunc(val)