79 lines
2.3 KiB
Odin
79 lines
2.3 KiB
Odin
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,
|
|
}
|
|
|
|
grid_get_zoom :: proc(zoom: v2) -> v2 {
|
|
return linalg.pow(v2(2.0), zoom)
|
|
}
|
|
|
|
grid_get_line_separation :: proc(zoom: v2, min_line_distance: f32) -> v2 {
|
|
zoom_factor := grid_get_zoom(zoom)
|
|
sep := linalg.pow(v2(10.0), linalg.floor(linalg.log10(min_line_distance * zoom_factor)))
|
|
for {
|
|
if sep.x / zoom_factor.x >= min_line_distance {
|
|
break
|
|
}
|
|
if sep.x * 2.5 / zoom_factor.x >= min_line_distance {
|
|
sep *= 2.5
|
|
break
|
|
}
|
|
if sep.x * 5.0 / zoom_factor.x >= min_line_distance {
|
|
sep *= 5.0
|
|
break
|
|
}
|
|
sep *= 10.0
|
|
}
|
|
return sep
|
|
}
|
|
|
|
grid_world_to_grid_matrix :: proc(zoom, offset: v2) -> mat3 {
|
|
zoom_amount := grid_get_zoom(zoom)
|
|
return (
|
|
mat3 {
|
|
1, 0, 0,
|
|
0, 1, 0,
|
|
offset.x, offset.y, 1,
|
|
} *
|
|
linalg.matrix3_scale(v3{**zoom_amount, 1.0}))
|
|
}
|
|
|
|
import "core:fmt"
|
|
|
|
draw_grid :: proc(grid: Grid, text_draw, text_clip: rect2) {
|
|
world_to_grid_matrix := grid_world_to_grid_matrix(grid.zoom, grid.offset)
|
|
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}
|
|
|
|
sep := grid_get_line_separation(grid.zoom, 32.0)
|
|
tl := (v3{**grid.world_position, 1.0} * world_to_grid_matrix).xy
|
|
tl = linalg.floor(tl / sep) * sep
|
|
br := (v3{**grid_world_br, 1.0} * world_to_grid_matrix).xy
|
|
|
|
for x: f32 = tl.x; x < br.x; x += sep.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 = tl.y; y < br.y; y += sep.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)
|
|
}
|
|
}
|
|
}
|