From 794852a0b0ac0908c3711c2b6a30c700926748d1 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 12 Feb 2024 00:35:22 -0500 Subject: [PATCH] Got initial box mouse select detection working --- code/api.odin | 3 ++ code/collision.odin | 19 ++++++------- code/colors.odin | 3 ++ code/entity_box2.odin | 1 + code/env.odin | 5 +++- code/space.odin | 10 +++++++ code/tick_render.odin | 64 +++++++++++++++++-------------------------- code/tick_update.odin | 36 ++++++++++++++++++++++++ 8 files changed, 90 insertions(+), 51 deletions(-) diff --git a/code/api.odin b/code/api.odin index 0ac8ec4..4663966 100644 --- a/code/api.odin +++ b/code/api.odin @@ -123,6 +123,9 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ frame_1.color = Color_BG_TextBox // Frame is getting interpreted as points (It doesn't have to be, I'm just doing it...) box_set_size( & frame_1, { 400, 200 } ) + + frame_2.color = Color_BG_TextBox_Green + box_set_size( & frame_2, { 350, 500 } ) // frame_1.position = { 1000, 1000 } } } diff --git a/code/collision.odin b/code/collision.odin index 2b9940c..4409a2c 100644 --- a/code/collision.odin +++ b/code/collision.odin @@ -3,6 +3,13 @@ package sectr import "core:math/linalg" +box_is_within :: proc ( box : ^ Box2, pos : Vec2 ) -> b32 { + bounds := box_get_bounds( box ) + within_x_bounds : b32 = pos.x >= bounds.top_left.x && pos.x <= bounds.bottom_right.x + within_y_bounds : b32 = pos.y >= bounds.bottom_right.y && pos.y <= bounds.top_left.y + return within_x_bounds && within_y_bounds +} + // Not sure if I should in the future not do the radius check, // As it maybe be better off as a general proc used in an iteration... box_is_within_view :: proc( box : ^ Box2 ) -> b32 @@ -26,18 +33,8 @@ box_is_within_view :: proc( box : ^ Box2 ) -> b32 within_bounds : b32 = false - when false { - within_x : b32 = box_bounds.top_left.x > screen_bounds.top_left.x - within_x &= box_bounds.top_left.x < screen_bounds.bottom_right.x +// TODO(Ed) : Should be easy to finish given the other impl... - within_y : b32 = box_bounds.top_left.y > screen_bounds.top_left.y - - state := get_state(); using state - screen_extent := state.app_window.extent - cam := & project.workspace.cam - within_x_bounds : b32 = pos.x >= -screen_extent.x && pos.x <= screen_extent.x - within_y_bounds : b32 = pos.y >= -screen_extent.y && pos.y <= screen_extent.y - } return within_bounds } diff --git a/code/colors.odin b/code/colors.odin index 36b1c11..a8a0034 100644 --- a/code/colors.odin +++ b/code/colors.odin @@ -9,5 +9,8 @@ Color_White :: rl.WHITE Color_Transparent :: Color { 0, 0, 0, 0 } Color_BG :: Color { 41, 41, 45, 255 } Color_BG_TextBox :: Color { 32, 32, 32, 255 } +Color_BG_TextBox_Green :: Color { 102, 102, 110, 255 } Color_Frame_Hover :: Color { 122, 122, 125, 255 } Color_Frame_Select :: Color { 188, 188, 188, 255 } +Color_GreyRed :: Color { 220, 100, 100, 125 } +Color_White_A125 :: Color { 255, 255, 255, 125 } diff --git a/code/entity_box2.odin b/code/entity_box2.odin index b3931c0..3a975d1 100644 --- a/code/entity_box2.odin +++ b/code/entity_box2.odin @@ -24,6 +24,7 @@ box_set_size :: proc( box : ^ Box2, size : AreaSize ) { box.extent = transmute(Extents2) size * 0.5 } +// TODO(Ed) : Fix this up? get_rl_rect :: proc ( box : ^ Box2 ) -> rl.Rectangle { rect : rl.Rectangle = { x = box.position.x - box.extent.x, diff --git a/code/env.odin b/code/env.odin index 83b999f..8ece4ca 100644 --- a/code/env.odin +++ b/code/env.odin @@ -85,7 +85,8 @@ Workspace :: struct { name : string, cam : Camera, - frame_1 : Box2 + frame_1 : Box2, + frame_2 : Box2, } DebugData :: struct { @@ -98,4 +99,6 @@ DebugData :: struct { cursor_unlock_pos : Vec2, // Raylib changes the mose position on lock, we want restore the position the user would be in on screen mouse_vis : b32, last_mouse_pos : Vec2, + + frame_1_on_top : b32, } diff --git a/code/space.odin b/code/space.odin index 91dc82a..8dd6aec 100644 --- a/code/space.odin +++ b/code/space.odin @@ -16,6 +16,10 @@ when ODIN_OS == OS_Type.Windows { // 1 inch = 2.54 cm, 96 inch * 2.54 = 243.84 DPC } +// points_to_cm :: proc( points : f32 ) -> f32 { +// return points * +// } + cm_to_pixels :: proc( cm : f32 ) -> f32 { screen_dpc := get_state().app_window.dpc return cm * screen_dpc @@ -103,6 +107,12 @@ view_get_corners :: proc() -> BoundsCorners2 { return { top_left, top_right, bottom_left, bottom_right } } +screen_to_world :: proc( pos : Vec2 ) -> Vec2 { + state := get_state(); using state + cam := & project.workspace.cam + return cam.target + pos * (1 / cam.zoom) +} + screen_to_render :: proc( pos : Vec2 ) -> Vec2 { screen_extent := transmute(Vec2) get_state().project.workspace.cam.offset return pos + { screen_extent.x, -screen_extent.y } diff --git a/code/tick_render.odin b/code/tick_render.odin index 52c341b..e68cf80 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -38,7 +38,7 @@ render :: proc() screen_corners := screen_get_corners() position := screen_corners.top_right - position.x -= 300 + position.x -= 200 position.y += debug.draw_debug_text_y content := fmt.bprintf( draw_text_scratch[:], format, ..args ) @@ -49,8 +49,8 @@ render :: proc() // Debug Text { - debug_text( "Screen Width : %v", rl.GetScreenWidth () ) - debug_text( "Screen Height: %v", rl.GetScreenHeight() ) + // debug_text( "Screen Width : %v", rl.GetScreenWidth () ) + // debug_text( "Screen Height: %v", rl.GetScreenHeight() ) if replay.mode == ReplayMode.Record { debug_text( "Recording Input") } @@ -61,15 +61,8 @@ render :: proc() if debug.mouse_vis { debug_text( "Position: %v", input.mouse.pos ) - rect_pos := transmute(Vec2) state.app_window.extent + input.mouse.pos - - width : f32 = 32 - mouse_rect : rl.Rectangle - mouse_rect.x = rect_pos.x - width * 0.5 - mouse_rect.y = rect_pos.y - width * 0.5 - mouse_rect.width = width - mouse_rect.height = width - rl.DrawRectangleRec( mouse_rect, Color_White ) + cursor_pos := transmute(Vec2) state.app_window.extent + input.mouse.pos + rl.DrawCircleV( cursor_pos, 10, Color_White_A125 ) } debug.draw_debug_text_y = 50 @@ -84,38 +77,31 @@ render_mode_2d :: proc() { rl.BeginMode2D( project.workspace.cam ) - // Frame 1 - { - frame_1 := & project.workspace.frame_1 - rect := get_rl_rect( frame_1 ) - screen_pos := world_to_screen_pos(frame_1.position) + // debug.frame_1_on_top = true - rect.width = points_to_pixels( rect.width ) - rect.height = points_to_pixels( rect.height ) - rect.x = points_to_pixels( screen_pos.x ) - rect.y = points_to_pixels( screen_pos.y ) - - rl.DrawRectangleRec( rect, frame_1.color ) - // rl.DrawRectangleV( frame_1.position, { frame_1.width, frame_1.height }, frame_1.color ) - // rl.DrawRectanglePro( rect, frame_1.position, 0, frame_1.color ) + boxes : [2]^Box2 + if debug.frame_1_on_top { + boxes = { & project.workspace.frame_2, & project.workspace.frame_1 } + } + else { + boxes = { & project.workspace.frame_1, & project.workspace.frame_2 } } - // Frame 2 - when false - { - frame_1 := & project.workspace.frame_1 - rect := get_rl_rect( frame_1 ) - screen_pos := world_to_screen_pos(frame_1.position) + for box in boxes { + screen_pos := world_to_screen_pos(box.position) - Vec2(box.extent) + size := transmute(Vec2) box.extent * 2.0 - rect.width = points_to_pixels( rect.width ) - rect.height = points_to_pixels( rect.height ) - rect.x = points_to_pixels( screen_pos.x ) - rect.y = points_to_pixels( screen_pos.y ) + rect : rl.Rectangle + rect.x = screen_pos.x + rect.y = screen_pos.y + rect.width = size.x + rect.height = size.y + rl.DrawRectangleRec( rect, box.color ) + } - rl.DrawRectangleRec( rect, frame_1.color ) - // rl.DrawRectangleV( frame_1.position, { frame_1.width, frame_1.height }, frame_1.color ) - // rl.DrawRectanglePro( rect, frame_1.position, 0, frame_1.color ) - } + if debug.mouse_vis { + // rl.DrawCircleV( screen_to_world(input.mouse.pos), 10, Color_GreyRed ) + } rl.EndMode2D() } diff --git a/code/tick_update.odin b/code/tick_update.odin index fd8bc27..2862611 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -16,6 +16,8 @@ DebugActions :: struct { show_mouse_pos : b32, + mouse_select : b32, + cam_move_up : b32, cam_move_left : b32, cam_move_down : b32, @@ -44,6 +46,8 @@ poll_debug_actions :: proc( actions : ^ DebugActions, input : ^ InputState ) show_mouse_pos = keyboard.right_alt.ended_down && pressed(keyboard.M) + mouse_select = pressed(mouse.left) + cam_move_up = keyboard.W.ended_down && ( ! modifier_active || keyboard.left_shift.ended_down ) cam_move_left = keyboard.A.ended_down && ( ! modifier_active || keyboard.left_shift.ended_down ) cam_move_down = keyboard.S.ended_down && ( ! modifier_active || keyboard.left_shift.ended_down ) @@ -154,6 +158,38 @@ update :: proc( delta_time : f64 ) -> b32 } } + // Frame 1 bounds detection + { + if debug_actions.mouse_select { + cursor_pos := screen_to_world( input.mouse.pos ) + + box_bounds := box_get_bounds(& project.workspace.frame_1) + within_x_bounds : b32 = cursor_pos.x >= box_bounds.top_left.x && cursor_pos.x <= box_bounds.bottom_right.x + within_y_bounds : b32 = cursor_pos.y >= box_bounds.bottom_right.y && cursor_pos.y <= box_bounds.top_left.y + + if within_x_bounds && within_y_bounds { + debug.frame_1_on_top = true + } + } + } + + // Frame 2 bounds detection + { + if debug_actions.mouse_select { + cursor_pos := screen_to_world( input.mouse.pos ) + box_extent := & project.workspace.frame_2.extent + + box_bounds := box_get_bounds(& project.workspace.frame_2) + + within_x_bounds : b32 = cursor_pos.x >= box_bounds.top_left.x && cursor_pos.x <= box_bounds.bottom_right.x + within_y_bounds : b32 = cursor_pos.y >= box_bounds.bottom_right.y && cursor_pos.y <= box_bounds.top_left.y + + if within_x_bounds && within_y_bounds { + debug.frame_1_on_top = false + } + } + } + debug.last_mouse_pos = input.mouse.pos should_shutdown : b32 = ! cast(b32) rl.WindowShouldClose()