vehicle-path2 1.0.0
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/README.md +160 -0
- package/dist/animation-loop-bZEm2pMN.js +37 -0
- package/dist/animation-loop-fC2LjxCd.cjs +1 -0
- package/dist/core/algorithms/math.d.ts +35 -0
- package/dist/core/algorithms/pathFinding.d.ts +62 -0
- package/dist/core/algorithms/vehicleMovement.d.ts +174 -0
- package/dist/core/index.d.ts +20 -0
- package/dist/core/types/api.d.ts +185 -0
- package/dist/core/types/config.d.ts +9 -0
- package/dist/core/types/geometry.d.ts +26 -0
- package/dist/core/types/movement.d.ts +56 -0
- package/dist/core/types/vehicle.d.ts +65 -0
- package/dist/core.cjs +1 -0
- package/dist/core.js +551 -0
- package/dist/index.d.ts +45 -0
- package/dist/react/dsl-hooks/useInitialMovement.d.ts +24 -0
- package/dist/react/dsl-hooks/useMovementSequence.d.ts +27 -0
- package/dist/react/dsl-hooks/useSceneDefinition.d.ts +22 -0
- package/dist/react/hooks/useAnimation.d.ts +43 -0
- package/dist/react/hooks/useMovementQueue.d.ts +52 -0
- package/dist/react/hooks/useScene.d.ts +78 -0
- package/dist/react/hooks/useVehicleSimulation.d.ts +126 -0
- package/dist/react/hooks/useVehicles.d.ts +55 -0
- package/dist/react/index.d.ts +48 -0
- package/dist/react/providers/useVehicleEvents.d.ts +78 -0
- package/dist/react.cjs +1 -0
- package/dist/react.js +18 -0
- package/dist/useVehicleEvents-B2JQFNjc.js +923 -0
- package/dist/useVehicleEvents-CBymulau.cjs +3 -0
- package/dist/utils/animation-loop.d.ts +105 -0
- package/dist/utils/dsl-parser.d.ts +152 -0
- package/dist/utils/event-emitter.d.ts +94 -0
- package/dist/utils/index.d.ts +15 -0
- package/dist/utils/type-converters.d.ts +38 -0
- package/dist/utils/vehicle-helpers.d.ts +8 -0
- package/dist/utils.cjs +1 -0
- package/dist/utils.js +17 -0
- package/dist/vehicle-helpers-DIcksrtO.cjs +7 -0
- package/dist/vehicle-helpers-_72KxCqO.js +276 -0
- package/dist/vehicle-path.cjs +1 -0
- package/dist/vehicle-path.js +62 -0
- package/package.json +103 -0
package/dist/core.js
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
function v(e, t) {
|
|
2
|
+
const o = t.x - e.x, n = t.y - e.y;
|
|
3
|
+
return Math.sqrt(o * o + n * n);
|
|
4
|
+
}
|
|
5
|
+
function M(e, t) {
|
|
6
|
+
const o = t.x - e.x, n = t.y - e.y, s = Math.sqrt(o * o + n * n);
|
|
7
|
+
return s === 0 ? { x: 0, y: 0 } : { x: o / s, y: n / s };
|
|
8
|
+
}
|
|
9
|
+
function F(e, t) {
|
|
10
|
+
return t * (e === "proportional-40" ? 0.4 : 0.5522);
|
|
11
|
+
}
|
|
12
|
+
function T(e, t, o, n = !1, s) {
|
|
13
|
+
const { wheelbase: c, tangentMode: i } = o;
|
|
14
|
+
let r;
|
|
15
|
+
s?.fromOffset !== void 0 ? r = S(e, s.fromOffset, s.fromIsPercentage ?? !1) : r = e.end;
|
|
16
|
+
let l;
|
|
17
|
+
s?.toOffset !== void 0 ? l = S(t, s.toOffset, s.toIsPercentage ?? !1) : l = t.start;
|
|
18
|
+
const d = M(e.start, e.end), a = n ? {
|
|
19
|
+
// Transition with flip: kurva dimulai dari P (baseP0 - wheelbase in line direction)
|
|
20
|
+
x: r.x - d.x * c,
|
|
21
|
+
y: r.y - d.y * c
|
|
22
|
+
} : r, u = M(e.start, e.end), g = M(t.start, t.end), p = v(a, l), I = F(i, p), f = n ? { x: a.x - u.x * I, y: a.y - u.y * I } : { x: a.x + u.x * I, y: a.y + u.y * I }, m = {
|
|
23
|
+
x: l.x - g.x * I,
|
|
24
|
+
y: l.y - g.y * I
|
|
25
|
+
};
|
|
26
|
+
return { p0: a, p1: f, p2: m, p3: l };
|
|
27
|
+
}
|
|
28
|
+
function K(e, t) {
|
|
29
|
+
return {
|
|
30
|
+
x: e.start.x + (e.end.x - e.start.x) * t,
|
|
31
|
+
y: e.start.y + (e.end.y - e.start.y) * t
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function S(e, t, o) {
|
|
35
|
+
const n = v(e.start, e.end);
|
|
36
|
+
let s;
|
|
37
|
+
return o ? s = t / 100 : s = n > 0 ? t / n : 0, s = Math.max(0, Math.min(1, s)), K(e, s);
|
|
38
|
+
}
|
|
39
|
+
function D(e, t) {
|
|
40
|
+
const { p0: o, p1: n, p2: s, p3: c } = e, i = 1 - t, r = i * i, l = r * i, d = t * t, a = d * t;
|
|
41
|
+
return {
|
|
42
|
+
x: l * o.x + 3 * r * t * n.x + 3 * i * d * s.x + a * c.x,
|
|
43
|
+
y: l * o.y + 3 * r * t * n.y + 3 * i * d * s.y + a * c.y
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function J(e, t, o = 10) {
|
|
47
|
+
return v(e, t) <= o;
|
|
48
|
+
}
|
|
49
|
+
function j(e, t = 100) {
|
|
50
|
+
const o = [{ t: 0, distance: 0 }];
|
|
51
|
+
let n = e.p0, s = 0;
|
|
52
|
+
for (let c = 1; c <= t; c++) {
|
|
53
|
+
const i = c / t, r = D(e, i);
|
|
54
|
+
s += v(n, r), o.push({ t: i, distance: s }), n = r;
|
|
55
|
+
}
|
|
56
|
+
return o;
|
|
57
|
+
}
|
|
58
|
+
function $(e, t) {
|
|
59
|
+
if (t <= 0) return 0;
|
|
60
|
+
const o = e[e.length - 1].distance;
|
|
61
|
+
if (t >= o) return 1;
|
|
62
|
+
let n = 0, s = e.length - 1;
|
|
63
|
+
for (; n < s - 1; ) {
|
|
64
|
+
const a = Math.floor((n + s) / 2);
|
|
65
|
+
e[a].distance < t ? n = a : s = a;
|
|
66
|
+
}
|
|
67
|
+
const c = e[n].distance, i = e[s].distance, r = e[n].t, l = e[s].t;
|
|
68
|
+
if (i === c) return r;
|
|
69
|
+
const d = (t - c) / (i - c);
|
|
70
|
+
return r + d * (l - r);
|
|
71
|
+
}
|
|
72
|
+
function U(e) {
|
|
73
|
+
return e[e.length - 1].distance;
|
|
74
|
+
}
|
|
75
|
+
function k(e, t = 100) {
|
|
76
|
+
let o = 0, n = e.p0;
|
|
77
|
+
for (let s = 1; s <= t; s++) {
|
|
78
|
+
const c = s / t, i = D(e, c);
|
|
79
|
+
o += v(n, i), n = i;
|
|
80
|
+
}
|
|
81
|
+
return o;
|
|
82
|
+
}
|
|
83
|
+
function b(e, t, o, n, s) {
|
|
84
|
+
const c = v(e.start, e.end), i = c - s;
|
|
85
|
+
if (i <= 0)
|
|
86
|
+
return c;
|
|
87
|
+
let r;
|
|
88
|
+
if (t === void 0)
|
|
89
|
+
r = n;
|
|
90
|
+
else if (o)
|
|
91
|
+
r = t;
|
|
92
|
+
else
|
|
93
|
+
return Math.max(s, Math.min(t, c));
|
|
94
|
+
return s + r / 100 * i;
|
|
95
|
+
}
|
|
96
|
+
function A(e, t, o, n, s) {
|
|
97
|
+
const i = v(e.start, e.end) - s;
|
|
98
|
+
if (i <= 0)
|
|
99
|
+
return 0;
|
|
100
|
+
let r;
|
|
101
|
+
if (t === void 0)
|
|
102
|
+
r = n;
|
|
103
|
+
else if (o)
|
|
104
|
+
r = t;
|
|
105
|
+
else
|
|
106
|
+
return Math.max(0, Math.min(t, i));
|
|
107
|
+
return r / 100 * i;
|
|
108
|
+
}
|
|
109
|
+
function X(e, t, o) {
|
|
110
|
+
const n = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
|
|
111
|
+
for (const i of e)
|
|
112
|
+
s.set(i.id, i), c.set(i.id, v(i.start, i.end)), n.set(i.id, []);
|
|
113
|
+
for (let i = 0; i < t.length; i++) {
|
|
114
|
+
const r = t[i], l = s.get(r.fromLineId), d = s.get(r.toLineId);
|
|
115
|
+
if (!l || !d) continue;
|
|
116
|
+
const a = b(l, r.fromOffset, r.fromIsPercentage, 100, o.wheelbase), u = A(d, r.toOffset, r.toIsPercentage, 0, o.wheelbase), g = T(
|
|
117
|
+
l,
|
|
118
|
+
d,
|
|
119
|
+
o,
|
|
120
|
+
!1,
|
|
121
|
+
// willFlip is always false now
|
|
122
|
+
{
|
|
123
|
+
fromOffset: a,
|
|
124
|
+
fromIsPercentage: !1,
|
|
125
|
+
// Already resolved to absolute
|
|
126
|
+
toOffset: u,
|
|
127
|
+
toIsPercentage: !1
|
|
128
|
+
// Already resolved to absolute
|
|
129
|
+
}
|
|
130
|
+
), p = k(g), I = {
|
|
131
|
+
curveIndex: i,
|
|
132
|
+
fromLineId: r.fromLineId,
|
|
133
|
+
toLineId: r.toLineId,
|
|
134
|
+
fromOffset: a,
|
|
135
|
+
toOffset: u,
|
|
136
|
+
curveLength: p
|
|
137
|
+
};
|
|
138
|
+
n.get(r.fromLineId).push(I);
|
|
139
|
+
}
|
|
140
|
+
return { adjacency: n, lines: s, lineLengths: c };
|
|
141
|
+
}
|
|
142
|
+
function G(e, t, o, n, s = !1) {
|
|
143
|
+
const { adjacency: c, lines: i, lineLengths: r } = e;
|
|
144
|
+
if (!i.get(o)) return null;
|
|
145
|
+
const d = r.get(o), a = s ? n / 100 * d : n, u = [], g = /* @__PURE__ */ new Map(), p = (f, m) => `${f}:${Math.round(m)}`;
|
|
146
|
+
if (t.lineId === o && a >= t.offset) {
|
|
147
|
+
const f = a - t.offset;
|
|
148
|
+
return {
|
|
149
|
+
segments: [{
|
|
150
|
+
type: "line",
|
|
151
|
+
lineId: t.lineId,
|
|
152
|
+
startOffset: t.offset,
|
|
153
|
+
endOffset: a,
|
|
154
|
+
length: f
|
|
155
|
+
}],
|
|
156
|
+
totalDistance: f
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const I = c.get(t.lineId) || [];
|
|
160
|
+
for (const f of I) {
|
|
161
|
+
if (f.fromOffset < t.offset) continue;
|
|
162
|
+
const m = f.fromOffset - t.offset, y = m + f.curveLength, L = {
|
|
163
|
+
type: "line",
|
|
164
|
+
lineId: t.lineId,
|
|
165
|
+
startOffset: t.offset,
|
|
166
|
+
endOffset: f.fromOffset,
|
|
167
|
+
length: m
|
|
168
|
+
}, h = {
|
|
169
|
+
type: "curve",
|
|
170
|
+
curveIndex: f.curveIndex,
|
|
171
|
+
startOffset: 0,
|
|
172
|
+
endOffset: f.curveLength,
|
|
173
|
+
length: f.curveLength
|
|
174
|
+
};
|
|
175
|
+
u.push({
|
|
176
|
+
lineId: f.toLineId,
|
|
177
|
+
entryOffset: f.toOffset,
|
|
178
|
+
totalDistance: y,
|
|
179
|
+
path: [L, h]
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
for (u.sort((f, m) => f.totalDistance - m.totalDistance); u.length > 0; ) {
|
|
183
|
+
const f = u.shift(), m = p(f.lineId, f.entryOffset), y = g.get(m);
|
|
184
|
+
if (y !== void 0 && y <= f.totalDistance)
|
|
185
|
+
continue;
|
|
186
|
+
if (g.set(m, f.totalDistance), f.lineId === o) {
|
|
187
|
+
const h = Math.abs(a - f.entryOffset);
|
|
188
|
+
if (a >= f.entryOffset) {
|
|
189
|
+
const x = {
|
|
190
|
+
type: "line",
|
|
191
|
+
lineId: o,
|
|
192
|
+
startOffset: f.entryOffset,
|
|
193
|
+
endOffset: a,
|
|
194
|
+
length: h
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
segments: [...f.path, x],
|
|
198
|
+
totalDistance: f.totalDistance + h
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const L = c.get(f.lineId) || [];
|
|
203
|
+
for (const h of L) {
|
|
204
|
+
if (h.fromOffset < f.entryOffset) continue;
|
|
205
|
+
const x = h.fromOffset - f.entryOffset, P = f.totalDistance + x + h.curveLength, q = p(h.toLineId, h.toOffset), C = g.get(q);
|
|
206
|
+
if (C !== void 0 && C <= P)
|
|
207
|
+
continue;
|
|
208
|
+
const z = {
|
|
209
|
+
type: "line",
|
|
210
|
+
lineId: f.lineId,
|
|
211
|
+
startOffset: f.entryOffset,
|
|
212
|
+
endOffset: h.fromOffset,
|
|
213
|
+
length: x
|
|
214
|
+
}, B = {
|
|
215
|
+
type: "curve",
|
|
216
|
+
curveIndex: h.curveIndex,
|
|
217
|
+
startOffset: 0,
|
|
218
|
+
endOffset: h.curveLength,
|
|
219
|
+
length: h.curveLength
|
|
220
|
+
};
|
|
221
|
+
u.push({
|
|
222
|
+
lineId: h.toLineId,
|
|
223
|
+
entryOffset: h.toOffset,
|
|
224
|
+
totalDistance: P,
|
|
225
|
+
path: [...f.path, z, B]
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
u.sort((h, x) => h.totalDistance - x.totalDistance);
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
function V(e, t) {
|
|
233
|
+
const o = Math.sqrt(
|
|
234
|
+
Math.pow(e.end.x - e.start.x, 2) + Math.pow(e.end.y - e.start.y, 2)
|
|
235
|
+
), n = o > 0 ? t / o : 0;
|
|
236
|
+
return {
|
|
237
|
+
x: e.start.x + (e.end.x - e.start.x) * Math.min(1, Math.max(0, n)),
|
|
238
|
+
y: e.start.y + (e.end.y - e.start.y) * Math.min(1, Math.max(0, n))
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function N(e) {
|
|
242
|
+
return Math.sqrt(
|
|
243
|
+
Math.pow(e.end.x - e.start.x, 2) + Math.pow(e.end.y - e.start.y, 2)
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
function Q(e, t, o) {
|
|
247
|
+
let n = 0;
|
|
248
|
+
for (let s = 0; s < t; s++)
|
|
249
|
+
n += e.segments[s].length;
|
|
250
|
+
return n += o, n;
|
|
251
|
+
}
|
|
252
|
+
function R(e, t) {
|
|
253
|
+
let o = 0;
|
|
254
|
+
for (let n = 0; n < e.segments.length; n++) {
|
|
255
|
+
const s = e.segments[n], c = o + s.length;
|
|
256
|
+
if (t < c)
|
|
257
|
+
return {
|
|
258
|
+
segmentIndex: n,
|
|
259
|
+
segmentDistance: t - o
|
|
260
|
+
};
|
|
261
|
+
if (t === c)
|
|
262
|
+
return n + 1 < e.segments.length ? {
|
|
263
|
+
segmentIndex: n + 1,
|
|
264
|
+
segmentDistance: 0
|
|
265
|
+
} : {
|
|
266
|
+
segmentIndex: n,
|
|
267
|
+
segmentDistance: s.length
|
|
268
|
+
};
|
|
269
|
+
o += s.length;
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
function W(e, t, o, n) {
|
|
274
|
+
const c = Q(
|
|
275
|
+
e,
|
|
276
|
+
t,
|
|
277
|
+
o
|
|
278
|
+
) + n;
|
|
279
|
+
return R(e, c);
|
|
280
|
+
}
|
|
281
|
+
function Y(e, t, o, n) {
|
|
282
|
+
const s = Math.sqrt(
|
|
283
|
+
Math.pow(n.end.x - n.start.x, 2) + Math.pow(n.end.y - n.start.y, 2)
|
|
284
|
+
);
|
|
285
|
+
let c = t + o;
|
|
286
|
+
c = Math.min(c, s);
|
|
287
|
+
const i = V(n, c);
|
|
288
|
+
return {
|
|
289
|
+
lineId: e,
|
|
290
|
+
position: i,
|
|
291
|
+
absoluteOffset: c
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function _(e, t) {
|
|
295
|
+
return {
|
|
296
|
+
...e,
|
|
297
|
+
state: "idle"
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function E(e) {
|
|
301
|
+
return {
|
|
302
|
+
vehicle: e,
|
|
303
|
+
execution: null
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function Z(e, t) {
|
|
307
|
+
const o = [], n = /* @__PURE__ */ new Map();
|
|
308
|
+
for (const s of e) {
|
|
309
|
+
if (!t.get(s.lineId)) continue;
|
|
310
|
+
const i = _(s);
|
|
311
|
+
o.push(i);
|
|
312
|
+
const r = E(i);
|
|
313
|
+
n.set(s.id, r);
|
|
314
|
+
}
|
|
315
|
+
return { movingVehicles: o, stateMap: n };
|
|
316
|
+
}
|
|
317
|
+
function O(e, t) {
|
|
318
|
+
return { position: V(e, t), lineId: e.id, absoluteOffset: t };
|
|
319
|
+
}
|
|
320
|
+
function w(e, t) {
|
|
321
|
+
const o = $(e.arcLengthTable, t);
|
|
322
|
+
return { position: D(e.bezier, o) };
|
|
323
|
+
}
|
|
324
|
+
function ee(e, t, o, n, s, c, i) {
|
|
325
|
+
const r = o.segments[t.currentSegmentIndex], l = t.segmentDistance + n;
|
|
326
|
+
if (l >= r.length) {
|
|
327
|
+
const a = l - r.length, u = t.currentSegmentIndex + 1;
|
|
328
|
+
if (u >= o.segments.length) {
|
|
329
|
+
if (i !== void 0 && r.type === "line") {
|
|
330
|
+
const f = s.get(r.lineId), m = r.startOffset + l;
|
|
331
|
+
if (m <= i) {
|
|
332
|
+
const L = O(f, m);
|
|
333
|
+
return {
|
|
334
|
+
axleState: { ...e, ...L },
|
|
335
|
+
execution: { ...t, segmentDistance: l },
|
|
336
|
+
completed: !1
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
const y = O(f, i);
|
|
340
|
+
return {
|
|
341
|
+
axleState: { ...e, ...y },
|
|
342
|
+
execution: { ...t, segmentDistance: i - r.startOffset },
|
|
343
|
+
completed: !0
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
const I = r.type === "line" ? O(
|
|
347
|
+
s.get(r.lineId),
|
|
348
|
+
r.endOffset
|
|
349
|
+
) : w(
|
|
350
|
+
c.get(r.curveIndex),
|
|
351
|
+
r.length
|
|
352
|
+
);
|
|
353
|
+
return {
|
|
354
|
+
axleState: { ...e, ...I },
|
|
355
|
+
execution: { ...t, segmentDistance: r.length },
|
|
356
|
+
completed: !0
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
const g = o.segments[u], p = g.type === "line" ? O(
|
|
360
|
+
s.get(g.lineId),
|
|
361
|
+
g.startOffset + a
|
|
362
|
+
) : w(
|
|
363
|
+
c.get(g.curveIndex),
|
|
364
|
+
a
|
|
365
|
+
);
|
|
366
|
+
return {
|
|
367
|
+
axleState: { ...e, ...p },
|
|
368
|
+
execution: {
|
|
369
|
+
currentSegmentIndex: u,
|
|
370
|
+
segmentDistance: a
|
|
371
|
+
},
|
|
372
|
+
completed: !1
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
const d = r.type === "line" ? O(
|
|
376
|
+
s.get(r.lineId),
|
|
377
|
+
r.startOffset + l
|
|
378
|
+
) : w(
|
|
379
|
+
c.get(r.curveIndex),
|
|
380
|
+
l
|
|
381
|
+
);
|
|
382
|
+
return {
|
|
383
|
+
axleState: { ...e, ...d },
|
|
384
|
+
execution: { ...t, segmentDistance: l },
|
|
385
|
+
completed: !1
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function H(e, t, o, n) {
|
|
389
|
+
const s = /* @__PURE__ */ new Map();
|
|
390
|
+
for (const c of e.segments)
|
|
391
|
+
if (c.type === "curve" && c.curveIndex !== void 0) {
|
|
392
|
+
const i = t[c.curveIndex];
|
|
393
|
+
if (i) {
|
|
394
|
+
const r = o.get(i.fromLineId), l = o.get(i.toLineId);
|
|
395
|
+
if (r && l) {
|
|
396
|
+
const d = b(
|
|
397
|
+
r,
|
|
398
|
+
i.fromOffset,
|
|
399
|
+
i.fromIsPercentage,
|
|
400
|
+
100,
|
|
401
|
+
n.wheelbase
|
|
402
|
+
), a = A(
|
|
403
|
+
l,
|
|
404
|
+
i.toOffset,
|
|
405
|
+
i.toIsPercentage,
|
|
406
|
+
0,
|
|
407
|
+
n.wheelbase
|
|
408
|
+
), u = T(
|
|
409
|
+
r,
|
|
410
|
+
l,
|
|
411
|
+
n,
|
|
412
|
+
!1,
|
|
413
|
+
// willFlip is always false now
|
|
414
|
+
{
|
|
415
|
+
fromOffset: d,
|
|
416
|
+
fromIsPercentage: !1,
|
|
417
|
+
// Already resolved to absolute
|
|
418
|
+
toOffset: a,
|
|
419
|
+
toIsPercentage: !1
|
|
420
|
+
// Already resolved to absolute
|
|
421
|
+
}
|
|
422
|
+
), g = j(u);
|
|
423
|
+
s.set(c.curveIndex, { bezier: u, arcLengthTable: g });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return s;
|
|
428
|
+
}
|
|
429
|
+
function te(e, t, o) {
|
|
430
|
+
const { graph: n, linesMap: s, curves: c, config: i } = o, r = s.get(t.targetLineId);
|
|
431
|
+
if (!r) return null;
|
|
432
|
+
const d = N(r) - i.wheelbase;
|
|
433
|
+
if (d <= 0) return null;
|
|
434
|
+
const a = t.isPercentage ? t.targetOffset / 100 * d : Math.min(t.targetOffset, d), u = G(
|
|
435
|
+
n,
|
|
436
|
+
{ lineId: e.rear.lineId, offset: e.rear.absoluteOffset },
|
|
437
|
+
t.targetLineId,
|
|
438
|
+
a,
|
|
439
|
+
!1
|
|
440
|
+
);
|
|
441
|
+
if (!u) return null;
|
|
442
|
+
const g = H(u, c, s, i);
|
|
443
|
+
return { path: u, curveDataMap: g };
|
|
444
|
+
}
|
|
445
|
+
function ne(e, t) {
|
|
446
|
+
const o = e.execution, n = t.vehicleQueues.get(e.vehicle.id), s = n?.[o.currentCommandIndex];
|
|
447
|
+
if (s && t.onCommandComplete && t.onCommandComplete({
|
|
448
|
+
vehicleId: e.vehicle.id,
|
|
449
|
+
command: s,
|
|
450
|
+
finalPosition: {
|
|
451
|
+
lineId: e.vehicle.rear.lineId,
|
|
452
|
+
absoluteOffset: e.vehicle.rear.absoluteOffset,
|
|
453
|
+
position: e.vehicle.rear.position
|
|
454
|
+
},
|
|
455
|
+
payload: s.payload
|
|
456
|
+
}), s?.awaitConfirmation)
|
|
457
|
+
return {
|
|
458
|
+
handled: !0,
|
|
459
|
+
vehicle: { ...e.vehicle, state: "waiting" },
|
|
460
|
+
newExecution: o,
|
|
461
|
+
// Keep execution state for resume
|
|
462
|
+
isWaiting: !0
|
|
463
|
+
};
|
|
464
|
+
const c = o.currentCommandIndex + 1;
|
|
465
|
+
if (n && c < n.length) {
|
|
466
|
+
const r = n[c], l = t.graphRef.current;
|
|
467
|
+
if (l) {
|
|
468
|
+
const d = {
|
|
469
|
+
graph: l,
|
|
470
|
+
linesMap: t.linesMap,
|
|
471
|
+
curves: t.curves,
|
|
472
|
+
config: t.config
|
|
473
|
+
}, a = t.prepareCommandPath(
|
|
474
|
+
e.vehicle,
|
|
475
|
+
r,
|
|
476
|
+
d
|
|
477
|
+
);
|
|
478
|
+
if (a) {
|
|
479
|
+
const u = W(
|
|
480
|
+
a.path,
|
|
481
|
+
0,
|
|
482
|
+
0,
|
|
483
|
+
t.config.wheelbase
|
|
484
|
+
);
|
|
485
|
+
t.onCommandStart && t.onCommandStart({
|
|
486
|
+
vehicleId: e.vehicle.id,
|
|
487
|
+
command: r,
|
|
488
|
+
commandIndex: c,
|
|
489
|
+
startPosition: {
|
|
490
|
+
lineId: e.vehicle.rear.lineId,
|
|
491
|
+
absoluteOffset: e.vehicle.rear.absoluteOffset,
|
|
492
|
+
position: e.vehicle.rear.position
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
const g = {
|
|
496
|
+
path: a.path,
|
|
497
|
+
curveDataMap: a.curveDataMap,
|
|
498
|
+
currentCommandIndex: c,
|
|
499
|
+
rear: {
|
|
500
|
+
currentSegmentIndex: 0,
|
|
501
|
+
segmentDistance: 0
|
|
502
|
+
},
|
|
503
|
+
front: u ? {
|
|
504
|
+
currentSegmentIndex: u.segmentIndex,
|
|
505
|
+
segmentDistance: u.segmentDistance
|
|
506
|
+
} : {
|
|
507
|
+
currentSegmentIndex: 0,
|
|
508
|
+
segmentDistance: 0
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
return { handled: !0, vehicle: { ...e.vehicle, state: "moving" }, newExecution: g };
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return { handled: !0, vehicle: {
|
|
516
|
+
...e.vehicle,
|
|
517
|
+
state: "idle"
|
|
518
|
+
}, newExecution: null };
|
|
519
|
+
}
|
|
520
|
+
export {
|
|
521
|
+
R as arcLengthToSegmentPosition,
|
|
522
|
+
j as buildArcLengthTable,
|
|
523
|
+
X as buildGraph,
|
|
524
|
+
k as calculateBezierArcLength,
|
|
525
|
+
W as calculateFrontAxlePosition,
|
|
526
|
+
Y as calculateInitialFrontPosition,
|
|
527
|
+
w as calculatePositionOnCurve,
|
|
528
|
+
O as calculatePositionOnLine,
|
|
529
|
+
F as calculateTangentLength,
|
|
530
|
+
T as createBezierCurve,
|
|
531
|
+
E as createInitialMovementState,
|
|
532
|
+
v as distance,
|
|
533
|
+
$ as distanceToT,
|
|
534
|
+
G as findPath,
|
|
535
|
+
U as getArcLength,
|
|
536
|
+
Q as getCumulativeArcLength,
|
|
537
|
+
N as getLineLength,
|
|
538
|
+
D as getPointOnBezier,
|
|
539
|
+
K as getPointOnLine,
|
|
540
|
+
S as getPointOnLineByOffset,
|
|
541
|
+
V as getPositionFromOffset,
|
|
542
|
+
ne as handleArrival,
|
|
543
|
+
Z as initializeAllVehicles,
|
|
544
|
+
_ as initializeMovingVehicle,
|
|
545
|
+
J as isPointNearPoint,
|
|
546
|
+
M as normalize,
|
|
547
|
+
te as prepareCommandPath,
|
|
548
|
+
b as resolveFromLineOffset,
|
|
549
|
+
A as resolveToLineOffset,
|
|
550
|
+
ee as updateAxlePosition
|
|
551
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VehiclePath - Vehicle motion simulator library
|
|
3
|
+
*
|
|
4
|
+
* A library for simulating dual-axle vehicle movement along paths
|
|
5
|
+
* composed of lines and Bezier curves.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { useVehicleSimulation } from 'vehicle-path'
|
|
10
|
+
*
|
|
11
|
+
* const sim = useVehicleSimulation({ wheelbase: 30 })
|
|
12
|
+
* sim.addLine({ id: 'line1', start: [0, 0], end: [400, 0] })
|
|
13
|
+
* sim.addVehicles({ id: 'v1', lineId: 'line1', position: 0 })
|
|
14
|
+
* sim.goto('v1', 'line1', 1.0)
|
|
15
|
+
* sim.prepare()
|
|
16
|
+
* sim.tick(5)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export type { Point, Line, BezierCurve, Curve } from './core/types/geometry';
|
|
20
|
+
export type { VehicleState, VehicleStart, Vehicle, AxleState, GotoCommand, GotoCompletionInfo, GotoCompletionCallback } from './core/types/vehicle';
|
|
21
|
+
export type { CurveData, PathExecutionState, VehicleMovementState, MovementConfig, SceneContext } from './core/types/movement';
|
|
22
|
+
export type { TangentMode } from './core/types/config';
|
|
23
|
+
export type { CoordinateInput, SceneLineInput, SceneConnectionInput, SceneConfig, VehicleInput, VehicleUpdateInput, ConnectionUpdateInput, GotoInput, GotoCommandInput, MovementCommandInput, SimulationConfig } from './core/types/api';
|
|
24
|
+
export { buildGraph, findPath, calculateBezierArcLength, resolveFromLineOffset, resolveToLineOffset, type Graph, type GraphEdge, type PathSegment, type PathResult, type VehiclePosition } from './core/algorithms/pathFinding';
|
|
25
|
+
export { initializeMovingVehicle, createInitialMovementState, initializeAllVehicles, calculateInitialFrontPosition, type InitializationResult, updateAxlePosition, calculatePositionOnLine, calculatePositionOnCurve, calculateFrontAxlePosition, getCumulativeArcLength, arcLengthToSegmentPosition, prepareCommandPath, type PreparedPath, handleArrival, type SegmentCompletionContext, type SegmentCompletionResult, type SegmentVehicleState, getPositionFromOffset, getLineLength } from './core/algorithms/vehicleMovement';
|
|
26
|
+
export { distance, normalize, getPointOnLine, getPointOnLineByOffset, getPointOnBezier, createBezierCurve, buildArcLengthTable, distanceToT, getArcLength, type ArcLengthEntry, type CurveOffsetOptions } from './core/algorithms/math';
|
|
27
|
+
export { VehicleEventEmitter, type VehicleEventMap, type VehicleEventType, type VehicleEventCallback, type VehiclePositionUpdate, type Unsubscribe, type CommandStartInfo } from './utils/event-emitter';
|
|
28
|
+
export { parseSceneDSL, parseVehiclesDSL, parseMovementDSL, parseAllDSL, generateSceneDSL, generateVehiclesDSL, generateMovementDSL, type ParseResult, type MovementCommand } from './utils/dsl-parser';
|
|
29
|
+
export { createAnimationLoop, useAnimationLoop, type AnimationLoopOptions, type AnimationLoopControls } from './utils/animation-loop';
|
|
30
|
+
export { validateAndCreateVehicles, getNextStartVehicleId, getNextGotoVehicleId } from './utils/vehicle-helpers';
|
|
31
|
+
export { useVehicleSimulation, type UseVehicleSimulationProps, type UseVehicleSimulationResult, type SimulationWarning, type SimulationResult } from './react/hooks/useVehicleSimulation';
|
|
32
|
+
export { useScene, type UseSceneResult } from './react/hooks/useScene';
|
|
33
|
+
export { useVehicles, type UseVehiclesResult, type UseVehiclesProps } from './react/hooks/useVehicles';
|
|
34
|
+
export { useMovementQueue, type UseMovementQueueResult, type UseMovementQueueProps } from './react/hooks/useMovementQueue';
|
|
35
|
+
export { useAnimation, type UseAnimationProps } from './react/hooks/useAnimation';
|
|
36
|
+
/** @deprecated Use useMovementQueue instead */
|
|
37
|
+
export { useMovementQueue as useMovement } from './react/hooks/useMovementQueue';
|
|
38
|
+
export type { UseMovementQueueResult as UseMovementResult } from './react/hooks/useMovementQueue';
|
|
39
|
+
export type { UseMovementQueueProps as UseMovementProps } from './react/hooks/useMovementQueue';
|
|
40
|
+
/** @deprecated Use useAnimation instead */
|
|
41
|
+
export { useAnimation as useVehicleMovement } from './react/hooks/useAnimation';
|
|
42
|
+
export { useSceneDefinition } from './react/dsl-hooks/useSceneDefinition';
|
|
43
|
+
export { useInitialMovement } from './react/dsl-hooks/useInitialMovement';
|
|
44
|
+
export { useMovementSequence } from './react/dsl-hooks/useMovementSequence';
|
|
45
|
+
export { useVehicleEventEmitter, useCreateVehicleEventEmitter, useVehicleEvent, VehicleEventContext, VehicleEventProvider, type VehicleEventProviderProps } from './react/providers/useVehicleEvents';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Line } from '../../core/types/geometry';
|
|
2
|
+
interface UseInitialMovementProps {
|
|
3
|
+
lines: Line[];
|
|
4
|
+
wheelbase: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* DSL wrapper for useVehicles hook.
|
|
8
|
+
*
|
|
9
|
+
* This hook provides text-based vehicle initialization that internally uses
|
|
10
|
+
* the programmatic useVehicles API as the single source of truth.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated Use `useVehicleSimulation.loadFromDSL()` instead. This hook will be removed in a future version.
|
|
13
|
+
* The new unified hook provides a simpler API for loading DSL definitions that includes
|
|
14
|
+
* scene, vehicles, and movements in a single call.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useInitialMovement({ lines, wheelbase }: UseInitialMovementProps): {
|
|
17
|
+
vehicles: import("../..").Vehicle[];
|
|
18
|
+
initialMovementText: string;
|
|
19
|
+
movementError: string | null;
|
|
20
|
+
isDebouncing: boolean;
|
|
21
|
+
debounceKey: number;
|
|
22
|
+
setInitialMovementText: (text: string) => void;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Line } from '../../core/types/geometry';
|
|
2
|
+
import type { Vehicle } from '../../core/types/vehicle';
|
|
3
|
+
import { type MovementCommand } from '../../utils/dsl-parser';
|
|
4
|
+
interface UseMovementSequenceProps {
|
|
5
|
+
lines: Line[];
|
|
6
|
+
vehicles: Vehicle[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* DSL wrapper for useMovementQueue hook.
|
|
10
|
+
*
|
|
11
|
+
* This hook provides text-based movement commands that internally uses
|
|
12
|
+
* the programmatic useMovementQueue API as the single source of truth.
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Use `useVehicleSimulation.loadFromDSL()` instead. This hook will be removed in a future version.
|
|
15
|
+
* The new unified hook provides a simpler API for loading DSL definitions that includes
|
|
16
|
+
* scene, vehicles, and movements in a single call.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useMovementSequence({ lines, vehicles }: UseMovementSequenceProps): {
|
|
19
|
+
movementSequenceText: string;
|
|
20
|
+
gotoCommands: MovementCommand[];
|
|
21
|
+
vehicleQueues: Map<string, import("../..").GotoCommand[]>;
|
|
22
|
+
sequenceError: string | null;
|
|
23
|
+
isDebouncing: boolean;
|
|
24
|
+
debounceKey: number;
|
|
25
|
+
setMovementSequenceText: (text: string) => void;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Line, Curve } from '../../core/types/geometry';
|
|
2
|
+
/**
|
|
3
|
+
* DSL wrapper for useScene hook.
|
|
4
|
+
*
|
|
5
|
+
* This hook provides text-based scene definition that internally uses
|
|
6
|
+
* the programmatic useScene API as the single source of truth.
|
|
7
|
+
*
|
|
8
|
+
* @deprecated Use `useVehicleSimulation.loadFromDSL()` instead. This hook will be removed in a future version.
|
|
9
|
+
* The new unified hook provides a simpler API for loading DSL definitions that includes
|
|
10
|
+
* scene, vehicles, and movements in a single call.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useSceneDefinition(): {
|
|
13
|
+
lines: Line[];
|
|
14
|
+
curves: Curve[];
|
|
15
|
+
sceneDefinitionText: string;
|
|
16
|
+
sceneError: string | null;
|
|
17
|
+
isDebouncing: boolean;
|
|
18
|
+
debounceKey: number;
|
|
19
|
+
setLines: (newLines: Line[] | ((prev: Line[]) => Line[])) => void;
|
|
20
|
+
setCurves: (newCurves: Curve[] | ((prev: Curve[]) => Curve[])) => void;
|
|
21
|
+
setSceneDefinitionText: (text: string) => void;
|
|
22
|
+
};
|