mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 12:13:25 +00:00
Improve Mesh
documentation (#9061)
# Objective This PR continues https://github.com/bevyengine/bevy/pull/8885 It aims to improve the `Mesh` documentation in the following ways: - Put everything at the "top level" instead of the "impl". - Explain better what is a Mesh, how it can be created, and that it can be edited. - Explain it can be used with a `Material`, and mention `StandardMaterial`, `PbrBundle`, `ColorMaterial`, and `ColorMesh2dBundle` since those cover most cases - Mention the glTF/Bevy vocabulary discrepancy for "Mesh" - Add an image for the example - Various nitpicky modifications ## Note - The image I added is 90.3ko which I think is small enough? - Since rustdoc doesn't allow cross-reference not in dependencies of a subcrate [yet](https://github.com/rust-lang/rust/issues/74481), I have a lot of backtick references that are not links :( - Since rustdoc doesn't allow linking to code in the crate (?) I put link to github directly. - Since rustdoc doesn't allow embed images in doc [yet](https://github.com/rust-lang/rust/issues/32104), maybe [soon](https://github.com/rust-lang/rfcs/pull/3397), I had to put only a link to the image. I don't think it's worth adding [embed_doc_image](https://docs.rs/embed-doc-image/latest/embed_doc_image/) as a dependency for this.
This commit is contained in:
parent
3c6fad269b
commit
cbe13f3aa5
4 changed files with 81 additions and 44 deletions
BIN
assets/docs/Mesh.png
Normal file
BIN
assets/docs/Mesh.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
|
@ -14,8 +14,8 @@ use std::path::Path;
|
||||||
|
|
||||||
/// A loader for an asset source.
|
/// A loader for an asset source.
|
||||||
///
|
///
|
||||||
/// Types implementing this trait are used by the asset server to load assets into their respective
|
/// Types implementing this trait are used by the [`AssetServer`] to load assets
|
||||||
/// asset storages.
|
/// into their respective asset storages.
|
||||||
pub trait AssetLoader: Send + Sync + 'static {
|
pub trait AssetLoader: Send + Sync + 'static {
|
||||||
/// Processes the asset in an asynchronous closure.
|
/// Processes the asset in an asynchronous closure.
|
||||||
fn load<'a>(
|
fn load<'a>(
|
||||||
|
|
|
@ -60,7 +60,8 @@ impl Plugin for GltfPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Representation of a loaded glTF file.
|
/// Representation of a loaded glTF file
|
||||||
|
/// (file loaded via the `AssetServer` with the extension `.glb` or `.gltf`).
|
||||||
#[derive(Debug, TypeUuid, TypePath)]
|
#[derive(Debug, TypeUuid, TypePath)]
|
||||||
#[uuid = "5c7d5f8a-f7b0-4e45-a09e-406c0372fea2"]
|
#[uuid = "5c7d5f8a-f7b0-4e45-a09e-406c0372fea2"]
|
||||||
pub struct Gltf {
|
pub struct Gltf {
|
||||||
|
|
|
@ -26,28 +26,24 @@ use wgpu::{
|
||||||
pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
|
pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
|
||||||
pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
||||||
|
|
||||||
// TODO: allow values to be unloaded after been submitting to the GPU to conserve memory
|
/// A 3D object made out of vertices representing triangles, lines, or points,
|
||||||
#[derive(Debug, TypeUuid, TypePath, Clone)]
|
/// with "attribute" values for each vertex.
|
||||||
#[uuid = "8ecbac0f-f545-4473-ad43-e1f4243af51e"]
|
|
||||||
pub struct Mesh {
|
|
||||||
primitive_topology: PrimitiveTopology,
|
|
||||||
/// `std::collections::BTreeMap` with all defined vertex attributes (Positions, Normals, ...)
|
|
||||||
/// for this mesh. Attribute ids to attribute values.
|
|
||||||
/// Uses a BTreeMap because, unlike HashMap, it has a defined iteration order,
|
|
||||||
/// which allows easy stable VertexBuffers (i.e. same buffer order)
|
|
||||||
attributes: BTreeMap<MeshVertexAttributeId, MeshAttributeData>,
|
|
||||||
indices: Option<Indices>,
|
|
||||||
morph_targets: Option<Handle<Image>>,
|
|
||||||
morph_target_names: Option<Vec<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Contains geometry in the form of a mesh.
|
|
||||||
///
|
///
|
||||||
/// Often meshes are automatically generated by bevy's asset loaders or primitives, such as
|
/// Meshes can be automatically generated by a bevy `AssetLoader` (generally by loading a `Gltf` file),
|
||||||
/// [`shape::Cube`](crate::mesh::shape::Cube) or [`shape::Box`](crate::mesh::shape::Box), but you can also construct
|
/// or by converting a primitive [`shape`](crate::mesh::shape) using [`into`](std::convert::Into).
|
||||||
/// one yourself.
|
/// It is also possible to create one manually.
|
||||||
|
/// They can be edited after creation.
|
||||||
///
|
///
|
||||||
/// Example of constructing a mesh (to be rendered with a `StandardMaterial`):
|
/// Meshes can be rendered with a `Material`, like `StandardMaterial` in `PbrBundle`
|
||||||
|
/// or `ColorMaterial` in `ColorMesh2dBundle`.
|
||||||
|
///
|
||||||
|
/// A [`Mesh`] in Bevy is equivalent to a "primitive" in the glTF format, for a
|
||||||
|
/// glTF Mesh representation, see `GltfMesh`.
|
||||||
|
///
|
||||||
|
/// ## Manual creation
|
||||||
|
///
|
||||||
|
/// The following function will construct a flat mesh, to be rendered with a
|
||||||
|
/// `StandardMaterial` or `ColorMaterial`:
|
||||||
/// ```
|
/// ```
|
||||||
/// # use bevy_render::mesh::{Mesh, Indices};
|
/// # use bevy_render::mesh::{Mesh, Indices};
|
||||||
/// # use bevy_render::render_resource::PrimitiveTopology;
|
/// # use bevy_render::render_resource::PrimitiveTopology;
|
||||||
|
@ -78,50 +74,90 @@ pub struct Mesh {
|
||||||
/// 1, 3, 2
|
/// 1, 3, 2
|
||||||
/// ])));
|
/// ])));
|
||||||
/// mesh
|
/// mesh
|
||||||
/// // For further visualization, explanation, and examples see the built-in Bevy examples
|
|
||||||
/// // and the implementation of the built-in shapes.
|
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// Common points of confusion:
|
|
||||||
/// - UV maps in Bevy are "flipped", (0.0, 0.0) = Top-Left (not Bot-Left like `OpenGL`)
|
|
||||||
/// - It is normal for multiple vertices to have the same position
|
|
||||||
/// attribute - it's a common technique in 3D modelling for complex UV mapping or other calculations.
|
|
||||||
///
|
///
|
||||||
/// To render correctly with `StandardMaterial` a mesh needs to have properly defined:
|
/// You can see how it looks like [here](https://github.com/bevyengine/bevy/blob/main/assets/dovs/Mesh.png),
|
||||||
/// - [`UVs`](Mesh::ATTRIBUTE_UV_0): Bevy needs to know how to map a texture onto the mesh.
|
/// used in a `PbrBundle` with a square bevy logo texture, with added axis, points,
|
||||||
/// - [`Normals`](Mesh::ATTRIBUTE_NORMAL): Bevy needs to know how light interacts with your mesh. ([0.0, 0.0, 1.0] is very
|
/// lines and text for clarity.
|
||||||
/// common for simple meshes because simple meshes are smooth, and they don't require complex light calculations.)
|
|
||||||
/// - Vertex winding order -
|
|
||||||
/// the default behavior is with `StandardMaterial.cull_mode` = Some([`Face::Front`](crate::render_resource::Face::Front)) which means
|
|
||||||
/// that by default Bevy would *only* render the front of each triangle, and the front
|
|
||||||
/// is the side of the triangle in which the vertices appear in a *counter-clockwise* order.
|
|
||||||
///
|
///
|
||||||
|
/// ## Other examples
|
||||||
|
///
|
||||||
|
/// For further visualization, explanation, and examples, see the built-in Bevy examples,
|
||||||
|
/// and the [implementation of the built-in shapes](https://github.com/bevyengine/bevy/tree/main/crates/bevy_render/src/mesh/shape).
|
||||||
|
/// In particular, [generate_custom_mesh](https://github.com/bevyengine/bevy/blob/main/examples/3d/generate_custom_mesh.rs)
|
||||||
|
/// teaches you to access modify a Mesh's attributes after creating it.
|
||||||
|
///
|
||||||
|
/// ## Common points of confusion
|
||||||
|
///
|
||||||
|
/// - UV maps in Bevy start at the top-left, see [`ATTRIBUTE_UV_0`](Mesh::ATTRIBUTE_UV_0),
|
||||||
|
/// other APIs can have other conventions, `OpenGL` starts at bottom-left.
|
||||||
|
/// - It is possible and sometimes useful for multiple vertices to have the same
|
||||||
|
/// [position attribute](Mesh::ATTRIBUTE_POSITION) value,
|
||||||
|
/// it's a common technique in 3D modelling for complex UV mapping or other calculations.
|
||||||
|
///
|
||||||
|
/// ## Use with `StandardMaterial`
|
||||||
|
///
|
||||||
|
/// To render correctly with `StandardMaterial`, a mesh needs to have properly defined:
|
||||||
|
/// - [`UVs`](Mesh::ATTRIBUTE_UV_0): Bevy needs to know how to map a texture onto the mesh
|
||||||
|
/// (also true for `ColorMaterial`).
|
||||||
|
/// - [`Normals`](Mesh::ATTRIBUTE_NORMAL): Bevy needs to know how light interacts with your mesh.
|
||||||
|
/// [0.0, 0.0, 1.0] is very common for simple flat meshes on the XY plane,
|
||||||
|
/// because simple meshes are smooth and they don't require complex light calculations.
|
||||||
|
/// - Vertex winding order: by default, `StandardMaterial.cull_mode` is [`Some(Face::Back)`](crate::render_resource::Face),
|
||||||
|
/// which means that Bevy would *only* render the "front" of each triangle, which
|
||||||
|
/// is the side of the triangle from where the vertices appear in a *counter-clockwise* order.
|
||||||
|
///
|
||||||
|
// TODO: allow values to be unloaded after been submitting to the GPU to conserve memory
|
||||||
|
#[derive(Debug, TypeUuid, TypePath, Clone)]
|
||||||
|
#[uuid = "8ecbac0f-f545-4473-ad43-e1f4243af51e"]
|
||||||
|
pub struct Mesh {
|
||||||
|
primitive_topology: PrimitiveTopology,
|
||||||
|
/// `std::collections::BTreeMap` with all defined vertex attributes (Positions, Normals, ...)
|
||||||
|
/// for this mesh. Attribute ids to attribute values.
|
||||||
|
/// Uses a BTreeMap because, unlike HashMap, it has a defined iteration order,
|
||||||
|
/// which allows easy stable VertexBuffers (i.e. same buffer order)
|
||||||
|
attributes: BTreeMap<MeshVertexAttributeId, MeshAttributeData>,
|
||||||
|
indices: Option<Indices>,
|
||||||
|
morph_targets: Option<Handle<Image>>,
|
||||||
|
morph_target_names: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
/// Where the vertex is located in space. Use in conjunction with [`Mesh::insert_attribute`]
|
/// Where the vertex is located in space. Use in conjunction with [`Mesh::insert_attribute`].
|
||||||
pub const ATTRIBUTE_POSITION: MeshVertexAttribute =
|
pub const ATTRIBUTE_POSITION: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_Position", 0, VertexFormat::Float32x3);
|
MeshVertexAttribute::new("Vertex_Position", 0, VertexFormat::Float32x3);
|
||||||
|
|
||||||
/// The direction the vertex normal is facing in.
|
/// The direction the vertex normal is facing in.
|
||||||
/// Use in conjunction with [`Mesh::insert_attribute`]
|
/// Use in conjunction with [`Mesh::insert_attribute`].
|
||||||
pub const ATTRIBUTE_NORMAL: MeshVertexAttribute =
|
pub const ATTRIBUTE_NORMAL: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_Normal", 1, VertexFormat::Float32x3);
|
MeshVertexAttribute::new("Vertex_Normal", 1, VertexFormat::Float32x3);
|
||||||
|
|
||||||
/// Texture coordinates for the vertex. Use in conjunction with [`Mesh::insert_attribute`]
|
/// Texture coordinates for the vertex. Use in conjunction with [`Mesh::insert_attribute`].
|
||||||
|
///
|
||||||
|
/// Values are generally between 0. and 1., with `StandardMaterial` and `ColorMaterial`
|
||||||
|
/// `[0.,0.]` is the top left of the texture, and [1.,1.] the bottom-right.
|
||||||
|
/// You usually want to only use values in that range, values outside will be
|
||||||
|
/// clamped per pixel not for the vertex, "stretching" the borders of the texture.
|
||||||
|
/// This behavior can be useful in some cases, usually when the borders have only
|
||||||
|
/// one color, for example a logo, and you want to "extend" those borders.
|
||||||
pub const ATTRIBUTE_UV_0: MeshVertexAttribute =
|
pub const ATTRIBUTE_UV_0: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_Uv", 2, VertexFormat::Float32x2);
|
MeshVertexAttribute::new("Vertex_Uv", 2, VertexFormat::Float32x2);
|
||||||
|
|
||||||
/// The direction of the vertex tangent. Used for normal mapping
|
/// The direction of the vertex tangent. Used for normal mapping.
|
||||||
|
/// Usually generated with [`generate_tangents`](Mesh::generate_tangents).
|
||||||
pub const ATTRIBUTE_TANGENT: MeshVertexAttribute =
|
pub const ATTRIBUTE_TANGENT: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_Tangent", 3, VertexFormat::Float32x4);
|
MeshVertexAttribute::new("Vertex_Tangent", 3, VertexFormat::Float32x4);
|
||||||
|
|
||||||
/// Per vertex coloring. Use in conjunction with [`Mesh::insert_attribute`]
|
/// Per vertex coloring. Use in conjunction with [`Mesh::insert_attribute`].
|
||||||
pub const ATTRIBUTE_COLOR: MeshVertexAttribute =
|
pub const ATTRIBUTE_COLOR: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_Color", 4, VertexFormat::Float32x4);
|
MeshVertexAttribute::new("Vertex_Color", 4, VertexFormat::Float32x4);
|
||||||
|
|
||||||
/// Per vertex joint transform matrix weight. Use in conjunction with [`Mesh::insert_attribute`]
|
/// Per vertex joint transform matrix weight. Use in conjunction with [`Mesh::insert_attribute`].
|
||||||
pub const ATTRIBUTE_JOINT_WEIGHT: MeshVertexAttribute =
|
pub const ATTRIBUTE_JOINT_WEIGHT: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_JointWeight", 5, VertexFormat::Float32x4);
|
MeshVertexAttribute::new("Vertex_JointWeight", 5, VertexFormat::Float32x4);
|
||||||
/// Per vertex joint transform matrix index. Use in conjunction with [`Mesh::insert_attribute`]
|
|
||||||
|
/// Per vertex joint transform matrix index. Use in conjunction with [`Mesh::insert_attribute`].
|
||||||
pub const ATTRIBUTE_JOINT_INDEX: MeshVertexAttribute =
|
pub const ATTRIBUTE_JOINT_INDEX: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("Vertex_JointIndex", 6, VertexFormat::Uint16x4);
|
MeshVertexAttribute::new("Vertex_JointIndex", 6, VertexFormat::Uint16x4);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue