pub mod registry;
mod setup;
mod update;
use crate::vrm::spring_bone::registry::SpringBoneRegistryPlugin;
use crate::vrm::spring_bone::setup::SpringBoneSetupPlugin;
use crate::vrm::spring_bone::update::SpringBoneUpdatePlugin;
use bevy::app::App;
use bevy::math::{Mat4, Quat, Vec3};
use bevy::prelude::*;
#[derive(PartialEq, Debug, Clone, Default, Reflect, Component)]
#[reflect(Default, Component)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", reflect(Serialize, Deserialize))]
pub(crate) struct SpringJointState {
prev_tail: Vec3,
current_tail: Vec3,
bone_axis: Vec3,
bone_length: f32,
initial_local_matrix: Mat4,
initial_local_rotation: Quat,
}
#[derive(Component, Debug, Clone, Eq, PartialEq, Default, Reflect)]
#[reflect(Component, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", reflect(Serialize, Deserialize))]
pub(crate) struct SpringRoot {
pub joints: SpringJoints,
pub colliders: SpringColliders,
pub center_node: SpringCenterNode,
}
#[derive(Eq, PartialEq, Debug, Clone, Default, Deref, Reflect)]
#[reflect(Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", reflect(Serialize, Deserialize))]
pub(crate) struct SpringJoints(pub Vec<Entity>);
#[derive(Eq, PartialEq, Debug, Clone, Default, Deref, Reflect)]
#[reflect(Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", reflect(Serialize, Deserialize))]
pub(crate) struct SpringColliders(pub Vec<Entity>);
#[derive(Eq, PartialEq, Debug, Clone, Default, Deref, Reflect)]
#[reflect(Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", reflect(Serialize, Deserialize))]
pub(crate) struct SpringCenterNode(pub Option<Entity>);
#[derive(Component, Debug, Copy, Clone, Default, PartialEq, Reflect)]
#[reflect(Default, Component)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", reflect(Serialize, Deserialize))]
pub(crate) struct SpringJointProps {
pub drag_force: f32,
pub gravity_dir: Vec3,
pub gravity_power: f32,
pub hit_radius: f32,
pub stiffness: f32,
}
pub struct VrmSpringBonePlugin;
impl Plugin for VrmSpringBonePlugin {
fn build(
&self,
app: &mut App,
) {
app.register_type::<SpringRoot>()
.register_type::<SpringJointState>()
.register_type::<SpringJoints>()
.register_type::<SpringColliders>()
.register_type::<SpringCenterNode>()
.add_plugins((
SpringBoneSetupPlugin,
SpringBoneRegistryPlugin,
SpringBoneUpdatePlugin,
));
}
}