diff --git a/Cargo.toml b/Cargo.toml index 1faa67d..971463f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,17 +11,17 @@ exclude = ["assets/*"] [dependencies] rusty_spine = "0.8" -bevy = { version = "0.14", default-features = false, features = [ +bevy = { version = "0.15", default-features = false, features = [ "bevy_render", "bevy_asset", "bevy_sprite", ] } -glam = { version = "0.27", features = ["mint"] } +glam = { version = "0.29", features = ["mint"] } thiserror = "1.0.50" [dev-dependencies] lerp = "0.5" -bevy = { version = "0.14", default-features = true } +bevy = { version = "0.15", default-features = true } [workspace] resolver = "2" diff --git a/examples/simple.rs b/examples/simple.rs index 9c5fd8b..65bd260 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; use bevy_spine::{ - SkeletonController, SkeletonData, Spine, SpineBundle, SpinePlugin, SpineReadyEvent, SpineSet, + SkeletonController, SkeletonData, Spine, SpineBundle, SpineLoader, SpinePlugin, SpineReadyEvent, SpineSet }; fn main() { @@ -16,7 +16,7 @@ fn setup( mut commands: Commands, mut skeletons: ResMut>, ) { - commands.spawn(Camera2dBundle::default()); + commands.spawn(Camera2d); let skeleton = SkeletonData::new_from_json( asset_server.load("spineboy/export/spineboy-pro.json"), @@ -25,7 +25,10 @@ fn setup( let skeleton_handle = skeletons.add(skeleton); commands.spawn(SpineBundle { - skeleton: skeleton_handle.clone(), + loader: SpineLoader { + skeleton: skeleton_handle.clone(), + with_children: true, + }, transform: Transform::from_xyz(0., -200., 0.), ..Default::default() }); diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..0af9708 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.83.0" +components = ["rustfmt", "clippy"] +targets = ["wasm32-unknown-unknown"] diff --git a/src/assets.rs b/src/assets.rs index 25a4735..edb01f9 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -32,11 +32,11 @@ impl AssetLoader for AtlasLoader { type Settings = (); type Error = SpineLoaderError; - async fn load<'a>( - &'a self, - reader: &'a mut Reader<'_>, - _settings: &'a Self::Settings, - load_context: &'a mut LoadContext<'_>, + async fn load( + &self, + reader: &mut dyn Reader, + _settings: &Self::Settings, + load_context: &mut LoadContext<'_>, ) -> Result { let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await?; @@ -72,11 +72,11 @@ impl AssetLoader for SkeletonJsonLoader { type Settings = (); type Error = SpineLoaderError; - async fn load<'a>( - &'a self, - reader: &'a mut Reader<'_>, - _settings: &'a Self::Settings, - _load_context: &'a mut LoadContext<'_>, + async fn load( + &self, + reader: &mut dyn Reader, + _settings: &Self::Settings, + _load_context: &mut LoadContext<'_>, ) -> Result { let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await?; @@ -106,11 +106,11 @@ impl AssetLoader for SkeletonBinaryLoader { type Settings = (); type Error = SpineLoaderError; - async fn load<'a>( - &'a self, - reader: &'a mut Reader<'_>, - _settings: &'a Self::Settings, - _load_context: &'a mut LoadContext<'_>, + async fn load( + &self, + reader: &mut dyn Reader, + _settings: &Self::Settings, + _load_context: &mut LoadContext<'_>, ) -> Result { let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).await?; diff --git a/src/lib.rs b/src/lib.rs index 6013af9..e3ceca6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,15 +9,11 @@ use std::{ }; use bevy::{ - asset::load_internal_binary_asset, - prelude::*, - render::{ + asset::load_internal_binary_asset, image::{ImageAddressMode, ImageFilterMode, ImageSampler, ImageSamplerDescriptor}, prelude::*, render::{ mesh::{Indices, MeshVertexAttribute}, render_asset::RenderAssetUsages, render_resource::{PrimitiveTopology, VertexFormat}, - texture::{ImageAddressMode, ImageFilterMode, ImageSampler, ImageSamplerDescriptor}, - }, - sprite::{Material2dPlugin, Mesh2dHandle}, + }, sprite::Material2dPlugin }; use materials::{ SpineAdditiveMaterial, SpineAdditivePmaMaterial, SpineMaterialInfo, SpineMultiplyMaterial, @@ -258,36 +254,16 @@ impl core::ops::DerefMut for Spine { /// entities representing the bones of a skeleton (see [`SpineBone`]). These bones are not /// synchronized (see [`SpineSync`]), and can be disabled entirely using /// [`SpineLoader::without_children`]. -#[derive(Component, Debug)] -pub enum SpineLoader { - /// The spine rig is still loading. - Loading { - /// If true, will spawn child entities for each bone in the skeleton (see [`SpineBone`]). - with_children: bool, - }, - /// The spine rig is ready. - Ready, - /// The spine rig failed to load. - Failed, -} - -impl Default for SpineLoader { - fn default() -> Self { - Self::new() - } +#[derive(Default, Component, Debug)] +pub struct SpineLoader { + pub skeleton: Handle, + /// If true, will spawn child entities for each bone in the skeleton (see [`SpineBone`]). + pub with_children: bool, } impl SpineLoader { - pub fn new() -> Self { - Self::with_children() - } - - pub fn with_children() -> Self { - Self::Loading { - with_children: true, - } - } - + // 0.15 TODO + /* /// Load a [`Spine`] entity without child entities containing [`SpineBone`] components. /// /// Renderable mesh child entities are still created. @@ -304,10 +280,19 @@ impl SpineLoader { /// # } /// ``` pub fn without_children() -> Self { - Self::Loading { + Self { with_children: false, + state: SpineLoadState::Loading, } - } + }*/ +} + +#[derive(Component, Default, Debug, Clone, Copy, PartialEq, Eq)] +pub enum SpineLoadState { + #[default] + Loading, + Ready, + Failed, } /// Settings for how this Spine updates and renders. @@ -430,8 +415,8 @@ impl Default for SpineSettings { #[derive(Default, Bundle)] pub struct SpineBundle { pub loader: SpineLoader, + pub load_state: SpineLoadState, pub settings: SpineSettings, - pub skeleton: Handle, pub crossfades: Crossfades, pub transform: Transform, pub global_transform: GlobalTransform, @@ -600,8 +585,8 @@ fn spine_load( fn spine_spawn( mut skeleton_query: Query<( &mut SpineLoader, + &mut SpineLoadState, Entity, - &Handle, Option<&Crossfades>, )>, mut commands: Commands, @@ -610,10 +595,10 @@ fn spine_spawn( mut skeleton_data_assets: ResMut>, spine_event_queue: Res, ) { - for (mut spine_loader, spine_entity, data_handle, crossfades) in skeleton_query.iter_mut() { - if let SpineLoader::Loading { with_children } = spine_loader.as_ref() { + for (mut spine_loader, mut spine_load_state, spine_entity, crossfades) in skeleton_query.iter_mut() { + if matches!(spine_load_state.as_ref(), SpineLoadState::Loading) { let skeleton_data_asset = - if let Some(skeleton_data_asset) = skeleton_data_assets.get_mut(data_handle) { + if let Some(skeleton_data_asset) = skeleton_data_assets.get_mut(&spine_loader.skeleton) { skeleton_data_asset } else { continue; @@ -738,7 +723,7 @@ fn spine_spawn( z += 0.001; } }); - if *with_children { + if spine_loader.with_children { spawn_bones( spine_entity, None, @@ -751,7 +736,7 @@ fn spine_spawn( }) .insert(Spine(controller)); } - *spine_loader = SpineLoader::Ready; + *spine_load_state = SpineLoadState::Ready; ready_events.0.push(SpineReadyEvent { entity: spine_entity, bones, @@ -759,7 +744,7 @@ fn spine_spawn( } SkeletonDataStatus::Loading => {} SkeletonDataStatus::Failed => { - *spine_loader = SpineLoader::Failed; + *spine_load_state = SpineLoadState::Failed; } } } @@ -833,7 +818,7 @@ fn spine_update_animation( spine_event_queue: Res, ) { for (_, mut spine) in spine_query.iter_mut() { - spine.update(time.delta_seconds(), Physics::Update); + spine.update(time.delta_secs(), Physics::Update); } { let mut events = spine_event_queue.0.lock().unwrap(); @@ -856,8 +841,8 @@ fn spine_update_meshes( Entity, &mut SpineMesh, &mut Transform, - Option<&Mesh2dHandle>, - Option<&Handle>, + Option<&Mesh2d>, + Option<&Mesh3d>, )>, mut commands: Commands, meshes_query: Query<(&Parent, &Children), With>, @@ -908,14 +893,14 @@ fn spine_update_meshes( apply_mesh!( spine_2d_mesh, mesh_type == SpineMeshType::Mesh2D, - Mesh2dHandle(spine_mesh.handle.clone()), - Mesh2dHandle + Mesh2d(spine_mesh.handle.clone()), + Mesh2d ); apply_mesh!( spine_3d_mesh, mesh_type == SpineMeshType::Mesh3D, - spine_mesh.handle.clone(), - Handle + Mesh3d(spine_mesh.handle.clone()), + Mesh3d ); let Some(mesh) = meshes.get_mut(&spine_mesh.handle) else { continue; diff --git a/src/materials.rs b/src/materials.rs index cc431c5..0b1ed00 100644 --- a/src/materials.rs +++ b/src/materials.rs @@ -28,7 +28,7 @@ use crate::{SpineMesh, SpineMeshState, SpineSettings, SpineSystem}; /// Implement the trait and add it with [`SpineMaterialPlugin`]. pub trait SpineMaterial: Sized { /// The material type to apply to [`SpineMesh`]. Usually is `Self`. - type Material: Asset + Clone; + type Material: Material2d; /// System parameters to query when updating this material. type Params<'w, 's>: SystemParam; @@ -82,7 +82,7 @@ pub struct SpineMaterialInfo { fn update_materials( mut commands: Commands, mut materials: ResMut>, - mesh_query: Query<(Entity, &SpineMesh, Option<&Handle>)>, + mesh_query: Query<(Entity, &SpineMesh, Option<&MeshMaterial2d>)>, params: StaticSystemParam>, ) { for (mesh_entity, spine_mesh, material_handle) in mesh_query.iter() { @@ -102,19 +102,19 @@ fn update_materials( } else { materials.remove(handle); if let Some(mut entity_commands) = commands.get_entity(mesh_entity) { - entity_commands.remove::>(); + entity_commands.remove::>(); } } } else if let Some(material) = T::update(None, spine_mesh.spine_entity, data, ¶ms) { let handle = materials.add(material); if let Some(mut entity_commands) = commands.get_entity(mesh_entity) { - entity_commands.insert(handle.clone()); + entity_commands.insert(MeshMaterial2d(handle.clone())); } }; } } -pub const DARK_COLOR_SHADER_POSITION: usize = 10; +pub const DARK_COLOR_SHADER_POSITION: u64 = 10; pub const DARK_COLOR_ATTRIBUTE: MeshVertexAttribute = MeshVertexAttribute::new( "Vertex_DarkColor", DARK_COLOR_SHADER_POSITION,