Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1020
vendor/bevy_render/src/mesh/allocator.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,157 @@
use crate::{
mesh::Mesh,
view::{self, Visibility, VisibilityClass},
};
use bevy_asset::{AsAssetId, AssetEvent, AssetId, Handle};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
change_detection::DetectChangesMut, component::Component, event::EventReader,
reflect::ReflectComponent, system::Query,
};
use bevy_platform::{collections::HashSet, hash::FixedHasher};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_transform::components::Transform;
use derive_more::derive::From;
/// A component for 2D meshes. Requires a [`MeshMaterial2d`] to be rendered, commonly using a [`ColorMaterial`].
///
/// [`MeshMaterial2d`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html>
/// [`ColorMaterial`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.ColorMaterial.html>
///
/// # Example
///
/// ```ignore
/// # use bevy_sprite::{ColorMaterial, Mesh2d, MeshMaterial2d};
/// # use bevy_ecs::prelude::*;
/// # use bevy_render::mesh::Mesh;
/// # use bevy_color::palettes::basic::RED;
/// # use bevy_asset::Assets;
/// # use bevy_math::primitives::Circle;
/// #
/// // Spawn an entity with a mesh using `ColorMaterial`.
/// fn setup(
/// mut commands: Commands,
/// mut meshes: ResMut<Assets<Mesh>>,
/// mut materials: ResMut<Assets<ColorMaterial>>,
/// ) {
/// commands.spawn((
/// Mesh2d(meshes.add(Circle::new(50.0))),
/// MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))),
/// ));
/// }
/// ```
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
#[reflect(Component, Default, Clone, PartialEq)]
#[require(Transform, Visibility, VisibilityClass)]
#[component(on_add = view::add_visibility_class::<Mesh2d>)]
pub struct Mesh2d(pub Handle<Mesh>);
impl From<Mesh2d> for AssetId<Mesh> {
fn from(mesh: Mesh2d) -> Self {
mesh.id()
}
}
impl From<&Mesh2d> for AssetId<Mesh> {
fn from(mesh: &Mesh2d) -> Self {
mesh.id()
}
}
impl AsAssetId for Mesh2d {
type Asset = Mesh;
fn as_asset_id(&self) -> AssetId<Self::Asset> {
self.id()
}
}
/// A component for 3D meshes. Requires a [`MeshMaterial3d`] to be rendered, commonly using a [`StandardMaterial`].
///
/// [`MeshMaterial3d`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html>
/// [`StandardMaterial`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html>
///
/// # Example
///
/// ```ignore
/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};
/// # use bevy_ecs::prelude::*;
/// # use bevy_render::mesh::{Mesh, Mesh3d};
/// # use bevy_color::palettes::basic::RED;
/// # use bevy_asset::Assets;
/// # use bevy_math::primitives::Capsule3d;
/// #
/// // Spawn an entity with a mesh using `StandardMaterial`.
/// fn setup(
/// mut commands: Commands,
/// mut meshes: ResMut<Assets<Mesh>>,
/// mut materials: ResMut<Assets<StandardMaterial>>,
/// ) {
/// commands.spawn((
/// Mesh3d(meshes.add(Capsule3d::default())),
/// MeshMaterial3d(materials.add(StandardMaterial {
/// base_color: RED.into(),
/// ..Default::default()
/// })),
/// ));
/// }
/// ```
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
#[reflect(Component, Default, Clone, PartialEq)]
#[require(Transform, Visibility, VisibilityClass)]
#[component(on_add = view::add_visibility_class::<Mesh3d>)]
pub struct Mesh3d(pub Handle<Mesh>);
impl From<Mesh3d> for AssetId<Mesh> {
fn from(mesh: Mesh3d) -> Self {
mesh.id()
}
}
impl From<&Mesh3d> for AssetId<Mesh> {
fn from(mesh: &Mesh3d) -> Self {
mesh.id()
}
}
impl AsAssetId for Mesh3d {
type Asset = Mesh;
fn as_asset_id(&self) -> AssetId<Self::Asset> {
self.id()
}
}
/// A system that marks a [`Mesh3d`] as changed if the associated [`Mesh`] asset
/// has changed.
///
/// This is needed because the systems that extract meshes, such as
/// `extract_meshes_for_gpu_building`, write some metadata about the mesh (like
/// the location within each slab) into the GPU structures that they build that
/// needs to be kept up to date if the contents of the mesh change.
pub fn mark_3d_meshes_as_changed_if_their_assets_changed(
mut meshes_3d: Query<&mut Mesh3d>,
mut mesh_asset_events: EventReader<AssetEvent<Mesh>>,
) {
let mut changed_meshes: HashSet<AssetId<Mesh>, FixedHasher> = HashSet::default();
for mesh_asset_event in mesh_asset_events.read() {
if let AssetEvent::Modified { id } = mesh_asset_event {
changed_meshes.insert(*id);
}
}
if changed_meshes.is_empty() {
return;
}
for mut mesh_3d in &mut meshes_3d {
if changed_meshes.contains(&mesh_3d.0.id()) {
mesh_3d.set_changed();
}
}
}
/// A component that stores an arbitrary index used to identify the mesh instance when rendering.
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
#[reflect(Component, Default, Clone, PartialEq)]
pub struct MeshTag(pub u32);

248
vendor/bevy_render/src/mesh/mod.rs vendored Normal file
View File

@@ -0,0 +1,248 @@
use bevy_math::Vec3;
pub use bevy_mesh::*;
use morph::{MeshMorphWeights, MorphWeights};
pub mod allocator;
mod components;
use crate::{
primitives::Aabb,
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
render_resource::TextureView,
texture::GpuImage,
view::VisibilitySystems,
RenderApp,
};
use allocator::MeshAllocatorPlugin;
use bevy_app::{App, Plugin, PostUpdate};
use bevy_asset::{AssetApp, AssetEvents, AssetId, RenderAssetUsages};
use bevy_ecs::{
prelude::*,
system::{
lifetimeless::{SRes, SResMut},
SystemParamItem,
},
};
pub use components::{mark_3d_meshes_as_changed_if_their_assets_changed, Mesh2d, Mesh3d, MeshTag};
use wgpu::IndexFormat;
/// Registers all [`MeshBuilder`] types.
pub struct MeshBuildersPlugin;
impl Plugin for MeshBuildersPlugin {
fn build(&self, app: &mut App) {
// 2D Mesh builders
app.register_type::<CircleMeshBuilder>()
.register_type::<CircularSectorMeshBuilder>()
.register_type::<CircularSegmentMeshBuilder>()
.register_type::<RegularPolygonMeshBuilder>()
.register_type::<EllipseMeshBuilder>()
.register_type::<AnnulusMeshBuilder>()
.register_type::<RhombusMeshBuilder>()
.register_type::<Triangle2dMeshBuilder>()
.register_type::<RectangleMeshBuilder>()
.register_type::<Capsule2dMeshBuilder>()
// 3D Mesh builders
.register_type::<Capsule3dMeshBuilder>()
.register_type::<ConeMeshBuilder>()
.register_type::<ConicalFrustumMeshBuilder>()
.register_type::<CuboidMeshBuilder>()
.register_type::<CylinderMeshBuilder>()
.register_type::<PlaneMeshBuilder>()
.register_type::<SphereMeshBuilder>()
.register_type::<TetrahedronMeshBuilder>()
.register_type::<TorusMeshBuilder>()
.register_type::<Triangle3dMeshBuilder>();
}
}
/// Adds the [`Mesh`] as an asset and makes sure that they are extracted and prepared for the GPU.
pub struct MeshPlugin;
impl Plugin for MeshPlugin {
fn build(&self, app: &mut App) {
app.init_asset::<Mesh>()
.init_asset::<skinning::SkinnedMeshInverseBindposes>()
.register_asset_reflect::<Mesh>()
.register_type::<Mesh3d>()
.register_type::<skinning::SkinnedMesh>()
.register_type::<Vec<Entity>>()
.add_plugins(MeshBuildersPlugin)
// 'Mesh' must be prepared after 'Image' as meshes rely on the morph target image being ready
.add_plugins(RenderAssetPlugin::<RenderMesh, GpuImage>::default())
.add_plugins(MeshAllocatorPlugin)
.add_systems(
PostUpdate,
mark_3d_meshes_as_changed_if_their_assets_changed
.ambiguous_with(VisibilitySystems::CalculateBounds)
.before(AssetEvents),
);
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app.init_resource::<MeshVertexBufferLayouts>();
}
}
/// [Inherit weights](inherit_weights) from glTF mesh parent entity to direct
/// bevy mesh child entities (ie: glTF primitive).
pub struct MorphPlugin;
impl Plugin for MorphPlugin {
fn build(&self, app: &mut App) {
app.register_type::<MorphWeights>()
.register_type::<MeshMorphWeights>()
.add_systems(PostUpdate, inherit_weights);
}
}
/// Bevy meshes are gltf primitives, [`MorphWeights`] on the bevy node entity
/// should be inherited by children meshes.
///
/// Only direct children are updated, to fulfill the expectations of glTF spec.
pub fn inherit_weights(
morph_nodes: Query<(&Children, &MorphWeights), (Without<Mesh3d>, Changed<MorphWeights>)>,
mut morph_primitives: Query<&mut MeshMorphWeights, With<Mesh3d>>,
) {
for (children, parent_weights) in &morph_nodes {
let mut iter = morph_primitives.iter_many_mut(children);
while let Some(mut child_weight) = iter.fetch_next() {
child_weight.clear_weights();
child_weight.extend_weights(parent_weights.weights());
}
}
}
pub trait MeshAabb {
/// Compute the Axis-Aligned Bounding Box of the mesh vertices in model space
///
/// Returns `None` if `self` doesn't have [`Mesh::ATTRIBUTE_POSITION`] of
/// type [`VertexAttributeValues::Float32x3`], or if `self` doesn't have any vertices.
fn compute_aabb(&self) -> Option<Aabb>;
}
impl MeshAabb for Mesh {
fn compute_aabb(&self) -> Option<Aabb> {
let Some(VertexAttributeValues::Float32x3(values)) =
self.attribute(Mesh::ATTRIBUTE_POSITION)
else {
return None;
};
Aabb::enclosing(values.iter().map(|p| Vec3::from_slice(p)))
}
}
/// The render world representation of a [`Mesh`].
#[derive(Debug, Clone)]
pub struct RenderMesh {
/// The number of vertices in the mesh.
pub vertex_count: u32,
/// Morph targets for the mesh, if present.
pub morph_targets: Option<TextureView>,
/// Information about the mesh data buffers, including whether the mesh uses
/// indices or not.
pub buffer_info: RenderMeshBufferInfo,
/// Precomputed pipeline key bits for this mesh.
pub key_bits: BaseMeshPipelineKey,
/// A reference to the vertex buffer layout.
///
/// Combined with [`RenderMesh::buffer_info`], this specifies the complete
/// layout of the buffers associated with this mesh.
pub layout: MeshVertexBufferLayoutRef,
}
impl RenderMesh {
/// Returns the primitive topology of this mesh (triangles, triangle strips,
/// etc.)
#[inline]
pub fn primitive_topology(&self) -> PrimitiveTopology {
self.key_bits.primitive_topology()
}
/// Returns true if this mesh uses an index buffer or false otherwise.
#[inline]
pub fn indexed(&self) -> bool {
matches!(self.buffer_info, RenderMeshBufferInfo::Indexed { .. })
}
}
/// The index/vertex buffer info of a [`RenderMesh`].
#[derive(Debug, Clone)]
pub enum RenderMeshBufferInfo {
Indexed {
count: u32,
index_format: IndexFormat,
},
NonIndexed,
}
impl RenderAsset for RenderMesh {
type SourceAsset = Mesh;
type Param = (
SRes<RenderAssets<GpuImage>>,
SResMut<MeshVertexBufferLayouts>,
);
#[inline]
fn asset_usage(mesh: &Self::SourceAsset) -> RenderAssetUsages {
mesh.asset_usage
}
fn byte_len(mesh: &Self::SourceAsset) -> Option<usize> {
let mut vertex_size = 0;
for attribute_data in mesh.attributes() {
let vertex_format = attribute_data.0.format;
vertex_size += vertex_format.size() as usize;
}
let vertex_count = mesh.count_vertices();
let index_bytes = mesh.get_index_buffer_bytes().map(<[_]>::len).unwrap_or(0);
Some(vertex_size * vertex_count + index_bytes)
}
/// Converts the extracted mesh into a [`RenderMesh`].
fn prepare_asset(
mesh: Self::SourceAsset,
_: AssetId<Self::SourceAsset>,
(images, mesh_vertex_buffer_layouts): &mut SystemParamItem<Self::Param>,
) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
let morph_targets = match mesh.morph_targets() {
Some(mt) => {
let Some(target_image) = images.get(mt) else {
return Err(PrepareAssetError::RetryNextUpdate(mesh));
};
Some(target_image.texture_view.clone())
}
None => None,
};
let buffer_info = match mesh.indices() {
Some(indices) => RenderMeshBufferInfo::Indexed {
count: indices.len() as u32,
index_format: indices.into(),
},
None => RenderMeshBufferInfo::NonIndexed,
};
let mesh_vertex_buffer_layout =
mesh.get_mesh_vertex_buffer_layout(mesh_vertex_buffer_layouts);
let mut key_bits = BaseMeshPipelineKey::from_primitive_topology(mesh.primitive_topology());
key_bits.set(
BaseMeshPipelineKey::MORPH_TARGETS,
mesh.morph_targets().is_some(),
);
Ok(RenderMesh {
vertex_count: mesh.count_vertices() as u32,
buffer_info,
key_bits,
layout: mesh_vertex_buffer_layout,
morph_targets,
})
}
}