Skip to content

Commit 5902dd1

Browse files
authored
Replace the FORWARD_DECAL_MESH_HANDLE with a resource that gets cloned out in a hook. (#19428)
# Objective - Related to #19024. ## Solution - Rather than adding a required component `Mesh3d` with a default set to `FORWARD_DECAL_MESH_HANDLE`, we use a hook to change the `Mesh3d`s asset handle. ## Testing - `decal` example still works.
1 parent 069f110 commit 5902dd1

File tree

1 file changed

+28
-9
lines changed

1 file changed

+28
-9
lines changed

crates/bevy_pbr/src/decal/forward.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@ use crate::{
33
MaterialPlugin, StandardMaterial,
44
};
55
use bevy_app::{App, Plugin};
6-
use bevy_asset::{uuid_handle, Asset, Assets, Handle};
7-
use bevy_ecs::component::Component;
6+
use bevy_asset::{Asset, Assets, Handle};
7+
use bevy_ecs::{
8+
component::Component, lifecycle::HookContext, resource::Resource, world::DeferredWorld,
9+
};
810
use bevy_math::{prelude::Rectangle, Quat, Vec2, Vec3};
911
use bevy_reflect::{Reflect, TypePath};
1012
use bevy_render::load_shader_library;
13+
use bevy_render::mesh::Mesh3d;
1114
use bevy_render::render_asset::RenderAssets;
1215
use bevy_render::render_resource::{AsBindGroupShaderType, ShaderType};
1316
use bevy_render::texture::GpuImage;
1417
use bevy_render::{
1518
alpha::AlphaMode,
16-
mesh::{Mesh, Mesh3d, MeshBuilder, MeshVertexBufferLayoutRef, Meshable},
19+
mesh::{Mesh, MeshBuilder, MeshVertexBufferLayoutRef, Meshable},
1720
render_resource::{
1821
AsBindGroup, CompareFunction, RenderPipelineDescriptor, SpecializedMeshPipelineError,
1922
},
2023
RenderDebugFlags,
2124
};
2225

23-
const FORWARD_DECAL_MESH_HANDLE: Handle<Mesh> =
24-
uuid_handle!("afa817f9-1869-4e0c-ac0d-d8cd1552d38a");
25-
2626
/// Plugin to render [`ForwardDecal`]s.
2727
pub struct ForwardDecalPlugin;
2828

@@ -32,8 +32,7 @@ impl Plugin for ForwardDecalPlugin {
3232

3333
app.register_type::<ForwardDecal>();
3434

35-
app.world_mut().resource_mut::<Assets<Mesh>>().insert(
36-
FORWARD_DECAL_MESH_HANDLE.id(),
35+
let mesh = app.world_mut().resource_mut::<Assets<Mesh>>().add(
3736
Rectangle::from_size(Vec2::ONE)
3837
.mesh()
3938
.build()
@@ -42,6 +41,8 @@ impl Plugin for ForwardDecalPlugin {
4241
.unwrap(),
4342
);
4443

44+
app.insert_resource(ForwardDecalMesh(mesh));
45+
4546
app.add_plugins(MaterialPlugin::<ForwardDecalMaterial<StandardMaterial>> {
4647
prepass_enabled: false,
4748
shadows_enabled: false,
@@ -63,7 +64,8 @@ impl Plugin for ForwardDecalPlugin {
6364
/// * Looking at forward decals at a steep angle can cause distortion. This can be mitigated by padding your decal's
6465
/// texture with extra transparent pixels on the edges.
6566
#[derive(Component, Reflect)]
66-
#[require(Mesh3d(FORWARD_DECAL_MESH_HANDLE))]
67+
#[require(Mesh3d)]
68+
#[component(on_add=forward_decal_set_mesh)]
6769
pub struct ForwardDecal;
6870

6971
/// Type alias for an extended material with a [`ForwardDecalMaterialExt`] extension.
@@ -146,3 +148,20 @@ impl Default for ForwardDecalMaterialExt {
146148
}
147149
}
148150
}
151+
152+
#[derive(Resource)]
153+
struct ForwardDecalMesh(Handle<Mesh>);
154+
155+
// Note: We need to use a hook here instead of required components since we cannot access resources
156+
// with required components, and we can't otherwise get a handle to the asset from a required
157+
// component constructor, since the constructor must be a function pointer, and we intentionally do
158+
// not want to use `uuid_handle!`.
159+
fn forward_decal_set_mesh(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
160+
let decal_mesh = world.resource::<ForwardDecalMesh>().0.clone();
161+
let mut entity = world.entity_mut(entity);
162+
let mut entity_mesh = entity.get_mut::<Mesh3d>().unwrap();
163+
// Only replace the mesh handle if the mesh handle is defaulted.
164+
if **entity_mesh == Handle::default() {
165+
entity_mesh.0 = decal_mesh;
166+
}
167+
}

0 commit comments

Comments
 (0)