bevy_vrm1 0.2.1

Allows you to use VRM and VRMA in Bevy
Documentation
mod material;
mod outline_pass;
mod setup;

use crate::vrm::gltf::materials::VrmcMaterialsExtensitions;
use crate::vrm::mtoon::outline_pass::MToonOutlinePlugin;
use crate::vrm::mtoon::setup::MToonMaterialSetupPlugin;
use bevy::asset::{load_internal_asset, weak_handle, AssetId};
use bevy::prelude::*;
use std::collections::HashMap;

use crate::prelude::*;

pub mod prelude {
    pub use crate::vrm::mtoon::{material::prelude::*, MtoonMaterialPlugin, VrmcMaterialRegistry};
}

const MTOON_FRAGMENT_SHADER_HANDLE: Handle<Shader> =
    weak_handle!("9a96eff2-1676-1dc0-9abc-2fd5e7134441");
const MTOON_VERTEX_SHADER_HANDLE: Handle<Shader> =
    weak_handle!("f4041db8-c464-b84c-e3c9-e618527945a1");
const MTOON_TYPES_SHADER_HANDLE: Handle<Shader> =
    weak_handle!("5d9302a3-6498-9d2a-fadb-842d01c87697");

pub struct MtoonMaterialPlugin;

impl Plugin for MtoonMaterialPlugin {
    fn build(
        &self,
        app: &mut App,
    ) {
        app.register_type::<MToonMaterial>()
            .register_type::<MToonOutline>()
            .register_type::<VrmcMaterialRegistry>()
            .register_type::<RimLighting>()
            .register_type::<UVAnimation>()
            .register_type::<Shade>()
            .add_plugins(MaterialPlugin::<MToonMaterial>::default())
            .add_plugins((MToonMaterialSetupPlugin, MToonOutlinePlugin));

        load_internal_asset!(
            app,
            MTOON_FRAGMENT_SHADER_HANDLE,
            "mtoon_fragment.wgsl",
            Shader::from_wgsl
        );
        load_internal_asset!(
            app,
            MTOON_VERTEX_SHADER_HANDLE,
            "mtoon_vertex.wgsl",
            Shader::from_wgsl
        );
        load_internal_asset!(
            app,
            MTOON_TYPES_SHADER_HANDLE,
            "mtoon_types.wgsl",
            Shader::from_wgsl
        );
    }
}

#[derive(Component, Default, Debug, Reflect)]
#[reflect(Component)]
pub struct VrmcMaterialRegistry {
    pub images: Vec<Handle<Image>>,
    pub materials: HashMap<AssetId<StandardMaterial>, VrmcMaterialsExtensitions>,
}

impl VrmcMaterialRegistry {
    pub fn new(
        gltf: &Gltf,
        images: Vec<Handle<Image>>,
    ) -> Self {
        Self::try_new(gltf, images).unwrap_or_default()
    }

    fn try_new(
        gltf: &Gltf,
        images: Vec<Handle<Image>>,
    ) -> Option<Self> {
        let materials = gltf
            .source
            .as_ref()?
            .materials()
            .flat_map(|m| {
                let asset_id = gltf.named_materials.get(m.name()?)?.id();
                let extensions = m.extensions()?;
                match serde_json::from_value(extensions.get("VRMC_materials_mtoon")?.clone()) {
                    Ok(properties) => Some((asset_id, properties)),
                    Err(e) => {
                        error!("Failed to parse VRMC_materials_mtoon: {e}");
                        None
                    }
                }
            })
            .collect();
        Some(Self { materials, images })
    }
}