fixed matrix math order

This commit is contained in:
Synthasmagoria 2026-08-30 00:24:02 +02:00
commit 9b550856fb
5 changed files with 125 additions and 60 deletions

View file

@ -22,12 +22,12 @@ rectangle_corners_from_rect :: proc "contextless" (rect: rect2) -> RectangleCorn
}
}
rectangle_corners_transform_mat3 :: proc "contextless" (corners: RectangleCorners, transform: mat3) -> RectangleCorners {
rectangle_corners_transform_mat3 :: proc "contextless" (transform: mat3, corners: RectangleCorners) -> RectangleCorners {
return {
(v3{**corners.tl, 1.0} * transform).xy,
(v3{**corners.tr, 1.0} * transform).xy,
(v3{**corners.br, 1.0} * transform).xy,
(v3{**corners.bl, 1.0} * transform).xy,
matrix3_transform_v2(transform, corners.tl),
matrix3_transform_v2(transform, corners.tr),
matrix3_transform_v2(transform, corners.br),
matrix3_transform_v2(transform, corners.bl),
}
}
@ -35,8 +35,8 @@ rectangle_corners_lerp :: proc "contextless" (a, b: RectangleCorners, t: f32) ->
return {
linalg.lerp(a.tl, b.tl, t),
linalg.lerp(a.tr, b.tr, t),
linalg.lerp(a.bl, b.bl, t),
linalg.lerp(a.br, b.br, t),
linalg.lerp(a.bl, b.bl, t),
}
}
@ -101,9 +101,12 @@ rectangle_corners_transform_mat2 :: proc "contextless" (corners: RectangleCorner
}
draw_animation_rectangle_corners :: proc(corners: RectangleCorners, color: rl.Color) {
rect := rect_from_corners(corners.tl, corners.tr, corners.br, corners.bl)
rl.DrawRectangleRec(rect, {**color.rgb, color.a >> 1})
rl.DrawRectangleLinesEx(rect, 2, color)
rl.DrawTriangle(corners.tl, corners.bl, corners.br, {**color.rgb, color.a >> 1})
rl.DrawTriangle(corners.br, corners.tr, corners.tl, {**color.rgb, color.a >> 1})
rl.DrawLineV(corners.tl, corners.tr, color)
rl.DrawLineV(corners.tr, corners.br, color)
rl.DrawLineV(corners.br, corners.bl, color)
rl.DrawLineV(corners.bl, corners.tl, color)
}
/*
@ -160,34 +163,88 @@ animation_get_eased_progress :: proc(animation: Animation) -> f32 {
return math.floor(animation.matrix_index) + ease.ease(animation.ease, fract(animation.matrix_index))
}
rectangle_corners_draw :: proc(corners: RectangleCorners, color: rl.Color) {
rl.DrawLineV(corners.tl, corners.tr, rl.RED)
rl.DrawLineV(corners.tr, corners.br, rl.YELLOW)
rl.DrawLineV(corners.br, corners.bl, rl.GREEN)
rl.DrawLineV(corners.bl, corners.tl, rl.BLUE)
}
animation_draw :: proc(animation: Animation, global_transform: mat3) {
switch animation.type {
case .Rectangle:
shape := animation.shapes.rectangle
draw_animation_rectangle_corners(rectangle_corners_transform_mat3(global_transform, shape), ANIMATION_COLOR_ORIGIN)
transform := linalg.identity(mat3)
color_origin := cast([4]f32)(ANIMATION_COLOR_ORIGIN)
color_end := cast([4]f32)(ANIMATION_COLOR_END)
draw_animation_rectangle_corners(rectangle_corners_transform_mat3(shape, global_transform), ANIMATION_COLOR_ORIGIN)
matrices := slice.reinterpret([]mat3, animation.matrices)
for i in 0..<animation.matrix_count {
animation_progress := f32(i + 1) / f32(animation.matrix_count)
previous := rectangle_corners_transform_mat3(shape, transform)
transform *= matrices[i]
next := rectangle_corners_transform_mat3(shape, transform)
color_next := linalg.lerp(color_origin, color_end, animation_progress)
draw_animation_rectangle_corners(rectangle_corners_transform_mat3(next, global_transform), cast(rl.Color)color_next)
if f32(i) == math.floor(animation.matrix_index) {
progress := ease.ease(animation.ease, fract(animation.matrix_index))
color_previous := linalg.lerp(color_origin, color_end, animation.matrix_index / f32(animation.matrix_count))
color := linalg.lerp(color_previous, color_next, progress)
animated_corners := rectangle_corners_lerp(previous, next, progress)
animated_corners_world := rectangle_corners_transform_mat3(animated_corners, global_transform)
draw_animation_rectangle_corners(animated_corners_world, cast(rl.Color)color)
}
matrices := slice.reinterpret([]mat3, animation.matrices[:animation.matrix_count * 9])
for mat in matrices {
transform *= mat
shape_next := rectangle_corners_transform_mat3(transform, shape)
shape_next_world := rectangle_corners_transform_mat3(global_transform, shape_next)
draw_animation_rectangle_corners(shape_next_world, ANIMATION_COLOR_ORIGIN)
}
// shape := animation.shapes.rectangle
// transform := linalg.identity(mat3)
// color_origin := cast([4]f32)(ANIMATION_COLOR_ORIGIN)
// color_end := cast([4]f32)(ANIMATION_COLOR_END)
// draw_animation_rectangle_corners(rectangle_corners_transform_mat3(shape, global_transform), ANIMATION_COLOR_ORIGIN)
// matrices := slice.reinterpret([]mat3, animation.matrices)
// for i in 0..<animation.matrix_count {
// animation_progress := f32(i + 1) / f32(animation.matrix_count)
// previous := rectangle_corners_transform_mat3(shape, transform)
// transform *= matrices[i]
// next := rectangle_corners_transform_mat3(shape, transform)
// color_next := linalg.lerp(color_origin, color_end, animation_progress)
// draw_animation_rectangle_corners(rectangle_corners_transform_mat3(next, global_transform), cast(rl.Color)color_next)
// if f32(i) == math.floor(animation.matrix_index) {
// progress := ease.ease(animation.ease, fract(animation.matrix_index))
// color_previous := linalg.lerp(color_origin, color_end, animation.matrix_index / f32(animation.matrix_count))
// color := linalg.lerp(color_previous, color_next, progress)
// animated_corners := rectangle_corners_lerp(previous, next, progress)
// animated_corners_world := rectangle_corners_transform_mat3(animated_corners, global_transform)
// draw_animation_rectangle_corners(animated_corners_world, cast(rl.Color)color)
// }
}
}
}
animation_get_center :: proc(animation: Animation) -> v2 {

View file

@ -35,13 +35,7 @@ grid_get_line_separation :: proc(zoom: v2, min_line_distance: v2) -> v2 {
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}))
return matrix3_translate2(offset) * linalg.matrix3_scale(v3{**zoom_amount, 1.0})
}
draw_grid :: proc(grid: Grid, area, text_draw, text_clip: rect2) {
@ -53,9 +47,9 @@ draw_grid :: proc(grid: Grid, area, text_draw, text_clip: rect2) {
grid_color := rl.Color{64, 64, 64, 255}
sep := grid_get_line_separation(grid.zoom, grid.cell_size_px)
tl := (v3{**position, 1.0} * world_to_grid_matrix).xy
tl := matrix3_transform_v2(world_to_grid_matrix, position)
tl = linalg.floor(tl / sep) * sep
br := (v3{**grid_world_br, 1.0} * world_to_grid_matrix).xy
br := matrix3_transform_v2(world_to_grid_matrix, grid_world_br)
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

View file

@ -545,10 +545,10 @@ program_update :: proc() {
for draggable in program.mouse_draggables {
switch draggable in draggable {
case MouseDraggable_Point:
position_world := (v3{**draggable.ref^, 1.0} * grid_to_world_matrix).xy
position_world := matrix3_transform_v2(grid_to_world_matrix, draggable.ref^)
rl.DrawCircleV(position_world, program.mouse_draggable_radius, ANIMATION_COLOR_ORIGIN)
case MouseDraggable_RectangleCornerData:
position_world := (v3{**draggable.corner_ref^, 1.0} * grid_to_world_matrix).xy
position_world := matrix3_transform_v2(grid_to_world_matrix, draggable.corner_ref^)
rl.DrawCircleV(position_world, program.mouse_draggable_radius, ANIMATION_COLOR_ORIGIN)
case MouseDraggable_RectangleData:
}
@ -608,17 +608,31 @@ program_add_rotation_matrix :: proc(angle: f32) {
case .Degrees: radians = linalg.RAD_PER_DEG * angle
case .Radians: radians = angle
}
rotmat := linalg.matrix2_rotate_f32(angle)
fmt.bprint(value_strings[0][:], rotmat[0, 0])
values[0] = rotmat[0, 0]
fmt.bprint(value_strings[1][:], rotmat[0, 1])
values[1] = rotmat[0, 1]
fmt.bprint(value_strings[3][:], rotmat[1, 0])
values[3] = rotmat[1, 0]
fmt.bprint(value_strings[4][:], rotmat[1, 1])
values[4] = rotmat[1, 1]
a := linalg.cos(radians)
b := linalg.sin(radians)
fmt.bprint(value_strings[0][:], 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)
values[4] = a
fmt.bprint(value_strings[8][:], 1)
values[8] = 1.0
// rotmat := linalg.matrix2_rotate_f32(angle)
// fmt.bprint(value_strings[0][:], rotmat[0, 0])
// values[0] = rotmat[0, 0]
// fmt.bprint(value_strings[1][:], rotmat[0, 1])
// values[1] = rotmat[0, 1]
// fmt.bprint(value_strings[1][:], rotmat[1, 0])
// values[3] = rotmat[1, 0]
// fmt.bprint(value_strings[4][:], rotmat[1, 1])
// values[4] = rotmat[1, 1]
// fmt.bprint(value_strings[8][:], 1)
// values[8] = 1.0
}
program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType) -> []ui.Element {
@ -847,21 +861,21 @@ 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 := (v3{**draggable.ref^, 1.0} * grid_to_world_matrix).xy
circle_position := matrix3_transform_v2(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 := (v3{**draggable.corner_ref^, 1.0} * grid_to_world_matrix).xy
circle_position := matrix3_transform_v2(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
break state_label
}
case MouseDraggable_RectangleData:
corners_world := rectangle_corners_transform_mat3(draggable.corners^, grid_to_world_matrix)
corners_world := rectangle_corners_transform_mat3(grid_to_world_matrix, draggable.corners^)
rect := rect_from(corners_world.tl, corners_world.tr, corners_world.br, corners_world.bl)
if rect_has_point(rect, mouse) {
program.mouse_current_draggable = draggable
@ -884,9 +898,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^ = (v3{**mouse, 1.0} * world_to_grid_matrix).xy
draggable.ref^ = matrix3_transform_v2(world_to_grid_matrix, mouse)
case MouseDraggable_RectangleCornerData:
position := (v3{**mouse, 1.0} * world_to_grid_matrix).xy
position := matrix3_transform_v2(world_to_grid_matrix, mouse)
corners := rectangle_corners_move_corner(draggable.corners_ref^, position, draggable.corner)
draggable.corners_ref^ = corners
case MouseDraggable_RectangleData:

View file

@ -289,13 +289,13 @@ rect_get_size :: proc {rect2_get_size, irect2_get_size}
/// ## LINEAR ALGEBRA ## ///
matrix3_translate2 :: proc "contextless" (translation: v2) -> mat3 {
return {
1.0, 0.0, translation.x,
0.0, 1.0, translation.y,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
translation.x, translation.y, 1.0,
}
}
matrix3_transform_v2 :: proc(m: mat3, v: v2) -> v2 {
matrix3_transform_v2 :: proc "contextless" (m: mat3, v: v2) -> v2 {
return (m * v3{**v, 1.0}).xy
}