Struct Mesh

Source
pub struct Mesh {
    pub asset_usage: RenderAssetUsages,
    /* private fields */
}
Expand description

A 3D object made out of vertices representing triangles, lines, or points, with “attribute” values for each vertex.

Meshes can be automatically generated by a bevy AssetLoader (generally by loading a Gltf file), or by converting a primitive using into. It is also possible to create one manually. They can be edited after creation.

Meshes can be rendered with a Mesh2d and MeshMaterial2d or Mesh3d and MeshMaterial3d for 2D and 3D respectively.

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:

fn create_simple_parallelogram() -> Mesh {
    // Create a new mesh using a triangle list topology, where each set of 3 vertices composes a triangle.
    Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::default())
        // Add 4 vertices, each with its own position attribute (coordinate in
        // 3D space), for each of the corners of the parallelogram.
        .with_inserted_attribute(
            Mesh::ATTRIBUTE_POSITION,
            vec![[0.0, 0.0, 0.0], [1.0, 2.0, 0.0], [2.0, 2.0, 0.0], [1.0, 0.0, 0.0]]
        )
        // Assign a UV coordinate to each vertex.
        .with_inserted_attribute(
            Mesh::ATTRIBUTE_UV_0,
            vec![[0.0, 1.0], [0.5, 0.0], [1.0, 0.0], [0.5, 1.0]]
        )
        // Assign normals (everything points outwards)
        .with_inserted_attribute(
            Mesh::ATTRIBUTE_NORMAL,
            vec![[0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]
        )
        // After defining all the vertices and their attributes, build each triangle using the
        // indices of the vertices that make it up in a counter-clockwise order.
        .with_inserted_indices(Indices::U32(vec![
            // First triangle
            0, 3, 1,
            // Second triangle
            1, 3, 2
        ]))
}

You can see how it looks like here, used in a Mesh3d with a square bevy logo texture, with added axis, points, lines and text for clarity.

§Other examples

For further visualization, explanation, and examples, see the built-in Bevy examples, and the implementation of the built-in shapes. In particular, generate_custom_mesh teaches you to access and modify the attributes of a Mesh after creating it.

§Common points of confusion

  • UV maps in Bevy start at the top-left, see 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 value, it’s a common technique in 3D modeling for complex UV mapping or other calculations.
  • Bevy performs frustum culling based on the Aabb of meshes, which is calculated and added automatically for new meshes only. If a mesh is modified, the entity’s Aabb needs to be updated manually or deleted so that it is re-calculated.

§Use with StandardMaterial

To render correctly with StandardMaterial, a mesh needs to have properly defined:

  • UVs: Bevy needs to know how to map a texture onto the mesh (also true for ColorMaterial).
  • Normals: 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), 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.

Fields§

§asset_usage: RenderAssetUsages

Implementations§

Source§

impl Mesh

Source

pub const ATTRIBUTE_POSITION: MeshVertexAttribute

Where the vertex is located in space. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

The format of this attribute is VertexFormat::Float32x3.

Source

pub const ATTRIBUTE_NORMAL: MeshVertexAttribute

The direction the vertex normal is facing in. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

The format of this attribute is VertexFormat::Float32x3.

Source

pub const ATTRIBUTE_UV_0: MeshVertexAttribute

Texture coordinates for the vertex. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

Generally [0.,0.] is mapped to the top left of the texture, and [1.,1.] to the bottom-right.

By default 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.

For different mapping outside of 0..=1 range, see ImageAddressMode.

The format of this attribute is VertexFormat::Float32x2.

Source

pub const ATTRIBUTE_UV_1: MeshVertexAttribute

Alternate texture coordinates for the vertex. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

Typically, these are used for lightmaps, textures that provide precomputed illumination.

The format of this attribute is VertexFormat::Float32x2.

Source

pub const ATTRIBUTE_TANGENT: MeshVertexAttribute

The direction of the vertex tangent. Used for normal mapping. Usually generated with generate_tangents or with_generated_tangents.

The format of this attribute is VertexFormat::Float32x4.

Source

pub const ATTRIBUTE_COLOR: MeshVertexAttribute

Per vertex coloring. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

The format of this attribute is VertexFormat::Float32x4.

Source

pub const ATTRIBUTE_JOINT_WEIGHT: MeshVertexAttribute

Per vertex joint transform matrix weight. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

The format of this attribute is VertexFormat::Float32x4.

Source

pub const ATTRIBUTE_JOINT_INDEX: MeshVertexAttribute

Per vertex joint transform matrix index. Use in conjunction with Mesh::insert_attribute or Mesh::with_inserted_attribute.

The format of this attribute is VertexFormat::Uint16x4.

Source

pub fn new( primitive_topology: PrimitiveTopology, asset_usage: RenderAssetUsages, ) -> Mesh

Construct a new mesh. You need to provide a PrimitiveTopology so that the renderer knows how to treat the vertex data. Most of the time this will be PrimitiveTopology::TriangleList.

Examples found in repository?
examples/3d/lines.rs (lines 101-106)
98    fn from(line: LineList) -> Self {
99        let vertices: Vec<_> = line.lines.into_iter().flat_map(|(a, b)| [a, b]).collect();
100
101        Mesh::new(
102            // This tells wgpu that the positions are list of lines
103            // where every pair is a start and end point
104            PrimitiveTopology::LineList,
105            RenderAssetUsages::RENDER_WORLD,
106        )
107        // Add the vertices positions as an attribute
108        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
109    }
110}
111
112/// A list of points that will have a line drawn between each consecutive points
113#[derive(Debug, Clone)]
114struct LineStrip {
115    points: Vec<Vec3>,
116}
117
118impl From<LineStrip> for Mesh {
119    fn from(line: LineStrip) -> Self {
120        Mesh::new(
121            // This tells wgpu that the positions are a list of points
122            // where a line will be drawn between each consecutive point
123            PrimitiveTopology::LineStrip,
124            RenderAssetUsages::RENDER_WORLD,
125        )
126        // Add the point positions as an attribute
127        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, line.points)
128    }
More examples
Hide additional examples
examples/shader/specialized_mesh_pipeline.rs (lines 61-64)
57fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
58    // Build a custom triangle mesh with colors
59    // We define a custom mesh because the examples only uses a limited
60    // set of vertex attributes for simplicity
61    let mesh = Mesh::new(
62        PrimitiveTopology::TriangleList,
63        RenderAssetUsages::default(),
64    )
65    .with_inserted_indices(Indices::U32(vec![0, 1, 2]))
66    .with_inserted_attribute(
67        Mesh::ATTRIBUTE_POSITION,
68        vec![
69            vec3(-0.5, -0.5, 0.0),
70            vec3(0.5, -0.5, 0.0),
71            vec3(0.0, 0.25, 0.0),
72        ],
73    )
74    .with_inserted_attribute(
75        Mesh::ATTRIBUTE_COLOR,
76        vec![
77            vec4(1.0, 0.0, 0.0, 1.0),
78            vec4(0.0, 1.0, 0.0, 1.0),
79            vec4(0.0, 0.0, 1.0, 1.0),
80        ],
81    );
82
83    // spawn 3 triangles to show that batching works
84    for (x, y) in [-0.5, 0.0, 0.5].into_iter().zip([-0.25, 0.5, -0.25]) {
85        // Spawn an entity with all the required components for it to be rendered with our custom pipeline
86        commands.spawn((
87            // We use a marker component to identify the mesh that will be rendered
88            // with our specialized pipeline
89            CustomRenderedEntity,
90            // We need to add the mesh handle to the entity
91            Mesh3d(meshes.add(mesh.clone())),
92            Transform::from_xyz(x, y, 0.0),
93        ));
94    }
95
96    // Spawn the camera.
97    commands.spawn((
98        Camera3d::default(),
99        // Move the camera back a bit to see all the triangles
100        Transform::from_xyz(0.0, 0.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
101    ));
102}
examples/math/custom_primitives.rs (lines 445-448)
402    fn build(&self) -> Mesh {
403        let radius = self.heart.radius;
404        // The curved parts of each wing (half) of the heart have an angle of `PI * 1.25` or 225°
405        let wing_angle = PI * 1.25;
406
407        // We create buffers for the vertices, their normals and UVs, as well as the indices used to connect the vertices.
408        let mut vertices = Vec::with_capacity(2 * self.resolution);
409        let mut uvs = Vec::with_capacity(2 * self.resolution);
410        let mut indices = Vec::with_capacity(6 * self.resolution - 9);
411        // Since the heart is flat, we know all the normals are identical already.
412        let normals = vec![[0f32, 0f32, 1f32]; 2 * self.resolution];
413
414        // The point in the middle of the two curved parts of the heart
415        vertices.push([0.0; 3]);
416        uvs.push([0.5, 0.5]);
417
418        // The left wing of the heart, starting from the point in the middle.
419        for i in 1..self.resolution {
420            let angle = (i as f32 / self.resolution as f32) * wing_angle;
421            let (sin, cos) = ops::sin_cos(angle);
422            vertices.push([radius * (cos - 1.0), radius * sin, 0.0]);
423            uvs.push([0.5 - (cos - 1.0) / 4., 0.5 - sin / 2.]);
424        }
425
426        // The bottom tip of the heart
427        vertices.push([0.0, radius * (-1. - SQRT_2), 0.0]);
428        uvs.push([0.5, 1.]);
429
430        // The right wing of the heart, starting from the bottom most point and going towards the middle point.
431        for i in 0..self.resolution - 1 {
432            let angle = (i as f32 / self.resolution as f32) * wing_angle - PI / 4.;
433            let (sin, cos) = ops::sin_cos(angle);
434            vertices.push([radius * (cos + 1.0), radius * sin, 0.0]);
435            uvs.push([0.5 - (cos + 1.0) / 4., 0.5 - sin / 2.]);
436        }
437
438        // This is where we build all the triangles from the points created above.
439        // Each triangle has one corner on the middle point with the other two being adjacent points on the perimeter of the heart.
440        for i in 2..2 * self.resolution as u32 {
441            indices.extend_from_slice(&[i - 1, i, 0]);
442        }
443
444        // Here, the actual `Mesh` is created. We set the indices, vertices, normals and UVs created above and specify the topology of the mesh.
445        Mesh::new(
446            bevy::render::mesh::PrimitiveTopology::TriangleList,
447            RenderAssetUsages::default(),
448        )
449        .with_inserted_indices(bevy::render::mesh::Indices::U32(indices))
450        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
451        .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
452        .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
453    }
examples/2d/mesh2d_manual.rs (lines 60-63)
48fn star(
49    mut commands: Commands,
50    // We will add a new Mesh for the star being created
51    mut meshes: ResMut<Assets<Mesh>>,
52) {
53    // Let's define the mesh for the object we want to draw: a nice star.
54    // We will specify here what kind of topology is used to define the mesh,
55    // that is, how triangles are built from the vertices. We will use a
56    // triangle list, meaning that each vertex of the triangle has to be
57    // specified. We set `RenderAssetUsages::RENDER_WORLD`, meaning this mesh
58    // will not be accessible in future frames from the `meshes` resource, in
59    // order to save on memory once it has been uploaded to the GPU.
60    let mut star = Mesh::new(
61        PrimitiveTopology::TriangleList,
62        RenderAssetUsages::RENDER_WORLD,
63    );
64
65    // Vertices need to have a position attribute. We will use the following
66    // vertices (I hope you can spot the star in the schema).
67    //
68    //        1
69    //
70    //     10   2
71    // 9      0      3
72    //     8     4
73    //        6
74    //   7        5
75    //
76    // These vertices are specified in 3D space.
77    let mut v_pos = vec![[0.0, 0.0, 0.0]];
78    for i in 0..10 {
79        // The angle between each vertex is 1/10 of a full rotation.
80        let a = i as f32 * PI / 5.0;
81        // The radius of inner vertices (even indices) is 100. For outer vertices (odd indices) it's 200.
82        let r = (1 - i % 2) as f32 * 100.0 + 100.0;
83        // Add the vertex position.
84        v_pos.push([r * ops::sin(a), r * ops::cos(a), 0.0]);
85    }
86    // Set the position attribute
87    star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos);
88    // And a RGB color attribute as well. A built-in `Mesh::ATTRIBUTE_COLOR` exists, but we
89    // use a custom vertex attribute here for demonstration purposes.
90    let mut v_color: Vec<u32> = vec![LinearRgba::BLACK.as_u32()];
91    v_color.extend_from_slice(&[LinearRgba::from(YELLOW).as_u32(); 10]);
92    star.insert_attribute(
93        MeshVertexAttribute::new("Vertex_Color", 1, VertexFormat::Uint32),
94        v_color,
95    );
96
97    // Now, we specify the indices of the vertex that are going to compose the
98    // triangles in our star. Vertices in triangles have to be specified in CCW
99    // winding (that will be the front face, colored). Since we are using
100    // triangle list, we will specify each triangle as 3 vertices
101    //   First triangle: 0, 2, 1
102    //   Second triangle: 0, 3, 2
103    //   Third triangle: 0, 4, 3
104    //   etc
105    //   Last triangle: 0, 1, 10
106    let mut indices = vec![0, 1, 10];
107    for i in 2..=10 {
108        indices.extend_from_slice(&[0, i, i - 1]);
109    }
110    star.insert_indices(Indices::U32(indices));
111
112    // We can now spawn the entities for the star and the camera
113    commands.spawn((
114        // We use a marker component to identify the custom colored meshes
115        ColoredMesh2d,
116        // The `Handle<Mesh>` needs to be wrapped in a `Mesh2d` for 2D rendering
117        Mesh2d(meshes.add(star)),
118    ));
119
120    commands.spawn(Camera2d);
121}
examples/animation/custom_skinned_mesh.rs (lines 59-62)
39fn setup(
40    mut commands: Commands,
41    asset_server: Res<AssetServer>,
42    mut meshes: ResMut<Assets<Mesh>>,
43    mut materials: ResMut<Assets<StandardMaterial>>,
44    mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
45) {
46    // Create a camera
47    commands.spawn((
48        Camera3d::default(),
49        Transform::from_xyz(2.5, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
50    ));
51
52    // Create inverse bindpose matrices for a skeleton consists of 2 joints
53    let inverse_bindposes = skinned_mesh_inverse_bindposes_assets.add(vec![
54        Mat4::from_translation(Vec3::new(-0.5, -1.0, 0.0)),
55        Mat4::from_translation(Vec3::new(-0.5, -1.0, 0.0)),
56    ]);
57
58    // Create a mesh
59    let mesh = Mesh::new(
60        PrimitiveTopology::TriangleList,
61        RenderAssetUsages::RENDER_WORLD,
62    )
63    // Set mesh vertex positions
64    .with_inserted_attribute(
65        Mesh::ATTRIBUTE_POSITION,
66        vec![
67            [0.0, 0.0, 0.0],
68            [1.0, 0.0, 0.0],
69            [0.0, 0.5, 0.0],
70            [1.0, 0.5, 0.0],
71            [0.0, 1.0, 0.0],
72            [1.0, 1.0, 0.0],
73            [0.0, 1.5, 0.0],
74            [1.0, 1.5, 0.0],
75            [0.0, 2.0, 0.0],
76            [1.0, 2.0, 0.0],
77        ],
78    )
79    // Add UV coordinates that map the left half of the texture since its a 1 x
80    // 2 rectangle.
81    .with_inserted_attribute(
82        Mesh::ATTRIBUTE_UV_0,
83        vec![
84            [0.0, 0.00],
85            [0.5, 0.00],
86            [0.0, 0.25],
87            [0.5, 0.25],
88            [0.0, 0.50],
89            [0.5, 0.50],
90            [0.0, 0.75],
91            [0.5, 0.75],
92            [0.0, 1.00],
93            [0.5, 1.00],
94        ],
95    )
96    // Set mesh vertex normals
97    .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vec![[0.0, 0.0, 1.0]; 10])
98    // Set mesh vertex joint indices for mesh skinning.
99    // Each vertex gets 4 indices used to address the `JointTransforms` array in the vertex shader
100    //  as well as `SkinnedMeshJoint` array in the `SkinnedMesh` component.
101    // This means that a maximum of 4 joints can affect a single vertex.
102    .with_inserted_attribute(
103        Mesh::ATTRIBUTE_JOINT_INDEX,
104        // Need to be explicit here as [u16; 4] could be either Uint16x4 or Unorm16x4.
105        VertexAttributeValues::Uint16x4(vec![
106            [0, 0, 0, 0],
107            [0, 0, 0, 0],
108            [0, 1, 0, 0],
109            [0, 1, 0, 0],
110            [0, 1, 0, 0],
111            [0, 1, 0, 0],
112            [0, 1, 0, 0],
113            [0, 1, 0, 0],
114            [0, 1, 0, 0],
115            [0, 1, 0, 0],
116        ]),
117    )
118    // Set mesh vertex joint weights for mesh skinning.
119    // Each vertex gets 4 joint weights corresponding to the 4 joint indices assigned to it.
120    // The sum of these weights should equal to 1.
121    .with_inserted_attribute(
122        Mesh::ATTRIBUTE_JOINT_WEIGHT,
123        vec![
124            [1.00, 0.00, 0.0, 0.0],
125            [1.00, 0.00, 0.0, 0.0],
126            [0.75, 0.25, 0.0, 0.0],
127            [0.75, 0.25, 0.0, 0.0],
128            [0.50, 0.50, 0.0, 0.0],
129            [0.50, 0.50, 0.0, 0.0],
130            [0.25, 0.75, 0.0, 0.0],
131            [0.25, 0.75, 0.0, 0.0],
132            [0.00, 1.00, 0.0, 0.0],
133            [0.00, 1.00, 0.0, 0.0],
134        ],
135    )
136    // Tell bevy to construct triangles from a list of vertex indices,
137    // where each 3 vertex indices form a triangle.
138    .with_inserted_indices(Indices::U16(vec![
139        0, 1, 3, 0, 3, 2, 2, 3, 5, 2, 5, 4, 4, 5, 7, 4, 7, 6, 6, 7, 9, 6, 9, 8,
140    ]));
141
142    let mesh = meshes.add(mesh);
143
144    // We're seeding the PRNG here to make this example deterministic for testing purposes.
145    // This isn't strictly required in practical use unless you need your app to be deterministic.
146    let mut rng = ChaCha8Rng::seed_from_u64(42);
147
148    for i in -5..5 {
149        // Create joint entities
150        let joint_0 = commands
151            .spawn(Transform::from_xyz(
152                i as f32 * 1.5,
153                0.0,
154                // Move quads back a small amount to avoid Z-fighting and not
155                // obscure the transform gizmos.
156                -(i as f32 * 0.01).abs(),
157            ))
158            .id();
159        let joint_1 = commands.spawn((AnimatedJoint(i), Transform::IDENTITY)).id();
160
161        // Set joint_1 as a child of joint_0.
162        commands.entity(joint_0).add_children(&[joint_1]);
163
164        // Each joint in this vector corresponds to each inverse bindpose matrix in `SkinnedMeshInverseBindposes`.
165        let joint_entities = vec![joint_0, joint_1];
166
167        // Create skinned mesh renderer. Note that its transform doesn't affect the position of the mesh.
168        commands.spawn((
169            Mesh3d(mesh.clone()),
170            MeshMaterial3d(materials.add(StandardMaterial {
171                base_color: Color::srgb(
172                    rng.gen_range(0.0..1.0),
173                    rng.gen_range(0.0..1.0),
174                    rng.gen_range(0.0..1.0),
175                ),
176                base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
177                ..default()
178            })),
179            SkinnedMesh {
180                inverse_bindposes: inverse_bindposes.clone(),
181                joints: joint_entities,
182            },
183        ));
184    }
185}
examples/3d/generate_custom_mesh.rs (line 110)
108fn create_cube_mesh() -> Mesh {
109    // Keep the mesh data accessible in future frames to be able to mutate it in toggle_texture.
110    Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD)
111    .with_inserted_attribute(
112        Mesh::ATTRIBUTE_POSITION,
113        // Each array is an [x, y, z] coordinate in local space.
114        // The camera coordinate space is right-handed x-right, y-up, z-back. This means "forward" is -Z.
115        // Meshes always rotate around their local [0, 0, 0] when a rotation is applied to their Transform.
116        // By centering our mesh around the origin, rotating the mesh preserves its center of mass.
117        vec![
118            // top (facing towards +y)
119            [-0.5, 0.5, -0.5], // vertex with index 0
120            [0.5, 0.5, -0.5], // vertex with index 1
121            [0.5, 0.5, 0.5], // etc. until 23
122            [-0.5, 0.5, 0.5],
123            // bottom   (-y)
124            [-0.5, -0.5, -0.5],
125            [0.5, -0.5, -0.5],
126            [0.5, -0.5, 0.5],
127            [-0.5, -0.5, 0.5],
128            // right    (+x)
129            [0.5, -0.5, -0.5],
130            [0.5, -0.5, 0.5],
131            [0.5, 0.5, 0.5], // This vertex is at the same position as vertex with index 2, but they'll have different UV and normal
132            [0.5, 0.5, -0.5],
133            // left     (-x)
134            [-0.5, -0.5, -0.5],
135            [-0.5, -0.5, 0.5],
136            [-0.5, 0.5, 0.5],
137            [-0.5, 0.5, -0.5],
138            // back     (+z)
139            [-0.5, -0.5, 0.5],
140            [-0.5, 0.5, 0.5],
141            [0.5, 0.5, 0.5],
142            [0.5, -0.5, 0.5],
143            // forward  (-z)
144            [-0.5, -0.5, -0.5],
145            [-0.5, 0.5, -0.5],
146            [0.5, 0.5, -0.5],
147            [0.5, -0.5, -0.5],
148        ],
149    )
150    // Set-up UV coordinates to point to the upper (V < 0.5), "dirt+grass" part of the texture.
151    // Take a look at the custom image (assets/textures/array_texture.png)
152    // so the UV coords will make more sense
153    // Note: (0.0, 0.0) = Top-Left in UV mapping, (1.0, 1.0) = Bottom-Right in UV mapping
154    .with_inserted_attribute(
155        Mesh::ATTRIBUTE_UV_0,
156        vec![
157            // Assigning the UV coords for the top side.
158            [0.0, 0.2], [0.0, 0.0], [1.0, 0.0], [1.0, 0.2],
159            // Assigning the UV coords for the bottom side.
160            [0.0, 0.45], [0.0, 0.25], [1.0, 0.25], [1.0, 0.45],
161            // Assigning the UV coords for the right side.
162            [1.0, 0.45], [0.0, 0.45], [0.0, 0.2], [1.0, 0.2],
163            // Assigning the UV coords for the left side.
164            [1.0, 0.45], [0.0, 0.45], [0.0, 0.2], [1.0, 0.2],
165            // Assigning the UV coords for the back side.
166            [0.0, 0.45], [0.0, 0.2], [1.0, 0.2], [1.0, 0.45],
167            // Assigning the UV coords for the forward side.
168            [0.0, 0.45], [0.0, 0.2], [1.0, 0.2], [1.0, 0.45],
169        ],
170    )
171    // For meshes with flat shading, normals are orthogonal (pointing out) from the direction of
172    // the surface.
173    // Normals are required for correct lighting calculations.
174    // Each array represents a normalized vector, which length should be equal to 1.0.
175    .with_inserted_attribute(
176        Mesh::ATTRIBUTE_NORMAL,
177        vec![
178            // Normals for the top side (towards +y)
179            [0.0, 1.0, 0.0],
180            [0.0, 1.0, 0.0],
181            [0.0, 1.0, 0.0],
182            [0.0, 1.0, 0.0],
183            // Normals for the bottom side (towards -y)
184            [0.0, -1.0, 0.0],
185            [0.0, -1.0, 0.0],
186            [0.0, -1.0, 0.0],
187            [0.0, -1.0, 0.0],
188            // Normals for the right side (towards +x)
189            [1.0, 0.0, 0.0],
190            [1.0, 0.0, 0.0],
191            [1.0, 0.0, 0.0],
192            [1.0, 0.0, 0.0],
193            // Normals for the left side (towards -x)
194            [-1.0, 0.0, 0.0],
195            [-1.0, 0.0, 0.0],
196            [-1.0, 0.0, 0.0],
197            [-1.0, 0.0, 0.0],
198            // Normals for the back side (towards +z)
199            [0.0, 0.0, 1.0],
200            [0.0, 0.0, 1.0],
201            [0.0, 0.0, 1.0],
202            [0.0, 0.0, 1.0],
203            // Normals for the forward side (towards -z)
204            [0.0, 0.0, -1.0],
205            [0.0, 0.0, -1.0],
206            [0.0, 0.0, -1.0],
207            [0.0, 0.0, -1.0],
208        ],
209    )
210    // Create the triangles out of the 24 vertices we created.
211    // To construct a square, we need 2 triangles, therefore 12 triangles in total.
212    // To construct a triangle, we need the indices of its 3 defined vertices, adding them one
213    // by one, in a counter-clockwise order (relative to the position of the viewer, the order
214    // should appear counter-clockwise from the front of the triangle, in this case from outside the cube).
215    // Read more about how to correctly build a mesh manually in the Bevy documentation of a Mesh,
216    // further examples and the implementation of the built-in shapes.
217    //
218    // The first two defined triangles look like this (marked with the vertex indices,
219    // and the axis), when looking down at the top (+y) of the cube:
220    //   -Z
221    //   ^
222    // 0---1
223    // |  /|
224    // | / | -> +X
225    // |/  |
226    // 3---2
227    //
228    // The right face's (+x) triangles look like this, seen from the outside of the cube.
229    //   +Y
230    //   ^
231    // 10--11
232    // |  /|
233    // | / | -> -Z
234    // |/  |
235    // 9---8
236    //
237    // The back face's (+z) triangles look like this, seen from the outside of the cube.
238    //   +Y
239    //   ^
240    // 17--18
241    // |\  |
242    // | \ | -> +X
243    // |  \|
244    // 16--19
245    .with_inserted_indices(Indices::U32(vec![
246        0,3,1 , 1,3,2, // triangles making up the top (+y) facing side.
247        4,5,7 , 5,6,7, // bottom (-y)
248        8,11,9 , 9,11,10, // right (+x)
249        12,13,15 , 13,14,15, // left (-x)
250        16,19,17 , 17,19,18, // back (+z)
251        20,21,23 , 21,22,23, // forward (-z)
252    ]))
253}
Source

pub fn primitive_topology(&self) -> PrimitiveTopology

Returns the topology of the mesh.

Examples found in repository?
examples/asset/asset_loading.rs (line 43)
12fn setup(
13    mut commands: Commands,
14    asset_server: Res<AssetServer>,
15    meshes: Res<Assets<Mesh>>,
16    mut materials: ResMut<Assets<StandardMaterial>>,
17) {
18    // By default AssetServer will load assets from inside the "assets" folder.
19    // For example, the next line will load GltfAssetLabel::Primitive{mesh:0,primitive:0}.from_asset("ROOT/assets/models/cube/cube.gltf"),
20    // where "ROOT" is the directory of the Application.
21    //
22    // This can be overridden by setting [`AssetPlugin.file_path`].
23    let cube_handle = asset_server.load(
24        GltfAssetLabel::Primitive {
25            mesh: 0,
26            primitive: 0,
27        }
28        .from_asset("models/cube/cube.gltf"),
29    );
30    let sphere_handle = asset_server.load(
31        GltfAssetLabel::Primitive {
32            mesh: 0,
33            primitive: 0,
34        }
35        .from_asset("models/sphere/sphere.gltf"),
36    );
37
38    // All assets end up in their Assets<T> collection once they are done loading:
39    if let Some(sphere) = meshes.get(&sphere_handle) {
40        // You might notice that this doesn't run! This is because assets load in parallel without
41        // blocking. When an asset has loaded, it will appear in relevant Assets<T>
42        // collection.
43        info!("{:?}", sphere.primitive_topology());
44    } else {
45        info!("sphere hasn't loaded yet");
46    }
47
48    // You can load all assets in a folder like this. They will be loaded in parallel without
49    // blocking. The LoadedFolder asset holds handles to each asset in the folder. These are all
50    // dependencies of the LoadedFolder asset, meaning you can wait for the LoadedFolder asset to
51    // fire AssetEvent::LoadedWithDependencies if you want to wait for all assets in the folder
52    // to load.
53    // If you want to keep the assets in the folder alive, make sure you store the returned handle
54    // somewhere.
55    let _loaded_folder: Handle<LoadedFolder> = asset_server.load_folder("models/torus");
56
57    // If you want a handle to a specific asset in a loaded folder, the easiest way to get one is to call load.
58    // It will _not_ be loaded a second time.
59    // The LoadedFolder asset will ultimately also hold handles to the assets, but waiting for it to load
60    // and finding the right handle is more work!
61    let torus_handle = asset_server.load(
62        GltfAssetLabel::Primitive {
63            mesh: 0,
64            primitive: 0,
65        }
66        .from_asset("models/torus/torus.gltf"),
67    );
68
69    // You can also add assets directly to their Assets<T> storage:
70    let material_handle = materials.add(StandardMaterial {
71        base_color: Color::srgb(0.8, 0.7, 0.6),
72        ..default()
73    });
74
75    // torus
76    commands.spawn((
77        Mesh3d(torus_handle),
78        MeshMaterial3d(material_handle.clone()),
79        Transform::from_xyz(-3.0, 0.0, 0.0),
80    ));
81    // cube
82    commands.spawn((
83        Mesh3d(cube_handle),
84        MeshMaterial3d(material_handle.clone()),
85        Transform::from_xyz(0.0, 0.0, 0.0),
86    ));
87    // sphere
88    commands.spawn((
89        Mesh3d(sphere_handle),
90        MeshMaterial3d(material_handle),
91        Transform::from_xyz(3.0, 0.0, 0.0),
92    ));
93    // light
94    commands.spawn((PointLight::default(), Transform::from_xyz(4.0, 5.0, 4.0)));
95    // camera
96    commands.spawn((
97        Camera3d::default(),
98        Transform::from_xyz(0.0, 3.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
99    ));
100}
Source

pub fn insert_attribute( &mut self, attribute: MeshVertexAttribute, values: impl Into<VertexAttributeValues>, )

Sets the data for a vertex attribute (position, normal, etc.). The name will often be one of the associated constants such as Mesh::ATTRIBUTE_POSITION.

Aabb of entities with modified mesh are not updated automatically.

§Panics

Panics when the format of the values does not match the attribute’s format.

Examples found in repository?
examples/2d/mesh2d_vertex_color_texture.rs (line 31)
13fn setup(
14    mut commands: Commands,
15    mut meshes: ResMut<Assets<Mesh>>,
16    mut materials: ResMut<Assets<ColorMaterial>>,
17    asset_server: Res<AssetServer>,
18) {
19    // Load the Bevy logo as a texture
20    let texture_handle = asset_server.load("branding/banner.png");
21    // Build a default quad mesh
22    let mut mesh = Mesh::from(Rectangle::default());
23    // Build vertex colors for the quad. One entry per vertex (the corners of the quad)
24    let vertex_colors: Vec<[f32; 4]> = vec![
25        LinearRgba::RED.to_f32_array(),
26        LinearRgba::GREEN.to_f32_array(),
27        LinearRgba::BLUE.to_f32_array(),
28        LinearRgba::WHITE.to_f32_array(),
29    ];
30    // Insert the vertex colors as an attribute
31    mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertex_colors);
32
33    let mesh_handle = meshes.add(mesh);
34
35    commands.spawn(Camera2d);
36
37    // Spawn the quad with vertex colors
38    commands.spawn((
39        Mesh2d(mesh_handle.clone()),
40        MeshMaterial2d(materials.add(ColorMaterial::default())),
41        Transform::from_translation(Vec3::new(-96., 0., 0.)).with_scale(Vec3::splat(128.)),
42    ));
43
44    // Spawning the quad with vertex colors and a texture results in tinting
45    commands.spawn((
46        Mesh2d(mesh_handle),
47        MeshMaterial2d(materials.add(texture_handle)),
48        Transform::from_translation(Vec3::new(96., 0., 0.)).with_scale(Vec3::splat(128.)),
49    ));
50}
More examples
Hide additional examples
examples/3d/vertex_colors.rs (line 33)
13fn setup(
14    mut commands: Commands,
15    mut meshes: ResMut<Assets<Mesh>>,
16    mut materials: ResMut<Assets<StandardMaterial>>,
17) {
18    // plane
19    commands.spawn((
20        Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
21        MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
22    ));
23    // cube
24    // Assign vertex colors based on vertex positions
25    let mut colorful_cube = Mesh::from(Cuboid::default());
26    if let Some(VertexAttributeValues::Float32x3(positions)) =
27        colorful_cube.attribute(Mesh::ATTRIBUTE_POSITION)
28    {
29        let colors: Vec<[f32; 4]> = positions
30            .iter()
31            .map(|[r, g, b]| [(1. - *r) / 2., (1. - *g) / 2., (1. - *b) / 2., 1.])
32            .collect();
33        colorful_cube.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
34    }
35    commands.spawn((
36        Mesh3d(meshes.add(colorful_cube)),
37        // This is the default color, but note that vertex colors are
38        // multiplied by the base color, so you'll likely want this to be
39        // white if using vertex colors.
40        MeshMaterial3d(materials.add(Color::srgb(1., 1., 1.))),
41        Transform::from_xyz(0.0, 0.5, 0.0),
42    ));
43
44    // Light
45    commands.spawn((
46        PointLight {
47            shadows_enabled: true,
48            ..default()
49        },
50        Transform::from_xyz(4.0, 5.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
51    ));
52
53    // Camera
54    commands.spawn((
55        Camera3d::default(),
56        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
57    ));
58}
examples/3d/motion_blur.rs (line 88)
53fn setup_scene(
54    asset_server: Res<AssetServer>,
55    mut images: ResMut<Assets<Image>>,
56    mut commands: Commands,
57    mut meshes: ResMut<Assets<Mesh>>,
58    mut materials: ResMut<Assets<StandardMaterial>>,
59) {
60    commands.insert_resource(AmbientLight {
61        color: Color::WHITE,
62        brightness: 300.0,
63        ..default()
64    });
65    commands.insert_resource(CameraMode::Chase);
66    commands.spawn((
67        DirectionalLight {
68            illuminance: 3_000.0,
69            shadows_enabled: true,
70            ..default()
71        },
72        Transform::default().looking_to(Vec3::new(-1.0, -0.7, -1.0), Vec3::X),
73    ));
74    // Sky
75    commands.spawn((
76        Mesh3d(meshes.add(Sphere::default())),
77        MeshMaterial3d(materials.add(StandardMaterial {
78            unlit: true,
79            base_color: Color::linear_rgb(0.1, 0.6, 1.0),
80            ..default()
81        })),
82        Transform::default().with_scale(Vec3::splat(-4000.0)),
83    ));
84    // Ground
85    let mut plane: Mesh = Plane3d::default().into();
86    let uv_size = 4000.0;
87    let uvs = vec![[uv_size, 0.0], [0.0, 0.0], [0.0, uv_size], [uv_size; 2]];
88    plane.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
89    commands.spawn((
90        Mesh3d(meshes.add(plane)),
91        MeshMaterial3d(materials.add(StandardMaterial {
92            base_color: Color::WHITE,
93            perceptual_roughness: 1.0,
94            base_color_texture: Some(images.add(uv_debug_texture())),
95            ..default()
96        })),
97        Transform::from_xyz(0.0, -0.65, 0.0).with_scale(Vec3::splat(80.)),
98    ));
99
100    spawn_cars(&asset_server, &mut meshes, &mut materials, &mut commands);
101    spawn_trees(&mut meshes, &mut materials, &mut commands);
102    spawn_barriers(&mut meshes, &mut materials, &mut commands);
103}
examples/2d/mesh2d_manual.rs (line 87)
48fn star(
49    mut commands: Commands,
50    // We will add a new Mesh for the star being created
51    mut meshes: ResMut<Assets<Mesh>>,
52) {
53    // Let's define the mesh for the object we want to draw: a nice star.
54    // We will specify here what kind of topology is used to define the mesh,
55    // that is, how triangles are built from the vertices. We will use a
56    // triangle list, meaning that each vertex of the triangle has to be
57    // specified. We set `RenderAssetUsages::RENDER_WORLD`, meaning this mesh
58    // will not be accessible in future frames from the `meshes` resource, in
59    // order to save on memory once it has been uploaded to the GPU.
60    let mut star = Mesh::new(
61        PrimitiveTopology::TriangleList,
62        RenderAssetUsages::RENDER_WORLD,
63    );
64
65    // Vertices need to have a position attribute. We will use the following
66    // vertices (I hope you can spot the star in the schema).
67    //
68    //        1
69    //
70    //     10   2
71    // 9      0      3
72    //     8     4
73    //        6
74    //   7        5
75    //
76    // These vertices are specified in 3D space.
77    let mut v_pos = vec![[0.0, 0.0, 0.0]];
78    for i in 0..10 {
79        // The angle between each vertex is 1/10 of a full rotation.
80        let a = i as f32 * PI / 5.0;
81        // The radius of inner vertices (even indices) is 100. For outer vertices (odd indices) it's 200.
82        let r = (1 - i % 2) as f32 * 100.0 + 100.0;
83        // Add the vertex position.
84        v_pos.push([r * ops::sin(a), r * ops::cos(a), 0.0]);
85    }
86    // Set the position attribute
87    star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos);
88    // And a RGB color attribute as well. A built-in `Mesh::ATTRIBUTE_COLOR` exists, but we
89    // use a custom vertex attribute here for demonstration purposes.
90    let mut v_color: Vec<u32> = vec![LinearRgba::BLACK.as_u32()];
91    v_color.extend_from_slice(&[LinearRgba::from(YELLOW).as_u32(); 10]);
92    star.insert_attribute(
93        MeshVertexAttribute::new("Vertex_Color", 1, VertexFormat::Uint32),
94        v_color,
95    );
96
97    // Now, we specify the indices of the vertex that are going to compose the
98    // triangles in our star. Vertices in triangles have to be specified in CCW
99    // winding (that will be the front face, colored). Since we are using
100    // triangle list, we will specify each triangle as 3 vertices
101    //   First triangle: 0, 2, 1
102    //   Second triangle: 0, 3, 2
103    //   Third triangle: 0, 4, 3
104    //   etc
105    //   Last triangle: 0, 1, 10
106    let mut indices = vec![0, 1, 10];
107    for i in 2..=10 {
108        indices.extend_from_slice(&[0, i, i - 1]);
109    }
110    star.insert_indices(Indices::U32(indices));
111
112    // We can now spawn the entities for the star and the camera
113    commands.spawn((
114        // We use a marker component to identify the custom colored meshes
115        ColoredMesh2d,
116        // The `Handle<Mesh>` needs to be wrapped in a `Mesh2d` for 2D rendering
117        Mesh2d(meshes.add(star)),
118    ));
119
120    commands.spawn(Camera2d);
121}
Source

pub fn with_inserted_attribute( self, attribute: MeshVertexAttribute, values: impl Into<VertexAttributeValues>, ) -> Mesh

Consumes the mesh and returns a mesh with data set for a vertex attribute (position, normal, etc.). The name will often be one of the associated constants such as Mesh::ATTRIBUTE_POSITION.

(Alternatively, you can use Mesh::insert_attribute to mutate an existing mesh in-place)

Aabb of entities with modified mesh are not updated automatically.

§Panics

Panics when the format of the values does not match the attribute’s format.

Examples found in repository?
examples/3d/lines.rs (line 108)
98    fn from(line: LineList) -> Self {
99        let vertices: Vec<_> = line.lines.into_iter().flat_map(|(a, b)| [a, b]).collect();
100
101        Mesh::new(
102            // This tells wgpu that the positions are list of lines
103            // where every pair is a start and end point
104            PrimitiveTopology::LineList,
105            RenderAssetUsages::RENDER_WORLD,
106        )
107        // Add the vertices positions as an attribute
108        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
109    }
110}
111
112/// A list of points that will have a line drawn between each consecutive points
113#[derive(Debug, Clone)]
114struct LineStrip {
115    points: Vec<Vec3>,
116}
117
118impl From<LineStrip> for Mesh {
119    fn from(line: LineStrip) -> Self {
120        Mesh::new(
121            // This tells wgpu that the positions are a list of points
122            // where a line will be drawn between each consecutive point
123            PrimitiveTopology::LineStrip,
124            RenderAssetUsages::RENDER_WORLD,
125        )
126        // Add the point positions as an attribute
127        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, line.points)
128    }
More examples
Hide additional examples
examples/shader/custom_vertex_attribute.rs (lines 39-43)
32fn setup(
33    mut commands: Commands,
34    mut meshes: ResMut<Assets<Mesh>>,
35    mut materials: ResMut<Assets<CustomMaterial>>,
36) {
37    let mesh = Mesh::from(Cuboid::default())
38        // Sets the custom attribute
39        .with_inserted_attribute(
40            ATTRIBUTE_BLEND_COLOR,
41            // The cube mesh has 24 vertices (6 faces, 4 vertices per face), so we insert one BlendColor for each
42            vec![[1.0, 0.0, 0.0, 1.0]; 24],
43        );
44
45    // cube
46    commands.spawn((
47        Mesh3d(meshes.add(mesh)),
48        MeshMaterial3d(materials.add(CustomMaterial {
49            color: LinearRgba::WHITE,
50        })),
51        Transform::from_xyz(0.0, 0.5, 0.0),
52    ));
53
54    // camera
55    commands.spawn((
56        Camera3d::default(),
57        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
58    ));
59}
examples/shader/specialized_mesh_pipeline.rs (lines 66-73)
57fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
58    // Build a custom triangle mesh with colors
59    // We define a custom mesh because the examples only uses a limited
60    // set of vertex attributes for simplicity
61    let mesh = Mesh::new(
62        PrimitiveTopology::TriangleList,
63        RenderAssetUsages::default(),
64    )
65    .with_inserted_indices(Indices::U32(vec![0, 1, 2]))
66    .with_inserted_attribute(
67        Mesh::ATTRIBUTE_POSITION,
68        vec![
69            vec3(-0.5, -0.5, 0.0),
70            vec3(0.5, -0.5, 0.0),
71            vec3(0.0, 0.25, 0.0),
72        ],
73    )
74    .with_inserted_attribute(
75        Mesh::ATTRIBUTE_COLOR,
76        vec![
77            vec4(1.0, 0.0, 0.0, 1.0),
78            vec4(0.0, 1.0, 0.0, 1.0),
79            vec4(0.0, 0.0, 1.0, 1.0),
80        ],
81    );
82
83    // spawn 3 triangles to show that batching works
84    for (x, y) in [-0.5, 0.0, 0.5].into_iter().zip([-0.25, 0.5, -0.25]) {
85        // Spawn an entity with all the required components for it to be rendered with our custom pipeline
86        commands.spawn((
87            // We use a marker component to identify the mesh that will be rendered
88            // with our specialized pipeline
89            CustomRenderedEntity,
90            // We need to add the mesh handle to the entity
91            Mesh3d(meshes.add(mesh.clone())),
92            Transform::from_xyz(x, y, 0.0),
93        ));
94    }
95
96    // Spawn the camera.
97    commands.spawn((
98        Camera3d::default(),
99        // Move the camera back a bit to see all the triangles
100        Transform::from_xyz(0.0, 0.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
101    ));
102}
examples/math/custom_primitives.rs (line 450)
402    fn build(&self) -> Mesh {
403        let radius = self.heart.radius;
404        // The curved parts of each wing (half) of the heart have an angle of `PI * 1.25` or 225°
405        let wing_angle = PI * 1.25;
406
407        // We create buffers for the vertices, their normals and UVs, as well as the indices used to connect the vertices.
408        let mut vertices = Vec::with_capacity(2 * self.resolution);
409        let mut uvs = Vec::with_capacity(2 * self.resolution);
410        let mut indices = Vec::with_capacity(6 * self.resolution - 9);
411        // Since the heart is flat, we know all the normals are identical already.
412        let normals = vec![[0f32, 0f32, 1f32]; 2 * self.resolution];
413
414        // The point in the middle of the two curved parts of the heart
415        vertices.push([0.0; 3]);
416        uvs.push([0.5, 0.5]);
417
418        // The left wing of the heart, starting from the point in the middle.
419        for i in 1..self.resolution {
420            let angle = (i as f32 / self.resolution as f32) * wing_angle;
421            let (sin, cos) = ops::sin_cos(angle);
422            vertices.push([radius * (cos - 1.0), radius * sin, 0.0]);
423            uvs.push([0.5 - (cos - 1.0) / 4., 0.5 - sin / 2.]);
424        }
425
426        // The bottom tip of the heart
427        vertices.push([0.0, radius * (-1. - SQRT_2), 0.0]);
428        uvs.push([0.5, 1.]);
429
430        // The right wing of the heart, starting from the bottom most point and going towards the middle point.
431        for i in 0..self.resolution - 1 {
432            let angle = (i as f32 / self.resolution as f32) * wing_angle - PI / 4.;
433            let (sin, cos) = ops::sin_cos(angle);
434            vertices.push([radius * (cos + 1.0), radius * sin, 0.0]);
435            uvs.push([0.5 - (cos + 1.0) / 4., 0.5 - sin / 2.]);
436        }
437
438        // This is where we build all the triangles from the points created above.
439        // Each triangle has one corner on the middle point with the other two being adjacent points on the perimeter of the heart.
440        for i in 2..2 * self.resolution as u32 {
441            indices.extend_from_slice(&[i - 1, i, 0]);
442        }
443
444        // Here, the actual `Mesh` is created. We set the indices, vertices, normals and UVs created above and specify the topology of the mesh.
445        Mesh::new(
446            bevy::render::mesh::PrimitiveTopology::TriangleList,
447            RenderAssetUsages::default(),
448        )
449        .with_inserted_indices(bevy::render::mesh::Indices::U32(indices))
450        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
451        .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
452        .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
453    }
examples/animation/custom_skinned_mesh.rs (lines 64-78)
39fn setup(
40    mut commands: Commands,
41    asset_server: Res<AssetServer>,
42    mut meshes: ResMut<Assets<Mesh>>,
43    mut materials: ResMut<Assets<StandardMaterial>>,
44    mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
45) {
46    // Create a camera
47    commands.spawn((
48        Camera3d::default(),
49        Transform::from_xyz(2.5, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
50    ));
51
52    // Create inverse bindpose matrices for a skeleton consists of 2 joints
53    let inverse_bindposes = skinned_mesh_inverse_bindposes_assets.add(vec![
54        Mat4::from_translation(Vec3::new(-0.5, -1.0, 0.0)),
55        Mat4::from_translation(Vec3::new(-0.5, -1.0, 0.0)),
56    ]);
57
58    // Create a mesh
59    let mesh = Mesh::new(
60        PrimitiveTopology::TriangleList,
61        RenderAssetUsages::RENDER_WORLD,
62    )
63    // Set mesh vertex positions
64    .with_inserted_attribute(
65        Mesh::ATTRIBUTE_POSITION,
66        vec![
67            [0.0, 0.0, 0.0],
68            [1.0, 0.0, 0.0],
69            [0.0, 0.5, 0.0],
70            [1.0, 0.5, 0.0],
71            [0.0, 1.0, 0.0],
72            [1.0, 1.0, 0.0],
73            [0.0, 1.5, 0.0],
74            [1.0, 1.5, 0.0],
75            [0.0, 2.0, 0.0],
76            [1.0, 2.0, 0.0],
77        ],
78    )
79    // Add UV coordinates that map the left half of the texture since its a 1 x
80    // 2 rectangle.
81    .with_inserted_attribute(
82        Mesh::ATTRIBUTE_UV_0,
83        vec![
84            [0.0, 0.00],
85            [0.5, 0.00],
86            [0.0, 0.25],
87            [0.5, 0.25],
88            [0.0, 0.50],
89            [0.5, 0.50],
90            [0.0, 0.75],
91            [0.5, 0.75],
92            [0.0, 1.00],
93            [0.5, 1.00],
94        ],
95    )
96    // Set mesh vertex normals
97    .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vec![[0.0, 0.0, 1.0]; 10])
98    // Set mesh vertex joint indices for mesh skinning.
99    // Each vertex gets 4 indices used to address the `JointTransforms` array in the vertex shader
100    //  as well as `SkinnedMeshJoint` array in the `SkinnedMesh` component.
101    // This means that a maximum of 4 joints can affect a single vertex.
102    .with_inserted_attribute(
103        Mesh::ATTRIBUTE_JOINT_INDEX,
104        // Need to be explicit here as [u16; 4] could be either Uint16x4 or Unorm16x4.
105        VertexAttributeValues::Uint16x4(vec![
106            [0, 0, 0, 0],
107            [0, 0, 0, 0],
108            [0, 1, 0, 0],
109            [0, 1, 0, 0],
110            [0, 1, 0, 0],
111            [0, 1, 0, 0],
112            [0, 1, 0, 0],
113            [0, 1, 0, 0],
114            [0, 1, 0, 0],
115            [0, 1, 0, 0],
116        ]),
117    )
118    // Set mesh vertex joint weights for mesh skinning.
119    // Each vertex gets 4 joint weights corresponding to the 4 joint indices assigned to it.
120    // The sum of these weights should equal to 1.
121    .with_inserted_attribute(
122        Mesh::ATTRIBUTE_JOINT_WEIGHT,
123        vec![
124            [1.00, 0.00, 0.0, 0.0],
125            [1.00, 0.00, 0.0, 0.0],
126            [0.75, 0.25, 0.0, 0.0],
127            [0.75, 0.25, 0.0, 0.0],
128            [0.50, 0.50, 0.0, 0.0],
129            [0.50, 0.50, 0.0, 0.0],
130            [0.25, 0.75, 0.0, 0.0],
131            [0.25, 0.75, 0.0, 0.0],
132            [0.00, 1.00, 0.0, 0.0],
133            [0.00, 1.00, 0.0, 0.0],
134        ],
135    )
136    // Tell bevy to construct triangles from a list of vertex indices,
137    // where each 3 vertex indices form a triangle.
138    .with_inserted_indices(Indices::U16(vec![
139        0, 1, 3, 0, 3, 2, 2, 3, 5, 2, 5, 4, 4, 5, 7, 4, 7, 6, 6, 7, 9, 6, 9, 8,
140    ]));
141
142    let mesh = meshes.add(mesh);
143
144    // We're seeding the PRNG here to make this example deterministic for testing purposes.
145    // This isn't strictly required in practical use unless you need your app to be deterministic.
146    let mut rng = ChaCha8Rng::seed_from_u64(42);
147
148    for i in -5..5 {
149        // Create joint entities
150        let joint_0 = commands
151            .spawn(Transform::from_xyz(
152                i as f32 * 1.5,
153                0.0,
154                // Move quads back a small amount to avoid Z-fighting and not
155                // obscure the transform gizmos.
156                -(i as f32 * 0.01).abs(),
157            ))
158            .id();
159        let joint_1 = commands.spawn((AnimatedJoint(i), Transform::IDENTITY)).id();
160
161        // Set joint_1 as a child of joint_0.
162        commands.entity(joint_0).add_children(&[joint_1]);
163
164        // Each joint in this vector corresponds to each inverse bindpose matrix in `SkinnedMeshInverseBindposes`.
165        let joint_entities = vec![joint_0, joint_1];
166
167        // Create skinned mesh renderer. Note that its transform doesn't affect the position of the mesh.
168        commands.spawn((
169            Mesh3d(mesh.clone()),
170            MeshMaterial3d(materials.add(StandardMaterial {
171                base_color: Color::srgb(
172                    rng.gen_range(0.0..1.0),
173                    rng.gen_range(0.0..1.0),
174                    rng.gen_range(0.0..1.0),
175                ),
176                base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
177                ..default()
178            })),
179            SkinnedMesh {
180                inverse_bindposes: inverse_bindposes.clone(),
181                joints: joint_entities,
182            },
183        ));
184    }
185}
examples/3d/generate_custom_mesh.rs (lines 111-149)
108fn create_cube_mesh() -> Mesh {
109    // Keep the mesh data accessible in future frames to be able to mutate it in toggle_texture.
110    Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD)
111    .with_inserted_attribute(
112        Mesh::ATTRIBUTE_POSITION,
113        // Each array is an [x, y, z] coordinate in local space.
114        // The camera coordinate space is right-handed x-right, y-up, z-back. This means "forward" is -Z.
115        // Meshes always rotate around their local [0, 0, 0] when a rotation is applied to their Transform.
116        // By centering our mesh around the origin, rotating the mesh preserves its center of mass.
117        vec![
118            // top (facing towards +y)
119            [-0.5, 0.5, -0.5], // vertex with index 0
120            [0.5, 0.5, -0.5], // vertex with index 1
121            [0.5, 0.5, 0.5], // etc. until 23
122            [-0.5, 0.5, 0.5],
123            // bottom   (-y)
124            [-0.5, -0.5, -0.5],
125            [0.5, -0.5, -0.5],
126            [0.5, -0.5, 0.5],
127            [-0.5, -0.5, 0.5],
128            // right    (+x)
129            [0.5, -0.5, -0.5],
130            [0.5, -0.5, 0.5],
131            [0.5, 0.5, 0.5], // This vertex is at the same position as vertex with index 2, but they'll have different UV and normal
132            [0.5, 0.5, -0.5],
133            // left     (-x)
134            [-0.5, -0.5, -0.5],
135            [-0.5, -0.5, 0.5],
136            [-0.5, 0.5, 0.5],
137            [-0.5, 0.5, -0.5],
138            // back     (+z)
139            [-0.5, -0.5, 0.5],
140            [-0.5, 0.5, 0.5],
141            [0.5, 0.5, 0.5],
142            [0.5, -0.5, 0.5],
143            // forward  (-z)
144            [-0.5, -0.5, -0.5],
145            [-0.5, 0.5, -0.5],
146            [0.5, 0.5, -0.5],
147            [0.5, -0.5, -0.5],
148        ],
149    )
150    // Set-up UV coordinates to point to the upper (V < 0.5), "dirt+grass" part of the texture.
151    // Take a look at the custom image (assets/textures/array_texture.png)
152    // so the UV coords will make more sense
153    // Note: (0.0, 0.0) = Top-Left in UV mapping, (1.0, 1.0) = Bottom-Right in UV mapping
154    .with_inserted_attribute(
155        Mesh::ATTRIBUTE_UV_0,
156        vec![
157            // Assigning the UV coords for the top side.
158            [0.0, 0.2], [0.0, 0.0], [1.0, 0.0], [1.0, 0.2],
159            // Assigning the UV coords for the bottom side.
160            [0.0, 0.45], [0.0, 0.25], [1.0, 0.25], [1.0, 0.45],
161            // Assigning the UV coords for the right side.
162            [1.0, 0.45], [0.0, 0.45], [0.0, 0.2], [1.0, 0.2],
163            // Assigning the UV coords for the left side.
164            [1.0, 0.45], [0.0, 0.45], [0.0, 0.2], [1.0, 0.2],
165            // Assigning the UV coords for the back side.
166            [0.0, 0.45], [0.0, 0.2], [1.0, 0.2], [1.0, 0.45],
167            // Assigning the UV coords for the forward side.
168            [0.0, 0.45], [0.0, 0.2], [1.0, 0.2], [1.0, 0.45],
169        ],
170    )
171    // For meshes with flat shading, normals are orthogonal (pointing out) from the direction of
172    // the surface.
173    // Normals are required for correct lighting calculations.
174    // Each array represents a normalized vector, which length should be equal to 1.0.
175    .with_inserted_attribute(
176        Mesh::ATTRIBUTE_NORMAL,
177        vec![
178            // Normals for the top side (towards +y)
179            [0.0, 1.0, 0.0],
180            [0.0, 1.0, 0.0],
181            [0.0, 1.0, 0.0],
182            [0.0, 1.0, 0.0],
183            // Normals for the bottom side (towards -y)
184            [0.0, -1.0, 0.0],
185            [0.0, -1.0, 0.0],
186            [0.0, -1.0, 0.0],
187            [0.0, -1.0, 0.0],
188            // Normals for the right side (towards +x)
189            [1.0, 0.0, 0.0],
190            [1.0, 0.0, 0.0],
191            [1.0, 0.0, 0.0],
192            [1.0, 0.0, 0.0],
193            // Normals for the left side (towards -x)
194            [-1.0, 0.0, 0.0],
195            [-1.0, 0.0, 0.0],
196            [-1.0, 0.0, 0.0],
197            [-1.0, 0.0, 0.0],
198            // Normals for the back side (towards +z)
199            [0.0, 0.0, 1.0],
200            [0.0, 0.0, 1.0],
201            [0.0, 0.0, 1.0],
202            [0.0, 0.0, 1.0],
203            // Normals for the forward side (towards -z)
204            [0.0, 0.0, -1.0],
205            [0.0, 0.0, -1.0],
206            [0.0, 0.0, -1.0],
207            [0.0, 0.0, -1.0],
208        ],
209    )
210    // Create the triangles out of the 24 vertices we created.
211    // To construct a square, we need 2 triangles, therefore 12 triangles in total.
212    // To construct a triangle, we need the indices of its 3 defined vertices, adding them one
213    // by one, in a counter-clockwise order (relative to the position of the viewer, the order
214    // should appear counter-clockwise from the front of the triangle, in this case from outside the cube).
215    // Read more about how to correctly build a mesh manually in the Bevy documentation of a Mesh,
216    // further examples and the implementation of the built-in shapes.
217    //
218    // The first two defined triangles look like this (marked with the vertex indices,
219    // and the axis), when looking down at the top (+y) of the cube:
220    //   -Z
221    //   ^
222    // 0---1
223    // |  /|
224    // | / | -> +X
225    // |/  |
226    // 3---2
227    //
228    // The right face's (+x) triangles look like this, seen from the outside of the cube.
229    //   +Y
230    //   ^
231    // 10--11
232    // |  /|
233    // | / | -> -Z
234    // |/  |
235    // 9---8
236    //
237    // The back face's (+z) triangles look like this, seen from the outside of the cube.
238    //   +Y
239    //   ^
240    // 17--18
241    // |\  |
242    // | \ | -> +X
243    // |  \|
244    // 16--19
245    .with_inserted_indices(Indices::U32(vec![
246        0,3,1 , 1,3,2, // triangles making up the top (+y) facing side.
247        4,5,7 , 5,6,7, // bottom (-y)
248        8,11,9 , 9,11,10, // right (+x)
249        12,13,15 , 13,14,15, // left (-x)
250        16,19,17 , 17,19,18, // back (+z)
251        20,21,23 , 21,22,23, // forward (-z)
252    ]))
253}
Source

pub fn remove_attribute( &mut self, attribute: impl Into<MeshVertexAttributeId>, ) -> Option<VertexAttributeValues>

Removes the data for a vertex attribute

Source

pub fn with_removed_attribute( self, attribute: impl Into<MeshVertexAttributeId>, ) -> Mesh

Consumes the mesh and returns a mesh without the data for a vertex attribute

(Alternatively, you can use Mesh::remove_attribute to mutate an existing mesh in-place)

Source

pub fn contains_attribute(&self, id: impl Into<MeshVertexAttributeId>) -> bool

Source

pub fn attribute( &self, id: impl Into<MeshVertexAttributeId>, ) -> Option<&VertexAttributeValues>

Retrieves the data currently set to the vertex attribute with the specified MeshVertexAttributeId.

Examples found in repository?
examples/3d/vertex_colors.rs (line 27)
13fn setup(
14    mut commands: Commands,
15    mut meshes: ResMut<Assets<Mesh>>,
16    mut materials: ResMut<Assets<StandardMaterial>>,
17) {
18    // plane
19    commands.spawn((
20        Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
21        MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
22    ));
23    // cube
24    // Assign vertex colors based on vertex positions
25    let mut colorful_cube = Mesh::from(Cuboid::default());
26    if let Some(VertexAttributeValues::Float32x3(positions)) =
27        colorful_cube.attribute(Mesh::ATTRIBUTE_POSITION)
28    {
29        let colors: Vec<[f32; 4]> = positions
30            .iter()
31            .map(|[r, g, b]| [(1. - *r) / 2., (1. - *g) / 2., (1. - *b) / 2., 1.])
32            .collect();
33        colorful_cube.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
34    }
35    commands.spawn((
36        Mesh3d(meshes.add(colorful_cube)),
37        // This is the default color, but note that vertex colors are
38        // multiplied by the base color, so you'll likely want this to be
39        // white if using vertex colors.
40        MeshMaterial3d(materials.add(Color::srgb(1., 1., 1.))),
41        Transform::from_xyz(0.0, 0.5, 0.0),
42    ));
43
44    // Light
45    commands.spawn((
46        PointLight {
47            shadows_enabled: true,
48            ..default()
49        },
50        Transform::from_xyz(4.0, 5.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
51    ));
52
53    // Camera
54    commands.spawn((
55        Camera3d::default(),
56        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
57    ));
58}
More examples
Hide additional examples
examples/3d/occlusion_culling.rs (line 321)
284fn spawn_small_cubes(
285    commands: &mut Commands,
286    meshes: &mut Assets<Mesh>,
287    materials: &mut Assets<StandardMaterial>,
288) {
289    // Add the cube mesh.
290    let small_cube = meshes.add(Cuboid::new(
291        SMALL_CUBE_SIZE,
292        SMALL_CUBE_SIZE,
293        SMALL_CUBE_SIZE,
294    ));
295
296    // Add the cube material.
297    let small_cube_material = materials.add(StandardMaterial {
298        base_color: SILVER.into(),
299        ..default()
300    });
301
302    // Create the entity that the small cubes will be parented to. This is the
303    // entity that we rotate.
304    let sphere_parent = commands
305        .spawn(Transform::from_translation(Vec3::ZERO))
306        .insert(Visibility::default())
307        .insert(SphereParent)
308        .id();
309
310    // Now we have to figure out where to place the cubes. To do that, we create
311    // a sphere mesh, but we don't add it to the scene. Instead, we inspect the
312    // sphere mesh to find the positions of its vertices, and spawn a small cube
313    // at each one. That way, we end up with a bunch of cubes arranged in a
314    // spherical shape.
315
316    // Create the sphere mesh, and extract the positions of its vertices.
317    let sphere = Sphere::new(OUTER_RADIUS)
318        .mesh()
319        .ico(OUTER_SUBDIVISION_COUNT)
320        .unwrap();
321    let sphere_positions = sphere.attribute(Mesh::ATTRIBUTE_POSITION).unwrap();
322
323    // At each vertex, create a small cube.
324    for sphere_position in sphere_positions.as_float3().unwrap() {
325        let sphere_position = Vec3::from_slice(sphere_position);
326        let small_cube = commands
327            .spawn(Mesh3d(small_cube.clone()))
328            .insert(MeshMaterial3d(small_cube_material.clone()))
329            .insert(Transform::from_translation(sphere_position))
330            .id();
331        commands.entity(sphere_parent).add_child(small_cube);
332    }
333}
Source

pub fn attribute_mut( &mut self, id: impl Into<MeshVertexAttributeId>, ) -> Option<&mut VertexAttributeValues>

Retrieves the data currently set to the vertex attribute with the specified name mutably.

Examples found in repository?
examples/3d/generate_custom_mesh.rs (line 258)
256fn toggle_texture(mesh_to_change: &mut Mesh) {
257    // Get a mutable reference to the values of the UV attribute, so we can iterate over it.
258    let uv_attribute = mesh_to_change.attribute_mut(Mesh::ATTRIBUTE_UV_0).unwrap();
259    // The format of the UV coordinates should be Float32x2.
260    let VertexAttributeValues::Float32x2(uv_attribute) = uv_attribute else {
261        panic!("Unexpected vertex format, expected Float32x2.");
262    };
263
264    // Iterate over the UV coordinates, and change them as we want.
265    for uv_coord in uv_attribute.iter_mut() {
266        // If the UV coordinate points to the upper, "dirt+grass" part of the texture...
267        if (uv_coord[1] + 0.5) < 1.0 {
268            // ... point to the equivalent lower, "sand+water" part instead,
269            uv_coord[1] += 0.5;
270        } else {
271            // else, point back to the upper, "dirt+grass" part.
272            uv_coord[1] -= 0.5;
273        }
274    }
275}
More examples
Hide additional examples
examples/3d/query_gltf_primitives.rs (line 39)
16fn find_top_material_and_mesh(
17    mut materials: ResMut<Assets<StandardMaterial>>,
18    mut meshes: ResMut<Assets<Mesh>>,
19    time: Res<Time>,
20    mat_query: Query<(
21        &MeshMaterial3d<StandardMaterial>,
22        &Mesh3d,
23        &GltfMaterialName,
24    )>,
25) {
26    for (mat_handle, mesh_handle, name) in mat_query.iter() {
27        // locate a material by material name
28        if name.0 == "Top" {
29            if let Some(material) = materials.get_mut(mat_handle) {
30                if let Color::Hsla(ref mut hsla) = material.base_color {
31                    *hsla = hsla.rotate_hue(time.delta_secs() * 100.0);
32                } else {
33                    material.base_color = Color::from(Hsla::hsl(0.0, 0.9, 0.7));
34                }
35            }
36
37            if let Some(mesh) = meshes.get_mut(mesh_handle) {
38                if let Some(VertexAttributeValues::Float32x3(positions)) =
39                    mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION)
40                {
41                    for position in positions {
42                        *position = (
43                            position[0],
44                            1.5 + 0.5 * ops::sin(time.elapsed_secs() / 2.0),
45                            position[2],
46                        )
47                            .into();
48                    }
49                }
50            }
51        }
52    }
53}
examples/asset/alter_mesh.rs (line 194)
173fn alter_mesh(
174    mut is_mesh_scaled: Local<bool>,
175    left_shape: Single<&Mesh3d, With<Left>>,
176    mut meshes: ResMut<Assets<Mesh>>,
177) {
178    // Obtain a mutable reference to the Mesh asset.
179    let Some(mesh) = meshes.get_mut(*left_shape) else {
180        return;
181    };
182
183    // Now we can directly manipulate vertices on the mesh. Here, we're just scaling in and out
184    // for demonstration purposes. This will affect all entities currently using the asset.
185    //
186    // To do this, we need to grab the stored attributes of each vertex. `Float32x3` just describes
187    // the format in which the attributes will be read: each position consists of an array of three
188    // f32 corresponding to x, y, and z.
189    //
190    // `ATTRIBUTE_POSITION` is a constant indicating that we want to know where the vertex is
191    // located in space (as opposed to which way its normal is facing, vertex color, or other
192    // details).
193    if let Some(VertexAttributeValues::Float32x3(positions)) =
194        mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION)
195    {
196        // Check a Local value (which only this system can make use of) to determine if we're
197        // currently scaled up or not.
198        let scale_factor = if *is_mesh_scaled { 0.5 } else { 2.0 };
199
200        for position in positions.iter_mut() {
201            // Apply the scale factor to each of x, y, and z.
202            position[0] *= scale_factor;
203            position[1] *= scale_factor;
204            position[2] *= scale_factor;
205        }
206
207        // Flip the local value to reverse the behavior next time the key is pressed.
208        *is_mesh_scaled = !*is_mesh_scaled;
209    }
210}
Source

pub fn attributes( &self, ) -> impl Iterator<Item = (&MeshVertexAttribute, &VertexAttributeValues)>

Returns an iterator that yields references to the data of each vertex attribute.

Source

pub fn attributes_mut( &mut self, ) -> impl Iterator<Item = (&MeshVertexAttribute, &mut VertexAttributeValues)>

Returns an iterator that yields mutable references to the data of each vertex attribute.

Source

pub fn insert_indices(&mut self, indices: Indices)

Sets the vertex indices of the mesh. They describe how triangles are constructed out of the vertex attributes and are therefore only useful for the PrimitiveTopology variants that use triangles.

Examples found in repository?
examples/2d/mesh2d_manual.rs (line 110)
48fn star(
49    mut commands: Commands,
50    // We will add a new Mesh for the star being created
51    mut meshes: ResMut<Assets<Mesh>>,
52) {
53    // Let's define the mesh for the object we want to draw: a nice star.
54    // We will specify here what kind of topology is used to define the mesh,
55    // that is, how triangles are built from the vertices. We will use a
56    // triangle list, meaning that each vertex of the triangle has to be
57    // specified. We set `RenderAssetUsages::RENDER_WORLD`, meaning this mesh
58    // will not be accessible in future frames from the `meshes` resource, in
59    // order to save on memory once it has been uploaded to the GPU.
60    let mut star = Mesh::new(
61        PrimitiveTopology::TriangleList,
62        RenderAssetUsages::RENDER_WORLD,
63    );
64
65    // Vertices need to have a position attribute. We will use the following
66    // vertices (I hope you can spot the star in the schema).
67    //
68    //        1
69    //
70    //     10   2
71    // 9      0      3
72    //     8     4
73    //        6
74    //   7        5
75    //
76    // These vertices are specified in 3D space.
77    let mut v_pos = vec![[0.0, 0.0, 0.0]];
78    for i in 0..10 {
79        // The angle between each vertex is 1/10 of a full rotation.
80        let a = i as f32 * PI / 5.0;
81        // The radius of inner vertices (even indices) is 100. For outer vertices (odd indices) it's 200.
82        let r = (1 - i % 2) as f32 * 100.0 + 100.0;
83        // Add the vertex position.
84        v_pos.push([r * ops::sin(a), r * ops::cos(a), 0.0]);
85    }
86    // Set the position attribute
87    star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos);
88    // And a RGB color attribute as well. A built-in `Mesh::ATTRIBUTE_COLOR` exists, but we
89    // use a custom vertex attribute here for demonstration purposes.
90    let mut v_color: Vec<u32> = vec![LinearRgba::BLACK.as_u32()];
91    v_color.extend_from_slice(&[LinearRgba::from(YELLOW).as_u32(); 10]);
92    star.insert_attribute(
93        MeshVertexAttribute::new("Vertex_Color", 1, VertexFormat::Uint32),
94        v_color,
95    );
96
97    // Now, we specify the indices of the vertex that are going to compose the
98    // triangles in our star. Vertices in triangles have to be specified in CCW
99    // winding (that will be the front face, colored). Since we are using
100    // triangle list, we will specify each triangle as 3 vertices
101    //   First triangle: 0, 2, 1
102    //   Second triangle: 0, 3, 2
103    //   Third triangle: 0, 4, 3
104    //   etc
105    //   Last triangle: 0, 1, 10
106    let mut indices = vec![0, 1, 10];
107    for i in 2..=10 {
108        indices.extend_from_slice(&[0, i, i - 1]);
109    }
110    star.insert_indices(Indices::U32(indices));
111
112    // We can now spawn the entities for the star and the camera
113    commands.spawn((
114        // We use a marker component to identify the custom colored meshes
115        ColoredMesh2d,
116        // The `Handle<Mesh>` needs to be wrapped in a `Mesh2d` for 2D rendering
117        Mesh2d(meshes.add(star)),
118    ));
119
120    commands.spawn(Camera2d);
121}
Source

pub fn with_inserted_indices(self, indices: Indices) -> Mesh

Consumes the mesh and returns a mesh with the given vertex indices. They describe how triangles are constructed out of the vertex attributes and are therefore only useful for the PrimitiveTopology variants that use triangles.

(Alternatively, you can use Mesh::insert_indices to mutate an existing mesh in-place)

Examples found in repository?
examples/shader/specialized_mesh_pipeline.rs (line 65)
57fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
58    // Build a custom triangle mesh with colors
59    // We define a custom mesh because the examples only uses a limited
60    // set of vertex attributes for simplicity
61    let mesh = Mesh::new(
62        PrimitiveTopology::TriangleList,
63        RenderAssetUsages::default(),
64    )
65    .with_inserted_indices(Indices::U32(vec![0, 1, 2]))
66    .with_inserted_attribute(
67        Mesh::ATTRIBUTE_POSITION,
68        vec![
69            vec3(-0.5, -0.5, 0.0),
70            vec3(0.5, -0.5, 0.0),
71            vec3(0.0, 0.25, 0.0),
72        ],
73    )
74    .with_inserted_attribute(
75        Mesh::ATTRIBUTE_COLOR,
76        vec![
77            vec4(1.0, 0.0, 0.0, 1.0),
78            vec4(0.0, 1.0, 0.0, 1.0),
79            vec4(0.0, 0.0, 1.0, 1.0),
80        ],
81    );
82
83    // spawn 3 triangles to show that batching works
84    for (x, y) in [-0.5, 0.0, 0.5].into_iter().zip([-0.25, 0.5, -0.25]) {
85        // Spawn an entity with all the required components for it to be rendered with our custom pipeline
86        commands.spawn((
87            // We use a marker component to identify the mesh that will be rendered
88            // with our specialized pipeline
89            CustomRenderedEntity,
90            // We need to add the mesh handle to the entity
91            Mesh3d(meshes.add(mesh.clone())),
92            Transform::from_xyz(x, y, 0.0),
93        ));
94    }
95
96    // Spawn the camera.
97    commands.spawn((
98        Camera3d::default(),
99        // Move the camera back a bit to see all the triangles
100        Transform::from_xyz(0.0, 0.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
101    ));
102}
More examples
Hide additional examples
examples/math/custom_primitives.rs (line 449)
402    fn build(&self) -> Mesh {
403        let radius = self.heart.radius;
404        // The curved parts of each wing (half) of the heart have an angle of `PI * 1.25` or 225°
405        let wing_angle = PI * 1.25;
406
407        // We create buffers for the vertices, their normals and UVs, as well as the indices used to connect the vertices.
408        let mut vertices = Vec::with_capacity(2 * self.resolution);
409        let mut uvs = Vec::with_capacity(2 * self.resolution);
410        let mut indices = Vec::with_capacity(6 * self.resolution - 9);
411        // Since the heart is flat, we know all the normals are identical already.
412        let normals = vec![[0f32, 0f32, 1f32]; 2 * self.resolution];
413
414        // The point in the middle of the two curved parts of the heart
415        vertices.push([0.0; 3]);
416        uvs.push([0.5, 0.5]);
417
418        // The left wing of the heart, starting from the point in the middle.
419        for i in 1..self.resolution {
420            let angle = (i as f32 / self.resolution as f32) * wing_angle;
421            let (sin, cos) = ops::sin_cos(angle);
422            vertices.push([radius * (cos - 1.0), radius * sin, 0.0]);
423            uvs.push([0.5 - (cos - 1.0) / 4., 0.5 - sin / 2.]);
424        }
425
426        // The bottom tip of the heart
427        vertices.push([0.0, radius * (-1. - SQRT_2), 0.0]);
428        uvs.push([0.5, 1.]);
429
430        // The right wing of the heart, starting from the bottom most point and going towards the middle point.
431        for i in 0..self.resolution - 1 {
432            let angle = (i as f32 / self.resolution as f32) * wing_angle - PI / 4.;
433            let (sin, cos) = ops::sin_cos(angle);
434            vertices.push([radius * (cos + 1.0), radius * sin, 0.0]);
435            uvs.push([0.5 - (cos + 1.0) / 4., 0.5 - sin / 2.]);
436        }
437
438        // This is where we build all the triangles from the points created above.
439        // Each triangle has one corner on the middle point with the other two being adjacent points on the perimeter of the heart.
440        for i in 2..2 * self.resolution as u32 {
441            indices.extend_from_slice(&[i - 1, i, 0]);
442        }
443
444        // Here, the actual `Mesh` is created. We set the indices, vertices, normals and UVs created above and specify the topology of the mesh.
445        Mesh::new(
446            bevy::render::mesh::PrimitiveTopology::TriangleList,
447            RenderAssetUsages::default(),
448        )
449        .with_inserted_indices(bevy::render::mesh::Indices::U32(indices))
450        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
451        .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
452        .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
453    }
examples/animation/custom_skinned_mesh.rs (lines 138-140)
39fn setup(
40    mut commands: Commands,
41    asset_server: Res<AssetServer>,
42    mut meshes: ResMut<Assets<Mesh>>,
43    mut materials: ResMut<Assets<StandardMaterial>>,
44    mut skinned_mesh_inverse_bindposes_assets: ResMut<Assets<SkinnedMeshInverseBindposes>>,
45) {
46    // Create a camera
47    commands.spawn((
48        Camera3d::default(),
49        Transform::from_xyz(2.5, 2.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
50    ));
51
52    // Create inverse bindpose matrices for a skeleton consists of 2 joints
53    let inverse_bindposes = skinned_mesh_inverse_bindposes_assets.add(vec![
54        Mat4::from_translation(Vec3::new(-0.5, -1.0, 0.0)),
55        Mat4::from_translation(Vec3::new(-0.5, -1.0, 0.0)),
56    ]);
57
58    // Create a mesh
59    let mesh = Mesh::new(
60        PrimitiveTopology::TriangleList,
61        RenderAssetUsages::RENDER_WORLD,
62    )
63    // Set mesh vertex positions
64    .with_inserted_attribute(
65        Mesh::ATTRIBUTE_POSITION,
66        vec![
67            [0.0, 0.0, 0.0],
68            [1.0, 0.0, 0.0],
69            [0.0, 0.5, 0.0],
70            [1.0, 0.5, 0.0],
71            [0.0, 1.0, 0.0],
72            [1.0, 1.0, 0.0],
73            [0.0, 1.5, 0.0],
74            [1.0, 1.5, 0.0],
75            [0.0, 2.0, 0.0],
76            [1.0, 2.0, 0.0],
77        ],
78    )
79    // Add UV coordinates that map the left half of the texture since its a 1 x
80    // 2 rectangle.
81    .with_inserted_attribute(
82        Mesh::ATTRIBUTE_UV_0,
83        vec![
84            [0.0, 0.00],
85            [0.5, 0.00],
86            [0.0, 0.25],
87            [0.5, 0.25],
88            [0.0, 0.50],
89            [0.5, 0.50],
90            [0.0, 0.75],
91            [0.5, 0.75],
92            [0.0, 1.00],
93            [0.5, 1.00],
94        ],
95    )
96    // Set mesh vertex normals
97    .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vec![[0.0, 0.0, 1.0]; 10])
98    // Set mesh vertex joint indices for mesh skinning.
99    // Each vertex gets 4 indices used to address the `JointTransforms` array in the vertex shader
100    //  as well as `SkinnedMeshJoint` array in the `SkinnedMesh` component.
101    // This means that a maximum of 4 joints can affect a single vertex.
102    .with_inserted_attribute(
103        Mesh::ATTRIBUTE_JOINT_INDEX,
104        // Need to be explicit here as [u16; 4] could be either Uint16x4 or Unorm16x4.
105        VertexAttributeValues::Uint16x4(vec![
106            [0, 0, 0, 0],
107            [0, 0, 0, 0],
108            [0, 1, 0, 0],
109            [0, 1, 0, 0],
110            [0, 1, 0, 0],
111            [0, 1, 0, 0],
112            [0, 1, 0, 0],
113            [0, 1, 0, 0],
114            [0, 1, 0, 0],
115            [0, 1, 0, 0],
116        ]),
117    )
118    // Set mesh vertex joint weights for mesh skinning.
119    // Each vertex gets 4 joint weights corresponding to the 4 joint indices assigned to it.
120    // The sum of these weights should equal to 1.
121    .with_inserted_attribute(
122        Mesh::ATTRIBUTE_JOINT_WEIGHT,
123        vec![
124            [1.00, 0.00, 0.0, 0.0],
125            [1.00, 0.00, 0.0, 0.0],
126            [0.75, 0.25, 0.0, 0.0],
127            [0.75, 0.25, 0.0, 0.0],
128            [0.50, 0.50, 0.0, 0.0],
129            [0.50, 0.50, 0.0, 0.0],
130            [0.25, 0.75, 0.0, 0.0],
131            [0.25, 0.75, 0.0, 0.0],
132            [0.00, 1.00, 0.0, 0.0],
133            [0.00, 1.00, 0.0, 0.0],
134        ],
135    )
136    // Tell bevy to construct triangles from a list of vertex indices,
137    // where each 3 vertex indices form a triangle.
138    .with_inserted_indices(Indices::U16(vec![
139        0, 1, 3, 0, 3, 2, 2, 3, 5, 2, 5, 4, 4, 5, 7, 4, 7, 6, 6, 7, 9, 6, 9, 8,
140    ]));
141
142    let mesh = meshes.add(mesh);
143
144    // We're seeding the PRNG here to make this example deterministic for testing purposes.
145    // This isn't strictly required in practical use unless you need your app to be deterministic.
146    let mut rng = ChaCha8Rng::seed_from_u64(42);
147
148    for i in -5..5 {
149        // Create joint entities
150        let joint_0 = commands
151            .spawn(Transform::from_xyz(
152                i as f32 * 1.5,
153                0.0,
154                // Move quads back a small amount to avoid Z-fighting and not
155                // obscure the transform gizmos.
156                -(i as f32 * 0.01).abs(),
157            ))
158            .id();
159        let joint_1 = commands.spawn((AnimatedJoint(i), Transform::IDENTITY)).id();
160
161        // Set joint_1 as a child of joint_0.
162        commands.entity(joint_0).add_children(&[joint_1]);
163
164        // Each joint in this vector corresponds to each inverse bindpose matrix in `SkinnedMeshInverseBindposes`.
165        let joint_entities = vec![joint_0, joint_1];
166
167        // Create skinned mesh renderer. Note that its transform doesn't affect the position of the mesh.
168        commands.spawn((
169            Mesh3d(mesh.clone()),
170            MeshMaterial3d(materials.add(StandardMaterial {
171                base_color: Color::srgb(
172                    rng.gen_range(0.0..1.0),
173                    rng.gen_range(0.0..1.0),
174                    rng.gen_range(0.0..1.0),
175                ),
176                base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
177                ..default()
178            })),
179            SkinnedMesh {
180                inverse_bindposes: inverse_bindposes.clone(),
181                joints: joint_entities,
182            },
183        ));
184    }
185}
examples/3d/generate_custom_mesh.rs (lines 245-252)
108fn create_cube_mesh() -> Mesh {
109    // Keep the mesh data accessible in future frames to be able to mutate it in toggle_texture.
110    Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD)
111    .with_inserted_attribute(
112        Mesh::ATTRIBUTE_POSITION,
113        // Each array is an [x, y, z] coordinate in local space.
114        // The camera coordinate space is right-handed x-right, y-up, z-back. This means "forward" is -Z.
115        // Meshes always rotate around their local [0, 0, 0] when a rotation is applied to their Transform.
116        // By centering our mesh around the origin, rotating the mesh preserves its center of mass.
117        vec![
118            // top (facing towards +y)
119            [-0.5, 0.5, -0.5], // vertex with index 0
120            [0.5, 0.5, -0.5], // vertex with index 1
121            [0.5, 0.5, 0.5], // etc. until 23
122            [-0.5, 0.5, 0.5],
123            // bottom   (-y)
124            [-0.5, -0.5, -0.5],
125            [0.5, -0.5, -0.5],
126            [0.5, -0.5, 0.5],
127            [-0.5, -0.5, 0.5],
128            // right    (+x)
129            [0.5, -0.5, -0.5],
130            [0.5, -0.5, 0.5],
131            [0.5, 0.5, 0.5], // This vertex is at the same position as vertex with index 2, but they'll have different UV and normal
132            [0.5, 0.5, -0.5],
133            // left     (-x)
134            [-0.5, -0.5, -0.5],
135            [-0.5, -0.5, 0.5],
136            [-0.5, 0.5, 0.5],
137            [-0.5, 0.5, -0.5],
138            // back     (+z)
139            [-0.5, -0.5, 0.5],
140            [-0.5, 0.5, 0.5],
141            [0.5, 0.5, 0.5],
142            [0.5, -0.5, 0.5],
143            // forward  (-z)
144            [-0.5, -0.5, -0.5],
145            [-0.5, 0.5, -0.5],
146            [0.5, 0.5, -0.5],
147            [0.5, -0.5, -0.5],
148        ],
149    )
150    // Set-up UV coordinates to point to the upper (V < 0.5), "dirt+grass" part of the texture.
151    // Take a look at the custom image (assets/textures/array_texture.png)
152    // so the UV coords will make more sense
153    // Note: (0.0, 0.0) = Top-Left in UV mapping, (1.0, 1.0) = Bottom-Right in UV mapping
154    .with_inserted_attribute(
155        Mesh::ATTRIBUTE_UV_0,
156        vec![
157            // Assigning the UV coords for the top side.
158            [0.0, 0.2], [0.0, 0.0], [1.0, 0.0], [1.0, 0.2],
159            // Assigning the UV coords for the bottom side.
160            [0.0, 0.45], [0.0, 0.25], [1.0, 0.25], [1.0, 0.45],
161            // Assigning the UV coords for the right side.
162            [1.0, 0.45], [0.0, 0.45], [0.0, 0.2], [1.0, 0.2],
163            // Assigning the UV coords for the left side.
164            [1.0, 0.45], [0.0, 0.45], [0.0, 0.2], [1.0, 0.2],
165            // Assigning the UV coords for the back side.
166            [0.0, 0.45], [0.0, 0.2], [1.0, 0.2], [1.0, 0.45],
167            // Assigning the UV coords for the forward side.
168            [0.0, 0.45], [0.0, 0.2], [1.0, 0.2], [1.0, 0.45],
169        ],
170    )
171    // For meshes with flat shading, normals are orthogonal (pointing out) from the direction of
172    // the surface.
173    // Normals are required for correct lighting calculations.
174    // Each array represents a normalized vector, which length should be equal to 1.0.
175    .with_inserted_attribute(
176        Mesh::ATTRIBUTE_NORMAL,
177        vec![
178            // Normals for the top side (towards +y)
179            [0.0, 1.0, 0.0],
180            [0.0, 1.0, 0.0],
181            [0.0, 1.0, 0.0],
182            [0.0, 1.0, 0.0],
183            // Normals for the bottom side (towards -y)
184            [0.0, -1.0, 0.0],
185            [0.0, -1.0, 0.0],
186            [0.0, -1.0, 0.0],
187            [0.0, -1.0, 0.0],
188            // Normals for the right side (towards +x)
189            [1.0, 0.0, 0.0],
190            [1.0, 0.0, 0.0],
191            [1.0, 0.0, 0.0],
192            [1.0, 0.0, 0.0],
193            // Normals for the left side (towards -x)
194            [-1.0, 0.0, 0.0],
195            [-1.0, 0.0, 0.0],
196            [-1.0, 0.0, 0.0],
197            [-1.0, 0.0, 0.0],
198            // Normals for the back side (towards +z)
199            [0.0, 0.0, 1.0],
200            [0.0, 0.0, 1.0],
201            [0.0, 0.0, 1.0],
202            [0.0, 0.0, 1.0],
203            // Normals for the forward side (towards -z)
204            [0.0, 0.0, -1.0],
205            [0.0, 0.0, -1.0],
206            [0.0, 0.0, -1.0],
207            [0.0, 0.0, -1.0],
208        ],
209    )
210    // Create the triangles out of the 24 vertices we created.
211    // To construct a square, we need 2 triangles, therefore 12 triangles in total.
212    // To construct a triangle, we need the indices of its 3 defined vertices, adding them one
213    // by one, in a counter-clockwise order (relative to the position of the viewer, the order
214    // should appear counter-clockwise from the front of the triangle, in this case from outside the cube).
215    // Read more about how to correctly build a mesh manually in the Bevy documentation of a Mesh,
216    // further examples and the implementation of the built-in shapes.
217    //
218    // The first two defined triangles look like this (marked with the vertex indices,
219    // and the axis), when looking down at the top (+y) of the cube:
220    //   -Z
221    //   ^
222    // 0---1
223    // |  /|
224    // | / | -> +X
225    // |/  |
226    // 3---2
227    //
228    // The right face's (+x) triangles look like this, seen from the outside of the cube.
229    //   +Y
230    //   ^
231    // 10--11
232    // |  /|
233    // | / | -> -Z
234    // |/  |
235    // 9---8
236    //
237    // The back face's (+z) triangles look like this, seen from the outside of the cube.
238    //   +Y
239    //   ^
240    // 17--18
241    // |\  |
242    // | \ | -> +X
243    // |  \|
244    // 16--19
245    .with_inserted_indices(Indices::U32(vec![
246        0,3,1 , 1,3,2, // triangles making up the top (+y) facing side.
247        4,5,7 , 5,6,7, // bottom (-y)
248        8,11,9 , 9,11,10, // right (+x)
249        12,13,15 , 13,14,15, // left (-x)
250        16,19,17 , 17,19,18, // back (+z)
251        20,21,23 , 21,22,23, // forward (-z)
252    ]))
253}
Source

pub fn indices(&self) -> Option<&Indices>

Retrieves the vertex indices of the mesh.

Source

pub fn indices_mut(&mut self) -> Option<&mut Indices>

Retrieves the vertex indices of the mesh mutably.

Source

pub fn remove_indices(&mut self) -> Option<Indices>

Removes the vertex indices from the mesh and returns them.

Source

pub fn with_removed_indices(self) -> Mesh

Consumes the mesh and returns a mesh without the vertex indices of the mesh.

(Alternatively, you can use Mesh::remove_indices to mutate an existing mesh in-place)

Source

pub fn get_vertex_size(&self) -> u64

Returns the size of a vertex in bytes.

Source

pub fn get_vertex_buffer_size(&self) -> usize

Returns the size required for the vertex buffer in bytes.

Source

pub fn get_index_buffer_bytes(&self) -> Option<&[u8]>

Computes and returns the index data of the mesh as bytes. This is used to transform the index data into a GPU friendly format.

Source

pub fn get_mesh_vertex_buffer_layout( &self, mesh_vertex_buffer_layouts: &mut MeshVertexBufferLayouts, ) -> MeshVertexBufferLayoutRef

Get this Mesh’s MeshVertexBufferLayout, used in SpecializedMeshPipeline.

Source

pub fn count_vertices(&self) -> usize

Counts all vertices of the mesh.

If the attributes have different vertex counts, the smallest is returned.

Source

pub fn create_packed_vertex_buffer_data(&self) -> Vec<u8>

Computes and returns the vertex data of the mesh as bytes. Therefore the attributes are located in the order of their MeshVertexAttribute::id. This is used to transform the vertex data into a GPU friendly format.

If the vertex attributes have different lengths, they are all truncated to the length of the smallest.

This is a convenience method which allocates a Vec. Prefer pre-allocating and using Mesh::write_packed_vertex_buffer_data when possible.

Source

pub fn write_packed_vertex_buffer_data(&self, slice: &mut [u8])

Computes and write the vertex data of the mesh into a mutable byte slice. The attributes are located in the order of their MeshVertexAttribute::id. This is used to transform the vertex data into a GPU friendly format.

If the vertex attributes have different lengths, they are all truncated to the length of the smallest.

Source

pub fn duplicate_vertices(&mut self)

Duplicates the vertex attributes so that no vertices are shared.

This can dramatically increase the vertex count, so make sure this is what you want. Does nothing if no Indices are set.

Source

pub fn with_duplicated_vertices(self) -> Mesh

Consumes the mesh and returns a mesh with no shared vertices.

This can dramatically increase the vertex count, so make sure this is what you want. Does nothing if no Indices are set.

(Alternatively, you can use Mesh::duplicate_vertices to mutate an existing mesh in-place)

Source

pub fn invert_winding(&mut self) -> Result<(), MeshWindingInvertError>

Inverts the winding of the indices such that all counter-clockwise triangles are now clockwise and vice versa. For lines, their start and end indices are flipped.

Does nothing if no Indices are set. If this operation succeeded, an Ok result is returned.

Source

pub fn with_inverted_winding(self) -> Result<Mesh, MeshWindingInvertError>

Consumes the mesh and returns a mesh with inverted winding of the indices such that all counter-clockwise triangles are now clockwise and vice versa.

Does nothing if no Indices are set.

Source

pub fn compute_normals(&mut self)

Calculates the Mesh::ATTRIBUTE_NORMAL of a mesh. If the mesh is indexed, this defaults to smooth normals. Otherwise, it defaults to flat normals.

§Panics

Panics if Mesh::ATTRIBUTE_POSITION is not of type float3. Panics if the mesh has any other topology than PrimitiveTopology::TriangleList.

FIXME: This should handle more cases since this is called as a part of gltf mesh loading where we can’t really blame users for loading meshes that might not conform to the limitations here!

Source

pub fn compute_flat_normals(&mut self)

Calculates the Mesh::ATTRIBUTE_NORMAL of a mesh.

§Panics

Panics if Indices are set or Mesh::ATTRIBUTE_POSITION is not of type float3. Panics if the mesh has any other topology than PrimitiveTopology::TriangleList. Consider calling Mesh::duplicate_vertices or exporting your mesh with normal attributes.

FIXME: This should handle more cases since this is called as a part of gltf mesh loading where we can’t really blame users for loading meshes that might not conform to the limitations here!

Source

pub fn compute_smooth_normals(&mut self)

Calculates the Mesh::ATTRIBUTE_NORMAL of an indexed mesh, smoothing normals for shared vertices.

§Panics

Panics if Mesh::ATTRIBUTE_POSITION is not of type float3. Panics if the mesh has any other topology than PrimitiveTopology::TriangleList. Panics if the mesh does not have indices defined.

FIXME: This should handle more cases since this is called as a part of gltf mesh loading where we can’t really blame users for loading meshes that might not conform to the limitations here!

Source

pub fn with_computed_normals(self) -> Mesh

Consumes the mesh and returns a mesh with calculated Mesh::ATTRIBUTE_NORMAL. If the mesh is indexed, this defaults to smooth normals. Otherwise, it defaults to flat normals.

(Alternatively, you can use Mesh::compute_normals to mutate an existing mesh in-place)

§Panics

Panics if Mesh::ATTRIBUTE_POSITION is not of type float3. Panics if the mesh has any other topology than PrimitiveTopology::TriangleList.

Source

pub fn with_computed_flat_normals(self) -> Mesh

Consumes the mesh and returns a mesh with calculated Mesh::ATTRIBUTE_NORMAL.

(Alternatively, you can use Mesh::compute_flat_normals to mutate an existing mesh in-place)

§Panics

Panics if Mesh::ATTRIBUTE_POSITION is not of type float3. Panics if the mesh has any other topology than PrimitiveTopology::TriangleList. Panics if the mesh has indices defined

Source

pub fn with_computed_smooth_normals(self) -> Mesh

Consumes the mesh and returns a mesh with calculated Mesh::ATTRIBUTE_NORMAL.

(Alternatively, you can use Mesh::compute_smooth_normals to mutate an existing mesh in-place)

§Panics

Panics if Mesh::ATTRIBUTE_POSITION is not of type float3. Panics if the mesh has any other topology than PrimitiveTopology::TriangleList. Panics if the mesh does not have indices defined.

Source

pub fn generate_tangents(&mut self) -> Result<(), GenerateTangentsError>

Generate tangents for the mesh using the mikktspace algorithm.

Sets the Mesh::ATTRIBUTE_TANGENT attribute if successful. Requires a PrimitiveTopology::TriangleList topology and the Mesh::ATTRIBUTE_POSITION, Mesh::ATTRIBUTE_NORMAL and Mesh::ATTRIBUTE_UV_0 attributes set.

Examples found in repository?
examples/3d/clearcoat.rs (line 86)
80fn create_sphere_mesh(meshes: &mut Assets<Mesh>) -> Handle<Mesh> {
81    // We're going to use normal maps, so make sure we've generated tangents, or
82    // else the normal maps won't show up.
83
84    let mut sphere_mesh = Sphere::new(1.0).mesh().build();
85    sphere_mesh
86        .generate_tangents()
87        .expect("Failed to generate tangents");
88    meshes.add(sphere_mesh)
89}
More examples
Hide additional examples
examples/3d/rotate_environment_map.rs (line 54)
48fn create_sphere_mesh(meshes: &mut Assets<Mesh>) -> Handle<Mesh> {
49    // We're going to use normal maps, so make sure we've generated tangents, or
50    // else the normal maps won't show up.
51
52    let mut sphere_mesh = Sphere::new(1.0).mesh().build();
53    sphere_mesh
54        .generate_tangents()
55        .expect("Failed to generate tangents");
56    meshes.add(sphere_mesh)
57}
examples/3d/deferred_rendering.rs (line 238)
218fn setup_parallax(
219    mut commands: Commands,
220    mut materials: ResMut<Assets<StandardMaterial>>,
221    mut meshes: ResMut<Assets<Mesh>>,
222    asset_server: Res<AssetServer>,
223) {
224    // The normal map. Note that to generate it in the GIMP image editor, you should
225    // open the depth map, and do Filters → Generic → Normal Map
226    // You should enable the "flip X" checkbox.
227    let normal_handle = asset_server.load_with_settings(
228        "textures/parallax_example/cube_normal.png",
229        // The normal map texture is in linear color space. Lighting won't look correct
230        // if `is_srgb` is `true`, which is the default.
231        |settings: &mut ImageLoaderSettings| settings.is_srgb = false,
232    );
233
234    let mut cube = Mesh::from(Cuboid::new(0.15, 0.15, 0.15));
235
236    // NOTE: for normal maps and depth maps to work, the mesh
237    // needs tangents generated.
238    cube.generate_tangents().unwrap();
239
240    let parallax_material = materials.add(StandardMaterial {
241        perceptual_roughness: 0.4,
242        base_color_texture: Some(asset_server.load("textures/parallax_example/cube_color.png")),
243        normal_map_texture: Some(normal_handle),
244        // The depth map is a grayscale texture where black is the highest level and
245        // white the lowest.
246        depth_map: Some(asset_server.load("textures/parallax_example/cube_depth.png")),
247        parallax_depth_scale: 0.09,
248        parallax_mapping_method: ParallaxMappingMethod::Relief { max_steps: 4 },
249        max_parallax_layer_count: ops::exp2(5.0f32),
250        ..default()
251    });
252    commands.spawn((
253        Mesh3d(meshes.add(cube)),
254        MeshMaterial3d(parallax_material),
255        Transform::from_xyz(0.4, 0.2, -0.8),
256        Spin { speed: 0.3 },
257    ));
258}
examples/ecs/error_handling.rs (line 98)
67fn setup(
68    mut commands: Commands,
69    mut meshes: ResMut<Assets<Mesh>>,
70    mut materials: ResMut<Assets<StandardMaterial>>,
71) -> Result {
72    let mut seeded_rng = ChaCha8Rng::seed_from_u64(19878367467712);
73
74    // Make a plane for establishing space.
75    commands.spawn((
76        Mesh3d(meshes.add(Plane3d::default().mesh().size(12.0, 12.0))),
77        MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
78        Transform::from_xyz(0.0, -2.5, 0.0),
79    ));
80
81    // Spawn a light:
82    commands.spawn((
83        PointLight {
84            shadows_enabled: true,
85            ..default()
86        },
87        Transform::from_xyz(4.0, 8.0, 4.0),
88    ));
89
90    // Spawn a camera:
91    commands.spawn((
92        Camera3d::default(),
93        Transform::from_xyz(-2.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
94    ));
95
96    // Create a new sphere mesh:
97    let mut sphere_mesh = Sphere::new(1.0).mesh().ico(7)?;
98    sphere_mesh.generate_tangents()?;
99
100    // Spawn the mesh into the scene:
101    let mut sphere = commands.spawn((
102        Mesh3d(meshes.add(sphere_mesh.clone())),
103        MeshMaterial3d(materials.add(StandardMaterial::default())),
104        Transform::from_xyz(-1.0, 1.0, 0.0),
105    ));
106
107    // Generate random sample points:
108    let triangles = sphere_mesh.triangles()?;
109    let distribution = UniformMeshSampler::try_new(triangles)?;
110
111    // Setup sample points:
112    let point_mesh = meshes.add(Sphere::new(0.01).mesh().ico(3)?);
113    let point_material = materials.add(StandardMaterial {
114        base_color: Srgba::RED.into(),
115        emissive: LinearRgba::rgb(1.0, 0.0, 0.0),
116        ..default()
117    });
118
119    // Add sample points as children of the sphere:
120    for point in distribution.sample_iter(&mut seeded_rng).take(10000) {
121        sphere.with_child((
122            Mesh3d(point_mesh.clone()),
123            MeshMaterial3d(point_material.clone()),
124            Transform::from_translation(point),
125        ));
126    }
127
128    // Indicate the system completed successfully:
129    Ok(())
130}
Source

pub fn with_generated_tangents(self) -> Result<Mesh, GenerateTangentsError>

Consumes the mesh and returns a mesh with tangents generated using the mikktspace algorithm.

The resulting mesh will have the Mesh::ATTRIBUTE_TANGENT attribute if successful.

(Alternatively, you can use Mesh::generate_tangents to mutate an existing mesh in-place)

Requires a PrimitiveTopology::TriangleList topology and the Mesh::ATTRIBUTE_POSITION, Mesh::ATTRIBUTE_NORMAL and Mesh::ATTRIBUTE_UV_0 attributes set.

Examples found in repository?
examples/3d/anisotropy.rs (line 118)
100fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_status: Res<AppStatus>) {
101    commands.spawn((
102        Camera3d::default(),
103        Transform::from_translation(CAMERA_INITIAL_POSITION).looking_at(Vec3::ZERO, Vec3::Y),
104    ));
105
106    spawn_directional_light(&mut commands);
107
108    commands.spawn((
109        SceneRoot(asset_server.load("models/AnisotropyBarnLamp/AnisotropyBarnLamp.gltf#Scene0")),
110        Transform::from_xyz(0.0, 0.07, -0.13),
111        Scene::BarnLamp,
112    ));
113
114    commands.spawn((
115        Mesh3d(
116            asset_server.add(
117                Mesh::from(Sphere::new(0.1))
118                    .with_generated_tangents()
119                    .unwrap(),
120            ),
121        ),
122        MeshMaterial3d(asset_server.add(StandardMaterial {
123            base_color: palettes::tailwind::GRAY_300.into(),
124            anisotropy_rotation: 0.5,
125            anisotropy_strength: 1.,
126            ..default()
127        })),
128        Scene::Sphere,
129        Visibility::Hidden,
130    ));
131
132    spawn_text(&mut commands, &app_status);
133}
More examples
Hide additional examples
examples/3d/parallax_mapping.rs (line 270)
198fn setup(
199    mut commands: Commands,
200    mut materials: ResMut<Assets<StandardMaterial>>,
201    mut meshes: ResMut<Assets<Mesh>>,
202    asset_server: Res<AssetServer>,
203) {
204    // The normal map. Note that to generate it in the GIMP image editor, you should
205    // open the depth map, and do Filters → Generic → Normal Map
206    // You should enable the "flip X" checkbox.
207    let normal_handle = asset_server.load_with_settings(
208        "textures/parallax_example/cube_normal.png",
209        // The normal map texture is in linear color space. Lighting won't look correct
210        // if `is_srgb` is `true`, which is the default.
211        |settings: &mut ImageLoaderSettings| settings.is_srgb = false,
212    );
213
214    // Camera
215    commands.spawn((
216        Camera3d::default(),
217        Transform::from_xyz(1.5, 1.5, 1.5).looking_at(Vec3::ZERO, Vec3::Y),
218        CameraController,
219    ));
220
221    // light
222    commands
223        .spawn((
224            PointLight {
225                shadows_enabled: true,
226                ..default()
227            },
228            Transform::from_xyz(2.0, 1.0, -1.1),
229        ))
230        .with_children(|commands| {
231            // represent the light source as a sphere
232            let mesh = meshes.add(Sphere::new(0.05).mesh().ico(3).unwrap());
233            commands.spawn((Mesh3d(mesh), MeshMaterial3d(materials.add(Color::WHITE))));
234        });
235
236    // Plane
237    commands.spawn((
238        Mesh3d(meshes.add(Plane3d::default().mesh().size(10.0, 10.0))),
239        MeshMaterial3d(materials.add(StandardMaterial {
240            // standard material derived from dark green, but
241            // with roughness and reflectance set.
242            perceptual_roughness: 0.45,
243            reflectance: 0.18,
244            ..Color::srgb_u8(0, 80, 0).into()
245        })),
246        Transform::from_xyz(0.0, -1.0, 0.0),
247    ));
248
249    let parallax_depth_scale = TargetDepth::default().0;
250    let max_parallax_layer_count = ops::exp2(TargetLayers::default().0);
251    let parallax_mapping_method = CurrentMethod::default();
252    let parallax_material = materials.add(StandardMaterial {
253        perceptual_roughness: 0.4,
254        base_color_texture: Some(asset_server.load("textures/parallax_example/cube_color.png")),
255        normal_map_texture: Some(normal_handle),
256        // The depth map is a grayscale texture where black is the highest level and
257        // white the lowest.
258        depth_map: Some(asset_server.load("textures/parallax_example/cube_depth.png")),
259        parallax_depth_scale,
260        parallax_mapping_method: parallax_mapping_method.0,
261        max_parallax_layer_count,
262        ..default()
263    });
264    commands.spawn((
265        Mesh3d(
266            meshes.add(
267                // NOTE: for normal maps and depth maps to work, the mesh
268                // needs tangents generated.
269                Mesh::from(Cuboid::default())
270                    .with_generated_tangents()
271                    .unwrap(),
272            ),
273        ),
274        MeshMaterial3d(parallax_material.clone()),
275        Spin { speed: 0.3 },
276    ));
277
278    let background_cube = meshes.add(
279        Mesh::from(Cuboid::new(40.0, 40.0, 40.0))
280            .with_generated_tangents()
281            .unwrap(),
282    );
283
284    let background_cube_bundle = |translation| {
285        (
286            Mesh3d(background_cube.clone()),
287            MeshMaterial3d(parallax_material.clone()),
288            Transform::from_translation(translation),
289            Spin { speed: -0.1 },
290        )
291    };
292    commands.spawn(background_cube_bundle(Vec3::new(45., 0., 0.)));
293    commands.spawn(background_cube_bundle(Vec3::new(-45., 0., 0.)));
294    commands.spawn(background_cube_bundle(Vec3::new(0., 0., 45.)));
295    commands.spawn(background_cube_bundle(Vec3::new(0., 0., -45.)));
296
297    // example instructions
298    commands
299        .spawn((
300            Text::default(),
301            Node {
302                position_type: PositionType::Absolute,
303                top: Val::Px(12.0),
304                left: Val::Px(12.0),
305                ..default()
306            },
307        ))
308        .with_children(|p| {
309            p.spawn(TextSpan(format!(
310                "Parallax depth scale: {parallax_depth_scale:.5}\n"
311            )));
312            p.spawn(TextSpan(format!("Layers: {max_parallax_layer_count:.0}\n")));
313            p.spawn(TextSpan(format!("{parallax_mapping_method}\n")));
314            p.spawn(TextSpan::new("\n\n"));
315            p.spawn(TextSpan::new("Controls:\n"));
316            p.spawn(TextSpan::new("Left click - Change view angle\n"));
317            p.spawn(TextSpan::new(
318                "1/2 - Decrease/Increase parallax depth scale\n",
319            ));
320            p.spawn(TextSpan::new("3/4 - Decrease/Increase layer count\n"));
321            p.spawn(TextSpan::new("Space - Switch parallaxing algorithm\n"));
322        });
323}
Source

pub fn merge(&mut self, other: &Mesh) -> Result<(), MergeMeshError>

Merges the Mesh data of other with self. The attributes and indices of other will be appended to self.

Note that attributes of other that don’t exist on self will be ignored.

Aabb of entities with modified mesh are not updated automatically.

§Errors

Returns Err(MergeMeshError) if the vertex attribute values of other are incompatible with self. For example, VertexAttributeValues::Float32 is incompatible with VertexAttributeValues::Float32x3.

Source

pub fn transformed_by(self, transform: Transform) -> Mesh

Transforms the vertex positions, normals, and tangents of the mesh by the given Transform.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn transform_by(&mut self, transform: Transform)

Transforms the vertex positions, normals, and tangents of the mesh in place by the given Transform.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn translated_by(self, translation: Vec3) -> Mesh

Translates the vertex positions of the mesh by the given Vec3.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn translate_by(&mut self, translation: Vec3)

Translates the vertex positions of the mesh in place by the given Vec3.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn rotated_by(self, rotation: Quat) -> Mesh

Rotates the vertex positions, normals, and tangents of the mesh by the given Quat.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn rotate_by(&mut self, rotation: Quat)

Rotates the vertex positions, normals, and tangents of the mesh in place by the given Quat.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn scaled_by(self, scale: Vec3) -> Mesh

Scales the vertex positions, normals, and tangents of the mesh by the given Vec3.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn scale_by(&mut self, scale: Vec3)

Scales the vertex positions, normals, and tangents of the mesh in place by the given Vec3.

Aabb of entities with modified mesh are not updated automatically.

Source

pub fn has_morph_targets(&self) -> bool

Whether this mesh has morph targets.

Source

pub fn set_morph_targets(&mut self, morph_targets: Handle<Image>)

Set morph targets image for this mesh. This requires a “morph target image”. See MorphTargetImage for info.

Source

pub fn morph_targets(&self) -> Option<&Handle<Image>>

Source

pub fn with_morph_targets(self, morph_targets: Handle<Image>) -> Mesh

Consumes the mesh and returns a mesh with the given morph targets.

This requires a “morph target image”. See MorphTargetImage for info.

(Alternatively, you can use Mesh::set_morph_targets to mutate an existing mesh in-place)

Source

pub fn set_morph_target_names(&mut self, names: Vec<String>)

Sets the names of each morph target. This should correspond to the order of the morph targets in set_morph_targets.

Source

pub fn with_morph_target_names(self, names: Vec<String>) -> Mesh

Consumes the mesh and returns a mesh with morph target names. Names should correspond to the order of the morph targets in set_morph_targets.

(Alternatively, you can use Mesh::set_morph_target_names to mutate an existing mesh in-place)

Source

pub fn morph_target_names(&self) -> Option<&[String]>

Gets a list of all morph target names, if they exist.

Examples found in repository?
examples/animation/morph_targets.rs (line 103)
91fn name_morphs(
92    mut has_printed: Local<bool>,
93    morph_data: Res<MorphData>,
94    meshes: Res<Assets<Mesh>>,
95) {
96    if *has_printed {
97        return;
98    }
99
100    let Some(mesh) = meshes.get(&morph_data.mesh) else {
101        return;
102    };
103    let Some(names) = mesh.morph_target_names() else {
104        return;
105    };
106
107    info!("Target names:");
108    for name in names {
109        info!("  {name}");
110    }
111    *has_printed = true;
112}
Source

pub fn normalize_joint_weights(&mut self)

Normalize joint weights so they sum to 1.

Source

pub fn triangles( &self, ) -> Result<impl Iterator<Item = Triangle3d>, MeshTrianglesError>

Get a list of this Mesh’s triangles as an iterator if possible.

Returns an error if any of the following conditions are met (see MeshTrianglesError):

  • The Mesh’s primitive topology is not TriangleList or TriangleStrip.
  • The Mesh is missing position or index data.
  • The Mesh’s position data has the wrong format (not Float32x3).
Examples found in repository?
examples/ecs/error_handling.rs (line 108)
67fn setup(
68    mut commands: Commands,
69    mut meshes: ResMut<Assets<Mesh>>,
70    mut materials: ResMut<Assets<StandardMaterial>>,
71) -> Result {
72    let mut seeded_rng = ChaCha8Rng::seed_from_u64(19878367467712);
73
74    // Make a plane for establishing space.
75    commands.spawn((
76        Mesh3d(meshes.add(Plane3d::default().mesh().size(12.0, 12.0))),
77        MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
78        Transform::from_xyz(0.0, -2.5, 0.0),
79    ));
80
81    // Spawn a light:
82    commands.spawn((
83        PointLight {
84            shadows_enabled: true,
85            ..default()
86        },
87        Transform::from_xyz(4.0, 8.0, 4.0),
88    ));
89
90    // Spawn a camera:
91    commands.spawn((
92        Camera3d::default(),
93        Transform::from_xyz(-2.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
94    ));
95
96    // Create a new sphere mesh:
97    let mut sphere_mesh = Sphere::new(1.0).mesh().ico(7)?;
98    sphere_mesh.generate_tangents()?;
99
100    // Spawn the mesh into the scene:
101    let mut sphere = commands.spawn((
102        Mesh3d(meshes.add(sphere_mesh.clone())),
103        MeshMaterial3d(materials.add(StandardMaterial::default())),
104        Transform::from_xyz(-1.0, 1.0, 0.0),
105    ));
106
107    // Generate random sample points:
108    let triangles = sphere_mesh.triangles()?;
109    let distribution = UniformMeshSampler::try_new(triangles)?;
110
111    // Setup sample points:
112    let point_mesh = meshes.add(Sphere::new(0.01).mesh().ico(3)?);
113    let point_material = materials.add(StandardMaterial {
114        base_color: Srgba::RED.into(),
115        emissive: LinearRgba::rgb(1.0, 0.0, 0.0),
116        ..default()
117    });
118
119    // Add sample points as children of the sphere:
120    for point in distribution.sample_iter(&mut seeded_rng).take(10000) {
121        sphere.with_child((
122            Mesh3d(point_mesh.clone()),
123            MeshMaterial3d(point_material.clone()),
124            Transform::from_translation(point),
125        ));
126    }
127
128    // Indicate the system completed successfully:
129    Ok(())
130}

Trait Implementations§

Source§

impl Clone for Mesh

Source§

fn clone(&self) -> Mesh

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Mesh

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl From<Annulus> for Mesh

Source§

fn from(annulus: Annulus) -> Mesh

Converts to this type from the input type.
Source§

impl From<Capsule2d> for Mesh

Source§

fn from(capsule: Capsule2d) -> Mesh

Converts to this type from the input type.
Source§

impl From<Capsule3d> for Mesh

Source§

fn from(capsule: Capsule3d) -> Mesh

Converts to this type from the input type.
Source§

impl From<Circle> for Mesh

Source§

fn from(circle: Circle) -> Mesh

Converts to this type from the input type.
Source§

impl From<CircularSector> for Mesh

Source§

fn from(sector: CircularSector) -> Mesh

Converts this sector into a Mesh using a default CircularSectorMeshBuilder.

See the documentation of CircularSectorMeshBuilder for more details.

Source§

impl From<CircularSegment> for Mesh

Source§

fn from(segment: CircularSegment) -> Mesh

Converts this sector into a Mesh using a default CircularSegmentMeshBuilder.

See the documentation of CircularSegmentMeshBuilder for more details.

Source§

impl From<Cone> for Mesh

Source§

fn from(cone: Cone) -> Mesh

Converts to this type from the input type.
Source§

impl From<ConicalFrustum> for Mesh

Source§

fn from(frustum: ConicalFrustum) -> Mesh

Converts to this type from the input type.
Source§

impl<const N: usize> From<ConvexPolygon<N>> for Mesh

Source§

fn from(polygon: ConvexPolygon<N>) -> Mesh

Converts to this type from the input type.
Source§

impl From<Cuboid> for Mesh

Source§

fn from(cuboid: Cuboid) -> Mesh

Converts to this type from the input type.
Source§

impl From<Cylinder> for Mesh

Source§

fn from(cylinder: Cylinder) -> Mesh

Converts to this type from the input type.
Source§

impl From<Ellipse> for Mesh

Source§

fn from(ellipse: Ellipse) -> Mesh

Converts to this type from the input type.
Source§

impl<P> From<Extrusion<P>> for Mesh

Source§

fn from(value: Extrusion<P>) -> Mesh

Converts to this type from the input type.
Source§

impl From<Plane3d> for Mesh

Source§

fn from(plane: Plane3d) -> Mesh

Converts to this type from the input type.
Source§

impl From<Rectangle> for Mesh

Source§

fn from(rectangle: Rectangle) -> Mesh

Converts to this type from the input type.
Source§

impl From<RegularPolygon> for Mesh

Source§

fn from(polygon: RegularPolygon) -> Mesh

Converts to this type from the input type.
Source§

impl From<Rhombus> for Mesh

Source§

fn from(rhombus: Rhombus) -> Mesh

Converts to this type from the input type.
Source§

impl From<Sphere> for Mesh

Source§

fn from(sphere: Sphere) -> Mesh

Converts to this type from the input type.
Source§

impl<T> From<T> for Mesh
where T: MeshBuilder,

Source§

fn from(builder: T) -> Mesh

Converts to this type from the input type.
Source§

impl From<Tetrahedron> for Mesh

Source§

fn from(tetrahedron: Tetrahedron) -> Mesh

Converts to this type from the input type.
Source§

impl From<Torus> for Mesh

Source§

fn from(torus: Torus) -> Mesh

Converts to this type from the input type.
Source§

impl From<Triangle2d> for Mesh

Source§

fn from(triangle: Triangle2d) -> Mesh

Converts to this type from the input type.
Source§

impl From<Triangle3d> for Mesh

Source§

fn from(triangle: Triangle3d) -> Mesh

Converts to this type from the input type.
Source§

impl FromArg for &'static Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

type This<'from_arg> = &'from_arg Mesh

The type to convert into. Read more
Source§

fn from_arg( arg: Arg<'_>, ) -> Result<<&'static Mesh as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromArg for &'static mut Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

type This<'from_arg> = &'from_arg mut Mesh

The type to convert into. Read more
Source§

fn from_arg( arg: Arg<'_>, ) -> Result<<&'static mut Mesh as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromArg for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

type This<'from_arg> = Mesh

The type to convert into. Read more
Source§

fn from_arg(arg: Arg<'_>) -> Result<<Mesh as FromArg>::This<'_>, ArgError>

Creates an item from an argument. Read more
Source§

impl FromReflect for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn from_reflect(reflect: &(dyn PartialReflect + 'static)) -> Option<Mesh>

Constructs a concrete instance of Self from a reflected value.
Source§

fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>

Attempts to downcast the given value to Self using, constructing the value using from_reflect if that fails. Read more
Source§

impl GetOwnership for &Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetOwnership for &mut Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetOwnership for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn ownership() -> Ownership

Returns the ownership of Self.
Source§

impl GetTypeRegistration for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn get_type_registration() -> TypeRegistration

Returns the default TypeRegistration for this type.
Source§

fn register_type_dependencies(registry: &mut TypeRegistry)

Registers other types needed by this type. Read more
Source§

impl IntoReturn for &Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where &Mesh: 'into_return,

Converts Self into a Return value.
Source§

impl IntoReturn for &mut Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where &mut Mesh: 'into_return,

Converts Self into a Return value.
Source§

impl IntoReturn for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_return<'into_return>(self) -> Return<'into_return>
where Mesh: 'into_return,

Converts Self into a Return value.
Source§

impl MeshAabb for Mesh

Source§

fn compute_aabb(&self) -> Option<Aabb>

Compute the Axis-Aligned Bounding Box of the mesh vertices in model space Read more
Source§

impl Mul<Mesh> for Transform

Source§

type Output = Mesh

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Mesh) -> <Transform as Mul<Mesh>>::Output

Performs the * operation. Read more
Source§

impl PartialReflect for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn get_represented_type_info(&self) -> Option<&'static TypeInfo>

Returns the TypeInfo of the type represented by this value. Read more
Source§

fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>

Tries to apply a reflected value to this value. Read more
Source§

fn reflect_kind(&self) -> ReflectKind

Returns a zero-sized enumeration of “kinds” of type. Read more
Source§

fn reflect_ref(&self) -> ReflectRef<'_>

Returns an immutable enumeration of “kinds” of type. Read more
Source§

fn reflect_mut(&mut self) -> ReflectMut<'_>

Returns a mutable enumeration of “kinds” of type. Read more
Source§

fn reflect_owned(self: Box<Mesh>) -> ReflectOwned

Returns an owned enumeration of “kinds” of type. Read more
Source§

fn try_into_reflect( self: Box<Mesh>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>

Attempts to cast this type to a boxed, fully-reflected value.
Source§

fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>

Attempts to cast this type to a fully-reflected value.
Source§

fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>

Attempts to cast this type to a mutable, fully-reflected value.
Source§

fn into_partial_reflect(self: Box<Mesh>) -> Box<dyn PartialReflect>

Casts this type to a boxed, reflected value. Read more
Source§

fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)

Casts this type to a reflected value. Read more
Source§

fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)

Casts this type to a mutable, reflected value. Read more
Source§

fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>

Returns a “partial equality” comparison result. Read more
Source§

fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>

Attempts to clone Self using reflection. Read more
Source§

fn apply(&mut self, value: &(dyn PartialReflect + 'static))

Applies a reflected value to this value. Read more
Source§

fn clone_value(&self) -> Box<dyn PartialReflect>

👎Deprecated since 0.16.0: to clone reflected values, prefer using reflect_clone. To convert reflected values to dynamic ones, use to_dynamic.
Clones Self into its dynamic representation. Read more
Source§

fn to_dynamic(&self) -> Box<dyn PartialReflect>

Converts this reflected value into its dynamic representation based on its kind. Read more
Source§

fn reflect_hash(&self) -> Option<u64>

Returns a hash of the value (which includes the type). Read more
Source§

fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Debug formatter for the value. Read more
Source§

fn is_dynamic(&self) -> bool

Indicates whether or not this type is a dynamic type. Read more
Source§

impl Reflect for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn into_any(self: Box<Mesh>) -> Box<dyn Any>

Returns the value as a Box<dyn Any>. Read more
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Returns the value as a &dyn Any. Read more
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Returns the value as a &mut dyn Any. Read more
Source§

fn into_reflect(self: Box<Mesh>) -> Box<dyn Reflect>

Casts this type to a boxed, fully-reflected value.
Source§

fn as_reflect(&self) -> &(dyn Reflect + 'static)

Casts this type to a fully-reflected value.
Source§

fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)

Casts this type to a mutable, fully-reflected value.
Source§

fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>

Performs a type-checked assignment of a reflected value to this value. Read more
Source§

impl Struct for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn field(&self, name: &str) -> Option<&(dyn PartialReflect + 'static)>

Returns a reference to the value of the field named name as a &dyn PartialReflect.
Source§

fn field_mut( &mut self, name: &str, ) -> Option<&mut (dyn PartialReflect + 'static)>

Returns a mutable reference to the value of the field named name as a &mut dyn PartialReflect.
Source§

fn field_at(&self, index: usize) -> Option<&(dyn PartialReflect + 'static)>

Returns a reference to the value of the field with index index as a &dyn PartialReflect.
Source§

fn field_at_mut( &mut self, index: usize, ) -> Option<&mut (dyn PartialReflect + 'static)>

Returns a mutable reference to the value of the field with index index as a &mut dyn PartialReflect.
Source§

fn name_at(&self, index: usize) -> Option<&str>

Returns the name of the field with index index.
Source§

fn field_len(&self) -> usize

Returns the number of fields in the struct.
Source§

fn iter_fields(&self) -> FieldIter<'_>

Returns an iterator over the values of the reflectable fields for this struct.
Source§

fn to_dynamic_struct(&self) -> DynamicStruct

Source§

fn clone_dynamic(&self) -> DynamicStruct

👎Deprecated since 0.16.0: use to_dynamic_struct instead
Clones the struct into a DynamicStruct.
Source§

fn get_represented_struct_info(&self) -> Option<&'static StructInfo>

Will return None if TypeInfo is not available.
Source§

impl TypePath for Mesh
where Mesh: Any + Send + Sync,

Source§

fn type_path() -> &'static str

Returns the fully qualified path of the underlying type. Read more
Source§

fn short_type_path() -> &'static str

Returns a short, pretty-print enabled path to the type. Read more
Source§

fn type_ident() -> Option<&'static str>

Returns the name of the type, or None if it is anonymous. Read more
Source§

fn crate_name() -> Option<&'static str>

Returns the name of the crate the type is in, or None if it is anonymous. Read more
Source§

fn module_path() -> Option<&'static str>

Returns the path to the module the type is in, or None if it is anonymous. Read more
Source§

impl Typed for Mesh
where Mesh: Any + Send + Sync, Option<Indices>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Handle<Image>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, Option<Vec<String>>: FromReflect + TypePath + MaybeTyped + RegisterForReflection, RenderAssetUsages: FromReflect + TypePath + MaybeTyped + RegisterForReflection,

Source§

fn type_info() -> &'static TypeInfo

Returns the compile-time info for the underlying type.
Source§

impl VisitAssetDependencies for Mesh

Source§

fn visit_dependencies(&self, visit: &mut impl FnMut(UntypedAssetId))

Source§

impl Asset for Mesh

Auto Trait Implementations§

§

impl Freeze for Mesh

§

impl !RefUnwindSafe for Mesh

§

impl Send for Mesh

§

impl Sync for Mesh

§

impl Unpin for Mesh

§

impl !UnwindSafe for Mesh

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<A> AssetContainer for A
where A: Asset,

Source§

fn insert(self: Box<A>, id: UntypedAssetId, world: &mut World)

Source§

fn asset_type_name(&self) -> &'static str

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynamicTypePath for T
where T: TypePath,

Source§

impl<T> DynamicTyped for T
where T: Typed,

Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<S> GetField for S
where S: Struct,

Source§

fn get_field<T>(&self, name: &str) -> Option<&T>
where T: Reflect,

Returns a reference to the value of the field named name, downcast to T.
Source§

fn get_field_mut<T>(&mut self, name: &str) -> Option<&mut T>
where T: Reflect,

Returns a mutable reference to the value of the field named name, downcast to T.
Source§

impl<T> GetPath for T
where T: Reflect + ?Sized,

Source§

fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>

Returns a reference to the value specified by path. Read more
Source§

fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>

Returns a mutable reference to the value specified by path. Read more
Source§

fn path<'p, T>( &self, path: impl ReflectPath<'p>, ) -> Result<&T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed reference to the value specified by path. Read more
Source§

fn path_mut<'p, T>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut T, ReflectPathError<'p>>
where T: Reflect,

Returns a statically typed mutable reference to the value specified by path. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> Reflectable for T

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,