@operato/scene-wheel-sorter 10.0.0-beta.13 → 10.0.0-beta.15

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.
@@ -1,16 +1,6 @@
1
1
  import { RealObjectGroup } from '@hatiolab/things-scene';
2
2
  export declare class Conveyor3D extends RealObjectGroup {
3
3
  get effectiveDepth(): number;
4
- get position(): {
5
- x: number;
6
- y: any;
7
- z: number;
8
- };
9
- /**
10
- * syncFromObject3D 역변환 시 zPos 오프셋.
11
- * position.y = zPos + effectiveDepth/2 이므로, 역변환도 effectiveDepth/2를 빼야 한다.
12
- */
13
- protected get syncZPosOffset(): number;
14
4
  build(): void;
15
5
  private buildRollers;
16
6
  private buildBelt;
@@ -32,21 +32,6 @@ export class Conveyor3D extends RealObjectGroup {
32
32
  const { width, height, depth } = this.component.state;
33
33
  return depth || Math.min(width, height) * 1.5;
34
34
  }
35
- get position() {
36
- const { zPos = 0 } = this.component.state;
37
- return {
38
- x: this.cx,
39
- y: zPos + this.effectiveDepth / 2,
40
- z: this.cy
41
- };
42
- }
43
- /**
44
- * syncFromObject3D 역변환 시 zPos 오프셋.
45
- * position.y = zPos + effectiveDepth/2 이므로, 역변환도 effectiveDepth/2를 빼야 한다.
46
- */
47
- get syncZPosOffset() {
48
- return this.effectiveDepth / 2;
49
- }
50
35
  build() {
51
36
  super.build();
52
37
  const { width, height, conveyorType = 0, value = 0, rollWidth = 10, orientation } = this.component.state;
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-3d.js","sourceRoot":"","sources":["../src/conveyor-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Straight Conveyor 3D Model\n *\n * Roller type: side rails + evenly-spaced cylindrical rollers + 4 legs with cross-bracing\n * Belt type: side rails + two end drums with belt wrapping over them + 4 legs with cross-bracing\n * Both types include a control box at one end and a status indicator light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\nexport class Conveyor3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.min(width, height) * 1.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n /**\n * syncFromObject3D 역변환 시 zPos 오프셋.\n * position.y = zPos + effectiveDepth/2 이므로, 역변환도 effectiveDepth/2를 빼야 한다.\n */\n protected get syncZPosOffset(): number {\n return this.effectiveDepth / 2\n }\n\n build() {\n super.build()\n\n const { width, height, conveyorType = 0, value = 0, rollWidth = 10, orientation } = this.component.state\n const depth = this.effectiveDepth\n\n // orientation: 'horizontal' = 이송 가로, 'vertical' = 이송 세로, '' = auto(긴 방향)\n const isVertical = orientation === 'vertical' ? true\n : orientation === 'horizontal' ? false\n : width < height\n\n // 프레임 두께: rollWidth(롤러 직경)와 동일 단위. 롤러를 감쌀 수 있어야 한다.\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const beltWidth = isVertical ? width : height\n const railW = Math.max(beltWidth * 0.06, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Frame: side rails + legs + cross-bracing ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const railY = depth / 2 - frameH / 2\n\n // Side rails — 이송 방향을 따라, 벨트 양측에 배치\n if (isVertical) {\n for (const xSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(railW, frameH, height)\n rail.translate(xSign * (width / 2 - railW / 2), railY, 0)\n frameGeometries.push(rail)\n }\n } else {\n for (const zSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(width, frameH, railW)\n rail.translate(0, railY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(rail)\n }\n }\n\n // 4 legs at corners\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n const legXPos = isVertical ? (width / 2 - railW / 2) : (width / 2 - legThickness / 2)\n const legZPos = isVertical ? (height / 2 - legThickness / 2) : (height / 2 - railW / 2)\n\n for (const xSign of [-1, 1]) {\n for (const zSign of [-1, 1]) {\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(xSign * legXPos, legCenterY, zSign * legZPos)\n frameGeometries.push(leg)\n }\n }\n\n // Cross-bracing\n const braceH = legThickness * 0.6\n const braceW = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n\n // 이송 방향 브레이스\n if (isVertical) {\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, height - legThickness)\n brace.translate(xSign * legXPos, braceY, 0)\n frameGeometries.push(brace)\n }\n } else {\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - legThickness, braceH, braceW)\n brace.translate(0, braceY, zSign * legZPos)\n frameGeometries.push(brace)\n }\n }\n\n // 벨트폭 방향 브레이스\n if (isVertical) {\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - railW, braceH, braceW)\n brace.translate(0, braceY, zSign * legZPos)\n frameGeometries.push(brace)\n }\n } else {\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, height - railW)\n brace.translate(xSign * legXPos, braceY, 0)\n frameGeometries.push(brace)\n }\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(width, height, depth, frameH, railW, value, isVertical)\n } else {\n this.buildRollers(width, height, depth, frameH, railW, rollWidth as number, isVertical)\n }\n\n // --- Control box (motor housing at one end) ---\n this.buildControlBox(width, height, depth, frameH, railW, value, isVertical)\n }\n\n private buildRollers(width: number, height: number, depth: number, frameH: number, railW: number, rollWidth: number, isVertical: boolean = false) {\n const rollerRadius = Math.max(rollWidth / 2, 1)\n const diameter = rollerRadius * 2\n const step = diameter + 1\n const rollerY = depth / 2 - frameH / 2\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n if (isVertical) {\n // 롤러 축 = X축(가로), 이송 방향 = Z축(세로)\n const rollerLength = width - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(height / step))\n const totalSpan = (count - 1) * step\n const startZ = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const z = startZ + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateZ(Math.PI / 2)\n roller.translate(0, rollerY, z)\n rollerGeometries.push(roller)\n }\n } else {\n // 롤러 축 = Z축(세로), 이송 방향 = X축(가로)\n const rollerLength = height - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(width / step))\n const totalSpan = (count - 1) * step\n const startX = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const x = startX + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateX(Math.PI / 2)\n roller.translate(x, rollerY, 0)\n rollerGeometries.push(roller)\n }\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(rollerGeometries),\n new THREE.MeshStandardMaterial({ color: ROLLER_COLOR, metalness: 0.9, roughness: 0.2 })\n )\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(width: number, height: number, depth: number, frameH: number, railW: number, value: number, isVertical: boolean = false) {\n const drumRadius = frameH * 0.38\n const beltY = depth / 2 - frameH / 2\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const transportLen = isVertical ? height : width\n const bw = isVertical ? width : height\n const drumLength = bw - railW * 2\n\n const rollerMaterial = new THREE.MeshStandardMaterial({\n color: ROLLER_COLOR,\n metalness: 0.9,\n roughness: 0.2\n })\n\n // Two end drums\n const drumGeometries: THREE.BufferGeometry[] = []\n const drumInset = drumRadius * 1.5\n const drum1 = -transportLen / 2 + drumInset\n const drum2 = transportLen / 2 - drumInset\n\n for (const dp of [drum1, drum2]) {\n const drum = new THREE.CylinderGeometry(drumRadius, drumRadius, drumLength, 16)\n if (isVertical) {\n drum.rotateZ(Math.PI / 2)\n drum.translate(0, beltY, dp)\n } else {\n drum.rotateX(Math.PI / 2)\n drum.translate(dp, beltY, 0)\n }\n drumGeometries.push(drum)\n }\n\n const drumMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(drumGeometries), rollerMaterial)\n drumMesh.castShadow = true\n this.object3d.add(drumMesh)\n\n // Belt surface: flat top + half-cylinder wraps around each drum end\n const beltThickness = drumRadius * 0.12\n const beltMaterial = new THREE.MeshStandardMaterial({\n color: fillColor,\n metalness: 0.0,\n roughness: 0.9\n })\n\n // Flat belt top surface spanning between drums\n const flatLen = drum2 - drum1\n const flatGeo = isVertical\n ? new THREE.BoxGeometry(drumLength, beltThickness, flatLen)\n : new THREE.BoxGeometry(flatLen, beltThickness, drumLength)\n const flatMesh = new THREE.Mesh(flatGeo, beltMaterial)\n flatMesh.position.set(0, beltY + drumRadius, 0)\n flatMesh.castShadow = true\n this.object3d.add(flatMesh)\n\n // Belt wrap around drums\n const wrapSegments = 12\n for (const [dp, angleStart] of [\n [drum1, Math.PI / 2],\n [drum2, -Math.PI / 2]\n ] as [number, number][]) {\n const wrapGeometries: THREE.BufferGeometry[] = []\n for (let i = 0; i < wrapSegments; i++) {\n const a0 = angleStart + (Math.PI * i) / wrapSegments\n const a1 = angleStart + (Math.PI * (i + 1)) / wrapSegments\n const r = drumRadius + beltThickness / 2\n\n const p0 = dp + Math.cos(a0) * r\n const y0 = beltY + Math.sin(a0) * r\n const p1 = dp + Math.cos(a1) * r\n const y1 = beltY + Math.sin(a1) * r\n\n const segLen = Math.sqrt((p1 - p0) ** 2 + (y1 - y0) ** 2) * 1.05\n const segAngle = Math.atan2(y1 - y0, p1 - p0)\n\n if (isVertical) {\n const seg = new THREE.BoxGeometry(drumLength, beltThickness, segLen)\n seg.rotateX(-segAngle)\n seg.translate(0, (y0 + y1) / 2, (p0 + p1) / 2)\n wrapGeometries.push(seg)\n } else {\n const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength)\n seg.rotateZ(segAngle)\n seg.translate((p0 + p1) / 2, (y0 + y1) / 2, 0)\n wrapGeometries.push(seg)\n }\n }\n const wrapMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(wrapGeometries), beltMaterial)\n wrapMesh.castShadow = true\n this.object3d.add(wrapMesh)\n }\n\n // Flat belt bottom (return path)\n const bottomGeo = isVertical\n ? new THREE.BoxGeometry(drumLength * 0.85, beltThickness, flatLen)\n : new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85)\n const bottomMesh = new THREE.Mesh(bottomGeo, beltMaterial)\n bottomMesh.position.set(0, beltY - drumRadius, 0)\n this.object3d.add(bottomMesh)\n }\n\n /** Control box (motor/controller housing) + status indicator light */\n private buildControlBox(\n width: number,\n height: number,\n depth: number,\n frameH: number,\n railW: number,\n value: number,\n isVertical: boolean = false\n ) {\n const bw = isVertical ? width : height\n const tl = isVertical ? height : width\n const boxW = Math.max(tl * 0.08, 4)\n const boxH = frameH * 0.7\n const boxD = Math.max(bw * 0.2, 4)\n const railY = depth / 2 - frameH / 2\n\n // Box positioned at one end, attached to the side rail\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = isVertical\n ? new THREE.BoxGeometry(boxD, boxH, boxW)\n : new THREE.BoxGeometry(boxW, boxH, boxD)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n if (isVertical) {\n boxMesh.position.set(\n -width / 2 + railW + boxD / 2,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + boxW / 2 + railW\n )\n } else {\n boxMesh.position.set(\n -width / 2 + boxW / 2 + railW,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + railW + boxD / 2\n )\n }\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status indicator light on top of control box\n const lightR = Math.min(boxW, boxD) * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n const lightIntensity = value > 0 ? 1.5 : 0.2\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: lightIntensity,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(\n boxMesh.position.x,\n boxMesh.position.y + boxH / 2 + lightH / 2,\n boxMesh.position.z\n )\n this.object3d.add(lightMesh)\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'conveyorType' in after || 'rollWidth' in after || 'orientation' in after || 'width' in after || 'height' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
1
+ {"version":3,"file":"conveyor-3d.js","sourceRoot":"","sources":["../src/conveyor-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Straight Conveyor 3D Model\n *\n * Roller type: side rails + evenly-spaced cylindrical rollers + 4 legs with cross-bracing\n * Belt type: side rails + two end drums with belt wrapping over them + 4 legs with cross-bracing\n * Both types include a control box at one end and a status indicator light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\nexport class Conveyor3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.min(width, height) * 1.5\n }\n\n build() {\n super.build()\n\n const { width, height, conveyorType = 0, value = 0, rollWidth = 10, orientation } = this.component.state\n const depth = this.effectiveDepth\n\n // orientation: 'horizontal' = 이송 가로, 'vertical' = 이송 세로, '' = auto(긴 방향)\n const isVertical = orientation === 'vertical' ? true\n : orientation === 'horizontal' ? false\n : width < height\n\n // 프레임 두께: rollWidth(롤러 직경)와 동일 단위. 롤러를 감쌀 수 있어야 한다.\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const beltWidth = isVertical ? width : height\n const railW = Math.max(beltWidth * 0.06, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Frame: side rails + legs + cross-bracing ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const railY = depth / 2 - frameH / 2\n\n // Side rails — 이송 방향을 따라, 벨트 양측에 배치\n if (isVertical) {\n for (const xSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(railW, frameH, height)\n rail.translate(xSign * (width / 2 - railW / 2), railY, 0)\n frameGeometries.push(rail)\n }\n } else {\n for (const zSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(width, frameH, railW)\n rail.translate(0, railY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(rail)\n }\n }\n\n // 4 legs at corners\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n const legXPos = isVertical ? (width / 2 - railW / 2) : (width / 2 - legThickness / 2)\n const legZPos = isVertical ? (height / 2 - legThickness / 2) : (height / 2 - railW / 2)\n\n for (const xSign of [-1, 1]) {\n for (const zSign of [-1, 1]) {\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(xSign * legXPos, legCenterY, zSign * legZPos)\n frameGeometries.push(leg)\n }\n }\n\n // Cross-bracing\n const braceH = legThickness * 0.6\n const braceW = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n\n // 이송 방향 브레이스\n if (isVertical) {\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, height - legThickness)\n brace.translate(xSign * legXPos, braceY, 0)\n frameGeometries.push(brace)\n }\n } else {\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - legThickness, braceH, braceW)\n brace.translate(0, braceY, zSign * legZPos)\n frameGeometries.push(brace)\n }\n }\n\n // 벨트폭 방향 브레이스\n if (isVertical) {\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - railW, braceH, braceW)\n brace.translate(0, braceY, zSign * legZPos)\n frameGeometries.push(brace)\n }\n } else {\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceW, braceH, height - railW)\n brace.translate(xSign * legXPos, braceY, 0)\n frameGeometries.push(brace)\n }\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(width, height, depth, frameH, railW, value, isVertical)\n } else {\n this.buildRollers(width, height, depth, frameH, railW, rollWidth as number, isVertical)\n }\n\n // --- Control box (motor housing at one end) ---\n this.buildControlBox(width, height, depth, frameH, railW, value, isVertical)\n }\n\n private buildRollers(width: number, height: number, depth: number, frameH: number, railW: number, rollWidth: number, isVertical: boolean = false) {\n const rollerRadius = Math.max(rollWidth / 2, 1)\n const diameter = rollerRadius * 2\n const step = diameter + 1\n const rollerY = depth / 2 - frameH / 2\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n if (isVertical) {\n // 롤러 축 = X축(가로), 이송 방향 = Z축(세로)\n const rollerLength = width - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(height / step))\n const totalSpan = (count - 1) * step\n const startZ = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const z = startZ + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateZ(Math.PI / 2)\n roller.translate(0, rollerY, z)\n rollerGeometries.push(roller)\n }\n } else {\n // 롤러 축 = Z축(세로), 이송 방향 = X축(가로)\n const rollerLength = height - railW * 2 - 0.5\n const count = Math.max(1, Math.floor(width / step))\n const totalSpan = (count - 1) * step\n const startX = -totalSpan / 2\n\n for (let i = 0; i < count; i++) {\n const x = startX + i * step\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateX(Math.PI / 2)\n roller.translate(x, rollerY, 0)\n rollerGeometries.push(roller)\n }\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(rollerGeometries),\n new THREE.MeshStandardMaterial({ color: ROLLER_COLOR, metalness: 0.9, roughness: 0.2 })\n )\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(width: number, height: number, depth: number, frameH: number, railW: number, value: number, isVertical: boolean = false) {\n const drumRadius = frameH * 0.38\n const beltY = depth / 2 - frameH / 2\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const transportLen = isVertical ? height : width\n const bw = isVertical ? width : height\n const drumLength = bw - railW * 2\n\n const rollerMaterial = new THREE.MeshStandardMaterial({\n color: ROLLER_COLOR,\n metalness: 0.9,\n roughness: 0.2\n })\n\n // Two end drums\n const drumGeometries: THREE.BufferGeometry[] = []\n const drumInset = drumRadius * 1.5\n const drum1 = -transportLen / 2 + drumInset\n const drum2 = transportLen / 2 - drumInset\n\n for (const dp of [drum1, drum2]) {\n const drum = new THREE.CylinderGeometry(drumRadius, drumRadius, drumLength, 16)\n if (isVertical) {\n drum.rotateZ(Math.PI / 2)\n drum.translate(0, beltY, dp)\n } else {\n drum.rotateX(Math.PI / 2)\n drum.translate(dp, beltY, 0)\n }\n drumGeometries.push(drum)\n }\n\n const drumMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(drumGeometries), rollerMaterial)\n drumMesh.castShadow = true\n this.object3d.add(drumMesh)\n\n // Belt surface: flat top + half-cylinder wraps around each drum end\n const beltThickness = drumRadius * 0.12\n const beltMaterial = new THREE.MeshStandardMaterial({\n color: fillColor,\n metalness: 0.0,\n roughness: 0.9\n })\n\n // Flat belt top surface spanning between drums\n const flatLen = drum2 - drum1\n const flatGeo = isVertical\n ? new THREE.BoxGeometry(drumLength, beltThickness, flatLen)\n : new THREE.BoxGeometry(flatLen, beltThickness, drumLength)\n const flatMesh = new THREE.Mesh(flatGeo, beltMaterial)\n flatMesh.position.set(0, beltY + drumRadius, 0)\n flatMesh.castShadow = true\n this.object3d.add(flatMesh)\n\n // Belt wrap around drums\n const wrapSegments = 12\n for (const [dp, angleStart] of [\n [drum1, Math.PI / 2],\n [drum2, -Math.PI / 2]\n ] as [number, number][]) {\n const wrapGeometries: THREE.BufferGeometry[] = []\n for (let i = 0; i < wrapSegments; i++) {\n const a0 = angleStart + (Math.PI * i) / wrapSegments\n const a1 = angleStart + (Math.PI * (i + 1)) / wrapSegments\n const r = drumRadius + beltThickness / 2\n\n const p0 = dp + Math.cos(a0) * r\n const y0 = beltY + Math.sin(a0) * r\n const p1 = dp + Math.cos(a1) * r\n const y1 = beltY + Math.sin(a1) * r\n\n const segLen = Math.sqrt((p1 - p0) ** 2 + (y1 - y0) ** 2) * 1.05\n const segAngle = Math.atan2(y1 - y0, p1 - p0)\n\n if (isVertical) {\n const seg = new THREE.BoxGeometry(drumLength, beltThickness, segLen)\n seg.rotateX(-segAngle)\n seg.translate(0, (y0 + y1) / 2, (p0 + p1) / 2)\n wrapGeometries.push(seg)\n } else {\n const seg = new THREE.BoxGeometry(segLen, beltThickness, drumLength)\n seg.rotateZ(segAngle)\n seg.translate((p0 + p1) / 2, (y0 + y1) / 2, 0)\n wrapGeometries.push(seg)\n }\n }\n const wrapMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(wrapGeometries), beltMaterial)\n wrapMesh.castShadow = true\n this.object3d.add(wrapMesh)\n }\n\n // Flat belt bottom (return path)\n const bottomGeo = isVertical\n ? new THREE.BoxGeometry(drumLength * 0.85, beltThickness, flatLen)\n : new THREE.BoxGeometry(flatLen, beltThickness, drumLength * 0.85)\n const bottomMesh = new THREE.Mesh(bottomGeo, beltMaterial)\n bottomMesh.position.set(0, beltY - drumRadius, 0)\n this.object3d.add(bottomMesh)\n }\n\n /** Control box (motor/controller housing) + status indicator light */\n private buildControlBox(\n width: number,\n height: number,\n depth: number,\n frameH: number,\n railW: number,\n value: number,\n isVertical: boolean = false\n ) {\n const bw = isVertical ? width : height\n const tl = isVertical ? height : width\n const boxW = Math.max(tl * 0.08, 4)\n const boxH = frameH * 0.7\n const boxD = Math.max(bw * 0.2, 4)\n const railY = depth / 2 - frameH / 2\n\n // Box positioned at one end, attached to the side rail\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = isVertical\n ? new THREE.BoxGeometry(boxD, boxH, boxW)\n : new THREE.BoxGeometry(boxW, boxH, boxD)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n if (isVertical) {\n boxMesh.position.set(\n -width / 2 + railW + boxD / 2,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + boxW / 2 + railW\n )\n } else {\n boxMesh.position.set(\n -width / 2 + boxW / 2 + railW,\n railY - frameH / 2 - boxH / 2 + boxH * 0.15,\n -height / 2 + railW + boxD / 2\n )\n }\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status indicator light on top of control box\n const lightR = Math.min(boxW, boxD) * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n const lightIntensity = value > 0 ? 1.5 : 0.2\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: lightIntensity,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(\n boxMesh.position.x,\n boxMesh.position.y + boxH / 2 + lightH / 2,\n boxMesh.position.z\n )\n this.object3d.add(lightMesh)\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'conveyorType' in after || 'rollWidth' in after || 'orientation' in after || 'width' in after || 'height' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
@@ -1,11 +1,6 @@
1
1
  import { RealObjectGroup } from '@hatiolab/things-scene';
2
2
  export declare class ConveyorJoin3D extends RealObjectGroup {
3
3
  get effectiveDepth(): number;
4
- get position(): {
5
- x: number;
6
- y: any;
7
- z: number;
8
- };
9
4
  build(): void;
10
5
  private addBrace;
11
6
  private buildArcRail;
@@ -54,14 +54,6 @@ export class ConveyorJoin3D extends RealObjectGroup {
54
54
  const beltWidth = outerR - (outerR * Math.abs(ratio)) / 100;
55
55
  return depth || beltWidth * 1.5;
56
56
  }
57
- get position() {
58
- const { zPos = 0 } = this.component.state;
59
- return {
60
- x: this.cx,
61
- y: zPos + this.effectiveDepth / 2,
62
- z: this.cy
63
- };
64
- }
65
57
  build() {
66
58
  super.build();
67
59
  const { rx: _rx = 100, ry: _ry = 100, ratio = 50, startAngle = 0, endAngle = Math.PI / 2, value = 0, conveyorType = 0, rollWidth = 10 } = this.component.state;
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-join-3d.js","sourceRoot":"","sources":["../src/conveyor-join-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Curved Conveyor (ConveyorJoin) 3D Model\n *\n * A curved conveyor section that changes direction of travel (e.g., 90° turn).\n * Key feature: conical (tapered) rollers — wider at outer radius, narrower at\n * inner radius — ensuring uniform belt speed across the curve width.\n * Structure: curved side rails + conical rollers/belt + end caps + legs\n * + cross-bracing + control box with status light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\n/**\n * BoxGeometry의 X축(길이방향)을 XZ 평면의 (dx, dz) 방향으로 정렬하는 Y축 회전각.\n * Three.js rotateY 컨벤션: +X → -Z 가 π/2.\n */\nfunction boxAlignAngle(dx: number, dz: number): number {\n return -Math.atan2(dz, dx)\n}\n\n/**\n * CylinderGeometry가 rotateX(π/2) 후 Z축 방향이 되었을 때,\n * Z축을 XZ 평면의 (dx, dz) 방향으로 정렬하는 Y축 회전각.\n */\nfunction cylinderAlignAngle(dx: number, dz: number): number {\n return Math.atan2(dx, dz)\n}\n\n/** 호 위의 점 (x, z) in XZ plane */\nfunction arcPoint(rx: number, ry: number, angle: number) {\n return { x: rx * Math.sin(angle), z: -ry * Math.cos(angle) }\n}\n\nexport class ConveyorJoin3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { rx = 100, ratio = 50, depth } = this.component.state\n const outerR = Math.abs(rx)\n const beltWidth = outerR - (outerR * Math.abs(ratio)) / 100\n return depth || beltWidth * 1.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n build() {\n super.build()\n\n const {\n rx: _rx = 100,\n ry: _ry = 100,\n ratio = 50,\n startAngle = 0,\n endAngle = Math.PI / 2,\n value = 0,\n conveyorType = 0,\n rollWidth = 10\n } = this.component.state\n\n const depth = this.effectiveDepth\n const outerRx = Math.abs(_rx)\n const outerRy = Math.abs(_ry)\n const innerRx = (outerRx * Math.abs(ratio)) / 100\n const innerRy = (outerRy * Math.abs(ratio)) / 100\n const beltWidth = outerRx - innerRx\n\n // Conveyor3D와 동일: frameH = rollWidth 기반\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const railW = Math.max(beltWidth * 0.06, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n const railY = depth / 2 - frameH / 2\n\n const arcSpan = endAngle - startAngle\n const segments = Math.max(12, Math.floor((Math.abs(arcSpan) * outerRx) / 5))\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Side rails (box segments along inner/outer arcs) ---\n const frameGeometries: THREE.BufferGeometry[] = []\n\n this.buildArcRail(frameGeometries, outerRx, outerRy, railW, startAngle, endAngle, segments, frameH, railY)\n this.buildArcRail(frameGeometries, innerRx, innerRy, railW, startAngle, endAngle, segments, frameH, railY)\n\n // End caps (straight segments connecting inner/outer at start and end angles)\n for (const angle of [startAngle, endAngle]) {\n const o = arcPoint(outerRx, outerRy, angle)\n const inn = arcPoint(innerRx, innerRy, angle)\n const dx = o.x - inn.x\n const dz = o.z - inn.z\n const capLen = Math.sqrt(dx * dx + dz * dz)\n\n const cap = new THREE.BoxGeometry(capLen, frameH, railW)\n cap.rotateY(boxAlignAngle(dx, dz))\n cap.translate((o.x + inn.x) / 2, railY, (o.z + inn.z) / 2)\n frameGeometries.push(cap)\n }\n\n // 4 legs at corners\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n const legPositions: [number, number][] = []\n\n for (const angle of [startAngle, endAngle]) {\n for (const [rx, ry] of [\n [outerRx - railW, outerRy - railW],\n [innerRx + railW, innerRy + railW]\n ]) {\n const p = arcPoint(rx, ry, angle)\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(p.x, legCenterY, p.z)\n frameGeometries.push(leg)\n legPositions.push([p.x, p.z])\n }\n }\n\n // Cross-bracing\n const braceSize = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n\n // Connect outer-to-inner at each end angle\n for (let i = 0; i < legPositions.length; i += 2) {\n const [x0, z0] = legPositions[i]\n const [x1, z1] = legPositions[i + 1]\n this.addBrace(frameGeometries, x0, z0, x1, z1, braceSize, braceY)\n }\n\n // Connect start-to-end along outer side and inner side\n for (const side of [0, 1]) {\n const [x0, z0] = legPositions[side]\n const [x1, z1] = legPositions[side + 2]\n this.addBrace(frameGeometries, x0, z0, x1, z1, braceSize, braceY)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(outerRx, outerRy, innerRx, innerRy, railW, startAngle, endAngle, segments, depth, frameH, value)\n } else {\n this.buildRollers(outerRx, outerRy, innerRx, innerRy, railW, startAngle, endAngle, depth, frameH, rollWidth as number, beltWidth)\n }\n\n // --- Control box + status light ---\n this.buildControlBox(outerRx, outerRy, innerRx, innerRy, startAngle, depth, frameH, railW, value)\n }\n\n private addBrace(\n geometries: THREE.BufferGeometry[],\n x0: number,\n z0: number,\n x1: number,\n z1: number,\n braceSize: number,\n braceY: number\n ) {\n const dx = x1 - x0\n const dz = z1 - z0\n const braceLen = Math.sqrt(dx * dx + dz * dz)\n const brace = new THREE.BoxGeometry(braceLen, braceSize, braceSize)\n brace.rotateY(boxAlignAngle(dx, dz))\n brace.translate((x0 + x1) / 2, braceY, (z0 + z1) / 2)\n geometries.push(brace)\n }\n\n private buildArcRail(\n geometries: THREE.BufferGeometry[],\n rx: number,\n ry: number,\n railW: number,\n startAngle: number,\n endAngle: number,\n segments: number,\n frameH: number,\n railY: number\n ) {\n const arcSpan = endAngle - startAngle\n\n for (let i = 0; i < segments; i++) {\n const a0 = startAngle + (arcSpan * i) / segments\n const a1 = startAngle + (arcSpan * (i + 1)) / segments\n\n const p0 = arcPoint(rx, ry, a0)\n const p1 = arcPoint(rx, ry, a1)\n\n const dx = p1.x - p0.x\n const dz = p1.z - p0.z\n const segLen = Math.sqrt(dx * dx + dz * dz) * 1.03\n\n const seg = new THREE.BoxGeometry(segLen, frameH, railW)\n seg.rotateY(boxAlignAngle(dx, dz))\n seg.translate((p0.x + p1.x) / 2, railY, (p0.z + p1.z) / 2)\n geometries.push(seg)\n }\n }\n\n private buildRollers(\n outerRx: number,\n outerRy: number,\n innerRx: number,\n innerRy: number,\n railW: number,\n startAngle: number,\n endAngle: number,\n depth: number,\n frameH: number,\n rollWidth: number,\n _beltWidth: number\n ) {\n const rollerRadius = Math.max(rollWidth / 2, 1)\n const rollerY = depth / 2 - frameH / 2\n\n const midRx = (outerRx + innerRx) / 2\n const arcLength = midRx * Math.abs(endAngle - startAngle)\n const diameter = rollerRadius * 2\n const step = diameter + 1\n const count = Math.max(1, Math.floor(arcLength / step))\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n for (let i = 1; i <= count; i++) {\n const t = i / (count + 1)\n const angle = startAngle + (endAngle - startAngle) * t\n\n const o = arcPoint(outerRx - railW, outerRy - railW, angle)\n const inn = arcPoint(innerRx + railW, innerRy + railW, angle)\n const dx = o.x - inn.x\n const dz = o.z - inn.z\n const rollerLength = Math.sqrt(dx * dx + dz * dz)\n const midX = (o.x + inn.x) / 2\n const midZ = (o.z + inn.z) / 2\n\n // Conical roller: outer end wider, inner end narrower (capped at 1.5:1)\n const outerDist = Math.sqrt(o.x * o.x + o.z * o.z)\n const innerDist = Math.sqrt(inn.x * inn.x + inn.z * inn.z)\n const rawRatio = innerDist > 0 ? outerDist / innerDist : 1\n const cappedRatio = Math.min(rawRatio, 1.5)\n const outerRollerR = (rollerRadius * (2 * cappedRatio)) / (cappedRatio + 1)\n const innerRollerR = (rollerRadius * 2) / (cappedRatio + 1)\n\n // CylinderGeometry: radiusTop at +Y, radiusBottom at -Y\n // After rotateX(π/2): +Y → -Z (top=inner), -Y → +Z (bottom=outer)\n // cylinderAlignAngle maps +Z to radial direction (inner→outer)\n const roller = new THREE.CylinderGeometry(outerRollerR, innerRollerR, rollerLength, 16)\n roller.rotateX(Math.PI / 2)\n roller.rotateY(cylinderAlignAngle(dx, dz))\n roller.translate(midX, rollerY, midZ)\n rollerGeometries.push(roller)\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(rollerGeometries),\n new THREE.MeshStandardMaterial({ color: ROLLER_COLOR, metalness: 0.9, roughness: 0.2 })\n )\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(\n outerRx: number,\n outerRy: number,\n innerRx: number,\n innerRy: number,\n railW: number,\n startAngle: number,\n endAngle: number,\n segments: number,\n depth: number,\n frameH: number,\n value: number\n ) {\n const beltOx = outerRx - railW\n const beltOy = outerRy - railW\n const beltIx = innerRx + railW\n const beltIy = innerRy + railW\n const beltH = frameH * 0.15\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const shape = new THREE.Shape()\n\n for (let i = 0; i <= segments; i++) {\n const angle = startAngle + ((endAngle - startAngle) * i) / segments\n const sx = beltOx * Math.sin(angle)\n const sy = beltOy * Math.cos(angle)\n if (i === 0) shape.moveTo(sx, sy)\n else shape.lineTo(sx, sy)\n }\n for (let i = segments; i >= 0; i--) {\n const angle = startAngle + ((endAngle - startAngle) * i) / segments\n shape.lineTo(beltIx * Math.sin(angle), beltIy * Math.cos(angle))\n }\n shape.closePath()\n\n const beltGeo = new THREE.ExtrudeGeometry(shape, { depth: beltH, bevelEnabled: false })\n beltGeo.rotateX(-Math.PI / 2)\n beltGeo.translate(0, depth / 2, 0)\n\n const beltMesh = new THREE.Mesh(\n beltGeo,\n new THREE.MeshStandardMaterial({ color: fillColor, metalness: 0.0, roughness: 0.9 })\n )\n beltMesh.castShadow = true\n this.object3d.add(beltMesh)\n }\n\n private buildControlBox(\n outerRx: number,\n _outerRy: number,\n innerRx: number,\n _innerRy: number,\n startAngle: number,\n depth: number,\n frameH: number,\n railW: number,\n value: number\n ) {\n const beltWidth = outerRx - innerRx\n const boxW = Math.max(beltWidth * 0.12, 3)\n const boxH = frameH * 0.6\n const boxD = Math.max(beltWidth * 0.15, 3)\n\n const midR = outerRx - railW - boxD / 2\n const p = arcPoint(midR, midR, startAngle)\n const railY = depth / 2 - frameH / 2\n\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = new THREE.BoxGeometry(boxW, boxH, boxD)\n boxGeo.rotateY(-startAngle)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n boxMesh.position.set(p.x, railY - frameH / 2 - boxH / 2, p.z)\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status light\n const lightR = Math.min(boxW, boxD) * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: value > 0 ? 1.5 : 0.2,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(p.x, boxMesh.position.y + boxH / 2 + lightH / 2, p.z)\n this.object3d.add(lightMesh)\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'value' in after ||\n 'conveyorType' in after ||\n 'rollWidth' in after ||\n 'rx' in after ||\n 'ry' in after ||\n 'ratio' in after ||\n 'startAngle' in after ||\n 'endAngle' in after ||\n 'depth' in after\n ) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
1
+ {"version":3,"file":"conveyor-join-3d.js","sourceRoot":"","sources":["../src/conveyor-join-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Curved Conveyor (ConveyorJoin) 3D Model\n *\n * A curved conveyor section that changes direction of travel (e.g., 90° turn).\n * Key feature: conical (tapered) rollers — wider at outer radius, narrower at\n * inner radius — ensuring uniform belt speed across the curve width.\n * Structure: curved side rails + conical rollers/belt + end caps + legs\n * + cross-bracing + control box with status light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\n/**\n * BoxGeometry의 X축(길이방향)을 XZ 평면의 (dx, dz) 방향으로 정렬하는 Y축 회전각.\n * Three.js rotateY 컨벤션: +X → -Z 가 π/2.\n */\nfunction boxAlignAngle(dx: number, dz: number): number {\n return -Math.atan2(dz, dx)\n}\n\n/**\n * CylinderGeometry가 rotateX(π/2) 후 Z축 방향이 되었을 때,\n * Z축을 XZ 평면의 (dx, dz) 방향으로 정렬하는 Y축 회전각.\n */\nfunction cylinderAlignAngle(dx: number, dz: number): number {\n return Math.atan2(dx, dz)\n}\n\n/** 호 위의 점 (x, z) in XZ plane */\nfunction arcPoint(rx: number, ry: number, angle: number) {\n return { x: rx * Math.sin(angle), z: -ry * Math.cos(angle) }\n}\n\nexport class ConveyorJoin3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { rx = 100, ratio = 50, depth } = this.component.state\n const outerR = Math.abs(rx)\n const beltWidth = outerR - (outerR * Math.abs(ratio)) / 100\n return depth || beltWidth * 1.5\n }\n\n build() {\n super.build()\n\n const {\n rx: _rx = 100,\n ry: _ry = 100,\n ratio = 50,\n startAngle = 0,\n endAngle = Math.PI / 2,\n value = 0,\n conveyorType = 0,\n rollWidth = 10\n } = this.component.state\n\n const depth = this.effectiveDepth\n const outerRx = Math.abs(_rx)\n const outerRy = Math.abs(_ry)\n const innerRx = (outerRx * Math.abs(ratio)) / 100\n const innerRy = (outerRy * Math.abs(ratio)) / 100\n const beltWidth = outerRx - innerRx\n\n // Conveyor3D와 동일: frameH = rollWidth 기반\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const railW = Math.max(beltWidth * 0.06, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n const railY = depth / 2 - frameH / 2\n\n const arcSpan = endAngle - startAngle\n const segments = Math.max(12, Math.floor((Math.abs(arcSpan) * outerRx) / 5))\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Side rails (box segments along inner/outer arcs) ---\n const frameGeometries: THREE.BufferGeometry[] = []\n\n this.buildArcRail(frameGeometries, outerRx, outerRy, railW, startAngle, endAngle, segments, frameH, railY)\n this.buildArcRail(frameGeometries, innerRx, innerRy, railW, startAngle, endAngle, segments, frameH, railY)\n\n // End caps (straight segments connecting inner/outer at start and end angles)\n for (const angle of [startAngle, endAngle]) {\n const o = arcPoint(outerRx, outerRy, angle)\n const inn = arcPoint(innerRx, innerRy, angle)\n const dx = o.x - inn.x\n const dz = o.z - inn.z\n const capLen = Math.sqrt(dx * dx + dz * dz)\n\n const cap = new THREE.BoxGeometry(capLen, frameH, railW)\n cap.rotateY(boxAlignAngle(dx, dz))\n cap.translate((o.x + inn.x) / 2, railY, (o.z + inn.z) / 2)\n frameGeometries.push(cap)\n }\n\n // 4 legs at corners\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n const legPositions: [number, number][] = []\n\n for (const angle of [startAngle, endAngle]) {\n for (const [rx, ry] of [\n [outerRx - railW, outerRy - railW],\n [innerRx + railW, innerRy + railW]\n ]) {\n const p = arcPoint(rx, ry, angle)\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(p.x, legCenterY, p.z)\n frameGeometries.push(leg)\n legPositions.push([p.x, p.z])\n }\n }\n\n // Cross-bracing\n const braceSize = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n\n // Connect outer-to-inner at each end angle\n for (let i = 0; i < legPositions.length; i += 2) {\n const [x0, z0] = legPositions[i]\n const [x1, z1] = legPositions[i + 1]\n this.addBrace(frameGeometries, x0, z0, x1, z1, braceSize, braceY)\n }\n\n // Connect start-to-end along outer side and inner side\n for (const side of [0, 1]) {\n const [x0, z0] = legPositions[side]\n const [x1, z1] = legPositions[side + 2]\n this.addBrace(frameGeometries, x0, z0, x1, z1, braceSize, braceY)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(outerRx, outerRy, innerRx, innerRy, railW, startAngle, endAngle, segments, depth, frameH, value)\n } else {\n this.buildRollers(outerRx, outerRy, innerRx, innerRy, railW, startAngle, endAngle, depth, frameH, rollWidth as number, beltWidth)\n }\n\n // --- Control box + status light ---\n this.buildControlBox(outerRx, outerRy, innerRx, innerRy, startAngle, depth, frameH, railW, value)\n }\n\n private addBrace(\n geometries: THREE.BufferGeometry[],\n x0: number,\n z0: number,\n x1: number,\n z1: number,\n braceSize: number,\n braceY: number\n ) {\n const dx = x1 - x0\n const dz = z1 - z0\n const braceLen = Math.sqrt(dx * dx + dz * dz)\n const brace = new THREE.BoxGeometry(braceLen, braceSize, braceSize)\n brace.rotateY(boxAlignAngle(dx, dz))\n brace.translate((x0 + x1) / 2, braceY, (z0 + z1) / 2)\n geometries.push(brace)\n }\n\n private buildArcRail(\n geometries: THREE.BufferGeometry[],\n rx: number,\n ry: number,\n railW: number,\n startAngle: number,\n endAngle: number,\n segments: number,\n frameH: number,\n railY: number\n ) {\n const arcSpan = endAngle - startAngle\n\n for (let i = 0; i < segments; i++) {\n const a0 = startAngle + (arcSpan * i) / segments\n const a1 = startAngle + (arcSpan * (i + 1)) / segments\n\n const p0 = arcPoint(rx, ry, a0)\n const p1 = arcPoint(rx, ry, a1)\n\n const dx = p1.x - p0.x\n const dz = p1.z - p0.z\n const segLen = Math.sqrt(dx * dx + dz * dz) * 1.03\n\n const seg = new THREE.BoxGeometry(segLen, frameH, railW)\n seg.rotateY(boxAlignAngle(dx, dz))\n seg.translate((p0.x + p1.x) / 2, railY, (p0.z + p1.z) / 2)\n geometries.push(seg)\n }\n }\n\n private buildRollers(\n outerRx: number,\n outerRy: number,\n innerRx: number,\n innerRy: number,\n railW: number,\n startAngle: number,\n endAngle: number,\n depth: number,\n frameH: number,\n rollWidth: number,\n _beltWidth: number\n ) {\n const rollerRadius = Math.max(rollWidth / 2, 1)\n const rollerY = depth / 2 - frameH / 2\n\n const midRx = (outerRx + innerRx) / 2\n const arcLength = midRx * Math.abs(endAngle - startAngle)\n const diameter = rollerRadius * 2\n const step = diameter + 1\n const count = Math.max(1, Math.floor(arcLength / step))\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n for (let i = 1; i <= count; i++) {\n const t = i / (count + 1)\n const angle = startAngle + (endAngle - startAngle) * t\n\n const o = arcPoint(outerRx - railW, outerRy - railW, angle)\n const inn = arcPoint(innerRx + railW, innerRy + railW, angle)\n const dx = o.x - inn.x\n const dz = o.z - inn.z\n const rollerLength = Math.sqrt(dx * dx + dz * dz)\n const midX = (o.x + inn.x) / 2\n const midZ = (o.z + inn.z) / 2\n\n // Conical roller: outer end wider, inner end narrower (capped at 1.5:1)\n const outerDist = Math.sqrt(o.x * o.x + o.z * o.z)\n const innerDist = Math.sqrt(inn.x * inn.x + inn.z * inn.z)\n const rawRatio = innerDist > 0 ? outerDist / innerDist : 1\n const cappedRatio = Math.min(rawRatio, 1.5)\n const outerRollerR = (rollerRadius * (2 * cappedRatio)) / (cappedRatio + 1)\n const innerRollerR = (rollerRadius * 2) / (cappedRatio + 1)\n\n // CylinderGeometry: radiusTop at +Y, radiusBottom at -Y\n // After rotateX(π/2): +Y → -Z (top=inner), -Y → +Z (bottom=outer)\n // cylinderAlignAngle maps +Z to radial direction (inner→outer)\n const roller = new THREE.CylinderGeometry(outerRollerR, innerRollerR, rollerLength, 16)\n roller.rotateX(Math.PI / 2)\n roller.rotateY(cylinderAlignAngle(dx, dz))\n roller.translate(midX, rollerY, midZ)\n rollerGeometries.push(roller)\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(rollerGeometries),\n new THREE.MeshStandardMaterial({ color: ROLLER_COLOR, metalness: 0.9, roughness: 0.2 })\n )\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(\n outerRx: number,\n outerRy: number,\n innerRx: number,\n innerRy: number,\n railW: number,\n startAngle: number,\n endAngle: number,\n segments: number,\n depth: number,\n frameH: number,\n value: number\n ) {\n const beltOx = outerRx - railW\n const beltOy = outerRy - railW\n const beltIx = innerRx + railW\n const beltIy = innerRy + railW\n const beltH = frameH * 0.15\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const shape = new THREE.Shape()\n\n for (let i = 0; i <= segments; i++) {\n const angle = startAngle + ((endAngle - startAngle) * i) / segments\n const sx = beltOx * Math.sin(angle)\n const sy = beltOy * Math.cos(angle)\n if (i === 0) shape.moveTo(sx, sy)\n else shape.lineTo(sx, sy)\n }\n for (let i = segments; i >= 0; i--) {\n const angle = startAngle + ((endAngle - startAngle) * i) / segments\n shape.lineTo(beltIx * Math.sin(angle), beltIy * Math.cos(angle))\n }\n shape.closePath()\n\n const beltGeo = new THREE.ExtrudeGeometry(shape, { depth: beltH, bevelEnabled: false })\n beltGeo.rotateX(-Math.PI / 2)\n beltGeo.translate(0, depth / 2, 0)\n\n const beltMesh = new THREE.Mesh(\n beltGeo,\n new THREE.MeshStandardMaterial({ color: fillColor, metalness: 0.0, roughness: 0.9 })\n )\n beltMesh.castShadow = true\n this.object3d.add(beltMesh)\n }\n\n private buildControlBox(\n outerRx: number,\n _outerRy: number,\n innerRx: number,\n _innerRy: number,\n startAngle: number,\n depth: number,\n frameH: number,\n railW: number,\n value: number\n ) {\n const beltWidth = outerRx - innerRx\n const boxW = Math.max(beltWidth * 0.12, 3)\n const boxH = frameH * 0.6\n const boxD = Math.max(beltWidth * 0.15, 3)\n\n const midR = outerRx - railW - boxD / 2\n const p = arcPoint(midR, midR, startAngle)\n const railY = depth / 2 - frameH / 2\n\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = new THREE.BoxGeometry(boxW, boxH, boxD)\n boxGeo.rotateY(-startAngle)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n boxMesh.position.set(p.x, railY - frameH / 2 - boxH / 2, p.z)\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status light\n const lightR = Math.min(boxW, boxD) * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: value > 0 ? 1.5 : 0.2,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(p.x, boxMesh.position.y + boxH / 2 + lightH / 2, p.z)\n this.object3d.add(lightMesh)\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'value' in after ||\n 'conveyorType' in after ||\n 'rollWidth' in after ||\n 'rx' in after ||\n 'ry' in after ||\n 'ratio' in after ||\n 'startAngle' in after ||\n 'endAngle' in after ||\n 'depth' in after\n ) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
@@ -2,11 +2,6 @@ import { RealObjectGroup } from '@hatiolab/things-scene';
2
2
  export declare class ConveyorJoinTrapezoid3D extends RealObjectGroup {
3
3
  private get polygonBounds();
4
4
  get effectiveDepth(): number;
5
- get position(): {
6
- x: number;
7
- y: any;
8
- z: number;
9
- };
10
5
  build(): void;
11
6
  private buildRollers;
12
7
  private buildBelt;
@@ -48,14 +48,6 @@ export class ConveyorJoinTrapezoid3D extends RealObjectGroup {
48
48
  const { w, h } = this.polygonBounds;
49
49
  return Math.min(w, h) * 1.5;
50
50
  }
51
- get position() {
52
- const { zPos = 0 } = this.component.state;
53
- return {
54
- x: this.cx,
55
- y: zPos + this.effectiveDepth / 2,
56
- z: this.cy
57
- };
58
- }
59
51
  build() {
60
52
  super.build();
61
53
  const { path = [], value = 0, conveyorType = 0, rollWidth } = this.component.state;
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-join-trapezoid-3d.js","sourceRoot":"","sources":["../src/conveyor-join-trapezoid-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Trapezoid/Polygon Conveyor (ConveyorJoinTrapezoid) 3D Model\n *\n * A funnel-shaped conveyor transition that merges or diverts between\n * conveyors of different widths. Same structure as a straight conveyor\n * — side rails along edges + rollers spanning the width + legs — but\n * following a polygon path (typically pentagon/trapezoid).\n * Structure: polygon edge rails + rollers/belt + legs at vertices\n * + cross-bracing + control box with status light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\ninterface PathPoint {\n x: number\n y: number\n}\n\nexport class ConveyorJoinTrapezoid3D extends RealObjectGroup {\n private get polygonBounds() {\n const path: PathPoint[] = this.component.state.path || []\n if (path.length === 0) return { cx: 0, cy: 0, w: 100, h: 100 }\n const xs = path.map(p => p.x)\n const ys = path.map(p => p.y)\n const minX = Math.min(...xs),\n maxX = Math.max(...xs)\n const minY = Math.min(...ys),\n maxY = Math.max(...ys)\n return { cx: (minX + maxX) / 2, cy: (minY + maxY) / 2, w: maxX - minX, h: maxY - minY }\n }\n\n get effectiveDepth(): number {\n const { depth } = this.component.state\n if (depth) return depth\n const { w, h } = this.polygonBounds\n return Math.min(w, h) * 1.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n build() {\n super.build()\n\n const { path = [] as PathPoint[], value = 0, conveyorType = 0, rollWidth } = this.component.state\n if (path.length < 3) return\n\n const depth = this.effectiveDepth\n const { cx: pcx, cy: pcy, w: bw, h: bh } = this.polygonBounds\n\n const frameH = depth * 0.15\n const legH = depth - frameH\n const railW = Math.max(Math.min(bw, bh) * 0.04, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n const railY = depth / 2 - frameH / 2\n\n // Convert 2D path to 3D XZ coords centered at origin\n const pts = path.map((p: PathPoint) => ({\n x: p.x - pcx,\n z: p.y - pcy\n }))\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Side rails + legs at vertices + cross-bracing ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const legPositions: [number, number][] = []\n\n for (let i = 0; i < pts.length; i++) {\n const p0 = pts[i]\n const p1 = pts[(i + 1) % pts.length]\n\n // Rail segment along this edge\n const edgeLen = Math.sqrt((p1.x - p0.x) ** 2 + (p1.z - p0.z) ** 2)\n if (edgeLen < 0.1) continue\n\n const edgeAngle = Math.atan2(p1.x - p0.x, -(p1.z - p0.z))\n const rail = new THREE.BoxGeometry(edgeLen, frameH, railW)\n rail.rotateY(-edgeAngle)\n rail.translate((p0.x + p1.x) / 2, railY, (p0.z + p1.z) / 2)\n frameGeometries.push(rail)\n\n // Leg at this vertex\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(p0.x, depth / 2 - frameH - legH / 2, p0.z)\n frameGeometries.push(leg)\n legPositions.push([p0.x, p0.z])\n }\n\n // Cross-bracing: connect adjacent legs\n const braceSize = legThickness * 0.6\n const braceY = depth / 2 - frameH - legH * 0.35\n\n for (let i = 0; i < legPositions.length; i++) {\n const [x0, z0] = legPositions[i]\n const [x1, z1] = legPositions[(i + 1) % legPositions.length]\n const braceLen = Math.sqrt((x1 - x0) ** 2 + (z1 - z0) ** 2)\n if (braceLen < 1) continue\n const braceAngle = Math.atan2(x1 - x0, -(z1 - z0))\n const brace = new THREE.BoxGeometry(braceLen * 0.85, braceSize, braceSize)\n brace.rotateY(-braceAngle)\n brace.translate((x0 + x1) / 2, braceY, (z0 + z1) / 2)\n frameGeometries.push(brace)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(pts, depth, frameH, railW, value)\n } else {\n this.buildRollers(pts, depth, frameH, railW, bw, bh, rollWidth)\n }\n\n // --- Control box + status light at first vertex ---\n this.buildControlBox(pts, depth, frameH, railW, bw, bh, value)\n }\n\n private buildRollers(\n pts: { x: number; z: number }[],\n depth: number,\n frameH: number,\n railW: number,\n bw: number,\n bh: number,\n rollWidth?: number\n ) {\n const rollerRadius = frameH * 0.4\n const rollerY = depth / 2 - frameH / 2\n const spacing = rollWidth || Math.max(Math.min(bw, bh) * 0.15, 8)\n\n const zMin = Math.min(...pts.map(p => p.z))\n const zMax = Math.max(...pts.map(p => p.z))\n const margin = spacing * 0.5\n\n const rollerMaterial = new THREE.MeshStandardMaterial({\n color: ROLLER_COLOR,\n metalness: 0.9,\n roughness: 0.2\n })\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n for (let z = zMin + margin; z < zMax - margin + 0.5; z += spacing) {\n const span = this.getPolygonWidthAtZ(pts, z)\n if (!span) continue\n\n const rollerLength = span.maxX - span.minX - railW * 2\n if (rollerLength <= rollerRadius * 2) continue\n\n const midX = (span.minX + span.maxX) / 2\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateZ(Math.PI / 2) // axis along X\n roller.translate(midX, rollerY, z)\n rollerGeometries.push(roller)\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(rollerGeometries), rollerMaterial)\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(\n pts: { x: number; z: number }[],\n depth: number,\n frameH: number,\n _railW: number,\n value: number\n ) {\n const beltH = frameH * 0.15\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const shape = new THREE.Shape()\n pts.forEach((p, i) => {\n if (i === 0) shape.moveTo(p.x, -p.z)\n else shape.lineTo(p.x, -p.z)\n })\n shape.closePath()\n\n const beltGeo = new THREE.ExtrudeGeometry(shape, { depth: beltH, bevelEnabled: false })\n beltGeo.rotateX(-Math.PI / 2)\n beltGeo.translate(0, depth / 2, 0)\n\n const beltMesh = new THREE.Mesh(\n beltGeo,\n new THREE.MeshStandardMaterial({ color: fillColor, metalness: 0.0, roughness: 0.9 })\n )\n beltMesh.castShadow = true\n this.object3d.add(beltMesh)\n }\n\n /** Control box + status light at first vertex */\n private buildControlBox(\n pts: { x: number; z: number }[],\n depth: number,\n frameH: number,\n railW: number,\n bw: number,\n bh: number,\n value: number\n ) {\n if (pts.length < 2) return\n\n const boxSize = Math.max(Math.min(bw, bh) * 0.06, 3)\n const boxH = frameH * 0.6\n const railY = depth / 2 - frameH / 2\n\n // Position near first vertex, inward from the edge\n const p0 = pts[0]\n const p1 = pts[1]\n const edgeAngle = Math.atan2(p1.x - p0.x, -(p1.z - p0.z))\n\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = new THREE.BoxGeometry(boxSize, boxH, boxSize)\n boxGeo.rotateY(-edgeAngle)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n boxMesh.position.set(p0.x, railY - frameH / 2 - boxH / 2, p0.z)\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status light\n const lightR = boxSize * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: value > 0 ? 1.5 : 0.2,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(p0.x, boxMesh.position.y + boxH / 2 + lightH / 2, p0.z)\n this.object3d.add(lightMesh)\n }\n\n private getPolygonWidthAtZ(poly: { x: number; z: number }[], z: number): { minX: number; maxX: number } | null {\n const intersections: number[] = []\n for (let i = 0; i < poly.length; i++) {\n const j = (i + 1) % poly.length\n const p1 = poly[i],\n p2 = poly[j]\n if ((p1.z <= z && p2.z > z) || (p2.z <= z && p1.z > z)) {\n const t = (z - p1.z) / (p2.z - p1.z)\n intersections.push(p1.x + t * (p2.x - p1.x))\n }\n }\n if (intersections.length < 2) return null\n return { minX: Math.min(...intersections), maxX: Math.max(...intersections) }\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'conveyorType' in after || 'rollWidth' in after || 'path' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
1
+ {"version":3,"file":"conveyor-join-trapezoid-3d.js","sourceRoot":"","sources":["../src/conveyor-join-trapezoid-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Trapezoid/Polygon Conveyor (ConveyorJoinTrapezoid) 3D Model\n *\n * A funnel-shaped conveyor transition that merges or diverts between\n * conveyors of different widths. Same structure as a straight conveyor\n * — side rails along edges + rollers spanning the width + legs — but\n * following a polygon path (typically pentagon/trapezoid).\n * Structure: polygon edge rails + rollers/belt + legs at vertices\n * + cross-bracing + control box with status light.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xafd0f1, // REVERSE\n 3: 0xffba00, // WARN\n 4: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst ROLLER_COLOR = 0xaaaabc\nconst CONTROL_BOX_COLOR = 0x556677\nconst STATUS_EMISSIVE: Record<number, number> = {\n 0: 0x333333,\n 1: 0x44aaff,\n 2: 0x44aaff,\n 3: 0xffaa00,\n 4: 0xff3333\n}\n\ninterface PathPoint {\n x: number\n y: number\n}\n\nexport class ConveyorJoinTrapezoid3D extends RealObjectGroup {\n private get polygonBounds() {\n const path: PathPoint[] = this.component.state.path || []\n if (path.length === 0) return { cx: 0, cy: 0, w: 100, h: 100 }\n const xs = path.map(p => p.x)\n const ys = path.map(p => p.y)\n const minX = Math.min(...xs),\n maxX = Math.max(...xs)\n const minY = Math.min(...ys),\n maxY = Math.max(...ys)\n return { cx: (minX + maxX) / 2, cy: (minY + maxY) / 2, w: maxX - minX, h: maxY - minY }\n }\n\n get effectiveDepth(): number {\n const { depth } = this.component.state\n if (depth) return depth\n const { w, h } = this.polygonBounds\n return Math.min(w, h) * 1.5\n }\n\n build() {\n super.build()\n\n const { path = [] as PathPoint[], value = 0, conveyorType = 0, rollWidth } = this.component.state\n if (path.length < 3) return\n\n const depth = this.effectiveDepth\n const { cx: pcx, cy: pcy, w: bw, h: bh } = this.polygonBounds\n\n const frameH = depth * 0.15\n const legH = depth - frameH\n const railW = Math.max(Math.min(bw, bh) * 0.04, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n const railY = depth / 2 - frameH / 2\n\n // Convert 2D path to 3D XZ coords centered at origin\n const pts = path.map((p: PathPoint) => ({\n x: p.x - pcx,\n z: p.y - pcy\n }))\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Side rails + legs at vertices + cross-bracing ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const legPositions: [number, number][] = []\n\n for (let i = 0; i < pts.length; i++) {\n const p0 = pts[i]\n const p1 = pts[(i + 1) % pts.length]\n\n // Rail segment along this edge\n const edgeLen = Math.sqrt((p1.x - p0.x) ** 2 + (p1.z - p0.z) ** 2)\n if (edgeLen < 0.1) continue\n\n const edgeAngle = Math.atan2(p1.x - p0.x, -(p1.z - p0.z))\n const rail = new THREE.BoxGeometry(edgeLen, frameH, railW)\n rail.rotateY(-edgeAngle)\n rail.translate((p0.x + p1.x) / 2, railY, (p0.z + p1.z) / 2)\n frameGeometries.push(rail)\n\n // Leg at this vertex\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(p0.x, depth / 2 - frameH - legH / 2, p0.z)\n frameGeometries.push(leg)\n legPositions.push([p0.x, p0.z])\n }\n\n // Cross-bracing: connect adjacent legs\n const braceSize = legThickness * 0.6\n const braceY = depth / 2 - frameH - legH * 0.35\n\n for (let i = 0; i < legPositions.length; i++) {\n const [x0, z0] = legPositions[i]\n const [x1, z1] = legPositions[(i + 1) % legPositions.length]\n const braceLen = Math.sqrt((x1 - x0) ** 2 + (z1 - z0) ** 2)\n if (braceLen < 1) continue\n const braceAngle = Math.atan2(x1 - x0, -(z1 - z0))\n const brace = new THREE.BoxGeometry(braceLen * 0.85, braceSize, braceSize)\n brace.rotateY(-braceAngle)\n brace.translate((x0 + x1) / 2, braceY, (z0 + z1) / 2)\n frameGeometries.push(brace)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Rollers or Belt ---\n if (conveyorType === 1) {\n this.buildBelt(pts, depth, frameH, railW, value)\n } else {\n this.buildRollers(pts, depth, frameH, railW, bw, bh, rollWidth)\n }\n\n // --- Control box + status light at first vertex ---\n this.buildControlBox(pts, depth, frameH, railW, bw, bh, value)\n }\n\n private buildRollers(\n pts: { x: number; z: number }[],\n depth: number,\n frameH: number,\n railW: number,\n bw: number,\n bh: number,\n rollWidth?: number\n ) {\n const rollerRadius = frameH * 0.4\n const rollerY = depth / 2 - frameH / 2\n const spacing = rollWidth || Math.max(Math.min(bw, bh) * 0.15, 8)\n\n const zMin = Math.min(...pts.map(p => p.z))\n const zMax = Math.max(...pts.map(p => p.z))\n const margin = spacing * 0.5\n\n const rollerMaterial = new THREE.MeshStandardMaterial({\n color: ROLLER_COLOR,\n metalness: 0.9,\n roughness: 0.2\n })\n\n const rollerGeometries: THREE.BufferGeometry[] = []\n\n for (let z = zMin + margin; z < zMax - margin + 0.5; z += spacing) {\n const span = this.getPolygonWidthAtZ(pts, z)\n if (!span) continue\n\n const rollerLength = span.maxX - span.minX - railW * 2\n if (rollerLength <= rollerRadius * 2) continue\n\n const midX = (span.minX + span.maxX) / 2\n const roller = new THREE.CylinderGeometry(rollerRadius, rollerRadius, rollerLength, 16)\n roller.rotateZ(Math.PI / 2) // axis along X\n roller.translate(midX, rollerY, z)\n rollerGeometries.push(roller)\n }\n\n if (rollerGeometries.length > 0) {\n const rollerMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(rollerGeometries), rollerMaterial)\n rollerMesh.castShadow = true\n this.object3d.add(rollerMesh)\n }\n }\n\n private buildBelt(\n pts: { x: number; z: number }[],\n depth: number,\n frameH: number,\n _railW: number,\n value: number\n ) {\n const beltH = frameH * 0.15\n const fillColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n const shape = new THREE.Shape()\n pts.forEach((p, i) => {\n if (i === 0) shape.moveTo(p.x, -p.z)\n else shape.lineTo(p.x, -p.z)\n })\n shape.closePath()\n\n const beltGeo = new THREE.ExtrudeGeometry(shape, { depth: beltH, bevelEnabled: false })\n beltGeo.rotateX(-Math.PI / 2)\n beltGeo.translate(0, depth / 2, 0)\n\n const beltMesh = new THREE.Mesh(\n beltGeo,\n new THREE.MeshStandardMaterial({ color: fillColor, metalness: 0.0, roughness: 0.9 })\n )\n beltMesh.castShadow = true\n this.object3d.add(beltMesh)\n }\n\n /** Control box + status light at first vertex */\n private buildControlBox(\n pts: { x: number; z: number }[],\n depth: number,\n frameH: number,\n railW: number,\n bw: number,\n bh: number,\n value: number\n ) {\n if (pts.length < 2) return\n\n const boxSize = Math.max(Math.min(bw, bh) * 0.06, 3)\n const boxH = frameH * 0.6\n const railY = depth / 2 - frameH / 2\n\n // Position near first vertex, inward from the edge\n const p0 = pts[0]\n const p1 = pts[1]\n const edgeAngle = Math.atan2(p1.x - p0.x, -(p1.z - p0.z))\n\n const boxMaterial = new THREE.MeshStandardMaterial({\n color: CONTROL_BOX_COLOR,\n metalness: 0.6,\n roughness: 0.4\n })\n\n const boxGeo = new THREE.BoxGeometry(boxSize, boxH, boxSize)\n boxGeo.rotateY(-edgeAngle)\n const boxMesh = new THREE.Mesh(boxGeo, boxMaterial)\n boxMesh.position.set(p0.x, railY - frameH / 2 - boxH / 2, p0.z)\n boxMesh.castShadow = true\n this.object3d.add(boxMesh)\n\n // Status light\n const lightR = boxSize * 0.25\n const lightH = lightR * 1.2\n const emissiveColor = STATUS_EMISSIVE[value] ?? STATUS_EMISSIVE[0]\n\n const lightMaterial = new THREE.MeshStandardMaterial({\n color: emissiveColor,\n emissive: emissiveColor,\n emissiveIntensity: value > 0 ? 1.5 : 0.2,\n metalness: 0.0,\n roughness: 0.3\n })\n\n const lightGeo = new THREE.CylinderGeometry(lightR, lightR * 0.8, lightH, 12)\n const lightMesh = new THREE.Mesh(lightGeo, lightMaterial)\n lightMesh.position.set(p0.x, boxMesh.position.y + boxH / 2 + lightH / 2, p0.z)\n this.object3d.add(lightMesh)\n }\n\n private getPolygonWidthAtZ(poly: { x: number; z: number }[], z: number): { minX: number; maxX: number } | null {\n const intersections: number[] = []\n for (let i = 0; i < poly.length; i++) {\n const j = (i + 1) % poly.length\n const p1 = poly[i],\n p2 = poly[j]\n if ((p1.z <= z && p2.z > z) || (p2.z <= z && p1.z > z)) {\n const t = (z - p1.z) / (p2.z - p1.z)\n intersections.push(p1.x + t * (p2.x - p1.x))\n }\n }\n if (intersections.length < 2) return null\n return { minX: Math.min(...intersections), maxX: Math.max(...intersections) }\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'conveyorType' in after || 'rollWidth' in after || 'path' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
@@ -7,7 +7,6 @@ declare const MixinPolygon: typeof Component & (new (...args: any[]) => RollerMi
7
7
  export default class ConveyorJoinTrapezoid extends MixinPolygon {
8
8
  get nature(): ComponentNature;
9
9
  get anchors(): never[];
10
- is3dish(): boolean;
11
10
  buildRealObject(): RealObject | undefined;
12
11
  render(context: CanvasRenderingContext2D): void;
13
12
  }
@@ -63,9 +63,6 @@ let ConveyorJoinTrapezoid = class ConveyorJoinTrapezoid extends MixinPolygon {
63
63
  get anchors() {
64
64
  return [];
65
65
  }
66
- is3dish() {
67
- return true;
68
- }
69
66
  buildRealObject() {
70
67
  return new ConveyorJoinTrapezoid3D(this);
71
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-join-trapezoid.js","sourceRoot":"","sources":["../src/conveyor-join-trapezoid.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqC,OAAO,EAAc,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE/G;;GAEG;AACH,OAAO,WAAW,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAEzE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP;wBACE,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,CAAC;qBACT;oBACD;wBACE,OAAO,EAAE,MAAM;wBACf,KAAK,EAAE,CAAC;qBACT;iBACF;aACF;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,yCAAyC;CAChD,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAQpB,sBAAsB;AACtB,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAwE,CAAA;AAGjG,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,YAAY;IAC7D,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,uBAAuB,CAAC,IAAW,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAC/C,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;CACF,CAAA;AArBoB,qBAAqB;IADzC,cAAc,CAAC,yBAAyB,CAAC;GACrB,qBAAqB,CAqBzC;eArBoB,qBAAqB","sourcesContent":["import { Class, Component, ComponentNature, Polygon, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoinTrapezoid3D } from './conveyor-join-trapezoid-3d.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join-trapezoid'\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 3\nconst STAT_ERROR = 4\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinPolygon = MixinRoller(Polygon) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join-trapezoid')\nexport default class ConveyorJoinTrapezoid extends MixinPolygon {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoinTrapezoid3D(this as any)\n }\n\n render(context: CanvasRenderingContext2D) {\n this.getState('animated') && this.animOnState()\n super.render(context)\n }\n}\n"]}
1
+ {"version":3,"file":"conveyor-join-trapezoid.js","sourceRoot":"","sources":["../src/conveyor-join-trapezoid.ts"],"names":[],"mappings":";AAAA,OAAO,EAAqC,OAAO,EAAc,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE/G;;GAEG;AACH,OAAO,WAAW,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAEzE,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE;oBACP;wBACE,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,CAAC;qBACT;oBACD;wBACE,OAAO,EAAE,MAAM;wBACf,KAAK,EAAE,CAAC;qBACT;iBACF;aACF;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,yCAAyC;CAChD,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAQpB,sBAAsB;AACtB,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAwE,CAAA;AAGjG,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,YAAY;IAC7D,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IACD,eAAe;QACb,OAAO,IAAI,uBAAuB,CAAC,IAAW,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,CAAC,OAAiC;QACtC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAC/C,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;CACF,CAAA;AAhBoB,qBAAqB;IADzC,cAAc,CAAC,yBAAyB,CAAC;GACrB,qBAAqB,CAgBzC;eAhBoB,qBAAqB","sourcesContent":["import { Class, Component, ComponentNature, Polygon, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoinTrapezoid3D } from './conveyor-join-trapezoid-3d.js'\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join-trapezoid'\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 3\nconst STAT_ERROR = 4\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinPolygon = MixinRoller(Polygon) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join-trapezoid')\nexport default class ConveyorJoinTrapezoid extends MixinPolygon {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoinTrapezoid3D(this as any)\n }\n\n render(context: CanvasRenderingContext2D) {\n this.getState('animated') && this.animOnState()\n super.render(context)\n }\n}\n"]}
@@ -8,7 +8,6 @@ export default class ConveyorJoin extends MixinDonut {
8
8
  get nature(): ComponentNature;
9
9
  get anchors(): never[];
10
10
  get fillStyle(): string;
11
- is3dish(): boolean;
12
11
  buildRealObject(): RealObject | undefined;
13
12
  contains(x: number, y: number): boolean;
14
13
  render(ctx: CanvasRenderingContext2D): void;
@@ -132,9 +132,6 @@ let ConveyorJoin = class ConveyorJoin extends MixinDonut {
132
132
  const FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b'];
133
133
  return FILL_STYLES[this.value || 0] || FILL_STYLES[0];
134
134
  }
135
- is3dish() {
136
- return true;
137
- }
138
135
  buildRealObject() {
139
136
  return new ConveyorJoin3D(this);
140
137
  }
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor-join.js","sourceRoot":"","sources":["../src/conveyor-join.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, Donut, POSITION, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoin3D } from './conveyor-join-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'angle',\n label: 'start-angle',\n name: 'startAngle'\n },\n {\n type: 'angle',\n label: 'end-angle',\n name: 'endAngle'\n },\n {\n type: 'number',\n label: 'ratio',\n name: 'ratio'\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join'\n}\n\nvar controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy, rx, ry, startAngle, endAngle } = component.model\n\n var { x, y } = component.transcoordP2S(point.x, point.y)\n\n const angle = (startAngle + endAngle) / 2\n\n /* 원점으로부터 최대 거리 */\n const dx = Math.abs(rx * Math.sin(angle))\n const dy = Math.abs(ry * Math.cos(angle))\n const distance = Math.sqrt(dx * dx + dy * dy)\n\n /* 원점으로부터 현재 컨트롤 위치까지의 거리 */\n const px = Math.abs(cx - x)\n const py = Math.abs(cy - y)\n const pdistance = Math.sqrt(px * px + py * py)\n\n var ratio = (pdistance / distance) * 100\n\n ratio = ratio >= 100 || ratio <= -100 ? 100 : Math.abs(ratio)\n\n component.set({ ratio })\n }\n}\n\nvar antiClockWiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0 && theta <= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0 && theta >= -Math.PI / 2) theta = -Math.PI / 2\n\n const startAngle = (-theta + Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n\n component.set({ startAngle })\n }\n}\n\nvar clockwiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0) if (theta >= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0) if (theta <= -Math.PI / 2) theta = -Math.PI / 2\n\n var endAngle = -theta + Math.PI / 2\n\n component.set({ endAngle })\n }\n}\n\nfunction normalizeAngle(angle: number): number {\n angle = angle % (2 * Math.PI)\n if (angle <= -Math.PI) {\n angle += 2 * Math.PI\n } else if (angle > Math.PI) {\n angle -= 2 * Math.PI\n }\n return angle\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinDonut = MixinRoller(Donut) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join')\nexport default class ConveyorJoin extends MixinDonut {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n // mixin의 패턴 fillStyle을 오버라이드 — 방사선 롤러를 직접 그리므로 단색 fill 사용\n get fillStyle() {\n const FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b']\n return FILL_STYLES[(this as any).value || 0] || FILL_STYLES[0]\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoin3D(this as any)\n }\n\n contains(x: number, y: number) {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n rx = Math.abs(rx)\n ry = Math.abs(ry)\n\n const normx = (x - cx) / (rx * 2 - 0.5)\n const normy = (y - cy) / (ry * 2 - 0.5)\n const ratiox = (x - cx) / ((rx / 100) * ratio * 2 - 0.5)\n const ratioy = (y - cy) / ((ry / 100) * ratio * 2 - 0.5)\n\n if (normx * normx + normy * normy < 0.25 && ratiox * ratiox + ratioy * ratioy > 0.25) {\n const angle = normalizeAngle(Math.atan2(-normy, normx) - Math.PI / 2)\n\n if (startAngle <= endAngle) {\n if (angle >= startAngle && angle <= endAngle) return true\n } else {\n // wraparound: startAngle > endAngle (예: π → 0)\n if (angle >= startAngle || angle <= endAngle) return true\n }\n }\n\n return false\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, animated = false, rollWidth = 10, conveyorType = 0 } = this.state\n\n animated && this.animOnState()\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n // 2D 각도 변환\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n // 호 영역 path\n ctx.beginPath()\n ctx.ellipse(cx, cy, outerRx, outerRy, 0, sa, ea)\n ctx.ellipse(cx, cy, innerRx, innerRy, 0, ea, sa, true)\n ctx.closePath()\n\n // 롤러 타입일 때: base class가 단색 fill 후, 여기서 방사선 롤러 라인 추가\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n\n const { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, rollWidth = 10, conveyorType = 0 } = this.state\n if (conveyorType === 1) return // 벨트 타입은 패턴 사용\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n const STROKE_STYLES = ['#999', '#87b1db', '#87b1db', '#d96f21', '#a73928']\n const v = (this as any).value || 0\n\n const midR = (outerRx + innerRx) / 2\n const arcLen = midR * Math.abs(ea - sa)\n const spacing = Math.max(rollWidth as number, 5)\n const count = Math.max(1, Math.floor(arcLen / spacing))\n\n ctx.save()\n ctx.strokeStyle = STROKE_STYLES[v] || STROKE_STYLES[0]\n ctx.lineWidth = Math.max(0.5, spacing * 0.12)\n\n for (let i = 1; i <= count; i++) {\n const t = i / (count + 1)\n const angle = sa + (ea - sa) * t\n\n ctx.beginPath()\n ctx.moveTo(outerRx * Math.cos(angle) + cx, outerRy * Math.sin(angle) + cy)\n ctx.lineTo(innerRx * Math.cos(angle) + cx, innerRy * Math.sin(angle) + cy)\n ctx.stroke()\n }\n ctx.restore()\n }\n\n get controls() {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n\n var controls = []\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(startAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(startAngle),\n handler: antiClockWiseControlHandler\n })\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(endAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(endAngle),\n handler: clockwiseControlHandler\n })\n\n const angle = (startAngle + endAngle) / 2\n controls.push({\n x: cx + ((rx * ratio) / 100) * Math.sin(angle),\n y: cy - ((ry * ratio) / 100) * Math.cos(angle),\n handler: controlHandler\n })\n\n return controls\n }\n}\n"]}
1
+ {"version":3,"file":"conveyor-join.js","sourceRoot":"","sources":["../src/conveyor-join.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, Donut, POSITION, RealObject, sceneComponent } from '@hatiolab/things-scene'\n\nimport MixinRoller from './mixin-conveyor.js'\nimport { ConveyorJoin3D } from './conveyor-join-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'angle',\n label: 'start-angle',\n name: 'startAngle'\n },\n {\n type: 'angle',\n label: 'end-angle',\n name: 'endAngle'\n },\n {\n type: 'number',\n label: 'ratio',\n name: 'ratio'\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor-join'\n}\n\nvar controlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy, rx, ry, startAngle, endAngle } = component.model\n\n var { x, y } = component.transcoordP2S(point.x, point.y)\n\n const angle = (startAngle + endAngle) / 2\n\n /* 원점으로부터 최대 거리 */\n const dx = Math.abs(rx * Math.sin(angle))\n const dy = Math.abs(ry * Math.cos(angle))\n const distance = Math.sqrt(dx * dx + dy * dy)\n\n /* 원점으로부터 현재 컨트롤 위치까지의 거리 */\n const px = Math.abs(cx - x)\n const py = Math.abs(cy - y)\n const pdistance = Math.sqrt(px * px + py * py)\n\n var ratio = (pdistance / distance) * 100\n\n ratio = ratio >= 100 || ratio <= -100 ? 100 : Math.abs(ratio)\n\n component.set({ ratio })\n }\n}\n\nvar antiClockWiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0 && theta <= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0 && theta >= -Math.PI / 2) theta = -Math.PI / 2\n\n const startAngle = (-theta + Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n\n component.set({ startAngle })\n }\n}\n\nvar clockwiseControlHandler = {\n ondragmove: function (point: POSITION, index: number, component: Component) {\n var { cx, cy } = component.model\n\n var transcoorded = component.transcoordP2S(point.x, point.y)\n\n var theta = Math.atan2(-(transcoorded.y - cy), transcoorded.x - cx)\n\n if (theta > 0) if (theta >= Math.PI / 2) theta = Math.PI / 2\n if (theta < 0) if (theta <= -Math.PI / 2) theta = -Math.PI / 2\n\n var endAngle = -theta + Math.PI / 2\n\n component.set({ endAngle })\n }\n}\n\nfunction normalizeAngle(angle: number): number {\n angle = angle % (2 * Math.PI)\n if (angle <= -Math.PI) {\n angle += 2 * Math.PI\n } else if (angle > Math.PI) {\n angle -= 2 * Math.PI\n }\n return angle\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinDonut = MixinRoller(Donut) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor-join')\nexport default class ConveyorJoin extends MixinDonut {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n // mixin의 패턴 fillStyle을 오버라이드 — 방사선 롤러를 직접 그리므로 단색 fill 사용\n get fillStyle() {\n const FILL_STYLES = ['#ccc', '#afd0f1', '#afd0f1', '#ffba00', '#e9746b']\n return FILL_STYLES[(this as any).value || 0] || FILL_STYLES[0]\n }\n buildRealObject(): RealObject | undefined {\n return new ConveyorJoin3D(this as any)\n }\n\n contains(x: number, y: number) {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n rx = Math.abs(rx)\n ry = Math.abs(ry)\n\n const normx = (x - cx) / (rx * 2 - 0.5)\n const normy = (y - cy) / (ry * 2 - 0.5)\n const ratiox = (x - cx) / ((rx / 100) * ratio * 2 - 0.5)\n const ratioy = (y - cy) / ((ry / 100) * ratio * 2 - 0.5)\n\n if (normx * normx + normy * normy < 0.25 && ratiox * ratiox + ratioy * ratioy > 0.25) {\n const angle = normalizeAngle(Math.atan2(-normy, normx) - Math.PI / 2)\n\n if (startAngle <= endAngle) {\n if (angle >= startAngle && angle <= endAngle) return true\n } else {\n // wraparound: startAngle > endAngle (예: π → 0)\n if (angle >= startAngle || angle <= endAngle) return true\n }\n }\n\n return false\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, animated = false, rollWidth = 10, conveyorType = 0 } = this.state\n\n animated && this.animOnState()\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n // 2D 각도 변환\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n // 호 영역 path\n ctx.beginPath()\n ctx.ellipse(cx, cy, outerRx, outerRy, 0, sa, ea)\n ctx.ellipse(cx, cy, innerRx, innerRy, 0, ea, sa, true)\n ctx.closePath()\n\n // 롤러 타입일 때: base class가 단색 fill 후, 여기서 방사선 롤러 라인 추가\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n\n const { ratio = 50, cx, cy, rx, ry, startAngle = 0, endAngle = Math.PI / 2, rollWidth = 10, conveyorType = 0 } = this.state\n if (conveyorType === 1) return // 벨트 타입은 패턴 사용\n\n const outerRx = Math.abs(rx)\n const outerRy = Math.abs(ry)\n const innerRx = Math.abs((rx / 100) * ratio)\n const innerRy = Math.abs((ry / 100) * ratio)\n\n const sa = (startAngle - Math.PI / 2 - Math.PI * 2) % (Math.PI * 2)\n const ea = endAngle - Math.PI / 2\n\n const STROKE_STYLES = ['#999', '#87b1db', '#87b1db', '#d96f21', '#a73928']\n const v = (this as any).value || 0\n\n const midR = (outerRx + innerRx) / 2\n const arcLen = midR * Math.abs(ea - sa)\n const spacing = Math.max(rollWidth as number, 5)\n const count = Math.max(1, Math.floor(arcLen / spacing))\n\n ctx.save()\n ctx.strokeStyle = STROKE_STYLES[v] || STROKE_STYLES[0]\n ctx.lineWidth = Math.max(0.5, spacing * 0.12)\n\n for (let i = 1; i <= count; i++) {\n const t = i / (count + 1)\n const angle = sa + (ea - sa) * t\n\n ctx.beginPath()\n ctx.moveTo(outerRx * Math.cos(angle) + cx, outerRy * Math.sin(angle) + cy)\n ctx.lineTo(innerRx * Math.cos(angle) + cx, innerRy * Math.sin(angle) + cy)\n ctx.stroke()\n }\n ctx.restore()\n }\n\n get controls() {\n var { cx, cy, rx, ry, ratio, startAngle, endAngle } = this.state\n\n var controls = []\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(startAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(startAngle),\n handler: antiClockWiseControlHandler\n })\n\n controls.push({\n x: cx + ((rx + (rx * ratio) / 100) / 2) * Math.sin(endAngle),\n y: cy - ((ry + (ry * ratio) / 100) / 2) * Math.cos(endAngle),\n handler: clockwiseControlHandler\n })\n\n const angle = (startAngle + endAngle) / 2\n controls.push({\n x: cx + ((rx * ratio) / 100) * Math.sin(angle),\n y: cy - ((ry * ratio) / 100) * Math.cos(angle),\n handler: controlHandler\n })\n\n return controls\n }\n}\n"]}
@@ -9,7 +9,6 @@ export default class Conveyor extends MixinShape {
9
9
  render(ctx: CanvasRenderingContext2D): void;
10
10
  onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
11
11
  get anchors(): never[];
12
- is3dish(): boolean;
13
12
  buildRealObject(): RealObject | undefined;
14
13
  }
15
14
  export {};
package/dist/conveyor.js CHANGED
@@ -89,9 +89,6 @@ let Conveyor = class Conveyor extends MixinShape {
89
89
  get anchors() {
90
90
  return [];
91
91
  }
92
- is3dish() {
93
- return true;
94
- }
95
92
  buildRealObject() {
96
93
  return new Conveyor3D(this);
97
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"conveyor.js","sourceRoot":"","sources":["../src/conveyor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { Conveyor3D } from './conveyor-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'select',\n label: 'conveyor-orientation',\n name: 'orientation',\n property: {\n options: [\n { display: 'Auto', value: '' },\n { display: 'Horizontal', value: 'horizontal' },\n { display: 'Vertical', value: 'vertical' }\n ]\n }\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinRoller(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor')\n@sceneComponent('conveyor-belt')\nexport default class Conveyor extends MixinShape {\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated = false } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('orientation' in after || 'conveyorType' in after || 'rollWidth' in after || 'value' in after) {\n delete (this as any)._roller_pattern\n delete (this as any)._roller_pattern_v\n delete (this as any)._pattern_image\n delete (this as any)._pattern_image_origin\n ;(this as any).clearCache('fillStyle')\n ;(this as any).clearCache('conveyorType')\n this.invalidate()\n }\n super.onchange(after, before)\n }\n\n get anchors() {\n return []\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Conveyor3D(this as any)\n }\n}\n"]}
1
+ {"version":3,"file":"conveyor.js","sourceRoot":"","sources":["../src/conveyor.ts"],"names":[],"mappings":"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","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinRoller from './mixin-conveyor.js'\nimport { Conveyor3D } from './conveyor-3d.js'\n\n// MixinRoller에서 확장된 클래스의 인터페이스 정의\ninterface RollerMixin {\n animOnState(): void\n conveyorType: number\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'conveyor-type',\n name: 'conveyorType',\n property: {\n options: [\n {\n display: 'Roller',\n value: 0\n },\n {\n display: 'Belt',\n value: 1\n }\n ]\n }\n },\n {\n type: 'number',\n label: 'roll-width',\n name: 'rollWidth'\n },\n {\n type: 'select',\n label: 'conveyor-orientation',\n name: 'orientation',\n property: {\n options: [\n { display: 'Auto', value: '' },\n { display: 'Horizontal', value: 'horizontal' },\n { display: 'Vertical', value: 'vertical' }\n ]\n }\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/conveyor'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinRoller(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => RollerMixin)\n\n@sceneComponent('conveyor')\n@sceneComponent('conveyor-belt')\nexport default class Conveyor extends MixinShape {\n get nature() {\n return NATURE\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated = false } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n }\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('orientation' in after || 'conveyorType' in after || 'rollWidth' in after || 'value' in after) {\n delete (this as any)._roller_pattern\n delete (this as any)._roller_pattern_v\n delete (this as any)._pattern_image\n delete (this as any)._pattern_image_origin\n ;(this as any).clearCache('fillStyle')\n ;(this as any).clearCache('conveyorType')\n this.invalidate()\n }\n super.onchange(after, before)\n }\n\n get anchors() {\n return []\n }\n buildRealObject(): RealObject | undefined {\n return new Conveyor3D(this as any)\n }\n}\n"]}
@@ -1,11 +1,6 @@
1
1
  import { RealObjectGroup } from '@hatiolab/things-scene';
2
2
  export declare class Scanner3D extends RealObjectGroup {
3
3
  get effectiveDepth(): number;
4
- get position(): {
5
- x: number;
6
- y: any;
7
- z: number;
8
- };
9
4
  build(): void;
10
5
  updateDimension(): void;
11
6
  onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
@@ -25,14 +25,6 @@ export class Scanner3D extends RealObjectGroup {
25
25
  const { width, height, depth } = this.component.state;
26
26
  return depth || Math.max(width, height) * 2.5;
27
27
  }
28
- get position() {
29
- const { zPos = 0 } = this.component.state;
30
- return {
31
- x: this.cx,
32
- y: zPos + this.effectiveDepth / 2,
33
- z: this.cy
34
- };
35
- }
36
28
  build() {
37
29
  super.build();
38
30
  const { width, height, value = 0 } = this.component.state;
@@ -1 +1 @@
1
- {"version":3,"file":"scanner-3d.js","sourceRoot":"","sources":["../src/scanner-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Scanner Gate 3D Model\n *\n * An overhead barcode/RFID scanner gate straddling a conveyor line.\n * Two vertical pillars connected by a top crossbar, with a translucent\n * scan window, LED status strip, and warning stripes at the base.\n * A cable conduit runs down one pillar for industrial character.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, THREE.Color> = {\n 0: new THREE.Color(0x000000), // IDLE — dark\n 1: new THREE.Color(0xafd0f1), // RUN — blue\n 2: new THREE.Color(0xffba00), // WARN — yellow/chute full\n 3: new THREE.Color(0xe9746b) // ERROR — red\n}\n\nconst PILLAR_COLOR = 0x333333\nconst LED_IDLE_COLOR = 0x444444\nconst WARNING_STRIPE = 0xffcc00\n\nexport class Scanner3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.max(width, height) * 2.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n build() {\n super.build()\n\n const { width, height, value = 0 } = this.component.state\n const depth = this.effectiveDepth\n\n const pillarW = Math.max(width * 0.3, 3)\n const pillarD = Math.max(height * 0.15, 3)\n const barH = Math.max(depth * 0.08, 3)\n const pillarH = depth - barH\n const ledH = Math.max(barH * 0.3, 1)\n\n const statusColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n // --- Pillar material ---\n const pillarMaterial = new THREE.MeshStandardMaterial({\n color: PILLAR_COLOR,\n metalness: 0.7,\n roughness: 0.4\n })\n\n // --- Pillars + top bar (merged) ---\n const structGeometries: THREE.BufferGeometry[] = []\n\n // Front pillar (세로 방향 배치)\n const frontPillar = new THREE.BoxGeometry(pillarW, pillarH, pillarD)\n frontPillar.translate(0, -depth / 2 + pillarH / 2, -height / 2 + pillarD / 2)\n structGeometries.push(frontPillar)\n\n // Back pillar\n const backPillar = new THREE.BoxGeometry(pillarW, pillarH, pillarD)\n backPillar.translate(0, -depth / 2 + pillarH / 2, height / 2 - pillarD / 2)\n structGeometries.push(backPillar)\n\n // Top bar spanning between pillars (along Z)\n const topBar = new THREE.BoxGeometry(pillarW, barH, height)\n topBar.translate(0, depth / 2 - barH / 2, 0)\n structGeometries.push(topBar)\n\n const structMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(structGeometries), pillarMaterial)\n structMesh.castShadow = true\n structMesh.receiveShadow = true\n this.object3d.add(structMesh)\n\n // --- Warning stripes at pillar bases (yellow/black hazard marking) ---\n const stripeH = pillarH * 0.06\n const stripeMaterial = new THREE.MeshStandardMaterial({\n color: WARNING_STRIPE,\n metalness: 0.0,\n roughness: 0.8\n })\n const stripeGeometries: THREE.BufferGeometry[] = []\n for (const zSign of [-1, 1]) {\n const stripe = new THREE.BoxGeometry(pillarW * 1.02, stripeH, pillarD * 1.02)\n stripe.translate(0, -depth / 2 + stripeH / 2, zSign * (height / 2 - pillarD / 2))\n stripeGeometries.push(stripe)\n }\n const stripeMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(stripeGeometries), stripeMaterial)\n this.object3d.add(stripeMesh)\n\n // --- Cable conduit (thin box running down one pillar) ---\n const conduitW = pillarW * 0.15\n const conduitD = pillarD * 0.2\n const conduitH = pillarH * 0.7\n const conduitMaterial = new THREE.MeshStandardMaterial({\n color: 0x222222,\n metalness: 0.3,\n roughness: 0.7\n })\n const conduitGeo = new THREE.BoxGeometry(conduitW, conduitH, conduitD)\n const conduitMesh = new THREE.Mesh(conduitGeo, conduitMaterial)\n conduitMesh.position.set(\n pillarW / 2 - conduitW / 2,\n -depth / 2 + conduitH / 2 + pillarH * 0.15,\n -height / 2 + pillarD + conduitD / 2\n )\n this.object3d.add(conduitMesh)\n\n // --- Scanner window (translucent emissive plane inside the gate) ---\n const windowD = height - pillarD * 2\n const windowH = pillarH * 0.6\n const windowEmissiveIntensity = value > 0 ? 0.8 : 0.1\n\n const windowMaterial = new THREE.MeshStandardMaterial({\n color: 0x000000,\n emissive: statusColor,\n emissiveIntensity: windowEmissiveIntensity,\n transparent: true,\n opacity: 0.35,\n side: THREE.DoubleSide\n })\n\n const windowGeometry = new THREE.PlaneGeometry(windowD, windowH)\n windowGeometry.rotateY(Math.PI / 2)\n const windowMesh = new THREE.Mesh(windowGeometry, windowMaterial)\n windowMesh.position.set(pillarW * 0.3, -depth / 2 + pillarH * 0.55, 0)\n this.object3d.add(windowMesh)\n\n // --- LED strip on top ---\n const ledW = pillarW * 0.5\n const ledD = height - pillarD * 0.5\n const ledColor = value > 0 ? statusColor : new THREE.Color(LED_IDLE_COLOR)\n\n const ledMaterial = new THREE.MeshStandardMaterial({\n color: ledColor,\n emissive: ledColor,\n emissiveIntensity: value > 0 ? 1.0 : 0.2\n })\n\n const ledGeometry = new THREE.BoxGeometry(ledW, ledH, ledD)\n const ledMesh = new THREE.Mesh(ledGeometry, ledMaterial)\n ledMesh.position.set(0, depth / 2 + ledH / 2, 0)\n this.object3d.add(ledMesh)\n\n // --- Laser line (thin red beam across the gate, only when running) ---\n if (value === 1) {\n const laserMaterial = new THREE.MeshBasicMaterial({ color: 0xcc3300 })\n const laserGeometry = new THREE.BoxGeometry(0.5, pillarH * 0.005, windowD)\n const laserMesh = new THREE.Mesh(laserGeometry, laserMaterial)\n laserMesh.position.set(0, -depth / 2 + pillarH * 0.5, 0)\n this.object3d.add(laserMesh)\n }\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'width' in after || 'height' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
1
+ {"version":3,"file":"scanner-3d.js","sourceRoot":"","sources":["../src/scanner-3d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,WAAW,GAAgC;IAC/C,CAAC,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,cAAc;IAC5C,CAAC,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,aAAa;IAC3C,CAAC,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,2BAA2B;IACzD,CAAC,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,cAAc;CAC5C,CAAA;AAED,MAAM,YAAY,GAAG,QAAQ,CAAA;AAC7B,MAAM,cAAc,GAAG,QAAQ,CAAA;AAC/B,MAAM,cAAc,GAAG,QAAQ,CAAA;AAE/B,MAAM,OAAO,SAAU,SAAQ,eAAe;IAC5C,IAAI,cAAc;QAChB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QACrD,OAAO,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAA;IAC/C,CAAC;IAED,KAAK;QACH,KAAK,CAAC,KAAK,EAAE,CAAA;QAEb,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAA;QAEjC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QACtC,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,CAAA;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QAEpC,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;QAExD,0BAA0B;QAC1B,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACpD,KAAK,EAAE,YAAY;YACnB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QAEF,qCAAqC;QACrC,MAAM,gBAAgB,GAA2B,EAAE,CAAA;QAEnD,0BAA0B;QAC1B,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACpE,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAA;QAC7E,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAElC,cAAc;QACd,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACnE,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAA;QAC3E,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAEjC,6CAA6C;QAC7C,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QAC3D,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QAC5C,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAE7B,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,cAAc,CAAC,CAAA;QACxG,UAAU,CAAC,UAAU,GAAG,IAAI,CAAA;QAC5B,UAAU,CAAC,aAAa,GAAG,IAAI,CAAA;QAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAE7B,wEAAwE;QACxE,MAAM,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;QAC9B,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACpD,KAAK,EAAE,cAAc;YACrB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QACF,MAAM,gBAAgB,GAA2B,EAAE,CAAA;QACnD,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;YAC7E,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;YACjF,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC/B,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,cAAc,CAAC,CAAA;QACxG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAE7B,2DAA2D;QAC3D,MAAM,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAA;QAC/B,MAAM,QAAQ,GAAG,OAAO,GAAG,GAAG,CAAA;QAC9B,MAAM,QAAQ,GAAG,OAAO,GAAG,GAAG,CAAA;QAC9B,MAAM,eAAe,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACrD,KAAK,EAAE,QAAQ;YACf,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CAAA;QACF,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACtE,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;QAC/D,WAAW,CAAC,QAAQ,CAAC,GAAG,CACtB,OAAO,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,EAC1B,CAAC,KAAK,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,OAAO,GAAG,IAAI,EAC1C,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,GAAG,QAAQ,GAAG,CAAC,CACrC,CAAA;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAE9B,sEAAsE;QACtE,MAAM,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,CAAA;QACpC,MAAM,OAAO,GAAG,OAAO,GAAG,GAAG,CAAA;QAC7B,MAAM,uBAAuB,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAErD,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACpD,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,WAAW;YACrB,iBAAiB,EAAE,uBAAuB;YAC1C,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,KAAK,CAAC,UAAU;SACvB,CAAC,CAAA;QAEF,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAChE,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QACnC,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;QACjE,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QACtE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAE7B,2BAA2B;QAC3B,MAAM,IAAI,GAAG,OAAO,GAAG,GAAG,CAAA;QAC1B,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,GAAG,CAAA;QACnC,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;QAE1E,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACjD,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,QAAQ;YAClB,iBAAiB,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;SACzC,CAAC,CAAA;QAEF,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QAChD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAE1B,wEAAwE;QACxE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;YACtE,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,EAAE,OAAO,CAAC,CAAA;YAC1E,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;YAC9D,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;YACxD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,eAAe,KAAI,CAAC;IAEpB,QAAQ,CAAC,KAA8B,EAAE,MAA+B;QACtE,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAClF,IAAI,CAAC,MAAM,EAAE,CAAA;YACb,OAAM;QACR,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC/B,CAAC;IAED,WAAW,KAAI,CAAC;CACjB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Scanner Gate 3D Model\n *\n * An overhead barcode/RFID scanner gate straddling a conveyor line.\n * Two vertical pillars connected by a top crossbar, with a translucent\n * scan window, LED status strip, and warning stripes at the base.\n * A cable conduit runs down one pillar for industrial character.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, THREE.Color> = {\n 0: new THREE.Color(0x000000), // IDLE — dark\n 1: new THREE.Color(0xafd0f1), // RUN — blue\n 2: new THREE.Color(0xffba00), // WARN — yellow/chute full\n 3: new THREE.Color(0xe9746b) // ERROR — red\n}\n\nconst PILLAR_COLOR = 0x333333\nconst LED_IDLE_COLOR = 0x444444\nconst WARNING_STRIPE = 0xffcc00\n\nexport class Scanner3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.max(width, height) * 2.5\n }\n\n build() {\n super.build()\n\n const { width, height, value = 0 } = this.component.state\n const depth = this.effectiveDepth\n\n const pillarW = Math.max(width * 0.3, 3)\n const pillarD = Math.max(height * 0.15, 3)\n const barH = Math.max(depth * 0.08, 3)\n const pillarH = depth - barH\n const ledH = Math.max(barH * 0.3, 1)\n\n const statusColor = FILL_COLORS[value] ?? FILL_COLORS[0]\n\n // --- Pillar material ---\n const pillarMaterial = new THREE.MeshStandardMaterial({\n color: PILLAR_COLOR,\n metalness: 0.7,\n roughness: 0.4\n })\n\n // --- Pillars + top bar (merged) ---\n const structGeometries: THREE.BufferGeometry[] = []\n\n // Front pillar (세로 방향 배치)\n const frontPillar = new THREE.BoxGeometry(pillarW, pillarH, pillarD)\n frontPillar.translate(0, -depth / 2 + pillarH / 2, -height / 2 + pillarD / 2)\n structGeometries.push(frontPillar)\n\n // Back pillar\n const backPillar = new THREE.BoxGeometry(pillarW, pillarH, pillarD)\n backPillar.translate(0, -depth / 2 + pillarH / 2, height / 2 - pillarD / 2)\n structGeometries.push(backPillar)\n\n // Top bar spanning between pillars (along Z)\n const topBar = new THREE.BoxGeometry(pillarW, barH, height)\n topBar.translate(0, depth / 2 - barH / 2, 0)\n structGeometries.push(topBar)\n\n const structMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(structGeometries), pillarMaterial)\n structMesh.castShadow = true\n structMesh.receiveShadow = true\n this.object3d.add(structMesh)\n\n // --- Warning stripes at pillar bases (yellow/black hazard marking) ---\n const stripeH = pillarH * 0.06\n const stripeMaterial = new THREE.MeshStandardMaterial({\n color: WARNING_STRIPE,\n metalness: 0.0,\n roughness: 0.8\n })\n const stripeGeometries: THREE.BufferGeometry[] = []\n for (const zSign of [-1, 1]) {\n const stripe = new THREE.BoxGeometry(pillarW * 1.02, stripeH, pillarD * 1.02)\n stripe.translate(0, -depth / 2 + stripeH / 2, zSign * (height / 2 - pillarD / 2))\n stripeGeometries.push(stripe)\n }\n const stripeMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(stripeGeometries), stripeMaterial)\n this.object3d.add(stripeMesh)\n\n // --- Cable conduit (thin box running down one pillar) ---\n const conduitW = pillarW * 0.15\n const conduitD = pillarD * 0.2\n const conduitH = pillarH * 0.7\n const conduitMaterial = new THREE.MeshStandardMaterial({\n color: 0x222222,\n metalness: 0.3,\n roughness: 0.7\n })\n const conduitGeo = new THREE.BoxGeometry(conduitW, conduitH, conduitD)\n const conduitMesh = new THREE.Mesh(conduitGeo, conduitMaterial)\n conduitMesh.position.set(\n pillarW / 2 - conduitW / 2,\n -depth / 2 + conduitH / 2 + pillarH * 0.15,\n -height / 2 + pillarD + conduitD / 2\n )\n this.object3d.add(conduitMesh)\n\n // --- Scanner window (translucent emissive plane inside the gate) ---\n const windowD = height - pillarD * 2\n const windowH = pillarH * 0.6\n const windowEmissiveIntensity = value > 0 ? 0.8 : 0.1\n\n const windowMaterial = new THREE.MeshStandardMaterial({\n color: 0x000000,\n emissive: statusColor,\n emissiveIntensity: windowEmissiveIntensity,\n transparent: true,\n opacity: 0.35,\n side: THREE.DoubleSide\n })\n\n const windowGeometry = new THREE.PlaneGeometry(windowD, windowH)\n windowGeometry.rotateY(Math.PI / 2)\n const windowMesh = new THREE.Mesh(windowGeometry, windowMaterial)\n windowMesh.position.set(pillarW * 0.3, -depth / 2 + pillarH * 0.55, 0)\n this.object3d.add(windowMesh)\n\n // --- LED strip on top ---\n const ledW = pillarW * 0.5\n const ledD = height - pillarD * 0.5\n const ledColor = value > 0 ? statusColor : new THREE.Color(LED_IDLE_COLOR)\n\n const ledMaterial = new THREE.MeshStandardMaterial({\n color: ledColor,\n emissive: ledColor,\n emissiveIntensity: value > 0 ? 1.0 : 0.2\n })\n\n const ledGeometry = new THREE.BoxGeometry(ledW, ledH, ledD)\n const ledMesh = new THREE.Mesh(ledGeometry, ledMaterial)\n ledMesh.position.set(0, depth / 2 + ledH / 2, 0)\n this.object3d.add(ledMesh)\n\n // --- Laser line (thin red beam across the gate, only when running) ---\n if (value === 1) {\n const laserMaterial = new THREE.MeshBasicMaterial({ color: 0xcc3300 })\n const laserGeometry = new THREE.BoxGeometry(0.5, pillarH * 0.005, windowD)\n const laserMesh = new THREE.Mesh(laserGeometry, laserMaterial)\n laserMesh.position.set(0, -depth / 2 + pillarH * 0.5, 0)\n this.object3d.add(laserMesh)\n }\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if ('value' in after || 'width' in after || 'height' in after || 'depth' in after) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
package/dist/scanner.d.ts CHANGED
@@ -6,7 +6,6 @@ export default class Scanner extends MixinShape {
6
6
  get nature(): ComponentNature;
7
7
  get anchors(): never[];
8
8
  render(ctx: CanvasRenderingContext2D): void;
9
- is3dish(): boolean;
10
9
  buildRealObject(): RealObject | undefined;
11
10
  }
12
11
  export {};
package/dist/scanner.js CHANGED
@@ -50,9 +50,6 @@ let Scanner = class Scanner extends MixinShape {
50
50
  ctx.quadraticCurveTo(left, top, left + radius, top);
51
51
  ctx.clip();
52
52
  }
53
- is3dish() {
54
- return true;
55
- }
56
53
  buildRealObject() {
57
54
  return new Scanner3D(this);
58
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAO3C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;CACF,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAEpB,sBAAsB;AACtB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAyE,CAAA;AAGzG,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAC7C,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7C,IAAI,MAAM,GAAG,KAAK,GAAG,EAAE,CAAA;QAEvB,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QAC9B,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACtC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACnE,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QAC/C,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACrF,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACvC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QACrE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QAC9B,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACnD,GAAG,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,SAAS,CAAC,IAAW,CAAC,CAAA;IACnC,CAAC;CACF,CAAA;AAlCoB,OAAO;IAD3B,cAAc,CAAC,SAAS,CAAC;GACL,OAAO,CAkC3B;eAlCoB,OAAO","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, sceneComponent, Shape } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinScanner from './mixin-scanner.js'\nimport { Scanner3D } from './scanner-3d.js'\n\n// MixinScanner에서 확장된 클래스의 인터페이스 정의\ninterface ScannerMixin {\n // 필요한 메서드나 속성을 여기에 정의\n}\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 },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ]\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 2\nconst STAT_ERROR = 3\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinScanner(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => ScannerMixin)\n\n@sceneComponent('scanner')\nexport default class Scanner extends MixinShape {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top } = this.state\n\n var radius = width / 10\n\n ctx.beginPath()\n ctx.moveTo(left + radius, top)\n ctx.lineTo(left + width - radius, top)\n ctx.quadraticCurveTo(left + width, top, left + width, top + radius)\n ctx.lineTo(left + width, top + height - radius)\n ctx.quadraticCurveTo(left + width, top + height, left + width - radius, top + height)\n ctx.lineTo(left + radius, top + height)\n ctx.quadraticCurveTo(left, top + height, left, top + height - radius)\n ctx.lineTo(left, top + radius)\n ctx.quadraticCurveTo(left, top, left + radius, top)\n ctx.clip()\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new Scanner3D(this as any)\n }\n}\n"]}
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAO3C,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;CACF,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAA;AAClB,MAAM,eAAe,GAAG,CAAC,CAAA;AACzB,MAAM,UAAU,GAAG,CAAC,CAAA;AAEpB,sBAAsB;AACtB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAyE,CAAA;AAGzG,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAC7C,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7C,IAAI,MAAM,GAAG,KAAK,GAAG,EAAE,CAAA;QAEvB,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QAC9B,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACtC,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACnE,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QAC/C,GAAG,CAAC,gBAAgB,CAAC,IAAI,GAAG,KAAK,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACrF,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QACvC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,CAAA;QACrE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,CAAA;QAC9B,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACnD,GAAG,CAAC,IAAI,EAAE,CAAA;IACZ,CAAC;IACD,eAAe;QACb,OAAO,IAAI,SAAS,CAAC,IAAW,CAAC,CAAA;IACnC,CAAC;CACF,CAAA;AA7BoB,OAAO;IAD3B,cAAc,CAAC,SAAS,CAAC;GACL,OAAO,CA6B3B;eA7BoB,OAAO","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, sceneComponent, Shape } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinScanner from './mixin-scanner.js'\nimport { Scanner3D } from './scanner-3d.js'\n\n// MixinScanner에서 확장된 클래스의 인터페이스 정의\ninterface ScannerMixin {\n // 필요한 메서드나 속성을 여기에 정의\n}\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 },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ]\n}\n\nconst STAT_IDLE = 0\nconst STAT_RUN = 1\nconst STAT_CHUTE_FULL = 2\nconst STAT_ERROR = 3\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinScanner(RectPath(Shape)) as unknown as typeof Component & (new (...args: any[]) => ScannerMixin)\n\n@sceneComponent('scanner')\nexport default class Scanner extends MixinShape {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top } = this.state\n\n var radius = width / 10\n\n ctx.beginPath()\n ctx.moveTo(left + radius, top)\n ctx.lineTo(left + width - radius, top)\n ctx.quadraticCurveTo(left + width, top, left + width, top + radius)\n ctx.lineTo(left + width, top + height - radius)\n ctx.quadraticCurveTo(left + width, top + height, left + width - radius, top + height)\n ctx.lineTo(left + radius, top + height)\n ctx.quadraticCurveTo(left, top + height, left, top + height - radius)\n ctx.lineTo(left, top + radius)\n ctx.quadraticCurveTo(left, top, left + radius, top)\n ctx.clip()\n }\n buildRealObject(): RealObject | undefined {\n return new Scanner3D(this as any)\n }\n}\n"]}
@@ -1,11 +1,6 @@
1
1
  import { RealObjectGroup } from '@hatiolab/things-scene';
2
2
  export declare class WheelSorter3D extends RealObjectGroup {
3
3
  get effectiveDepth(): number;
4
- get position(): {
5
- x: number;
6
- y: any;
7
- z: number;
8
- };
9
4
  build(): void;
10
5
  private buildWheelModules;
11
6
  updateDimension(): void;
@@ -28,14 +28,6 @@ export class WheelSorter3D extends RealObjectGroup {
28
28
  const { width, height, depth } = this.component.state;
29
29
  return depth || Math.min(width, height) * 1.5;
30
30
  }
31
- get position() {
32
- const { zPos = 0 } = this.component.state;
33
- return {
34
- x: this.cx,
35
- y: zPos + this.effectiveDepth / 2,
36
- z: this.cy
37
- };
38
- }
39
31
  build() {
40
32
  super.build();
41
33
  const { width, height, value = 0, tilt = 0, wheelSize = 3, rollWidth = 10 } = this.component.state;
@@ -1 +1 @@
1
- {"version":3,"file":"wheel-sorter-3d.js","sourceRoot":"","sources":["../src/wheel-sorter-3d.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Pivot Wheel Sorter 3D Model\n *\n * A flat conveyor-height platform densely packed with circular pivot wheel\n * modules. Each module has small rubber roller wheels arranged in a cross (+)\n * pattern that rotate to divert packages straight, left, or right.\n *\n * Visual identity: dark base plate + dense grid of raised circular housings\n * with clearly visible small roller wheels — immediately recognizable.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xffba00, // WARN\n 3: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst PLATE_COLOR = 0x555566\nconst HOUSING_COLOR = 0x222233\nconst WHEEL_COLOR = 0x333333\n\nexport class WheelSorter3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.min(width, height) * 1.5\n }\n\n get position() {\n const { zPos = 0 } = this.component.state\n return {\n x: this.cx,\n y: zPos + this.effectiveDepth / 2,\n z: this.cy\n }\n }\n\n build() {\n super.build()\n\n const { width, height, value = 0, tilt = 0, wheelSize = 3, rollWidth = 10 } = this.component.state\n const depth = this.effectiveDepth\n\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const railW = Math.max(Math.min(width, height) * 0.04, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Frame: side rails + legs + cross-bracing (Conveyor3D 패턴) ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const railY = depth / 2 - frameH / 2\n\n for (const zSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(width, frameH, railW)\n rail.translate(0, railY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(rail)\n }\n for (const xSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(railW, frameH, height - railW * 2)\n rail.translate(xSign * (width / 2 - railW / 2), railY, 0)\n frameGeometries.push(rail)\n }\n\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n for (const xSign of [-1, 1]) {\n for (const zSign of [-1, 1]) {\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(xSign * (width / 2 - legThickness / 2), legCenterY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(leg)\n }\n }\n\n const braceSize = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceSize, braceSize, height - railW)\n brace.translate(xSign * (width / 2 - legThickness / 2), braceY, 0)\n frameGeometries.push(brace)\n }\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - legThickness, braceSize, braceSize)\n brace.translate(0, braceY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(brace)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Dark base plate (프레임 상단에 플러시) ---\n const plateThickness = Math.max(frameH * 0.3, 1)\n const plateW = width - railW * 2\n const plateD = height - railW * 2\n const plateY = depth / 2 - plateThickness / 2\n\n const plateMesh = new THREE.Mesh(\n new THREE.BoxGeometry(plateW, plateThickness, plateD),\n new THREE.MeshStandardMaterial({\n color: PLATE_COLOR,\n metalness: 0.3,\n roughness: 0.5\n })\n )\n plateMesh.position.set(0, plateY, 0)\n plateMesh.receiveShadow = true\n this.object3d.add(plateMesh)\n\n // --- Status color strip (플레이트 위 얇은 상태 표시면) ---\n const statusThickness = Math.max(plateThickness * 0.15, 0.3)\n const statusMesh = new THREE.Mesh(\n new THREE.BoxGeometry(plateW, statusThickness, plateD),\n new THREE.MeshStandardMaterial({\n color: FILL_COLORS[value] ?? FILL_COLORS[0],\n metalness: 0.1,\n roughness: 0.6\n })\n )\n statusMesh.position.set(0, depth / 2 + statusThickness / 2, 0)\n statusMesh.receiveShadow = true\n this.object3d.add(statusMesh)\n\n // --- Pivot wheel modules (핵심 시각 요소) ---\n this.buildWheelModules(width, height, depth, railW, tilt, wheelSize)\n }\n\n private buildWheelModules(\n width: number,\n height: number,\n depth: number,\n railW: number,\n tilt: number,\n wheelSize: number\n ) {\n // 모듈 크기: 플레이트 면적에 빽빽하게 채움\n const cellSize = Math.max(wheelSize * 8, Math.min(width, height) / 8)\n const moduleRadius = cellSize * 0.44\n const moduleH = Math.max(cellSize * 0.06, 0.8)\n const topY = depth / 2\n\n // 개별 소형 롤러 휠 치수\n const wheelRadius = moduleRadius * 0.18\n const wheelLen = moduleRadius * 0.35\n const wheelH = Math.max(cellSize * 0.1, 1.2)\n\n // tilt: 0 → left (-45°), 1 → straight (0°), 2 → right (+45°)\n const normalizedTilt = ((tilt || 0) % 3) - 1\n const tiltAngle = normalizedTilt * (Math.PI / 4)\n\n const housingGeometries: THREE.BufferGeometry[] = []\n const wheelGeometries: THREE.BufferGeometry[] = []\n\n const areaW = width - railW * 2\n const areaD = height - railW * 2\n const colCount = Math.max(1, Math.floor(areaW / cellSize))\n const rowCount = Math.max(1, Math.floor(areaD / cellSize))\n\n // 실제 셀 크기를 면적에 맞게 재계산\n const actualCellW = areaW / colCount\n const actualCellD = areaD / rowCount\n\n for (let col = 0; col < colCount; col++) {\n for (let row = 0; row < rowCount; row++) {\n const cx = -areaW / 2 + actualCellW * (col + 0.5)\n const cz = -areaD / 2 + actualCellD * (row + 0.5)\n\n // 원형 하우징 (어두운 디스크, 플레이트 위에 약간 돌출)\n const housing = new THREE.CylinderGeometry(moduleRadius, moduleRadius, moduleH, 16)\n housing.translate(cx, topY + moduleH / 2, cz)\n housingGeometries.push(housing)\n\n // 십자 배열 소형 롤러 휠 (4방향 × 각 1개 = 원형 배치)\n const armCount = 4\n const armSpacing = moduleRadius * 0.55\n for (let a = 0; a < armCount; a++) {\n const armAngle = tiltAngle + (a * Math.PI) / 2\n const wx = cx + Math.cos(armAngle) * armSpacing\n const wz = cz + Math.sin(armAngle) * armSpacing\n const wy = topY + moduleH + wheelH / 2\n\n // 소형 원통 롤러 (회전 방향으로 길게)\n const wheel = new THREE.CylinderGeometry(wheelRadius, wheelRadius, wheelLen, 8)\n // 롤러를 눕혀서 arm 방향에 수직으로 배치\n wheel.rotateX(Math.PI / 2)\n wheel.rotateY(armAngle)\n wheel.translate(wx, wy, wz)\n wheelGeometries.push(wheel)\n }\n }\n }\n\n if (housingGeometries.length > 0) {\n const housingMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(housingGeometries),\n new THREE.MeshStandardMaterial({ color: HOUSING_COLOR, metalness: 0.4, roughness: 0.5 })\n )\n housingMesh.receiveShadow = true\n this.object3d.add(housingMesh)\n }\n\n if (wheelGeometries.length > 0) {\n const wheelMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(wheelGeometries),\n new THREE.MeshStandardMaterial({ color: WHEEL_COLOR, metalness: 0.6, roughness: 0.4 })\n )\n wheelMesh.castShadow = true\n this.object3d.add(wheelMesh)\n }\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'value' in after ||\n 'tilt' in after ||\n 'wheelSize' in after ||\n 'rollWidth' in after ||\n 'width' in after ||\n 'height' in after ||\n 'depth' in after\n ) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
1
+ {"version":3,"file":"wheel-sorter-3d.js","sourceRoot":"","sources":["../src/wheel-sorter-3d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,mBAAmB,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,WAAW,GAA2B;IAC1C,CAAC,EAAE,QAAQ,EAAE,OAAO;IACpB,CAAC,EAAE,QAAQ,EAAE,MAAM;IACnB,CAAC,EAAE,QAAQ,EAAE,OAAO;IACpB,CAAC,EAAE,QAAQ,CAAC,QAAQ;CACrB,CAAA;AAED,MAAM,WAAW,GAAG,QAAQ,CAAA;AAC5B,MAAM,WAAW,GAAG,QAAQ,CAAA;AAC5B,MAAM,aAAa,GAAG,QAAQ,CAAA;AAC9B,MAAM,WAAW,GAAG,QAAQ,CAAA;AAE5B,MAAM,OAAO,aAAc,SAAQ,eAAe;IAChD,IAAI,cAAc;QAChB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QACrD,OAAO,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAA;IAC/C,CAAC;IAED,KAAK;QACH,KAAK,CAAC,KAAK,EAAE,CAAA;QAEb,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAA;QAClG,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAA;QAEjC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,SAAmB,EAAE,CAAC,CAAC,CAAA;QACvD,MAAM,MAAM,GAAG,cAAc,CAAA;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QAE7C,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACnD,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QAEF,mEAAmE;QACnE,MAAM,eAAe,GAA2B,EAAE,CAAA;QAClD,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;QAEpC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;YACxD,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;YAC1D,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,CAAA;YACrE,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YACzD,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,CAAA;QAClC,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,CAAC,CAAA;QACrC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;gBACnE,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;gBACnG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,GAAG,GAAG,CAAA;QACpC,MAAM,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAA;QACpC,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC,CAAA;YACzE,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAClE,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,GAAG,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;YAC/E,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;YAC5D,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC,CAAA;QACrG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAA;QAC3B,SAAS,CAAC,aAAa,GAAG,IAAI,CAAA;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAE5B,wCAAwC;QACxC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;QAChD,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAA;QAChC,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,CAAA;QACjC,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,GAAG,cAAc,GAAG,CAAC,CAAA;QAE7C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,IAAI,CAC9B,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,EACrD,IAAI,KAAK,CAAC,oBAAoB,CAAC;YAC7B,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CACH,CAAA;QACD,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QACpC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAA;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAE5B,gDAAgD;QAChD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,EAAE,GAAG,CAAC,CAAA;QAC5D,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,IAAI,CAC/B,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,EACtD,IAAI,KAAK,CAAC,oBAAoB,CAAC;YAC7B,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC;YAC3C,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC,CACH,CAAA;QACD,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,eAAe,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QAC9D,UAAU,CAAC,aAAa,GAAG,IAAI,CAAA;QAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAE7B,yCAAyC;QACzC,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;IACtE,CAAC;IAEO,iBAAiB,CACvB,KAAa,EACb,MAAc,EACd,KAAa,EACb,KAAa,EACb,IAAY,EACZ,SAAiB;QAEjB,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACrE,MAAM,YAAY,GAAG,QAAQ,GAAG,IAAI,CAAA;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,EAAE,GAAG,CAAC,CAAA;QAC9C,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAA;QAEtB,gBAAgB;QAChB,MAAM,WAAW,GAAG,YAAY,GAAG,IAAI,CAAA;QACvC,MAAM,QAAQ,GAAG,YAAY,GAAG,IAAI,CAAA;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,EAAE,GAAG,CAAC,CAAA;QAE5C,6DAA6D;QAC7D,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAC5C,MAAM,SAAS,GAAG,cAAc,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QAEhD,MAAM,iBAAiB,GAA2B,EAAE,CAAA;QACpD,MAAM,eAAe,GAA2B,EAAE,CAAA;QAElD,MAAM,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAA;QAC/B,MAAM,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,CAAA;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAA;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAA;QAE1D,sBAAsB;QACtB,MAAM,WAAW,GAAG,KAAK,GAAG,QAAQ,CAAA;QACpC,MAAM,WAAW,GAAG,KAAK,GAAG,QAAQ,CAAA;QAEpC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;YACxC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;gBACxC,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;gBACjD,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;gBAEjD,kCAAkC;gBAClC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;gBACnF,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,GAAG,OAAO,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;gBAC7C,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAE/B,qCAAqC;gBACrC,MAAM,QAAQ,GAAG,CAAC,CAAA;gBAClB,MAAM,UAAU,GAAG,YAAY,GAAG,IAAI,CAAA;gBACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;oBAClC,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;oBAC9C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAA;oBAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAA;oBAC/C,MAAM,EAAE,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,CAAC,CAAA;oBAEtC,wBAAwB;oBACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;oBAC/E,0BAA0B;oBAC1B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;oBAC1B,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;oBACvB,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;oBAC3B,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,IAAI,CAChC,mBAAmB,CAAC,eAAe,CAAC,iBAAiB,CAAC,EACtD,IAAI,KAAK,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CACzF,CAAA;YACD,WAAW,CAAC,aAAa,GAAG,IAAI,CAAA;YAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QAChC,CAAC;QAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,IAAI,CAC9B,mBAAmB,CAAC,eAAe,CAAC,eAAe,CAAC,EACpD,IAAI,KAAK,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CACvF,CAAA;YACD,SAAS,CAAC,UAAU,GAAG,IAAI,CAAA;YAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,eAAe,KAAI,CAAC;IAEpB,QAAQ,CAAC,KAA8B,EAAE,MAA+B;QACtE,IACE,OAAO,IAAI,KAAK;YAChB,MAAM,IAAI,KAAK;YACf,WAAW,IAAI,KAAK;YACpB,WAAW,IAAI,KAAK;YACpB,OAAO,IAAI,KAAK;YAChB,QAAQ,IAAI,KAAK;YACjB,OAAO,IAAI,KAAK,EAChB,CAAC;YACD,IAAI,CAAC,MAAM,EAAE,CAAA;YACb,OAAM;QACR,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAC/B,CAAC;IAED,WAAW,KAAI,CAAC;CACjB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * Pivot Wheel Sorter 3D Model\n *\n * A flat conveyor-height platform densely packed with circular pivot wheel\n * modules. Each module has small rubber roller wheels arranged in a cross (+)\n * pattern that rotate to divert packages straight, left, or right.\n *\n * Visual identity: dark base plate + dense grid of raised circular housings\n * with clearly visible small roller wheels — immediately recognizable.\n */\n\nimport * as THREE from 'three'\nimport * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js'\nimport { RealObjectGroup } from '@hatiolab/things-scene'\n\nconst FILL_COLORS: Record<number, number> = {\n 0: 0xcccccc, // IDLE\n 1: 0xafd0f1, // RUN\n 2: 0xffba00, // WARN\n 3: 0xe9746b // ERROR\n}\n\nconst FRAME_COLOR = 0x888899\nconst PLATE_COLOR = 0x555566\nconst HOUSING_COLOR = 0x222233\nconst WHEEL_COLOR = 0x333333\n\nexport class WheelSorter3D extends RealObjectGroup {\n get effectiveDepth(): number {\n const { width, height, depth } = this.component.state\n return depth || Math.min(width, height) * 1.5\n }\n\n build() {\n super.build()\n\n const { width, height, value = 0, tilt = 0, wheelSize = 3, rollWidth = 10 } = this.component.state\n const depth = this.effectiveDepth\n\n const rollerDiameter = Math.max(rollWidth as number, 2)\n const frameH = rollerDiameter\n const legH = Math.max(depth - frameH, 0)\n const railW = Math.max(Math.min(width, height) * 0.04, 2)\n const legThickness = Math.max(railW * 0.8, 2)\n\n const frameMaterial = new THREE.MeshStandardMaterial({\n color: FRAME_COLOR,\n metalness: 0.85,\n roughness: 0.35\n })\n\n // --- Frame: side rails + legs + cross-bracing (Conveyor3D 패턴) ---\n const frameGeometries: THREE.BufferGeometry[] = []\n const railY = depth / 2 - frameH / 2\n\n for (const zSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(width, frameH, railW)\n rail.translate(0, railY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(rail)\n }\n for (const xSign of [-1, 1]) {\n const rail = new THREE.BoxGeometry(railW, frameH, height - railW * 2)\n rail.translate(xSign * (width / 2 - railW / 2), railY, 0)\n frameGeometries.push(rail)\n }\n\n const legTopY = depth / 2 - frameH\n const legCenterY = legTopY - legH / 2\n for (const xSign of [-1, 1]) {\n for (const zSign of [-1, 1]) {\n const leg = new THREE.BoxGeometry(legThickness, legH, legThickness)\n leg.translate(xSign * (width / 2 - legThickness / 2), legCenterY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(leg)\n }\n }\n\n const braceSize = legThickness * 0.6\n const braceY = legTopY - legH * 0.35\n for (const xSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(braceSize, braceSize, height - railW)\n brace.translate(xSign * (width / 2 - legThickness / 2), braceY, 0)\n frameGeometries.push(brace)\n }\n for (const zSign of [-1, 1]) {\n const brace = new THREE.BoxGeometry(width - legThickness, braceSize, braceSize)\n brace.translate(0, braceY, zSign * (height / 2 - railW / 2))\n frameGeometries.push(brace)\n }\n\n const frameMesh = new THREE.Mesh(BufferGeometryUtils.mergeGeometries(frameGeometries), frameMaterial)\n frameMesh.castShadow = true\n frameMesh.receiveShadow = true\n this.object3d.add(frameMesh)\n\n // --- Dark base plate (프레임 상단에 플러시) ---\n const plateThickness = Math.max(frameH * 0.3, 1)\n const plateW = width - railW * 2\n const plateD = height - railW * 2\n const plateY = depth / 2 - plateThickness / 2\n\n const plateMesh = new THREE.Mesh(\n new THREE.BoxGeometry(plateW, plateThickness, plateD),\n new THREE.MeshStandardMaterial({\n color: PLATE_COLOR,\n metalness: 0.3,\n roughness: 0.5\n })\n )\n plateMesh.position.set(0, plateY, 0)\n plateMesh.receiveShadow = true\n this.object3d.add(plateMesh)\n\n // --- Status color strip (플레이트 위 얇은 상태 표시면) ---\n const statusThickness = Math.max(plateThickness * 0.15, 0.3)\n const statusMesh = new THREE.Mesh(\n new THREE.BoxGeometry(plateW, statusThickness, plateD),\n new THREE.MeshStandardMaterial({\n color: FILL_COLORS[value] ?? FILL_COLORS[0],\n metalness: 0.1,\n roughness: 0.6\n })\n )\n statusMesh.position.set(0, depth / 2 + statusThickness / 2, 0)\n statusMesh.receiveShadow = true\n this.object3d.add(statusMesh)\n\n // --- Pivot wheel modules (핵심 시각 요소) ---\n this.buildWheelModules(width, height, depth, railW, tilt, wheelSize)\n }\n\n private buildWheelModules(\n width: number,\n height: number,\n depth: number,\n railW: number,\n tilt: number,\n wheelSize: number\n ) {\n // 모듈 크기: 플레이트 면적에 빽빽하게 채움\n const cellSize = Math.max(wheelSize * 8, Math.min(width, height) / 8)\n const moduleRadius = cellSize * 0.44\n const moduleH = Math.max(cellSize * 0.06, 0.8)\n const topY = depth / 2\n\n // 개별 소형 롤러 휠 치수\n const wheelRadius = moduleRadius * 0.18\n const wheelLen = moduleRadius * 0.35\n const wheelH = Math.max(cellSize * 0.1, 1.2)\n\n // tilt: 0 → left (-45°), 1 → straight (0°), 2 → right (+45°)\n const normalizedTilt = ((tilt || 0) % 3) - 1\n const tiltAngle = normalizedTilt * (Math.PI / 4)\n\n const housingGeometries: THREE.BufferGeometry[] = []\n const wheelGeometries: THREE.BufferGeometry[] = []\n\n const areaW = width - railW * 2\n const areaD = height - railW * 2\n const colCount = Math.max(1, Math.floor(areaW / cellSize))\n const rowCount = Math.max(1, Math.floor(areaD / cellSize))\n\n // 실제 셀 크기를 면적에 맞게 재계산\n const actualCellW = areaW / colCount\n const actualCellD = areaD / rowCount\n\n for (let col = 0; col < colCount; col++) {\n for (let row = 0; row < rowCount; row++) {\n const cx = -areaW / 2 + actualCellW * (col + 0.5)\n const cz = -areaD / 2 + actualCellD * (row + 0.5)\n\n // 원형 하우징 (어두운 디스크, 플레이트 위에 약간 돌출)\n const housing = new THREE.CylinderGeometry(moduleRadius, moduleRadius, moduleH, 16)\n housing.translate(cx, topY + moduleH / 2, cz)\n housingGeometries.push(housing)\n\n // 십자 배열 소형 롤러 휠 (4방향 × 각 1개 = 원형 배치)\n const armCount = 4\n const armSpacing = moduleRadius * 0.55\n for (let a = 0; a < armCount; a++) {\n const armAngle = tiltAngle + (a * Math.PI) / 2\n const wx = cx + Math.cos(armAngle) * armSpacing\n const wz = cz + Math.sin(armAngle) * armSpacing\n const wy = topY + moduleH + wheelH / 2\n\n // 소형 원통 롤러 (회전 방향으로 길게)\n const wheel = new THREE.CylinderGeometry(wheelRadius, wheelRadius, wheelLen, 8)\n // 롤러를 눕혀서 arm 방향에 수직으로 배치\n wheel.rotateX(Math.PI / 2)\n wheel.rotateY(armAngle)\n wheel.translate(wx, wy, wz)\n wheelGeometries.push(wheel)\n }\n }\n }\n\n if (housingGeometries.length > 0) {\n const housingMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(housingGeometries),\n new THREE.MeshStandardMaterial({ color: HOUSING_COLOR, metalness: 0.4, roughness: 0.5 })\n )\n housingMesh.receiveShadow = true\n this.object3d.add(housingMesh)\n }\n\n if (wheelGeometries.length > 0) {\n const wheelMesh = new THREE.Mesh(\n BufferGeometryUtils.mergeGeometries(wheelGeometries),\n new THREE.MeshStandardMaterial({ color: WHEEL_COLOR, metalness: 0.6, roughness: 0.4 })\n )\n wheelMesh.castShadow = true\n this.object3d.add(wheelMesh)\n }\n }\n\n updateDimension() {}\n\n onchange(after: Record<string, unknown>, before: Record<string, unknown>) {\n if (\n 'value' in after ||\n 'tilt' in after ||\n 'wheelSize' in after ||\n 'rollWidth' in after ||\n 'width' in after ||\n 'height' in after ||\n 'depth' in after\n ) {\n this.update()\n return\n }\n super.onchange(after, before)\n }\n\n updateAlpha() {}\n}\n"]}
@@ -12,7 +12,6 @@ export default class WheelSorter extends MixinShape {
12
12
  get anchors(): never[];
13
13
  render(ctx: CanvasRenderingContext2D): void;
14
14
  postrender(ctx: CanvasRenderingContext2D): void;
15
- is3dish(): boolean;
16
15
  buildRealObject(): RealObject | undefined;
17
16
  }
18
17
  export {};
@@ -58,9 +58,6 @@ let WheelSorter = class WheelSorter extends MixinShape {
58
58
  super.postrender(ctx);
59
59
  this._draw_pattern(ctx);
60
60
  }
61
- is3dish() {
62
- return true;
63
- }
64
61
  buildRealObject() {
65
62
  return new WheelSorter3D(this);
66
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wheel-sorter.js","sourceRoot":"","sources":["../src/wheel-sorter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,gBAAgB,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAWpD,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,8BAA8B;CACrC,CAAA;AAED,sBAAsB;AACtB,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,CACP,CAAA;AAG7B,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IACjD,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAEvD,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAE9B,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAElC,GAAG,CAAC,IAAI,EAAE,CAAA,CAAC,8BAA8B;IAC3C,CAAC;IAED,UAAU,CAAC,GAA6B;QACtC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAA;IACb,CAAC;IAED,eAAe;QACb,OAAO,IAAI,aAAa,CAAC,IAAW,CAAC,CAAA;IACvC,CAAC;CACF,CAAA;AAhCoB,WAAW;IAD/B,cAAc,CAAC,cAAc,CAAC;GACV,WAAW,CAgC/B;eAhCoB,WAAW","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinWheelSorter from './mixin-wheel-sorter.js'\nimport { WheelSorter3D } from './wheel-sorter-3d.js'\n\n// MixinWheelSorter에서 확장된 클래스의 인터페이스 정의\ninterface WheelSorterMixin {\n animOnState(): void\n _draw_pattern(ctx: CanvasRenderingContext2D): void\n _draw_circle(ctx: CanvasRenderingContext2D): void\n _draw_inner(ctx: CanvasRenderingContext2D): void\n _draw_wheel(ctx: CanvasRenderingContext2D): void\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'tilt',\n name: 'tilt'\n },\n {\n type: 'number',\n label: 'wheel-size',\n name: 'wheelSize'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/wheel-sorter'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinWheelSorter(RectPath(Shape)) as unknown as typeof Component &\n (new (...args: any[]) => WheelSorterMixin)\n\n@sceneComponent('wheel-sorter')\nexport default class WheelSorter extends MixinShape {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n\n ctx.clip() // bound를 벗어난 영역에도 그려지는 것을 예방.\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n this._draw_pattern(ctx)\n }\n\n is3dish() {\n return true\n }\n\n buildRealObject(): RealObject | undefined {\n return new WheelSorter3D(this as any)\n }\n}\n"]}
1
+ {"version":3,"file":"wheel-sorter.js","sourceRoot":"","sources":["../src/wheel-sorter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAiD,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvH;;GAEG;AACH,OAAO,gBAAgB,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAWpD,MAAM,MAAM,GAAoB;IAC9B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,WAAW;SAClB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;QACD;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd;KACF;IACD,IAAI,EAAE,8BAA8B;CACrC,CAAA;AAED,sBAAsB;AACtB,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,CACP,CAAA;AAG7B,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,UAAU;IACjD,IAAI,MAAM;QACR,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,OAAO;QACT,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,CAAC,GAA6B;QAClC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAEvD,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAA;QAE9B,GAAG,CAAC,SAAS,EAAE,CAAA;QACf,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAElC,GAAG,CAAC,IAAI,EAAE,CAAA,CAAC,8BAA8B;IAC3C,CAAC;IAED,UAAU,CAAC,GAA6B;QACtC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IACD,eAAe;QACb,OAAO,IAAI,aAAa,CAAC,IAAW,CAAC,CAAA;IACvC,CAAC;CACF,CAAA;AA3BoB,WAAW;IAD/B,cAAc,CAAC,cAAc,CAAC;GACV,WAAW,CA2B/B;eA3BoB,WAAW","sourcesContent":["import { Class, Component, ComponentNature, RealObject, RectPath, Shape, sceneComponent } from '@hatiolab/things-scene'\n\n/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport MixinWheelSorter from './mixin-wheel-sorter.js'\nimport { WheelSorter3D } from './wheel-sorter-3d.js'\n\n// MixinWheelSorter에서 확장된 클래스의 인터페이스 정의\ninterface WheelSorterMixin {\n animOnState(): void\n _draw_pattern(ctx: CanvasRenderingContext2D): void\n _draw_circle(ctx: CanvasRenderingContext2D): void\n _draw_inner(ctx: CanvasRenderingContext2D): void\n _draw_wheel(ctx: CanvasRenderingContext2D): void\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'number',\n label: 'tilt',\n name: 'tilt'\n },\n {\n type: 'number',\n label: 'wheel-size',\n name: 'wheelSize'\n },\n {\n type: 'number',\n label: 'value',\n name: 'value'\n },\n {\n type: 'checkbox',\n label: 'animation',\n name: 'animated'\n },\n {\n type: 'number',\n label: 'depth',\n name: 'depth'\n }\n ],\n help: 'scene/component/wheel-sorter'\n}\n\n// 클래스 확장 타입을 명시적으로 정의\nconst MixinShape = MixinWheelSorter(RectPath(Shape)) as unknown as typeof Component &\n (new (...args: any[]) => WheelSorterMixin)\n\n@sceneComponent('wheel-sorter')\nexport default class WheelSorter extends MixinShape {\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n render(ctx: CanvasRenderingContext2D) {\n var { width, height, left, top, animated } = this.state\n\n animated && this.animOnState()\n\n ctx.beginPath()\n ctx.rect(left, top, width, height)\n\n ctx.clip() // bound를 벗어난 영역에도 그려지는 것을 예방.\n }\n\n postrender(ctx: CanvasRenderingContext2D) {\n super.postrender(ctx)\n this._draw_pattern(ctx)\n }\n buildRealObject(): RealObject | undefined {\n return new WheelSorter3D(this as any)\n }\n}\n"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/scene-wheel-sorter",
3
3
  "description": "The wheel sorter component for things-scene",
4
4
  "author": "heartyoh",
5
- "version": "10.0.0-beta.13",
5
+ "version": "10.0.0-beta.15",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
@@ -60,5 +60,5 @@
60
60
  "prettier --write"
61
61
  ]
62
62
  },
63
- "gitHead": "5ff3381b1fd89d65db95ecec15589c3edc508dff"
63
+ "gitHead": "b15033427eb7ed337c4ff5e64221b847d3d07b0e"
64
64
  }