Skip to main content

scena/scene/connectors/
solving.rs

1use super::metadata::ConnectorRollPolicy;
2use super::options::{ConnectOptions, ConnectionRoll};
3use super::{ConnectionError, ConnectionPreview, ConnectorFrame, Transform};
4
5pub(super) fn effective_mate_offset(
6    options: ConnectOptions,
7    source: &ConnectorFrame,
8    target: &ConnectorFrame,
9) -> Transform {
10    let clearance = source
11        .clearance_hint()
12        .into_iter()
13        .chain(target.clearance_hint())
14        .fold(0.0, f32::max);
15    let mut offset = options.mate_offset;
16    if clearance > offset.translation.x {
17        offset.translation.x = clearance;
18    }
19    offset
20}
21
22pub(super) fn effective_roll(options: ConnectOptions, source: &ConnectorFrame) -> ConnectionRoll {
23    if options.roll() != ConnectionRoll::MatchTarget {
24        return options.roll();
25    }
26    match source.roll_policy() {
27        ConnectorRollPolicy::Preserve => ConnectionRoll::PreserveSource,
28        ConnectorRollPolicy::ChooseNearest => ConnectionRoll::ChooseNearest { step_degrees: 90.0 },
29    }
30}
31
32pub(super) fn validate_snap_tolerance_for_apply(
33    preview: &ConnectionPreview,
34    options: ConnectOptions,
35) -> Result<(), ConnectionError> {
36    if options.mate_offset != Transform::IDENTITY {
37        return Ok(());
38    }
39    let tolerance = preview
40        .source
41        .snap_tolerance()
42        .into_iter()
43        .chain(preview.target.snap_tolerance())
44        .fold(0.0, f32::max);
45    if tolerance <= 0.0 {
46        return Ok(());
47    }
48    let distance = preview.snap_distance;
49    if distance <= tolerance {
50        Ok(())
51    } else {
52        Err(ConnectionError::SnapToleranceExceeded {
53            distance,
54            tolerance,
55        })
56    }
57}
58
59impl PartialEq for ConnectorFrame {
60    fn eq(&self, other: &Self) -> bool {
61        self.node == other.node
62            && self.local_transform == other.local_transform
63            && self.name == other.name
64            && self.kind == other.kind
65            && self.allowed_mates == other.allowed_mates
66            && self.tags == other.tags
67            && self.snap_tolerance == other.snap_tolerance
68            && self.clearance_hint == other.clearance_hint
69            && self.roll_policy == other.roll_policy
70            && self.polarity == other.polarity
71            && self.metadata == other.metadata
72            && self.source_units == other.source_units
73            && self.source_coordinate_system == other.source_coordinate_system
74    }
75}