dynamis-model 0.4.2

GPU-driven physics engine
Documentation
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ConstraintKind {
    Ball,
    Distance,
    Revolute,
    Prismatic,
    Fixed,
}

#[derive(Clone, Copy, Debug)]
pub struct ConstraintLimit {
    pub min: f32,
    pub max: f32,
}

#[derive(Clone, Copy, Debug)]
pub struct ConstraintMotor {
    pub speed: f32,
}

#[derive(Clone, Copy, Debug)]
pub struct ConstraintSpring {
    pub frequency: f32,
    pub damping_ratio: f32,
}

#[derive(Clone, Copy, Debug)]
pub struct ConstraintDesc {
    pub kind: ConstraintKind,
    pub anchor_a: [f32; 3],
    pub anchor_b: [f32; 3],
    pub axis: [f32; 3],
    pub distance: f32,
    pub limit: Option<ConstraintLimit>,
    pub motor: Option<ConstraintMotor>,
    pub spring: Option<ConstraintSpring>,
    pub disable_collisions: bool,
}

impl ConstraintDesc {
    fn base(kind: ConstraintKind) -> Self {
        Self {
            kind,
            anchor_a: [0.0; 3],
            anchor_b: [0.0; 3],
            axis: [0.0, 1.0, 0.0],
            distance: 0.0,
            limit: None,
            motor: None,
            spring: None,
            disable_collisions: true,
        }
    }

    pub fn ball(anchor_a: [f32; 3], anchor_b: [f32; 3]) -> Self {
        Self::base(ConstraintKind::Ball).anchors(anchor_a, anchor_b)
    }

    pub fn distance(anchor_a: [f32; 3], anchor_b: [f32; 3], distance: f32) -> Self {
        assert!(distance >= 0.0, "constraint distance must be non-negative");
        Self::base(ConstraintKind::Distance)
            .anchors(anchor_a, anchor_b)
            .with_distance(distance)
    }

    pub fn revolute(anchor_a: [f32; 3], anchor_b: [f32; 3], axis: [f32; 3]) -> Self {
        assert!(axis != [0.0; 3], "revolute axis must be non-zero");
        Self::base(ConstraintKind::Revolute)
            .anchors(anchor_a, anchor_b)
            .with_axis(axis)
    }

    pub fn prismatic(anchor_a: [f32; 3], anchor_b: [f32; 3], axis: [f32; 3]) -> Self {
        assert!(axis != [0.0; 3], "prismatic axis must be non-zero");
        Self::base(ConstraintKind::Prismatic)
            .anchors(anchor_a, anchor_b)
            .with_axis(axis)
    }

    pub fn fixed(anchor_a: [f32; 3], anchor_b: [f32; 3]) -> Self {
        Self::base(ConstraintKind::Fixed).anchors(anchor_a, anchor_b)
    }

    pub fn anchors(mut self, anchor_a: [f32; 3], anchor_b: [f32; 3]) -> Self {
        self.anchor_a = anchor_a;
        self.anchor_b = anchor_b;
        self
    }

    pub fn with_axis(mut self, axis: [f32; 3]) -> Self {
        assert!(axis != [0.0; 3], "constraint axis must be non-zero");
        self.axis = axis;
        self
    }

    pub fn with_distance(mut self, distance: f32) -> Self {
        assert!(distance >= 0.0, "constraint distance must be non-negative");
        self.distance = distance;
        self
    }

    pub fn limit(mut self, min: f32, max: f32) -> Self {
        assert!(max >= min, "constraint limit max must not be below min");
        self.limit = Some(ConstraintLimit { min, max });
        self
    }

    pub fn motor(mut self, speed: f32) -> Self {
        self.motor = Some(ConstraintMotor { speed });
        self
    }

    pub fn spring(mut self, frequency: f32, damping_ratio: f32) -> Self {
        assert!(frequency >= 0.0, "spring frequency must be non-negative");
        assert!(
            damping_ratio >= 0.0,
            "spring damping ratio must be non-negative"
        );
        self.spring = Some(ConstraintSpring {
            frequency,
            damping_ratio,
        });
        self
    }

    pub fn disable_collisions(mut self, disable: bool) -> Self {
        self.disable_collisions = disable;
        self
    }
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ConstraintHandle {
    pub id: u32,
    pub generation: u32,
}