// ▄████████▄ + ███ + ▄█████████ ███ + // ███▀ ▀███ + + ███ ███▀ + ███ + + // ███ + ███ ███ ███ █████████ ███ ███ ███ ███ // ███ +███ ███ ███ ███ ███▐██████ ███ ███ ███ // ███ + ███ ███+ ███ +███ ███ + ███ ███ + ███ // ███▄ ▄███ ███▄ ███ ███ + ███ + ███ ███▄ ███ // ▀████████▀ + ▀███████ ███▄ ███▄ ▀████ ▀███████ // + + + ███ // + ▀████████████████████████████████████████████████████▀ // // This module manages asset loading. use bevy::ecs::system::EntityCommands; use bevy::pbr::{ExtendedMaterial, MaterialExtension, OpaqueRendererMethod}; use bevy::prelude::*; use bevy::render::render_resource::{AsBindGroup, ShaderRef}; pub struct LoadPlugin; impl Plugin for LoadPlugin { fn build(&self, app: &mut App) { app.add_plugins(MaterialPlugin::::default()); app.add_plugins(MaterialPlugin::::default()); app.add_plugins(MaterialPlugin::::default()); app.add_plugins(MaterialPlugin::< ExtendedMaterial, >::default()); } } pub fn asset_name_to_path(name: &str) -> &'static str { match name { "suitv2" => "models/suit_v2.gltf#Scene0", "suit_ar_armor" => "models/ar_armor.gltf#Scene0", "suit_ar_bra" => "models/ar_bra.gltf#Scene0", "suit_ar_chefhat" => "models/suit_v2/ar_chefhat.glb#Scene0", "suit_ar_choker" => "models/ar_choker.gltf#Scene0", "suit_ar_choker_lace" => "models/ar_choker_lace.gltf#Scene0", "suit_ar_nekomimi" => "models/ar_nekomimi.gltf#Scene0", "suit_ar_hoodie" => "models/ar_hoodie.gltf#Scene0", "suit_ar_hoodie_up" => "models/ar_hoodie_up.gltf#Scene0", "suit_ar_skirt" => "models/ar_skirt.gltf#Scene0", "suit_ar_skirt_tartan" => "models/ar_skirt_tartan.gltf#Scene0", "suit_ar_dress" => "models/ar_dress.gltf#Scene0", "suit_ar_wings" => "models/suit_v2/ar_wings.glb#Scene0", "sus" => "models/sus.glb#Scene0", "asteroid1" => "models/asteroid1.gltf#Scene0", "hollow_asteroid" => "models/hollow_asteroid.gltf#Scene0", "moonlet" => "models/moonlet.glb#Scene0", "monolith" => "models/monolith_neon.glb#Scene0", "mirror" => "models/mirror.glb#Scene0", "greenhouse" => "models/greenhouse.gltf#Scene0", "lightorb" => "models/lightorb.glb#Scene0", "orb_busstop" => "models/orb_busstop.glb#Scene0", "orb_busstop_dim" => "models/orb_busstop_dim.glb#Scene0", "crate" => "models/crate.glb#Scene0", "MeteorAceGT" => "models/MeteorAceGT.glb#Scene0", "cruiser" => "models/cruiser.glb#Scene0", "shippingcontainer" => "models/shippingcontainer.glb#Scene0", "frameflat" => "models/frameflat.gltf#Scene0", "fueltank" => "models/fueltank.glb#Scene0", "satellite" => "models/satellite.gltf#Scene0", "pizzeria" => "models/pizzeria3.gltf#Scene0", "pizzasign" => "models/pizzasign.glb#Scene0", "selectagon" => "models/selectagon.glb#Scene0", "orbitring" => "models/orbitring.glb#Scene0", "mapgrid" => "models/mapgrid.glb#Scene0", "clippy" => "models/clippy/clippy.glb#Scene0", "clippy_ar" => "models/clippy/ar_happy.glb#Scene0", "whale" => "models/whale.gltf#Scene0", "marker_satellites" => "models/marker_satellites.glb#Scene0", "marker_planets" => "models/marker_planets.glb#Scene0", "marker_player" => "models/marker_player.glb#Scene0", "marker_race" => "models/marker_race.glb#Scene0", "point_of_interest" => "models/point_of_interest.glb#Scene0", "metis" => "models/metis.gltf#Scene0", "thebe" => "models/thebe.gltf#Scene0", _ => "models/error.glb#Scene0", } } pub fn load_asset(name: &str, entity_commands: &mut EntityCommands, asset_server: &AssetServer) { entity_commands.insert(load_scene_by_path(asset_name_to_path(name), asset_server)); } #[inline] pub fn load_scene_by_path(path: &str, asset_server: &AssetServer) -> Handle { let path_string = path.to_string(); if let Some(handle) = asset_server.get_handle(&path_string) { handle } else { asset_server.load(&path_string) } } // Jupiter's Ring #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct JupitersRing { pub alpha_mode: AlphaMode, #[uniform(0)] pub ring_radius: f32, #[uniform(1)] pub jupiter_radius: f32, } impl Material for JupitersRing { fn fragment_shader() -> ShaderRef { "shaders/jupiters_rings.wgsl".into() } fn alpha_mode(&self) -> AlphaMode { self.alpha_mode } } // Jupiter's Aurora #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct JupitersAurora { pub alpha_mode: AlphaMode, } impl Material for JupitersAurora { fn fragment_shader() -> ShaderRef { "shaders/aurora.wgsl".into() } fn alpha_mode(&self) -> AlphaMode { self.alpha_mode } } // Sky Box #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct SkyBox {} impl Material for SkyBox { fn fragment_shader() -> ShaderRef { "shaders/skybox.wgsl".into() } } // Asteroid Surface #[derive(Asset, Reflect, AsBindGroup, Debug, Clone)] pub struct AsteroidSurface { #[uniform(100)] quantize_steps: u32, } impl MaterialExtension for AsteroidSurface { fn fragment_shader() -> ShaderRef { "shaders/material_asteroid.wgsl".into() } fn deferred_fragment_shader() -> ShaderRef { "shaders/material_asteroid.wgsl".into() } } impl AsteroidSurface { pub fn material() -> ExtendedMaterial { ExtendedMaterial { base: StandardMaterial { base_color: Color::srgb(0.29, 0.255, 0.208), perceptual_roughness: 1.0, opaque_render_method: OpaqueRendererMethod::Auto, ..default() }, extension: Self::default(), } } } impl Default for AsteroidSurface { fn default() -> Self { Self { quantize_steps: 3 } } }