bevy_vrm1 0.1.2

Allows you to use VRM and VRMA in Bevy
Documentation
use bevy::app::{App, Plugin};
use bevy::asset::io::Reader;
use bevy::asset::{Asset, AssetLoader, Handle, LoadContext};
use bevy::gltf::{Gltf, GltfAssetLabel, GltfError, GltfLoader, GltfLoaderSettings};
use bevy::image::{CompressedImageFormats, Image};
use bevy::prelude::{AssetApp, Component, TypePath};
use bevy::render::renderer::RenderDevice;
use bevy::utils::default;

pub struct VrmLoaderPlugin;

impl Plugin for VrmLoaderPlugin {
    fn build(
        &self,
        app: &mut App,
    ) {
        app.preregister_asset_loader::<VrmLoader>(&["vrm"]);
    }

    fn finish(
        &self,
        app: &mut App,
    ) {
        let supported_compressed_formats = match app.world().get_resource::<RenderDevice>() {
            Some(render_device) => CompressedImageFormats::from_features(render_device.features()),
            None => CompressedImageFormats::NONE,
        };
        app.register_asset_loader(VrmLoader(GltfLoader {
            supported_compressed_formats,
            custom_vertex_attributes: Default::default(),
        }));
    }
}

#[derive(Debug, Component)]
pub struct VrmHandle(pub Handle<VrmAsset>);

#[derive(Debug, Asset, TypePath)]
pub struct VrmAsset {
    pub(crate) gltf: Gltf,
    pub(crate) images: Vec<Handle<Image>>,
}

struct VrmLoader(GltfLoader);

impl AssetLoader for VrmLoader {
    type Asset = VrmAsset;
    type Settings = ();
    type Error = GltfError;
    async fn load(
        &self,
        reader: &mut dyn Reader,
        _: &Self::Settings,
        load_context: &mut LoadContext<'_>,
    ) -> Result<Self::Asset, Self::Error> {
        let settings = GltfLoaderSettings {
            include_source: true,
            ..default()
        };
        let gltf = self.0.load(reader, &settings, load_context).await?;
        Ok(VrmAsset {
            images: gltf
                .source
                .as_ref()
                .unwrap()
                .textures()
                .map(|tex| {
                    load_context.get_label_handle(GltfAssetLabel::Texture(tex.index()).to_string())
                })
                .collect(),
            gltf,
        })
    }

    fn extensions(&self) -> &[&str] {
        &["vrm"]
    }
}