1pub mod allocator;
2use crate::{
3 render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
4 render_resource::TextureView,
5 texture::GpuImage,
6 RenderApp,
7};
8use allocator::MeshAllocatorPlugin;
9use bevy_app::{App, Plugin, PostUpdate};
10use bevy_asset::{AssetId, RenderAssetUsages};
11use bevy_ecs::{
12 prelude::*,
13 system::{
14 lifetimeless::{SRes, SResMut},
15 SystemParamItem,
16 },
17};
18use bevy_mesh::morph::{MeshMorphWeights, MorphWeights};
19use bevy_mesh::*;
20use wgpu::IndexFormat;
21
22pub struct MeshRenderAssetPlugin;
25
26impl Plugin for MeshRenderAssetPlugin {
27 fn build(&self, app: &mut App) {
28 app
29 .add_plugins(RenderAssetPlugin::<RenderMesh, GpuImage>::default())
31 .add_plugins(MeshAllocatorPlugin);
32
33 let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
34 return;
35 };
36
37 render_app.init_resource::<MeshVertexBufferLayouts>();
38 }
39}
40
41pub struct MorphPlugin;
44impl Plugin for MorphPlugin {
45 fn build(&self, app: &mut App) {
46 app.add_systems(PostUpdate, inherit_weights.in_set(InheritWeightSystems));
47 }
48}
49
50pub fn inherit_weights(
55 morph_nodes: Query<(&Children, &MorphWeights), (Without<Mesh3d>, Changed<MorphWeights>)>,
56 mut morph_primitives: Query<&mut MeshMorphWeights, With<Mesh3d>>,
57) {
58 for (children, parent_weights) in &morph_nodes {
59 let mut iter = morph_primitives.iter_many_mut(children);
60 while let Some(mut child_weight) = iter.fetch_next() {
61 child_weight.clear_weights();
62 child_weight.extend_weights(parent_weights.weights());
63 }
64 }
65}
66
67#[derive(Debug, Clone)]
69pub struct RenderMesh {
70 pub vertex_count: u32,
72
73 pub morph_targets: Option<TextureView>,
75
76 pub buffer_info: RenderMeshBufferInfo,
79
80 pub key_bits: BaseMeshPipelineKey,
82
83 pub layout: MeshVertexBufferLayoutRef,
88}
89
90impl RenderMesh {
91 #[inline]
94 pub fn primitive_topology(&self) -> PrimitiveTopology {
95 self.key_bits.primitive_topology()
96 }
97
98 #[inline]
100 pub fn indexed(&self) -> bool {
101 matches!(self.buffer_info, RenderMeshBufferInfo::Indexed { .. })
102 }
103}
104
105#[derive(Debug, Clone)]
107pub enum RenderMeshBufferInfo {
108 Indexed {
109 count: u32,
110 index_format: IndexFormat,
111 },
112 NonIndexed,
113}
114
115impl RenderAsset for RenderMesh {
116 type SourceAsset = Mesh;
117 type Param = (
118 SRes<RenderAssets<GpuImage>>,
119 SResMut<MeshVertexBufferLayouts>,
120 );
121
122 #[inline]
123 fn asset_usage(mesh: &Self::SourceAsset) -> RenderAssetUsages {
124 mesh.asset_usage
125 }
126
127 fn byte_len(mesh: &Self::SourceAsset) -> Option<usize> {
128 let mut vertex_size = 0;
129 for attribute_data in mesh.attributes() {
130 let vertex_format = attribute_data.0.format;
131 vertex_size += vertex_format.size() as usize;
132 }
133
134 let vertex_count = mesh.count_vertices();
135 let index_bytes = mesh.get_index_buffer_bytes().map(<[_]>::len).unwrap_or(0);
136 Some(vertex_size * vertex_count + index_bytes)
137 }
138
139 fn prepare_asset(
141 mesh: Self::SourceAsset,
142 _: AssetId<Self::SourceAsset>,
143 (images, mesh_vertex_buffer_layouts): &mut SystemParamItem<Self::Param>,
144 _: Option<&Self>,
145 ) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
146 let morph_targets = match mesh.morph_targets() {
147 Some(mt) => {
148 let Some(target_image) = images.get(mt) else {
149 return Err(PrepareAssetError::RetryNextUpdate(mesh));
150 };
151 Some(target_image.texture_view.clone())
152 }
153 None => None,
154 };
155
156 let buffer_info = match mesh.indices() {
157 Some(indices) => RenderMeshBufferInfo::Indexed {
158 count: indices.len() as u32,
159 index_format: indices.into(),
160 },
161 None => RenderMeshBufferInfo::NonIndexed,
162 };
163
164 let mesh_vertex_buffer_layout =
165 mesh.get_mesh_vertex_buffer_layout(mesh_vertex_buffer_layouts);
166
167 let mut key_bits = BaseMeshPipelineKey::from_primitive_topology(mesh.primitive_topology());
168 key_bits.set(
169 BaseMeshPipelineKey::MORPH_TARGETS,
170 mesh.morph_targets().is_some(),
171 );
172
173 Ok(RenderMesh {
174 vertex_count: mesh.count_vertices() as u32,
175 buffer_info,
176 key_bits,
177 layout: mesh_vertex_buffer_layout,
178 morph_targets,
179 })
180 }
181}