bevy_mod_raycast
bevy_mod_raycast copied to clipboard
Make `DefaultRaycastPlugin` respect the material `cull_mode`
It would be nice if a hit was detected on all visible faces. For the moment object with a material with a cull_mode of None (no backface culling) are not hit.
I think I found a way to make this in the application using bevy and the raycast add-on. I am not sure if this is totally correct or if it is worth including the code in this add-on to avoid users wanting the same functionality the work I have done. But here is my code:
fn make_raycast_nobfc_respect_material(
commands: &mut Commands,
entity: Entity,
entity_has_raycast_nobfc_component: bool,
material_cull_mode: Option<Face>,
) {
match material_cull_mode {
None | Some(Face::Front) => {
if !entity_has_raycast_nobfc_component {
commands.entity(entity).insert(NoBackfaceCulling);
}
}
Some(Face::Back) => {
if entity_has_raycast_nobfc_component {
commands.entity(entity).remove::<NoBackfaceCulling>();
}
}
}
}
pub fn change_entity_raycast_backface_culling_system(
mut commands: Commands,
entities: Query<
(
Entity,
&Handle<StandardMaterial>,
Option<&NoBackfaceCulling>,
),
Changed<Handle<StandardMaterial>>,
>,
materials: Res<Assets<StandardMaterial>>,
) {
for (entity, material_handle, nobfc_opt) in entities.iter() {
let material_cull_mode =
materials.get(material_handle).unwrap().cull_mode;
make_raycast_nobfc_respect_material(
&mut commands,
entity,
nobfc_opt.is_some(),
material_cull_mode,
);
}
}
pub fn change_asset_raycast_backface_cullin_system(
mut commands: Commands,
entities: Query<
(
Entity,
&Handle<StandardMaterial>,
Option<&NoBackfaceCulling>,
),
With<Handle<StandardMaterial>>,
>,
mut ev_asset: EventReader<AssetEvent<StandardMaterial>>,
materials: Res<Assets<StandardMaterial>>,
) {
for ev in ev_asset.read() {
match ev {
AssetEvent::Modified { id } => {
let material_cull_mode = materials.get(*id).unwrap().cull_mode;
for (entity, material_handle, nobfc_opt) in entities.iter() {
if *id == material_handle.id() {
make_raycast_nobfc_respect_material(
&mut commands,
entity,
nobfc_opt.is_some(),
material_cull_mode,
);
}
}
}
_ => {}
}
}
}