bevy_mesh/
lib.rs

1#![expect(missing_docs, reason = "Not all docs are written yet, see #3492.")]
2
3extern crate alloc;
4extern crate core;
5
6mod components;
7mod conversions;
8mod index;
9mod mesh;
10mod mikktspace;
11pub mod morph;
12pub mod primitives;
13pub mod skinning;
14mod vertex;
15use bevy_app::{App, Plugin, PostUpdate};
16use bevy_asset::{AssetApp, AssetEventSystems};
17use bevy_ecs::schedule::{IntoScheduleConfigs, SystemSet};
18use bitflags::bitflags;
19pub use components::*;
20pub use index::*;
21pub use mesh::*;
22pub use mikktspace::*;
23pub use primitives::*;
24pub use vertex::*;
25pub use wgpu_types::VertexFormat;
26
27/// The mesh prelude.
28///
29/// This includes the most common types in this crate, re-exported for your convenience.
30pub mod prelude {
31    #[doc(hidden)]
32    pub use crate::{
33        morph::MorphWeights, primitives::MeshBuilder, primitives::Meshable, Mesh, Mesh2d, Mesh3d,
34    };
35}
36
37bitflags! {
38    /// Our base mesh pipeline key bits start from the highest bit and go
39    /// downward. The PBR mesh pipeline key bits start from the lowest bit and
40    /// go upward. This allows the PBR bits in the downstream crate `bevy_pbr`
41    /// to coexist in the same field without any shifts.
42    #[derive(Clone, Debug)]
43    pub struct BaseMeshPipelineKey: u64 {
44        const MORPH_TARGETS = 1 << (u64::BITS - 1);
45    }
46}
47
48/// Adds [`Mesh`] as an asset.
49#[derive(Default)]
50pub struct MeshPlugin;
51
52impl Plugin for MeshPlugin {
53    fn build(&self, app: &mut App) {
54        app.init_asset::<Mesh>()
55            .init_asset::<skinning::SkinnedMeshInverseBindposes>()
56            .register_asset_reflect::<Mesh>()
57            .add_systems(
58                PostUpdate,
59                mark_3d_meshes_as_changed_if_their_assets_changed.after(AssetEventSystems),
60            );
61    }
62}
63
64impl BaseMeshPipelineKey {
65    pub const PRIMITIVE_TOPOLOGY_MASK_BITS: u64 = 0b111;
66    pub const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u64 =
67        (u64::BITS - 1 - Self::PRIMITIVE_TOPOLOGY_MASK_BITS.count_ones()) as u64;
68
69    pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self {
70        let primitive_topology_bits = ((primitive_topology as u64)
71            & Self::PRIMITIVE_TOPOLOGY_MASK_BITS)
72            << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
73        Self::from_bits_retain(primitive_topology_bits)
74    }
75
76    pub fn primitive_topology(&self) -> PrimitiveTopology {
77        let primitive_topology_bits = (self.bits() >> Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
78            & Self::PRIMITIVE_TOPOLOGY_MASK_BITS;
79        match primitive_topology_bits {
80            x if x == PrimitiveTopology::PointList as u64 => PrimitiveTopology::PointList,
81            x if x == PrimitiveTopology::LineList as u64 => PrimitiveTopology::LineList,
82            x if x == PrimitiveTopology::LineStrip as u64 => PrimitiveTopology::LineStrip,
83            x if x == PrimitiveTopology::TriangleList as u64 => PrimitiveTopology::TriangleList,
84            x if x == PrimitiveTopology::TriangleStrip as u64 => PrimitiveTopology::TriangleStrip,
85            _ => PrimitiveTopology::default(),
86        }
87    }
88}
89
90/// `bevy_render::mesh::inherit_weights` runs in this `SystemSet`
91#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
92pub struct InheritWeightSystems;