@willcgage/module-schematic 0.82.0 → 0.83.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +56 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -1
- package/dist/index.d.ts +73 -1
- package/dist/index.js +54 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,55 @@ var FREEMO_ENDPLATE_WIDTH_MIN_INCHES = 12;
|
|
|
5
5
|
var FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES = 24;
|
|
6
6
|
var FREEMO_TRACK_SPACING_INCHES = 1.125;
|
|
7
7
|
var FREEMO_ENDPLATE_TRACK_FASCIA_CLEARANCE_INCHES = 4;
|
|
8
|
+
var PINCH_EASE_INCHES = 3;
|
|
9
|
+
function laneOffsetAt(lane, pos, pinches, spacingInches = FREEMO_TRACK_SPACING_INCHES) {
|
|
10
|
+
const base = (lane ?? 0) * spacingInches;
|
|
11
|
+
if (!lane || !pinches?.length) return base;
|
|
12
|
+
const sign = Math.sign(lane);
|
|
13
|
+
const smooth = (t) => t * t * (3 - 2 * t);
|
|
14
|
+
let off = base;
|
|
15
|
+
for (const p of pinches) {
|
|
16
|
+
if (p.lane !== lane) continue;
|
|
17
|
+
const a = Math.min(p.fromPos, p.toPos);
|
|
18
|
+
const b = Math.max(p.fromPos, p.toPos);
|
|
19
|
+
const target = base - sign * (spacingInches * Math.abs(lane) - p.spacingInches);
|
|
20
|
+
const e = PINCH_EASE_INCHES;
|
|
21
|
+
let t = null;
|
|
22
|
+
if (pos >= a && pos <= b) t = 1;
|
|
23
|
+
else if (pos > a - e && pos < a) t = smooth((pos - (a - e)) / e);
|
|
24
|
+
else if (pos > b && pos < b + e) t = smooth(1 - (pos - b) / e);
|
|
25
|
+
if (t == null) continue;
|
|
26
|
+
const candidate = base + (target - base) * t;
|
|
27
|
+
if (Math.abs(candidate - base) > Math.abs(off - base)) off = candidate;
|
|
28
|
+
}
|
|
29
|
+
return off;
|
|
30
|
+
}
|
|
31
|
+
function crossoverPinches(tracks, library = BUILT_IN_TRACK_PARTS, spacingInches = FREEMO_TRACK_SPACING_INCHES) {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const t of tracks) {
|
|
34
|
+
if (t.role !== "crossover" || !t.crossoverPartId) continue;
|
|
35
|
+
const part = library.find((p) => p.id === t.crossoverPartId);
|
|
36
|
+
const s = part?.trackSpacing?.inches;
|
|
37
|
+
if (typeof s !== "number" || !Number.isFinite(s) || s <= 0) continue;
|
|
38
|
+
if (Math.abs(s - spacingInches) < 1e-9) continue;
|
|
39
|
+
const lane = t.lane ?? 1;
|
|
40
|
+
if (!lane) continue;
|
|
41
|
+
const a = t.fromPos ?? 0;
|
|
42
|
+
const b = t.toPos ?? 0;
|
|
43
|
+
if (!Number.isFinite(a) || !Number.isFinite(b) || Math.abs(b - a) < 1e-9) continue;
|
|
44
|
+
const pinch = {
|
|
45
|
+
lane,
|
|
46
|
+
fromPos: Math.min(a, b),
|
|
47
|
+
toPos: Math.max(a, b),
|
|
48
|
+
spacingInches: s
|
|
49
|
+
};
|
|
50
|
+
const same = out.some(
|
|
51
|
+
(p) => p.lane === pinch.lane && Math.abs(p.fromPos - pinch.fromPos) < 1e-9 && Math.abs(p.toPos - pinch.toPos) < 1e-9 && Math.abs(p.spacingInches - pinch.spacingInches) < 1e-9
|
|
52
|
+
);
|
|
53
|
+
if (!same) out.push(pinch);
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
8
57
|
function endplateWidthInches(ep) {
|
|
9
58
|
const w = ep?.widthInches;
|
|
10
59
|
return typeof w === "number" && w > 0 ? w : FREEMO_ENDPLATE_WIDTH_RECOMMENDED_INCHES;
|
|
@@ -943,6 +992,7 @@ function stateToDoc(state, recordNumber) {
|
|
|
943
992
|
}).scaleFeet,
|
|
944
993
|
...typeof t.measuredUsableInches === "number" && t.measuredUsableInches >= 0 ? { measuredUsableInches: t.measuredUsableInches } : {},
|
|
945
994
|
...state.loop && t.inLoop ? { inLoop: true } : {},
|
|
995
|
+
...t.crossoverPartId ? { crossoverPartId: t.crossoverPartId } : {},
|
|
946
996
|
...t.path && t.path.length >= 2 ? { path: t.path } : {}
|
|
947
997
|
}))
|
|
948
998
|
]),
|
|
@@ -1039,6 +1089,9 @@ function docToState(doc, fallbackLength, moduleTracks = []) {
|
|
|
1039
1089
|
moduleTrackId,
|
|
1040
1090
|
trackName: t.trackName ?? nameOf(moduleTrackId),
|
|
1041
1091
|
...t.inLoop ? { inLoop: true } : {},
|
|
1092
|
+
// The crossover product this connector was built from — what makes the
|
|
1093
|
+
// physical view draw the pair at the spacing it was really built to.
|
|
1094
|
+
...typeof t.crossoverPartId === "string" && t.crossoverPartId ? { crossoverPartId: t.crossoverPartId } : {},
|
|
1042
1095
|
// Authored path kept as-drawn (a physical shape, not rescaled with length).
|
|
1043
1096
|
...trackPath(t.path) ? { path: trackPath(t.path) } : {},
|
|
1044
1097
|
// A MEASURED length is a real-world fact about the physical track, so it
|
|
@@ -2672,6 +2725,7 @@ exports.MAIN2_TRACK_ID = MAIN2_TRACK_ID;
|
|
|
2672
2725
|
exports.MAIN_TRACK_ID = MAIN_TRACK_ID;
|
|
2673
2726
|
exports.N_CAR_LENGTH_INCHES = N_CAR_LENGTH_INCHES;
|
|
2674
2727
|
exports.N_SCALE_RATIO = N_SCALE_RATIO;
|
|
2728
|
+
exports.PINCH_EASE_INCHES = PINCH_EASE_INCHES;
|
|
2675
2729
|
exports.RAIL_GAUGE_INCHES = RAIL_GAUGE_INCHES;
|
|
2676
2730
|
exports.TIE_HALF_LENGTH_INCHES = TIE_HALF_LENGTH_INCHES;
|
|
2677
2731
|
exports.TURNOUT_LEAD_INCHES_PER_FROG = TURNOUT_LEAD_INCHES_PER_FROG;
|
|
@@ -2687,6 +2741,7 @@ exports.buildTransition = buildTransition;
|
|
|
2687
2741
|
exports.carCapacity = carCapacity;
|
|
2688
2742
|
exports.checkEndplateWidth = checkEndplateWidth;
|
|
2689
2743
|
exports.clearancePointPastFrogInches = clearancePointPastFrogInches;
|
|
2744
|
+
exports.crossoverPinches = crossoverPinches;
|
|
2690
2745
|
exports.deriveEndplatePoses = deriveEndplatePoses;
|
|
2691
2746
|
exports.divergeSideForHand = divergeSideForHand;
|
|
2692
2747
|
exports.docToState = docToState;
|
|
@@ -2709,6 +2764,7 @@ exports.importedPartToTrackPart = importedPartToTrackPart;
|
|
|
2709
2764
|
exports.inchesToScaleFeet = inchesToScaleFeet;
|
|
2710
2765
|
exports.isLoopDoc = isLoopDoc;
|
|
2711
2766
|
exports.isTransitionTurnout = isTransitionTurnout;
|
|
2767
|
+
exports.laneOffsetAt = laneOffsetAt;
|
|
2712
2768
|
exports.leadInchesForSize = leadInchesForSize;
|
|
2713
2769
|
exports.maxFlexPieceInches = maxFlexPieceInches;
|
|
2714
2770
|
exports.mergeImportedParts = mergeImportedParts;
|