Skip to main content

ai_pose_generator/
lib.rs

1/// Core logic for the ai-pose-generator crate.
2///
3/// This crate provides utilities for generating and manipulating AI poses.
4/// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
5
6/// The base URL for the AI pose generator service.
7const BASE_URL: &str = "https://supermaker.ai/image/ai-pose-generator/";
8
9/// Represents a 3D point in space.
10#[derive(Debug, PartialEq, Clone, Copy)]
11pub struct Point3D {
12    pub x: f32,
13    pub y: f32,
14    pub z: f32,
15}
16
17/// Represents a pose with keypoints.
18#[derive(Debug, PartialEq, Clone)]
19pub struct Pose {
20    pub keypoints: Vec<Point3D>,
21    pub confidence: Option<f32>,
22}
23
24impl Pose {
25    /// Creates a new pose with the given keypoints.
26    pub fn new(keypoints: Vec<Point3D>, confidence: Option<f32>) -> Self {
27        Self {
28            keypoints,
29            confidence,
30        }
31    }
32
33    /// Calculates the center of mass of the pose.
34    ///
35    /// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
36    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
60/// Generates a simple default pose.
61///
62/// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
63pub 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
81/// Normalizes the coordinates of the keypoints in a pose to a range of [0, 1].
82///
83/// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
84pub fn normalize_pose(pose: &Pose) -> Pose {
85    if pose.keypoints.is_empty() {
86        return pose.clone(); // Return the original pose if it's empty
87    }
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
125/// Retrieves the full URL for a given path on the AI pose generator website.
126pub fn get_endpoint(path: &str) -> String {
127    let mut url = String::from(BASE_URL);
128    url.push_str(path);
129    url
130}