Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_mesh/src/components.rs
6595 views
1
use crate::mesh::Mesh;
2
use bevy_asset::{AsAssetId, AssetEvent, AssetId, Handle};
3
use bevy_derive::{Deref, DerefMut};
4
use bevy_ecs::{
5
change_detection::DetectChangesMut, component::Component, event::EventReader,
6
reflect::ReflectComponent, system::Query,
7
};
8
use bevy_platform::{collections::HashSet, hash::FixedHasher};
9
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
10
use bevy_transform::components::Transform;
11
use derive_more::derive::From;
12
13
/// A component for 2D meshes. Requires a [`MeshMaterial2d`] to be rendered, commonly using a [`ColorMaterial`].
14
///
15
/// [`MeshMaterial2d`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html>
16
/// [`ColorMaterial`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.ColorMaterial.html>
17
///
18
/// # Example
19
///
20
/// ```ignore
21
/// # use bevy_sprite::{ColorMaterial, MeshMaterial2d};
22
/// # use bevy_ecs::prelude::*;
23
/// # use bevy_mesh::{Mesh, Mesh2d};
24
/// # use bevy_color::palettes::basic::RED;
25
/// # use bevy_asset::Assets;
26
/// # use bevy_math::primitives::Circle;
27
/// #
28
/// // Spawn an entity with a mesh using `ColorMaterial`.
29
/// fn setup(
30
/// mut commands: Commands,
31
/// mut meshes: ResMut<Assets<Mesh>>,
32
/// mut materials: ResMut<Assets<ColorMaterial>>,
33
/// ) {
34
/// commands.spawn((
35
/// Mesh2d(meshes.add(Circle::new(50.0))),
36
/// MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))),
37
/// ));
38
/// }
39
/// ```
40
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
41
#[reflect(Component, Default, Clone, PartialEq)]
42
#[require(Transform)]
43
pub struct Mesh2d(pub Handle<Mesh>);
44
45
impl From<Mesh2d> for AssetId<Mesh> {
46
fn from(mesh: Mesh2d) -> Self {
47
mesh.id()
48
}
49
}
50
51
impl From<&Mesh2d> for AssetId<Mesh> {
52
fn from(mesh: &Mesh2d) -> Self {
53
mesh.id()
54
}
55
}
56
57
impl AsAssetId for Mesh2d {
58
type Asset = Mesh;
59
60
fn as_asset_id(&self) -> AssetId<Self::Asset> {
61
self.id()
62
}
63
}
64
65
/// A component for 3D meshes. Requires a [`MeshMaterial3d`] to be rendered, commonly using a [`StandardMaterial`].
66
///
67
/// [`MeshMaterial3d`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html>
68
/// [`StandardMaterial`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html>
69
///
70
/// # Example
71
///
72
/// ```ignore
73
/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};
74
/// # use bevy_ecs::prelude::*;
75
/// # use bevy_mesh::{Mesh, Mesh3d};
76
/// # use bevy_color::palettes::basic::RED;
77
/// # use bevy_asset::Assets;
78
/// # use bevy_math::primitives::Capsule3d;
79
/// #
80
/// // Spawn an entity with a mesh using `StandardMaterial`.
81
/// fn setup(
82
/// mut commands: Commands,
83
/// mut meshes: ResMut<Assets<Mesh>>,
84
/// mut materials: ResMut<Assets<StandardMaterial>>,
85
/// ) {
86
/// commands.spawn((
87
/// Mesh3d(meshes.add(Capsule3d::default())),
88
/// MeshMaterial3d(materials.add(StandardMaterial {
89
/// base_color: RED.into(),
90
/// ..Default::default()
91
/// })),
92
/// ));
93
/// }
94
/// ```
95
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
96
#[reflect(Component, Default, Clone, PartialEq)]
97
#[require(Transform)]
98
pub struct Mesh3d(pub Handle<Mesh>);
99
100
impl From<Mesh3d> for AssetId<Mesh> {
101
fn from(mesh: Mesh3d) -> Self {
102
mesh.id()
103
}
104
}
105
106
impl From<&Mesh3d> for AssetId<Mesh> {
107
fn from(mesh: &Mesh3d) -> Self {
108
mesh.id()
109
}
110
}
111
112
impl AsAssetId for Mesh3d {
113
type Asset = Mesh;
114
115
fn as_asset_id(&self) -> AssetId<Self::Asset> {
116
self.id()
117
}
118
}
119
120
/// A system that marks a [`Mesh3d`] as changed if the associated [`Mesh`] asset
121
/// has changed.
122
///
123
/// This is needed because the systems that extract meshes, such as
124
/// `extract_meshes_for_gpu_building`, write some metadata about the mesh (like
125
/// the location within each slab) into the GPU structures that they build that
126
/// needs to be kept up to date if the contents of the mesh change.
127
pub fn mark_3d_meshes_as_changed_if_their_assets_changed(
128
mut meshes_3d: Query<&mut Mesh3d>,
129
mut mesh_asset_events: EventReader<AssetEvent<Mesh>>,
130
) {
131
let mut changed_meshes: HashSet<AssetId<Mesh>, FixedHasher> = HashSet::default();
132
for mesh_asset_event in mesh_asset_events.read() {
133
if let AssetEvent::Modified { id } = mesh_asset_event {
134
changed_meshes.insert(*id);
135
}
136
}
137
138
if changed_meshes.is_empty() {
139
return;
140
}
141
142
for mut mesh_3d in &mut meshes_3d {
143
if changed_meshes.contains(&mesh_3d.0.id()) {
144
mesh_3d.set_changed();
145
}
146
}
147
}
148
149
/// A component that stores an arbitrary index used to identify the mesh instance when rendering.
150
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
151
#[reflect(Component, Default, Clone, PartialEq)]
152
pub struct MeshTag(pub u32);
153
154