Grid matrix math fix

This commit is contained in:
Synthasmagoria 2026-08-30 14:01:17 +02:00
commit c0d84bae43
4 changed files with 80 additions and 34 deletions

View file

@ -1,5 +1,32 @@
package main
/*
Rules of matrices:
1) Order matters when multiplying with vectors
- m * v = Column vector x matrix
- v * m = Row vector x matrix
2) Odin matrices are column-major for math efficiency
fmt.println(matrix[3, 3]f32 {
a, -b, 0,
b, a, 0,
0, 0, 1,
})
>> [0.8660254, 0.5, 0, -0.5, 0.8660254, 0, 0, 0, 1]
Additionally this means that the first index of a matrix is the column.
mat[<column>, <row>].
If you had an array of 9 floats ([9]f32) and you accessed the first one
It'd be the same as accessing the first colmun of a matrix.
array[1] = mat[1, 0]
3) Matrix multiplication order matters
// scale first then translate
transformation_a := translation * scale
// translate first then scale
transformation_b := scale * translation
*/
import rl "libraries/raylib"
import ui "libraries/snths_ui"
import "core:mem"
@ -275,8 +302,10 @@ matrix_pool_get_mat3 :: proc() -> (value_strings: []InputFloatField, values: []f
assert(program.matrix_count + 1 < matrix_pool_max(), "Max matrix count exceeded")
value_strings = program.matrix_value_string_pool[program.matrix_count * 9 : program.matrix_count * 9 + 9]
values = program.matrix_float_pool[program.matrix_count * 9 : program.matrix_count * 9 + 9]
for &str in value_strings {
str[0] = '0'
for i in 0..<len(value_strings) {
mem.set(raw_data(&value_strings[i]), 0, len(InputFloatField))
value_strings[i][0] = '0'
values[i] = 0.0
}
program.matrix_count += 1
return value_strings, values
@ -508,7 +537,7 @@ program_update :: proc() {
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}, program_screen_size())
grid_area := rect2{0.0, 0.0, **program_screen_size()}
draw_grid(program.grid, grid_area, rect_grow(grid_text_clip, -4.0), rect_grow(grid_text_clip, -32.0))
draw_grid(program.grid, grid_area, rect_grow(grid_text_clip, -4.0), rect_grow(grid_text_clip, -32.0), {255, 255, 255, 64})
{
animation := &program.animation
@ -545,10 +574,10 @@ program_update :: proc() {
for draggable in program.mouse_draggables {
switch draggable in draggable {
case MouseDraggable_Point:
position_world := matrix3_transform_v2(grid_to_world_matrix, draggable.ref^)
position_world := matrix3_transform_xy(grid_to_world_matrix, draggable.ref^)
rl.DrawCircleV(position_world, program.mouse_draggable_radius, ANIMATION_COLOR_ORIGIN)
case MouseDraggable_RectangleCornerData:
position_world := matrix3_transform_v2(grid_to_world_matrix, draggable.corner_ref^)
position_world := matrix3_transform_xy(grid_to_world_matrix, draggable.corner_ref^)
rl.DrawCircleV(position_world, program.mouse_draggable_radius, ANIMATION_COLOR_ORIGIN)
case MouseDraggable_RectangleData:
}
@ -611,15 +640,15 @@ program_add_rotation_matrix :: proc(angle: f32) {
a := linalg.cos(radians)
b := linalg.sin(radians)
fmt.bprint(value_strings[0][:], a)
fmt.bprintf(value_strings[0][:], "%.3f", a)
values[0] = a
fmt.bprint(value_strings[1][:], -b)
values[1] = b
fmt.bprint(value_strings[3][:], b)
values[3] = a
fmt.bprint(value_strings[4][:], a)
fmt.bprintf(value_strings[1][:], "%.3f", -b)
values[1] = -b
fmt.bprintf(value_strings[3][:], "%.3f", b)
values[3] = b
fmt.bprintf(value_strings[4][:], "%.3f", a)
values[4] = a
fmt.bprint(value_strings[8][:], 1)
fmt.bprint(value_strings[8][:], f32(1.0))
values[8] = 1.0
// rotmat := linalg.matrix2_rotate_f32(angle)
@ -861,14 +890,14 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_
for draggable in program.mouse_draggables {
switch draggable in draggable {
case MouseDraggable_Point:
circle_position := matrix3_transform_v2(grid_to_world_matrix, draggable.ref^)
circle_position := matrix3_transform_xy(grid_to_world_matrix, draggable.ref^)
if linalg.distance(mouse, circle_position) <= program.mouse_draggable_radius {
program.mouse_current_draggable = draggable
mouse_state = .DraggingDraggable
break state_label
}
case MouseDraggable_RectangleCornerData:
circle_position := matrix3_transform_v2(grid_to_world_matrix, draggable.corner_ref^)
circle_position := matrix3_transform_xy(grid_to_world_matrix, draggable.corner_ref^)
if linalg.distance(mouse, circle_position) <= program.mouse_draggable_radius {
program.mouse_current_draggable = draggable
mouse_state = .DraggingDraggable
@ -898,9 +927,9 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_
draggable := program.mouse_current_draggable
switch draggable in draggable {
case MouseDraggable_Point:
draggable.ref^ = matrix3_transform_v2(world_to_grid_matrix, mouse)
draggable.ref^ = matrix3_transform_xy(world_to_grid_matrix, mouse)
case MouseDraggable_RectangleCornerData:
position := matrix3_transform_v2(world_to_grid_matrix, mouse)
position := matrix3_transform_xy(world_to_grid_matrix, mouse)
corners := rectangle_corners_move_corner(draggable.corners_ref^, position, draggable.corner)
draggable.corners_ref^ = corners
case MouseDraggable_RectangleData:
@ -908,7 +937,7 @@ program_handle_mouse :: proc(mouse_state: MouseState, top_bar_container, matrix_
draggable.corners^ = rectangle_corners_add(draggable.corners^, mouse_delta_grid)
}
case .DraggingGrid:
program.grid.offset -= rl.GetMouseDelta()
program.grid.offset -= rl.GetMouseDelta() * grid_get_zoom(program.grid.zoom)
if !rl.IsMouseButtonDown(.LEFT) {
mouse_state = .Hover
break state_label