From 80de060002c5be23ad8d89aacc1d2992155a0f66 Mon Sep 17 00:00:00 2001 From: Daniel Bross Date: Thu, 28 Nov 2024 00:15:07 +0100 Subject: [PATCH 1/2] entity_ui_proc generation --- core/scene.jai | 9 ++++ editor/editor_ui.jai | 2 + metaprogram.jai | 58 +++++++++++++++++++++++++ ui/widgets.jai | 101 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+) diff --git a/core/scene.jai b/core/scene.jai index 9036e62..b0124c3 100644 --- a/core/scene.jai +++ b/core/scene.jai @@ -7,6 +7,7 @@ #placeholder serialize_entity; #placeholder deserialize_entity; #placeholder duplicate_entity; +#placeholder entity_ui; MAX_CACHED_PILES :: 8; last_unnamed_scene_id := 0; @@ -262,6 +263,14 @@ update_entity_transform :: (e: *Entity, parent_matrix: Matrix4 = Matrix4_Identit } } +get_entity_with_id :: (scene: *Scene, id: s64) -> *Entity { + for scene.entities { + if it.id == id return it; + } + + return null; +} + #scope_file next_entity_id: Entity_Id; \ No newline at end of file diff --git a/editor/editor_ui.jai b/editor/editor_ui.jai index 5a9e517..1de7438 100644 --- a/editor/editor_ui.jai +++ b/editor/editor_ui.jai @@ -229,6 +229,8 @@ editor_ui :: () { ui_vector_field("Scale", *entity.transform.scale); update_matrix(*entity.transform); + + entity_ui(entity); } } diff --git a/metaprogram.jai b/metaprogram.jai index 2097062..3033283 100644 --- a/metaprogram.jai +++ b/metaprogram.jai @@ -81,6 +81,32 @@ should_serialize :: (type: *Type_Info_Struct, member: Type_Info_Struct_Member) - return true; } +generate_member_ui :: (type: *Type_Info_Struct, builder: *String_Builder, path: string = "") { + for type.members { + if should_serialize(type, it) { + new_path : string; + if path.count == 0 { + new_path = it.name; + } else { + new_path = tprint("%1.%2", path, it.name); + } + + if it.type.type == { + //case .STRUCT; { + // info_struct := cast(*Type_Info_Struct) it.type; + // generate_member_serialization(info_struct, builder, new_path); + //} + //case .BOOL; #through; + //case .FLOAT; #through; + //case .ENUM; #through; + case .INTEGER; { + print_to_builder(builder, "\tui_int_field(tprint(\"%\"), *e.%);\n", new_path, new_path); + } + } + } + } +} + generate_member_serialization :: (type: *Type_Info_Struct, builder: *String_Builder, path: string = "") { for type.members { if should_serialize(type, it) { @@ -159,6 +185,18 @@ generate_member_copy :: (type: *Type_Info_Struct, builder: *String_Builder, path } } +generate_ui_procedure_for_entity :: (code_struct: *Code_Struct) { + name := code_struct.defined_type.name; + + // Serialize + ui : String_Builder; + print_to_builder(*ui, "entity_ui_proc :: (e: *%) {\n", name); + generate_member_ui(code_struct.defined_type, *ui); + print_to_builder(*ui, "}\n"); + + array_add(*entity_serialize_proc_string, builder_to_string(*ui)); +} + generate_serialize_procedure_for_entity :: (code_struct: *Code_Struct) { name := code_struct.defined_type.name; @@ -213,6 +251,7 @@ note_struct :: (code_struct: *Code_Struct) { print("Detected entity '%'.\n", name); generate_serialize_procedure_for_entity(code_struct); + generate_ui_procedure_for_entity(code_struct); } } } @@ -356,6 +395,17 @@ generate_code :: (w: Workspace) { add_build_string(build_string, w); } + { + builder: String_Builder; + + for entity_type_names { + print_to_builder(*builder, "\tcase %1; entity_ui_proc(cast(*%1)e);\n", it); + } + + build_string := sprint(ENTITY_UI, builder_to_string(*builder)); + add_build_string(build_string, w); + } + { builder: String_Builder; @@ -462,6 +512,14 @@ duplicate_entity :: (e: *Entity) -> *Entity { } DONE +ENTITY_UI :: #string DONE +entity_ui :: (e: *Entity) { + if e.type == { + %1 + } +} +DONE + INIT_SCENE :: #string DONE init_scene :: (scene: *Scene) { %1 diff --git a/ui/widgets.jai b/ui/widgets.jai index c606b07..e9fc8aa 100644 --- a/ui/widgets.jai +++ b/ui/widgets.jai @@ -184,6 +184,107 @@ ui_textfield :: (label: string, text: *string, identifier: s64 = 0, loc := #call ui_pop_parent(); } +ui_int_field :: (label: string, value: *int, identifier: s64 = 0, loc := #caller_location) { + ui_container_layout(identifier=identifier, loc=loc); + ui_set_next_size_x(.CHILDREN_SUM); + ui_push_parent(ui_state.last_box, .LEFT, .HORIZONTAL); + { + ui_label(label); + + text_size := get_text_size(engine.renderer, tprint("%", < 0 { + text_widget._number_text.count -= 1; + } + + if key_down(.RETURN) { + // FORMAT IT BACK! + temp_str : string; + temp_str.data = text_widget._number_text.data.data; + temp_str.count = text_widget._number_text.count; + < Date: Sun, 1 Dec 2024 17:55:08 +0100 Subject: [PATCH 2/2] Improvements --- core/entity.jai | 6 +++++- core/scene.jai | 7 +++++++ metaprogram.jai | 29 +++++++++++++++++++++++------ module.jai | 6 ++++++ physics/physics.jai | 33 ++++++++++++++++++++------------- ui/widgets.jai | 12 ++++++++++++ 6 files changed, 73 insertions(+), 20 deletions(-) diff --git a/core/entity.jai b/core/entity.jai index 5efad39..06baa36 100644 --- a/core/entity.jai +++ b/core/entity.jai @@ -79,7 +79,7 @@ Entity :: struct { // Physics body : Physics_Body; @DontSerialize - collider : Collider; @DontSerialize + collider : Collider; // End physics #if NETWORKING { @@ -174,6 +174,10 @@ mark_entity_deleted :: (e: *Entity) { } destroy_entity :: (e: *Entity) { + if e.collider.mesh.vertices.data != null { + array_free(e.collider.mesh.vertices); + } + for 0..e.renderable.num_nodes-1 { node_data := e.renderable.nodes[it]; diff --git a/core/scene.jai b/core/scene.jai index b0124c3..639711e 100644 --- a/core/scene.jai +++ b/core/scene.jai @@ -124,6 +124,13 @@ unload_scene :: (scene: *Scene) { free(scene); } +switch_to_scene :: (scene_name: string) { + new_scene := load_scene(scene_name); + unload_scene(engine.current_scene); + + engine.current_scene = new_scene; +} + reload_scene :: (scene: *Scene) { name := copy_temporary_string(scene.name); unload_scene(engine.current_scene); diff --git a/metaprogram.jai b/metaprogram.jai index 3033283..9189573 100644 --- a/metaprogram.jai +++ b/metaprogram.jai @@ -92,12 +92,22 @@ generate_member_ui :: (type: *Type_Info_Struct, builder: *String_Builder, path: } if it.type.type == { - //case .STRUCT; { - // info_struct := cast(*Type_Info_Struct) it.type; - // generate_member_serialization(info_struct, builder, new_path); - //} + case .STRUCT; { + info_struct := cast(*Type_Info_Struct) it.type; + if info_struct.name == "Vector3" { + print_to_builder(builder, "\tui_vector_field(tprint(\"%\"), *e.%);\n", new_path, new_path); + } else { + generate_member_ui(info_struct, builder, new_path); + } + } //case .BOOL; #through; - //case .FLOAT; #through; + case .STRING; { + print_to_builder(builder, "\tui_textfield(tprint(\"%\"), *e.%);\n", new_path, new_path); + //ui_textfield :: (label: string, text: *string, identifier: s64 = 0, loc := #caller_location) { + } + case .FLOAT; { + print_to_builder(builder, "\tui_float_field(tprint(\"%\"), *e.%);\n", new_path, new_path); + } //case .ENUM; #through; case .INTEGER; { print_to_builder(builder, "\tui_int_field(tprint(\"%\"), *e.%);\n", new_path, new_path); @@ -122,6 +132,9 @@ generate_member_serialization :: (type: *Type_Info_Struct, builder: *String_Buil info_struct := cast(*Type_Info_Struct) it.type; generate_member_serialization(info_struct, builder, new_path); } + case .STRING; { + print_to_builder(builder, "\tprint_to_builder(builder, \"%: \%\\n\", e.%);\n", new_path, new_path); + } case .BOOL; #through; case .FLOAT; #through; case .ENUM; #through; @@ -147,6 +160,10 @@ generate_member_deserialization :: (type: *Type_Info_Struct, builder: *String_Bu info_struct := cast(*Type_Info_Struct) it.type; generate_member_deserialization(info_struct, builder, new_path); } + case .STRING; { + print_to_builder(builder, "\t\t\t\tcase \"%\";\n", new_path); + print_to_builder(builder, "\t\t\t\tif values[1].count > 0 { e.%1 = copy_string(trim(values[1])); }\n", new_path); + } case .BOOL; #through; case .FLOAT; #through; case .ENUM; #through; @@ -428,7 +445,7 @@ generate_code :: (w: Workspace) { add_build_string(build_string, w); // We'll print out the added code just to show at compile-time what we are doing: - print("Adding build string:\n%\n", build_string); + //print("Adding build string:\n%\n", build_string); } generated_code := false; diff --git a/module.jai b/module.jai index b253eaa..cdf7050 100644 --- a/module.jai +++ b/module.jai @@ -36,6 +36,8 @@ Engine_Core :: struct { procs: struct { on_scene_loaded: (*Scene, Engine_Mode); on_pre_scene_loaded: (*Scene, Engine_Mode); + on_trigger_enter: (*Entity, *Entity); + on_trigger_exit: (*Entity, *Entity); } paused: bool; @@ -115,6 +117,10 @@ coven_run :: (game_update_proc: (float), game_update_post_physics_proc: (float)) update_physics(engine.current_scene, clamped_dt); game_update_post_physics_proc(clamped_dt); } + } else { + if engine.current_scene != null { + update_trigger_mesh_colliders(engine.current_scene); + } } if engine.current_scene != null { diff --git a/physics/physics.jai b/physics/physics.jai index 2b17aef..76cc2b2 100644 --- a/physics/physics.jai +++ b/physics/physics.jai @@ -26,9 +26,6 @@ Trigger_Overlap :: struct { MAX_TRIGGER_OVERLAPS :: 16; -on_trigger_enter_callback : (*Entity, *Entity); -on_trigger_exit_callback : (*Entity, *Entity); - Collision_Layers :: enum_flags { NONE; @@ -52,17 +49,17 @@ Collider :: struct { layer: Collision_Layers = .LAYER1; collides_with_layers: Collision_Layers = .LAYER1; - aabb: AABB; override_aabb: bool; + aabb: AABB; union { - sphere: Sphere; - mesh : Mesh_Collider; + sphere: Sphere; @DontSerialize + mesh : Mesh_Collider; @DontSerialize } - overlaps: [MAX_TRIGGER_OVERLAPS] Trigger_Overlap; - num_overlaps: s64; + overlaps: [MAX_TRIGGER_OVERLAPS] Trigger_Overlap; @DontSerialize + num_overlaps: s64; @DontSerialize - ignore: bool; + ignore: bool; @DontSerialize } Physics_Body :: struct { @@ -95,6 +92,16 @@ update_mesh_collider :: (e: *Entity) { e.collider.mesh.is_baked = true; } +update_trigger_mesh_colliders :: (scene: *Scene) { + for e: scene.entities { + if e.flags & .TRIGGER { + if e.collider.type == .MESH { + update_mesh_collider(e); + } + } + } +} + update_mesh_colliders :: (scene: *Scene) { for e: scene.entities { if e.flags & .COLLISION { @@ -187,8 +194,8 @@ add_trigger_overlap_if_new :: (triggered_entity: *Entity, triggered_by_entity: * } } - if on_trigger_enter_callback != null { - on_trigger_enter_callback(triggered_entity, triggered_by_entity); + if engine.procs.on_trigger_enter != null { + engine.procs.on_trigger_enter(triggered_entity, triggered_by_entity); } triggered_entity.collider.overlaps[triggered_entity.collider.num_overlaps] = .{ triggered_by_entity, frame_index }; @@ -288,8 +295,8 @@ update_physics :: (scene: *Scene, dt: float) { defer index += 1; if e.collider.overlaps[index].frame_index < frame_index { - if on_trigger_exit_callback != null { - on_trigger_exit_callback(e, e.collider.overlaps[index].entity); + if engine.procs.on_trigger_exit != null { + engine.procs.on_trigger_exit(e, e.collider.overlaps[index].entity); } if e.collider.num_overlaps > 1 { diff --git a/ui/widgets.jai b/ui/widgets.jai index e9fc8aa..a1e1031 100644 --- a/ui/widgets.jai +++ b/ui/widgets.jai @@ -285,6 +285,17 @@ ui_int_field :: (label: string, value: *int, identifier: s64 = 0, loc := #caller ui_set_next_size_x(.CHILDREN_SUM, 1); } +ui_float_field :: (label: string, value: *float, identifier: s64 = 0, loc := #caller_location) { + ui_container_layout(identifier=identifier, loc=loc); + ui_set_next_size_x(.CHILDREN_SUM); + ui_push_parent(ui_state.last_box, .LEFT, .HORIZONTAL); + { + ui_label(label); + ui_float_field(value, identifier); + } + ui_pop_parent(); +} + ui_float_field :: (value: *float, identifier: s64 = 0, loc := #caller_location) { ui_set_next_background_color(.{0.0,1.0,1.0,0.0}); ui_set_next_border_color(.{0.3,0.3,0.3,1.0}); @@ -350,6 +361,7 @@ ui_float_field :: (value: *float, identifier: s64 = 0, loc := #caller_location) case "7";#through; case "8";#through; case "9";#through; + case "-";#through; case "."; { if !(text_str == "." && (array_contains(text_widget._number_text, #char ".") || text_widget._number_text.count == 0)) { text_widget._number_text.data[text_widget._number_text.count] = text_str[0];