# Bundles
## `MaterialMeshBundle`
```rust
pub struct MaterialMeshBundle<M: Material> {
pub mesh: Handle<Mesh>,
pub material: Handle<M>,
pub transform: Transform,
pub global_transform: GlobalTransform,
/// User indication of whether an entity is visible
pub visibility: Visibility,
/// Inherited visibility of an entity.
pub inherited_visibility: InheritedVisibility,
/// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering
pub view_visibility: ViewVisibility,
}
```
## `MaterialMesh2dBundle`
```rust
pub struct MaterialMesh2dBundle<M: Material2d> {
pub mesh: Mesh2dHandle,
pub material: Handle<M>,
pub transform: Transform,
pub global_transform: GlobalTransform,
/// User indication of whether an entity is visible
pub visibility: Visibility,
// Inherited visibility of an entity.
pub inherited_visibility: InheritedVisibility,
// Indication of whether an entity is visible in any view.
pub view_visibility: ViewVisibility,
}
```
## Combined Proposal 1
```rust
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct Mesh3d<M: Material> {
pub mesh: Handle<Mesh>
pub material: Handle<M>
}
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct Mesh2d<M: Material> {
pub mesh: Handle<Mesh>
pub material: Handle<M>
}
```
The generic makes it hard to depend on materials, and materials can't require mesh because the default value is unclear.
As a side note, this would be simpler if we removed the `Material` trait to a component, which is something we may want to do anyway for asset-loading reasons.
Name of these components can be bikeshed: `Mesh`, `MaterialMesh`, `Surface` ect.
## Combined Proposal 2
```rust
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct Mesh3d(Handle<Mesh>);
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct Mesh2d(Handle<Mesh>);
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct MeshMaterial<M: Material>(Handle<M>);
```
This keeps meshes and materials seperate, but you have to remember to insert both of them. Would it be a terrible idea to leave around the MeshMaterial bundles?
> but you have to remember to insert both of them
cart: In a way this is already true in the context of required components. I think we should answer the question "how should a Mesh without a Material behave"? If the answer is "use some default / placeholder material", then we can use Proposal 3. If the answer is "don't render", then we can use Proposal 2.
## Combined Proposal 3 (Selected)
```rust
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct Mesh3d(Handle<Mesh>);
#[derive(Component)]
#[require(Transform, Visibility)]
pub struct Mesh2d(Handle<Mesh>);
#[derive(Component)]
#[require(HasMaterial3d, Transform, Visibility)]
pub struct MeshMaterial3d<M: Material>(Handle<M>);
#[derive(Component)]
#[require(HasMaterial2d, Transform, Visibility)]
pub struct MeshMaterial2d<M: Material2d>(Handle<M>);
#[derive(Component)]
pub struct HasMaterial3d;
#[derive(Component)]
pub struct HasMaterial2d;
```
To make the material optional, we could have all generic material components require a `HasMaterial` marker. We could then have a fallback system that renders meshes without `HasMaterial` with a placeholder / default material.