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;
|
||||
|
||||
editor_shows_water :: () -> bool {
|
||||
return current_editor_view == .Level_Editor;
|
||||
}
|
||||
|
||||
init_editor :: () {
|
||||
#if !FLAG_RELEASE_BUILD {
|
||||
#if OS != .WASM {
|
||||
|
||||
@ -65,8 +65,15 @@ Key_Combo :: struct {
|
||||
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?
|
||||
keys : [5000]Key_Combo;
|
||||
keys : [5000]Action_Bindings;
|
||||
|
||||
check_action :: (action: $T, status: Key_Current_State) -> bool {
|
||||
offset := 0;
|
||||
@ -75,12 +82,16 @@ check_action :: (action: $T, status: Key_Current_State) -> bool {
|
||||
}
|
||||
if console_open_ignore_input 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);
|
||||
shift_down := cast(bool)(input_button_states[Key_Code.SHIFT] & .DOWN);
|
||||
if combo.ctrl != ctrl_down then return false;
|
||||
if combo.shift != shift_down then return false;
|
||||
return cast(bool)(input_button_states[combo.key] & status);
|
||||
for 0..bindings.count-1 {
|
||||
combo := bindings.combos[it];
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -116,7 +137,7 @@ get_action_combo :: (action: $T) -> Key_Combo {
|
||||
#if T != Editor_Action {
|
||||
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 {
|
||||
|
||||
@ -112,9 +112,12 @@ add_particle_render_tasks :: () {
|
||||
batches : [..] Batch;
|
||||
batches.allocator = temp;
|
||||
|
||||
has_water, water_y := particle_water_height();
|
||||
|
||||
for *p: g_particles {
|
||||
if !p.alive then continue;
|
||||
if p.definition == null then continue;
|
||||
if has_water && p.position.y < water_y then continue;
|
||||
def := p.definition;
|
||||
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 {
|
||||
for *def: g_emitter_defs {
|
||||
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) {
|
||||
for *p: g_particles {
|
||||
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 {
|
||||
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_h = h;
|
||||
plane_data.cameraPosition = camera.position.component;
|
||||
plane_data.reflectionDistortion = 0.1;
|
||||
plane_data.reflectionDistortion = wc.waterDistortion;
|
||||
plane_data.shininess = wc.waterShininess;
|
||||
|
||||
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 deepColor;
|
||||
float time;
|
||||
float waterReflectivity;
|
||||
};
|
||||
|
||||
layout(binding=2) uniform plane_data {
|
||||
@ -136,12 +137,12 @@ void main() {
|
||||
|
||||
vec2 screen_uv = gl_FragCoord.xy / vec2(screen_w, screen_h);
|
||||
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 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;
|
||||
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);
|
||||
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 {
|
||||
if it.flags & .CONSTANT continue;
|
||||
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;
|
||||
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.
|
||||
}
|
||||
|
||||
// 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 {
|
||||
coord: Chunk_Key;
|
||||
groups: [..]Chunk_Trile_Group;
|
||||
@ -524,6 +554,8 @@ World_Json_Config :: struct {
|
||||
waterColor : [3]float;
|
||||
deepColor : [3]float;
|
||||
waterShininess : float;
|
||||
waterReflectivity : float = 0.0;
|
||||
waterDistortion : float = 0.007;
|
||||
}
|
||||
|
||||
World_Json_Chunk :: struct {
|
||||
@ -685,6 +717,8 @@ world_config_to_json :: (conf: *World_Config) -> World_Json_Config {
|
||||
jc.waterColor = conf.waterColor.component;
|
||||
jc.deepColor = conf.deepColor.component;
|
||||
jc.waterShininess = conf.waterShininess;
|
||||
jc.waterReflectivity = conf.waterReflectivity;
|
||||
jc.waterDistortion = conf.waterDistortion;
|
||||
return jc;
|
||||
}
|
||||
|
||||
@ -705,6 +739,8 @@ world_config_from_json :: (jc: *World_Json_Config) -> World_Config {
|
||||
conf.waterColor.component = jc.waterColor;
|
||||
conf.deepColor.component = jc.deepColor;
|
||||
conf.waterShininess = ifx jc.waterShininess > 0 then jc.waterShininess else 64.0;
|
||||
conf.waterReflectivity = jc.waterReflectivity;
|
||||
conf.waterDistortion = jc.waterDistortion;
|
||||
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);
|
||||
array_add(*group.instances, inst);
|
||||
}
|
||||
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;
|
||||
recompute_group_bounds(*group);
|
||||
array_add(*chunk.groups, group);
|
||||
}
|
||||
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.
|
||||
deepColor : Vector3 = .{1.0, 1.0, 1.0}; @Color // @ToDo: sensible default values.
|
||||
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
|
||||
|
||||
// ambientColor : Vector3 = .{1.0, 1.0, 1.0}; @Color
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user