Skip to content

Commit 29002ca

Browse files
committed
Gizmo improvements.
1 parent 03c9e4e commit 29002ca

11 files changed

Lines changed: 151 additions & 21 deletions

File tree

res/editor/shader/gizmo.vert.glsl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
attribute vec3 pos;
2+
attribute vec3 normal;
3+
attribute vec2 uv;
4+
5+
varying vec3 frag_pos;
6+
varying vec3 frag_normal;
7+
varying vec2 frag_uv;
8+
9+
uniform mat4 view_proj_mat;
10+
uniform mat4 world_mat;
11+
uniform mat3 normal_mat;
12+
13+
void main(void) {
14+
vec4 world_pos = world_mat * vec4(pos, 1.0);
15+
gl_Position = view_proj_mat * world_pos;
16+
17+
frag_pos = world_pos.xyz;
18+
frag_normal = normal_mat * normal;
19+
frag_uv = uv;
20+
21+
gl_Position.z = -1.0;
22+
}

res/engine/shader/model.frag.glsl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ void main(void) {
1313

1414
vec4 out_color = color;
1515
if (tiling.x > 0.0) {
16-
out_color *= texture2D(model_texture, (frag_uv + uv_offset) * tiling);
16+
out_color *= texture2D(model_texture, (frag_uv + uv_offset) * tiling);
1717
}
1818
if (out_color.a < 0.1) {
19-
discard;
19+
discard;
2020
}
2121

2222
// TODO: dummy normal usage (before lighting is implemented)
2323
if (frag_normal.x < -50.0){
24-
out_color.r = 0.0;
24+
out_color.r = 0.0;
2525
}
26-
26+
2727
gl_FragColor = out_color;
2828
}

src/editor/src/editor.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,17 @@ editor_set_gizmo(te_editor* editor, te_model* target) {
217217
}
218218
}
219219

220+
void editor_on_before_game_obj_deleted(te_editor* editor, void* game_obj) {
221+
if (editor->gizmo == NULL) {
222+
return;
223+
}
224+
225+
if (gizmo_get_target(editor->gizmo) == game_obj) {
226+
gizmo_destroy_in_world_now(editor->gizmo, editor->game_world);
227+
editor->gizmo = NULL;
228+
}
229+
}
230+
220231
void
221232
editor_on_game_tick(void* game_instance, te_game_manager* game_manager, float delta_time_sec) {
222233
(void)game_manager;

src/editor/src/editor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ void editor_create_game_world(te_editor* editor, const char* relative_path_to_wo
2020
// Specify NULL to hide the gizmo.
2121
void editor_set_gizmo(te_editor* editor, struct te_model* target);
2222

23+
// Called before a game object (for example: te_model) is deleted from the game world.
24+
void editor_on_before_game_obj_deleted(te_editor* editor, void* game_obj);
25+
2326
// window callbacks -------------------------------------------------------------------------------
2427
void editor_on_game_started(void* game_instance, struct te_game_manager* game_manager);
2528
void editor_on_game_tick(

src/editor/src/gizmo.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ create_gizmo_model(te_gizmo* gizmo) {
3434
model_set_is_serialization_allowed(model, false);
3535
model_set_custom_ptr(model, gizmo);
3636
model_set_custom_geometry_provider(model, get_geometry);
37+
model_set_custom_vert_shader(model, "editor/shader/gizmo.vert.glsl");
3738

3839
return model;
3940
}
@@ -84,6 +85,11 @@ gizmo_destroy_in_world_now(te_gizmo* gizmo, te_world* world) {
8485
model_destroy(gizmo->model_z); // <- triggers gizmo destroy
8586
}
8687

88+
void*
89+
gizmo_get_target(te_gizmo* gizmo) {
90+
return gizmo->target;
91+
}
92+
8793
void
8894
gizmo_start_grab_x(te_gizmo* gizmo) {
8995
gizmo->grab_x = true;
@@ -281,7 +287,7 @@ get_geometry(
281287

282288
// Make origin around 0.
283289
for (unsigned int k = 0; k < (*vertex_count); k++) {
284-
(*vertices)[k].pos[0] += half_width;
290+
(*vertices)[k].pos[0] += half_width + half_width / 4.0f;
285291
}
286292

287293
(*index_count) = 36;

src/editor/src/gizmo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ te_gizmo* gizmo_create_in_world(struct te_world* world, struct te_model* target)
1616
// you can call this function to do it right now.
1717
void gizmo_destroy_in_world_now(te_gizmo* gizmo, struct te_world* world);
1818

19+
// Returns game object that the gizmo controls.
20+
void* gizmo_get_target(te_gizmo* gizmo);
21+
1922
void gizmo_start_grab_x(te_gizmo* gizmo);
2023
void gizmo_start_grab_y(te_gizmo* gizmo);
2124
void gizmo_start_grab_z(te_gizmo* gizmo);

src/editor/src/ui/property_inspector.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,8 @@ property_inspector_hide(te_property_inspector* inspector) {
551551

552552
free(widgets);
553553
}
554+
555+
void*
556+
property_inspector_get_inspected_obj(te_property_inspector* inspector) {
557+
return inspector->obj;
558+
}

src/editor/src/ui/property_inspector.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ void property_inspector_set_parent(te_property_inspector* inspector, struct te_w
1111

1212
// Displays/hides properties of the specified object.
1313
void property_inspector_show(te_property_inspector* inspector, void* obj, const char* obj_type_id);
14-
void property_inspector_hide(te_property_inspector* inspector);
14+
void property_inspector_hide(te_property_inspector* inspector);
15+
16+
// Returns NULL or the currently displayed game object.
17+
void* property_inspector_get_inspected_obj(te_property_inspector* inspector);

src/editor/src/ui/world_inspector.c

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,38 @@ world_inspector_destroy(te_world_inspector* inspector) {
132132
free(inspector);
133133
}
134134

135+
static void
136+
refresh_button_highlight(te_world_inspector* inspector) {
137+
// Clear highlight.
138+
vec4 color;
139+
theme_get_button_color(color);
140+
for (unsigned int i = 0; i < inspector->item_buttons_count; i++) {
141+
button_widget_set_color(inspector->item_buttons[i], color);
142+
}
143+
144+
if (inspector->state != TE_WIS_SHOW_WORLD_OBJECTS) {
145+
return;
146+
}
147+
148+
void* game_obj = property_inspector_get_inspected_obj(inspector->property_inspector);
149+
if (game_obj == NULL) {
150+
return;
151+
}
152+
153+
for (unsigned int i = 0; i < inspector->item_buttons_count; i++) {
154+
te_world_item_info* info =
155+
&((te_world_item_info*)inspector->item_list)
156+
[inspector->current_page * inspector->item_buttons_count + i];
157+
if (info->obj != game_obj) {
158+
continue;
159+
}
160+
161+
theme_get_accent_color(color);
162+
button_widget_set_color(inspector->item_buttons[i], color);
163+
break;
164+
}
165+
}
166+
135167
// Uses item_list and updates text on the buttons depending on the current world inspector state.
136168
static void
137169
refresh_item_names(te_world_inspector* inspector) {
@@ -240,6 +272,8 @@ refresh_item_names(te_world_inspector* inspector) {
240272
widget_set_relative_position(
241273
button_widget_get_widget(inspector->item_buttons[button_idx]), pos);
242274
}
275+
276+
refresh_button_highlight(inspector);
243277
}
244278

245279
static void
@@ -331,6 +365,7 @@ rebuild_item_list_to_display_world_objects(te_world_inspector* inspector) {
331365
}
332366

333367
property_inspector_hide(inspector->property_inspector);
368+
editor_set_gizmo(inspector->editor, NULL);
334369

335370
free(inspector->item_list);
336371
inspector->item_list = NULL;
@@ -553,6 +588,7 @@ world_inspector_select_obj(te_world_inspector* inspector, void* obj) {
553588

554589
if (obj == NULL) {
555590
property_inspector_hide(inspector->property_inspector);
591+
refresh_button_highlight(inspector);
556592
editor_set_gizmo(inspector->editor, NULL);
557593
return;
558594
}
@@ -588,7 +624,29 @@ world_inspector_select_obj(te_world_inspector* inspector, void* obj) {
588624
}
589625
}
590626

627+
// Switch the current page to show the selected item.
628+
bool found = false;
629+
for (unsigned int page_idx = 0; page_idx < inspector->page_count; page_idx++) {
630+
for (unsigned int i = 0; i < inspector->item_buttons_count; i++) {
631+
te_world_item_info* info = &(
632+
(te_world_item_info*)inspector
633+
->item_list)[page_idx * inspector->item_buttons_count + i];
634+
if (info->obj != selected_info->obj) {
635+
continue;
636+
}
637+
638+
inspector->current_page = page_idx;
639+
found = true;
640+
break;
641+
}
642+
if (found) {
643+
break;
644+
}
645+
}
646+
591647
property_inspector_show(inspector->property_inspector, selected_info->obj, type_id);
648+
refresh_item_names(inspector);
649+
refresh_page_text(inspector);
592650
}
593651

594652
void
@@ -641,6 +699,9 @@ static void
641699
on_top_button_clicked(te_button_widget* button) {
642700
te_world_inspector* inspector = widget_get_custom_ptr(button_widget_get_widget(button));
643701

702+
property_inspector_hide(inspector->property_inspector);
703+
editor_set_gizmo(inspector->editor, NULL);
704+
644705
if (inspector->state == TE_WIS_SHOW_WORLD_OBJECTS) {
645706
inspector->state = TE_WIS_CREATE_NEW_OBJECT;
646707
} else if (
@@ -708,6 +769,7 @@ on_button_list_item_clicked(te_button_widget* button) {
708769
switch (selected_info->type) {
709770
case (TE_WIT_MODEL): {
710771
type_id = model_get_type_id();
772+
editor_set_gizmo(inspector->editor, selected_info->obj);
711773
break;
712774
}
713775
case (TE_WIT_CAMERA): {
@@ -722,6 +784,7 @@ on_button_list_item_clicked(te_button_widget* button) {
722784

723785
property_inspector_show(
724786
inspector->property_inspector, selected_info->obj, type_id);
787+
refresh_button_highlight(inspector);
725788
break;
726789
}
727790
case (TE_WIS_CREATE_NEW_OBJECT): {
@@ -777,6 +840,9 @@ on_button_list_item_clicked(te_button_widget* button) {
777840
rebuild_item_list_to_display_world_objects(inspector);
778841
refresh_page_text(inspector);
779842
} else if (option_index == TE_OMO_DELETE_OBJ) {
843+
// First check if we have gizmo on the object we are about to delete.
844+
editor_on_before_game_obj_deleted(inspector->editor, inspector->selected_obj);
845+
780846
const te_type_info* info =
781847
type_database_get_type_info(inspector->selected_obj_type_id);
782848
info->despawn(inspector->game_world, inspector->selected_obj);
@@ -819,7 +885,7 @@ on_button_list_item_clicked(te_button_widget* button) {
819885

820886
const size_t button_index =
821887
widget_get_custom_value(button_widget_get_widget(button));
822-
te_world_item_info* selected_info =
888+
te_world_item_info* target_info =
823889
&((te_world_item_info*)inspector->item_list)
824890
[inspector->current_page * inspector->item_buttons_count + button_index];
825891

@@ -828,14 +894,14 @@ on_button_list_item_clicked(te_button_widget* button) {
828894

829895
switch (inspector->selected_obj_type) {
830896
case (TE_WIT_CAMERA): {
831-
switch (selected_info->type) {
897+
switch (target_info->type) {
832898
case (TE_WIT_CAMERA): {
833899
log_error("unexpected state");
834900
abort();
835901
break;
836902
}
837903
case (TE_WIT_MODEL): {
838-
model_attach_camera(inspector->selected_obj, selected_info->obj);
904+
model_attach_camera(target_info->obj, inspector->selected_obj);
839905
break;
840906
}
841907
case (TE_WIT_WIDGET): {
@@ -847,14 +913,14 @@ on_button_list_item_clicked(te_button_widget* button) {
847913
break;
848914
}
849915
case (TE_WIT_MODEL): {
850-
switch (selected_info->type) {
916+
switch (target_info->type) {
851917
case (TE_WIT_CAMERA): {
852918
log_error("unexpected state");
853919
abort();
854920
break;
855921
}
856922
case (TE_WIT_MODEL): {
857-
model_set_parent(inspector->selected_obj, selected_info->obj);
923+
model_set_parent(inspector->selected_obj, target_info->obj);
858924
break;
859925
}
860926
case (TE_WIT_WIDGET): {
@@ -866,7 +932,7 @@ on_button_list_item_clicked(te_button_widget* button) {
866932
break;
867933
}
868934
case (TE_WIT_WIDGET): {
869-
switch (selected_info->type) {
935+
switch (target_info->type) {
870936
case (TE_WIT_CAMERA): {
871937
log_error("unexpected state");
872938
abort();
@@ -879,8 +945,8 @@ on_button_list_item_clicked(te_button_widget* button) {
879945
}
880946
case (TE_WIT_WIDGET): {
881947
widget_set_parent(
882-
selected_info->obj,
883-
selected_type_info->get_widget(inspector->selected_obj));
948+
selected_type_info->get_widget(inspector->selected_obj),
949+
target_info->obj);
884950
break;
885951
}
886952
}
@@ -898,6 +964,8 @@ static void
898964
on_button_list_item_right_clicked(te_button_widget* button) {
899965
te_world_inspector* inspector = widget_get_custom_ptr(button_widget_get_widget(button));
900966
property_inspector_hide(inspector->property_inspector);
967+
editor_set_gizmo(inspector->editor, NULL);
968+
refresh_button_highlight(inspector);
901969

902970
const size_t button_index = widget_get_custom_value(button_widget_get_widget(button));
903971

src/engine_lib/src/game/model.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ model_destroy(te_model* model) {
166166

167167
free(model->name);
168168
free(model->tex_relative_path);
169+
free(model->custom_frag_relative_path);
170+
free(model->custom_vert_relative_path);
169171
free(model->path_to_geo);
170172
free(model);
171173
}
@@ -411,7 +413,8 @@ model_get_scale(te_model* model, vec3 out) {
411413
glm_vec3_copy(model->scale, out);
412414
}
413415

414-
void model_get_world_position(te_model* model, vec3 out) {
416+
void
417+
model_get_world_position(te_model* model, vec3 out) {
415418
if (model->render_data_handle == 0xFFFFFFFF) {
416419
model_get_position(model, out);
417420
return;
@@ -562,7 +565,8 @@ model_get_attached_camera(te_model* model) {
562565
return model->attached_camera;
563566
}
564567

565-
void model_set_custom_ptr(te_model* model, void* ptr) {
568+
void
569+
model_set_custom_ptr(te_model* model, void* ptr) {
566570
model->custom_ptr = ptr;
567571
}
568572

@@ -571,7 +575,8 @@ model_get_custom_ptr(te_model* model) {
571575
return model->custom_ptr;
572576
}
573577

574-
void model_set_custom_on_before_destroyed(
578+
void
579+
model_set_custom_on_before_destroyed(
575580
te_model* model, void (*custom_on_before_destroyed)(te_model*)) {
576581
model->custom_on_before_destroyed = custom_on_before_destroyed;
577582
}
@@ -860,8 +865,10 @@ model_get_geometry(te_model* model) {
860865
return model->path_to_geo;
861866
}
862867

863-
void model_set_custom_geometry_provider(
864-
te_model* model, void (*custom_get_geometry)(
868+
void
869+
model_set_custom_geometry_provider(
870+
te_model* model,
871+
void (*custom_get_geometry)(
865872
te_model* model, te_model_vertex** vertices, unsigned short** indices,
866873
unsigned int* vertex_count, unsigned int* index_count, bool* free_custom_geometry)) {
867874
model->custom_get_geometry = custom_get_geometry;
@@ -891,7 +898,8 @@ prv_model_get_render_data_handle(te_model* model) {
891898
return model->render_data_handle;
892899
}
893900

894-
te_model_renderer* prv_model_get_model_renderer(te_model* model) {
901+
te_model_renderer*
902+
prv_model_get_model_renderer(te_model* model) {
895903
if (model->render_data_handle == 0xFFFFFFFF) {
896904
return NULL;
897905
}

0 commit comments

Comments
 (0)