use crate::mesh::Mesh;1use bevy_asset::{AsAssetId, AssetEvent, AssetId, Handle};2use bevy_derive::{Deref, DerefMut};3use bevy_ecs::{4change_detection::DetectChangesMut, component::Component, event::EventReader,5reflect::ReflectComponent, system::Query,6};7use bevy_platform::{collections::HashSet, hash::FixedHasher};8use bevy_reflect::{std_traits::ReflectDefault, Reflect};9use bevy_transform::components::Transform;10use derive_more::derive::From;1112/// A component for 2D meshes. Requires a [`MeshMaterial2d`] to be rendered, commonly using a [`ColorMaterial`].13///14/// [`MeshMaterial2d`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html>15/// [`ColorMaterial`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.ColorMaterial.html>16///17/// # Example18///19/// ```ignore20/// # use bevy_sprite::{ColorMaterial, MeshMaterial2d};21/// # use bevy_ecs::prelude::*;22/// # use bevy_mesh::{Mesh, Mesh2d};23/// # use bevy_color::palettes::basic::RED;24/// # use bevy_asset::Assets;25/// # use bevy_math::primitives::Circle;26/// #27/// // Spawn an entity with a mesh using `ColorMaterial`.28/// fn setup(29/// mut commands: Commands,30/// mut meshes: ResMut<Assets<Mesh>>,31/// mut materials: ResMut<Assets<ColorMaterial>>,32/// ) {33/// commands.spawn((34/// Mesh2d(meshes.add(Circle::new(50.0))),35/// MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))),36/// ));37/// }38/// ```39#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]40#[reflect(Component, Default, Clone, PartialEq)]41#[require(Transform)]42pub struct Mesh2d(pub Handle<Mesh>);4344impl From<Mesh2d> for AssetId<Mesh> {45fn from(mesh: Mesh2d) -> Self {46mesh.id()47}48}4950impl From<&Mesh2d> for AssetId<Mesh> {51fn from(mesh: &Mesh2d) -> Self {52mesh.id()53}54}5556impl AsAssetId for Mesh2d {57type Asset = Mesh;5859fn as_asset_id(&self) -> AssetId<Self::Asset> {60self.id()61}62}6364/// A component for 3D meshes. Requires a [`MeshMaterial3d`] to be rendered, commonly using a [`StandardMaterial`].65///66/// [`MeshMaterial3d`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html>67/// [`StandardMaterial`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html>68///69/// # Example70///71/// ```ignore72/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};73/// # use bevy_ecs::prelude::*;74/// # use bevy_mesh::{Mesh, Mesh3d};75/// # use bevy_color::palettes::basic::RED;76/// # use bevy_asset::Assets;77/// # use bevy_math::primitives::Capsule3d;78/// #79/// // Spawn an entity with a mesh using `StandardMaterial`.80/// fn setup(81/// mut commands: Commands,82/// mut meshes: ResMut<Assets<Mesh>>,83/// mut materials: ResMut<Assets<StandardMaterial>>,84/// ) {85/// commands.spawn((86/// Mesh3d(meshes.add(Capsule3d::default())),87/// MeshMaterial3d(materials.add(StandardMaterial {88/// base_color: RED.into(),89/// ..Default::default()90/// })),91/// ));92/// }93/// ```94#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]95#[reflect(Component, Default, Clone, PartialEq)]96#[require(Transform)]97pub struct Mesh3d(pub Handle<Mesh>);9899impl From<Mesh3d> for AssetId<Mesh> {100fn from(mesh: Mesh3d) -> Self {101mesh.id()102}103}104105impl From<&Mesh3d> for AssetId<Mesh> {106fn from(mesh: &Mesh3d) -> Self {107mesh.id()108}109}110111impl AsAssetId for Mesh3d {112type Asset = Mesh;113114fn as_asset_id(&self) -> AssetId<Self::Asset> {115self.id()116}117}118119/// A system that marks a [`Mesh3d`] as changed if the associated [`Mesh`] asset120/// has changed.121///122/// This is needed because the systems that extract meshes, such as123/// `extract_meshes_for_gpu_building`, write some metadata about the mesh (like124/// the location within each slab) into the GPU structures that they build that125/// needs to be kept up to date if the contents of the mesh change.126pub fn mark_3d_meshes_as_changed_if_their_assets_changed(127mut meshes_3d: Query<&mut Mesh3d>,128mut mesh_asset_events: EventReader<AssetEvent<Mesh>>,129) {130let mut changed_meshes: HashSet<AssetId<Mesh>, FixedHasher> = HashSet::default();131for mesh_asset_event in mesh_asset_events.read() {132if let AssetEvent::Modified { id } = mesh_asset_event {133changed_meshes.insert(*id);134}135}136137if changed_meshes.is_empty() {138return;139}140141for mut mesh_3d in &mut meshes_3d {142if changed_meshes.contains(&mesh_3d.0.id()) {143mesh_3d.set_changed();144}145}146}147148/// A component that stores an arbitrary index used to identify the mesh instance when rendering.149#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]150#[reflect(Component, Default, Clone, PartialEq)]151pub struct MeshTag(pub u32);152153154