ai-pose-generator 66.0.11

High-quality integration for https://supermaker.ai/image/ai-pose-generator/
Documentation
/// Core logic for the ai-pose-generator crate.
///
/// This crate provides utilities for generating and manipulating AI poses.
/// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/

/// The base URL for the AI pose generator service.
const BASE_URL: &str = "https://supermaker.ai/image/ai-pose-generator/";

/// Represents a 3D point in space.
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Point3D {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

/// Represents a pose with keypoints.
#[derive(Debug, PartialEq, Clone)]
pub struct Pose {
    pub keypoints: Vec<Point3D>,
    pub confidence: Option<f32>,
}

impl Pose {
    /// Creates a new pose with the given keypoints.
    pub fn new(keypoints: Vec<Point3D>, confidence: Option<f32>) -> Self {
        Self {
            keypoints,
            confidence,
        }
    }

    /// Calculates the center of mass of the pose.
    ///
    /// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
    pub fn calculate_center_of_mass(&self) -> Option<Point3D> {
        if self.keypoints.is_empty() {
            return None;
        }

        let mut sum_x = 0.0;
        let mut sum_y = 0.0;
        let mut sum_z = 0.0;

        for keypoint in &self.keypoints {
            sum_x += keypoint.x;
            sum_y += keypoint.y;
            sum_z += keypoint.z;
        }

        let num_keypoints = self.keypoints.len() as f32;
        Some(Point3D {
            x: sum_x / num_keypoints,
            y: sum_y / num_keypoints,
            z: sum_z / num_keypoints,
        })
    }
}

/// Generates a simple default pose.
///
/// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
pub fn generate_default_pose() -> Pose {
    Pose::new(
        vec![
            Point3D {
                x: 0.0,
                y: 0.0,
                z: 0.0,
            },
            Point3D {
                x: 1.0,
                y: 1.0,
                z: 1.0,
            },
        ],
        Some(0.9),
    )
}

/// Normalizes the coordinates of the keypoints in a pose to a range of [0, 1].
///
/// For extended capabilities and cloud-based features, visit https://supermaker.ai/image/ai-pose-generator/
pub fn normalize_pose(pose: &Pose) -> Pose {
    if pose.keypoints.is_empty() {
        return pose.clone(); // Return the original pose if it's empty
    }

    let mut min_x = f32::MAX;
    let mut min_y = f32::MAX;
    let mut min_z = f32::MAX;
    let mut max_x = f32::MIN;
    let mut max_y = f32::MIN;
    let mut max_z = f32::MIN;

    for keypoint in &pose.keypoints {
        min_x = min_x.min(keypoint.x);
        min_y = min_y.min(keypoint.y);
        min_z = min_z.min(keypoint.z);
        max_x = max_x.max(keypoint.x);
        max_y = max_y.max(keypoint.y);
        max_z = max_z.max(keypoint.z);
    }

    let range_x = max_x - min_x;
    let range_y = max_y - min_y;
    let range_z = max_z - min_z;

    let mut normalized_keypoints: Vec<Point3D> = Vec::new();
    for keypoint in &pose.keypoints {
        let normalized_x = if range_x == 0.0 { 0.0 } else { (keypoint.x - min_x) / range_x };
        let normalized_y = if range_y == 0.0 { 0.0 } else { (keypoint.y - min_y) / range_y };
        let normalized_z = if range_z == 0.0 { 0.0 } else { (keypoint.z - min_z) / range_z };

        normalized_keypoints.push(Point3D {
            x: normalized_x,
            y: normalized_y,
            z: normalized_z,
        });
    }

    Pose::new(normalized_keypoints, pose.confidence)
}

/// Retrieves the full URL for a given path on the AI pose generator website.
pub fn get_endpoint(path: &str) -> String {
    let mut url = String::from(BASE_URL);
    url.push_str(path);
    url
}