implement constructing suits from skeleton

This commit is contained in:
yuni 2024-04-22 22:21:18 +02:00
parent f118384661
commit bc9ff6b7a6
3 changed files with 141 additions and 15 deletions

View file

@ -39,9 +39,68 @@ pub fn asset_name_to_path(name: &str) -> &'static str {
pub fn skeleton_name_to_skeletondef(name: &str) -> Option<SkeletonDef> { pub fn skeleton_name_to_skeletondef(name: &str) -> Option<SkeletonDef> {
match name { match name {
"suitv1" => Some(SkeletonDef { "suitv1" => Some(SkeletonDef::Human(HumanDef {
base: "skeleton/suit_v1/base.glb#Scene0".to_string(), collider: "skeleton/suit_v1/collider.glb#Scene0".into(),
}), base: "skeleton/suit_v1/base.glb#Scene0".into(),
limbs: vec![
LimbDef {
class: Limb::Head,
path: "skeleton/suit_v1/head.glb#Scene0".into(),
pos: Vec3::new(0.0, 0.5, 0.0),
..default()
},
LimbDef {
class: Limb::UpperArmLeft,
path: "skeleton/suit_v1/upper_arm.glb#Scene0".into(),
pos: Vec3::new(0.25, 0.3, 0.0),
mirror: true,
children: vec![LimbDef {
class: Limb::LowerArmLeft,
path: "skeleton/suit_v1/lower_arm.glb#Scene0".into(),
pos: Vec3::new(-0.33, 0.0, 0.0),
..default()
}],
..default()
},
LimbDef {
class: Limb::UpperArmRight,
path: "skeleton/suit_v1/upper_arm.glb#Scene0".into(),
pos: Vec3::new(-0.25, 0.3, 0.0),
children: vec![LimbDef {
class: Limb::LowerArmRight,
path: "skeleton/suit_v1/lower_arm.glb#Scene0".into(),
pos: Vec3::new(-0.33, 0.0, 0.0),
..default()
}],
..default()
},
LimbDef {
class: Limb::UpperLegLeft,
path: "skeleton/suit_v1/upper_leg.glb#Scene0".into(),
pos: Vec3::new(0.15, -0.25, 0.0),
mirror: true,
children: vec![LimbDef {
class: Limb::LowerLegLeft,
path: "skeleton/suit_v1/lower_leg.glb#Scene0".into(),
pos: Vec3::new(0.0, -0.3, 0.0),
..default()
}],
..default()
},
LimbDef {
class: Limb::UpperLegRight,
path: "skeleton/suit_v1/upper_leg.glb#Scene0".into(),
pos: Vec3::new(-0.15, -0.25, 0.0),
children: vec![LimbDef {
class: Limb::LowerLegRight,
path: "skeleton/suit_v1/lower_leg.glb#Scene0".into(),
pos: Vec3::new(0.0, -0.3, 0.0),
..default()
}],
..default()
},
],
})),
_ => None, _ => None,
} }
} }
@ -54,19 +113,39 @@ impl Plugin for SkeletonPlugin {
} }
#[derive(Component)] pub struct SkeletonLimb; #[derive(Component)] pub struct SkeletonLimb;
pub struct SkeletonDef { pub enum SkeletonDef {
pub base: String, Human(HumanDef)
} }
//pub fn spawn( pub struct HumanDef {
// name: &str, collider: String,
// commands: Commands, base: String,
// asset_server: &AssetServer, limbs: Vec<LimbDef>,
//) -> EntityCommands { }
// let mut entity_commands = commands.spawn_empty();
// load(name, &mut entity_commands, asset_server); #[derive(Default)]
// return entity_commands; pub struct LimbDef {
//} path: String,
pos: Vec3,
class: Limb,
mirror: bool,
children: Vec<LimbDef>,
}
#[derive(Component, Default)]
pub enum Limb {
#[default]
Base,
Head,
UpperArmRight,
UpperArmLeft,
LowerArmRight,
LowerArmLeft,
UpperLegRight,
UpperLegLeft,
LowerLegRight,
LowerLegLeft,
}
pub fn load( pub fn load(
name: &str, name: &str,
@ -74,7 +153,54 @@ pub fn load(
asset_server: &AssetServer, asset_server: &AssetServer,
) { ) {
if let Some(skel) = skeleton_name_to_skeletondef(name) { if let Some(skel) = skeleton_name_to_skeletondef(name) {
entity_commands.insert(load_scene_by_path(skel.base.as_str(), asset_server)); match skel {
SkeletonDef::Human(human) => {
entity_commands.insert(load_scene_by_path(human.collider.as_str(), asset_server));
entity_commands.with_children(|parent| {
parent.spawn((
Limb::Base,
SceneBundle {
scene: load_scene_by_path(human.base.as_str(), asset_server),
..default()
}
));
for limb in human.limbs {
let rot = if limb.mirror {
Quat::from_rotation_y(180.0f32.to_radians())
} else {
Quat::IDENTITY
};
let mut parent_limb = parent.spawn((
limb.class,
SceneBundle {
scene: load_scene_by_path(limb.path.as_str(), asset_server),
transform: Transform::from_translation(limb.pos).with_rotation(rot),
..default()
}
));
if !limb.children.is_empty() {
parent_limb.with_children(|parent| {
for child_limb in limb.children {
let rot = if child_limb.mirror {
Quat::from_rotation_y(180.0f32.to_radians())
} else {
Quat::IDENTITY
};
parent.spawn((
child_limb.class,
SceneBundle {
scene: load_scene_by_path(child_limb.path.as_str(), asset_server),
transform: Transform::from_translation(child_limb.pos).with_rotation(rot),
..default()
}
));
}
});
}
}
});
}
}
} else { } else {
entity_commands.insert(load_scene_by_path(asset_name_to_path(name), asset_server)); entity_commands.insert(load_scene_by_path(asset_name_to_path(name), asset_server));
} }