Blender_bevy_components_wor.../crates/bevy_gltf_components
2024-07-08 13:18:21 +02:00
..
src chore(Blenvy:Bevy): cargo fmt 2024-07-08 13:18:21 +02:00
Cargo.toml feat(Blenvy): updated (most) of the crates' code to bevy 0.14 (rc) 2024-06-18 22:30:59 +02:00
LICENSE_APACHE.md feat(): Blueprints, crates, enhanced Blender tooling & more (#5) 2023-09-28 14:10:45 +02:00
LICENSE_MIT.md feat(): Blueprints, crates, enhanced Blender tooling & more (#5) 2023-09-28 14:10:45 +02:00
LICENSE.md fix(): various Fixes and tweaks (#7) 2023-09-28 16:53:21 +02:00
README.md refactor(): removed remains of legacy mode 2024-04-30 11:33:05 +02:00

Crates.io Docs License Bevy tracking

bevy_gltf_components

This crate allows you to define Bevy components direclty inside gltf files and instanciate the components on the Bevy side.

Usage

important : the plugin for processing gltf files runs in update , so you cannot use the components directly if you spawn your scene from gltf in setup (the additional components will not show up)

Please see the

  • example
  • or use bevy_asset_loader for reliable preloading of files, as this crate does not deal with loading your assets.
  • alternatively, use the bevy_gltf_blueprints crate, built on this crate's features, that allows you to directly spawn entities from gltf based blueprints.

Here's a minimal usage example:

# Cargo.toml
[dependencies]
bevy="0.13"
bevy_gltf_components = { version = "0.5"} 

//too barebones of an example to be meaningfull, please see https://github.com/kaosat-dev/Blender_bevy_components_workflow/bevy_gltf_components/examples/basic for a real example
 fn main() {
    App::new()
         .add_plugins(DefaultPlugins)
         .add_plugin(ComponentsFromGltfPlugin::default())
         .add_system(spawn_level)
         .run();
 }
 
 fn spawn_level(
   asset_server: Res<AssetServer>, 
   mut commands: bevy::prelude::Commands,
   keycode: Res<Input<KeyCode>>,

 ){
 if keycode.just_pressed(KeyCode::Return) {
  commands.spawn(SceneBundle {
   scene: asset_server.load("basic/models/level1.glb#Scene0"),
   transform: Transform::from_xyz(2.0, 0.0, -5.0),
 ..Default::default()
 });
 }
}

Installation

Add the following to your [dependencies] section in Cargo.toml:

bevy_gltf_components = "0.5"

Or use cargo add:

cargo add bevy_gltf_components

Configuration

starting with version 0.3, this plugin is configurable Use the default configuration:

ComponentsFromGltfPlugin::default()

As of v0.6 Legacy mode has been removed , you can emulate it using a system that should run BEFORE bevy_gltf_components

            if simplified_types {
                if let TypeInfo::TupleStruct(info) = type_registration.type_info() {
                    // we handle tupple strucs with only one field differently, as Blender's custom properties with custom ui (float, int, bool, etc) always give us a tupple struct
                    if info.field_len() == 1 {
                        let field = info
                            .field_at(0)
                            .expect("we should always have at least one field here");
                        let field_name = field.type_path();
                        let mut formated = parsed_value.clone();
                        match field_name {
                            "f32" => {
                                formated = parsed_value.parse::<f32>().unwrap().to_string();
                            }
                            "f64" => {
                                formated = parsed_value.parse::<f64>().unwrap().to_string();
                            }
                            "u8" => {
                                formated = parsed_value.parse::<u8>().unwrap().to_string();
                            }
                            "u16" => {
                                formated = parsed_value.parse::<u16>().unwrap().to_string();
                            }
                            "u32" => {
                                formated = parsed_value.parse::<u32>().unwrap().to_string();
                            }
                            "u64" => {
                                formated = parsed_value.parse::<u64>().unwrap().to_string();
                            }
                            "u128" => {
                                formated = parsed_value.parse::<u128>().unwrap().to_string();
                            }
                            "glam::Vec2" => {
                                let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap();
                                formated = format!("(x:{},y:{})", parsed[0], parsed[1]);
                            }
                            "glam::Vec3" => {
                                let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap();
                                formated =
                                    format!("(x:{},y:{},z:{})", parsed[0], parsed[1], parsed[2]);
                            }
                            "bevy_render::color::Color" => {
                                let parsed: Vec<f32> = ron::from_str(&parsed_value).unwrap();
                                if parsed.len() == 3 {
                                    formated = format!(
                                        "Rgba(red:{},green:{},blue:{}, alpha: 1.0)",
                                        parsed[0], parsed[1], parsed[2]
                                    );
                                }
                                if parsed.len() == 4 {
                                    formated = format!(
                                        "Rgba(red:{},green:{},blue:{}, alpha:{})",
                                        parsed[0], parsed[1], parsed[2], parsed[3]
                                    );
                                }
                            }
                            _ => {}
                        }

                        parsed_value = format!("({formated})");
                    }
                }

                if parsed_value.is_empty() {
                    parsed_value = "()".to_string();
                }
            }

SystemSet

the ordering of systems is very important !

For example to replace your proxy components (stand-in components when you cannot/ do not want to use real components in the gltf file) with actual ones,

which should happen AFTER the components from the gltf files have been injected,

so bevy_gltf_components provides a SystemSet for that purpose:GltfComponentsSet

Typically , the order of systems should be

bevy_gltf_components (GltfComponentsSet::Injection) => replace_proxies

Additional features

  • as of version 0.5 , this crate also includes automatic handling of lights in gltf files, to attempt to match Blender's eevee rendering as close as possible:
  • BlenderLightShadows (automatically generated by the gltf_auto_export Blender add-on) allows you to toggle light's shadows on/off in Blender and have matching behaviour in Bevy
  • BlenderBackgroundShader aka background color is also automatically set on the Bevy side
  • BlenderShadowSettings sets the cascade_size on the bevy side to match the one configured in Blender

If these components are present in your gltf file, they will be handled automatically by this crate, will be ignored otherwise.

Examples

https://github.com/kaosat-dev/Blender_bevy_components_workflow/tree/main/examples/bevy_gltf_components/basic

Compatible Bevy versions

The main branch is compatible with the latest Bevy release, while the branch bevy_main tries to track the main branch of Bevy (PRs updating the tracked commit are welcome).

Compatibility of bevy_gltf_components versions:

bevy_gltf_components bevy
0.5 0.13
0.2 - 0.4 0.12
0.1 0.11
branch main 0.13
branch bevy_main main

License

This crate, all its code, contents & assets is Dual-licensed under either of