use std::collections::HashMap; use itertools::Itertools; use bevy::{ prelude::*, reflect::TypeUuid, render::render_resource::{AsBindGroup, ShaderRef}, }; use polyhedron_ops as p_ops; use smooth_bevy_cameras::{ controllers::orbit::{OrbitCameraBundle, OrbitCameraController, OrbitCameraPlugin}, LookTransformPlugin, }; fn main() { App::new() .insert_resource(Msaa::Sample4) .add_plugins(DefaultPlugins) .add_plugin(LookTransformPlugin) .add_plugin(OrbitCameraPlugin::default()) .add_startup_system(setup) .add_system(bevy::window::close_on_esc) .add_plugin(MaterialPlugin::::default()) .run(); } #[derive(Debug, Clone)] struct ShapeMap { shapes: HashMap, } impl ShapeMap { fn new(seed: &str, ops: &str, depth: u32) -> Self { let mut sm = ShapeMap { shapes: HashMap::new(), }; for var in (1..=depth as usize).flat_map(|n| { std::iter::repeat(ops.chars()) .take(n) .multi_cartesian_product() }) { let key = var.into_iter().collect::() + seed; let mut polyhedron = p_ops::Polyhedron::try_from(key.as_ref()).unwrap(); polyhedron.planarize(Some(100), false); println!("{}: {}", key, polyhedron.positions().len()); sm.shapes.insert(key, polyhedron); } println!("{}", sm.shapes.len()); sm } } fn setup( mut commands: Commands, mut meshes: ResMut>, mut base_materials: ResMut>, mut enemy_materials: ResMut>, ) { let depth = 1; let sm = ShapeMap::new("T", "skad", depth); let mut x = 0; let mut y = 0; for (_, s) in sm.shapes.iter() { let pos = Vec3::new(0.0, x as f32 * 2.0, y as f32 * 2.0); commands.spawn(MaterialMeshBundle { mesh: meshes.add(Mesh::from(s.clone())), material: enemy_materials.add(EnemyMaterial { color: Color::rgba(1.0, 1.0, 1.0, 1.0), alpha_mode: AlphaMode::Opaque, }), transform: Transform::from_translation(pos), ..default() }); x += 1; if x > 5 { x = 0; y += 1; } } // reference cube commands.spawn(MaterialMeshBundle { mesh: meshes.add(Mesh::from(shape::Cube::default())), material: base_materials.add(Color::BLUE.into()), transform: Transform::from_translation(Vec3::new(-2.0, 0.0, 0.0)), ..default() }); commands // light .spawn(DirectionalLightBundle { transform: Transform::from_translation(Vec3::new(4.0, 8.0, 4.0)), ..Default::default() }); commands // camera .spawn(Camera3dBundle::default()) .insert(OrbitCameraBundle::new( OrbitCameraController { mouse_rotate_sensitivity: Vec2::new(2.0, 2.0), mouse_translate_sensitivity: Vec2::new(2.0, 2.0), ..default() }, Vec3::new(-3.0, 3.0, 5.0), Vec3::new(0., 0., 0.), Vec3::new(0., -1., 0.), )); } impl Material for EnemyMaterial { fn fragment_shader() -> ShaderRef { "shaders/enemy_material.wgsl".into() } fn alpha_mode(&self) -> AlphaMode { self.alpha_mode } } #[derive(AsBindGroup, TypeUuid, Debug, Clone)] #[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"] pub struct EnemyMaterial { #[uniform(0)] color: Color, alpha_mode: AlphaMode, }