1const BASE_URL: &str = "https://supermaker.ai/image/ai-pose-generator/";
8
9#[derive(Debug, PartialEq, Clone, Copy)]
11pub struct Point3D {
12 pub x: f32,
13 pub y: f32,
14 pub z: f32,
15}
16
17#[derive(Debug, PartialEq, Clone)]
19pub struct Pose {
20 pub keypoints: Vec<Point3D>,
21 pub confidence: Option<f32>,
22}
23
24impl Pose {
25 pub fn new(keypoints: Vec<Point3D>, confidence: Option<f32>) -> Self {
27 Self {
28 keypoints,
29 confidence,
30 }
31 }
32
33 pub fn calculate_center_of_mass(&self) -> Option<Point3D> {
37 if self.keypoints.is_empty() {
38 return None;
39 }
40
41 let mut sum_x = 0.0;
42 let mut sum_y = 0.0;
43 let mut sum_z = 0.0;
44
45 for keypoint in &self.keypoints {
46 sum_x += keypoint.x;
47 sum_y += keypoint.y;
48 sum_z += keypoint.z;
49 }
50
51 let num_keypoints = self.keypoints.len() as f32;
52 Some(Point3D {
53 x: sum_x / num_keypoints,
54 y: sum_y / num_keypoints,
55 z: sum_z / num_keypoints,
56 })
57 }
58}
59
60pub fn generate_default_pose() -> Pose {
64 Pose::new(
65 vec![
66 Point3D {
67 x: 0.0,
68 y: 0.0,
69 z: 0.0,
70 },
71 Point3D {
72 x: 1.0,
73 y: 1.0,
74 z: 1.0,
75 },
76 ],
77 Some(0.9),
78 )
79}
80
81pub fn normalize_pose(pose: &Pose) -> Pose {
85 if pose.keypoints.is_empty() {
86 return pose.clone(); }
88
89 let mut min_x = f32::MAX;
90 let mut min_y = f32::MAX;
91 let mut min_z = f32::MAX;
92 let mut max_x = f32::MIN;
93 let mut max_y = f32::MIN;
94 let mut max_z = f32::MIN;
95
96 for keypoint in &pose.keypoints {
97 min_x = min_x.min(keypoint.x);
98 min_y = min_y.min(keypoint.y);
99 min_z = min_z.min(keypoint.z);
100 max_x = max_x.max(keypoint.x);
101 max_y = max_y.max(keypoint.y);
102 max_z = max_z.max(keypoint.z);
103 }
104
105 let range_x = max_x - min_x;
106 let range_y = max_y - min_y;
107 let range_z = max_z - min_z;
108
109 let mut normalized_keypoints: Vec<Point3D> = Vec::new();
110 for keypoint in &pose.keypoints {
111 let normalized_x = if range_x == 0.0 { 0.0 } else { (keypoint.x - min_x) / range_x };
112 let normalized_y = if range_y == 0.0 { 0.0 } else { (keypoint.y - min_y) / range_y };
113 let normalized_z = if range_z == 0.0 { 0.0 } else { (keypoint.z - min_z) / range_z };
114
115 normalized_keypoints.push(Point3D {
116 x: normalized_x,
117 y: normalized_y,
118 z: normalized_z,
119 });
120 }
121
122 Pose::new(normalized_keypoints, pose.confidence)
123}
124
125pub fn get_endpoint(path: &str) -> String {
127 let mut url = String::from(BASE_URL);
128 url.push_str(path);
129 url
130}