UI: Added widget focus for regular input blocking | Physics: Trigger callbacks
This commit is contained in:
@@ -27,3 +27,7 @@ array_contains :: (static_array: Static_Array, value: static_array.Data_Type) ->
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
operator [] :: (static_array: Static_Array, index: int) -> static_array.Data_Type {
|
||||
return static_array.data[index];
|
||||
}
|
||||
@@ -61,6 +61,8 @@ Transform_Gizmo :: struct {
|
||||
}
|
||||
|
||||
Editor :: struct {
|
||||
focused_widget: *UI_Box;
|
||||
|
||||
show_menu: bool;
|
||||
should_check_entities: bool;
|
||||
camera: Camera;
|
||||
|
||||
@@ -251,6 +251,7 @@ base_editor_update :: () {
|
||||
|
||||
camera := *engine.editor.camera;
|
||||
|
||||
if engine.editor.focused_widget == null {
|
||||
if key_pressed(.CTRL) && key_down(.S) {
|
||||
save_scene(engine.current_scene, "../assets/scenes/");
|
||||
//show_message("Saved scene");
|
||||
@@ -263,6 +264,7 @@ base_editor_update :: () {
|
||||
|
||||
engine.editor.selected_entities.count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//if entity != null {
|
||||
// // @Incomplete:@Incomplete: Duplicate
|
||||
|
||||
@@ -36,6 +36,8 @@ Engine_Core :: struct {
|
||||
procs: struct {
|
||||
on_scene_loaded: (*Scene, Engine_Mode);
|
||||
}
|
||||
|
||||
paused: bool;
|
||||
}
|
||||
|
||||
engine: Engine_Core;
|
||||
@@ -106,7 +108,7 @@ coven_run :: (game_update_proc: (float), game_update_post_physics_proc: (float))
|
||||
if engine.mode == .PLAYING {
|
||||
game_update_proc(clamped_dt);
|
||||
|
||||
if engine.current_scene != null {
|
||||
if engine.current_scene != null && !engine.paused {
|
||||
update_animators(clamped_dt);
|
||||
update_physics(engine.current_scene, clamped_dt);
|
||||
game_update_post_physics_proc(clamped_dt);
|
||||
@@ -117,8 +119,10 @@ coven_run :: (game_update_proc: (float), game_update_post_physics_proc: (float))
|
||||
update_transforms();
|
||||
sync_engine_buffers();
|
||||
|
||||
if !engine.paused {
|
||||
update_particle_systems(clamped_dt);
|
||||
}
|
||||
}
|
||||
|
||||
#if EDITOR {
|
||||
ui_end();
|
||||
|
||||
@@ -76,9 +76,10 @@ nearly_equal :: (a: float, b: float) -> bool {
|
||||
return abs(a - b) < 0.00001;
|
||||
}
|
||||
|
||||
polytope : [..] Vector3;
|
||||
|
||||
epa :: (simplex: Simplex, collider_a: Collider, collider_b: Collider) -> Collision_Point {
|
||||
polytope : [..] Vector3;
|
||||
polytope.allocator = temp;
|
||||
polytope.count = 0;
|
||||
|
||||
array_reserve(*polytope, simplex.size);
|
||||
for simplex.points {
|
||||
|
||||
@@ -26,6 +26,9 @@ Trigger_Overlap :: struct {
|
||||
|
||||
MAX_TRIGGER_OVERLAPS :: 16;
|
||||
|
||||
on_trigger_enter_callback : (*Entity, *Entity);
|
||||
on_trigger_exit_callback : (*Entity, *Entity);
|
||||
|
||||
Collision_Layers :: enum_flags {
|
||||
NONE;
|
||||
|
||||
@@ -63,6 +66,7 @@ Collider :: struct {
|
||||
}
|
||||
|
||||
Physics_Body :: struct {
|
||||
enabled: bool = true;
|
||||
velocity: Vector3;
|
||||
|
||||
friction : float = 0.0;
|
||||
@@ -134,6 +138,7 @@ make_sure_nothing_collides :: (scene: *Scene) {
|
||||
update_gravity :: (scene: *Scene, dt: float) {
|
||||
for e: scene.entities {
|
||||
if !e.enabled continue;
|
||||
if !e.body.enabled continue;
|
||||
|
||||
if e.flags & .PHYSICS {
|
||||
#if NETWORKING { if e.is_proxy continue; }
|
||||
@@ -147,6 +152,7 @@ update_gravity :: (scene: *Scene, dt: float) {
|
||||
update_positions :: (scene: *Scene, dt: float) {
|
||||
for e: scene.entities {
|
||||
if !e.enabled continue;
|
||||
if !e.body.enabled continue;
|
||||
|
||||
#if NETWORKING { if e.is_proxy continue; }
|
||||
|
||||
@@ -172,18 +178,21 @@ update_positions :: (scene: *Scene, dt: float) {
|
||||
}
|
||||
}
|
||||
|
||||
add_trigger_overlap_if_new :: (e: *Entity, other_e: *Entity) {
|
||||
for 0..e.collider.num_overlaps-1 {
|
||||
overlap := *e.collider.overlaps[it];
|
||||
if overlap.entity == other_e {
|
||||
add_trigger_overlap_if_new :: (triggered_entity: *Entity, triggered_by_entity: *Entity) {
|
||||
for 0..triggered_entity.collider.num_overlaps-1 {
|
||||
overlap := *triggered_entity.collider.overlaps[it];
|
||||
if overlap.entity == triggered_by_entity {
|
||||
overlap.frame_index = frame_index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
on_trigger_enter(e, other_e);
|
||||
e.collider.overlaps[e.collider.num_overlaps] = .{ other_e, frame_index };
|
||||
e.collider.num_overlaps += 1;
|
||||
if on_trigger_enter_callback != null {
|
||||
on_trigger_enter_callback(triggered_entity, triggered_by_entity);
|
||||
}
|
||||
|
||||
triggered_entity.collider.overlaps[triggered_entity.collider.num_overlaps] = .{ triggered_by_entity, frame_index };
|
||||
triggered_entity.collider.num_overlaps += 1;
|
||||
}
|
||||
|
||||
can_collide :: (e: *Entity, other: *Entity) -> bool {
|
||||
@@ -196,6 +205,7 @@ physics_step :: (scene: *Scene, timestep: float) {
|
||||
|
||||
for e: scene.entities {
|
||||
if !e.enabled continue;
|
||||
if !e.body.enabled continue;
|
||||
#if NETWORKING { if e.is_proxy continue;}
|
||||
if e.collider.ignore continue;
|
||||
|
||||
@@ -203,6 +213,8 @@ physics_step :: (scene: *Scene, timestep: float) {
|
||||
for other_e: scene.entities {
|
||||
if e == other_e continue;
|
||||
if other_e.collider.ignore continue;
|
||||
if !other_e.enabled continue;
|
||||
if !other_e.body.enabled continue;
|
||||
if !can_collide(e, other_e) continue;
|
||||
|
||||
if other_e.flags & .COLLISION {
|
||||
@@ -211,7 +223,7 @@ physics_step :: (scene: *Scene, timestep: float) {
|
||||
if point.has_collision {
|
||||
if other_e.flags & .TRIGGER {
|
||||
// TRIGGER CALLBACK
|
||||
add_trigger_overlap_if_new(e, other_e);
|
||||
add_trigger_overlap_if_new(other_e, e);
|
||||
} else {
|
||||
n := -point.normal;
|
||||
speed_along_normal := dot(e.body.velocity, n);
|
||||
@@ -241,18 +253,6 @@ physics_step :: (scene: *Scene, timestep: float) {
|
||||
}
|
||||
}
|
||||
|
||||
on_trigger_enter :: (e: *Entity, other_e: *Entity) {
|
||||
//if (e.type == Player || e.type == Npc) && other_e.type == Door {
|
||||
// other_e.enabled = false;
|
||||
//}
|
||||
}
|
||||
|
||||
on_trigger_exit :: (e: *Entity, other_e: *Entity) {
|
||||
//if other_e.type == Door {
|
||||
// other_e.enabled = true;
|
||||
//}
|
||||
}
|
||||
|
||||
update_physics :: (scene: *Scene, dt: float) {
|
||||
for scene.entities {
|
||||
if it.collider.type == .MESH {
|
||||
@@ -284,7 +284,9 @@ update_physics :: (scene: *Scene, dt: float) {
|
||||
defer index += 1;
|
||||
|
||||
if e.collider.overlaps[index].frame_index < frame_index {
|
||||
on_trigger_exit(e, e.collider.overlaps[index].entity);
|
||||
if on_trigger_exit_callback != null {
|
||||
on_trigger_exit_callback(e, e.collider.overlaps[index].entity);
|
||||
}
|
||||
|
||||
if e.collider.num_overlaps > 1 {
|
||||
e.collider.overlaps[index] = e.collider.overlaps[e.collider.num_overlaps-1];
|
||||
|
||||
@@ -7,13 +7,14 @@ ui_full_size_background :: (color: Color = .{0,0,0,1}, identifier: s64 = 0, loc
|
||||
background := ui_box_make(.DRAW_BACKGROUND, hash=get_hash(loc, identifier));
|
||||
}
|
||||
|
||||
ui_container_layout :: (color: Color = .{0,0,0,0}, identifier: s64 = 0, loc := #caller_location) {
|
||||
ui_container_layout :: (color: Color = .{0,0,0,0}, identifier: s64 = 0, loc := #caller_location) -> *UI_Box {
|
||||
ui_set_next_size_x(.CHILDREN_SUM);
|
||||
ui_set_next_size_y(.CHILDREN_SUM);
|
||||
|
||||
ui_set_next_background_color(color);
|
||||
|
||||
container := ui_box_make(.DRAW_BACKGROUND, hash=get_hash(loc, identifier));
|
||||
return container;
|
||||
}
|
||||
|
||||
ui_button :: (text: string, identifier: s64 = 0, loc := #caller_location) -> clicked: bool, Interaction_State {
|
||||
@@ -109,7 +110,7 @@ ui_label_fill_parent_x :: (text: string, identifier: s64 = 0, loc := #caller_loc
|
||||
}
|
||||
|
||||
ui_textfield :: (label: string, text: *string, identifier: s64 = 0, loc := #caller_location) {
|
||||
ui_container_layout();
|
||||
container := ui_container_layout();
|
||||
ui_push_parent(ui_state.last_box, .LEFT, .HORIZONTAL);
|
||||
{
|
||||
ui_label(label);
|
||||
@@ -143,6 +144,12 @@ ui_textfield :: (label: string, text: *string, identifier: s64 = 0, loc := #call
|
||||
|
||||
if outer.interaction.clicked {
|
||||
outer.interaction.editing = true;
|
||||
|
||||
if engine.editor.focused_widget != null {
|
||||
engine.editor.focused_widget.interaction.editing = false;
|
||||
}
|
||||
|
||||
engine.editor.focused_widget = container;
|
||||
}
|
||||
|
||||
if outer.interaction.editing {
|
||||
@@ -154,6 +161,7 @@ ui_textfield :: (label: string, text: *string, identifier: s64 = 0, loc := #call
|
||||
|
||||
if key_down(.RETURN) {
|
||||
outer.interaction.editing = false;
|
||||
engine.editor.focused_widget = null;
|
||||
}
|
||||
|
||||
if engine.input.has_char {
|
||||
@@ -223,6 +231,7 @@ ui_float_field :: (value: *float, identifier: s64 = 0, loc := #caller_location)
|
||||
temp_str.count = text_widget._number_text.count;
|
||||
<<value = parse_float(*temp_str);
|
||||
outer.interaction.editing = false;
|
||||
engine.editor.focused_widget = null;
|
||||
}
|
||||
|
||||
if engine.input.has_char {
|
||||
@@ -254,7 +263,12 @@ ui_float_field :: (value: *float, identifier: s64 = 0, loc := #caller_location)
|
||||
}
|
||||
|
||||
if outer.interaction.clicked {
|
||||
if engine.editor.focused_widget != null {
|
||||
engine.editor.focused_widget.interaction.editing = false;
|
||||
}
|
||||
|
||||
outer.interaction.editing = true;
|
||||
engine.editor.focused_widget = outer;
|
||||
formatted_text := copy_temporary_string(tprint("%", formatFloat(<<value, trailing_width = 2, zero_removal=.NO)));
|
||||
memcpy(text_widget._number_text.data.data, formatted_text.data, formatted_text.count);
|
||||
text_widget._number_text.count = formatted_text.count;
|
||||
|
||||
Reference in New Issue
Block a user