use super::{FixedAngleConstraintShared, PointConstraintShared};
use crate::{
dynamics::solver::{
solver_body::{SolverBody, SolverBodyInertia},
xpbd::*,
},
prelude::*,
};
use bevy::prelude::*;
#[derive(Component, Clone, Copy, Debug, Default, PartialEq, Reflect)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
#[reflect(Component, Debug, PartialEq)]
pub struct FixedJointSolverData {
pub(super) point_constraint: PointConstraintShared,
pub(super) angle_constraint: FixedAngleConstraintShared,
}
impl XpbdConstraintSolverData for FixedJointSolverData {
fn clear_lagrange_multipliers(&mut self) {
self.point_constraint.clear_lagrange_multipliers();
self.angle_constraint.clear_lagrange_multipliers();
}
fn total_position_lagrange(&self) -> Vector {
self.point_constraint.total_position_lagrange()
}
fn total_rotation_lagrange(&self) -> AngularVector {
self.angle_constraint.total_rotation_lagrange()
}
}
impl XpbdConstraint<2> for FixedJoint {
type SolverData = FixedJointSolverData;
fn prepare(
&mut self,
bodies: [&RigidBodyQueryReadOnlyItem; 2],
solver_data: &mut FixedJointSolverData,
) {
let [body1, body2] = bodies;
let Some(local_anchor1) = self.local_anchor1() else {
return;
};
let Some(local_anchor2) = self.local_anchor2() else {
return;
};
let Some(local_basis1) = self.local_basis1() else {
return;
};
let Some(local_basis2) = self.local_basis2() else {
return;
};
solver_data
.point_constraint
.prepare(bodies, local_anchor1, local_anchor2);
solver_data.angle_constraint.prepare(
body1.rotation,
body2.rotation,
local_basis1,
local_basis2,
);
}
fn solve(
&mut self,
bodies: [&mut SolverBody; 2],
inertias: [&SolverBodyInertia; 2],
solver_data: &mut FixedJointSolverData,
dt: Scalar,
) {
let [body1, body2] = bodies;
solver_data
.angle_constraint
.solve([body1, body2], inertias, self.angle_compliance, dt);
solver_data
.point_constraint
.solve([body1, body2], inertias, self.point_compliance, dt);
}
}
impl PositionConstraint for FixedJoint {}
impl AngularConstraint for FixedJoint {}