Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DefaultRaycastPlugin respect the material cull_mode #112

Open
thmxv opened this issue Mar 11, 2024 · 1 comment
Open

Make DefaultRaycastPlugin respect the material cull_mode #112

thmxv opened this issue Mar 11, 2024 · 1 comment

Comments

@thmxv
Copy link

thmxv commented Mar 11, 2024

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.

@thmxv
Copy link
Author

thmxv commented Mar 31, 2024

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,
                        );
                    }
                }
            }
            _ => {}
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant