@operato/scene-storage 10.0.0-beta.38 → 10.0.0-beta.41

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 (44) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/box.js +18 -0
  3. package/dist/box.js.map +1 -1
  4. package/dist/crane-3d.d.ts +47 -2
  5. package/dist/crane-3d.js +246 -89
  6. package/dist/crane-3d.js.map +1 -1
  7. package/dist/crane.d.ts +96 -12
  8. package/dist/crane.js +395 -100
  9. package/dist/crane.js.map +1 -1
  10. package/dist/pallet.d.ts +15 -0
  11. package/dist/pallet.js +38 -2
  12. package/dist/pallet.js.map +1 -1
  13. package/dist/parcel-3d.js +22 -18
  14. package/dist/parcel-3d.js.map +1 -1
  15. package/dist/parcel.d.ts +4 -3
  16. package/dist/parcel.js +24 -5
  17. package/dist/parcel.js.map +1 -1
  18. package/dist/storage-cell.d.ts +5 -2
  19. package/dist/storage-cell.js +21 -3
  20. package/dist/storage-cell.js.map +1 -1
  21. package/dist/storage-rack-3d.js +42 -7
  22. package/dist/storage-rack-3d.js.map +1 -1
  23. package/dist/storage-rack.d.ts +26 -2
  24. package/dist/storage-rack.js +92 -10
  25. package/dist/storage-rack.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/box.ts +18 -0
  28. package/src/crane-3d.ts +258 -93
  29. package/src/crane.ts +445 -110
  30. package/src/pallet.ts +50 -1
  31. package/src/parcel-3d.ts +23 -18
  32. package/src/parcel.ts +24 -5
  33. package/src/storage-cell.ts +23 -3
  34. package/src/storage-rack-3d.ts +47 -8
  35. package/src/storage-rack.ts +110 -10
  36. package/test/test-cell-position.ts +105 -0
  37. package/test/test-crane-geometry.ts +167 -0
  38. package/test/test-phase-h-carrier-pickable.ts +4 -3
  39. package/translations/en.json +5 -1
  40. package/translations/ja.json +5 -1
  41. package/translations/ko.json +5 -1
  42. package/translations/ms.json +5 -1
  43. package/translations/zh.json +5 -1
  44. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"crane-3d.js","sourceRoot":"","sources":["../src/crane-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Crane 3D — heavy-duty pallet AS/RS stacker crane (twin-mast).\n *\n * Axis convention (things-scene 3D):\n * +X = aisle 진행 방향 (Crane 좌우 이동, *옆으로 길게* 축)\n * +Y = 수직 (Crane 키, carriage 상하 이동)\n * +Z = aisle 폭 방향 (Rack cell 쪽 / fork 신축 방향)\n *\n * **스케일 룰**:\n * - 모든 가로(X,Z) dimension 과 Y 두께 → 2D footprint (state.width, state.height) 비례\n * - Mast Y 길이만 → state.depth 사용 (수직 키)\n * - Y 두께는 절대 depth (크레인 키) 에 비례 안 함 → 키워도 뭉치 안 두꺼워짐\n * - mm/cm/scene-unit 무관 — 사용자의 footprint 스케일에 자동 맞춤\n *\n * 부품:\n * [Ceiling rail]\n * [Top guide trolley] — 천장 rail 위\n * [Top frame] — 두 mast 상부 연결\n * [Mast L][Mast R] — twin yellow column (X 축으로 떨어져 있음)\n * [Carriage] — 두 mast 사이 가로 frame (carriageHeight 로 상하)\n * └── [Two forks] — carriage 에서 ±Z 신축 (forkExtension)\n * [Base trolley] — 바닥 motor housing (X 길게)\n * └── [Cabinet] — base 한쪽 red 컨트롤박스\n * └── [Status lamp]\n * [Floor rail]\n *\n * Actuators (state):\n * carriageHeight, forkExtension (±), forkLift\n */\n\nimport * as THREE from 'three'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst MAST_COLOR = 0xff7a00 // mast — orange\nconst TROLLEY_COLOR = 0x3a4048 // base / top — dark charcoal\nconst CARRIAGE_COLOR = 0xffcc00 // carriage (shuttle) — yellow\nconst CONTROLLER_COLOR = 0xc63333 // cabinet — red\nconst FORK_COLOR = 0xffcc00 // fork — yellow (same as carriage)\nconst RAIL_COLOR = 0x1a1f24 // rail — dark steel\nconst LAMP_OFF = 0x222222\n\nexport class Crane3D extends RealObjectGroup {\n private _forkGroup?: THREE.Group\n private _forkTopY: number = 0\n private _bladeMidZ: number = 0\n\n build() {\n super.build()\n\n this._forkGroup = undefined\n this._forkTopY = 0\n this._bladeMidZ = 0\n\n const { width, height, depth } = this.component.state\n const emissiveColor = (this.component.state.lampEmissive as string) || '#222222'\n const status = this.component.state.status\n const lampOn = status && status !== 'idle'\n\n // Actuators\n const D = numOr(depth, Math.max(width, height) * 4)\n const carriageRaw = numOr((this.component.state as any).carriageHeight, D * 0.4)\n const carriageHeight = Math.max(0, Math.min(carriageRaw, D * 0.85))\n\n const forkLength = numOr((this.component.state as any).forkLength, height * 0.6)\n const forkExtensionRaw = numOr((this.component.state as any).forkExtension, 0)\n const forkExtension = Math.max(-forkLength, Math.min(forkLength, forkExtensionRaw))\n const forkLift = numOr((this.component.state as any).forkLift, 0)\n\n // ── Axis convention (FIXED): ─────────────────────────────────────\n // Rail = X (state.left = 2D X = 3D X). Crane 좌우 이동.\n // Fork = Z (2D Y = 3D Z). Fork 앞뒤 신축.\n // 사용자: \"포크는 앞뒤로, 크레인 본체는 좌우로.\"\n // width = rail-direction 풋프린트 (좁음)\n // height = cross-aisle (fork 방향) 풋프린트 (깊음, fork 가 cell 까지 닿는 거리)\n const S = Math.min(width, height)\n const railH = S * 0.04\n const baseH = S * 0.18\n const topFrameH = S * 0.1\n const topGuideH = S * 0.1\n const carriageH = S * 0.12\n const mastW = width * 0.1 // mast X 단면 (along rail)\n const mastD = height * 0.25 // mast Z 단면 (cross-rail)\n const mastSpacing = width * 0.7 // 두 mast X 간격\n const bladeW = S * 0.1\n const bladeH = S * 0.05\n const bladeL = forkLength\n const bladeSpacing = mastSpacing * 0.45\n const carriageW = mastSpacing - mastW * 0.2\n const carriageZ = height * 0.55\n const cabW = S * 0.4\n const cabH = S * 0.4\n const cabD = S * 0.3\n\n const baseY = -D / 2\n const mastH = Math.max(D - railH * 2 - baseH - topFrameH - topGuideH, S * 0.5)\n\n // ── Materials ─────────────────────────────────────────────────────\n const mastMat = new THREE.MeshStandardMaterial({ color: MAST_COLOR, metalness: 0.3, roughness: 0.5 })\n const trolleyMat = new THREE.MeshStandardMaterial({ color: TROLLEY_COLOR, metalness: 0.6, roughness: 0.5 })\n const carriageMat = new THREE.MeshStandardMaterial({ color: CARRIAGE_COLOR, metalness: 0.85, roughness: 0.35 })\n const cabinetMat = new THREE.MeshStandardMaterial({ color: CONTROLLER_COLOR, metalness: 0.2, roughness: 0.6 })\n const forkMat = new THREE.MeshStandardMaterial({ color: FORK_COLOR, metalness: 0.85, roughness: 0.3 })\n const railMat = new THREE.MeshStandardMaterial({ color: RAIL_COLOR, metalness: 0.9, roughness: 0.3 })\n\n // ── Floor rail ────────────────────────────────────────────────────\n {\n const geo = new THREE.BoxGeometry(width * 1.1, railH, height * 0.35)\n const mesh = new THREE.Mesh(geo, railMat)\n mesh.position.set(0, baseY + railH / 2, 0)\n mesh.receiveShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Base trolley ──────────────────────────────────────────────────\n const baseTrolleyY = baseY + railH + baseH / 2\n {\n const geo = new THREE.BoxGeometry(width * 0.95, baseH, height * 0.7)\n const mesh = new THREE.Mesh(geo, trolleyMat)\n mesh.position.set(0, baseTrolleyY, 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Control cabinet on one side of base ───────────────────────────\n {\n const geo = new THREE.BoxGeometry(cabW, cabH, cabD)\n const cab = new THREE.Mesh(geo, cabinetMat)\n cab.position.set(\n -width * 0.4 + cabW / 2,\n baseTrolleyY + baseH / 2 + cabH / 2,\n -height * 0.25 + cabD / 2\n )\n cab.castShadow = true\n this.object3d.add(cab)\n }\n\n // ── Status lamp ───────────────────────────────────────────────────\n {\n const lampR = S * 0.04\n const lampH = S * 0.1\n const lampMat = new THREE.MeshStandardMaterial({\n color: lampOn ? emissiveColor : LAMP_OFF,\n emissive: lampOn ? emissiveColor : LAMP_OFF,\n emissiveIntensity: lampOn ? 1.5 : 0.2,\n metalness: 0,\n roughness: 0.3\n })\n const geo = new THREE.CylinderGeometry(lampR, lampR * 0.8, lampH, 12)\n const lamp = new THREE.Mesh(geo, lampMat)\n lamp.position.set(width * 0.4, baseTrolleyY + baseH / 2 + lampH / 2, 0)\n this.object3d.add(lamp)\n }\n\n // ── Twin masts ────────────────────────────────────────────────────\n const mastY = baseTrolleyY + baseH / 2 + mastH / 2\n for (const xOff of [-mastSpacing / 2, +mastSpacing / 2]) {\n const geo = new THREE.BoxGeometry(mastW, mastH, mastD)\n const mesh = new THREE.Mesh(geo, mastMat)\n mesh.position.set(xOff, mastY, 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Carriage + Fork 어셈블리 (forkLift 시 함께 이동) ───────────────\n // 시각 단절 방지를 위해 carriage 와 fork 를 *함께* forkLift 만큼 올림.\n // 의미상으로는 carriageHeight 가 mast 위 carriage 위치, forkLift 가 *그 어셈블리의*\n // 추가 미세 Y. 둘 다 적용된 위치를 carriage / fork 둘 다 공유.\n const carriageY = baseTrolleyY + baseH / 2 + carriageHeight + forkLift + carriageH / 2\n {\n const geo = new THREE.BoxGeometry(carriageW, carriageH, carriageZ)\n const mesh = new THREE.Mesh(geo, carriageMat)\n mesh.position.set(0, carriageY, 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Two-prong forks (양옆 stub + active 신축, 2D 와 동일 모델) ─────\n // ext=0: 양 ±Z 면에 작은 stub. carriage 안에 들어있는 인상 (튀어나옴 없음)\n // ext=±forkLen: active 쪽 stub + |ext| 길이로 신장. 반대쪽 stub 유지.\n // 회전 flip 없음 → ext 가 0 을 지날 때 시각 점프 없음.\n const forkY = carriageY // carriage 중심 Y (embed)\n const stubL = Math.min(carriageZ * 0.2, Math.max(bladeL * 0.05, 6))\n const absExt = Math.abs(forkExtension)\n const sign = forkExtension >= 0 ? 1 : -1\n {\n const group = new THREE.Group()\n group.position.set(0, forkY, 0)\n\n // 양옆 stub — 두 prong × 두 측면 = 4 box\n const stubGeo = new THREE.BoxGeometry(bladeW, bladeH, stubL)\n for (const xOff of [-bladeSpacing / 2, +bladeSpacing / 2]) {\n for (const zSide of [-1, +1]) {\n const mesh = new THREE.Mesh(stubGeo, forkMat)\n mesh.position.set(xOff, 0, zSide * (carriageZ / 2 + stubL / 2))\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n }\n\n // Active side 신장\n if (absExt > 0.5) {\n const extGeo = new THREE.BoxGeometry(bladeW, bladeH, absExt)\n for (const xOff of [-bladeSpacing / 2, +bladeSpacing / 2]) {\n const mesh = new THREE.Mesh(extGeo, forkMat)\n mesh.position.set(xOff, 0, sign * (carriageZ / 2 + stubL + absExt / 2))\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n }\n\n // Pallet — 정지 시 carriage 중심 Z, 신축 시 fork 중간으로 이동.\n const loaded = forkLift > 0 || !!(this.component.state as any).loaded || !!(this.component.state as any).carrying\n if (loaded) {\n const palletMat = new THREE.MeshStandardMaterial({\n color: 0xa08864, metalness: 0.1, roughness: 0.85\n })\n const palletW = bladeSpacing * 1.2\n const palletH = Math.max(bladeH * 2.5, carriageH * 0.5)\n const palletL = Math.max(bladeL * 0.3, carriageZ * 0.6)\n const geo = new THREE.BoxGeometry(palletW, palletH, palletL)\n const pallet = new THREE.Mesh(geo, palletMat)\n const palletZ = absExt < 0.5 ? 0 : sign * (carriageZ / 2 + absExt / 2)\n pallet.position.set(0, carriageH / 2 + palletH / 2, palletZ)\n pallet.castShadow = true\n pallet.receiveShadow = true\n group.add(pallet)\n }\n\n this.object3d.add(group)\n this._forkGroup = group\n this._forkTopY = carriageH / 2\n this._bladeMidZ = absExt < 0.5 ? 0 : sign * (carriageZ / 2 + absExt / 2)\n }\n\n // ── Top frame (connects mast tops) ────────────────────────────────\n const topFrameY = mastY + mastH / 2 + topFrameH / 2\n {\n const geo = new THREE.BoxGeometry(mastSpacing + mastW, topFrameH, height * 0.35)\n const mesh = new THREE.Mesh(geo, trolleyMat)\n mesh.position.set(0, topFrameY, 0)\n mesh.castShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Top guide trolley ─────────────────────────────────────────────\n const topGuideY = topFrameY + topFrameH / 2 + topGuideH / 2\n {\n const geo = new THREE.BoxGeometry(mastSpacing + mastW * 2, topGuideH, height * 0.3)\n const mesh = new THREE.Mesh(geo, trolleyMat)\n mesh.position.set(0, topGuideY, 0)\n mesh.castShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Ceiling rail ──────────────────────────────────────────────────\n {\n const geo = new THREE.BoxGeometry(width * 1.1, railH, height * 0.3)\n const mesh = new THREE.Mesh(geo, railMat)\n mesh.position.set(0, topGuideY + topGuideH / 2 + railH / 2, 0)\n this.object3d.add(mesh)\n }\n }\n\n getCarriageFrame(): THREE.Object3D | undefined {\n return this._forkGroup ?? this.object3d\n }\n\n get platformTopY(): number {\n return this._forkTopY\n }\n\n get bladeMidZ(): number {\n return this._bladeMidZ\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'width' in after ||\n 'height' in after ||\n 'depth' in after ||\n 'carriageHeight' in after ||\n 'forkLength' in after ||\n 'forkExtension' in after ||\n 'forkLift' in after ||\n 'status' in after ||\n 'bodyColor' in after ||\n 'lampEmissive' in after\n ) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n\nfunction numOr(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n"]}
1
+ {"version":3,"file":"crane-3d.js","sourceRoot":"","sources":["../src/crane-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Crane 3D — heavy-duty pallet AS/RS stacker crane (twin-mast).\n *\n * Axis convention (things-scene 3D):\n * +X = aisle 진행 방향 (Crane 좌우 이동, *옆으로 길게* 축)\n * +Y = 수직 (Crane 키, carriage 상하 이동)\n * +Z = aisle 폭 방향 (Rack cell 쪽 / fork 신축 방향)\n *\n * **스케일 룰**:\n * - 모든 가로(X,Z) dimension 과 Y 두께 → 2D footprint (state.width, state.height) 비례\n * - Mast Y 길이만 → state.depth 사용 (수직 키)\n * - Y 두께는 절대 depth (크레인 키) 에 비례 안 함 → 키워도 뭉치 안 두꺼워짐\n * - mm/cm/scene-unit 무관 — 사용자의 footprint 스케일에 자동 맞춤\n *\n * 부품:\n * [Ceiling rail]\n * [Top guide trolley] — 천장 rail 위\n * [Top frame] — 두 mast 상부 연결\n * [Mast L][Mast R] — twin yellow column (X 축으로 떨어져 있음)\n * [Carriage] — 두 mast 사이 가로 frame (carriageHeight 로 상하)\n * └── [Two forks] — carriage 에서 ±Z 신축 (forkExtension)\n * [Base trolley] — 바닥 motor housing (X 길게)\n * └── [Cabinet] — base 한쪽 red 컨트롤박스\n * └── [Status lamp]\n * [Floor rail]\n *\n * Actuators (state):\n * carriageHeight, forkExtension (±), forkLift\n */\n\nimport * as THREE from 'three'\nimport { RealObject, RealObjectGroup } from '@hatiolab/things-scene'\n\nconst MAST_COLOR = 0xff7a00 // mast — orange\nconst TROLLEY_COLOR = 0x3a4048 // base / top — dark charcoal\nconst CARRIAGE_COLOR = 0xffcc00 // carriage (shuttle) — yellow\nconst CONTROLLER_COLOR = 0xc63333 // cabinet — red\nconst FORK_COLOR = 0xffcc00 // fork — yellow (same as carriage)\nconst RAIL_COLOR = 0x1a1f24 // rail — dark steel\nconst LAMP_OFF = 0x222222\n\nexport class Crane3D extends RealObjectGroup {\n private _forkGroup?: THREE.Group\n private _carrierBaseY: number = 0\n private _bladeMidZ: number = 0\n /** floor rail 만 제외한 나머지 (trolley + masts + carriage + fork) 의 movable parent. */\n private _trolleyGroup?: THREE.Group\n /** carriage + fork 의 lift parent (carriageHeight + forkLiftRT 변경 시 Y 만 update). */\n private _carriageLiftGroup?: THREE.Group\n /** Fork active extension mesh — scale.z 와 position.z 로 lerp (rebuild 없이). */\n private _extLeftMesh?: THREE.Mesh\n private _extRightMesh?: THREE.Mesh\n private _extBaseParams?: { bladeSpacing: number; carriageZ: number; stubL: number }\n /** Fork mesh 의 group-local Y center (carriage 위 + bladeH/2). _applyForkExtensionMeshes 가 ext mesh Y 결정. */\n private _forkOffsetY: number = 0\n /** liftGroup.position.y 재계산용 base parameters. */\n private _liftBaseParams?: { baseTrolleyY: number; baseH: number; carriageH: number; bladeH: number }\n\n build() {\n super.build()\n\n this._forkGroup = undefined\n this._carrierBaseY = 0\n this._bladeMidZ = 0\n this._trolleyGroup = undefined\n this._carriageLiftGroup = undefined\n this._extLeftMesh = undefined\n this._extRightMesh = undefined\n this._extBaseParams = undefined\n this._liftBaseParams = undefined\n\n const { width, height, depth } = this.component.state\n const emissiveColor = (this.component.state.lampEmissive as string) || '#222222'\n const status = this.component.state.status\n const lampOn = status && status !== 'idle'\n\n // Actuators\n const D = numOr(depth, Math.max(width, height) * 4)\n const carriageRaw = numOr((this.component.state as any).carriageHeight, (this.component as any)._canonicalDefault?.('carriageHeight') ?? D * 0.4)\n const carriageHeight = Math.max(0, Math.min(carriageRaw, D * 0.85))\n\n const forkLength = numOr((this.component.state as any).forkLength, height * 0.6)\n const forkExtensionRaw = numOr((this.component.state as any).forkExtension, 0)\n const forkExtension = Math.max(-forkLength, Math.min(forkLength, forkExtensionRaw))\n // forkLiftRT — 시뮬 runtime current 들림. state.forkLift 는 *configured 진폭*\n // (사용자 설정) 라 안 건드림. 3D carriage Y 는 runtime 값 사용.\n const forkLift = numOr((this.component.state as any).forkLiftRT, 0)\n\n // ── Axis convention (FIXED): ─────────────────────────────────────\n // Rail = X (state.left = 2D X = 3D X). Crane 좌우 이동.\n // Fork = Z (2D Y = 3D Z). Fork 앞뒤 신축.\n // 사용자: \"포크는 앞뒤로, 크레인 본체는 좌우로.\"\n // width = rail-direction 풋프린트 (좁음)\n // height = cross-aisle (fork 방향) 풋프린트 (깊음, fork 가 cell 까지 닿는 거리)\n const S = Math.min(width, height)\n const railH = S * 0.04\n const baseH = S * 0.18\n const topFrameH = S * 0.1\n const topGuideH = S * 0.1\n const carriageH = S * 0.12\n // Carriage assembly 크기 — state.carriageWidth 기반 (rail 길이 = crane.width\n // 와 독립). 미명시 시 rail 의 10%.\n const carriageAssemblyW = numOr((this.component.state as any).carriageWidth, width * 0.1)\n const mastW = carriageAssemblyW * 0.15 // mast X 단면 (along rail)\n const mastD = height * 0.25 // mast Z 단면 (cross-rail)\n const mastSpacing = carriageAssemblyW * 0.85 // 두 mast X 간격\n const bladeW = S * 0.1\n // bladeH — fork 두께. carriage 보다 얇게 (실 fork prong 의 가는 모양).\n // carriage 와 *같은 Y center (0)* 이고 두께만 carriageH * 0.35.\n const bladeH = carriageH * 0.35\n const bladeL = forkLength\n const bladeSpacing = mastSpacing * 0.45\n const carriageW = mastSpacing - mastW * 0.2\n const carriageZ = height * 0.55\n // Cabinet — 존재감만. 작게.\n const cabW = S * 0.18\n const cabH = S * 0.18\n const cabD = S * 0.15\n\n const baseY = -D / 2\n const mastH = Math.max(D - railH * 2 - baseH - topFrameH - topGuideH, S * 0.5)\n\n // ── Materials ─────────────────────────────────────────────────────\n const mastMat = new THREE.MeshStandardMaterial({ color: MAST_COLOR, metalness: 0.3, roughness: 0.5 })\n const trolleyMat = new THREE.MeshStandardMaterial({ color: TROLLEY_COLOR, metalness: 0.6, roughness: 0.5 })\n const carriageMat = new THREE.MeshStandardMaterial({ color: CARRIAGE_COLOR, metalness: 0.85, roughness: 0.35 })\n const cabinetMat = new THREE.MeshStandardMaterial({ color: CONTROLLER_COLOR, metalness: 0.2, roughness: 0.6 })\n const forkMat = new THREE.MeshStandardMaterial({ color: FORK_COLOR, metalness: 0.85, roughness: 0.3 })\n const railMat = new THREE.MeshStandardMaterial({ color: RAIL_COLOR, metalness: 0.9, roughness: 0.3 })\n\n // ── Floor rail (고정 — crane 본체 안 움직임). 폭 = crane.width (overhang 제거).\n {\n const railThin = railH * 0.5\n const geo = new THREE.BoxGeometry(width, railThin, height * 0.15)\n const mesh = new THREE.Mesh(geo, railMat)\n mesh.position.set(0, baseY + railThin / 2, 0)\n mesh.receiveShadow = true\n this.object3d.add(mesh)\n }\n\n // ── Trolley group — carriage assembly (rail 위 X 만 이동) ─────────\n // 모든 movable 부품 (base trolley, masts, carriage, fork, cabinet, lamp)\n // 의 parent. carriagePosition 변경 시 group 의 local X 만 변경.\n const trolleyGroup = new THREE.Group()\n this._trolleyGroup = trolleyGroup\n this.object3d.add(trolleyGroup)\n // 초기 carriagePosition 적용 — rail-local X (0 ~ width) → object3d-local X (-W/2 ~ +W/2)\n const carriagePos = numOr((this.component.state as any).carriagePosition, (this.component as any)._canonicalDefault?.('carriagePosition') ?? width / 2)\n trolleyGroup.position.x = carriagePos - width / 2\n\n // ── Base trolley ──────────────────────────────────────────────────\n // Cabinet 이 mast 바깥쪽에 자연스럽게 놓이도록 *trolley 폭을 mast + cabinet\n // padding 까지 확장*. carriage assembly width 보다 양 옆으로 (cabW + gap) × 2.\n const trolleyPad = cabW + S * 0.04\n const baseTrolleyW = carriageAssemblyW + trolleyPad * 2\n const baseTrolleyY = baseY + railH + baseH / 2\n {\n const geo = new THREE.BoxGeometry(baseTrolleyW, baseH, height * 0.7)\n const mesh = new THREE.Mesh(geo, trolleyMat)\n mesh.position.set(0, baseTrolleyY, 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n trolleyGroup.add(mesh)\n }\n\n // ── Control cabinet — mast 바깥쪽 (trolley 의 *확장 padding 영역* 위) ─────\n {\n const geo = new THREE.BoxGeometry(cabW, cabH, cabD)\n const cab = new THREE.Mesh(geo, cabinetMat)\n cab.position.set(\n -(carriageAssemblyW / 2 + cabW / 2 + S * 0.02), // mast 왼쪽 바깥\n baseTrolleyY + baseH / 2 + cabH / 2,\n -height * 0.25 + cabD / 2\n )\n cab.castShadow = true\n trolleyGroup.add(cab)\n }\n\n // ── Status lamp ───────────────────────────────────────────────────\n {\n const lampR = S * 0.04\n const lampH = S * 0.1\n const lampMat = new THREE.MeshStandardMaterial({\n color: lampOn ? emissiveColor : LAMP_OFF,\n emissive: lampOn ? emissiveColor : LAMP_OFF,\n emissiveIntensity: lampOn ? 1.5 : 0.2,\n metalness: 0,\n roughness: 0.3\n })\n const geo = new THREE.CylinderGeometry(lampR, lampR * 0.8, lampH, 12)\n const lamp = new THREE.Mesh(geo, lampMat)\n lamp.position.set(carriageAssemblyW / 2 + lampR * 1.5 + S * 0.02, baseTrolleyY + baseH / 2 + lampH / 2, 0)\n trolleyGroup.add(lamp)\n }\n\n // ── Twin masts ────────────────────────────────────────────────────\n const mastY = baseTrolleyY + baseH / 2 + mastH / 2\n for (const xOff of [-mastSpacing / 2, +mastSpacing / 2]) {\n const geo = new THREE.BoxGeometry(mastW, mastH, mastD)\n const mesh = new THREE.Mesh(geo, mastMat)\n mesh.position.set(xOff, mastY, 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n trolleyGroup.add(mesh)\n }\n\n // ── Carriage + Fork lift group (carriageHeight + forkLiftRT 따라 Y 이동) ─\n // _carriageLiftGroup 안에 carriage + forkGroup. forkLiftRT / carriageHeight\n // 변경 시 *그룹 Y 만 update* (mesh rebuild X). _forkGroup 의 child carrier 가\n // *dispose 없이 그대로* 함께 따라 움직임.\n const stubL = Math.min(carriageZ * 0.2, Math.max(bladeL * 0.05, 6))\n const liftGroup = new THREE.Group()\n this._carriageLiftGroup = liftGroup\n this._liftBaseParams = { baseTrolleyY, baseH, carriageH, bladeH }\n liftGroup.position.set(0, this._computeLiftGroupY(carriageHeight, forkLift), 0)\n trolleyGroup.add(liftGroup)\n\n // Carriage — liftGroup local center\n {\n const geo = new THREE.BoxGeometry(carriageW, carriageH, carriageZ)\n const mesh = new THREE.Mesh(geo, carriageMat)\n mesh.position.set(0, 0, 0)\n mesh.castShadow = true\n mesh.receiveShadow = true\n liftGroup.add(mesh)\n }\n\n // ── Two-prong forks ───────────────────────────────────────────────\n // stub (4 box, fixed) + active extension (2 box, scale.z 로 lerp).\n // active mesh 는 *unit-length* 로 생성. _applyForkExtension 이 scale.z 와\n // position.z 로 길이/방향 update — rebuild 없이 매 frame 부드러운 변형.\n const absExt = Math.abs(forkExtension)\n const sign = forkExtension >= 0 ? 1 : -1\n {\n const group = new THREE.Group()\n // _forkGroup 은 liftGroup-local center (0,0,0) — frame 일치 단순화.\n // attach localPosition (carrier 자식) 도 *group-local = liftGroup-local* 동일 frame.\n // Fork mesh 자체가 group-local 안에서 carriage *위* 로 (mesh.position.y).\n group.position.set(0, 0, 0)\n\n // Fork mesh 가 carriage 와 *수평 (같은 Y 평면)* — carriage 안에 embed.\n // fork mesh group-local Y center = 0 (carriage center 와 같음).\n // fork blade *bottom* 면 group-local Y = -bladeH/2.\n // fork blade *top* 면 group-local Y = +bladeH/2.\n const forkOffsetY = 0\n\n // 양옆 stub — 두 prong × 두 측면 = 4 box\n const stubGeo = new THREE.BoxGeometry(bladeW, bladeH, stubL)\n for (const xOff of [-bladeSpacing / 2, +bladeSpacing / 2]) {\n for (const zSide of [-1, +1]) {\n const mesh = new THREE.Mesh(stubGeo, forkMat)\n mesh.position.set(xOff, forkOffsetY, zSide * (carriageZ / 2 + stubL / 2))\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n }\n\n // Active extension — unit length, scale.z + position.z 로 변형\n const extGeo = new THREE.BoxGeometry(bladeW, bladeH, 1)\n const extLeft = new THREE.Mesh(extGeo, forkMat)\n const extRight = new THREE.Mesh(extGeo, forkMat)\n this._forkOffsetY = forkOffsetY\n extLeft.castShadow = true\n extLeft.receiveShadow = true\n extRight.castShadow = true\n extRight.receiveShadow = true\n group.add(extLeft)\n group.add(extRight)\n this._extLeftMesh = extLeft\n this._extRightMesh = extRight\n this._extBaseParams = { bladeSpacing, carriageZ, stubL }\n this._applyForkExtensionMeshes(absExt, sign)\n\n // carrier 의 초기 Z = sign * absExt (= _applyForkExtensionMeshes 의 공식 동일).\n const carrierZ = sign * absExt\n\n liftGroup.add(group)\n this._forkGroup = group\n // Carrier 외부 bottom 정렬점 (liftGroup-local Y) = fork blade *bottom* =\n // -bladeH/2 (fork mesh group-local center = 0, 두께 bladeH).\n // 사용자 모델: \"fork 의 아랫면 ≈ carrier 의 아랫면\" — fork blade 가 carrier\n // 의 bottom 부분 안으로 *찔러 들어감* (겹친 자세).\n this._carrierBaseY = -bladeH / 2\n this._bladeMidZ = carrierZ\n }\n\n // ── Top frame (connects mast tops) — trolley 함께 이동 ─────────────\n const topFrameY = mastY + mastH / 2 + topFrameH / 2\n {\n const geo = new THREE.BoxGeometry(mastSpacing + mastW, topFrameH, height * 0.35)\n const mesh = new THREE.Mesh(geo, trolleyMat)\n mesh.position.set(0, topFrameY, 0)\n mesh.castShadow = true\n trolleyGroup.add(mesh)\n }\n\n // ── Top guide trolley — trolley 함께 이동 (ceiling rail 위 미끄러짐) ─\n const topGuideY = topFrameY + topFrameH / 2 + topGuideH / 2\n {\n const geo = new THREE.BoxGeometry(mastSpacing + mastW * 2, topGuideH, height * 0.3)\n const mesh = new THREE.Mesh(geo, trolleyMat)\n mesh.position.set(0, topGuideY, 0)\n mesh.castShadow = true\n trolleyGroup.add(mesh)\n }\n\n // Ceiling rail 생략 — 상단은 top guide trolley 만으로 충분. 사용자 의도.\n\n }\n\n getCarriageFrame(): THREE.Object3D | undefined {\n // Fallback chain — carrier 가 *carriage transform (X 이동, Y lift)* 따라오도록.\n // _forkGroup 미존재 시 _carriageLiftGroup (X+Y 따라옴) → _trolleyGroup (X 만) →\n // root (no follow). 절대 root 로 떨어지지 않도록 lift/trolley 우선.\n return this._forkGroup ?? this._carriageLiftGroup ?? this._trolleyGroup ?? this.object3d\n }\n\n /**\n * Fork blade *bottom* 의 liftGroup-local Y. *carrier 외부 bottom 정렬점*.\n *\n * 모델: carrier 의 외부 bottom 과 fork blade 의 bottom 이 *거의 일치*. fork 가\n * carrier 의 bottom 부분을 *찔러 들어가* carrier 와 *겹친 자세* (pallet pocket\n * 안 fork 진입). attachPointFor 가 `carrierBaseY + carrier.depth/2` 로 carrier\n * center 를 정렬 → carrier bottom = fork blade bottom.\n */\n get carrierBaseY(): number {\n return this._carrierBaseY\n }\n\n get bladeMidZ(): number {\n return this._bladeMidZ\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n // carriagePosition — trolleyGroup.position.x (mesh-level update).\n if ('carriagePosition' in after && this._trolleyGroup) {\n const W = numOr(this.component.state.width, 100)\n const pos = numOr(after.carriagePosition, W / 2)\n this._trolleyGroup.position.x = pos - W / 2\n }\n\n // Mesh-level updates — fork extension / lift / carriage height. *rebuild 없이*\n // mesh 의 scale / position 만 변경. _forkGroup 의 child carrier 가 dispose\n // 없이 그대로 따라 움직임 (fork 작업 시 시각 자연스러움).\n //\n // status / bodyColor / lampEmissive 는 *cosmetic* — full rebuild 회피. 별도\n // 처리 없음 시 status 변경 시 carrier dispose → 사라짐 결함의 원인. 향후\n // material color 만 update 하는 path 추가 가능.\n const needsFullRebuild =\n 'width' in after ||\n 'height' in after ||\n 'depth' in after ||\n 'forkLength' in after ||\n 'carriageWidth' in after\n\n if (!needsFullRebuild) {\n let meshUpdated = false\n if (('carriageHeight' in after || 'forkLiftRT' in after) && this._carriageLiftGroup) {\n const state = this.component.state as any\n const D = numOr(state.depth, Math.max(numOr(state.width, 100), numOr(state.height, 100)) * 4)\n const carriageRaw = numOr(state.carriageHeight, D * 0.4)\n const carriageHeight = Math.max(0, Math.min(carriageRaw, D * 0.85))\n const forkLift = numOr(state.forkLiftRT, 0)\n this._carriageLiftGroup.position.y = this._computeLiftGroupY(carriageHeight, forkLift)\n meshUpdated = true\n }\n if ('forkExtension' in after && this._extLeftMesh && this._extRightMesh) {\n const state = this.component.state as any\n const forkLength = numOr(state.forkLength, numOr(state.height, 100) * 0.6)\n const forkExtensionRaw = numOr(state.forkExtension, 0)\n const forkExtension = Math.max(-forkLength, Math.min(forkLength, forkExtensionRaw))\n const absExt = Math.abs(forkExtension)\n const sign = forkExtension >= 0 ? 1 : -1\n this._applyForkExtensionMeshes(absExt, sign)\n meshUpdated = true\n }\n if (meshUpdated) return\n }\n\n if (needsFullRebuild) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n /** carriageHeight + forkLiftRT 를 liftGroup.position.y 로 변환. */\n private _computeLiftGroupY(carriageHeight: number, forkLift: number): number {\n const p = this._liftBaseParams\n if (!p) return 0\n return p.baseTrolleyY + p.baseH / 2 + carriageHeight + forkLift + p.carriageH / 2\n }\n\n /**\n * Carrier 외부 bottom 의 world Y → carriageHeight state 값 inverse-solve.\n *\n * Forward 공식 (build):\n * liftGroup.y crane-local = baseTrolleyY + baseH/2 + carriageHeight + forkLift + carriageH/2\n * carrier 외부 bottom crane-local = liftGroup.y + carrierBaseY (= -bladeH/2)\n * = baseTrolleyY + baseH/2 + carriageH/2 - bladeH/2 + carriageHeight + forkLift\n *\n * Inverse:\n * carriageHeight = worldY − craneCenterY − (baseTrolleyY + baseH/2 + carriageH/2 − bladeH/2) − forkLift\n */\n solveCarriageHeightForCarrierBaseWorldY(worldY: number, forkLift: number = 0): number {\n const p = this._liftBaseParams\n if (!p) return 0\n this.object3d.updateWorldMatrix(true, false)\n const v = new THREE.Vector3()\n this.object3d.matrixWorld.decompose(v, new THREE.Quaternion(), new THREE.Vector3())\n const craneCenterWorldY = v.y\n return worldY - craneCenterWorldY - (p.baseTrolleyY + p.baseH / 2 + p.carriageH / 2 - p.bladeH / 2) - forkLift\n }\n\n /**\n * target 의 *crane-local Z* → fork extension 값 inverse-solve.\n *\n * Forward (_applyForkExtensionMeshes): `_bladeMidZ = sign * absExt`\n * (carrier 가 ext 만큼 fork 따라 진출). Inverse: `ext = |localZ|, sign = sign(localZ)`.\n *\n * forkLength 로 clamp — localZ 가 forkLength 보다 멀면 carrier 가 fork tip 까지만.\n */\n solveForkExtensionForLocalZ(localZ: number): number {\n const sign = localZ >= 0 ? 1 : -1\n const state = this.component.state as any\n const forkLen = numOr(state.forkLength, numOr(state.height, 100) * 0.6)\n const clamped = Math.max(0, Math.min(forkLen, Math.abs(localZ)))\n return sign * clamped\n }\n\n /** Fork active extension mesh 의 scale.z + position.z + visibility update. */\n private _applyForkExtensionMeshes(absExt: number, sign: number) {\n if (!this._extLeftMesh || !this._extRightMesh || !this._extBaseParams) return\n const { bladeSpacing, carriageZ, stubL } = this._extBaseParams\n const visible = absExt > 0.5\n const len = Math.max(0.001, absExt)\n const posZ = sign * (carriageZ / 2 + stubL + absExt / 2)\n this._extLeftMesh.scale.z = len\n this._extRightMesh.scale.z = len\n this._extLeftMesh.position.set(-bladeSpacing / 2, this._forkOffsetY, posZ)\n this._extRightMesh.position.set(+bladeSpacing / 2, this._forkOffsetY, posZ)\n this._extLeftMesh.visible = visible\n this._extRightMesh.visible = visible\n\n // _bladeMidZ = carrier 의 Z 위치 = sign * absExt (= fork extension 만큼 직접).\n // ext=0 → 0 (carriage 정중앙 — retract 끝 자세)\n // ext=L → ±L (fork 가 L 만큼 진출한 위치 = carrier 도 그 위치)\n // 단순 linear — solveForkExtensionForLocalZ 의 inverse 도 단순 (ext = |localZ|).\n this._bladeMidZ = sign * absExt\n\n // _forkGroup 의 child carrier 의 Z 도 동기 — fork tip 위치 따라 carrier 가\n // 함께 끌려와야 retract 시각 자연.\n if (this._forkGroup) {\n for (const child of this._forkGroup.children) {\n const ctx = (child as any).userData?.context\n if (ctx && ctx !== this && ctx instanceof RealObject) {\n child.position.z = this._bladeMidZ\n }\n }\n }\n\n }\n\n updateAlpha() {}\n}\n\nfunction numOr(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n"]}
package/dist/crane.d.ts CHANGED
@@ -16,13 +16,6 @@ export type CraneStatus = 'idle' | 'moving' | 'loading' | 'unloading' | 'error';
16
16
  /** Crane 컴포넌트 state */
17
17
  export interface CraneState extends State {
18
18
  status?: CraneStatus;
19
- /**
20
- * Crane 이 서비스 할 타깃 컴포넌트의 refid (또는 id).
21
- * 명시되면 그 컴포넌트 (또는 그 children) 의 위치를 stop point 로 사용 — heuristic
22
- * 으로 sibling 추정 안 함. 미명시면 sibling 안에서 추측.
23
- * 예: RackGrid 의 refid 를 지정하면 그 안의 cell 들 사이에서만 이동.
24
- */
25
- target?: string;
26
19
  /** 마스트 따라 carriage 의 수직 위치 (mm). */
27
20
  carriageHeight?: number;
28
21
  /**
@@ -41,10 +34,37 @@ export interface CraneState extends State {
41
34
  */
42
35
  forkExtension?: number;
43
36
  /**
44
- * Fork *carrier 들어올림 높이* (mm). 0 = neutral (cell shelf 와 같은 면),
45
- * +값 = carrier *위로* 들어올림 (fork pocket 안으로 진입 후 위로 lifting).
37
+ * Fork carrier *cell shelf 에서 분리하기 위해 들어올리는 높이* (mm).
38
+ * 사용자가 board 에서 설정하는 *configured 진폭*. engage lift 단계 target.
39
+ * 미명시 시 default 30mm.
40
+ *
41
+ * Note: 시뮬 *진행 중 current 들림 값* 은 별도 internal transient — `forkLiftRT`
42
+ * state. 3D / 2D render 가 carriage Y 결정 시 그 값을 사용.
46
43
  */
47
44
  forkLift?: number;
45
+ /**
46
+ * Fork lift *runtime current value* (mm). engage 가 시뮬 진행 중 매 frame
47
+ * setState 로 lerp. *사용자가 설정하는 값 아님* — internal transient.
48
+ */
49
+ forkLiftRT?: number;
50
+ /**
51
+ * 자동 random simulate (visual smoke test) 시작 여부.
52
+ * - `undefined` 또는 `false` (default): 자동 시작 안 함. application 이 crane.
53
+ * pickAndPlace 등 직접 제어 시 사용.
54
+ * - `true`: added() 시 자동 시작.
55
+ */
56
+ simulate?: boolean;
57
+ /**
58
+ * Carriage 의 rail-local X 위치 (0 ~ crane.width). Crane.moveTo / simulate 가
59
+ * lerp. crane 본체 (rail) 는 안 움직임 — carriage assembly (masts + carriage +
60
+ * forks) 만 rail 안 X 만 슬라이드.
61
+ */
62
+ carriagePosition?: number;
63
+ /**
64
+ * Carriage 의 폭 (rail-local X 방향). 미명시 시 rail (crane.width) 의 ~10%.
65
+ * Target rack 의 cell 폭과 매칭 권유.
66
+ */
67
+ carriageWidth?: number;
48
68
  material3d?: Material3D;
49
69
  }
50
70
  declare const Crane_base: any;
@@ -88,8 +108,46 @@ export default class Crane extends Crane_base {
88
108
  get toolType(): string;
89
109
  get nature(): ComponentNature;
90
110
  get anchors(): never[];
91
- /** Stacker crane carries at most one load at a time on its forks. */
111
+ /**
112
+ * Stacker crane carries at most one load at a time on its forks.
113
+ *
114
+ * localPosition.z = 0 명시 — ContainerCapacity.receive 의 atomic setState 가
115
+ * `carrier.state.zPos = slot.localPosition.z + parentGeoOffset = 0` 강제.
116
+ * 미명시 시 zPos update skip → carrier 의 *이전 holder 또는 board model 의
117
+ * 임의 zPos (음수 가능)* 그대로 → _realObject 미빌드 시점 (transient placement
118
+ * 미설정 = state-driven) 에 carrier 가 *지하* 로 가는 결함.
119
+ */
92
120
  get slots(): SlotDef[];
121
+ /**
122
+ * Acceptance rotation — carrier 가 crane.fork 에 attach 시 *crane 의 local
123
+ * axis (전방)* 으로 정렬. identity quaternion 반환 → atomic setState 가
124
+ * carrier.state.rotation/X/Y = 0 강제. _realObject 미빌드 시점 (transient
125
+ * placement 미설정 = state-driven) fallback 에서도 자세 정렬.
126
+ *
127
+ * follow-holder carryPolicy 와 짝 — 두 path 모두 동일 결과 (local identity).
128
+ */
129
+ acceptanceRotation(_carrier: Component, _slot?: SlotDef): {
130
+ x: number;
131
+ y: number;
132
+ z: number;
133
+ w: number;
134
+ };
135
+ /**
136
+ * Arrangement — carrier.state.left/top 의 *기준* 이 *crane 전체 footprint* 가
137
+ * 아닌 *carriage X (carriagePosition) + fork Z (bladeMidZ)*. carriage / fork
138
+ * 의 위치가 carrier 의 위치.
139
+ *
140
+ * left = carriagePosition − carrier.w/2 (carriage X 중심)
141
+ * top = crane.h/2 + bladeMidZ − carrier.h/2 (fork Z 중심)
142
+ */
143
+ get arrangementStrategy(): {
144
+ positionAt(_idx: number, _slot: any, _occ: number, component?: any): {
145
+ x: number;
146
+ y: number;
147
+ z: number;
148
+ };
149
+ capacity(slot: any): any;
150
+ };
93
151
  /**
94
152
  * Return the 3D attach frame on the crane's carriage (fork tip).
95
153
  * Carriers are attached here while the crane is in transit (pick phase).
@@ -118,6 +176,17 @@ export default class Crane extends Crane_base {
118
176
  * binding sets 'moving' in monitoring mode; override pick()/place() to
119
177
  * set it in full simulation environments.
120
178
  */
179
+ /**
180
+ * Crane.moveTo — **Crane 본체 (rail) 은 안 움직임**. *내부 carriage 의 rail-
181
+ * local X 위치 (carriagePosition) 만 lerp*. 실제 gantry / AS/RS crane 의
182
+ * 자연스러운 운동 패턴.
183
+ *
184
+ * target.center 의 world 좌표를 *crane 의 local frame (rail-aligned)* 로
185
+ * 변환 → rail-local X 추출 → carriagePosition setState.
186
+ *
187
+ * Crane.state.rotation = rail 방향. carriage 가 rail 위 X 만 이동.
188
+ */
189
+ moveTo(target: Component, options?: MoveOptions): Promise<void>;
121
190
  engage(target: Component, kind: 'pick' | 'place', _options?: MoveOptions): Promise<void>;
122
191
  /** Fetch a carrier from a rack cell (semantically = pick). */
123
192
  fetch(carrier: Component, options?: MoveOptions): Promise<void>;
@@ -141,6 +210,20 @@ export default class Crane extends Crane_base {
141
210
  */
142
211
  render(ctx: CanvasRenderingContext2D): void;
143
212
  added(parent: any): void;
213
+ /**
214
+ * Actuator state 의 *canonical default*. state 미설정 시 모든 read 경로
215
+ * (build / _tween / 외부) 가 *동일 값* 보도록.
216
+ *
217
+ * single source 패턴 — visual fallback 과 state fallback 이 *분리* 되어
218
+ * 첫 _tween 시 start 가 visual current 와 어긋나는 jump 결함을 근본 차단.
219
+ */
220
+ _canonicalDefault(key: string): number;
221
+ private _startAutoSimulate;
222
+ /**
223
+ * state.simulate 변경 시 자동 simulate 시작/중단. application 이 런타임 toggle
224
+ * 가능 (예: editor 에서 simulate off, view 에서 on).
225
+ */
226
+ onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
144
227
  buildRealObject(): RealObject | undefined;
145
228
  private _simStarted;
146
229
  private _simRunning;
@@ -168,8 +251,9 @@ export default class Crane extends Crane_base {
168
251
  dispose(): void;
169
252
  private _oneCycle;
170
253
  /**
171
- * things-scene 의 `component.animate()` 로 한 구간 tween. step 콜백에서 setState 호출.
172
- * frameClock.simTime 기반이라 scene pause / speed change / suppressAnimations 모두 자동 대응.
254
+ * frameClock 기반 tween — things-scene 의 표준 `Component.animate()` 사용.
255
+ * frameClock.simTime 진행 (view mode + scene 활성) 시에만 step 호출 modeler
256
+ * 또는 paused 시 자동 정지. scene.simulationSpeed 도 자동 대응.
173
257
  */
174
258
  private _tween;
175
259
  }