Skip to content

Commit 03c9e4e

Browse files
committed
Implement a simple gizmo.
1 parent 841a3f3 commit 03c9e4e

22 files changed

Lines changed: 1023 additions & 88 deletions
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
void main() {
2+
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
3+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
attribute vec3 local_pos;
2+
3+
uniform vec3 pos_offset;
4+
uniform vec3 extents;
5+
uniform mat4 view_proj_mat;
6+
7+
void main() {
8+
gl_Position = view_proj_mat * vec4((local_pos * extents) + pos_offset, 1.0);
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
void main() {
2+
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
3+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
attribute vec3 local_pos;
2+
3+
uniform vec3 from;
4+
uniform vec3 to;
5+
uniform mat4 view_proj_mat;
6+
7+
void main() {
8+
gl_Position = view_proj_mat * vec4(float(local_pos.x < 0.5) * from + float(local_pos.x > 0.5) * to, 1.0);
9+
}

src/editor/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ set(PROJECT_SOURCES
1212
src/editor_camera.h
1313
src/obj_picking.c
1414
src/obj_picking.h
15+
src/gizmo.c
16+
src/gizmo.h
1517
src/ui/editor_ui.c
1618
src/ui/editor_ui.h
1719
src/ui/theme.h

src/editor/src/editor.c

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <ui/editor_ui.h>
2020
#include <ui/world_inspector.h>
2121
#include <obj_picking.h>
22+
#include <gizmo.h>
2223

2324
struct te_editor {
2425
// Not NULL if @ref game_world was loaded from a file (relative to the `res` directory).
@@ -48,6 +49,9 @@ struct te_editor {
4849
// Always valid.
4950
te_editor_ui* ui;
5051

52+
// Not NULL if shown.
53+
te_gizmo* gizmo;
54+
5155
// Time (in seconds) since @ref game_world_stats_widget was updated.
5256
float time_since_stats_update_sec;
5357
};
@@ -64,6 +68,7 @@ editor_create() {
6468
editor->file_dialog = NULL;
6569
editor->game_world_relative_path = NULL;
6670
editor->editor_world = NULL;
71+
editor->gizmo = NULL;
6772
editor->time_since_stats_update_sec = 10.0f;
6873

6974
return editor;
@@ -96,6 +101,8 @@ destroy_game_world(te_editor* editor, te_game_manager* game_manager) {
96101
game_manager_destroy_world(game_manager, editor->game_world);
97102
editor->game_world = NULL;
98103
editor->game_world_stats_widget = NULL;
104+
105+
editor->gizmo = NULL;
99106
}
100107

101108
void
@@ -104,7 +111,6 @@ editor_on_window_close(void* game_instance, struct te_game_manager* game_manager
104111

105112
if (editor->game_world != NULL) {
106113
destroy_game_world(editor, game_manager);
107-
editor->game_world = NULL;
108114
}
109115

110116
if (editor->file_dialog != NULL) {
@@ -194,6 +200,23 @@ editor_create_game_world(te_editor* editor, const char* relative_path_to_world)
194200
world_inspector_rebuild_list(inspector, editor->game_world);
195201
}
196202

203+
void
204+
editor_set_gizmo(te_editor* editor, te_model* target) {
205+
if (editor->game_world == NULL){
206+
log_error("expected the game world to be valid");
207+
abort();
208+
}
209+
210+
if (editor->gizmo != NULL) {
211+
gizmo_destroy_in_world_now(editor->gizmo, editor->game_world);
212+
editor->gizmo = NULL;
213+
}
214+
215+
if (target != NULL) {
216+
editor->gizmo = gizmo_create_in_world(editor->game_world, target);
217+
}
218+
}
219+
197220
void
198221
editor_on_game_tick(void* game_instance, te_game_manager* game_manager, float delta_time_sec) {
199222
(void)game_manager;
@@ -395,7 +418,20 @@ editor_on_mouse_button_pressed(
395418
window_capture_mouse_cursor(window, true);
396419
editor_camera_enable_input(editor->editor_camera, true);
397420
}else if (button == TE_MB_LEFT) {
398-
void* obj = obj_picking_find_obj_under_cursor(cursor_pos, game_camera, editor->game_world);
421+
void* obj = obj_picking_find_obj_under_cursor(cursor_pos, game_camera, editor->game_world, editor->gizmo);
422+
423+
if (editor->gizmo != NULL) {
424+
if (obj == gizmo_get_model_x(editor->gizmo)) {
425+
gizmo_start_grab_x(editor->gizmo);
426+
return;
427+
} else if (obj == gizmo_get_model_y(editor->gizmo)) {
428+
gizmo_start_grab_y(editor->gizmo);
429+
return;
430+
} else if (obj == gizmo_get_model_z(editor->gizmo)) {
431+
gizmo_start_grab_z(editor->gizmo);
432+
return;
433+
}
434+
}
399435
world_inspector_select_obj(editor_ui_get_world_inspector(editor->ui), obj);
400436
}
401437
}
@@ -409,13 +445,20 @@ editor_on_mouse_button_released(
409445
te_editor* editor = game_instance;
410446
te_window* window = game_manager_get_window(game_manager);
411447

412-
if (button == TE_MB_RIGHT && window_is_mouse_captured(window)) {
413-
if (editor->game_world == NULL) {
448+
if (button == TE_MB_RIGHT) {
449+
if (window_is_mouse_captured(window)) {
450+
if (editor->game_world == NULL) {
451+
return;
452+
}
453+
454+
window_capture_mouse_cursor(window, false);
455+
editor_camera_enable_input(editor->editor_camera, false);
456+
}
457+
}else if (button == TE_MB_LEFT) {
458+
if (editor->gizmo == NULL) {
414459
return;
415460
}
416-
417-
window_capture_mouse_cursor(window, false);
418-
editor_camera_enable_input(editor->editor_camera, false);
461+
gizmo_end_grab(editor->gizmo);
419462
}
420463
}
421464

@@ -426,7 +469,15 @@ editor_on_mouse_moved(
426469
(void)game_manager;
427470

428471
te_editor* editor = game_instance;
472+
if (editor->game_world == NULL) {
473+
return;
474+
}
475+
429476
editor_camera_on_mouse_moved(editor->editor_camera, x_offset, y_offset);
477+
478+
if (editor->gizmo != NULL && gizmo_is_grabbed(editor->gizmo)) {
479+
gizmo_move(editor->gizmo, editor_camera_get_camera(editor->editor_camera), x_offset, y_offset);
480+
}
430481
}
431482

432483
void

src/editor/src/editor.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
struct te_game_manager;
88

99
typedef struct te_editor te_editor;
10+
struct te_model;
1011

1112
te_editor* editor_create();
1213
void editor_destroy(te_editor* editor);
@@ -15,6 +16,10 @@ void editor_destroy(te_editor* editor);
1516
// Optionally specify a non-NULL path to file to load as the new world.
1617
void editor_create_game_world(te_editor* editor, const char* relative_path_to_world);
1718

19+
// Shows or hides gizmo around the specified model.
20+
// Specify NULL to hide the gizmo.
21+
void editor_set_gizmo(te_editor* editor, struct te_model* target);
22+
1823
// window callbacks -------------------------------------------------------------------------------
1924
void editor_on_game_started(void* game_instance, struct te_game_manager* game_manager);
2025
void editor_on_game_tick(

0 commit comments

Comments
 (0)