1use glam::{Vec2, Vec3, Vec4};
4use super::density_entity::{DensityEntity, ShapeField, ShapeBone};
5
6pub struct DensityTemplates;
7
8impl DensityTemplates {
9 pub fn humanoid(name: &str, position: Vec3, color: Vec4, particle_count: u32) -> DensityEntity {
11 let shape = ShapeField::new(vec![
12 ShapeBone::new(Vec2::new(0.0, -0.2), Vec2::new(0.0, 0.6), 0.25, 1.5).named("torso"),
13 ShapeBone::new(Vec2::new(0.0, 0.6), Vec2::new(0.0, 0.9), 0.18, 2.0).named("head"),
14 ShapeBone::new(Vec2::new(-0.25, 0.5), Vec2::new(-0.7, 0.2), 0.1, 0.8).named("left_arm"),
15 ShapeBone::new(Vec2::new(0.25, 0.5), Vec2::new(0.7, 0.2), 0.1, 0.8).named("right_arm"),
16 ShapeBone::new(Vec2::new(-0.1, -0.2), Vec2::new(-0.2, -0.9), 0.1, 0.9).named("left_leg"),
17 ShapeBone::new(Vec2::new(0.1, -0.2), Vec2::new(0.2, -0.9), 0.1, 0.9).named("right_leg"),
18 ]);
19 DensityEntity::new(name, position, shape, particle_count, color)
20 }
21
22 pub fn beast(name: &str, position: Vec3, color: Vec4, particle_count: u32) -> DensityEntity {
24 let shape = ShapeField::new(vec![
25 ShapeBone::new(Vec2::new(-0.6, 0.0), Vec2::new(0.6, 0.0), 0.3, 1.8).named("body"),
26 ShapeBone::new(Vec2::new(0.6, 0.0), Vec2::new(0.8, 0.3), 0.2, 1.5).named("head"),
27 ShapeBone::new(Vec2::new(-0.4, 0.0), Vec2::new(-0.5, -0.6), 0.08, 0.7).named("front_left"),
28 ShapeBone::new(Vec2::new(-0.2, 0.0), Vec2::new(-0.3, -0.6), 0.08, 0.7).named("front_right"),
29 ShapeBone::new(Vec2::new(0.3, 0.0), Vec2::new(0.2, -0.6), 0.08, 0.7).named("back_left"),
30 ShapeBone::new(Vec2::new(0.5, 0.0), Vec2::new(0.4, -0.6), 0.08, 0.7).named("back_right"),
31 ShapeBone::new(Vec2::new(-0.6, 0.0), Vec2::new(-1.0, 0.2), 0.06, 0.5).named("tail1"),
32 ShapeBone::new(Vec2::new(-1.0, 0.2), Vec2::new(-1.3, 0.4), 0.04, 0.4).named("tail2"),
33 ]);
34 DensityEntity::new(name, position, shape, particle_count, color)
35 }
36
37 pub fn swarm(name: &str, position: Vec3, color: Vec4, particle_count: u32) -> DensityEntity {
39 let shape = ShapeField::new(vec![
40 ShapeBone::new(Vec2::ZERO, Vec2::new(0.01, 0.0), 1.5, 0.5).named("center"),
41 ]);
42 let mut ent = DensityEntity::new(name, position, shape, particle_count, color);
43 ent.jitter = 0.5; ent.binding_strength = 5.0;
45 ent.base_binding = 5.0;
46 ent
47 }
48
49 pub fn boss(name: &str, position: Vec3, color: Vec4, particle_count: u32) -> DensityEntity {
51 let shape = ShapeField::new(vec![
52 ShapeBone::new(Vec2::new(0.0, -0.3), Vec2::new(0.0, 0.8), 0.4, 2.5).named("torso"),
54 ShapeBone::new(Vec2::new(0.0, 0.8), Vec2::new(0.0, 1.2), 0.25, 2.0).named("head"),
56 ShapeBone::new(Vec2::new(-0.2, 1.1), Vec2::new(-0.5, 1.5), 0.08, 1.0).named("left_horn"),
58 ShapeBone::new(Vec2::new(0.2, 1.1), Vec2::new(0.5, 1.5), 0.08, 1.0).named("right_horn"),
59 ShapeBone::new(Vec2::new(-0.4, 0.6), Vec2::new(-0.9, 0.3), 0.15, 1.0).named("left_upper_arm"),
61 ShapeBone::new(Vec2::new(-0.9, 0.3), Vec2::new(-1.2, 0.0), 0.12, 0.8).named("left_forearm"),
62 ShapeBone::new(Vec2::new(0.4, 0.6), Vec2::new(0.9, 0.3), 0.15, 1.0).named("right_upper_arm"),
63 ShapeBone::new(Vec2::new(0.9, 0.3), Vec2::new(1.2, 0.0), 0.12, 0.8).named("right_forearm"),
64 ShapeBone::new(Vec2::new(-0.15, -0.3), Vec2::new(-0.25, -1.0), 0.13, 1.0).named("left_leg"),
66 ShapeBone::new(Vec2::new(0.15, -0.3), Vec2::new(0.25, -1.0), 0.13, 1.0).named("right_leg"),
67 ShapeBone::new(Vec2::new(-0.5, 0.7), Vec2::new(-0.6, 0.5), 0.15, 0.8).named("left_plate"),
69 ShapeBone::new(Vec2::new(0.5, 0.7), Vec2::new(0.6, 0.5), 0.15, 0.8).named("right_plate"),
70 ]);
71 let mut ent = DensityEntity::new(name, position, shape, particle_count, color);
72 ent.breath_amplitude = 0.03;
73 ent.breath_rate = 0.2;
74 ent
75 }
76
77 pub fn mage(position: Vec3) -> DensityEntity {
79 let mut ent = Self::humanoid("Mage", position, Vec4::new(0.3, 0.5, 1.0, 0.9), 2000);
80 ent.shape_field.bones.push(ShapeBone::new(Vec2::new(0.7, 0.2), Vec2::new(0.8, 1.0), 0.04, 0.6).named("staff"));
82 ent.shape_field.bones.push(ShapeBone::new(Vec2::new(0.8, 1.0), Vec2::new(0.8, 1.1), 0.08, 1.2).named("staff_orb"));
83 ent
84 }
85
86 pub fn warrior(position: Vec3) -> DensityEntity {
88 let mut ent = Self::humanoid("Warrior", position, Vec4::new(0.9, 0.2, 0.3, 0.9), 1500);
89 ent.binding_strength = 25.0;
90 ent.base_binding = 25.0;
91 ent
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_humanoid() {
101 let ent = DensityTemplates::humanoid("test", Vec3::ZERO, Vec4::ONE, 500);
102 assert_eq!(ent.particles.len(), 500);
103 assert!(ent.shape_field.bones.len() >= 6);
104 }
105
106 #[test]
107 fn test_boss() {
108 let ent = DensityTemplates::boss("boss", Vec3::ZERO, Vec4::ONE, 3000);
109 assert_eq!(ent.particles.len(), 3000);
110 assert!(ent.shape_field.bones.len() >= 10);
111 }
112
113 #[test]
114 fn test_mage() {
115 let ent = DensityTemplates::mage(Vec3::ZERO);
116 assert!(ent.particles.len() >= 2000);
117 assert!(ent.shape_field.bones.iter().any(|b| b.name == "staff"));
118 }
119}