# 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.