package main import rl "libraries/raylib" import "core:math/ease" import "core:math/linalg" import "core:slice" import "core:fmt" ANIMATION_COLOR_ORIGIN :: rl.RED ANIMATION_COLOR_END :: rl.BLUE RectangleCorners :: struct {tl, tr, br, bl: v2} rectangle_corners_from_rect :: proc "contextless" (rect: rect2) -> RectangleCorners { return { tl = {rect.x, rect.y}, tr = {rect.x + rect.width, rect.y}, bl = {rect.x + rect.width, rect.y + rect.height}, br = {rect.x, rect.y + rect.height} } } rectangle_corners_transform_mat3 :: proc "contextless" (corners: RectangleCorners, transform: mat3) -> 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, } } rectangle_corners_transform_mat2 :: proc "contextless" (corners: RectangleCorners, transform: mat2) -> RectangleCorners { return {corners.tl * transform, corners.tr * transform, corners.br * transform, corners.bl * transform} } 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) } /* Maybe it is possible to have everything 3d be mathed the same way as in 2d. But I'm not sure if that's actually how it works. */ AnimationShape_Rectangle :: struct { origin: RectangleCorners, } AnimationShapes :: struct { rectangle: AnimationShape_Rectangle, } Animation :: struct { matrices: []f32, matrix_index: int, matrix_count: int, matrix_type: AnimationMatrixType, shapes: AnimationShapes, ease: ease.Ease, state: AnimationState, type: AnimationType, } AnimationMatrixType :: enum { Mat2, Mat3, Mat4, } @private @rodata animation_matrix_type_size := [AnimationMatrixType]int { .Mat2 = size_of(mat2), .Mat3 = size_of(mat3), .Mat4 = size_of(mat4), } AnimationType :: enum { Rectangle, } AnimationState :: enum { Ready, Playing, Paused, Finished, } animation_init :: proc(animation: ^Animation, matrices: []f32) { animation^ = { ease = .Cubic_Out, type = .Rectangle, matrices = matrices, shapes = { rectangle = { origin = rectangle_corners_from_rect(rect2{-16, -16, 32, 32}) } }, } } animation_play :: proc(animation: ^Animation) { } animation_reset :: proc(animation: ^Animation) { } animation_pause :: proc(animation: ^Animation) { } animation_update :: proc(animation: ^Animation, matrices: []mat3) { } animation_draw :: proc(animation: Animation) { switch animation.type { case .Rectangle: shape := animation.shapes.rectangle transformation := linalg.identity(mat3) previous, next := shape.origin, shape.origin color_origin := cast([4]f32)(ANIMATION_COLOR_ORIGIN) color_end := cast([4]f32)(ANIMATION_COLOR_END) draw_animation_rectangle_corners(next, ANIMATION_COLOR_ORIGIN) matrices := slice.reinterpret([]mat3, animation.matrices) for m, i in matrices { progress := f32(i + 1) / f32(len(animation.matrices)) transformation *= m previous = next next := rectangle_corners_transform_mat3(previous, transformation) draw_animation_rectangle_corners(next, cast(rl.Color)linalg.lerp(color_origin, color_end, progress)) } } } animation_set_playback_speed :: proc(animation: ^Animation) { } animation_set_type :: proc(animation: ^Animation, type: AnimationType) { animation.type = type } animation_is_finished :: proc() -> bool { return false }