@operato/scene-storage 10.0.0-beta.43 → 10.0.0-beta.46

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/box-3d.d.ts +2 -0
  3. package/dist/box-3d.js +103 -64
  4. package/dist/box-3d.js.map +1 -1
  5. package/dist/crane-3d.d.ts +10 -0
  6. package/dist/crane-3d.js +34 -5
  7. package/dist/crane-3d.js.map +1 -1
  8. package/dist/crane.d.ts +136 -6
  9. package/dist/crane.js +567 -46
  10. package/dist/crane.js.map +1 -1
  11. package/dist/pallet-3d.d.ts +2 -0
  12. package/dist/pallet-3d.js +103 -53
  13. package/dist/pallet-3d.js.map +1 -1
  14. package/dist/parcel-3d.d.ts +1 -0
  15. package/dist/parcel-3d.js +18 -1
  16. package/dist/parcel-3d.js.map +1 -1
  17. package/dist/rack-grid-3d.js +26 -8
  18. package/dist/rack-grid-3d.js.map +1 -1
  19. package/dist/rack-grid.d.ts +94 -10
  20. package/dist/rack-grid.js +468 -86
  21. package/dist/rack-grid.js.map +1 -1
  22. package/dist/storage-rack-3d.js +1 -1
  23. package/dist/storage-rack-3d.js.map +1 -1
  24. package/dist/storage-rack.d.ts +31 -6
  25. package/dist/storage-rack.js +96 -14
  26. package/dist/storage-rack.js.map +1 -1
  27. package/package.json +3 -3
  28. package/src/box-3d.ts +121 -68
  29. package/src/crane-3d.ts +34 -4
  30. package/src/crane.ts +615 -55
  31. package/src/pallet-3d.ts +122 -55
  32. package/src/parcel-3d.ts +19 -1
  33. package/src/rack-grid-3d.ts +31 -8
  34. package/src/rack-grid.ts +488 -82
  35. package/src/storage-rack-3d.ts +1 -1
  36. package/src/storage-rack.ts +96 -14
  37. package/test/test-coord-alignment.ts +2 -2
  38. package/test/test-crane-bay-match.ts +130 -0
  39. package/test/test-crane-binding-resolve.ts +168 -0
  40. package/test/test-crane-duration.ts +90 -0
  41. package/test/test-crane-rotation-reach.ts +218 -0
  42. package/test/test-rack-grid-3d-alignment.ts +235 -0
  43. package/test/test-rack-grid-3d-attach-real.ts +375 -0
  44. package/test/test-rack-grid-cell.ts +2 -2
  45. package/test/test-rack-grid-location.ts +2 -2
  46. package/test/test-rack-grid-occupied-slots.ts +165 -0
  47. package/test/test-rack-grid-picking-position.ts +154 -0
  48. package/test/test-rack-grid-slot-api.ts +483 -0
  49. package/test/test-slot-ids-enumeration.ts +137 -0
  50. package/tsconfig.tsbuildinfo +1 -1
@@ -1,7 +1,7 @@
1
1
  import { Component, ComponentNature, Control, Properties, RealObject } from '@hatiolab/things-scene';
2
2
  import type { State } from '@hatiolab/things-scene';
3
3
  import * as THREE from 'three';
4
- import { SlotTarget, type Alignment, type Heights, type PlacementArchetype, type SlotRecord, type SlottedHolder } from '@operato/scene-base';
4
+ import { SlotTarget, type AttachFrame, type Alignment, type Heights, type PlacementArchetype, type SlotRecord, type SlottedHolder } from '@operato/scene-base';
5
5
  import RackGridCell from './rack-grid-cell.js';
6
6
  /** 한 (col, row) 위치의 메타데이터. 명시되지 않은 위치는 *룰의 기본값* 적용 (= location 없음). */
7
7
  export interface CellOverride {
@@ -150,6 +150,35 @@ export default class RackGrid extends RackGrid_base implements SlottedHolder {
150
150
  * truth, 없으면 cellOverrides[posKey].isEmpty fallback.
151
151
  */
152
152
  isBayEmpty(col: number, row?: number): boolean;
153
+ /**
154
+ * 모든 slot id 의 목록. columns × rackRows × shelves 조합. *isEmpty bay 는 제외*
155
+ * (물리적으로 없는 위치). SlottedHolder.slotIds — capability 기반 enumeration
156
+ * entry point.
157
+ */
158
+ slotIds(): ReadonlyArray<string>;
159
+ /**
160
+ * 점유된 slot 의 id 목록 — state.data record + child *carrier* 둘 다.
161
+ *
162
+ * 중요: RackGridCell (시각 proxy) 의 *state.cellId 는 bayKey ("col-row")
163
+ * 형식* (`_syncChildCellIds` 가 set). slot 의 *full id ("col-row-shelf")* 와
164
+ * 다르다 — RackGridCell 은 *carrier 아닌 시각 proxy* 라 *occupied 카운트
165
+ * 대상 아님*. carriable child (= 실 carrier) 만 sweep.
166
+ *
167
+ * @param filter predicate — 통과하는 slotId 만. sweep 중 즉시 reject.
168
+ */
169
+ occupiedSlotIds(filter?: (slotId: string) => boolean): ReadonlyArray<string>;
170
+ /** 비어있는 slot 의 id 목록 — slotIds() - occupiedSlotIds(). isEmpty bay 자동 제외. */
171
+ emptySlotIds(filter?: (slotId: string) => boolean): ReadonlyArray<string>;
172
+ /**
173
+ * slot 의 *world position* — anchor object3d *생성 없이* 직접 계산. crane 의
174
+ * reach 검사 같은 *match 전 단계* 에서 *anchor 생성 0* 으로 사용 가능.
175
+ * match 후 *실제 attach* 가 필요할 때 `getSlotAttachObject3d` 가 lazy 생성.
176
+ */
177
+ slotWorldPosition(slotId: string): {
178
+ x: number;
179
+ y: number;
180
+ z: number;
181
+ } | undefined;
153
182
  buildRealObject(): RealObject | undefined;
154
183
  get layout(): any;
155
184
  get widths(): number[];
@@ -165,8 +194,8 @@ export default class RackGrid extends RackGrid_base implements SlottedHolder {
165
194
  /** posKey = `${col-1}-${row-1}` (0-based, 2 segments). 1-based input. */
166
195
  posKeyOf(col: number, row?: number): string;
167
196
  /** cellId = `${col-1}-${row-1}-${shelf-1}` (0-based, 3 segments). 1-based input. */
168
- cellIdOf(col: number, row?: number, shelf?: number): string;
169
- parseCellId(cellId: string): {
197
+ slotIdOf(col: number, row?: number, shelf?: number): string;
198
+ parseSlotId(cellId: string): {
170
199
  col: number;
171
200
  row: number;
172
201
  shelf: number;
@@ -220,18 +249,73 @@ export default class RackGrid extends RackGrid_base implements SlottedHolder {
220
249
  * 자식의 grid 위치 식별: 자식의 state.column / state.row (1-based) 명시. RackGrid 가
221
250
  * 자식 추가 시 자동 할당 또는 사용자가 명시.
222
251
  */
223
- private _childRackAt;
224
- hasCarrierAt(slotId: string): boolean;
252
+ /**
253
+ * cellId 매칭되는 RackGrid 의 직접 자식 carrier (operation archetype).
254
+ * RackGrid 의 자식 중 rack-grid-cell (시각 proxy) 외에 obtainCarrier 가 add 한
255
+ * transient carrier 들이 섞임 — 그 중 cellId / placement='operation' 매칭.
256
+ * storage-rack 의 동일 패턴.
257
+ */
258
+ private _carrierChildAt;
259
+ /**
260
+ * state.data 의 internal 갱신 — obtainCarrier / receiveAt 가 사용.
261
+ * setState 와 달리 'change' / onchangeData / mapping cascade 우회 — 사용자 script
262
+ * 의 자기-자신 호출 회귀 차단. 시각 갱신은 직접 RealObject.rebuildStockMesh 호출.
263
+ * storage-rack 의 동일 패턴.
264
+ */
265
+ private _setDataSilently;
266
+ /** state.data record 또는 이미 transient materialize 된 carrier child 가 있는가. */
267
+ hasCarrierAt(slotIdOrLocation: string): boolean;
268
+ /**
269
+ * carrier 를 obtain — 이미 child 면 그대로, 아니면 state.data record 로 transient
270
+ * materialize 후 RackGrid 의 직접 자식으로 add 하고 state.data 에서 그 record 제거.
271
+ * record 도 child 도 없으면 null.
272
+ */
225
273
  obtainCarrier(slotIdOrLocation: string): Component | null;
274
+ /**
275
+ * cell 이 carrier 를 받을 수 있는가.
276
+ * - isEmpty 위치 는 거부 (modeling 차원 location-less)
277
+ * - state.data 에 record 있으면 점유 → false
278
+ * - 자기 자신 carrier 가 child 면 idempotent true (자기 자리 복귀)
279
+ */
226
280
  canReceiveAt(slotIdOrLocation: string, carrier?: Component): boolean;
227
- receiveAt(slotIdOrLocation: string, carrier: Component, options?: any): Promise<void>;
228
- recordFromCarrier(carrier: Component, slotId: string): SlotRecord;
281
+ /**
282
+ * Carrier RackGrid 의 slot 으로 들어옴 — 즉시 dispose + state.data 에 record 로
283
+ * 환원. 결과: stock InstancedMesh 가 그 자리에 instance 표시, RackGrid 의 자식 트리는
284
+ * 깨끗 (rack-grid-cell 만 남음).
285
+ */
286
+ receiveAt(slotIdOrLocation: string, carrier: Component, _options?: any): Promise<void>;
287
+ /**
288
+ * Carrier 의 state 를 state.data record 로 추출. transform/position 관련은 record
289
+ * 와 무관해 skip. (storage-rack 의 동일 패턴.)
290
+ */
291
+ recordFromCarrier(carrier: Component, cellId: string): SlotRecord;
292
+ /**
293
+ * children gate — CarrierHolder.containable 의 *carriable-only* 제한을 완화.
294
+ * RackGrid 의 자식은 두 종류:
295
+ * - RackGridCell : modeling-time visual proxy (carriable 아님)
296
+ * - carrier : Plan A 의 obtainCarrier 가 materialize (carriable)
297
+ * 둘 다 허용해야 정상 동작.
298
+ */
299
+ containable(component: Component): boolean;
300
+ /**
301
+ * Attach frame for direct-child carrier — `applyHolderAttachPoint` 가 이 결과의
302
+ * `attach` 에 carrier obj3d 를 attach 하고 `localPosition` 을 set. cell anchor
303
+ * 반환 + carried placement 와 함께 동작 — carrier 가 cell 위치에 고정.
304
+ */
305
+ attachPointFor(carrier: Component): AttachFrame | null;
229
306
  /**
230
307
  * Slot 의 attach object3d — Stock InstancedMesh 의 instance 와 *같은 world 위치* 에
231
- * 위치한 invisible Object3D. popup tether / Carriable.applyHolderAttachPoint
232
- * object3d 의 matrixWorld 를 사용. lazy 생성 + cache.
308
+ * 위치한 invisible Object3D. popup tether 등이 object3d 의 matrixWorld 를
309
+ * 사용. lazy 생성 + cache.
310
+ */
311
+ private _attachAnchorBySlot;
312
+ /**
313
+ * Anchor position cache 의 signature — rack 의 차원 state 변경 시 무효화 trigger.
314
+ * 동일 signature 인 동안 *anchor.position.set 재계산 skip*. crane 의 첫
315
+ * findAdjacentSlots 가 *수많은 anchor 의 position.set 매 호출* — *동일 차원
316
+ * state 일 때* 의 *중복 계산 차단*.
233
317
  */
234
- private _attachAnchorByCell;
318
+ private _attachAnchorSig?;
235
319
  getSlotAttachObject3d(slotId: string): THREE.Object3D | undefined;
236
320
  getSlotSize(slotId: string): {
237
321
  width: number;