forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split out bevy_mesh from bevy_render (bevyengine#15666)
# Objective - bevy_render is gargantuan ## Solution - Split out bevy_mesh ## Testing - Ran some examples, everything looks fine ## Migration Guide `bevy_render::mesh::morph::inherit_weights` is now `bevy_render::mesh::inherit_weights` if you were using `Mesh::compute_aabb`, you will need to `use bevy_render::mesh::MeshAabb;` now --------- Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
- Loading branch information
Showing
32 changed files
with
1,087 additions
and
1,042 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
[package] | ||
name = "bevy_mesh" | ||
version = "0.15.0-dev" | ||
edition = "2021" | ||
description = "Provides mesh types for Bevy Engine" | ||
homepage = "https://bevyengine.org" | ||
repository = "https://github.com/bevyengine/bevy" | ||
license = "MIT OR Apache-2.0" | ||
keywords = ["bevy"] | ||
|
||
[dependencies] | ||
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" } | ||
bevy_image = { path = "../bevy_image", version = "0.15.0-dev" } | ||
bevy_math = { path = "../bevy_math", version = "0.15.0-dev" } | ||
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [ | ||
"bevy", | ||
] } | ||
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" } | ||
bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" } | ||
bevy_mikktspace = { path = "../bevy_mikktspace", version = "0.15.0-dev" } | ||
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" } | ||
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" } | ||
|
||
# misc | ||
bitflags = { version = "2.3", features = ["serde"] } | ||
bytemuck = { version = "1.5" } | ||
wgpu = { version = "22", default-features = false } | ||
serde = { version = "1", features = ["derive"] } | ||
hexasphere = "15.0" | ||
thiserror = "1.0" | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[package.metadata.docs.rs] | ||
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"] | ||
all-features = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
use bevy_reflect::Reflect; | ||
use core::iter::FusedIterator; | ||
use thiserror::Error; | ||
use wgpu::IndexFormat; | ||
|
||
/// A disjunction of four iterators. This is necessary to have a well-formed type for the output | ||
/// of [`Mesh::triangles`](super::Mesh::triangles), which produces iterators of four different types depending on the | ||
/// branch taken. | ||
pub(crate) enum FourIterators<A, B, C, D> { | ||
First(A), | ||
Second(B), | ||
Third(C), | ||
Fourth(D), | ||
} | ||
|
||
impl<A, B, C, D, I> Iterator for FourIterators<A, B, C, D> | ||
where | ||
A: Iterator<Item = I>, | ||
B: Iterator<Item = I>, | ||
C: Iterator<Item = I>, | ||
D: Iterator<Item = I>, | ||
{ | ||
type Item = I; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
match self { | ||
FourIterators::First(iter) => iter.next(), | ||
FourIterators::Second(iter) => iter.next(), | ||
FourIterators::Third(iter) => iter.next(), | ||
FourIterators::Fourth(iter) => iter.next(), | ||
} | ||
} | ||
} | ||
|
||
/// An error that occurred while trying to invert the winding of a [`Mesh`](super::Mesh). | ||
#[derive(Debug, Error)] | ||
pub enum MeshWindingInvertError { | ||
/// This error occurs when you try to invert the winding for a mesh with [`PrimitiveTopology::PointList`](super::PrimitiveTopology::PointList). | ||
#[error("Mesh winding invertation does not work for primitive topology `PointList`")] | ||
WrongTopology, | ||
|
||
/// This error occurs when you try to invert the winding for a mesh with | ||
/// * [`PrimitiveTopology::TriangleList`](super::PrimitiveTopology::TriangleList), but the indices are not in chunks of 3. | ||
/// * [`PrimitiveTopology::LineList`](super::PrimitiveTopology::LineList), but the indices are not in chunks of 2. | ||
#[error("Indices weren't in chunks according to topology")] | ||
AbruptIndicesEnd, | ||
} | ||
|
||
/// An error that occurred while trying to extract a collection of triangles from a [`Mesh`](super::Mesh). | ||
#[derive(Debug, Error)] | ||
pub enum MeshTrianglesError { | ||
#[error("Source mesh does not have primitive topology TriangleList or TriangleStrip")] | ||
WrongTopology, | ||
|
||
#[error("Source mesh lacks position data")] | ||
MissingPositions, | ||
|
||
#[error("Source mesh position data is not Float32x3")] | ||
PositionsFormat, | ||
|
||
#[error("Source mesh lacks face index data")] | ||
MissingIndices, | ||
|
||
#[error("Face index data references vertices that do not exist")] | ||
BadIndices, | ||
} | ||
|
||
/// An array of indices into the [`VertexAttributeValues`](super::VertexAttributeValues) for a mesh. | ||
/// | ||
/// It describes the order in which the vertex attributes should be joined into faces. | ||
#[derive(Debug, Clone, Reflect)] | ||
pub enum Indices { | ||
U16(Vec<u16>), | ||
U32(Vec<u32>), | ||
} | ||
|
||
impl Indices { | ||
/// Returns an iterator over the indices. | ||
pub fn iter(&self) -> impl Iterator<Item = usize> + '_ { | ||
match self { | ||
Indices::U16(vec) => IndicesIter::U16(vec.iter()), | ||
Indices::U32(vec) => IndicesIter::U32(vec.iter()), | ||
} | ||
} | ||
|
||
/// Returns the number of indices. | ||
pub fn len(&self) -> usize { | ||
match self { | ||
Indices::U16(vec) => vec.len(), | ||
Indices::U32(vec) => vec.len(), | ||
} | ||
} | ||
|
||
/// Returns `true` if there are no indices. | ||
pub fn is_empty(&self) -> bool { | ||
match self { | ||
Indices::U16(vec) => vec.is_empty(), | ||
Indices::U32(vec) => vec.is_empty(), | ||
} | ||
} | ||
} | ||
|
||
/// An Iterator for the [`Indices`]. | ||
enum IndicesIter<'a> { | ||
U16(core::slice::Iter<'a, u16>), | ||
U32(core::slice::Iter<'a, u32>), | ||
} | ||
|
||
impl Iterator for IndicesIter<'_> { | ||
type Item = usize; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
match self { | ||
IndicesIter::U16(iter) => iter.next().map(|val| *val as usize), | ||
IndicesIter::U32(iter) => iter.next().map(|val| *val as usize), | ||
} | ||
} | ||
|
||
fn size_hint(&self) -> (usize, Option<usize>) { | ||
match self { | ||
IndicesIter::U16(iter) => iter.size_hint(), | ||
IndicesIter::U32(iter) => iter.size_hint(), | ||
} | ||
} | ||
} | ||
|
||
impl<'a> ExactSizeIterator for IndicesIter<'a> {} | ||
impl<'a> FusedIterator for IndicesIter<'a> {} | ||
|
||
impl From<&Indices> for IndexFormat { | ||
fn from(indices: &Indices) -> Self { | ||
match indices { | ||
Indices::U16(_) => IndexFormat::Uint16, | ||
Indices::U32(_) => IndexFormat::Uint32, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// FIXME(15321): solve CI failures, then replace with `#![expect()]`. | ||
#![allow(missing_docs, reason = "Not all docs are written yet, see #3492.")] | ||
#![allow(unsafe_code)] | ||
|
||
extern crate alloc; | ||
extern crate core; | ||
|
||
mod conversions; | ||
mod index; | ||
mod mesh; | ||
mod mikktspace; | ||
pub mod morph; | ||
pub mod primitives; | ||
pub mod skinning; | ||
mod vertex; | ||
use bitflags::bitflags; | ||
pub use index::*; | ||
pub use mesh::*; | ||
pub use mikktspace::*; | ||
pub use primitives::*; | ||
pub use vertex::*; | ||
|
||
bitflags! { | ||
/// Our base mesh pipeline key bits start from the highest bit and go | ||
/// downward. The PBR mesh pipeline key bits start from the lowest bit and | ||
/// go upward. This allows the PBR bits in the downstream crate `bevy_pbr` | ||
/// to coexist in the same field without any shifts. | ||
#[derive(Clone, Debug)] | ||
pub struct BaseMeshPipelineKey: u64 { | ||
const MORPH_TARGETS = 1 << (u64::BITS - 1); | ||
} | ||
} | ||
|
||
impl BaseMeshPipelineKey { | ||
pub const PRIMITIVE_TOPOLOGY_MASK_BITS: u64 = 0b111; | ||
pub const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u64 = | ||
(u64::BITS - 1 - Self::PRIMITIVE_TOPOLOGY_MASK_BITS.count_ones()) as u64; | ||
|
||
pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self { | ||
let primitive_topology_bits = ((primitive_topology as u64) | ||
& Self::PRIMITIVE_TOPOLOGY_MASK_BITS) | ||
<< Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS; | ||
Self::from_bits_retain(primitive_topology_bits) | ||
} | ||
|
||
pub fn primitive_topology(&self) -> PrimitiveTopology { | ||
let primitive_topology_bits = (self.bits() >> Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS) | ||
& Self::PRIMITIVE_TOPOLOGY_MASK_BITS; | ||
match primitive_topology_bits { | ||
x if x == PrimitiveTopology::PointList as u64 => PrimitiveTopology::PointList, | ||
x if x == PrimitiveTopology::LineList as u64 => PrimitiveTopology::LineList, | ||
x if x == PrimitiveTopology::LineStrip as u64 => PrimitiveTopology::LineStrip, | ||
x if x == PrimitiveTopology::TriangleList as u64 => PrimitiveTopology::TriangleList, | ||
x if x == PrimitiveTopology::TriangleStrip as u64 => PrimitiveTopology::TriangleStrip, | ||
_ => PrimitiveTopology::default(), | ||
} | ||
} | ||
} |
Oops, something went wrong.