From eac5104bbe357ba774a70719547b910ee802a780 Mon Sep 17 00:00:00 2001 From: Synthasmagoria Date: Sun, 30 Aug 2026 20:05:22 +0200 Subject: [PATCH] Skew matrix --- TODO.MD | 2 -- default | Bin 202 -> 238 bytes src/animation.odin | 12 +++--------- src/grid.odin | 8 +++++++- src/program.odin | 47 +++++++++++++++++++++++++++++++++++---------- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/TODO.MD b/TODO.MD index 29d1fa2..797fef5 100644 --- a/TODO.MD +++ b/TODO.MD @@ -1,5 +1,3 @@ -- Save grid and animation data to file -- Rotation matrix math is mathing wrong - Centered justification in UI - Make web build - Center line diff --git a/default b/default index 6dacf6be6ba7e419920c7ef042a98834d94f701b..ac30279b5e44d88b74adfc9a631c7910865f4470 100755 GIT binary patch delta 108 zcmX@b_>OUc5+ln*WnU(S{S%9nq8j!yFfiByF%UEWX%I#RAijqa2%kCQV+X?j^n8z; f-}dlu!bY>h@9xMRUUh!|As8L?uIUg+97F>EXAmf$ delta 72 zcmaFIc#3g?5+n0OW#5TQ1SU3!n0YucFn}<_eh^k&ef{vYc@2mEKj}Gi>)3@u8CHsL NI>dO&A&@wT1^^3UAx{7R diff --git a/src/animation.odin b/src/animation.odin index bb001b3..998ab02 100644 --- a/src/animation.odin +++ b/src/animation.odin @@ -200,13 +200,6 @@ 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, temp_allocator := context.temp_allocator) { color_origin := cast([4]f32)ANIMATION_COLOR_ORIGIN color_end := cast([4]f32)ANIMATION_COLOR_END @@ -231,8 +224,9 @@ animation_draw :: proc(animation: Animation, global_transform: mat3, temp_alloca } animation_progress := math.clamp(animation.matrix_index, 0.0, f32(animation.matrix_count)) animation_progress_frame := ease.ease(animation.ease, fract(animation.matrix_index)) - animation_progress_total := animation_progress + animation_progress_frame - animation_progress_fraction := animation_progress_total / f32(animation.matrix_count) + animation_progress_total := math.floor(animation_progress) + animation_progress_frame + // TODO (synthas): math.min is a temp fix because I lost track of the math and got lazy with it + animation_progress_fraction := math.min(animation_progress_total / f32(animation.matrix_count), 1.0) rectangle_previous := rectangles[int(animation_progress)] rectangle_next := rectangles[min(int(animation_progress + 1), animation.matrix_count)] rectangle_current := rectangle_corners_lerp(rectangle_previous, rectangle_next, animation_progress_frame) diff --git a/src/grid.odin b/src/grid.odin index 3e118ed..a0a1aaa 100644 --- a/src/grid.odin +++ b/src/grid.odin @@ -47,7 +47,7 @@ grid_zoom_in_on :: proc(grid: ^Grid, world_area: rect2, position: v2, amount: f3 program.grid.offset -= (current - previous) * mouse_screen_fraction } -draw_grid :: proc(grid: Grid, area, text_draw, text_clip: rect2, color: rl.Color) { +draw_grid :: proc(grid: Grid, area, text_draw, text_clip: rect2, color: rl.Color, origin_color: rl.Color) { world_to_grid_matrix := grid_world_to_grid_matrix(grid.zoom, grid.offset) grid_to_world_matrix := linalg.inverse(world_to_grid_matrix) position := rect_get_tl(area) @@ -78,4 +78,10 @@ draw_grid :: proc(grid: Grid, area, text_draw, text_clip: rect2, color: rl.Color draw_float_aligned(y, {text_draw.x, world_position_y}, program.font_style, .Left, .Center, rl.GRAY) } } + + if rect_has_point(rect_from_area(tl, br), v2(0)) { + origin := matrix3_transform_xy(grid_to_world_matrix, v2(0)) + rl.DrawLineV({area.x, origin.y}, {area.x + area.width, origin.y}, origin_color) + rl.DrawLineV({origin.x, area.y}, {origin.x, area.y + area.height}, origin_color) + } } diff --git a/src/program.odin b/src/program.odin index 0d93a9c..e6676b2 100644 --- a/src/program.odin +++ b/src/program.odin @@ -42,7 +42,8 @@ RAYGUI_ICON_LOAD :: "#006#" RAYGUI_ICON_IDENTITY_MATRIX :: "#000#" RAYGUI_ICON_TRANSLATION_MATRIX :: "#068#" RAYGUI_ICON_SCALE_MATRIX :: "#070#" -RAYGUI_ICON_ROTATION_MATRIX :: "#078#" +RAYGUI_ICON_ROTATION_MATRIX :: "#211#" +RAYGUI_ICON_SKEW_MATRIX :: "#192#" RAYGUI_ICON_PLAY :: "#131#" RAYGUI_ICON_PAUSE :: "#132#" RAYGUI_ICON_RESET :: "#211#" @@ -103,9 +104,11 @@ UiButtonType :: enum { AddTranslation, AddScale, AddRotation, + AddSkewMatrix, AddTranslationMatrixConfirm, AddScaleMatrixConfirm, AddRotationMatrixConfirm, + AddSkewMatrixConfirm, ExitDialog, StartTransformation, PauseTransformation, @@ -185,6 +188,7 @@ ProgramDialogType :: enum { CreateTranslationMatrix, CreateScaleMatrix, CreateRotationMatrix, + CreateSkewMatrix, SaveProject, LoadProject, Error, @@ -194,6 +198,7 @@ ProgramDialogType :: enum { .CreateTranslationMatrix = "Create tranlation matrix", .CreateScaleMatrix = "Create scale matrix", .CreateRotationMatrix = "Create rotation matrix", + .CreateSkewMatrix = "Create skew matrix", .SaveProject = "Save project", .LoadProject = "Load project", .Error = "Error", @@ -517,6 +522,7 @@ program_update :: proc() { case .CreateTranslationMatrix: program_add_translation_matrix(vals[0], vals[1], vals[2]) case .CreateScaleMatrix: program_add_scalar_matrix(vals[0], vals[1], vals[2]) case .CreateRotationMatrix: program_add_rotation_matrix(vals[0]) + case .CreateSkewMatrix: program_add_skew_matrix(vals[0], vals[1]) case .SaveProject: path := strings.string_from_null_terminated_ptr(&program.dialog_data.input_text_buffers[0][0], DIALOG_STATE_TEXT_INPUT_FIELD_SIZE) if err := program_save_project(&program, path); err != nil { @@ -548,7 +554,9 @@ 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), {255, 255, 255, 64}) + grid_color := rl.Color{255, 255, 255, 64} + grid_origin_color := rl.Color{255, 255, 255, 128} + draw_grid(program.grid, grid_area, rect_grow(grid_text_clip, -4.0), rect_grow(grid_text_clip, -32.0), grid_color, grid_origin_color) { animation := &program.animation @@ -636,6 +644,16 @@ program_add_rotation_matrix :: proc(angle: f32) { write_matrix_to_values_and_value_strings(values, value_strings, matrix3_rotate2(radians)) } +program_add_skew_matrix :: proc(x, y: f32) { + value_strings, values := matrix_pool_get_mat3() + mat := mat3 { + 1, x, 0, + y, 1, 0, + 0, 0, 1, + } + write_matrix_to_values_and_value_strings(values, value_strings, mat) +} + write_matrix_to_values_and_value_strings :: proc(values: []f32, value_strings: []InputFloatField, mat: mat3) { for i in 0..<9 { col := i % 3 @@ -699,6 +717,10 @@ program_build_dialog_ui :: proc(ctx: ^ui.Context, dialog_type: ProgramDialogType toggle_group_data^ = {value = cast(^i32)&program.rotation_mode} ui.element(.ToggleGroup, toggle_group_dimensions, toggle_group_config, toggle_group_data) ui_confirm_and_cancel_buttons(.AddRotationMatrixConfirm, element_margin) + case .CreateSkewMatrix: + ui_labeled_input_float_element("X", 4.0, &dialog_data.input_float_values[0], &dialog_data.input_float_value_strings[0]) + ui_labeled_input_float_element("Y", 4.0, &dialog_data.input_float_values[1], &dialog_data.input_float_value_strings[1]) + ui_confirm_and_cancel_buttons(.AddSkewMatrixConfirm, element_margin) case .SaveProject: ui_labeled_input_text_element("Path", 4.0, dialog_data.input_text_buffers[0][:]) ui_confirm_and_cancel_buttons(.ProjectSaveConfirm, element_margin) @@ -770,7 +792,7 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element, button_data = new(UiElementData_Button, context.temp_allocator) button_tooltip = fmt.ctprint("Add identity\nmatrix (", hotkey_without_modifier[.AddIdentity], ")", sep = "") - button_config = {margin = button_margin, label = RAYGUI_ICON_IDENTITY_MATRIX, tooltip = button_tooltip} + button_config = {margin = button_margin, label = "1", tooltip = button_tooltip} button_data^ = {type = .AddIdentity} ui.same_line() ui.element(.Button, button_dimensions, button_config, button_data) @@ -790,12 +812,19 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element, ui.element(.Button, button_dimensions, button_config, button_data) button_data = new(UiElementData_Button, context.temp_allocator) - button_tooltip = fmt.ctprint("Add rotation\nmatrix (", hotkey_without_modifier[.AddIdentity], ")", sep = "") + button_tooltip = fmt.ctprint("Add rotation\nmatrix (", hotkey_without_modifier[.AddRotation], ")", sep = "") button_config = {margin = button_margin, label = RAYGUI_ICON_ROTATION_MATRIX, tooltip = button_tooltip} button_data^ = {type = .AddRotation} ui.same_line() ui.element(.Button, button_dimensions, button_config, button_data) + button_data = new(UiElementData_Button, context.temp_allocator) + button_tooltip = fmt.ctprint("Add rotation\nmatrix", sep = "") + button_config = {margin = button_margin, label = RAYGUI_ICON_SKEW_MATRIX, tooltip = button_tooltip} + button_data^ = {type = .AddSkewMatrix} + ui.same_line() + ui.element(.Button, button_dimensions, button_config, button_data) + // TODO (synthas): Use raygui border theme color for consistency // TODO (synthas): Padding and margin doesn't work here for some reason ui.same_line() @@ -823,12 +852,6 @@ program_build_workspace_ui :: proc(ctx: ^ui.Context) -> (elements: []ui.Element, ui.same_line() ui.element(.Button, button_dimensions, button_config, button_data) - button_config = {margin = button_margin, label = RAYGUI_ICON_RESET, tooltip = "Reset\ngrid"} - button_data = new(UiElementData_Button, context.temp_allocator) - button_data^ = {type = .ResetGrid} - ui.same_line() - ui.element(.Button, button_dimensions, button_config, button_data) - button_config = {margin = button_margin, label = "1", tooltip = "Center\nanimation"} button_data = new(UiElementData_Button, context.temp_allocator) button_data^ = {type = .CenterView} @@ -1027,6 +1050,7 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u case .AddTranslation: program_show_dialog(&program, .CreateTranslationMatrix) case .AddScale: program_show_dialog(&program, .CreateScaleMatrix) case .AddRotation: program_show_dialog(&program, .CreateRotationMatrix) + case .AddSkewMatrix: program_show_dialog(&program, .CreateSkewMatrix) case .AddTranslationMatrixConfirm: inputs := program.dialog_data.input_float_values program_add_translation_matrix(inputs[0], inputs[1], inputs[2]) @@ -1038,6 +1062,9 @@ program_render_ui_and_handle_focus :: proc(ctx: ^ui.Context, focus_element_id: u case .AddRotationMatrixConfirm: program_add_rotation_matrix(program.dialog_data.input_float_values[0]) program.state = .Normal + case .AddSkewMatrixConfirm: + inputs := program.dialog_data.input_float_values + program_add_skew_matrix(inputs[0], inputs[1]) case .ExitDialog: program.state = .Normal case .StartTransformation: