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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/dist/carrier.d.ts +263 -0
  2. package/dist/carrier.js +272 -0
  3. package/dist/carrier.js.map +1 -0
  4. package/dist/desk.d.ts +238 -3
  5. package/dist/desk.js +1 -2
  6. package/dist/desk.js.map +1 -1
  7. package/dist/editors/index.d.ts +3 -0
  8. package/dist/editors/index.js +15 -0
  9. package/dist/editors/index.js.map +1 -1
  10. package/dist/editors/property-editor-gltf-fill-targets.d.ts +20 -0
  11. package/dist/editors/property-editor-gltf-fill-targets.js +313 -0
  12. package/dist/editors/property-editor-gltf-fill-targets.js.map +1 -0
  13. package/dist/editors/property-editor-gltf-info.d.ts +25 -3
  14. package/dist/editors/property-editor-gltf-info.js +333 -73
  15. package/dist/editors/property-editor-gltf-info.js.map +1 -1
  16. package/dist/editors/property-editor-gltf-play-targets.d.ts +25 -0
  17. package/dist/editors/property-editor-gltf-play-targets.js +388 -0
  18. package/dist/editors/property-editor-gltf-play-targets.js.map +1 -0
  19. package/dist/editors/property-editor-location-increase-pattern.js +87 -95
  20. package/dist/editors/property-editor-location-increase-pattern.js.map +1 -1
  21. package/dist/editors/property-editor-stocker-location.d.ts +13 -0
  22. package/dist/editors/property-editor-stocker-location.js +151 -0
  23. package/dist/editors/property-editor-stocker-location.js.map +1 -0
  24. package/dist/editors/property-editor-stocker-ports.d.ts +8 -0
  25. package/dist/editors/property-editor-stocker-ports.js +112 -0
  26. package/dist/editors/property-editor-stocker-ports.js.map +1 -0
  27. package/dist/effects/outline.js +1 -1
  28. package/dist/effects/outline.js.map +1 -1
  29. package/dist/index.d.ts +8 -17
  30. package/dist/index.js +10 -17
  31. package/dist/index.js.map +1 -1
  32. package/dist/rack-table-3d.d.ts +16 -0
  33. package/dist/rack-table-3d.js +95 -0
  34. package/dist/rack-table-3d.js.map +1 -0
  35. package/dist/rack-table-cell.d.ts +238 -3
  36. package/dist/rack-table-cell.js +44 -51
  37. package/dist/rack-table-cell.js.map +1 -1
  38. package/dist/rack-table-location.d.ts +37 -0
  39. package/dist/rack-table-location.js +227 -0
  40. package/dist/rack-table-location.js.map +1 -0
  41. package/dist/rack-table.d.ts +13 -29
  42. package/dist/rack-table.js +121 -380
  43. package/dist/rack-table.js.map +1 -1
  44. package/dist/rack.d.ts +16 -5
  45. package/dist/rack.js +106 -19
  46. package/dist/rack.js.map +1 -1
  47. package/dist/signal-tower.d.ts +492 -0
  48. package/dist/signal-tower.js +275 -0
  49. package/dist/signal-tower.js.map +1 -0
  50. package/dist/stock-hub.d.ts +25 -0
  51. package/dist/stock-hub.js +147 -0
  52. package/dist/stock-hub.js.map +1 -0
  53. package/dist/stock.d.ts +52 -8
  54. package/dist/stock.js +223 -120
  55. package/dist/stock.js.map +1 -1
  56. package/dist/stocker-3d.d.ts +23 -0
  57. package/dist/stocker-3d.js +352 -0
  58. package/dist/stocker-3d.js.map +1 -0
  59. package/dist/stocker-port-3d.d.ts +14 -0
  60. package/dist/stocker-port-3d.js +80 -0
  61. package/dist/stocker-port-3d.js.map +1 -0
  62. package/dist/stocker-port.d.ts +254 -0
  63. package/dist/stocker-port.js +123 -0
  64. package/dist/stocker-port.js.map +1 -0
  65. package/dist/stocker.d.ts +340 -0
  66. package/dist/stocker.js +370 -0
  67. package/dist/stocker.js.map +1 -0
  68. package/dist/tank.d.ts +492 -0
  69. package/dist/tank.js +312 -0
  70. package/dist/tank.js.map +1 -0
  71. package/dist/templates/carrier.d.ts +19 -0
  72. package/dist/templates/carrier.js +20 -0
  73. package/dist/templates/carrier.js.map +1 -0
  74. package/dist/templates/cube.js +1 -1
  75. package/dist/templates/cube.js.map +1 -1
  76. package/dist/templates/cylinder.js +3 -3
  77. package/dist/templates/cylinder.js.map +1 -1
  78. package/dist/templates/index.d.ts +38 -38
  79. package/dist/templates/index.js +15 -1
  80. package/dist/templates/index.js.map +1 -1
  81. package/dist/templates/rack-table.d.ts +2 -0
  82. package/dist/templates/rack-table.js +4 -2
  83. package/dist/templates/rack-table.js.map +1 -1
  84. package/dist/templates/signal-tower.d.ts +21 -0
  85. package/dist/templates/signal-tower.js +22 -0
  86. package/dist/templates/signal-tower.js.map +1 -0
  87. package/dist/templates/sphere.d.ts +1 -0
  88. package/dist/templates/sphere.js +5 -4
  89. package/dist/templates/sphere.js.map +1 -1
  90. package/dist/templates/stock-hub.d.ts +14 -0
  91. package/dist/templates/stock-hub.js +15 -0
  92. package/dist/templates/stock-hub.js.map +1 -0
  93. package/dist/templates/stocker-port.d.ts +17 -0
  94. package/dist/templates/stocker-port.js +17 -0
  95. package/dist/templates/stocker-port.js.map +1 -0
  96. package/dist/templates/stocker.d.ts +27 -0
  97. package/dist/templates/stocker.js +38 -0
  98. package/dist/templates/stocker.js.map +1 -0
  99. package/dist/templates/tank.d.ts +21 -0
  100. package/dist/templates/tank.js +22 -0
  101. package/dist/templates/tank.js.map +1 -0
  102. package/dist/templates/vehicle.d.ts +19 -0
  103. package/dist/templates/vehicle.js +20 -0
  104. package/dist/templates/vehicle.js.map +1 -0
  105. package/dist/templates/visualizer.js +1 -1
  106. package/dist/templates/visualizer.js.map +1 -1
  107. package/dist/vehicle.d.ts +248 -0
  108. package/dist/vehicle.js +133 -0
  109. package/dist/vehicle.js.map +1 -0
  110. package/dist/visualizer.d.ts +5 -5
  111. package/dist/visualizer.js +72 -68
  112. package/dist/visualizer.js.map +1 -1
  113. package/icons/carrier.png +0 -0
  114. package/icons/signal-tower.png +0 -0
  115. package/icons/stock-hub.png +0 -0
  116. package/icons/tank.png +0 -0
  117. package/icons/vehicle.png +0 -0
  118. package/package.json +16 -18
  119. package/translations/en.json +6 -0
  120. package/translations/ja.json +5 -0
  121. package/translations/ko.json +6 -1
  122. package/translations/ms.json +5 -0
  123. package/translations/zh.json +5 -0
  124. package/dist/banner.d.ts +0 -15
  125. package/dist/banner.js +0 -76
  126. package/dist/banner.js.map +0 -1
  127. package/dist/camera.d.ts +0 -20
  128. package/dist/camera.js +0 -108
  129. package/dist/camera.js.map +0 -1
  130. package/dist/cube.d.ts +0 -13
  131. package/dist/cube.js +0 -38
  132. package/dist/cube.js.map +0 -1
  133. package/dist/cylinder.d.ts +0 -11
  134. package/dist/cylinder.js +0 -38
  135. package/dist/cylinder.js.map +0 -1
  136. package/dist/ellipse.d.ts +0 -5
  137. package/dist/ellipse.js +0 -22
  138. package/dist/ellipse.js.map +0 -1
  139. package/dist/gltf-object.d.ts +0 -20
  140. package/dist/gltf-object.js +0 -104
  141. package/dist/gltf-object.js.map +0 -1
  142. package/dist/html-overlay-element.d.ts +0 -1
  143. package/dist/html-overlay-element.js +0 -12
  144. package/dist/html-overlay-element.js.map +0 -1
  145. package/dist/light.d.ts +0 -15
  146. package/dist/light.js +0 -135
  147. package/dist/light.js.map +0 -1
  148. package/dist/polygon.d.ts +0 -17
  149. package/dist/polygon.js +0 -64
  150. package/dist/polygon.js.map +0 -1
  151. package/dist/rect.d.ts +0 -5
  152. package/dist/rect.js +0 -36
  153. package/dist/rect.js.map +0 -1
  154. package/dist/scene/component.d.ts +0 -1
  155. package/dist/scene/component.js +0 -29
  156. package/dist/scene/component.js.map +0 -1
  157. package/dist/sphere.d.ts +0 -11
  158. package/dist/sphere.js +0 -38
  159. package/dist/sphere.js.map +0 -1
  160. package/dist/sprite.d.ts +0 -9
  161. package/dist/sprite.js +0 -28
  162. package/dist/sprite.js.map +0 -1
  163. package/dist/text.d.ts +0 -1
  164. package/dist/text.js +0 -9
  165. package/dist/text.js.map +0 -1
  166. package/dist/three-container-editor.d.ts +0 -22
  167. package/dist/three-container-editor.js +0 -132
  168. package/dist/three-container-editor.js.map +0 -1
  169. package/dist/three-container.d.ts +0 -85
  170. package/dist/three-container.js +0 -565
  171. package/dist/three-container.js.map +0 -1
  172. package/dist/three-controls.d.ts +0 -11
  173. package/dist/three-controls.js +0 -616
  174. package/dist/three-controls.js.map +0 -1
  175. package/dist/three-layout.d.ts +0 -8
  176. package/dist/three-layout.js +0 -20
  177. package/dist/three-layout.js.map +0 -1
  178. package/dist/three-space.d.ts +0 -85
  179. package/dist/three-space.js +0 -570
  180. package/dist/three-space.js.map +0 -1
  181. package/dist/threed/common.d.ts +0 -22
  182. package/dist/threed/common.js +0 -19
  183. package/dist/threed/common.js.map +0 -1
  184. package/dist/threed/floor/floor.d.ts +0 -3
  185. package/dist/threed/floor/floor.js +0 -51
  186. package/dist/threed/floor/floor.js.map +0 -1
  187. package/dist/threed/html/elements.d.ts +0 -2
  188. package/dist/threed/html/elements.js +0 -21
  189. package/dist/threed/html/elements.js.map +0 -1
  190. package/dist/threed/index.d.ts +0 -15
  191. package/dist/threed/index.js +0 -16
  192. package/dist/threed/index.js.map +0 -1
  193. package/dist/threed/real-object-camera-meshed.d.ts +0 -12
  194. package/dist/threed/real-object-camera-meshed.js +0 -49
  195. package/dist/threed/real-object-camera-meshed.js.map +0 -1
  196. package/dist/threed/real-object-camera.d.ts +0 -9
  197. package/dist/threed/real-object-camera.js +0 -31
  198. package/dist/threed/real-object-camera.js.map +0 -1
  199. package/dist/threed/real-object-dom-element.d.ts +0 -9
  200. package/dist/threed/real-object-dom-element.js +0 -40
  201. package/dist/threed/real-object-dom-element.js.map +0 -1
  202. package/dist/threed/real-object-dummy.d.ts +0 -6
  203. package/dist/threed/real-object-dummy.js +0 -11
  204. package/dist/threed/real-object-dummy.js.map +0 -1
  205. package/dist/threed/real-object-extrude.d.ts +0 -21
  206. package/dist/threed/real-object-extrude.js +0 -173
  207. package/dist/threed/real-object-extrude.js.map +0 -1
  208. package/dist/threed/real-object-gltf.d.ts +0 -16
  209. package/dist/threed/real-object-gltf.js +0 -101
  210. package/dist/threed/real-object-gltf.js.map +0 -1
  211. package/dist/threed/real-object-group.d.ts +0 -5
  212. package/dist/threed/real-object-group.js +0 -11
  213. package/dist/threed/real-object-group.js.map +0 -1
  214. package/dist/threed/real-object-mesh.d.ts +0 -13
  215. package/dist/threed/real-object-mesh.js +0 -75
  216. package/dist/threed/real-object-mesh.js.map +0 -1
  217. package/dist/threed/real-object-plane.d.ts +0 -5
  218. package/dist/threed/real-object-plane.js +0 -22
  219. package/dist/threed/real-object-plane.js.map +0 -1
  220. package/dist/threed/real-object-scene.d.ts +0 -21
  221. package/dist/threed/real-object-scene.js +0 -67
  222. package/dist/threed/real-object-scene.js.map +0 -1
  223. package/dist/threed/real-object-sprite-2d.d.ts +0 -14
  224. package/dist/threed/real-object-sprite-2d.js +0 -45
  225. package/dist/threed/real-object-sprite-2d.js.map +0 -1
  226. package/dist/threed/real-object-sprite.d.ts +0 -11
  227. package/dist/threed/real-object-sprite.js +0 -50
  228. package/dist/threed/real-object-sprite.js.map +0 -1
  229. package/dist/threed/real-object-text.d.ts +0 -15
  230. package/dist/threed/real-object-text.js +0 -64
  231. package/dist/threed/real-object-text.js.map +0 -1
  232. package/dist/threed/real-object.d.ts +0 -64
  233. package/dist/threed/real-object.js +0 -260
  234. package/dist/threed/real-object.js.map +0 -1
  235. package/dist/threed/texture/canvas-texture.d.ts +0 -4
  236. package/dist/threed/texture/canvas-texture.js +0 -49
  237. package/dist/threed/texture/canvas-texture.js.map +0 -1
  238. package/dist/threed/texture/text-texture.d.ts +0 -8
  239. package/dist/threed/texture/text-texture.js +0 -79
  240. package/dist/threed/texture/text-texture.js.map +0 -1
  241. package/dist/threed/three-dimensional-container.d.ts +0 -8
  242. package/dist/threed/three-dimensional-container.js +0 -2
  243. package/dist/threed/three-dimensional-container.js.map +0 -1
  244. package/dist/threed/utils/bound-uv-generator.d.ts +0 -16
  245. package/dist/threed/utils/bound-uv-generator.js +0 -42
  246. package/dist/threed/utils/bound-uv-generator.js.map +0 -1
  247. package/dist/wall.d.ts +0 -13
  248. package/dist/wall.js +0 -45
  249. package/dist/wall.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"property-editor-gltf-fill-targets.js","sourceRoot":"","sources":["../../src/editors/property-editor-gltf-fill-targets.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n *\n * GLTF fillStyle 타겟 노드 선택 에디터.\n * All / None / Custom 모드로 명시적 설정.\n * Custom 모드에서 개별 Mesh 체크박스 선택.\n */\n\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxPropertyEditor, PropertySpec } from '@operato/property-editor'\nimport { ScrollbarStyles } from '@operato/styles/scrollbar-styles.js'\n\n// fillStyleTargets 값 규칙:\n// undefined 또는 미설정 → None (적용 안 함, 기본값)\n// '*' → All (전체 메시 적용)\n// ['mesh_0', ...] → Custom (선택 메시만 적용)\n\ntype FillMode = 'all' | 'none' | 'custom'\n\nfunction getMode(value: any): FillMode {\n if (value === '*') return 'all'\n if (value === 'none' || !value) return 'none'\n if (Array.isArray(value) && value.length > 0) return 'custom'\n // [] (빈 배열) = custom with nothing selected\n if (Array.isArray(value)) return 'custom'\n return 'none'\n}\n\n@customElement('property-editor-gltf-fill-targets')\nexport default class GLTFFillTargetsEditor extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n ScrollbarStyles,\n css`\n .mode-selector {\n display: flex;\n gap: 0;\n margin-bottom: 6px;\n border: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.15));\n border-radius: 6px;\n overflow: hidden;\n }\n\n .mode-btn {\n flex: 1;\n padding: 5px 0;\n font-size: 11px;\n font-weight: 500;\n text-align: center;\n cursor: pointer;\n background: var(--md-sys-color-surface-container, #f3edf7);\n color: var(--md-sys-color-on-surface, #1c1b1f);\n border: none;\n border-right: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.1));\n transition: all 0.15s;\n }\n\n .mode-btn:last-child {\n border-right: none;\n }\n\n .mode-btn:hover {\n background: var(--md-sys-color-surface-container-highest, #e6e0e9);\n }\n\n .mode-btn[active] {\n background: var(--md-sys-color-primary, #6750a4);\n color: var(--md-sys-color-on-primary, #fff);\n }\n\n .node-list {\n display: flex;\n flex-direction: column;\n gap: 1px;\n max-height: 200px;\n overflow-y: auto;\n font-size: 12px;\n }\n\n .node-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.1s;\n }\n\n .node-item:hover {\n background: var(--md-sys-color-primary-container, rgba(103, 80, 164, 0.12));\n }\n\n .node-item input[type='checkbox'] {\n margin: 0;\n accent-color: var(--md-sys-color-primary, #6750a4);\n }\n\n .node-item span {\n font-size: 12px;\n color: var(--md-sys-color-on-surface, #1c1b1f);\n }\n\n .mode-desc {\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant, #666);\n padding: 4px 0;\n }\n\n .mini-btn {\n font-size: 10px;\n padding: 2px 8px;\n border: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.15));\n border-radius: 4px;\n background: var(--md-sys-color-surface-container, #f3edf7);\n color: var(--md-sys-color-on-surface, #1c1b1f);\n cursor: pointer;\n }\n\n .mini-btn:hover {\n background: var(--md-sys-color-surface-container-highest, #e6e0e9);\n }\n\n .empty {\n color: var(--md-sys-color-on-surface-variant, #999);\n font-size: 11px;\n padding: 8px;\n text-align: center;\n }\n `\n ]\n\n @property({ type: String }) declare src: string | undefined\n\n @state() declare private _meshNames: string[]\n @state() declare private _mode: FillMode\n\n private _component: any = null\n private _lastExternalValue: any = undefined\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('src')) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: any[]) => {\n this._component = selected?.[0]\n this._refreshMeshNames()\n }\n }\n })\n )\n }\n }\n\n private _refreshMeshNames() {\n if (!this._component) {\n this._meshNames = []\n return\n }\n\n const ro = this._component.realObject as any\n if (!ro?.getNode) {\n this._meshNames = []\n return\n }\n\n this._meshNames = ((this._component.nodeNames as string[]) ?? []).filter((name: string) => {\n const node = ro.getNode(name)\n return node?.isMesh\n })\n }\n\n editorTemplate(value: any, _spec: PropertySpec): TemplateResult {\n if (!this._meshNames?.length) {\n this._refreshMeshNames()\n }\n\n // 외부 value가 변경되면 모드 동기화\n if (value !== this._lastExternalValue) {\n this._lastExternalValue = value\n this._mode = getMode(value)\n }\n\n const mode = this._mode\n const meshCount = this._meshNames?.length ?? 0\n const targets: string[] = Array.isArray(this.value) ? this.value : (Array.isArray(value) ? value : [])\n\n return html`\n <fieldset fullwidth>\n ${meshCount > 0\n ? html`\n <div class=\"mode-selector\">\n <div class=\"mode-btn\" ?active=${mode === 'all'} @click=${() => this._setMode('all')}>All</div>\n <div class=\"mode-btn\" ?active=${mode === 'none'} @click=${() => this._setMode('none')}>None</div>\n <div class=\"mode-btn\" ?active=${mode === 'custom'} @click=${() => this._setMode('custom')}>Custom</div>\n </div>\n\n ${mode === 'all'\n ? html`<div class=\"mode-desc\">${meshCount} meshes — fillStyle applies to all</div>`\n : nothing}\n ${mode === 'none'\n ? html`<div class=\"mode-desc\">fillStyle not applied to any mesh</div>`\n : nothing}\n ${mode === 'custom'\n ? html`\n <div style=\"display:flex;align-items:center;gap:6px\">\n <div class=\"mode-desc\" style=\"flex:1\">${targets.length} / ${meshCount} selected</div>\n <button class=\"mini-btn\" @click=${() => this._applyValue([...(this._meshNames ?? [])])}>All</button>\n <button class=\"mini-btn\" @click=${() => this._applyValue([])}>Clear</button>\n </div>\n <div class=\"node-list\">\n ${(this._meshNames ?? []).map(\n name => html`\n <label\n class=\"node-item\"\n @mouseenter=${() => this._highlightNode(name)}\n @mouseleave=${() => this._clearHighlight()}\n >\n <input\n type=\"checkbox\"\n .checked=${targets.includes(name)}\n @change=${(e: Event) => {\n e.stopPropagation()\n this._onToggle(name, (e.target as HTMLInputElement).checked, targets)\n }}\n />\n <span>${name}</span>\n </label>\n `\n )}\n </div>\n `\n : nothing}\n `\n : html`<div class=\"empty\">\n <ox-i18n msgid=\"label.no-gltf-meshes\">No meshes available</ox-i18n>\n </div>`}\n </fieldset>\n `\n }\n\n private _setMode(mode: FillMode) {\n const prevMode = this._mode\n this._mode = mode\n\n let newValue: any\n switch (mode) {\n case 'all':\n newValue = '*'\n break\n case 'none':\n newValue = 'none'\n break\n case 'custom':\n // 이전 상태에 따라: All → 전체 선택, None → 전체 해제\n if (prevMode === 'all') {\n newValue = [...(this._meshNames ?? [])]\n } else if (prevMode === 'none') {\n newValue = []\n } else {\n // 이미 custom이면 현재 값 유지\n newValue = Array.isArray(this.value) ? this.value : []\n }\n break\n }\n\n this._applyValue(newValue)\n }\n\n private _onToggle(name: string, checked: boolean, current: string[]) {\n const list = [...current]\n if (checked) {\n if (!list.includes(name)) list.push(name)\n } else {\n const idx = list.indexOf(name)\n if (idx >= 0) list.splice(idx, 1)\n }\n\n this._applyValue(list)\n }\n\n private _applyValue(newValue: any) {\n // 로컬 value 즉시 반영 (re-render)\n this.value = newValue\n this.requestUpdate()\n\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: any[]) => {\n selected[0].set('fillStyleTargets', newValue)\n }\n }\n })\n )\n }\n\n // --- Outline 강조 ---\n\n private _highlightNode(name: string) {\n const ro = this._component?.realObject as any\n if (!ro?.getNode) return\n\n const node = ro.getNode(name)\n if (!node) return\n\n this._getRendererManager()?.setOutlineObjects([node])\n this._component?.invalidate()\n }\n\n private _clearHighlight() {\n const ro = this._component?.realObject as any\n if (!ro) return\n\n this._getRendererManager()?.setOutlineObjects(ro.object3d ? [ro.object3d] : [])\n this._component?.invalidate()\n }\n\n private _getRendererManager(): any {\n const ro = this._component?.realObject as any\n const container = ro?.threeContainer as any\n return container?._capability?.rendererManager ?? container?._threeCapability?.rendererManager ?? null\n }\n}\n"]}
@@ -1,16 +1,38 @@
1
1
  import '@material/web/icon/icon.js';
2
- import '@material/web/button/elevated-button.js';
3
2
  import '@operato/i18n/ox-i18n.js';
4
3
  import { PropertyValues, TemplateResult } from 'lit';
5
4
  import { OxPropertyEditor, PropertySpec } from '@operato/property-editor';
6
5
  import { Component } from '@hatiolab/things-scene';
7
6
  export default class GLTFInfoEditor extends OxPropertyEditor {
8
7
  static styles: import("lit").CSSResult[];
9
- src?: string;
8
+ src: string | undefined;
9
+ private _component;
10
10
  width: number;
11
11
  height: number;
12
12
  depth: number;
13
+ currentWidth: number;
14
+ currentHeight: number;
15
+ currentDepth: number;
16
+ meshCount: number;
17
+ vertexCount: number;
18
+ animationCount: number;
19
+ materialCount: number;
20
+ constructor();
13
21
  editorTemplate(value: any, spec: PropertySpec): TemplateResult;
22
+ private _formatNumber;
23
+ private _isProportional;
24
+ private _applyAction;
25
+ /**
26
+ * W, H 중 짧은 쪽을 기준으로 원래 모델의 비율에 맞게 치수를 조절한다.
27
+ * (contain 방식 — 모델이 컴포넌트 영역 안에 들어감)
28
+ */
29
+ private _applyProportional;
30
+ private _getRatioLock;
31
+ private _setRatioLock;
32
+ private _refreshCurrentSize;
14
33
  updated(changes: PropertyValues<this>): void;
15
- fetchSourceInfo(component: Component, src: string): Promise<unknown>;
34
+ private _pollTimer?;
35
+ fetchSourceInfo(component: Component, src: string): Promise<void>;
36
+ private _tryReadFromRealObject;
37
+ disconnectedCallback(): void;
16
38
  }
@@ -1,58 +1,281 @@
1
1
  import { __decorate } from "tslib";
2
2
  import '@material/web/icon/icon.js';
3
- import '@material/web/button/elevated-button.js';
4
3
  import '@operato/i18n/ox-i18n.js';
5
4
  import { css, html } from 'lit';
6
5
  import { customElement, property, state } from 'lit/decorators.js';
7
6
  import { OxPropertyEditor } from '@operato/property-editor';
8
- import * as THREE from 'three';
9
- import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
7
+ import { ScrollbarStyles } from '@operato/styles/scrollbar-styles.js';
10
8
  let GLTFInfoEditor = class GLTFInfoEditor extends OxPropertyEditor {
9
+ static styles = [
10
+ ...OxPropertyEditor.styles,
11
+ ScrollbarStyles,
12
+ css `
13
+ [info-panel] {
14
+ font-size: 12px;
15
+ padding: 4px 0;
16
+ }
17
+
18
+ .dim-row {
19
+ display: flex;
20
+ align-items: center;
21
+ gap: 6px;
22
+ padding: 3px 0;
23
+ }
24
+
25
+ .dim-label {
26
+ min-width: 65px;
27
+ font-size: 11px;
28
+ color: var(--md-sys-color-on-surface-variant, #666);
29
+ }
30
+
31
+ .dim-value {
32
+ font-family: monospace;
33
+ font-size: 12px;
34
+ font-weight: 500;
35
+ }
36
+
37
+ .dim-value.mismatch {
38
+ color: var(--md-sys-color-error, #b3261e);
39
+ }
40
+
41
+ .dim-value.match {
42
+ color: var(--md-sys-color-primary, #6750a4);
43
+ }
44
+
45
+ .ratio-info {
46
+ font-size: 10px;
47
+ color: var(--md-sys-color-on-surface-variant, #888);
48
+ padding: 2px 0;
49
+ }
50
+
51
+ .button-row {
52
+ display: flex;
53
+ gap: 4px;
54
+ margin-top: 6px;
55
+ }
56
+
57
+ .action-btn {
58
+ flex: 1;
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ gap: 4px;
63
+ padding: 6px 8px;
64
+ border: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.2));
65
+ border-radius: 6px;
66
+ background: var(--md-sys-color-surface-container, #f3edf7);
67
+ cursor: pointer;
68
+ font-size: 11px;
69
+ color: var(--md-sys-color-on-surface, #1c1b1f);
70
+ transition: background 0.15s;
71
+ }
72
+
73
+ .action-btn:hover {
74
+ background: var(--md-sys-color-surface-container-highest, #e6e0e9);
75
+ }
76
+
77
+ .action-btn md-icon {
78
+ --md-icon-size: 16px;
79
+ }
80
+
81
+ .ratio-lock-toggle {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 4px;
85
+ font-size: 11px;
86
+ cursor: pointer;
87
+ color: var(--md-sys-color-on-surface, #1c1b1f);
88
+ }
89
+
90
+ .ratio-lock-toggle input[type='checkbox'] {
91
+ accent-color: var(--md-sys-color-primary, #6750a4);
92
+ margin: 0;
93
+ }
94
+
95
+ .stats-row {
96
+ display: flex;
97
+ gap: 12px;
98
+ padding: 4px 0;
99
+ margin-top: 4px;
100
+ border-top: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.1));
101
+ }
102
+
103
+ .stat-item {
104
+ display: flex;
105
+ align-items: center;
106
+ gap: 3px;
107
+ font-size: 11px;
108
+ color: var(--md-sys-color-on-surface-variant, #666);
109
+ }
110
+
111
+ .stat-item md-icon {
112
+ --md-icon-size: 13px;
113
+ }
114
+
115
+ .stat-value {
116
+ font-weight: 600;
117
+ color: var(--md-sys-color-on-surface, #1c1b1f);
118
+ }
119
+ `
120
+ ];
121
+ _component = null;
11
122
  constructor() {
12
- super(...arguments);
123
+ super();
13
124
  this.width = 0;
14
125
  this.height = 0;
15
126
  this.depth = 0;
127
+ this.currentWidth = 0;
128
+ this.currentHeight = 0;
129
+ this.currentDepth = 0;
130
+ this.meshCount = 0;
131
+ this.vertexCount = 0;
132
+ this.animationCount = 0;
133
+ this.materialCount = 0;
16
134
  }
17
135
  editorTemplate(value, spec) {
18
136
  const valid = this.width && this.height && this.depth;
19
137
  var property = spec.property || {};
20
138
  var { action } = property;
139
+ const isProportional = valid && this._isProportional();
21
140
  return html `
22
141
  <fieldset fullwidth>
23
- <legend><ox-i18n msgid="label.gltf-info">GLTF info.</ox-i18n></legend>
24
-
25
- <div>
26
- <div info>
27
- <div label>[W x H x D] :</div>
28
- ${valid
29
- ? html ` <div value>${this.width} x ${this.height} x ${this.depth}</div>
30
- <md-elevated-button
31
- @click=${(e) => {
32
- this.dispatchEvent(new CustomEvent('i-need-selected', {
33
- bubbles: true,
34
- composed: true,
35
- detail: {
36
- callback: (selected) => {
37
- typeof action === 'function' &&
38
- action(selected[0], {
39
- width: this.width,
40
- height: this.height,
41
- depth: this.depth
42
- });
43
- }
44
- }
45
- }));
46
- }}
142
+ <div info-panel>
143
+ ${valid
144
+ ? html `
145
+ <div class="dim-row">
146
+ <span class="dim-label">Model</span>
147
+ <span class="dim-value">${this.width} × ${this.height} × ${this.depth}</span>
148
+ </div>
149
+ <div class="dim-row">
150
+ <span class="dim-label">Current</span>
151
+ <span class="dim-value ${isProportional ? 'match' : 'mismatch'}">
152
+ ${this.currentWidth} × ${this.currentHeight} × ${this.currentDepth}
153
+ </span>
154
+ </div>
155
+
156
+ <div class="stats-row">
157
+ <span class="stat-item"><md-icon>view_in_ar</md-icon> <span class="stat-value">${this.meshCount}</span> meshes</span>
158
+ <span class="stat-item"><md-icon>scatter_plot</md-icon> <span class="stat-value">${this._formatNumber(this.vertexCount)}</span> verts</span>
159
+ <span class="stat-item"><md-icon>palette</md-icon> <span class="stat-value">${this.materialCount}</span> mats</span>
160
+ ${this.animationCount > 0
161
+ ? html `<span class="stat-item"><md-icon>animation</md-icon> <span class="stat-value">${this.animationCount}</span> anims</span>`
162
+ : ''}
163
+ </div>
164
+
165
+ <div class="button-row">
166
+ <div
167
+ class="action-btn"
168
+ title="W,H 중 짧은 쪽 기준으로 원본 비율 적용"
169
+ @click=${() => this._applyProportional(action)}
47
170
  >
48
- <md-icon>autorenew</md-icon>
49
- </md-elevated-button>`
50
- : html ` <div></div> `}
51
- </div>
171
+ <md-icon>aspect_ratio</md-icon>
172
+ <ox-i18n msgid="label.fit-ratio">Fit Ratio</ox-i18n>
173
+ </div>
174
+ <label class="ratio-lock-toggle">
175
+ <input
176
+ type="checkbox"
177
+ .checked=${this._getRatioLock()}
178
+ @change=${(e) => {
179
+ e.stopPropagation();
180
+ this._setRatioLock(e.target.checked);
181
+ }}
182
+ />
183
+ <md-icon style="--md-icon-size:14px">lock</md-icon>
184
+ Ratio Lock
185
+ </label>
186
+ </div>
187
+ `
188
+ : html `<div class="dim-row"><span class="dim-label">Loading...</span></div>`}
52
189
  </div>
53
190
  </fieldset>
54
191
  `;
55
192
  }
193
+ _formatNumber(n) {
194
+ if (n >= 1000000)
195
+ return (n / 1000000).toFixed(1) + 'M';
196
+ if (n >= 1000)
197
+ return (n / 1000).toFixed(1) + 'K';
198
+ return String(n);
199
+ }
200
+ _isProportional() {
201
+ if (!this.width || !this.height || !this.depth)
202
+ return true;
203
+ if (!this.currentWidth || !this.currentHeight || !this.currentDepth)
204
+ return true;
205
+ const rw = this.currentWidth / this.width;
206
+ const rh = this.currentHeight / this.height;
207
+ const rd = this.currentDepth / this.depth;
208
+ const avg = (rw + rh + rd) / 3;
209
+ const tolerance = 0.05;
210
+ return Math.abs(rw - avg) / avg < tolerance && Math.abs(rh - avg) / avg < tolerance && Math.abs(rd - avg) / avg < tolerance;
211
+ }
212
+ _applyAction(action, dimension) {
213
+ this.dispatchEvent(new CustomEvent('i-need-selected', {
214
+ bubbles: true,
215
+ composed: true,
216
+ detail: {
217
+ callback: (selected) => {
218
+ typeof action === 'function' && action(selected[0], dimension);
219
+ this._refreshCurrentSize(selected[0]);
220
+ }
221
+ }
222
+ }));
223
+ }
224
+ /**
225
+ * W, H 중 짧은 쪽을 기준으로 원래 모델의 비율에 맞게 치수를 조절한다.
226
+ * (contain 방식 — 모델이 컴포넌트 영역 안에 들어감)
227
+ */
228
+ _applyProportional(action) {
229
+ this.dispatchEvent(new CustomEvent('i-need-selected', {
230
+ bubbles: true,
231
+ composed: true,
232
+ detail: {
233
+ callback: (selected) => {
234
+ const component = selected[0];
235
+ if (!component || typeof action !== 'function')
236
+ return;
237
+ const { width: cw = 1, height: ch = 1, depth: cd = 1 } = component.state;
238
+ const { width: ow, height: oh, depth: od } = this; // 원래 모델 치수
239
+ if (!ow || !oh || !od)
240
+ return;
241
+ // 이미 비율이 맞으면 스킵
242
+ if (this._isProportional())
243
+ return;
244
+ // W, H 중 ratio가 작은 축을 기준
245
+ const scale = Math.min(cw / ow, ch / oh);
246
+ action(component, {
247
+ width: Math.round(ow * scale),
248
+ height: Math.round(oh * scale),
249
+ depth: Math.round(od * scale)
250
+ });
251
+ this._refreshCurrentSize(component);
252
+ }
253
+ }
254
+ }));
255
+ }
256
+ _getRatioLock() {
257
+ return !!this._component?.state?.ratioLock;
258
+ }
259
+ _setRatioLock(value) {
260
+ this.dispatchEvent(new CustomEvent('i-need-selected', {
261
+ bubbles: true,
262
+ composed: true,
263
+ detail: {
264
+ callback: (selected) => {
265
+ selected[0].set('ratioLock', value);
266
+ this.requestUpdate();
267
+ }
268
+ }
269
+ }));
270
+ }
271
+ _refreshCurrentSize(component) {
272
+ if (!component)
273
+ return;
274
+ const state = component.state || {};
275
+ this.currentWidth = Math.round(state.width || 0);
276
+ this.currentHeight = Math.round(state.height || 0);
277
+ this.currentDepth = Math.round(state.depth || 0);
278
+ }
56
279
  updated(changes) {
57
280
  if (changes.has('src')) {
58
281
  this.dispatchEvent(new CustomEvent('i-need-selected', {
@@ -60,60 +283,76 @@ let GLTFInfoEditor = class GLTFInfoEditor extends OxPropertyEditor {
60
283
  composed: true,
61
284
  detail: {
62
285
  callback: async (selected) => {
63
- await this.fetchSourceInfo(selected[0], this.src);
286
+ const component = selected[0];
287
+ this._component = component;
288
+ this._refreshCurrentSize(component);
289
+ await this.fetchSourceInfo(component, this.src);
64
290
  }
65
291
  }
66
292
  }));
67
293
  }
68
294
  }
295
+ _pollTimer;
69
296
  async fetchSourceInfo(component, src) {
70
297
  if (!src || !src.trim()) {
71
298
  return;
72
299
  }
73
- try {
74
- const path = component.app.url(src);
75
- let gltfLoader = new GLTFLoader();
76
- gltfLoader.setCrossOrigin('use-credentials');
77
- return new Promise((resolve) => {
78
- gltfLoader.load(path, gltf => {
79
- var box = new THREE.Box3().setFromObject(gltf.scene);
80
- var { x, y, z } = box.getSize(new THREE.Vector3());
81
- this.width = Math.floor(x);
82
- this.depth = Math.floor(y);
83
- this.height = Math.floor(z);
84
- resolve();
85
- });
86
- });
87
- }
88
- catch (e) {
89
- console.error(e);
300
+ // 이미 로드된 realObject에서 직접 정보를 읽는다
301
+ if (this._tryReadFromRealObject(component)) {
90
302
  return;
91
303
  }
304
+ // GLTF 비동기 로드 중이면 폴링 (최대 20회 = 10초)
305
+ if (this._pollTimer)
306
+ clearInterval(this._pollTimer);
307
+ let retries = 0;
308
+ this._pollTimer = window.setInterval(() => {
309
+ if (this._tryReadFromRealObject(component) || ++retries >= 20) {
310
+ clearInterval(this._pollTimer);
311
+ this._pollTimer = undefined;
312
+ }
313
+ }, 500);
314
+ }
315
+ _tryReadFromRealObject(component) {
316
+ const ro = component?.realObject;
317
+ if (!ro?.objectSize)
318
+ return false;
319
+ const { x = 0, y = 0, z = 0 } = ro.objectSize;
320
+ this.width = Math.round(x * 100) / 100;
321
+ this.depth = Math.round(y * 100) / 100;
322
+ this.height = Math.round(z * 100) / 100;
323
+ // 통계: pivot 또는 object3d에서 수집
324
+ const root = ro.pivot || ro.object3d;
325
+ if (root) {
326
+ let meshes = 0;
327
+ let vertices = 0;
328
+ const materials = new Set();
329
+ root.traverse((node) => {
330
+ if (node.isMesh) {
331
+ meshes++;
332
+ if (node.geometry) {
333
+ const pos = node.geometry.getAttribute('position');
334
+ if (pos)
335
+ vertices += pos.count;
336
+ }
337
+ if (node.material) {
338
+ const mats = Array.isArray(node.material) ? node.material : [node.material];
339
+ mats.forEach((m) => materials.add(m.uuid));
340
+ }
341
+ }
342
+ });
343
+ this.meshCount = meshes;
344
+ this.vertexCount = vertices;
345
+ this.materialCount = materials.size;
346
+ }
347
+ this.animationCount = ro._animationActions?.size || 0;
348
+ return true;
349
+ }
350
+ disconnectedCallback() {
351
+ super.disconnectedCallback();
352
+ if (this._pollTimer)
353
+ clearInterval(this._pollTimer);
92
354
  }
93
355
  };
94
- GLTFInfoEditor.styles = [
95
- ...OxPropertyEditor.styles,
96
- css `
97
- div[info] {
98
- display: flex;
99
- flex-direction: row;
100
- font-size: 12px;
101
- }
102
-
103
- div[info] * {
104
- align-self: center;
105
- }
106
-
107
- div[info] title {
108
- font-weight: bold;
109
- }
110
-
111
- div[info] md-elevated-button {
112
- margin-left: auto;
113
- --md-icon-size: 24px;
114
- }
115
- `
116
- ];
117
356
  __decorate([
118
357
  property({ type: String })
119
358
  ], GLTFInfoEditor.prototype, "src", void 0);
@@ -126,6 +365,27 @@ __decorate([
126
365
  __decorate([
127
366
  state()
128
367
  ], GLTFInfoEditor.prototype, "depth", void 0);
368
+ __decorate([
369
+ state()
370
+ ], GLTFInfoEditor.prototype, "currentWidth", void 0);
371
+ __decorate([
372
+ state()
373
+ ], GLTFInfoEditor.prototype, "currentHeight", void 0);
374
+ __decorate([
375
+ state()
376
+ ], GLTFInfoEditor.prototype, "currentDepth", void 0);
377
+ __decorate([
378
+ state()
379
+ ], GLTFInfoEditor.prototype, "meshCount", void 0);
380
+ __decorate([
381
+ state()
382
+ ], GLTFInfoEditor.prototype, "vertexCount", void 0);
383
+ __decorate([
384
+ state()
385
+ ], GLTFInfoEditor.prototype, "animationCount", void 0);
386
+ __decorate([
387
+ state()
388
+ ], GLTFInfoEditor.prototype, "materialCount", void 0);
129
389
  GLTFInfoEditor = __decorate([
130
390
  customElement('property-editor-gltf-info')
131
391
  ], GLTFInfoEditor);
@@ -1 +1 @@
1
- {"version":3,"file":"property-editor-gltf-info.js","sourceRoot":"","sources":["../../src/editors/property-editor-gltf-info.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/button/elevated-button.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxPropertyEditor, PropertySpec } from '@operato/property-editor'\nimport { Component } from '@hatiolab/things-scene'\n\nimport * as THREE from 'three'\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'\n\n@customElement('property-editor-gltf-info')\nexport default class GLTFInfoEditor extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n css`\n div[info] {\n display: flex;\n flex-direction: row;\n font-size: 12px;\n }\n\n div[info] * {\n align-self: center;\n }\n\n div[info] title {\n font-weight: bold;\n }\n\n div[info] md-elevated-button {\n margin-left: auto;\n --md-icon-size: 24px;\n }\n `\n ]\n\n @property({ type: String }) src?: string\n\n @state() width: number = 0\n @state() height: number = 0\n @state() depth: number = 0\n\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n const valid = this.width && this.height && this.depth\n\n var property = spec.property || {}\n var { action } = property\n\n return html`\n <fieldset fullwidth>\n <legend><ox-i18n msgid=\"label.gltf-info\">GLTF info.</ox-i18n></legend>\n\n <div>\n <div info>\n <div label>[W x H x D] :</div>\n ${valid\n ? html` <div value>${this.width} x ${this.height} x ${this.depth}</div>\n <md-elevated-button\n @click=${(e: MouseEvent) => {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: any[]) => {\n typeof action === 'function' &&\n action(selected[0], {\n width: this.width,\n height: this.height,\n depth: this.depth\n })\n }\n }\n })\n )\n }}\n >\n <md-icon>autorenew</md-icon>\n </md-elevated-button>`\n : html` <div></div> `}\n </div>\n </div>\n </fieldset>\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('src')) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: async (selected: any[]) => {\n await this.fetchSourceInfo(selected[0], this.src!)\n }\n }\n })\n )\n }\n }\n\n async fetchSourceInfo(component: Component, src: string) {\n if (!src || !src.trim()) {\n return\n }\n\n try {\n const path = component.app.url(src)\n\n let gltfLoader = new GLTFLoader()\n\n gltfLoader.setCrossOrigin('use-credentials')\n\n return new Promise((resolve: any) => {\n gltfLoader.load(path, gltf => {\n var box = new THREE.Box3().setFromObject(gltf.scene)\n var { x, y, z } = box.getSize(new THREE.Vector3())\n\n this.width = Math.floor(x)\n this.depth = Math.floor(y)\n this.height = Math.floor(z)\n\n resolve()\n })\n })\n } catch (e) {\n console.error(e)\n return\n }\n }\n}\n"]}
1
+ {"version":3,"file":"property-editor-gltf-info.js","sourceRoot":"","sources":["../../src/editors/property-editor-gltf-info.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, PropertyValues, TemplateResult } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { OxPropertyEditor, PropertySpec } from '@operato/property-editor'\nimport { ScrollbarStyles } from '@operato/styles/scrollbar-styles.js'\nimport { Component } from '@hatiolab/things-scene'\n\n@customElement('property-editor-gltf-info')\nexport default class GLTFInfoEditor extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n ScrollbarStyles,\n css`\n [info-panel] {\n font-size: 12px;\n padding: 4px 0;\n }\n\n .dim-row {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 3px 0;\n }\n\n .dim-label {\n min-width: 65px;\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant, #666);\n }\n\n .dim-value {\n font-family: monospace;\n font-size: 12px;\n font-weight: 500;\n }\n\n .dim-value.mismatch {\n color: var(--md-sys-color-error, #b3261e);\n }\n\n .dim-value.match {\n color: var(--md-sys-color-primary, #6750a4);\n }\n\n .ratio-info {\n font-size: 10px;\n color: var(--md-sys-color-on-surface-variant, #888);\n padding: 2px 0;\n }\n\n .button-row {\n display: flex;\n gap: 4px;\n margin-top: 6px;\n }\n\n .action-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 6px 8px;\n border: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.2));\n border-radius: 6px;\n background: var(--md-sys-color-surface-container, #f3edf7);\n cursor: pointer;\n font-size: 11px;\n color: var(--md-sys-color-on-surface, #1c1b1f);\n transition: background 0.15s;\n }\n\n .action-btn:hover {\n background: var(--md-sys-color-surface-container-highest, #e6e0e9);\n }\n\n .action-btn md-icon {\n --md-icon-size: 16px;\n }\n\n .ratio-lock-toggle {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n cursor: pointer;\n color: var(--md-sys-color-on-surface, #1c1b1f);\n }\n\n .ratio-lock-toggle input[type='checkbox'] {\n accent-color: var(--md-sys-color-primary, #6750a4);\n margin: 0;\n }\n\n .stats-row {\n display: flex;\n gap: 12px;\n padding: 4px 0;\n margin-top: 4px;\n border-top: 1px solid var(--md-sys-color-outline-variant, rgba(0, 0, 0, 0.1));\n }\n\n .stat-item {\n display: flex;\n align-items: center;\n gap: 3px;\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant, #666);\n }\n\n .stat-item md-icon {\n --md-icon-size: 13px;\n }\n\n .stat-value {\n font-weight: 600;\n color: var(--md-sys-color-on-surface, #1c1b1f);\n }\n `\n ]\n\n @property({ type: String }) declare src: string | undefined\n\n private _component: any = null\n\n @state() declare width: number\n @state() declare height: number\n @state() declare depth: number\n @state() declare currentWidth: number\n @state() declare currentHeight: number\n @state() declare currentDepth: number\n @state() declare meshCount: number\n @state() declare vertexCount: number\n @state() declare animationCount: number\n @state() declare materialCount: number\n\n constructor() {\n super()\n this.width = 0\n this.height = 0\n this.depth = 0\n this.currentWidth = 0\n this.currentHeight = 0\n this.currentDepth = 0\n this.meshCount = 0\n this.vertexCount = 0\n this.animationCount = 0\n this.materialCount = 0\n }\n\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n const valid = this.width && this.height && this.depth\n\n var property = spec.property || {}\n var { action } = property\n\n const isProportional = valid && this._isProportional()\n\n return html`\n <fieldset fullwidth>\n <div info-panel>\n ${valid\n ? html`\n <div class=\"dim-row\">\n <span class=\"dim-label\">Model</span>\n <span class=\"dim-value\">${this.width} × ${this.height} × ${this.depth}</span>\n </div>\n <div class=\"dim-row\">\n <span class=\"dim-label\">Current</span>\n <span class=\"dim-value ${isProportional ? 'match' : 'mismatch'}\">\n ${this.currentWidth} × ${this.currentHeight} × ${this.currentDepth}\n </span>\n </div>\n\n <div class=\"stats-row\">\n <span class=\"stat-item\"><md-icon>view_in_ar</md-icon> <span class=\"stat-value\">${this.meshCount}</span> meshes</span>\n <span class=\"stat-item\"><md-icon>scatter_plot</md-icon> <span class=\"stat-value\">${this._formatNumber(this.vertexCount)}</span> verts</span>\n <span class=\"stat-item\"><md-icon>palette</md-icon> <span class=\"stat-value\">${this.materialCount}</span> mats</span>\n ${this.animationCount > 0\n ? html`<span class=\"stat-item\"><md-icon>animation</md-icon> <span class=\"stat-value\">${this.animationCount}</span> anims</span>`\n : ''}\n </div>\n\n <div class=\"button-row\">\n <div\n class=\"action-btn\"\n title=\"W,H 중 짧은 쪽 기준으로 원본 비율 적용\"\n @click=${() => this._applyProportional(action)}\n >\n <md-icon>aspect_ratio</md-icon>\n <ox-i18n msgid=\"label.fit-ratio\">Fit Ratio</ox-i18n>\n </div>\n <label class=\"ratio-lock-toggle\">\n <input\n type=\"checkbox\"\n .checked=${this._getRatioLock()}\n @change=${(e: Event) => {\n e.stopPropagation()\n this._setRatioLock((e.target as HTMLInputElement).checked)\n }}\n />\n <md-icon style=\"--md-icon-size:14px\">lock</md-icon>\n Ratio Lock\n </label>\n </div>\n `\n : html`<div class=\"dim-row\"><span class=\"dim-label\">Loading...</span></div>`}\n </div>\n </fieldset>\n `\n }\n\n private _formatNumber(n: number): string {\n if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M'\n if (n >= 1000) return (n / 1000).toFixed(1) + 'K'\n return String(n)\n }\n\n private _isProportional(): boolean {\n if (!this.width || !this.height || !this.depth) return true\n if (!this.currentWidth || !this.currentHeight || !this.currentDepth) return true\n\n const rw = this.currentWidth / this.width\n const rh = this.currentHeight / this.height\n const rd = this.currentDepth / this.depth\n const avg = (rw + rh + rd) / 3\n const tolerance = 0.05\n\n return Math.abs(rw - avg) / avg < tolerance && Math.abs(rh - avg) / avg < tolerance && Math.abs(rd - avg) / avg < tolerance\n }\n\n private _applyAction(action: any, dimension: { width: number; height: number; depth: number }) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: any[]) => {\n typeof action === 'function' && action(selected[0], dimension)\n this._refreshCurrentSize(selected[0])\n }\n }\n })\n )\n }\n\n /**\n * W, H 중 짧은 쪽을 기준으로 원래 모델의 비율에 맞게 치수를 조절한다.\n * (contain 방식 — 모델이 컴포넌트 영역 안에 들어감)\n */\n private _applyProportional(action: any) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: any[]) => {\n const component = selected[0]\n if (!component || typeof action !== 'function') return\n\n const { width: cw = 1, height: ch = 1, depth: cd = 1 } = component.state\n const { width: ow, height: oh, depth: od } = this // 원래 모델 치수\n\n if (!ow || !oh || !od) return\n\n // 이미 비율이 맞으면 스킵\n if (this._isProportional()) return\n\n // W, H 중 ratio가 작은 축을 기준\n const scale = Math.min(cw / ow, ch / oh)\n\n action(component, {\n width: Math.round(ow * scale),\n height: Math.round(oh * scale),\n depth: Math.round(od * scale)\n })\n\n this._refreshCurrentSize(component)\n }\n }\n })\n )\n }\n\n private _getRatioLock(): boolean {\n return !!this._component?.state?.ratioLock\n }\n\n private _setRatioLock(value: boolean) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: (selected: any[]) => {\n selected[0].set('ratioLock', value)\n this.requestUpdate()\n }\n }\n })\n )\n }\n\n private _refreshCurrentSize(component: any) {\n if (!component) return\n const state = component.state || {}\n this.currentWidth = Math.round(state.width || 0)\n this.currentHeight = Math.round(state.height || 0)\n this.currentDepth = Math.round(state.depth || 0)\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('src')) {\n this.dispatchEvent(\n new CustomEvent('i-need-selected', {\n bubbles: true,\n composed: true,\n detail: {\n callback: async (selected: any[]) => {\n const component = selected[0]\n this._component = component\n this._refreshCurrentSize(component)\n await this.fetchSourceInfo(component, this.src!)\n }\n }\n })\n )\n }\n }\n\n private _pollTimer?: number\n\n async fetchSourceInfo(component: Component, src: string) {\n if (!src || !src.trim()) {\n return\n }\n\n // 이미 로드된 realObject에서 직접 정보를 읽는다\n if (this._tryReadFromRealObject(component)) {\n return\n }\n\n // GLTF 비동기 로드 중이면 폴링 (최대 20회 = 10초)\n if (this._pollTimer) clearInterval(this._pollTimer)\n let retries = 0\n this._pollTimer = window.setInterval(() => {\n if (this._tryReadFromRealObject(component) || ++retries >= 20) {\n clearInterval(this._pollTimer)\n this._pollTimer = undefined\n }\n }, 500)\n }\n\n private _tryReadFromRealObject(component: any): boolean {\n const ro = component?.realObject\n if (!ro?.objectSize) return false\n\n const { x = 0, y = 0, z = 0 } = ro.objectSize\n this.width = Math.round(x * 100) / 100\n this.depth = Math.round(y * 100) / 100\n this.height = Math.round(z * 100) / 100\n\n // 통계: pivot 또는 object3d에서 수집\n const root = ro.pivot || ro.object3d\n if (root) {\n let meshes = 0\n let vertices = 0\n const materials = new Set()\n\n root.traverse((node: any) => {\n if (node.isMesh) {\n meshes++\n if (node.geometry) {\n const pos = node.geometry.getAttribute('position')\n if (pos) vertices += pos.count\n }\n if (node.material) {\n const mats = Array.isArray(node.material) ? node.material : [node.material]\n mats.forEach((m: any) => materials.add(m.uuid))\n }\n }\n })\n\n this.meshCount = meshes\n this.vertexCount = vertices\n this.materialCount = materials.size\n }\n\n this.animationCount = ro._animationActions?.size || 0\n\n return true\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n if (this._pollTimer) clearInterval(this._pollTimer)\n }\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import '@material/web/icon/icon.js';
2
+ import '@operato/i18n/ox-i18n.js';
3
+ import { PropertyValues, TemplateResult } from 'lit';
4
+ import { OxPropertyEditor, PropertySpec } from '@operato/property-editor';
5
+ export default class GLTFPlayTargetsEditor extends OxPropertyEditor {
6
+ static styles: import("lit").CSSResult[];
7
+ src: string | undefined;
8
+ private _animNames;
9
+ private _mode;
10
+ private _playingAnim;
11
+ private _component;
12
+ private _lastExternalValue;
13
+ updated(changes: PropertyValues<this>): void;
14
+ private _refreshAnimNames;
15
+ private _pollTimer?;
16
+ connectedCallback(): void;
17
+ disconnectedCallback(): void;
18
+ editorTemplate(value: any, _spec: PropertySpec): TemplateResult;
19
+ private _setMode;
20
+ private _onToggle;
21
+ private _applyValue;
22
+ private _getPlayState;
23
+ private _setPlay;
24
+ private _togglePreview;
25
+ }