@operato/scene-storage 10.0.0-beta.32 → 10.0.0-beta.34
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/CHANGELOG.md +22 -0
- package/dist/crane-3d.d.ts +14 -0
- package/dist/crane-3d.js +238 -0
- package/dist/crane-3d.js.map +1 -0
- package/dist/crane.d.ts +157 -0
- package/dist/crane.js +440 -0
- package/dist/crane.js.map +1 -0
- package/dist/index.d.ts +13 -6
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/mobile-storage-rack.d.ts +17 -0
- package/dist/mobile-storage-rack.js +55 -0
- package/dist/mobile-storage-rack.js.map +1 -0
- package/dist/rack-column.d.ts +35 -0
- package/dist/rack-column.js +258 -0
- package/dist/rack-column.js.map +1 -0
- package/dist/rack-grid-3d.d.ts +13 -0
- package/dist/rack-grid-3d.js +94 -0
- package/dist/rack-grid-3d.js.map +1 -0
- package/dist/rack-grid-cell.d.ts +341 -0
- package/dist/rack-grid-cell.js +321 -0
- package/dist/rack-grid-cell.js.map +1 -0
- package/dist/rack-grid-helpers.d.ts +28 -0
- package/dist/rack-grid-helpers.js +71 -0
- package/dist/rack-grid-helpers.js.map +1 -0
- package/dist/rack-grid-location.d.ts +37 -0
- package/dist/rack-grid-location.js +227 -0
- package/dist/rack-grid-location.js.map +1 -0
- package/dist/rack-grid.d.ts +80 -0
- package/dist/rack-grid.js +829 -0
- package/dist/rack-grid.js.map +1 -0
- package/dist/stock.d.ts +78 -0
- package/dist/stock.js +333 -0
- package/dist/stock.js.map +1 -0
- package/dist/{rack-cell-3d.d.ts → storage-cell-3d.d.ts} +1 -1
- package/dist/{rack-cell-3d.js → storage-cell-3d.js} +3 -3
- package/dist/storage-cell-3d.js.map +1 -0
- package/dist/{rack-cell.d.ts → storage-cell.d.ts} +12 -6
- package/dist/{rack-cell.js → storage-cell.js} +9 -9
- package/dist/storage-cell.js.map +1 -0
- package/dist/{asrs-rack-3d.d.ts → storage-rack-3d.d.ts} +1 -1
- package/dist/{asrs-rack-3d.js → storage-rack-3d.js} +4 -4
- package/dist/storage-rack-3d.js.map +1 -0
- package/dist/{asrs-rack.d.ts → storage-rack.d.ts} +22 -16
- package/dist/{asrs-rack.js → storage-rack.js} +32 -26
- package/dist/storage-rack.js.map +1 -0
- package/dist/templates/index.d.ts +60 -0
- package/dist/templates/index.js +59 -17
- package/dist/templates/index.js.map +1 -1
- package/package.json +3 -3
- package/src/crane-3d.ts +273 -0
- package/src/crane.ts +538 -0
- package/src/index.ts +13 -6
- package/src/mobile-storage-rack.ts +56 -0
- package/src/rack-column.ts +340 -0
- package/src/rack-grid-3d.ts +128 -0
- package/src/rack-grid-cell.ts +404 -0
- package/src/rack-grid-helpers.ts +77 -0
- package/src/rack-grid-location.ts +286 -0
- package/src/rack-grid.ts +994 -0
- package/src/stock.ts +426 -0
- package/src/{rack-cell-3d.ts → storage-cell-3d.ts} +2 -2
- package/src/{rack-cell.ts → storage-cell.ts} +19 -13
- package/src/{asrs-rack-3d.ts → storage-rack-3d.ts} +3 -3
- package/src/{asrs-rack.ts → storage-rack.ts} +31 -25
- package/src/templates/index.ts +59 -17
- package/test/test-rack-grid-crane.ts +212 -0
- package/test/test-rack-grid.ts +77 -0
- package/test/{test-asrs-crane.ts → test-storage-rack-crane.ts} +8 -8
- package/translations/en.json +55 -7
- package/translations/ja.json +52 -4
- package/translations/ko.json +52 -4
- package/translations/ms.json +55 -7
- package/translations/zh.json +52 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/asrs-crane-3d.d.ts +0 -17
- package/dist/asrs-crane-3d.js +0 -181
- package/dist/asrs-crane-3d.js.map +0 -1
- package/dist/asrs-crane.d.ts +0 -98
- package/dist/asrs-crane.js +0 -216
- package/dist/asrs-crane.js.map +0 -1
- package/dist/asrs-rack-3d.js.map +0 -1
- package/dist/asrs-rack.js.map +0 -1
- package/dist/rack-cell-3d.js.map +0 -1
- package/dist/rack-cell.js.map +0 -1
- package/src/asrs-crane-3d.ts +0 -211
- package/src/asrs-crane.ts +0 -275
- /package/icons/{asrs-crane.png → crane.png} +0 -0
- /package/icons/{asrs-rack.png → storage-rack.png} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobile-storage-rack.js","sourceRoot":"","sources":["../src/mobile-storage-rack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;AAEH,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAErF,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAE3C,OAAO,WAAW,MAAM,mBAAmB,CAAA;AAE3C,4EAA4E;AAC5E,yEAAyE;AACzE,4EAA4E;AAC5E,0DAA0D;AAC1D,qGAAqG;AAEtF,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,KAAK,CAAC,iBAAiB,CAAC,WAAkB,CAAC,CAAC;IAClF;;;OAGG;IACH,IAAI,KAAK;QACP,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;IACtC,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,YAAY,CAAA;IACrB,CAAC;CACF,CAAA;AAjBoB,UAAU;IAD9B,cAAc,CAAC,qBAAqB,CAAC;GACjB,UAAU,CAiB9B;eAjBoB,UAAU;AAmB/B,6EAA6E;AAC7E,0EAA0E;AAC1E,OAAO,EAAE,SAAS,EAAE,CAAA","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * MobileRack — a Rack that can also move.\n *\n * The whole point of the storage abstraction: `Mover(Rack)` mixin gives a\n * *moving storage* without changing Rack's role. Use cases — an AGV-mounted\n * rack, a cart, a tote-on-conveyor, a mobile shelving unit, etc.\n *\n * The cells, the cell-map topology, the Pickable contract, the carrier\n * attach-point — all unchanged. Only thing added: the rack can `moveTo(...)`,\n * `pick(...)`, `place(...)`, `pickAndPlace(...)`.\n *\n * Component type: `mobile-rack`. Use `<mobile-rack levels=...>` on the\n * board same as a Rack; pickers (Crane / Forklift / robot arm) interact\n * with its cells via the same RackCell-side contract.\n *\n * Note: a moving rack is itself a *picker target* from another picker's\n * point of view — the same RackCell.acceptanceRotation contract applies\n * because cells, not racks, are the picker's interlocutor.\n */\n\nimport { Component, ContainerCapacity, sceneComponent } from '@hatiolab/things-scene'\nimport type { SlotDef } from '@hatiolab/things-scene'\nimport { Mover } from '@operato/scene-base'\n\nimport StorageRack from './storage-rack.js'\n\n// `Mover(Rack)` adds moveTo / pick / place / engage. `ContainerCapacity` is\n// also added so the rack itself participates in slot bookkeeping when it\n// behaves as a (mobile) carrier holder during transit. Rack already extends\n// `CarrierHolder + Placeable`, so the full chain becomes:\n// Mover → ContainerCapacity → Rack(=CellContainer → CarrierHolder → Placeable → ContainerAbstract)\n@sceneComponent('mobile-storage-rack')\nexport default class MobileRack extends Mover(ContainerCapacity(StorageRack as any)) {\n /**\n * Mobile racks carry their cells as cargo. The crane that *moves* a\n * MobileRack treats the rack itself as the carrier — one slot, one rack.\n */\n get slots(): SlotDef[] {\n return [{ id: 'self', maxCount: 1 }]\n }\n\n /**\n * The toolType for a fork/clamp that lifts an entire mobile rack.\n * Different from the per-pallet tooling used to extract a carrier from\n * a cell inside the rack.\n */\n get toolType(): string {\n return 'rack-clamp'\n }\n}\n\n// Re-export `Component` import to keep the file self-contained for IDEs that\n// flatten dependency graphs. (Used implicitly by the parent mixin chain.)\nexport { Component }\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { RealObject } from '@hatiolab/things-scene';
|
|
3
|
+
import { Stock } from './stock.js';
|
|
4
|
+
import RackGrid from './rack-grid.js';
|
|
5
|
+
export declare class Rack extends RealObject {
|
|
6
|
+
private _frame?;
|
|
7
|
+
private _board?;
|
|
8
|
+
private _instancedMesh?;
|
|
9
|
+
private _stocks;
|
|
10
|
+
static rackFrameGeometry: THREE.BoxGeometry;
|
|
11
|
+
static boardGeometry: THREE.PlaneGeometry;
|
|
12
|
+
private static _boardMaterial?;
|
|
13
|
+
private static _stockMaterial?;
|
|
14
|
+
get visualizer(): any | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Stock 등록 대상: 1순위 조상 Visualizer(하위호환), 2순위 서비스 레지스트리의 stock-hub
|
|
17
|
+
*/
|
|
18
|
+
get stockRegistry(): {
|
|
19
|
+
putObject(id: string, obj: RealObject): void;
|
|
20
|
+
} | undefined;
|
|
21
|
+
get rackTable(): RackGrid | undefined;
|
|
22
|
+
get cz(): number;
|
|
23
|
+
static get boardMaterial(): THREE.MeshStandardMaterial;
|
|
24
|
+
static get stockMaterial(): THREE.MeshStandardMaterial;
|
|
25
|
+
get frame(): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap> | undefined;
|
|
26
|
+
get board(): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap> | undefined;
|
|
27
|
+
get instancedMesh(): THREE.InstancedMesh<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.Material | THREE.Material[], THREE.InstancedMeshEventMap> | undefined;
|
|
28
|
+
get stocks(): Stock[];
|
|
29
|
+
build(): void;
|
|
30
|
+
createRackFrame(w: number, h: number, d: number): THREE.BufferGeometry;
|
|
31
|
+
createRackBoards(shelves: number, width: number, height: number, depth: number, shelfLocIds: string[]): THREE.BufferGeometry;
|
|
32
|
+
makeLocationString(shelfString: string): string;
|
|
33
|
+
makeShelfString(pattern: string, shelf: number, length: number): string | undefined;
|
|
34
|
+
updateAlpha(): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import * as THREE from 'three';
|
|
5
|
+
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
6
|
+
import { RealObject } from '@hatiolab/things-scene';
|
|
7
|
+
import { Stock } from './stock.js';
|
|
8
|
+
const _color = new THREE.Color();
|
|
9
|
+
const _matrix = new THREE.Matrix4();
|
|
10
|
+
const _position = new THREE.Vector3();
|
|
11
|
+
const _quaternion = new THREE.Quaternion();
|
|
12
|
+
const _scale = new THREE.Vector3();
|
|
13
|
+
export class Rack extends RealObject {
|
|
14
|
+
_frame;
|
|
15
|
+
_board;
|
|
16
|
+
_instancedMesh;
|
|
17
|
+
_stocks = [];
|
|
18
|
+
static rackFrameGeometry = new THREE.BoxGeometry(1, 1, 1);
|
|
19
|
+
static boardGeometry = new THREE.PlaneGeometry(1, 1, 1, 1);
|
|
20
|
+
static _boardMaterial;
|
|
21
|
+
static _stockMaterial;
|
|
22
|
+
get visualizer() {
|
|
23
|
+
var component = this.component;
|
|
24
|
+
while (component) {
|
|
25
|
+
if (component.state.type == 'visualizer') {
|
|
26
|
+
return component;
|
|
27
|
+
}
|
|
28
|
+
component = component.parent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Stock 등록 대상: 1순위 조상 Visualizer(하위호환), 2순위 서비스 레지스트리의 stock-hub
|
|
33
|
+
*/
|
|
34
|
+
get stockRegistry() {
|
|
35
|
+
const vis = this.visualizer;
|
|
36
|
+
if (vis)
|
|
37
|
+
return vis;
|
|
38
|
+
return this.component.root?.getService?.('stock');
|
|
39
|
+
}
|
|
40
|
+
get rackTable() {
|
|
41
|
+
var component = this.component;
|
|
42
|
+
while (component) {
|
|
43
|
+
if (component.state.type == 'rack-grid') {
|
|
44
|
+
return component;
|
|
45
|
+
}
|
|
46
|
+
component = component.parent;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
get cz() {
|
|
50
|
+
var { shelves = 1, depth = 1 } = this.rackTable.state;
|
|
51
|
+
return 0.5 * depth * shelves;
|
|
52
|
+
}
|
|
53
|
+
static get boardMaterial() {
|
|
54
|
+
if (!Rack._boardMaterial) {
|
|
55
|
+
Rack._boardMaterial = new THREE.MeshStandardMaterial({
|
|
56
|
+
color: '#dedede',
|
|
57
|
+
side: THREE.DoubleSide,
|
|
58
|
+
polygonOffset: true,
|
|
59
|
+
polygonOffsetFactor: -0.1
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return Rack._boardMaterial;
|
|
63
|
+
}
|
|
64
|
+
static get stockMaterial() {
|
|
65
|
+
if (!Rack._stockMaterial) {
|
|
66
|
+
Rack._stockMaterial = new THREE.MeshStandardMaterial({
|
|
67
|
+
color: 0xffffff,
|
|
68
|
+
side: THREE.FrontSide,
|
|
69
|
+
metalness: 0,
|
|
70
|
+
roughness: 1,
|
|
71
|
+
envMapIntensity: 0
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return Rack._stockMaterial;
|
|
75
|
+
}
|
|
76
|
+
get frame() {
|
|
77
|
+
return this._frame;
|
|
78
|
+
}
|
|
79
|
+
get board() {
|
|
80
|
+
return this._board;
|
|
81
|
+
}
|
|
82
|
+
get instancedMesh() {
|
|
83
|
+
return this._instancedMesh;
|
|
84
|
+
}
|
|
85
|
+
get stocks() {
|
|
86
|
+
return this._stocks;
|
|
87
|
+
}
|
|
88
|
+
build() {
|
|
89
|
+
super.build();
|
|
90
|
+
var { depth, hideRackFrame, shelves = 1, shelfLocations: commonShelfLocation, stockScale = 0.7 } = this.rackTable.state;
|
|
91
|
+
var { width, height, shelfLocations = commonShelfLocation, binLocations = '' } = this.component.state;
|
|
92
|
+
let scale = stockScale;
|
|
93
|
+
var shelfLocIds;
|
|
94
|
+
if (!shelfLocations) {
|
|
95
|
+
shelfLocIds = [];
|
|
96
|
+
for (var i = 0; i < shelves; i++)
|
|
97
|
+
shelfLocIds.push(i + 1);
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
shelfLocIds = shelfLocations.split(/\s*,\s*/);
|
|
101
|
+
var shelfBins = binLocations.trim().split('\n').reverse();
|
|
102
|
+
if (!hideRackFrame) {
|
|
103
|
+
this._frame = this.createRackFrame(width, height, depth * shelves);
|
|
104
|
+
this._board = this.createRackBoards(shelves, width, height, depth, shelfLocIds);
|
|
105
|
+
}
|
|
106
|
+
// Stock 인스턴스 정보 수집
|
|
107
|
+
const stockEntries = [];
|
|
108
|
+
for (var i = 0; i < shelves; i++) {
|
|
109
|
+
let bottom = -depth * shelves * 0.5;
|
|
110
|
+
if (shelfLocIds[i] == '') {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
var bins = (shelfBins[i] || '').trim().split(/\s*,\s*/);
|
|
114
|
+
var binWidth = width / (bins.length || 1);
|
|
115
|
+
for (var b = 0; b < bins.length; b++) {
|
|
116
|
+
let sw = binWidth * scale;
|
|
117
|
+
let sh = height * scale;
|
|
118
|
+
let sd = depth * scale;
|
|
119
|
+
let stock = new Stock(this.component, { width: sw, height: sh, depth: sd });
|
|
120
|
+
let x = (width / 2) * ((2 * b - (bins.length - 1)) / bins.length);
|
|
121
|
+
let y = bottom + depth * i + sd * 0.5;
|
|
122
|
+
let z = 0;
|
|
123
|
+
var binCode = (bins[b] || '').replace('.', '');
|
|
124
|
+
let name = `${this.makeLocationString(shelfLocIds[i])}${binCode}`;
|
|
125
|
+
stockEntries.push({ stock, x, y, z, w: sw, h: sh, d: sd, name });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// InstancedMesh 생성 (전체 Stock을 1개 draw call로)
|
|
129
|
+
if (stockEntries.length > 0) {
|
|
130
|
+
const instMesh = new THREE.InstancedMesh(Stock.stockGeometry, Rack.stockMaterial, stockEntries.length);
|
|
131
|
+
// instanceColor 초기화
|
|
132
|
+
const defaultColor = new THREE.Color(Stock.defaultMaterial.color);
|
|
133
|
+
for (let idx = 0; idx < stockEntries.length; idx++) {
|
|
134
|
+
const { stock, x, y, z, w, h, d, name } = stockEntries[idx];
|
|
135
|
+
_matrix.compose(_position.set(x, y, z), _quaternion.identity(), _scale.set(w, d, h));
|
|
136
|
+
instMesh.setMatrixAt(idx, _matrix);
|
|
137
|
+
instMesh.setColorAt(idx, defaultColor);
|
|
138
|
+
// Stock에 instanced 참조 설정
|
|
139
|
+
stock._instancedMesh = instMesh;
|
|
140
|
+
stock._instanceIndex = idx;
|
|
141
|
+
stock._basePosition = { x, y, z };
|
|
142
|
+
stock._baseScale = { x: w, y: d, z: h };
|
|
143
|
+
// name 기반 lookup 유지
|
|
144
|
+
this._stocks.push(stock);
|
|
145
|
+
this.stockRegistry?.putObject(name, stock);
|
|
146
|
+
}
|
|
147
|
+
instMesh.instanceMatrix.needsUpdate = true;
|
|
148
|
+
instMesh.instanceColor.needsUpdate = true;
|
|
149
|
+
instMesh.receiveShadow = true;
|
|
150
|
+
// focused stock 회전 애니메이션
|
|
151
|
+
const self = this;
|
|
152
|
+
instMesh.onBeforeRender = () => {
|
|
153
|
+
let needsUpdate = false;
|
|
154
|
+
let hasFocused = false;
|
|
155
|
+
for (const stock of self._stocks) {
|
|
156
|
+
if (stock._focused && stock._focusedAt != null) {
|
|
157
|
+
const elapsed = performance.now() - stock._focusedAt;
|
|
158
|
+
const angle = 2 * Math.PI * (elapsed / 2000);
|
|
159
|
+
_quaternion.setFromAxisAngle(_position.set(0, 1, 0), angle);
|
|
160
|
+
_matrix.compose(_position.set(stock._basePosition.x, stock._basePosition.y, stock._basePosition.z), _quaternion, _scale.set(stock._baseScale.x, stock._baseScale.y, stock._baseScale.z));
|
|
161
|
+
instMesh.setMatrixAt(stock._instanceIndex, _matrix);
|
|
162
|
+
needsUpdate = true;
|
|
163
|
+
hasFocused = true;
|
|
164
|
+
}
|
|
165
|
+
else if (stock._focusedAt != null) {
|
|
166
|
+
delete stock._focusedAt;
|
|
167
|
+
_matrix.compose(_position.set(stock._basePosition.x, stock._basePosition.y, stock._basePosition.z), _quaternion.identity(), _scale.set(stock._baseScale.x, stock._baseScale.y, stock._baseScale.z));
|
|
168
|
+
instMesh.setMatrixAt(stock._instanceIndex, _matrix);
|
|
169
|
+
needsUpdate = true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (needsUpdate) {
|
|
173
|
+
instMesh.instanceMatrix.needsUpdate = true;
|
|
174
|
+
}
|
|
175
|
+
if (hasFocused) {
|
|
176
|
+
self.component.invalidate();
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
this.object3d.add(instMesh);
|
|
180
|
+
this._instancedMesh = instMesh;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
createRackFrame(w, h, d) {
|
|
184
|
+
const frameWeight = Math.round(Math.min(w, h) / 10);
|
|
185
|
+
const geometries = [];
|
|
186
|
+
for (let i = 0; i < 4; i++) {
|
|
187
|
+
const geometry = Rack.rackFrameGeometry.clone();
|
|
188
|
+
geometry.scale(frameWeight, d, frameWeight);
|
|
189
|
+
switch (i) {
|
|
190
|
+
case 0:
|
|
191
|
+
geometry.translate(w / 2, 0, h / 2);
|
|
192
|
+
break;
|
|
193
|
+
case 1:
|
|
194
|
+
geometry.translate(w / 2, 0, -h / 2);
|
|
195
|
+
break;
|
|
196
|
+
case 2:
|
|
197
|
+
geometry.translate(-w / 2, 0, h / 2);
|
|
198
|
+
break;
|
|
199
|
+
case 3:
|
|
200
|
+
geometry.translate(-w / 2, 0, -h / 2);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
geometries.push(geometry);
|
|
204
|
+
}
|
|
205
|
+
return BufferGeometryUtils.mergeGeometries(geometries);
|
|
206
|
+
}
|
|
207
|
+
createRackBoards(shelves, width, height, depth, shelfLocIds) {
|
|
208
|
+
let bottom = -depth * shelves * 0.5;
|
|
209
|
+
const geometries = [];
|
|
210
|
+
for (let i = 1; i < shelves; i++) {
|
|
211
|
+
if (shelfLocIds[i] === '') {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const geometry = Rack.boardGeometry.clone();
|
|
215
|
+
geometry.scale(width, height, 1);
|
|
216
|
+
geometry.rotateX(Math.PI / 2);
|
|
217
|
+
geometry.translate(0, bottom + depth * i, 0);
|
|
218
|
+
geometries.push(geometry);
|
|
219
|
+
}
|
|
220
|
+
return BufferGeometryUtils.mergeGeometries(geometries);
|
|
221
|
+
}
|
|
222
|
+
makeLocationString(shelfString) {
|
|
223
|
+
var { section = '', unit = '' } = this.component.state;
|
|
224
|
+
var { locPattern = '{z}{s}-{u}-{sh}', zone = '' } = this.rackTable.state;
|
|
225
|
+
var locationString = locPattern;
|
|
226
|
+
locationString = locationString.replace(/{z}/i, zone);
|
|
227
|
+
locationString = locationString.replace(/{s}/i, section);
|
|
228
|
+
locationString = locationString.replace(/{u}/i, unit);
|
|
229
|
+
locationString = locationString.replace(/{sh}/i, shelfString);
|
|
230
|
+
return locationString;
|
|
231
|
+
}
|
|
232
|
+
makeShelfString(pattern, shelf, length) {
|
|
233
|
+
/**
|
|
234
|
+
* pattern #: 숫자
|
|
235
|
+
* pattern 0: 고정 자리수
|
|
236
|
+
* pattern -: 역순
|
|
237
|
+
*/
|
|
238
|
+
if (!pattern || !shelf || !length)
|
|
239
|
+
return;
|
|
240
|
+
var isReverse = /^\-/.test(pattern);
|
|
241
|
+
pattern = pattern.replace(/#+/, '#');
|
|
242
|
+
var fixedLength = (pattern.match(/0/g) || []).length || 0;
|
|
243
|
+
var shelfString = String(isReverse ? length - shelf + 1 : shelf);
|
|
244
|
+
if (shelfString.length > fixedLength && fixedLength > 0) {
|
|
245
|
+
shelfString = shelfString.substring(shelfString.length - fixedLength);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
var prefix = '';
|
|
249
|
+
for (var i = 0; i < fixedLength - shelfString.length; i++) {
|
|
250
|
+
prefix += '0';
|
|
251
|
+
}
|
|
252
|
+
shelfString = prefix + shelfString;
|
|
253
|
+
}
|
|
254
|
+
return shelfString;
|
|
255
|
+
}
|
|
256
|
+
updateAlpha() { }
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=rack-column.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rack-column.js","sourceRoot":"","sources":["../src/rack-column.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\n\nimport { RealObject } from '@hatiolab/things-scene'\nimport { Stock } from './stock.js'\nimport RackGrid from './rack-grid.js'\n\n\nconst _color = new THREE.Color()\nconst _matrix = new THREE.Matrix4()\nconst _position = new THREE.Vector3()\nconst _quaternion = new THREE.Quaternion()\nconst _scale = new THREE.Vector3()\n\nexport class Rack extends RealObject {\n private _frame?: THREE.BufferGeometry\n private _board?: THREE.BufferGeometry\n private _instancedMesh?: THREE.InstancedMesh\n private _stocks: Stock[] = []\n\n static rackFrameGeometry = new THREE.BoxGeometry(1, 1, 1)\n static boardGeometry = new THREE.PlaneGeometry(1, 1, 1, 1)\n\n private static _boardMaterial?: THREE.MeshStandardMaterial\n private static _stockMaterial?: THREE.MeshStandardMaterial\n\n get visualizer(): any | undefined {\n var component = this.component\n\n while (component) {\n if (component.state.type == 'visualizer') {\n return component as any\n }\n component = component.parent\n }\n }\n\n /**\n * Stock 등록 대상: 1순위 조상 Visualizer(하위호환), 2순위 서비스 레지스트리의 stock-hub\n */\n get stockRegistry(): { putObject(id: string, obj: RealObject): void } | undefined {\n const vis = this.visualizer\n if (vis) return vis\n return (this.component.root as any)?.getService?.('stock')\n }\n\n get rackTable(): RackGrid | undefined {\n var component = this.component\n\n while (component) {\n if (component.state.type == 'rack-grid') {\n return component as unknown as RackGrid\n }\n component = component.parent\n }\n }\n\n get cz() {\n var { shelves = 1, depth = 1 } = this.rackTable!.state\n\n return 0.5 * depth * shelves\n }\n\n static get boardMaterial() {\n if (!Rack._boardMaterial) {\n Rack._boardMaterial = new THREE.MeshStandardMaterial({\n color: '#dedede',\n side: THREE.DoubleSide,\n polygonOffset: true,\n polygonOffsetFactor: -0.1\n })\n }\n\n return Rack._boardMaterial\n }\n\n static get stockMaterial() {\n if (!Rack._stockMaterial) {\n Rack._stockMaterial = new THREE.MeshStandardMaterial({\n color: 0xffffff,\n side: THREE.FrontSide,\n metalness: 0,\n roughness: 1,\n envMapIntensity: 0\n })\n }\n return Rack._stockMaterial\n }\n\n get frame() {\n return this._frame\n }\n\n get board() {\n return this._board\n }\n\n get instancedMesh() {\n return this._instancedMesh\n }\n\n get stocks() {\n return this._stocks\n }\n\n build() {\n super.build()\n\n var { depth, hideRackFrame, shelves = 1, shelfLocations: commonShelfLocation, stockScale = 0.7 } = this.rackTable!.state\n\n var { width, height, shelfLocations = commonShelfLocation, binLocations = '' } = this.component.state\n\n let scale = stockScale\n\n var shelfLocIds\n\n if (!shelfLocations) {\n shelfLocIds = []\n for (var i = 0; i < shelves; i++) shelfLocIds.push(i + 1)\n } else shelfLocIds = shelfLocations.split(/\\s*,\\s*/)\n\n var shelfBins = binLocations.trim().split('\\n').reverse()\n\n if (!hideRackFrame) {\n this._frame = this.createRackFrame(width, height, depth * shelves)\n this._board = this.createRackBoards(shelves, width, height, depth, shelfLocIds)\n }\n\n // Stock 인스턴스 정보 수집\n const stockEntries: { stock: Stock; x: number; y: number; z: number; w: number; h: number; d: number; name: string }[] = []\n\n for (var i = 0; i < shelves; i++) {\n let bottom = -depth * shelves * 0.5\n if (shelfLocIds[i] == '') {\n continue\n }\n\n var bins = (shelfBins[i] || '').trim().split(/\\s*,\\s*/)\n\n var binWidth = width / (bins.length || 1)\n for (var b = 0; b < bins.length; b++) {\n let sw = binWidth * scale\n let sh = height * scale\n let sd = depth * scale\n\n let stock = new Stock(this.component, { width: sw, height: sh, depth: sd })\n\n let x = (width / 2) * ((2 * b - (bins.length - 1)) / bins.length)\n let y = bottom + depth * i + sd * 0.5\n let z = 0\n\n var binCode = (bins[b] || '').replace('.', '')\n let name = `${this.makeLocationString(shelfLocIds[i])}${binCode}`\n\n stockEntries.push({ stock, x, y, z, w: sw, h: sh, d: sd, name })\n }\n }\n\n // InstancedMesh 생성 (전체 Stock을 1개 draw call로)\n if (stockEntries.length > 0) {\n const instMesh = new THREE.InstancedMesh(\n Stock.stockGeometry,\n Rack.stockMaterial,\n stockEntries.length\n )\n\n // instanceColor 초기화\n const defaultColor = new THREE.Color(Stock.defaultMaterial.color)\n for (let idx = 0; idx < stockEntries.length; idx++) {\n const { stock, x, y, z, w, h, d, name } = stockEntries[idx]\n\n _matrix.compose(\n _position.set(x, y, z),\n _quaternion.identity(),\n _scale.set(w, d, h)\n )\n instMesh.setMatrixAt(idx, _matrix)\n instMesh.setColorAt(idx, defaultColor)\n\n // Stock에 instanced 참조 설정\n stock._instancedMesh = instMesh\n stock._instanceIndex = idx\n stock._basePosition = { x, y, z }\n stock._baseScale = { x: w, y: d, z: h }\n\n // name 기반 lookup 유지\n this._stocks.push(stock)\n this.stockRegistry?.putObject(name, stock)\n }\n\n instMesh.instanceMatrix.needsUpdate = true\n instMesh.instanceColor!.needsUpdate = true\n instMesh.receiveShadow = true\n\n // focused stock 회전 애니메이션\n const self = this\n instMesh.onBeforeRender = () => {\n let needsUpdate = false\n let hasFocused = false\n for (const stock of self._stocks) {\n if (stock._focused && stock._focusedAt != null) {\n const elapsed = performance.now() - stock._focusedAt\n const angle = 2 * Math.PI * (elapsed / 2000)\n _quaternion.setFromAxisAngle(_position.set(0, 1, 0), angle)\n _matrix.compose(\n _position.set(stock._basePosition!.x, stock._basePosition!.y, stock._basePosition!.z),\n _quaternion,\n _scale.set(stock._baseScale!.x, stock._baseScale!.y, stock._baseScale!.z)\n )\n instMesh.setMatrixAt(stock._instanceIndex, _matrix)\n needsUpdate = true\n hasFocused = true\n } else if (stock._focusedAt != null) {\n delete stock._focusedAt\n _matrix.compose(\n _position.set(stock._basePosition!.x, stock._basePosition!.y, stock._basePosition!.z),\n _quaternion.identity(),\n _scale.set(stock._baseScale!.x, stock._baseScale!.y, stock._baseScale!.z)\n )\n instMesh.setMatrixAt(stock._instanceIndex, _matrix)\n needsUpdate = true\n }\n }\n if (needsUpdate) {\n instMesh.instanceMatrix.needsUpdate = true\n }\n if (hasFocused) {\n self.component.invalidate()\n }\n }\n\n this.object3d.add(instMesh)\n this._instancedMesh = instMesh\n }\n }\n\n createRackFrame(w: number, h: number, d: number): THREE.BufferGeometry {\n const frameWeight = Math.round(Math.min(w, h) / 10)\n const geometries = []\n\n for (let i = 0; i < 4; i++) {\n const geometry = Rack.rackFrameGeometry.clone()\n geometry.scale(frameWeight, d, frameWeight)\n\n switch (i) {\n case 0:\n geometry.translate(w / 2, 0, h / 2)\n break\n case 1:\n geometry.translate(w / 2, 0, -h / 2)\n break\n case 2:\n geometry.translate(-w / 2, 0, h / 2)\n break\n case 3:\n geometry.translate(-w / 2, 0, -h / 2)\n break\n }\n\n geometries.push(geometry)\n }\n\n return BufferGeometryUtils.mergeGeometries(geometries)\n }\n\n createRackBoards(\n shelves: number,\n width: number,\n height: number,\n depth: number,\n shelfLocIds: string[]\n ): THREE.BufferGeometry {\n let bottom = -depth * shelves * 0.5\n const geometries = []\n\n for (let i = 1; i < shelves; i++) {\n if (shelfLocIds[i] === '') {\n continue\n }\n\n const geometry = Rack.boardGeometry.clone()\n\n geometry.scale(width, height, 1)\n geometry.rotateX(Math.PI / 2)\n geometry.translate(0, bottom + depth * i, 0)\n\n geometries.push(geometry)\n }\n\n return BufferGeometryUtils.mergeGeometries(geometries)\n }\n\n makeLocationString(shelfString: string) {\n var { section = '', unit = '' } = this.component.state\n var { locPattern = '{z}{s}-{u}-{sh}', zone = '' } = this.rackTable!.state\n\n var locationString = locPattern\n\n locationString = locationString.replace(/{z}/i, zone)\n locationString = locationString.replace(/{s}/i, section)\n locationString = locationString.replace(/{u}/i, unit)\n locationString = locationString.replace(/{sh}/i, shelfString)\n\n return locationString\n }\n\n makeShelfString(pattern: string, shelf: number, length: number) {\n /**\n * pattern #: 숫자\n * pattern 0: 고정 자리수\n * pattern -: 역순\n */\n\n if (!pattern || !shelf || !length) return\n\n var isReverse = /^\\-/.test(pattern)\n pattern = pattern.replace(/#+/, '#')\n\n var fixedLength = (pattern.match(/0/g) || []).length || 0\n var shelfString = String(isReverse ? length - shelf + 1 : shelf)\n\n if (shelfString.length > fixedLength && fixedLength > 0) {\n shelfString = shelfString.substring(shelfString.length - fixedLength)\n } else {\n var prefix = ''\n for (var i = 0; i < fixedLength - shelfString.length; i++) {\n prefix += '0'\n }\n shelfString = prefix + shelfString\n }\n\n return shelfString\n }\n\n updateAlpha() {}\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RealObjectGroup } from '@hatiolab/things-scene';
|
|
2
|
+
import { Rack } from './rack-column.js';
|
|
3
|
+
export declare class RackGrid3D extends RealObjectGroup {
|
|
4
|
+
private _frameMaterial?;
|
|
5
|
+
build(): void;
|
|
6
|
+
protected get syncZPosOffset(): number;
|
|
7
|
+
get geometricOffsetY(): number;
|
|
8
|
+
private createFrameMaterial;
|
|
9
|
+
createRacks(): void;
|
|
10
|
+
mergeAndAddRackCommonObjects(racks: Rack[]): void;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
updateAlpha(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import * as THREE from 'three';
|
|
5
|
+
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
6
|
+
import { RealObjectGroup } from '@hatiolab/things-scene';
|
|
7
|
+
import { Rack } from './rack-column.js';
|
|
8
|
+
const DEFAULT_FRAME_COLOR = 0x8a8a8a;
|
|
9
|
+
export class RackGrid3D extends RealObjectGroup {
|
|
10
|
+
_frameMaterial;
|
|
11
|
+
build() {
|
|
12
|
+
super.build();
|
|
13
|
+
this.createRacks();
|
|
14
|
+
}
|
|
15
|
+
// bottom origin: object3d가 zPos(바닥)에 위치 (내부 mesh는 center-local 좌표로 쌓임)
|
|
16
|
+
get syncZPosOffset() {
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
get geometricOffsetY() {
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
createFrameMaterial() {
|
|
23
|
+
this._frameMaterial?.dispose();
|
|
24
|
+
const { strokeStyle } = this.component.state;
|
|
25
|
+
const color = strokeStyle && typeof strokeStyle === 'string' ? strokeStyle : DEFAULT_FRAME_COLOR;
|
|
26
|
+
this._frameMaterial = new THREE.MeshStandardMaterial({
|
|
27
|
+
color,
|
|
28
|
+
roughness: 0.35,
|
|
29
|
+
metalness: 0.85
|
|
30
|
+
});
|
|
31
|
+
return this._frameMaterial;
|
|
32
|
+
}
|
|
33
|
+
createRacks() {
|
|
34
|
+
const { rotation = 0, shelfLocations, shelves = 1 } = this.component.state;
|
|
35
|
+
this.object3d.rotation.y = -rotation;
|
|
36
|
+
const racks = this.component.components
|
|
37
|
+
.map((cell) => {
|
|
38
|
+
const { shelfLocations: shelfLoc = shelfLocations, isEmpty } = cell.state;
|
|
39
|
+
if (!isEmpty) {
|
|
40
|
+
cell.setState('shelfLocations', shelfLoc);
|
|
41
|
+
const rack = new Rack(cell);
|
|
42
|
+
cell._realObject = rack; // 중복 생성 방지: addObject 재귀에서 skip
|
|
43
|
+
rack.update();
|
|
44
|
+
this.object3d.add(rack.object3d);
|
|
45
|
+
return rack;
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
})
|
|
49
|
+
.filter((rack) => !!rack);
|
|
50
|
+
this.mergeAndAddRackCommonObjects(racks);
|
|
51
|
+
}
|
|
52
|
+
mergeAndAddRackCommonObjects(racks) {
|
|
53
|
+
const framesGeometries = [];
|
|
54
|
+
const boardsGeometries = [];
|
|
55
|
+
if (racks.length > 0) {
|
|
56
|
+
racks.forEach(rack => {
|
|
57
|
+
const geometry = rack.frame;
|
|
58
|
+
if (!geometry) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
geometry.translate(rack.position.x, rack.position.y, rack.position.z);
|
|
62
|
+
geometry.scale(rack.scale.x, rack.scale.y, rack.scale.z);
|
|
63
|
+
framesGeometries.push(geometry);
|
|
64
|
+
});
|
|
65
|
+
if (framesGeometries.length > 0) {
|
|
66
|
+
const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(framesGeometries), this.createFrameMaterial());
|
|
67
|
+
this.object3d.add(frameMesh);
|
|
68
|
+
}
|
|
69
|
+
racks.forEach(rack => {
|
|
70
|
+
const geometry = rack.board;
|
|
71
|
+
if (!geometry) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
geometry.translate(rack.position.x, rack.position.y, rack.position.z);
|
|
75
|
+
geometry.scale(rack.scale.x, rack.scale.y, rack.scale.z);
|
|
76
|
+
boardsGeometries.push(geometry);
|
|
77
|
+
});
|
|
78
|
+
if (boardsGeometries.length > 0) {
|
|
79
|
+
const material = Rack.boardMaterial;
|
|
80
|
+
material.opacity = 0.5;
|
|
81
|
+
material.transparent = true;
|
|
82
|
+
const boardMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(boardsGeometries), material);
|
|
83
|
+
this.object3d.add(boardMesh);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
dispose() {
|
|
88
|
+
this._frameMaterial?.dispose();
|
|
89
|
+
this._frameMaterial = undefined;
|
|
90
|
+
super.dispose();
|
|
91
|
+
}
|
|
92
|
+
updateAlpha() { }
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=rack-grid-3d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rack-grid-3d.js","sourceRoot":"","sources":["../src/rack-grid-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { Component, RealObjectGroup } from '@hatiolab/things-scene'\n\nimport { Rack } from './rack-column.js'\nimport type RackGrid from './rack-grid.js'\n\nconst DEFAULT_FRAME_COLOR = 0x8a8a8a\n\nexport class RackGrid3D extends RealObjectGroup {\n private _frameMaterial?: THREE.MeshStandardMaterial\n\n build() {\n super.build()\n\n this.createRacks()\n }\n\n // bottom origin: object3d가 zPos(바닥)에 위치 (내부 mesh는 center-local 좌표로 쌓임)\n protected get syncZPosOffset(): number {\n return 0\n }\n\n override get geometricOffsetY(): number {\n return 0\n }\n\n private createFrameMaterial(): THREE.MeshStandardMaterial {\n this._frameMaterial?.dispose()\n\n const { strokeStyle } = this.component.state\n const color = strokeStyle && typeof strokeStyle === 'string' ? strokeStyle : DEFAULT_FRAME_COLOR\n\n this._frameMaterial = new THREE.MeshStandardMaterial({\n color,\n roughness: 0.35,\n metalness: 0.85\n })\n\n return this._frameMaterial\n }\n\n createRacks() {\n const { rotation = 0, shelfLocations, shelves = 1 } = this.component.state\n\n this.object3d.rotation.y = -rotation\n\n const racks = (this.component as unknown as RackGrid).components\n .map((cell: Component) => {\n const { shelfLocations: shelfLoc = shelfLocations, isEmpty } = cell.state\n\n if (!isEmpty) {\n cell.setState('shelfLocations', shelfLoc)\n\n const rack = new Rack(cell)\n cell._realObject = rack // 중복 생성 방지: addObject 재귀에서 skip\n\n rack.update()\n this.object3d.add(rack.object3d)\n\n return rack\n }\n return\n })\n .filter((rack: any): rack is Rack => !!rack)\n\n this.mergeAndAddRackCommonObjects(racks)\n }\n\n mergeAndAddRackCommonObjects(racks: Rack[]) {\n const framesGeometries: THREE.BufferGeometry[] = []\n const boardsGeometries: THREE.BufferGeometry[] = []\n\n if (racks.length > 0) {\n racks.forEach(rack => {\n const geometry = rack.frame\n\n if (!geometry) {\n return\n }\n\n geometry.translate(rack.position.x, rack.position.y, rack.position.z)\n geometry.scale(rack.scale.x, rack.scale.y, rack.scale.z)\n framesGeometries.push(geometry)\n })\n\n if (framesGeometries.length > 0) {\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(framesGeometries), this.createFrameMaterial())\n this.object3d.add(frameMesh)\n }\n\n racks.forEach(rack => {\n const geometry = rack.board\n\n if (!geometry) {\n return\n }\n\n geometry.translate(rack.position.x, rack.position.y, rack.position.z)\n geometry.scale(rack.scale.x, rack.scale.y, rack.scale.z)\n boardsGeometries.push(geometry)\n })\n\n if (boardsGeometries.length > 0) {\n const material = Rack.boardMaterial\n material.opacity = 0.5\n material.transparent = true\n\n const boardMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(boardsGeometries), material)\n\n this.object3d.add(boardMesh)\n }\n }\n }\n\n dispose() {\n this._frameMaterial?.dispose()\n this._frameMaterial = undefined\n\n super.dispose()\n }\n\n updateAlpha() {}\n}\n"]}
|