mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'door-fixes' into 'master'
Doors now animate opening when entities are near them. See merge request veloren/veloren!3683
This commit is contained in:
commit
aa846ddb31
@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- FxUpscale AA mode for higher quality graphics at reduced internal resolutions
|
- FxUpscale AA mode for higher quality graphics at reduced internal resolutions
|
||||||
- Graphics presets
|
- Graphics presets
|
||||||
- Sword
|
- Sword
|
||||||
|
- Doors now animate opening when entities are near them.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Use fluent for translations
|
- Use fluent for translations
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
#include <sky.glsl>
|
#include <sky.glsl>
|
||||||
|
#include <light.glsl>
|
||||||
|
|
||||||
layout(location = 0) in vec4 inst_mat0;
|
layout(location = 0) in vec4 inst_mat0;
|
||||||
layout(location = 1) in vec4 inst_mat1;
|
layout(location = 1) in vec4 inst_mat1;
|
||||||
@ -22,7 +23,7 @@ layout(location = 2) in vec4 inst_mat2;
|
|||||||
layout(location = 3) in vec4 inst_mat3;
|
layout(location = 3) in vec4 inst_mat3;
|
||||||
// TODO: is there a better way to pack the various vertex attributes?
|
// TODO: is there a better way to pack the various vertex attributes?
|
||||||
// TODO: ori is unused
|
// TODO: ori is unused
|
||||||
layout(location = 4) in uint inst_pos_ori;
|
layout(location = 4) in uint inst_pos_ori_door;
|
||||||
layout(location = 5) in uint inst_vert_page; // NOTE: this could fit in less bits
|
layout(location = 5) in uint inst_vert_page; // NOTE: this could fit in less bits
|
||||||
// TODO: do we need this many bits for light and glow?
|
// TODO: do we need this many bits for light and glow?
|
||||||
layout(location = 6) in float inst_light;
|
layout(location = 6) in float inst_light;
|
||||||
@ -55,6 +56,24 @@ const float EXTRA_NEG_Z = 32768.0;
|
|||||||
const float VERT_EXTRA_NEG_Z = 128.0;
|
const float VERT_EXTRA_NEG_Z = 128.0;
|
||||||
const uint VERT_PAGE_SIZE = 256;
|
const uint VERT_PAGE_SIZE = 256;
|
||||||
|
|
||||||
|
// vec4(vec3(position), distance)
|
||||||
|
vec4 nearest_entity(in vec3 sprite_pos, const float entity_radius_factor) {
|
||||||
|
vec4 closest = vec4(vec3(0), 65536);
|
||||||
|
|
||||||
|
for (uint i = 0u; i < light_shadow_count.y; i ++) {
|
||||||
|
// Only access the array once
|
||||||
|
Shadow S = shadows[i];
|
||||||
|
vec3 shadow_pos = S.shadow_pos_radius.xyz - focus_off.xyz;
|
||||||
|
float dist_sq = dot(sprite_pos - shadow_pos, sprite_pos - shadow_pos)
|
||||||
|
- S.shadow_pos_radius.w * S.shadow_pos_radius.w * entity_radius_factor;
|
||||||
|
if (dist_sq < closest.w) {
|
||||||
|
closest = vec4(shadow_pos, dist_sq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closest.w = sqrt(max(closest.w, 0));
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Matrix to transform this sprite instance from model space to chunk space
|
// Matrix to transform this sprite instance from model space to chunk space
|
||||||
mat4 inst_mat;
|
mat4 inst_mat;
|
||||||
@ -77,6 +96,35 @@ void main() {
|
|||||||
// Expand the model vertex position bits into float values
|
// Expand the model vertex position bits into float values
|
||||||
vec3 v_pos = vec3(v_pos_norm & 0xFFu, (v_pos_norm >> 8) & 0xFFu, float((v_pos_norm >> 16) & 0x0FFFu) - VERT_EXTRA_NEG_Z);
|
vec3 v_pos = vec3(v_pos_norm & 0xFFu, (v_pos_norm >> 8) & 0xFFu, float((v_pos_norm >> 16) & 0x0FFFu) - VERT_EXTRA_NEG_Z);
|
||||||
|
|
||||||
|
// Position of the sprite block in the chunk
|
||||||
|
// Used for highlighting the selected sprite, and for opening doors
|
||||||
|
vec3 inst_chunk_pos = vec3(inst_pos_ori_door & 0x3Fu, (inst_pos_ori_door >> 6) & 0x3Fu, float((inst_pos_ori_door >> 12) & 0xFFFFu) - EXTRA_NEG_Z);
|
||||||
|
vec3 sprite_pos = inst_chunk_pos + chunk_offs;
|
||||||
|
float sprite_ori = (inst_pos_ori_door >> 29) & 0x7u;
|
||||||
|
|
||||||
|
#ifndef EXPERIMENTAL_BAREMINIMUM
|
||||||
|
if((inst_pos_ori_door & (1 << 28)) != 0) {
|
||||||
|
const float MIN_OPEN_DIST = 0.2;
|
||||||
|
const float MAX_OPEN_DIST = 1.5;
|
||||||
|
float min_entity_dist = nearest_entity(sprite_pos + 0.5, 1.0).w;
|
||||||
|
|
||||||
|
if (min_entity_dist < MAX_OPEN_DIST) {
|
||||||
|
float flip = sprite_ori <= 3 ? 1.0 : -1.0;
|
||||||
|
float theta = mix(PI/2.0, 0, pow(max(0.0, min_entity_dist - MIN_OPEN_DIST) / (MAX_OPEN_DIST - MIN_OPEN_DIST), 1.0));
|
||||||
|
float costheta = cos(flip * theta);
|
||||||
|
float sintheta = sin(flip * theta);
|
||||||
|
mat3 rot_z = mat3(
|
||||||
|
vec3(costheta, -sintheta, 0),
|
||||||
|
vec3(sintheta, costheta, 0),
|
||||||
|
vec3(0, 0, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
vec3 delta = vec3(-0.0, -5.5, 0);
|
||||||
|
v_pos = (rot_z * (v_pos + delta)) - delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Transform into chunk space and scale
|
// Transform into chunk space and scale
|
||||||
f_pos = (inst_mat * vec4(v_pos, 1.0)).xyz;
|
f_pos = (inst_mat * vec4(v_pos, 1.0)).xyz;
|
||||||
// Transform info world space
|
// Transform info world space
|
||||||
@ -103,6 +151,17 @@ void main() {
|
|||||||
// NOTE: could potentially replace `v_pos.z * model_z_scale` with a calculation using `inst_chunk_pos` from below
|
// NOTE: could potentially replace `v_pos.z * model_z_scale` with a calculation using `inst_chunk_pos` from below
|
||||||
//) * pow(abs(v_pos.z * model_z_scale), 1.3) * SCALE_FACTOR;
|
//) * pow(abs(v_pos.z * model_z_scale), 1.3) * SCALE_FACTOR;
|
||||||
) * v_pos.z * model_z_scale * SCALE_FACTOR;
|
) * v_pos.z * model_z_scale * SCALE_FACTOR;
|
||||||
|
|
||||||
|
if (model_wind_sway > 0.0) {
|
||||||
|
vec2 center = sprite_pos.xy + 0.5;
|
||||||
|
vec4 min_entity = nearest_entity(vec3(center, sprite_pos.z), 0.0);
|
||||||
|
|
||||||
|
const float PUSH_FACTOR = 5;
|
||||||
|
|
||||||
|
float push_dist = max(1.0 - min_entity.w, 0.0);
|
||||||
|
|
||||||
|
f_pos.xy += normalize(center - min_entity.xy) * v_pos.z * model_z_scale * SCALE_FACTOR * PUSH_FACTOR * push_dist;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Determine normal
|
// Determine normal
|
||||||
@ -127,11 +186,7 @@ void main() {
|
|||||||
// NOTE: Could defer to fragment shader if we are vert heavy
|
// NOTE: Could defer to fragment shader if we are vert heavy
|
||||||
f_uv_pos = vec2((uvec2(v_atlas_pos) >> uvec2(0, 16)) & uvec2(0xFFFFu, 0xFFFFu));;
|
f_uv_pos = vec2((uvec2(v_atlas_pos) >> uvec2(0, 16)) & uvec2(0xFFFFu, 0xFFFFu));;
|
||||||
|
|
||||||
// Position of the sprite block in the chunk
|
|
||||||
// Used solely for highlighting the selected sprite
|
|
||||||
vec3 inst_chunk_pos = vec3(inst_pos_ori & 0x3Fu, (inst_pos_ori >> 6) & 0x3Fu, float((inst_pos_ori >> 12) & 0xFFFFu) - EXTRA_NEG_Z);
|
|
||||||
// Select glowing
|
// Select glowing
|
||||||
vec3 sprite_pos = inst_chunk_pos + chunk_offs;
|
|
||||||
f_select = (select_pos.w > 0 && select_pos.xyz == sprite_pos) ? 1.0 : 0.0;
|
f_select = (select_pos.w > 0 && select_pos.xyz == sprite_pos) ? 1.0 : 0.0;
|
||||||
|
|
||||||
gl_Position =
|
gl_Position =
|
||||||
|
@ -99,7 +99,7 @@ pub struct Instance {
|
|||||||
inst_mat1: [f32; 4],
|
inst_mat1: [f32; 4],
|
||||||
inst_mat2: [f32; 4],
|
inst_mat2: [f32; 4],
|
||||||
inst_mat3: [f32; 4],
|
inst_mat3: [f32; 4],
|
||||||
pos_ori: u32,
|
pos_ori_door: u32,
|
||||||
inst_vert_page: u32,
|
inst_vert_page: u32,
|
||||||
inst_light: f32,
|
inst_light: f32,
|
||||||
inst_glow: f32,
|
inst_glow: f32,
|
||||||
@ -117,6 +117,7 @@ impl Instance {
|
|||||||
light: f32,
|
light: f32,
|
||||||
glow: f32,
|
glow: f32,
|
||||||
vert_page: u32,
|
vert_page: u32,
|
||||||
|
is_door: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
const EXTRA_NEG_Z: i32 = 32768;
|
const EXTRA_NEG_Z: i32 = 32768;
|
||||||
|
|
||||||
@ -126,10 +127,11 @@ impl Instance {
|
|||||||
inst_mat1: mat_arr[1],
|
inst_mat1: mat_arr[1],
|
||||||
inst_mat2: mat_arr[2],
|
inst_mat2: mat_arr[2],
|
||||||
inst_mat3: mat_arr[3],
|
inst_mat3: mat_arr[3],
|
||||||
pos_ori: ((pos.x as u32) & 0x003F)
|
pos_ori_door: ((pos.x as u32) & 0x003F)
|
||||||
| ((pos.y as u32) & 0x003F) << 6
|
| ((pos.y as u32) & 0x003F) << 6
|
||||||
| (((pos.z + EXTRA_NEG_Z).max(0).min(1 << 16) as u32) & 0xFFFF) << 12
|
| (((pos.z + EXTRA_NEG_Z).max(0).min(1 << 16) as u32) & 0xFFFF) << 12
|
||||||
| (u32::from(ori_bits) & 0x7) << 29,
|
| (u32::from(ori_bits) & 0x7) << 29
|
||||||
|
| (u32::from(is_door) & 1) << 28,
|
||||||
inst_vert_page: vert_page,
|
inst_vert_page: vert_page,
|
||||||
inst_light: light,
|
inst_light: light,
|
||||||
inst_glow: glow,
|
inst_glow: glow,
|
||||||
@ -160,7 +162,19 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Instance {
|
impl Default for Instance {
|
||||||
fn default() -> Self { Self::new(Mat4::identity(), 0.0, 0.0, Vec3::zero(), 0, 1.0, 0.0, 0) }
|
fn default() -> Self {
|
||||||
|
Self::new(
|
||||||
|
Mat4::identity(),
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
Vec3::zero(),
|
||||||
|
0,
|
||||||
|
1.0,
|
||||||
|
0.0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ColLightsWrapper instead?
|
// TODO: ColLightsWrapper instead?
|
||||||
|
@ -330,6 +330,7 @@ fn mesh_worker(
|
|||||||
light,
|
light,
|
||||||
glow,
|
glow,
|
||||||
page,
|
page,
|
||||||
|
matches!(sprite, SpriteKind::Door),
|
||||||
);
|
);
|
||||||
lod_level.push(instance);
|
lod_level.push(instance);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user