working voronoi representation using custom flat interpolation in
material shader
This commit is contained in:
parent
f46536ecc8
commit
9b4d9d74fc
136
assets/shaders/vertex.wgsl
Normal file
136
assets/shaders/vertex.wgsl
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#import bevy_pbr::{
|
||||||
|
pbr_types,
|
||||||
|
pbr_functions::alpha_discard,
|
||||||
|
pbr_fragment::pbr_input_from_standard_material,
|
||||||
|
decal::clustered::apply_decal_base_color,
|
||||||
|
mesh_functions,
|
||||||
|
view_transformations::position_world_to_clip
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PREPASS_PIPELINE
|
||||||
|
#import bevy_pbr::{
|
||||||
|
prepass_io::{VertexOutput, FragmentOutput},
|
||||||
|
pbr_deferred_functions::deferred_output,
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#import bevy_pbr::{
|
||||||
|
forward_io::{VertexOutput, FragmentOutput},
|
||||||
|
pbr_functions,
|
||||||
|
pbr_functions::{apply_pbr_lighting, main_pass_post_lighting_processing},
|
||||||
|
pbr_types::STANDARD_MATERIAL_FLAGS_UNLIT_BIT,
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MESHLET_MESH_MATERIAL_PASS
|
||||||
|
#import bevy_pbr::meshlet_visibility_buffer_resolve::resolve_vertex_output
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OIT_ENABLED
|
||||||
|
#import bevy_core_pipeline::oit::oit_draw
|
||||||
|
#endif // OIT_ENABLED
|
||||||
|
|
||||||
|
#ifdef FORWARD_DECAL
|
||||||
|
#import bevy_pbr::decal::forward::get_forward_decal_info
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
@builtin(instance_index) instance_index: u32,
|
||||||
|
@location(0) position: vec3<f32>,
|
||||||
|
@location(1) normal: vec3<f32>,
|
||||||
|
// @location(2) cell_kind: u32
|
||||||
|
@location(5) color: vec4<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FlatVertexOutput {
|
||||||
|
// This is `clip position` when the struct is used as a vertex stage output
|
||||||
|
// and `frag coord` when used as a fragment stage input
|
||||||
|
@builtin(position) position: vec4<f32>,
|
||||||
|
@location(0) world_position: vec4<f32>,
|
||||||
|
@location(1) @interpolate(flat) world_normal: vec3<f32>,
|
||||||
|
// @location(2) @interpolate(flat) cell_kind: u32
|
||||||
|
@location(5) @interpolate(flat) color: vec4<f32>,
|
||||||
|
@location(6) @interpolate(flat) instance_index: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct FragmentOutput {
|
||||||
|
// @location(0) color: vec4<f32>,
|
||||||
|
// }
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vertex(vert: Vertex) -> FlatVertexOutput {
|
||||||
|
var out: FlatVertexOutput;
|
||||||
|
|
||||||
|
let mesh_world_from_local = mesh_functions::get_world_from_local(vert.instance_index);
|
||||||
|
|
||||||
|
out.world_normal = mesh_functions::mesh_normal_local_to_world(
|
||||||
|
vert.normal,
|
||||||
|
vert.instance_index
|
||||||
|
);
|
||||||
|
|
||||||
|
out.world_position = mesh_functions::mesh_position_local_to_world(mesh_world_from_local, vec4<f32>(vert.position, 1.0));
|
||||||
|
out.position = position_world_to_clip(out.world_position.xyz);
|
||||||
|
|
||||||
|
// out.cell_kind = vert.cell_kind;
|
||||||
|
out.instance_index = vert.instance_index;
|
||||||
|
out.color = vert.color;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fragment(
|
||||||
|
vertex_output: FlatVertexOutput,
|
||||||
|
@builtin(front_facing) is_front: bool
|
||||||
|
) -> FragmentOutput {
|
||||||
|
var in: VertexOutput;
|
||||||
|
in.instance_index = vertex_output.instance_index;
|
||||||
|
in.position = vertex_output.position;
|
||||||
|
in.world_normal = vertex_output.world_normal;
|
||||||
|
in.color = vertex_output.color;
|
||||||
|
|
||||||
|
// generate a PbrInput struct from the StandardMaterial bindings
|
||||||
|
var pbr_input = pbr_input_from_standard_material(in, is_front);
|
||||||
|
|
||||||
|
// alpha discard
|
||||||
|
pbr_input.material.base_color = alpha_discard(pbr_input.material, pbr_input.material.base_color);
|
||||||
|
|
||||||
|
// // clustered decals
|
||||||
|
// pbr_input.material.base_color = apply_decal_base_color(
|
||||||
|
// in.world_position.xyz,
|
||||||
|
// in.position.xy,
|
||||||
|
// pbr_input.material.base_color
|
||||||
|
// );
|
||||||
|
|
||||||
|
#ifdef PREPASS_PIPELINE
|
||||||
|
// write the gbuffer, lighting pass id, and optionally normal and motion_vector textures
|
||||||
|
let out = deferred_output(in, pbr_input);
|
||||||
|
#else
|
||||||
|
// in forward mode, we calculate the lit color immediately, and then apply some post-lighting effects here.
|
||||||
|
// in deferred mode the lit color and these effects will be calculated in the deferred lighting shader
|
||||||
|
var out: FragmentOutput;
|
||||||
|
if (pbr_input.material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) == 0u {
|
||||||
|
out.color = apply_pbr_lighting(pbr_input);
|
||||||
|
} else {
|
||||||
|
out.color = pbr_input.material.base_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply in-shader post processing (fog, alpha-premultiply, and also tonemapping, debanding if the camera is non-hdr)
|
||||||
|
// note this does not include fullscreen postprocessing effects like bloom.
|
||||||
|
out.color = main_pass_post_lighting_processing(pbr_input, out.color);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OIT_ENABLED
|
||||||
|
let alpha_mode = pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS;
|
||||||
|
if alpha_mode != pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE {
|
||||||
|
// The fragments will only be drawn during the oit resolve pass.
|
||||||
|
oit_draw(in.position, out.color);
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif // OIT_ENABLED
|
||||||
|
|
||||||
|
#ifdef FORWARD_DECAL
|
||||||
|
out.color.a = min(forward_decal_info.alpha, out.color.a);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
@ -24,7 +24,6 @@ fn setup(mut cmds: Commands, window: Query<&Window>) {
|
|||||||
DirectionalLight {
|
DirectionalLight {
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
illuminance: 17000.,
|
illuminance: 17000.,
|
||||||
//shadows_enabled: true,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Transform::default().looking_to(Vec3::new(1., -1., -1.), Vec3::ZERO),
|
Transform::default().looking_to(Vec3::new(1., -1., -1.), Vec3::ZERO),
|
||||||
|
91
src/map.rs
91
src/map.rs
@ -1,7 +1,9 @@
|
|||||||
|
use core::f32;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
asset::RenderAssetUsages,
|
asset::RenderAssetUsages,
|
||||||
|
pbr::MaterialExtension,
|
||||||
picking::PickSet,
|
picking::PickSet,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::mesh::{Indices, PrimitiveTopology},
|
render::mesh::{Indices, PrimitiveTopology},
|
||||||
@ -15,7 +17,10 @@ mod cells;
|
|||||||
mod picking;
|
mod picking;
|
||||||
pub use animals::AnimalKind;
|
pub use animals::AnimalKind;
|
||||||
pub use cells::CellKind;
|
pub use cells::CellKind;
|
||||||
use cells::*;
|
use cells::{
|
||||||
|
material::{CellMaterial, CellMaterialExtension},
|
||||||
|
*,
|
||||||
|
};
|
||||||
use picking::*;
|
use picking::*;
|
||||||
|
|
||||||
pub struct Plugin;
|
pub struct Plugin;
|
||||||
@ -25,7 +30,8 @@ impl bevy::prelude::Plugin for Plugin {
|
|||||||
.add_systems(PreUpdate, picking_backend.in_set(PickSet::Backend))
|
.add_systems(PreUpdate, picking_backend.in_set(PickSet::Backend))
|
||||||
.add_systems(Update, (update_map_mesh, cells_regeneration, expand))
|
.add_systems(Update, (update_map_mesh, cells_regeneration, expand))
|
||||||
.insert_resource(ClearColor(Color::srgb(0., 0., 1.)))
|
.insert_resource(ClearColor(Color::srgb(0., 0., 1.)))
|
||||||
.insert_resource(Seed(thread_rng().gen()));
|
.insert_resource(Seed(thread_rng().gen()))
|
||||||
|
.add_plugins(MaterialPlugin::<CellMaterial>::default());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,16 +45,16 @@ pub const SIZE: usize = 10000;
|
|||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct Seed(u32);
|
struct Seed(u32);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Resource)]
|
||||||
pub struct Voronoi(voronoice::Voronoi);
|
pub struct Voronoi(voronoice::Voronoi);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct MapMarker;
|
pub struct MapMarker;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
struct MapColors(Vec<[f32; 4]>);
|
struct MapMeshColors(Vec<[f32; 4]>);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Resource)]
|
||||||
pub struct CellsEntities(Vec<Entity>);
|
pub struct CellsEntities(Vec<Entity>);
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
@ -57,7 +63,8 @@ pub struct MeshNeedsUpdate(bool);
|
|||||||
fn setup(
|
fn setup(
|
||||||
mut cmds: Commands,
|
mut cmds: Commands,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
// mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
|
mut materials: ResMut<Assets<CellMaterial>>,
|
||||||
seed: Res<Seed>,
|
seed: Res<Seed>,
|
||||||
) {
|
) {
|
||||||
let mut rng = rand::rngs::SmallRng::seed_from_u64(seed.0 as u64);
|
let mut rng = rand::rngs::SmallRng::seed_from_u64(seed.0 as u64);
|
||||||
@ -81,7 +88,6 @@ fn setup(
|
|||||||
let c = voronoi.cell(i);
|
let c = voronoi.cell(i);
|
||||||
let site = c.site_position();
|
let site = c.site_position();
|
||||||
let z = get_altitude(&z_noise, &[site.x as f32, site.y as f32]);
|
let z = get_altitude(&z_noise, &[site.x as f32, site.y as f32]);
|
||||||
info!(z);
|
|
||||||
let _m = (
|
let _m = (
|
||||||
(moisture_noise.get([site.x, site.y]) + 1.) / 2.
|
(moisture_noise.get([site.x, site.y]) + 1.) / 2.
|
||||||
// Noise + [0; 1]
|
// Noise + [0; 1]
|
||||||
@ -105,27 +111,42 @@ fn setup(
|
|||||||
|
|
||||||
let mut poss = Vec::new();
|
let mut poss = Vec::new();
|
||||||
let mut indices = Vec::new();
|
let mut indices = Vec::new();
|
||||||
let mut normals = Vec::new();
|
// let mut normals = Vec::new();
|
||||||
|
|
||||||
for (c, cd) in voronoi.iter_cells().zip(cells.iter_mut()) {
|
for (i, pos) in voronoi.sites().iter().enumerate() {
|
||||||
let vs = c.iter_vertices().collect::<Vec<_>>();
|
let z = get_altitude(&z_noise, &[pos.x as f32, pos.y as f32]);
|
||||||
let i = poss.len();
|
poss.push(Vec3::new(pos.x as f32, pos.y as f32, z));
|
||||||
for v in vs.iter() {
|
cells[i].vertices.push(i);
|
||||||
poss.push(Vec3::new(
|
|
||||||
v.x as f32,
|
|
||||||
v.y as f32,
|
|
||||||
(get_altitude(&z_noise, &[v.x as f32, v.y as f32]) / 1.),
|
|
||||||
));
|
|
||||||
normals.push(Vec3::new(0., 0., 1.));
|
|
||||||
}
|
|
||||||
for v in 1..(vs.len() - 1) {
|
|
||||||
indices.extend_from_slice(&[(i + v + 1) as u32, (i + v) as u32, i as u32]);
|
|
||||||
cd.vertices.extend_from_slice(&[i, i + v, i + v + 1]);
|
|
||||||
}
|
}
|
||||||
|
for t in voronoi.triangulation().triangles.chunks_exact(3) {
|
||||||
|
indices.extend_from_slice(&[t[2] as u32, t[1] as u32, t[0] as u32]);
|
||||||
}
|
}
|
||||||
|
// indices.extend(voronoi.triangulation().triangles.iter().map(|t| *t as u32));
|
||||||
|
|
||||||
|
// for (c, cd) in voronoi.iter_cells().zip(cells.iter_mut()) {
|
||||||
|
// let vs = c.iter_vertices().collect::<Vec<_>>();
|
||||||
|
// let i = poss.len();
|
||||||
|
// for v in vs.iter() {
|
||||||
|
// let z = get_altitude(&z_noise, &[v.x as f32, v.y as f32]);
|
||||||
|
// poss.push(Vec3::new(v.x as f32, v.y as f32, z));
|
||||||
|
// // const EPSILON: f32 = 0.01;
|
||||||
|
// // let dzx = get_altitude(&z_noise, &[v.x as f32 + EPSILON, v.y as f32]) - z;
|
||||||
|
// // let nx = (f32::consts::FRAC_PI_2 - (dzx / EPSILON).atan()).cos();
|
||||||
|
// // let dzy = get_altitude(&z_noise, &[v.x as f32, v.y as f32 + EPSILON]) - z;
|
||||||
|
// // let ny = (f32::consts::FRAC_PI_2 - (dzy / EPSILON).atan()).cos();
|
||||||
|
|
||||||
|
// // let nz = (1. - (nx.powi(2) + ny.powi(2))).sqrt();
|
||||||
|
|
||||||
|
// // normals.push(Vec3::new(nx, ny, nz));
|
||||||
|
// }
|
||||||
|
// for v in 1..(vs.len() - 1) {
|
||||||
|
// indices.extend_from_slice(&[(i + v + 1) as u32, (i + v) as u32, i as u32]);
|
||||||
|
// cd.vertices.extend_from_slice(&[i, i + v, i + v + 1]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
let colors = vec![[0.; 4]; poss.len()];
|
let colors = vec![[0.; 4]; poss.len()];
|
||||||
let mesh = Mesh::new(
|
let mut mesh = Mesh::new(
|
||||||
PrimitiveTopology::TriangleList,
|
PrimitiveTopology::TriangleList,
|
||||||
RenderAssetUsages::default(),
|
RenderAssetUsages::default(),
|
||||||
)
|
)
|
||||||
@ -133,17 +154,26 @@ fn setup(
|
|||||||
// 3D space), for each of the corners of the parallelogram.
|
// 3D space), for each of the corners of the parallelogram.
|
||||||
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, poss)
|
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, poss)
|
||||||
.with_inserted_attribute(Mesh::ATTRIBUTE_COLOR, colors.clone())
|
.with_inserted_attribute(Mesh::ATTRIBUTE_COLOR, colors.clone())
|
||||||
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
|
// .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
|
||||||
.with_inserted_indices(Indices::U32(indices));
|
.with_inserted_indices(Indices::U32(indices));
|
||||||
|
|
||||||
|
mesh.compute_smooth_normals();
|
||||||
|
mesh.generate_tangents();
|
||||||
|
// mesh.duplicate_vertices();
|
||||||
|
// mesh.compute_flat_normals();
|
||||||
|
|
||||||
let mut cells_entities = Vec::with_capacity(cells.len());
|
let mut cells_entities = Vec::with_capacity(cells.len());
|
||||||
|
|
||||||
cmds.spawn((
|
cmds.spawn((
|
||||||
Mesh3d(meshes.add(mesh)),
|
Mesh3d(meshes.add(mesh)),
|
||||||
// StandardMaterial
|
// StandardMaterial
|
||||||
MeshMaterial3d(materials.add(StandardMaterial::default())),
|
// MeshMaterial3d(materials.add(StandardMaterial::default())),
|
||||||
|
MeshMaterial3d(materials.add(CellMaterial {
|
||||||
|
base: StandardMaterial::default(),
|
||||||
|
extension: CellMaterialExtension {},
|
||||||
|
})),
|
||||||
Transform::default(),
|
Transform::default(),
|
||||||
Voronoi(voronoi),
|
MapMeshColors(colors),
|
||||||
MapColors(colors),
|
|
||||||
MeshNeedsUpdate(true),
|
MeshNeedsUpdate(true),
|
||||||
MapMarker,
|
MapMarker,
|
||||||
))
|
))
|
||||||
@ -166,13 +196,14 @@ fn setup(
|
|||||||
cmd.observe(self::cells::on_click);
|
cmd.observe(self::cells::on_click);
|
||||||
cells_entities.push(cmd.id());
|
cells_entities.push(cmd.id());
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.insert(CellsEntities(cells_entities));
|
cmds.insert_resource(Voronoi(voronoi));
|
||||||
|
cmds.insert_resource(CellsEntities(cells_entities));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_map_mesh(
|
fn update_map_mesh(
|
||||||
cells: Query<(&Cell, Option<&Wealth>)>,
|
cells: Query<(&Cell, Option<&Wealth>)>,
|
||||||
mut map: Query<(&Mesh3d, &mut MapColors, &mut MeshNeedsUpdate), With<MapMarker>>,
|
mut map: Query<(&Mesh3d, &mut MapMeshColors, &mut MeshNeedsUpdate), With<MapMarker>>,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
) {
|
) {
|
||||||
let (mesh, mut cols, mut needs_update) = map.single_mut();
|
let (mesh, mut cols, mut needs_update) = map.single_mut();
|
||||||
|
@ -7,6 +7,8 @@ use crate::{time::GameTime, ui::CurrentAction};
|
|||||||
|
|
||||||
use super::{animals::Animal, AnimalKind, CellsEntities, MapMarker, MeshNeedsUpdate, Voronoi};
|
use super::{animals::Animal, AnimalKind, CellsEntities, MapMarker, MeshNeedsUpdate, Voronoi};
|
||||||
|
|
||||||
|
pub mod material;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum CellKind {
|
pub enum CellKind {
|
||||||
Sea,
|
Sea,
|
||||||
@ -94,12 +96,12 @@ pub fn cells_regeneration(
|
|||||||
|
|
||||||
pub fn expand(
|
pub fn expand(
|
||||||
mut cells: Query<(&mut Cell, Option<&Wealth>)>,
|
mut cells: Query<(&mut Cell, Option<&Wealth>)>,
|
||||||
map: Query<(&Voronoi, &CellsEntities)>,
|
voronoi: Res<Voronoi>,
|
||||||
|
cells_entities: Res<CellsEntities>,
|
||||||
mut cmds: Commands,
|
mut cmds: Commands,
|
||||||
t: Res<Time>,
|
t: Res<Time>,
|
||||||
gt: Res<GameTime>,
|
gt: Res<GameTime>,
|
||||||
) {
|
) {
|
||||||
let (voronoi, cells_entities) = map.single();
|
|
||||||
let mut random = thread_rng();
|
let mut random = thread_rng();
|
||||||
let mut changes = Vec::new();
|
let mut changes = Vec::new();
|
||||||
for (cell, wealth) in cells.iter() {
|
for (cell, wealth) in cells.iter() {
|
||||||
@ -172,7 +174,7 @@ pub fn expand(
|
|||||||
pub fn on_click(
|
pub fn on_click(
|
||||||
trigger: Trigger<Pointer<Click>>,
|
trigger: Trigger<Pointer<Click>>,
|
||||||
mut cells: Query<&mut Cell>,
|
mut cells: Query<&mut Cell>,
|
||||||
voronoi: Query<&Voronoi>,
|
voronoi: Res<Voronoi>,
|
||||||
mut map_needs_update: Query<&mut MeshNeedsUpdate, With<MapMarker>>,
|
mut map_needs_update: Query<&mut MeshNeedsUpdate, With<MapMarker>>,
|
||||||
mut cmds: Commands,
|
mut cmds: Commands,
|
||||||
ca: Res<CurrentAction>,
|
ca: Res<CurrentAction>,
|
||||||
@ -216,7 +218,7 @@ pub fn on_click(
|
|||||||
},
|
},
|
||||||
CurrentAction::AddAnimal(ak) => {
|
CurrentAction::AddAnimal(ak) => {
|
||||||
if cell.kind.can_place_animal(ak) {
|
if cell.kind.can_place_animal(ak) {
|
||||||
let v_cell = voronoi.single().0.cell(cell.voronoi_id);
|
let v_cell = voronoi.0.cell(cell.voronoi_id);
|
||||||
let cell_pos = v_cell.site_position();
|
let cell_pos = v_cell.site_position();
|
||||||
cmds.spawn((
|
cmds.spawn((
|
||||||
Animal { kind: ak },
|
Animal { kind: ak },
|
||||||
|
18
src/map/cells/material.rs
Normal file
18
src/map/cells/material.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use bevy::pbr::{ExtendedMaterial, MaterialExtension};
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy::render::render_resource::*;
|
||||||
|
|
||||||
|
#[derive(Asset, AsBindGroup, Clone, Debug, Reflect)]
|
||||||
|
pub struct CellMaterialExtension {}
|
||||||
|
|
||||||
|
pub type CellMaterial = ExtendedMaterial<StandardMaterial, CellMaterialExtension>;
|
||||||
|
|
||||||
|
const SHADER_PATH: &str = "shaders/vertex.wgsl";
|
||||||
|
impl MaterialExtension for CellMaterialExtension {
|
||||||
|
fn vertex_shader() -> ShaderRef {
|
||||||
|
SHADER_PATH.into()
|
||||||
|
}
|
||||||
|
fn fragment_shader() -> ShaderRef {
|
||||||
|
SHADER_PATH.into()
|
||||||
|
}
|
||||||
|
}
|
@ -8,19 +8,21 @@ use bevy::{
|
|||||||
};
|
};
|
||||||
use voronoice::Point;
|
use voronoice::Point;
|
||||||
|
|
||||||
use crate::camera::CameraMarker;
|
|
||||||
use super::{CellsEntities, MapMarker, Voronoi};
|
use super::{CellsEntities, MapMarker, Voronoi};
|
||||||
|
use crate::camera::CameraMarker;
|
||||||
|
|
||||||
pub fn picking_backend(
|
pub fn picking_backend(
|
||||||
cam: Query<(&Transform, Entity), With<CameraMarker>>,
|
cam: Query<(&Transform, Entity), With<CameraMarker>>,
|
||||||
window: Query<&Window, With<PrimaryWindow>>,
|
window: Query<&Window, With<PrimaryWindow>>,
|
||||||
pointers: Query<(&PointerId, &PointerLocation)>,
|
pointers: Query<(&PointerId, &PointerLocation)>,
|
||||||
map: Query<(&Voronoi, &CellsEntities, &Transform), With<MapMarker>>,
|
map: Query<&Transform, With<MapMarker>>,
|
||||||
|
voronoi: Res<Voronoi>,
|
||||||
|
cells_entities: Res<CellsEntities>,
|
||||||
mut output: EventWriter<PointerHits>,
|
mut output: EventWriter<PointerHits>,
|
||||||
) {
|
) {
|
||||||
let (cam, cam_id) = cam.single();
|
let (cam, cam_id) = cam.single();
|
||||||
let window = window.single();
|
let window = window.single();
|
||||||
let (voronoi, cells_entities, map_pos) = map.single();
|
let map_pos = map.single();
|
||||||
let mut last_cell = 0;
|
let mut last_cell = 0;
|
||||||
for (id, l) in pointers.iter() {
|
for (id, l) in pointers.iter() {
|
||||||
if let Some(mut pos) = l.location().map(|l| l.position) {
|
if let Some(mut pos) = l.location().map(|l| l.position) {
|
||||||
|
Loading…
Reference in New Issue
Block a user