world fixes and water improvements
This commit is contained in:
parent
279b7ca81d
commit
0d44c75fa9
@ -26,6 +26,10 @@ current_editor_view : Editor_View = .Trile_Editor;
|
|||||||
|
|
||||||
in_editor_view : bool = false;
|
in_editor_view : bool = false;
|
||||||
|
|
||||||
|
editor_shows_water :: () -> bool {
|
||||||
|
return current_editor_view == .Level_Editor;
|
||||||
|
}
|
||||||
|
|
||||||
init_editor :: () {
|
init_editor :: () {
|
||||||
#if !FLAG_RELEASE_BUILD {
|
#if !FLAG_RELEASE_BUILD {
|
||||||
#if OS != .WASM {
|
#if OS != .WASM {
|
||||||
|
|||||||
@ -65,8 +65,15 @@ Key_Combo :: struct {
|
|||||||
shift : bool;
|
shift : bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MAX_BINDINGS_PER_ACTION :: 4;
|
||||||
|
|
||||||
|
Action_Bindings :: struct {
|
||||||
|
combos : [MAX_BINDINGS_PER_ACTION]Key_Combo;
|
||||||
|
count : s32;
|
||||||
|
}
|
||||||
|
|
||||||
// 5000 different actions ought to be enough for anything right?
|
// 5000 different actions ought to be enough for anything right?
|
||||||
keys : [5000]Key_Combo;
|
keys : [5000]Action_Bindings;
|
||||||
|
|
||||||
check_action :: (action: $T, status: Key_Current_State) -> bool {
|
check_action :: (action: $T, status: Key_Current_State) -> bool {
|
||||||
offset := 0;
|
offset := 0;
|
||||||
@ -75,12 +82,16 @@ check_action :: (action: $T, status: Key_Current_State) -> bool {
|
|||||||
}
|
}
|
||||||
if console_open_ignore_input then return false;
|
if console_open_ignore_input then return false;
|
||||||
if ui_keyboard_captured then return false;
|
if ui_keyboard_captured then return false;
|
||||||
combo := keys[cast(s32)action + offset];
|
bindings := *keys[cast(s32)action + offset];
|
||||||
ctrl_down := cast(bool)(input_button_states[Key_Code.CTRL] & .DOWN);
|
ctrl_down := cast(bool)(input_button_states[Key_Code.CTRL] & .DOWN);
|
||||||
shift_down := cast(bool)(input_button_states[Key_Code.SHIFT] & .DOWN);
|
shift_down := cast(bool)(input_button_states[Key_Code.SHIFT] & .DOWN);
|
||||||
if combo.ctrl != ctrl_down then return false;
|
for 0..bindings.count-1 {
|
||||||
if combo.shift != shift_down then return false;
|
combo := bindings.combos[it];
|
||||||
return cast(bool)(input_button_states[combo.key] & status);
|
if combo.ctrl != ctrl_down then continue;
|
||||||
|
if combo.shift != shift_down then continue;
|
||||||
|
if input_button_states[combo.key] & status then return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,7 +103,17 @@ set_binding :: (action: $T, combo: Key_Combo) {
|
|||||||
offset = EDITOR_ACTION_COUNT;
|
offset = EDITOR_ACTION_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys[cast(s32)action + offset] = combo;
|
bindings := *keys[cast(s32)action + offset];
|
||||||
|
for 0..bindings.count-1 {
|
||||||
|
c := bindings.combos[it];
|
||||||
|
if c.key == combo.key && c.ctrl == combo.ctrl && c.shift == combo.shift return;
|
||||||
|
}
|
||||||
|
if bindings.count >= MAX_BINDINGS_PER_ACTION {
|
||||||
|
log_warn("Action % already has % bindings, ignoring %", action, MAX_BINDINGS_PER_ACTION, combo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bindings.combos[bindings.count] = combo;
|
||||||
|
bindings.count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_action_down :: (action: $T) -> bool {
|
is_action_down :: (action: $T) -> bool {
|
||||||
@ -116,7 +137,7 @@ get_action_combo :: (action: $T) -> Key_Combo {
|
|||||||
#if T != Editor_Action {
|
#if T != Editor_Action {
|
||||||
offset = EDITOR_ACTION_COUNT;
|
offset = EDITOR_ACTION_COUNT;
|
||||||
}
|
}
|
||||||
return keys[cast(s32)action + offset];
|
return keys[cast(s32)action + offset].combos[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
keybind_button :: (r: GR.Rect, label: string, action: Editor_Action, theme: *GR.Button_Theme, loc := #caller_location) -> bool {
|
keybind_button :: (r: GR.Rect, label: string, action: Editor_Action, theme: *GR.Button_Theme, loc := #caller_location) -> bool {
|
||||||
|
|||||||
@ -112,9 +112,12 @@ add_particle_render_tasks :: () {
|
|||||||
batches : [..] Batch;
|
batches : [..] Batch;
|
||||||
batches.allocator = temp;
|
batches.allocator = temp;
|
||||||
|
|
||||||
|
has_water, water_y := particle_water_height();
|
||||||
|
|
||||||
for *p: g_particles {
|
for *p: g_particles {
|
||||||
if !p.alive then continue;
|
if !p.alive then continue;
|
||||||
if p.definition == null then continue;
|
if p.definition == null then continue;
|
||||||
|
if has_water && p.position.y < water_y then continue;
|
||||||
def := p.definition;
|
def := p.definition;
|
||||||
if def.animation_name.count == 0 then continue;
|
if def.animation_name.count == 0 then continue;
|
||||||
|
|
||||||
@ -194,6 +197,15 @@ add_particle_render_tasks :: () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
particle_water_height :: () -> (has_water: bool, height: float) {
|
||||||
|
#if !FLAG_RELEASE_BUILD {
|
||||||
|
if in_editor_view && !editor_shows_water() return false, 0;
|
||||||
|
}
|
||||||
|
curworld := get_current_world();
|
||||||
|
if !curworld.valid return false, 0;
|
||||||
|
return true, effective_plane_height(*curworld.world.conf);
|
||||||
|
}
|
||||||
|
|
||||||
get_emitter_def :: (name: string) -> *Particle_Emitter_Config {
|
get_emitter_def :: (name: string) -> *Particle_Emitter_Config {
|
||||||
for *def: g_emitter_defs {
|
for *def: g_emitter_defs {
|
||||||
if def.name == name then return def;
|
if def.name == name then return def;
|
||||||
@ -238,14 +250,6 @@ save_particle_defs :: () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#scope_file
|
|
||||||
|
|
||||||
Random :: #import "Random";
|
|
||||||
|
|
||||||
rng :: inline (lo: float, hi: float) -> float {
|
|
||||||
return lo + Random.random_get_zero_to_one() * (hi - lo);
|
|
||||||
}
|
|
||||||
|
|
||||||
spawn_one_particle :: (position: Vector3, def: *Particle_Emitter_Config) {
|
spawn_one_particle :: (position: Vector3, def: *Particle_Emitter_Config) {
|
||||||
for *p: g_particles {
|
for *p: g_particles {
|
||||||
if p.alive then continue;
|
if p.alive then continue;
|
||||||
@ -268,6 +272,14 @@ spawn_one_particle :: (position: Vector3, def: *Particle_Emitter_Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#scope_file
|
||||||
|
|
||||||
|
Random :: #import "Random";
|
||||||
|
|
||||||
|
rng :: inline (lo: float, hi: float) -> float {
|
||||||
|
return lo + Random.random_get_zero_to_one() * (hi - lo);
|
||||||
|
}
|
||||||
|
|
||||||
lerp_color :: (a: Vector4, b: Vector4, t: float) -> Vector4 {
|
lerp_color :: (a: Vector4, b: Vector4, t: float) -> Vector4 {
|
||||||
return a * (1.0 - t) + b * t;
|
return a * (1.0 - t) + b * t;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -468,7 +468,7 @@ backend_draw_ground :: (wc: *World_Config) {
|
|||||||
plane_data.screen_w = w;
|
plane_data.screen_w = w;
|
||||||
plane_data.screen_h = h;
|
plane_data.screen_h = h;
|
||||||
plane_data.cameraPosition = camera.position.component;
|
plane_data.cameraPosition = camera.position.component;
|
||||||
plane_data.reflectionDistortion = 0.1;
|
plane_data.reflectionDistortion = wc.waterDistortion;
|
||||||
plane_data.shininess = wc.waterShininess;
|
plane_data.shininess = wc.waterShininess;
|
||||||
|
|
||||||
world_config_to_shader_type(wc, *world_conf);
|
world_config_to_shader_type(wc, *world_conf);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -45,6 +45,7 @@ layout(binding=1) uniform plane_world_config {
|
|||||||
vec3 waterColor;
|
vec3 waterColor;
|
||||||
vec3 deepColor;
|
vec3 deepColor;
|
||||||
float time;
|
float time;
|
||||||
|
float waterReflectivity;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(binding=2) uniform plane_data {
|
layout(binding=2) uniform plane_data {
|
||||||
@ -136,12 +137,12 @@ void main() {
|
|||||||
|
|
||||||
vec2 screen_uv = gl_FragCoord.xy / vec2(screen_w, screen_h);
|
vec2 screen_uv = gl_FragCoord.xy / vec2(screen_w, screen_h);
|
||||||
screen_uv.y = 1.0 - screen_uv.y;
|
screen_uv.y = 1.0 - screen_uv.y;
|
||||||
vec2 distortion = normal.xz * 0.007;
|
vec2 distortion = normal.xz * reflectionDistortion;
|
||||||
vec3 reflected_color = texture(sampler2D(reftex, refsmp), screen_uv + distortion).rgb;
|
vec3 reflected_color = texture(sampler2D(reftex, refsmp), screen_uv + distortion).rgb;
|
||||||
|
|
||||||
vec3 surface_color = mix(refracted_color, reflected_color, fresnel);
|
vec3 surface_color = mix(refracted_color, reflected_color, mix(fresnel, 1.0, waterReflectivity));
|
||||||
vec3 final_color = surface_color + specular_highlight;
|
vec3 final_color = surface_color + specular_highlight;
|
||||||
float alpha = mix(0.3, 0.5, fresnel);
|
float alpha = mix(mix(0.3, 0.5, fresnel), 1.0, waterReflectivity);
|
||||||
|
|
||||||
vec3 fog = skyIntensity * sky(normalize(pos.xyz), sunPosition);
|
vec3 fog = skyIntensity * sky(normalize(pos.xyz), sunPosition);
|
||||||
float fogFactor = smoothstep(750.0, 1000.0, length(pos.xz));
|
float fogFactor = smoothstep(750.0, 1000.0, length(pos.xz));
|
||||||
|
|||||||
@ -149,6 +149,7 @@ autoedit :: (rect: GR.Rect, value: *$T, theme: *GR.Overall_Theme, identifier: s3
|
|||||||
for ti.members {
|
for ti.members {
|
||||||
if it.flags & .CONSTANT continue;
|
if it.flags & .CONSTANT continue;
|
||||||
if it.flags & .USING continue; // e.g. an entity's Entity base
|
if it.flags & .USING continue; // e.g. an entity's Entity base
|
||||||
|
if array_find(it.notes, "NoSave") continue; // runtime state, not for editing
|
||||||
if !autoedit_supports_type(it.type) continue;
|
if !autoedit_supports_type(it.type) continue;
|
||||||
print_to_builder(*builder, "%\n", input_code_from_type_and_notes(it.name, it.type, it.notes, it_index));
|
print_to_builder(*builder, "%\n", input_code_from_type_and_notes(it.name, it.type, it.notes, it_index));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,36 @@ Chunk_Trile_Group :: struct {
|
|||||||
is_buried : [..]bool; // Runtime-only, parallel to instances. Not serialized.
|
is_buried : [..]bool; // Runtime-only, parallel to instances. Not serialized.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chunk-local, like the instances. Call after changing group.instances.
|
||||||
|
recompute_group_bounds :: (group: *Chunk_Trile_Group) {
|
||||||
|
if group.instances.count == 0 {
|
||||||
|
group.bounding_min = .{};
|
||||||
|
group.bounding_max = .{};
|
||||||
|
group.average_pos = .{};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gmin := Vector3.{31,31,31};
|
||||||
|
gmax := Vector3.{0,0,0};
|
||||||
|
gavg := Vector3.{0,0,0};
|
||||||
|
|
||||||
|
for i : group.instances {
|
||||||
|
gmin.x = min(gmin.x, xx i.x);
|
||||||
|
gmin.y = min(gmin.y, xx i.y);
|
||||||
|
gmin.z = min(gmin.z, xx i.z);
|
||||||
|
gmax.x = max(gmax.x, xx i.x);
|
||||||
|
gmax.y = max(gmax.y, xx i.y);
|
||||||
|
gmax.z = max(gmax.z, xx i.z);
|
||||||
|
|
||||||
|
gavg += Vector3.{xx i.x, xx i.y, xx i.z};
|
||||||
|
}
|
||||||
|
gavg /= cast(float) group.instances.count;
|
||||||
|
|
||||||
|
group.bounding_min = gmin;
|
||||||
|
group.bounding_max = gmax;
|
||||||
|
group.average_pos = gavg;
|
||||||
|
}
|
||||||
|
|
||||||
Chunk :: struct {
|
Chunk :: struct {
|
||||||
coord: Chunk_Key;
|
coord: Chunk_Key;
|
||||||
groups: [..]Chunk_Trile_Group;
|
groups: [..]Chunk_Trile_Group;
|
||||||
@ -524,6 +554,8 @@ World_Json_Config :: struct {
|
|||||||
waterColor : [3]float;
|
waterColor : [3]float;
|
||||||
deepColor : [3]float;
|
deepColor : [3]float;
|
||||||
waterShininess : float;
|
waterShininess : float;
|
||||||
|
waterReflectivity : float = 0.0;
|
||||||
|
waterDistortion : float = 0.007;
|
||||||
}
|
}
|
||||||
|
|
||||||
World_Json_Chunk :: struct {
|
World_Json_Chunk :: struct {
|
||||||
@ -685,6 +717,8 @@ world_config_to_json :: (conf: *World_Config) -> World_Json_Config {
|
|||||||
jc.waterColor = conf.waterColor.component;
|
jc.waterColor = conf.waterColor.component;
|
||||||
jc.deepColor = conf.deepColor.component;
|
jc.deepColor = conf.deepColor.component;
|
||||||
jc.waterShininess = conf.waterShininess;
|
jc.waterShininess = conf.waterShininess;
|
||||||
|
jc.waterReflectivity = conf.waterReflectivity;
|
||||||
|
jc.waterDistortion = conf.waterDistortion;
|
||||||
return jc;
|
return jc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,6 +739,8 @@ world_config_from_json :: (jc: *World_Json_Config) -> World_Config {
|
|||||||
conf.waterColor.component = jc.waterColor;
|
conf.waterColor.component = jc.waterColor;
|
||||||
conf.deepColor.component = jc.deepColor;
|
conf.deepColor.component = jc.deepColor;
|
||||||
conf.waterShininess = ifx jc.waterShininess > 0 then jc.waterShininess else 64.0;
|
conf.waterShininess = ifx jc.waterShininess > 0 then jc.waterShininess else 64.0;
|
||||||
|
conf.waterReflectivity = jc.waterReflectivity;
|
||||||
|
conf.waterDistortion = jc.waterDistortion;
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,25 +873,7 @@ load_world_from_json :: (json_str: string, chunk_bin: []u8) -> (World, bool) {
|
|||||||
inst := read_value(chunk_data, *chunk_cursor, Trile_Instance);
|
inst := read_value(chunk_data, *chunk_cursor, Trile_Instance);
|
||||||
array_add(*group.instances, inst);
|
array_add(*group.instances, inst);
|
||||||
}
|
}
|
||||||
gmin := Vector3.{31,31,31};
|
recompute_group_bounds(*group);
|
||||||
gmax := Vector3.{0,0,0};
|
|
||||||
gavg := Vector3.{0,0,0};
|
|
||||||
|
|
||||||
for i : group.instances {
|
|
||||||
gmin.x = min(gmin.x, xx i.x);
|
|
||||||
gmin.y = min(gmin.y, xx i.y);
|
|
||||||
gmin.z = min(gmin.z, xx i.z);
|
|
||||||
gmax.x = max(gmax.x, xx i.x);
|
|
||||||
gmax.y = max(gmax.y, xx i.y);
|
|
||||||
gmax.z = max(gmax.z, xx i.z);
|
|
||||||
|
|
||||||
gavg += Vector3.{xx i.x, xx i.y, xx i.z};
|
|
||||||
}
|
|
||||||
gavg /= cast(float) group.instances.count;
|
|
||||||
|
|
||||||
group.bounding_min = gmin;
|
|
||||||
group.bounding_max = gmax;
|
|
||||||
group.average_pos = gavg;
|
|
||||||
array_add(*chunk.groups, group);
|
array_add(*chunk.groups, group);
|
||||||
}
|
}
|
||||||
calculate_and_set_chunk_occupancy_mask(*chunk);
|
calculate_and_set_chunk_occupancy_mask(*chunk);
|
||||||
@ -915,6 +933,8 @@ World_Config :: struct {
|
|||||||
waterColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
|
waterColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
|
||||||
deepColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
|
deepColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
|
||||||
waterShininess : float = 64.0; @Slider,1,512,8
|
waterShininess : float = 64.0; @Slider,1,512,8
|
||||||
|
waterReflectivity : float = 0.0; @Slider,0,1,0.05
|
||||||
|
waterDistortion : float = 0.007; @Slider,0,0.05,0.001
|
||||||
hsv_lighting : s32 = 1; @Slider,0,1,1
|
hsv_lighting : s32 = 1; @Slider,0,1,1
|
||||||
|
|
||||||
// ambientColor : Vector3 = .{1.0, 1.0, 1.0}; @Color
|
// ambientColor : Vector3 = .{1.0, 1.0, 1.0}; @Color
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user