diff --git a/apps/tools/twndel/state.h b/apps/tools/twndel/state.h index fe2efd8..d3ee078 100644 --- a/apps/tools/twndel/state.h +++ b/apps/tools/twndel/state.h @@ -109,6 +109,9 @@ typedef struct State { /* order: x, y, z */ bool axis_mask[3]; char *current_texture; + + uint8_t current_hovered_obj; + uint16_t current_hovered_face; } State; diff --git a/apps/tools/twndel/tool.c b/apps/tools/twndel/tool.c index d1919a1..5564cc6 100644 --- a/apps/tools/twndel/tool.c +++ b/apps/tools/twndel/tool.c @@ -664,24 +664,29 @@ static void process_operations(void) { } /* texture setting */ - } else if (input_action_pressed("select")) { + } else { uint8_t obj_select; uint16_t face_select; if (find_closest_face(&obj_select, &face_select)) { - uint8_t new_tex = push_texture(obj_select, state.current_texture); - uint8_t cur_tex = state.objects[obj_select].faces[face_select].texture; + state.current_hovered_face = face_select; + state.current_hovered_obj = obj_select; - if (new_tex != cur_tex) { - state.objects[obj_select].faces[face_select].texture = new_tex; - audio_play("/data/bong.ogg", NULL, false, 0.5f, 0.0f); + if (input_action_pressed("select")) { + uint8_t new_tex = push_texture(obj_select, state.current_texture); + uint8_t cur_tex = state.objects[obj_select].faces[face_select].texture; - push_operation((Operation){ - .kind = OPERATION_SET_TEXTURE, - .data = { .set_texture = { - .face = face_select, - .object = obj_select, - .delta_texture = cur_tex - new_tex, - }}, - }, false ); + if (new_tex != cur_tex) { + state.objects[obj_select].faces[face_select].texture = new_tex; + audio_play("/data/bong.ogg", NULL, false, 0.5f, 0.0f); + + push_operation((Operation){ + .kind = OPERATION_SET_TEXTURE, + .data = { .set_texture = { + .face = face_select, + .object = obj_select, + .delta_texture = cur_tex - new_tex, + }}, + }, false ); + } } } } @@ -737,6 +742,44 @@ static void draw_axes(void) { } +static void draw_hovered_face_border(void) { + if (state.current_hovered_obj == INVALID_OBJECT || state.current_hovered_face == INVALID_FACE) + return; + + Object *o = &state.objects[state.current_hovered_obj]; + Face *f = &o->faces[state.current_hovered_face]; + + if (f->p[3] != INVALID_POINT) { + Vec3 p0 = point_to_vec3(state.current_hovered_obj, f->p[0]); + Vec3 p1 = point_to_vec3(state.current_hovered_obj, f->p[1]); + Vec3 p2 = point_to_vec3(state.current_hovered_obj, f->p[2]); + Vec3 p3 = point_to_vec3(state.current_hovered_obj, f->p[3]); + Vec3 center = vec3_add(p0, vec3_scale(vec3_sub(p2, p0), 0.5)); + float size = sinf(ctx.frame_number / 10) * 0.05f + 0.1f; + Vec3 c0 = vec3_add(p0, vec3_scale(vec3_sub(p0, center), size)); + Vec3 c1 = vec3_add(p1, vec3_scale(vec3_sub(p1, center), size)); + Vec3 c2 = vec3_add(p2, vec3_scale(vec3_sub(p2, center), size)); + Vec3 c3 = vec3_add(p3, vec3_scale(vec3_sub(p3, center), size)); + draw_line_3d(c0, c1, 1, (Color){255,255,255,255}); + draw_line_3d(c1, c2, 1, (Color){255,255,255,255}); + draw_line_3d(c2, c3, 1, (Color){255,255,255,255}); + draw_line_3d(c3, c0, 1, (Color){255,255,255,255}); + } else { + Vec3 p0 = point_to_vec3(state.current_hovered_obj, f->p[0]); + Vec3 p1 = point_to_vec3(state.current_hovered_obj, f->p[1]); + Vec3 p2 = point_to_vec3(state.current_hovered_obj, f->p[2]); + Vec3 center = vec3_scale(vec3_add(p0, vec3_add(p1, p2)), 0.33f); + float size = sinf(ctx.frame_number / 10) * 0.05f + 0.1f; + Vec3 c0 = vec3_add(p0, vec3_scale(vec3_sub(p0, center), size)); + Vec3 c1 = vec3_add(p1, vec3_scale(vec3_sub(p1, center), size)); + Vec3 c2 = vec3_add(p2, vec3_scale(vec3_sub(p2, center), size)); + draw_line_3d(c0, c1, 1, (Color){255,255,255,255}); + draw_line_3d(c1, c2, 1, (Color){255,255,255,255}); + draw_line_3d(c2, c0, 1, (Color){255,255,255,255}); + } +} + + static void display_textures(void) { String list = file_read("/data/assets/", ":images"); if (!list.data) @@ -785,6 +828,9 @@ void game_tick(void) { init = true; } + state.current_hovered_face = INVALID_FACE; + state.current_hovered_obj = INVALID_OBJECT; + input_action("toggle_display_mode", "Q"); input_action("toggle_projection", "E"); @@ -820,7 +866,9 @@ void game_tick(void) { process_camera_movement(); process_operations(); + /* helpres */ draw_axes(); + draw_hovered_face_border(); for (uint8_t obj = 0; obj < state.objects_sz; ++obj) render_object(obj);