@operato/scene-visualizer 9.2.2 → 10.0.0-beta.2

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 (204) hide show
  1. package/dist/carrier.d.ts +263 -0
  2. package/dist/carrier.js +272 -0
  3. package/dist/carrier.js.map +1 -0
  4. package/dist/desk.d.ts +238 -3
  5. package/dist/desk.js +1 -2
  6. package/dist/desk.js.map +1 -1
  7. package/dist/editors/index.d.ts +1 -0
  8. package/dist/editors/index.js +5 -0
  9. package/dist/editors/index.js.map +1 -1
  10. package/dist/editors/property-editor-gltf-fill-targets.d.ts +17 -0
  11. package/dist/editors/property-editor-gltf-fill-targets.js +211 -0
  12. package/dist/editors/property-editor-gltf-fill-targets.js.map +1 -0
  13. package/dist/editors/property-editor-gltf-info.js +38 -29
  14. package/dist/editors/property-editor-gltf-info.js.map +1 -1
  15. package/dist/editors/property-editor-location-increase-pattern.js +91 -95
  16. package/dist/editors/property-editor-location-increase-pattern.js.map +1 -1
  17. package/dist/effects/outline.js +1 -1
  18. package/dist/effects/outline.js.map +1 -1
  19. package/dist/index.d.ts +5 -17
  20. package/dist/index.js +7 -17
  21. package/dist/index.js.map +1 -1
  22. package/dist/rack-table-3d.d.ts +16 -0
  23. package/dist/rack-table-3d.js +94 -0
  24. package/dist/rack-table-3d.js.map +1 -0
  25. package/dist/rack-table-cell.d.ts +238 -3
  26. package/dist/rack-table-cell.js +44 -51
  27. package/dist/rack-table-cell.js.map +1 -1
  28. package/dist/rack-table-location.d.ts +37 -0
  29. package/dist/rack-table-location.js +227 -0
  30. package/dist/rack-table-location.js.map +1 -0
  31. package/dist/rack-table.d.ts +13 -29
  32. package/dist/rack-table.js +108 -380
  33. package/dist/rack-table.js.map +1 -1
  34. package/dist/rack.d.ts +3 -5
  35. package/dist/rack.js +7 -9
  36. package/dist/rack.js.map +1 -1
  37. package/dist/signal-tower.d.ts +492 -0
  38. package/dist/signal-tower.js +275 -0
  39. package/dist/signal-tower.js.map +1 -0
  40. package/dist/stock.d.ts +22 -10
  41. package/dist/stock.js +87 -81
  42. package/dist/stock.js.map +1 -1
  43. package/dist/tank.d.ts +492 -0
  44. package/dist/tank.js +312 -0
  45. package/dist/tank.js.map +1 -0
  46. package/dist/templates/carrier.d.ts +19 -0
  47. package/dist/templates/carrier.js +20 -0
  48. package/dist/templates/carrier.js.map +1 -0
  49. package/dist/templates/cube.js +1 -1
  50. package/dist/templates/cube.js.map +1 -1
  51. package/dist/templates/cylinder.js +3 -3
  52. package/dist/templates/cylinder.js.map +1 -1
  53. package/dist/templates/index.d.ts +1 -0
  54. package/dist/templates/index.js +9 -1
  55. package/dist/templates/index.js.map +1 -1
  56. package/dist/templates/signal-tower.d.ts +21 -0
  57. package/dist/templates/signal-tower.js +22 -0
  58. package/dist/templates/signal-tower.js.map +1 -0
  59. package/dist/templates/sphere.d.ts +1 -0
  60. package/dist/templates/sphere.js +5 -4
  61. package/dist/templates/sphere.js.map +1 -1
  62. package/dist/templates/tank.d.ts +21 -0
  63. package/dist/templates/tank.js +22 -0
  64. package/dist/templates/tank.js.map +1 -0
  65. package/dist/templates/vehicle.d.ts +19 -0
  66. package/dist/templates/vehicle.js +20 -0
  67. package/dist/templates/vehicle.js.map +1 -0
  68. package/dist/vehicle.d.ts +248 -0
  69. package/dist/vehicle.js +133 -0
  70. package/dist/vehicle.js.map +1 -0
  71. package/dist/visualizer.d.ts +4 -5
  72. package/dist/visualizer.js +15 -28
  73. package/dist/visualizer.js.map +1 -1
  74. package/icons/carrier.png +0 -0
  75. package/icons/signal-tower.png +0 -0
  76. package/icons/tank.png +0 -0
  77. package/icons/vehicle.png +0 -0
  78. package/package.json +16 -18
  79. package/dist/banner.d.ts +0 -15
  80. package/dist/banner.js +0 -76
  81. package/dist/banner.js.map +0 -1
  82. package/dist/camera.d.ts +0 -20
  83. package/dist/camera.js +0 -108
  84. package/dist/camera.js.map +0 -1
  85. package/dist/cube.d.ts +0 -13
  86. package/dist/cube.js +0 -38
  87. package/dist/cube.js.map +0 -1
  88. package/dist/cylinder.d.ts +0 -11
  89. package/dist/cylinder.js +0 -38
  90. package/dist/cylinder.js.map +0 -1
  91. package/dist/ellipse.d.ts +0 -5
  92. package/dist/ellipse.js +0 -22
  93. package/dist/ellipse.js.map +0 -1
  94. package/dist/gltf-object.d.ts +0 -20
  95. package/dist/gltf-object.js +0 -104
  96. package/dist/gltf-object.js.map +0 -1
  97. package/dist/html-overlay-element.d.ts +0 -1
  98. package/dist/html-overlay-element.js +0 -12
  99. package/dist/html-overlay-element.js.map +0 -1
  100. package/dist/light.d.ts +0 -15
  101. package/dist/light.js +0 -135
  102. package/dist/light.js.map +0 -1
  103. package/dist/polygon.d.ts +0 -17
  104. package/dist/polygon.js +0 -64
  105. package/dist/polygon.js.map +0 -1
  106. package/dist/rect.d.ts +0 -5
  107. package/dist/rect.js +0 -36
  108. package/dist/rect.js.map +0 -1
  109. package/dist/scene/component.d.ts +0 -1
  110. package/dist/scene/component.js +0 -29
  111. package/dist/scene/component.js.map +0 -1
  112. package/dist/sphere.d.ts +0 -11
  113. package/dist/sphere.js +0 -38
  114. package/dist/sphere.js.map +0 -1
  115. package/dist/sprite.d.ts +0 -9
  116. package/dist/sprite.js +0 -28
  117. package/dist/sprite.js.map +0 -1
  118. package/dist/text.d.ts +0 -1
  119. package/dist/text.js +0 -9
  120. package/dist/text.js.map +0 -1
  121. package/dist/three-container-editor.d.ts +0 -22
  122. package/dist/three-container-editor.js +0 -132
  123. package/dist/three-container-editor.js.map +0 -1
  124. package/dist/three-container.d.ts +0 -85
  125. package/dist/three-container.js +0 -565
  126. package/dist/three-container.js.map +0 -1
  127. package/dist/three-controls.d.ts +0 -11
  128. package/dist/three-controls.js +0 -616
  129. package/dist/three-controls.js.map +0 -1
  130. package/dist/three-layout.d.ts +0 -8
  131. package/dist/three-layout.js +0 -20
  132. package/dist/three-layout.js.map +0 -1
  133. package/dist/three-space.d.ts +0 -85
  134. package/dist/three-space.js +0 -570
  135. package/dist/three-space.js.map +0 -1
  136. package/dist/threed/common.d.ts +0 -22
  137. package/dist/threed/common.js +0 -19
  138. package/dist/threed/common.js.map +0 -1
  139. package/dist/threed/floor/floor.d.ts +0 -3
  140. package/dist/threed/floor/floor.js +0 -51
  141. package/dist/threed/floor/floor.js.map +0 -1
  142. package/dist/threed/html/elements.d.ts +0 -2
  143. package/dist/threed/html/elements.js +0 -21
  144. package/dist/threed/html/elements.js.map +0 -1
  145. package/dist/threed/index.d.ts +0 -15
  146. package/dist/threed/index.js +0 -16
  147. package/dist/threed/index.js.map +0 -1
  148. package/dist/threed/real-object-camera-meshed.d.ts +0 -12
  149. package/dist/threed/real-object-camera-meshed.js +0 -49
  150. package/dist/threed/real-object-camera-meshed.js.map +0 -1
  151. package/dist/threed/real-object-camera.d.ts +0 -9
  152. package/dist/threed/real-object-camera.js +0 -31
  153. package/dist/threed/real-object-camera.js.map +0 -1
  154. package/dist/threed/real-object-dom-element.d.ts +0 -9
  155. package/dist/threed/real-object-dom-element.js +0 -40
  156. package/dist/threed/real-object-dom-element.js.map +0 -1
  157. package/dist/threed/real-object-dummy.d.ts +0 -6
  158. package/dist/threed/real-object-dummy.js +0 -11
  159. package/dist/threed/real-object-dummy.js.map +0 -1
  160. package/dist/threed/real-object-extrude.d.ts +0 -21
  161. package/dist/threed/real-object-extrude.js +0 -173
  162. package/dist/threed/real-object-extrude.js.map +0 -1
  163. package/dist/threed/real-object-gltf.d.ts +0 -16
  164. package/dist/threed/real-object-gltf.js +0 -101
  165. package/dist/threed/real-object-gltf.js.map +0 -1
  166. package/dist/threed/real-object-group.d.ts +0 -5
  167. package/dist/threed/real-object-group.js +0 -11
  168. package/dist/threed/real-object-group.js.map +0 -1
  169. package/dist/threed/real-object-mesh.d.ts +0 -13
  170. package/dist/threed/real-object-mesh.js +0 -75
  171. package/dist/threed/real-object-mesh.js.map +0 -1
  172. package/dist/threed/real-object-plane.d.ts +0 -5
  173. package/dist/threed/real-object-plane.js +0 -22
  174. package/dist/threed/real-object-plane.js.map +0 -1
  175. package/dist/threed/real-object-scene.d.ts +0 -21
  176. package/dist/threed/real-object-scene.js +0 -67
  177. package/dist/threed/real-object-scene.js.map +0 -1
  178. package/dist/threed/real-object-sprite-2d.d.ts +0 -14
  179. package/dist/threed/real-object-sprite-2d.js +0 -45
  180. package/dist/threed/real-object-sprite-2d.js.map +0 -1
  181. package/dist/threed/real-object-sprite.d.ts +0 -11
  182. package/dist/threed/real-object-sprite.js +0 -50
  183. package/dist/threed/real-object-sprite.js.map +0 -1
  184. package/dist/threed/real-object-text.d.ts +0 -15
  185. package/dist/threed/real-object-text.js +0 -64
  186. package/dist/threed/real-object-text.js.map +0 -1
  187. package/dist/threed/real-object.d.ts +0 -64
  188. package/dist/threed/real-object.js +0 -260
  189. package/dist/threed/real-object.js.map +0 -1
  190. package/dist/threed/texture/canvas-texture.d.ts +0 -4
  191. package/dist/threed/texture/canvas-texture.js +0 -49
  192. package/dist/threed/texture/canvas-texture.js.map +0 -1
  193. package/dist/threed/texture/text-texture.d.ts +0 -8
  194. package/dist/threed/texture/text-texture.js +0 -79
  195. package/dist/threed/texture/text-texture.js.map +0 -1
  196. package/dist/threed/three-dimensional-container.d.ts +0 -8
  197. package/dist/threed/three-dimensional-container.js +0 -2
  198. package/dist/threed/three-dimensional-container.js.map +0 -1
  199. package/dist/threed/utils/bound-uv-generator.d.ts +0 -16
  200. package/dist/threed/utils/bound-uv-generator.js +0 -42
  201. package/dist/threed/utils/bound-uv-generator.js.map +0 -1
  202. package/dist/wall.d.ts +0 -13
  203. package/dist/wall.js +0 -45
  204. package/dist/wall.js.map +0 -1
@@ -0,0 +1,275 @@
1
+ /*
2
+ * Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+ import { __decorate } from "tslib";
5
+ import { RealObjectGroup, RectPath, Shape, ValueHolder, sceneComponent } from '@hatiolab/things-scene';
6
+ import * as THREE from 'three';
7
+ import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js';
8
+ const NATURE = {
9
+ mutable: false,
10
+ resizable: true,
11
+ rotatable: true,
12
+ properties: [
13
+ {
14
+ type: 'number',
15
+ label: 'value',
16
+ name: 'value',
17
+ property: 'value'
18
+ },
19
+ {
20
+ type: 'checkbox',
21
+ label: 'blink',
22
+ name: 'blink',
23
+ property: 'blink'
24
+ }
25
+ ],
26
+ help: 'scene/component/signal-tower'
27
+ };
28
+ /* ── 색상 상수 ── */
29
+ const LIGHT_COLORS = {
30
+ red: { on: '#cc0000', off: '#1a0505' },
31
+ yellow: { on: '#cc8800', off: '#1a1400' },
32
+ green: { on: '#00bb00', off: '#051a05' }
33
+ };
34
+ const BODY_COLOR = '#333333';
35
+ const POLE_COLOR = '#888888';
36
+ const RING_COLOR = '#222222';
37
+ /* ── 2D 렌더 ── */
38
+ const BLINK_PERIOD = 500; // ms
39
+ function isBlinkOn() {
40
+ return Math.floor(Date.now() / BLINK_PERIOD) % 2 === 0;
41
+ }
42
+ function renderSignalTower(ctx, x, y, w, h, value, blink) {
43
+ const sep = Math.max(1, h * 0.01);
44
+ const poleH = h * 0.08;
45
+ const lightH = (h - sep * 2 - poleH) / 3;
46
+ const blinkVisible = !blink || isBlinkOn();
47
+ const lights = [
48
+ { color: LIGHT_COLORS.red, on: !!(value & 4) && blinkVisible },
49
+ { color: LIGHT_COLORS.yellow, on: !!(value & 2) && blinkVisible },
50
+ { color: LIGHT_COLORS.green, on: !!(value & 1) && blinkVisible }
51
+ ];
52
+ let cy = y;
53
+ for (let i = 0; i < 3; i++) {
54
+ const light = lights[i];
55
+ // light band — full width
56
+ ctx.fillStyle = light.on ? light.color.on : light.color.off;
57
+ ctx.fillRect(x, cy, w, lightH);
58
+ // ON glow overlay
59
+ if (light.on) {
60
+ const cx = x + w / 2;
61
+ const my = cy + lightH / 2;
62
+ const grad = ctx.createRadialGradient(cx, my, 0, cx, my, w * 0.6);
63
+ grad.addColorStop(0, '#ffffff88');
64
+ grad.addColorStop(1, '#ffffff00');
65
+ ctx.fillStyle = grad;
66
+ ctx.fillRect(x, cy, w, lightH);
67
+ }
68
+ cy += lightH;
69
+ // thin separator between lights
70
+ if (i < 2) {
71
+ ctx.fillStyle = RING_COLOR;
72
+ ctx.fillRect(x, cy, w, sep);
73
+ cy += sep;
74
+ }
75
+ }
76
+ // pole stub
77
+ const poleW = w * 0.3;
78
+ ctx.fillStyle = POLE_COLOR;
79
+ ctx.fillRect(x + (w - poleW) / 2, cy, poleW, poleH);
80
+ }
81
+ /* ── 3D 렌더 ── */
82
+ export class SignalTower3D extends RealObjectGroup {
83
+ _lightMeshes = [];
84
+ build() {
85
+ super.build();
86
+ const { width, height } = this.component.bounds;
87
+ const { depth } = this.component.state;
88
+ const d = depth || width * 5;
89
+ const radius = Math.min(width, height) / 2;
90
+ // 경광등 부분: width 기반 고정 크기
91
+ const lightH = radius * 1.8;
92
+ const ringH = radius * 0.12;
93
+ const capH = radius * 0.25;
94
+ const baseH = radius * 0.15;
95
+ // 경광등 헤드 총 높이 (등3 + 링4 + 캡)
96
+ const headH = lightH * 3 + ringH * 4 + capH;
97
+ // 폴: 전체 depth에서 헤드+베이스를 뺀 나머지
98
+ const poleH = Math.max(radius * 0.5, d - headH - baseH);
99
+ // ── static parts (merged) ──
100
+ const statics = [];
101
+ // base
102
+ const baseGeo = new THREE.CylinderGeometry(radius * 1.4, radius * 1.4, baseH, 24);
103
+ baseGeo.translate(0, baseH / 2, 0);
104
+ statics.push(baseGeo);
105
+ // pole
106
+ const poleGeo = new THREE.CylinderGeometry(radius * 0.25, radius * 0.25, poleH, 12);
107
+ poleGeo.translate(0, baseH + poleH / 2, 0);
108
+ statics.push(poleGeo);
109
+ let y = baseH + poleH;
110
+ // ring between pole and first light
111
+ const ring0Geo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24);
112
+ ring0Geo.translate(0, y + ringH / 2, 0);
113
+ statics.push(ring0Geo);
114
+ y += ringH;
115
+ // rings between lights
116
+ const lightOrder = ['green', 'yellow', 'red'];
117
+ for (let i = 0; i < 3; i++) {
118
+ y += lightH;
119
+ if (i < 2) {
120
+ const rGeo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24);
121
+ rGeo.translate(0, y + ringH / 2, 0);
122
+ statics.push(rGeo);
123
+ y += ringH;
124
+ }
125
+ }
126
+ // cap
127
+ const capGeo = new THREE.CylinderGeometry(radius * 0.5, radius * 1.05, capH, 24);
128
+ capGeo.translate(0, y + capH / 2, 0);
129
+ statics.push(capGeo);
130
+ const mergedGeo = BufferGeometryUtils.mergeGeometries(statics);
131
+ const staticMat = new THREE.MeshStandardMaterial({
132
+ color: BODY_COLOR,
133
+ roughness: 0.6,
134
+ metalness: 0.3
135
+ });
136
+ const staticMesh = new THREE.Mesh(mergedGeo, staticMat);
137
+ staticMesh.castShadow = true;
138
+ this.object3d.add(staticMesh);
139
+ // ── light meshes (individual for emissive control) ──
140
+ this._lightMeshes = [];
141
+ let ly = baseH + poleH + ringH;
142
+ const value = this.component.value;
143
+ const bitMap = [1, 2, 4]; // green, yellow, red
144
+ for (let i = 0; i < 3; i++) {
145
+ const colorKey = lightOrder[i];
146
+ const isOn = !!(value & bitMap[i]);
147
+ const lightGeo = new THREE.CylinderGeometry(radius, radius, lightH, 24);
148
+ const lightMat = new THREE.MeshStandardMaterial({
149
+ color: isOn ? 0x000000 : LIGHT_COLORS[colorKey].off,
150
+ emissive: isOn ? new THREE.Color(LIGHT_COLORS[colorKey].on) : new THREE.Color(0x000000),
151
+ emissiveIntensity: isOn ? 1.0 : 0,
152
+ roughness: isOn ? 0.1 : 0.7,
153
+ metalness: 0.1
154
+ });
155
+ const mesh = new THREE.Mesh(lightGeo, lightMat);
156
+ mesh.position.y = ly + lightH / 2;
157
+ mesh.castShadow = true;
158
+ this.object3d.add(mesh);
159
+ this._lightMeshes.push(mesh);
160
+ ly += lightH + (i < 2 ? ringH : 0);
161
+ }
162
+ // center vertically
163
+ const totalH = baseH + poleH + headH;
164
+ this.object3d.children.forEach(child => {
165
+ child.position.y -= totalH / 2;
166
+ });
167
+ }
168
+ updateLights(forceOff = false) {
169
+ const value = this.component.value;
170
+ const lightOrder = ['green', 'yellow', 'red'];
171
+ const bitMap = [1, 2, 4]; // green, yellow, red
172
+ for (let i = 0; i < this._lightMeshes.length; i++) {
173
+ const mat = this._lightMeshes[i].material;
174
+ const colorKey = lightOrder[i];
175
+ const isOn = !!(value & bitMap[i]) && !forceOff;
176
+ mat.color.set(isOn ? 0x000000 : LIGHT_COLORS[colorKey].off);
177
+ mat.emissive.set(isOn ? LIGHT_COLORS[colorKey].on : 0x000000);
178
+ mat.emissiveIntensity = isOn ? 1.0 : 0;
179
+ mat.roughness = isOn ? 0.1 : 0.7;
180
+ mat.needsUpdate = true;
181
+ }
182
+ }
183
+ blinkTick() {
184
+ this.updateLights(!isBlinkOn());
185
+ }
186
+ update() {
187
+ super.update();
188
+ this.updateLights();
189
+ }
190
+ updateDimension() {
191
+ this.clear();
192
+ this.build();
193
+ }
194
+ onchange(after, before) {
195
+ super.onchange(after, before);
196
+ if ('value' in after) {
197
+ this.updateLights();
198
+ }
199
+ }
200
+ }
201
+ /* ── Component 클래스 ── */
202
+ const MixedShape = ValueHolder(RectPath(Shape));
203
+ let SignalTower = class SignalTower extends MixedShape {
204
+ _blinkRaf = null;
205
+ _lastBlinkOn = false;
206
+ is3dish() {
207
+ return true;
208
+ }
209
+ buildRealObject() {
210
+ return new SignalTower3D(this);
211
+ }
212
+ get nature() {
213
+ return NATURE;
214
+ }
215
+ async ready() {
216
+ await super.ready();
217
+ if (this.getState('blink')) {
218
+ this._startBlink();
219
+ }
220
+ }
221
+ dispose() {
222
+ this._stopBlink();
223
+ super.dispose();
224
+ }
225
+ _startBlink() {
226
+ if (this._blinkRaf)
227
+ return;
228
+ const tick = () => {
229
+ const on = isBlinkOn();
230
+ if (on !== this._lastBlinkOn) {
231
+ this._lastBlinkOn = on;
232
+ this.invalidate();
233
+ if (this._realObject) {
234
+ ;
235
+ this._realObject.blinkTick();
236
+ }
237
+ }
238
+ this._blinkRaf = requestAnimationFrame(tick);
239
+ };
240
+ this._blinkRaf = requestAnimationFrame(tick);
241
+ }
242
+ _stopBlink() {
243
+ if (!this._blinkRaf)
244
+ return;
245
+ cancelAnimationFrame(this._blinkRaf);
246
+ this._blinkRaf = null;
247
+ // 정상 점등 상태로 복원
248
+ this.invalidate();
249
+ if (this._realObject) {
250
+ ;
251
+ this._realObject.updateLights();
252
+ }
253
+ }
254
+ onchange(after, before) {
255
+ super.onchange(after, before);
256
+ if ('value' in after || 'blink' in after) {
257
+ this.invalidate();
258
+ if (this.getState('blink')) {
259
+ this._startBlink();
260
+ }
261
+ else {
262
+ this._stopBlink();
263
+ }
264
+ }
265
+ }
266
+ render(ctx) {
267
+ const { left, top, width, height } = this.bounds;
268
+ renderSignalTower(ctx, left, top, width, height, this.value, !!this.getState('blink'));
269
+ }
270
+ };
271
+ SignalTower = __decorate([
272
+ sceneComponent('signal-tower')
273
+ ], SignalTower);
274
+ export { SignalTower };
275
+ //# sourceMappingURL=signal-tower.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-tower.js","sourceRoot":"","sources":["../src/signal-tower.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport {\n Component,\n ComponentNature,\n RealObjectGroup,\n RealObject,\n RectPath,\n Shape,\n ValueHolder,\n sceneComponent\n} from '@hatiolab/things-scene'\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'value',\n name: 'value',\n property: 'value'\n },\n {\n type: 'checkbox',\n label: 'blink',\n name: 'blink',\n property: 'blink'\n }\n ],\n help: 'scene/component/signal-tower'\n}\n\n/* ── 색상 상수 ── */\nconst LIGHT_COLORS = {\n red: { on: '#cc0000', off: '#1a0505' },\n yellow: { on: '#cc8800', off: '#1a1400' },\n green: { on: '#00bb00', off: '#051a05' }\n} as const\n\nconst BODY_COLOR = '#333333'\nconst POLE_COLOR = '#888888'\nconst RING_COLOR = '#222222'\n\n/* ── 2D 렌더 ── */\n\nconst BLINK_PERIOD = 500 // ms\n\nfunction isBlinkOn() {\n return Math.floor(Date.now() / BLINK_PERIOD) % 2 === 0\n}\n\nfunction renderSignalTower(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, value: number, blink: boolean) {\n const sep = Math.max(1, h * 0.01)\n const poleH = h * 0.08\n const lightH = (h - sep * 2 - poleH) / 3\n\n const blinkVisible = !blink || isBlinkOn()\n const lights = [\n { color: LIGHT_COLORS.red, on: !!(value & 4) && blinkVisible },\n { color: LIGHT_COLORS.yellow, on: !!(value & 2) && blinkVisible },\n { color: LIGHT_COLORS.green, on: !!(value & 1) && blinkVisible }\n ]\n\n let cy = y\n\n for (let i = 0; i < 3; i++) {\n const light = lights[i]\n\n // light band — full width\n ctx.fillStyle = light.on ? light.color.on : light.color.off\n ctx.fillRect(x, cy, w, lightH)\n\n // ON glow overlay\n if (light.on) {\n const cx = x + w / 2\n const my = cy + lightH / 2\n const grad = ctx.createRadialGradient(cx, my, 0, cx, my, w * 0.6)\n grad.addColorStop(0, '#ffffff88')\n grad.addColorStop(1, '#ffffff00')\n ctx.fillStyle = grad\n ctx.fillRect(x, cy, w, lightH)\n }\n\n cy += lightH\n\n // thin separator between lights\n if (i < 2) {\n ctx.fillStyle = RING_COLOR\n ctx.fillRect(x, cy, w, sep)\n cy += sep\n }\n }\n\n // pole stub\n const poleW = w * 0.3\n ctx.fillStyle = POLE_COLOR\n ctx.fillRect(x + (w - poleW) / 2, cy, poleW, poleH)\n}\n\n/* ── 3D 렌더 ── */\n\nexport class SignalTower3D extends RealObjectGroup {\n private _lightMeshes: THREE.Mesh[] = []\n\n build() {\n super.build()\n\n const { width, height } = this.component.bounds\n const { depth } = this.component.state\n const d = depth || width * 5\n\n const radius = Math.min(width, height) / 2\n\n // 경광등 부분: width 기반 고정 크기\n const lightH = radius * 1.8\n const ringH = radius * 0.12\n const capH = radius * 0.25\n const baseH = radius * 0.15\n\n // 경광등 헤드 총 높이 (등3 + 링4 + 캡)\n const headH = lightH * 3 + ringH * 4 + capH\n\n // 폴: 전체 depth에서 헤드+베이스를 뺀 나머지\n const poleH = Math.max(radius * 0.5, d - headH - baseH)\n\n // ── static parts (merged) ──\n const statics: THREE.BufferGeometry[] = []\n\n // base\n const baseGeo = new THREE.CylinderGeometry(radius * 1.4, radius * 1.4, baseH, 24)\n baseGeo.translate(0, baseH / 2, 0)\n statics.push(baseGeo)\n\n // pole\n const poleGeo = new THREE.CylinderGeometry(radius * 0.25, radius * 0.25, poleH, 12)\n poleGeo.translate(0, baseH + poleH / 2, 0)\n statics.push(poleGeo)\n\n let y = baseH + poleH\n\n // ring between pole and first light\n const ring0Geo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24)\n ring0Geo.translate(0, y + ringH / 2, 0)\n statics.push(ring0Geo)\n y += ringH\n\n // rings between lights\n const lightOrder = ['green', 'yellow', 'red'] as const\n for (let i = 0; i < 3; i++) {\n y += lightH\n if (i < 2) {\n const rGeo = new THREE.CylinderGeometry(radius * 1.05, radius * 1.05, ringH, 24)\n rGeo.translate(0, y + ringH / 2, 0)\n statics.push(rGeo)\n y += ringH\n }\n }\n\n // cap\n const capGeo = new THREE.CylinderGeometry(radius * 0.5, radius * 1.05, capH, 24)\n capGeo.translate(0, y + capH / 2, 0)\n statics.push(capGeo)\n\n const mergedGeo = BufferGeometryUtils.mergeGeometries(statics)\n const staticMat = new THREE.MeshStandardMaterial({\n color: BODY_COLOR,\n roughness: 0.6,\n metalness: 0.3\n })\n const staticMesh = new THREE.Mesh(mergedGeo, staticMat)\n staticMesh.castShadow = true\n this.object3d.add(staticMesh)\n\n // ── light meshes (individual for emissive control) ──\n this._lightMeshes = []\n let ly = baseH + poleH + ringH\n const value = (this.component as unknown as SignalTower).value\n const bitMap = [1, 2, 4] // green, yellow, red\n\n for (let i = 0; i < 3; i++) {\n const colorKey = lightOrder[i]\n const isOn = !!(value & bitMap[i])\n\n const lightGeo = new THREE.CylinderGeometry(radius, radius, lightH, 24)\n const lightMat = new THREE.MeshStandardMaterial({\n color: isOn ? 0x000000 : LIGHT_COLORS[colorKey].off,\n emissive: isOn ? new THREE.Color(LIGHT_COLORS[colorKey].on) : new THREE.Color(0x000000),\n emissiveIntensity: isOn ? 1.0 : 0,\n roughness: isOn ? 0.1 : 0.7,\n metalness: 0.1\n })\n\n const mesh = new THREE.Mesh(lightGeo, lightMat)\n mesh.position.y = ly + lightH / 2\n mesh.castShadow = true\n this.object3d.add(mesh)\n this._lightMeshes.push(mesh)\n\n ly += lightH + (i < 2 ? ringH : 0)\n }\n\n // center vertically\n const totalH = baseH + poleH + headH\n this.object3d.children.forEach(child => {\n child.position.y -= totalH / 2\n })\n }\n\n updateLights(forceOff = false) {\n const value = (this.component as unknown as SignalTower).value\n const lightOrder = ['green', 'yellow', 'red'] as const\n const bitMap = [1, 2, 4] // green, yellow, red\n\n for (let i = 0; i < this._lightMeshes.length; i++) {\n const mat = this._lightMeshes[i].material as THREE.MeshStandardMaterial\n const colorKey = lightOrder[i]\n const isOn = !!(value & bitMap[i]) && !forceOff\n\n mat.color.set(isOn ? 0x000000 : LIGHT_COLORS[colorKey].off)\n mat.emissive.set(isOn ? LIGHT_COLORS[colorKey].on : 0x000000)\n mat.emissiveIntensity = isOn ? 1.0 : 0\n mat.roughness = isOn ? 0.1 : 0.7\n mat.needsUpdate = true\n }\n }\n\n blinkTick() {\n this.updateLights(!isBlinkOn())\n }\n\n update() {\n super.update()\n this.updateLights()\n }\n\n updateDimension() {\n this.clear()\n this.build()\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n super.onchange(after, before)\n\n if ('value' in after) {\n this.updateLights()\n }\n }\n}\n\n/* ── Component 클래스 ── */\n\nconst MixedShape = ValueHolder(RectPath(Shape))\n\n@sceneComponent('signal-tower')\nexport class SignalTower extends MixedShape {\n private _blinkRaf: number | null = null\n private _lastBlinkOn: boolean = false\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new SignalTower3D(this as any)\n }\n\n get nature() {\n return NATURE\n }\n\n async ready() {\n await super.ready()\n if (this.getState('blink')) {\n this._startBlink()\n }\n }\n\n dispose() {\n this._stopBlink()\n super.dispose()\n }\n\n private _startBlink() {\n if (this._blinkRaf) return\n\n const tick = () => {\n const on = isBlinkOn()\n if (on !== this._lastBlinkOn) {\n this._lastBlinkOn = on\n this.invalidate()\n if (this._realObject) {\n ;(this._realObject as SignalTower3D).blinkTick()\n }\n }\n this._blinkRaf = requestAnimationFrame(tick)\n }\n\n this._blinkRaf = requestAnimationFrame(tick)\n }\n\n private _stopBlink() {\n if (!this._blinkRaf) return\n cancelAnimationFrame(this._blinkRaf)\n this._blinkRaf = null\n // 정상 점등 상태로 복원\n this.invalidate()\n if (this._realObject) {\n ;(this._realObject as SignalTower3D).updateLights()\n }\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n super.onchange(after, before)\n\n if ('value' in after || 'blink' in after) {\n this.invalidate()\n\n if (this.getState('blink')) {\n this._startBlink()\n } else {\n this._stopBlink()\n }\n }\n }\n\n render(ctx: CanvasRenderingContext2D) {\n const { left, top, width, height } = this.bounds\n\n renderSignalTower(ctx, left, top, width, height, this.value, !!this.getState('blink'))\n }\n\n}\n"]}
package/dist/stock.d.ts CHANGED
@@ -1,18 +1,30 @@
1
- import { Component, Model } from '@hatiolab/things-scene';
1
+ import { Component, RealObject } from '@hatiolab/things-scene';
2
2
  import * as THREE from 'three';
3
- import { RealObject } from './threed/real-object.js';
4
- import { Visualizer } from './visualizer.js';
3
+ /**
4
+ * Stock material/legend 정보를 제공하는 컴포넌트 인터페이스.
5
+ * Visualizer와 RackTable 모두 이를 구현한다.
6
+ */
7
+ export interface StockMaterialProvider {
8
+ _stock_materials: THREE.Material[];
9
+ _default_material?: THREE.Material;
10
+ _empty_material?: THREE.Material;
11
+ legendTarget?: Component;
12
+ hideEmptyStock?: boolean;
13
+ }
5
14
  export declare class Stock extends RealObject<THREE.Mesh> {
6
15
  static defaultMaterial: THREE.MeshStandardMaterial;
16
+ static defaultEmptyMaterial: THREE.MeshStandardMaterial;
7
17
  static stockGeometry: THREE.BoxGeometry;
8
18
  _hideEmptyStock: boolean;
9
- _focused: boolean;
10
- _focusedAt?: number;
11
- model: Model;
12
- constructor(component: Component, model: Model);
13
- protected getObject3dInstance(): THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>;
19
+ model: any;
20
+ constructor(component: Component, model: any);
21
+ protected getObject3dInstance(): THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>;
22
+ /**
23
+ * 가장 가까운 StockMaterialProvider 조상을 찾는다 (RackTable 또는 Visualizer).
24
+ */
25
+ get provider(): StockMaterialProvider | undefined;
26
+ private get _legendStatus();
14
27
  getMaterial(index: number): THREE.Material;
15
- get visualizer(): Visualizer | undefined;
16
28
  get stockMaterials(): THREE.Material[];
17
29
  get userDefineDefaultMaterial(): THREE.Material;
18
30
  get emptyMaterial(): THREE.Material;
@@ -20,7 +32,7 @@ export declare class Stock extends RealObject<THREE.Mesh> {
20
32
  createStock(w: number, h: number, d: number): void;
21
33
  onchangeStockData(data: any): void;
22
34
  onBeforeRender: () => void;
23
- onmouseup(e: MouseEvent, visualizer: Visualizer, callback: (arg: {
35
+ onmouseup(e: MouseEvent, _context: unknown, callback: (arg: {
24
36
  data: any;
25
37
  location: string;
26
38
  }) => void): void;
package/dist/stock.js CHANGED
@@ -1,38 +1,50 @@
1
1
  /*
2
2
  * Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
+ import { RealObject } from '@hatiolab/things-scene';
4
5
  import * as THREE from 'three';
5
- import { RealObject } from './threed/real-object.js';
6
6
  const STOCK_COLOR = '#ccaa76';
7
7
  export class Stock extends RealObject {
8
+ static defaultMaterial = new THREE.MeshStandardMaterial({
9
+ color: STOCK_COLOR,
10
+ side: THREE.FrontSide,
11
+ roughness: 0.7
12
+ });
13
+ static defaultEmptyMaterial = new THREE.MeshStandardMaterial({
14
+ color: STOCK_COLOR,
15
+ opacity: 0.33,
16
+ transparent: true
17
+ });
18
+ static stockGeometry = new THREE.BoxGeometry(1, 1, 1);
19
+ _hideEmptyStock = false;
20
+ model;
8
21
  constructor(component, model) {
9
22
  super(component);
10
- this._hideEmptyStock = false;
11
- this._focused = false;
12
- this.onBeforeRender = () => {
13
- if (this._focused) {
14
- var lastTime = performance.now() - this._focusedAt;
15
- var progress = lastTime / 2000;
16
- this.object3d.rotation.y = 2 * Math.PI * progress;
17
- this.component.invalidate();
18
- }
19
- else if (this._focusedAt) {
20
- delete this._focusedAt;
21
- this.object3d.rotation.y = 0;
22
- this.component.invalidate();
23
- }
24
- };
25
23
  this.model = model;
26
24
  }
27
25
  getObject3dInstance() {
28
26
  return new THREE.Mesh();
29
27
  }
28
+ /**
29
+ * 가장 가까운 StockMaterialProvider 조상을 찾는다 (RackTable 또는 Visualizer).
30
+ */
31
+ get provider() {
32
+ let component = this.component;
33
+ while (component) {
34
+ if ('_stock_materials' in component) {
35
+ return component;
36
+ }
37
+ component = component.parent;
38
+ }
39
+ }
40
+ get _legendStatus() {
41
+ return this.provider?.legendTarget?.getState('status') || undefined;
42
+ }
30
43
  getMaterial(index) {
31
- var visualizer = this.visualizer;
32
- if (!(visualizer && visualizer && visualizer.legendTarget && visualizer.legendTarget.getState('status')))
44
+ const status = this._legendStatus;
45
+ if (!status)
33
46
  return this.userDefineDefaultMaterial;
34
- var stockStatus = visualizer.legendTarget.getState('status');
35
- var range = stockStatus.ranges[index];
47
+ const range = status.ranges?.[index];
36
48
  if (!(range && range.color)) {
37
49
  this.stockMaterials[index] = this.userDefineDefaultMaterial;
38
50
  }
@@ -50,68 +62,57 @@ export class Stock extends RealObject {
50
62
  }
51
63
  return this.stockMaterials[index];
52
64
  }
53
- get visualizer() {
54
- var component = this.component;
55
- while (component) {
56
- if (component.state.type == 'visualizer') {
57
- return component;
58
- }
59
- component = component.parent;
60
- }
61
- }
62
65
  get stockMaterials() {
63
- return this.visualizer._stock_materials;
66
+ return this.provider?._stock_materials ?? [];
64
67
  }
65
68
  get userDefineDefaultMaterial() {
66
- var visualizer = this.visualizer;
67
- if (!visualizer._default_material) {
68
- if (!(visualizer && visualizer && visualizer.legendTarget && visualizer.legendTarget.getState('status')))
69
- return Stock.defaultMaterial;
70
- var stockStatus = visualizer.legendTarget.getState('status');
71
- var defaultColor = stockStatus.defaultColor;
72
- if (!defaultColor)
73
- return Stock.defaultMaterial;
74
- visualizer._default_material = new THREE.MeshStandardMaterial({
75
- color: defaultColor,
76
- side: THREE.FrontSide,
77
- roughness: 0.7
78
- });
79
- var alpha = defaultColor.replace(/^.*,(.+)\)/, '$1');
80
- if (alpha > 0 && alpha < 1) {
81
- visualizer._default_material.opacity = alpha;
82
- visualizer._default_material.transparent = true;
69
+ const p = this.provider;
70
+ if (p) {
71
+ if (!p._default_material) {
72
+ const status = this._legendStatus;
73
+ const defaultColor = status?.defaultColor;
74
+ if (!defaultColor)
75
+ return Stock.defaultMaterial;
76
+ p._default_material = new THREE.MeshStandardMaterial({
77
+ color: defaultColor,
78
+ side: THREE.FrontSide,
79
+ roughness: 0.7
80
+ });
81
+ var alpha = defaultColor.replace(/^.*,(.+)\)/, '$1');
82
+ if (alpha > 0 && alpha < 1) {
83
+ p._default_material.opacity = alpha;
84
+ p._default_material.transparent = true;
85
+ }
83
86
  }
87
+ return p._default_material;
84
88
  }
85
- return visualizer._default_material;
89
+ return Stock.defaultMaterial;
86
90
  }
87
91
  get emptyMaterial() {
88
- var visualizer = this.visualizer;
89
- var defaultColor = STOCK_COLOR;
90
- if (!visualizer._empty_material) {
91
- if (visualizer && visualizer && visualizer.legendTarget && visualizer.legendTarget.getState('status')) {
92
- var stockStatus = visualizer.legendTarget.getState('status');
93
- defaultColor = stockStatus.defaultColor || STOCK_COLOR;
94
- }
95
- visualizer._empty_material = new THREE.MeshStandardMaterial({
96
- color: defaultColor
97
- });
98
- var alpha = Number(defaultColor.replace(/^.*,(.+)\)/, '$1'));
99
- if (alpha > 0 && alpha < 1) {
100
- visualizer._empty_material.opacity = alpha;
101
- visualizer._empty_material.transparent = true;
102
- }
103
- else {
104
- visualizer._empty_material.opacity = 0.33;
105
- visualizer._empty_material.transparent = true;
92
+ const p = this.provider;
93
+ if (p) {
94
+ if (!p._empty_material) {
95
+ const status = this._legendStatus;
96
+ const defaultColor = status?.defaultColor || STOCK_COLOR;
97
+ p._empty_material = new THREE.MeshStandardMaterial({ color: defaultColor });
98
+ var alpha = Number(defaultColor.replace(/^.*,(.+)\)/, '$1'));
99
+ if (alpha > 0 && alpha < 1) {
100
+ p._empty_material.opacity = alpha;
101
+ p._empty_material.transparent = true;
102
+ }
103
+ else {
104
+ p._empty_material.opacity = 0.33;
105
+ p._empty_material.transparent = true;
106
+ }
106
107
  }
108
+ return p._empty_material;
107
109
  }
108
- return visualizer._empty_material;
110
+ return Stock.defaultEmptyMaterial;
109
111
  }
110
112
  build() {
111
113
  super.build();
112
- var visualizer = this.visualizer;
113
114
  var { width, height, depth } = this.model;
114
- this._hideEmptyStock = visualizer && visualizer.model.hideEmptyStock;
115
+ this._hideEmptyStock = !!this.provider?.hideEmptyStock;
115
116
  this.createStock(width, height, depth);
116
117
  }
117
118
  createStock(w, h, d) {
@@ -129,10 +130,9 @@ export class Stock extends RealObject {
129
130
  ...this.object3d.userData,
130
131
  data
131
132
  };
132
- var visualizer = this.visualizer;
133
- if (!(visualizer && visualizer && visualizer.legendTarget && visualizer.legendTarget.getState('status')))
133
+ const stockStatus = this._legendStatus;
134
+ if (!stockStatus)
134
135
  return;
135
- var stockStatus = visualizer.legendTarget.getState('status');
136
136
  var statusField = stockStatus.field;
137
137
  var aggregation = stockStatus.aggregation || 'sum';
138
138
  var ranges = stockStatus.ranges;
@@ -189,8 +189,20 @@ export class Stock extends RealObject {
189
189
  this.object3d.material = this.userDefineDefaultMaterial;
190
190
  }
191
191
  }
192
- onmouseup(e, visualizer, callback) {
193
- var _a;
192
+ onBeforeRender = () => {
193
+ if (this._focused) {
194
+ var lastTime = performance.now() - this._focusedAt;
195
+ var progress = lastTime / 2000;
196
+ this.object3d.rotation.y = 2 * Math.PI * progress;
197
+ this.component.invalidate();
198
+ }
199
+ else if (this._focusedAt) {
200
+ delete this._focusedAt;
201
+ this.object3d.rotation.y = 0;
202
+ this.component.invalidate();
203
+ }
204
+ };
205
+ onmouseup(e, _context, callback) {
194
206
  if (!this.object3d.visible)
195
207
  return;
196
208
  if (!this.object3d.userData || !this.object3d.userData.data)
@@ -208,7 +220,7 @@ export class Stock extends RealObject {
208
220
  if (callback && typeof callback == 'function') {
209
221
  callback({
210
222
  ...this.object3d.userData.data,
211
- color: '#' + ((_a = this.object3d.material.color) === null || _a === void 0 ? void 0 : _a.getHexString())
223
+ color: '#' + this.object3d.material.color?.getHexString()
212
224
  });
213
225
  }
214
226
  }
@@ -221,10 +233,4 @@ export class Stock extends RealObject {
221
233
  updateHidden() { }
222
234
  updateText() { }
223
235
  }
224
- Stock.defaultMaterial = new THREE.MeshStandardMaterial({
225
- color: STOCK_COLOR,
226
- side: THREE.FrontSide,
227
- roughness: 0.7
228
- });
229
- Stock.stockGeometry = new THREE.BoxGeometry(1, 1, 1);
230
236
  //# sourceMappingURL=stock.js.map