@planara/core 3.0.0 → 3.2.0

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 (302) hide show
  1. package/dist/core/index.d.ts +2 -0
  2. package/dist/core/index.d.ts.map +1 -0
  3. package/dist/core/renderer.d.ts +15 -18
  4. package/dist/core/renderer.d.ts.map +1 -1
  5. package/dist/handlers/benchmark/base-benchmark-handler.d.ts +81 -0
  6. package/dist/handlers/benchmark/base-benchmark-handler.d.ts.map +1 -0
  7. package/dist/handlers/benchmark/heavy-benchmark-handler.d.ts +33 -0
  8. package/dist/handlers/benchmark/heavy-benchmark-handler.d.ts.map +1 -0
  9. package/dist/handlers/benchmark/index.d.ts +6 -0
  10. package/dist/handlers/benchmark/index.d.ts.map +1 -0
  11. package/dist/handlers/benchmark/light-benchmark-handler.d.ts +33 -0
  12. package/dist/handlers/benchmark/light-benchmark-handler.d.ts.map +1 -0
  13. package/dist/handlers/benchmark/medium-benchmark-handler.d.ts +33 -0
  14. package/dist/handlers/benchmark/medium-benchmark-handler.d.ts.map +1 -0
  15. package/dist/handlers/benchmark/mixed-benchmark-handler.d.ts +37 -0
  16. package/dist/handlers/benchmark/mixed-benchmark-handler.d.ts.map +1 -0
  17. package/dist/handlers/display/index.d.ts +2 -0
  18. package/dist/handlers/display/index.d.ts.map +1 -0
  19. package/dist/handlers/display/wireframe-handler.d.ts +2 -2
  20. package/dist/handlers/display/wireframe-handler.d.ts.map +1 -1
  21. package/dist/handlers/scene/add-figure-scene-handler.d.ts +2 -2
  22. package/dist/handlers/scene/add-figure-scene-handler.d.ts.map +1 -1
  23. package/dist/handlers/scene/delete-figure-scene-handler.d.ts +3 -3
  24. package/dist/handlers/scene/delete-figure-scene-handler.d.ts.map +1 -1
  25. package/dist/handlers/scene/export-scene-handler.d.ts +23 -0
  26. package/dist/handlers/scene/export-scene-handler.d.ts.map +1 -0
  27. package/dist/handlers/scene/index.d.ts +6 -0
  28. package/dist/handlers/scene/index.d.ts.map +1 -0
  29. package/dist/handlers/scene/load-figure-scene-handler.d.ts +23 -0
  30. package/dist/handlers/scene/load-figure-scene-handler.d.ts.map +1 -0
  31. package/dist/handlers/scene/load-scene-handler.d.ts +23 -0
  32. package/dist/handlers/scene/load-scene-handler.d.ts.map +1 -0
  33. package/dist/handlers/select/edge-select-handler.d.ts +5 -8
  34. package/dist/handlers/select/edge-select-handler.d.ts.map +1 -1
  35. package/dist/handlers/select/face-select-handler.d.ts +5 -8
  36. package/dist/handlers/select/face-select-handler.d.ts.map +1 -1
  37. package/dist/handlers/select/index.d.ts +5 -0
  38. package/dist/handlers/select/index.d.ts.map +1 -0
  39. package/dist/handlers/select/mesh-select-handler.d.ts +5 -6
  40. package/dist/handlers/select/mesh-select-handler.d.ts.map +1 -1
  41. package/dist/handlers/select/vertex-select-handler.d.ts +5 -8
  42. package/dist/handlers/select/vertex-select-handler.d.ts.map +1 -1
  43. package/dist/handlers/tool/base-tool-handler.d.ts +3 -3
  44. package/dist/handlers/tool/base-tool-handler.d.ts.map +1 -1
  45. package/dist/handlers/tool/index.d.ts +4 -0
  46. package/dist/handlers/tool/index.d.ts.map +1 -0
  47. package/dist/handlers/tool/rotate-tool-handler.d.ts +2 -2
  48. package/dist/handlers/tool/rotate-tool-handler.d.ts.map +1 -1
  49. package/dist/handlers/tool/scale-tool-handler.d.ts +2 -2
  50. package/dist/handlers/tool/scale-tool-handler.d.ts.map +1 -1
  51. package/dist/handlers/tool/translate-tool-handler.d.ts +2 -2
  52. package/dist/handlers/tool/translate-tool-handler.d.ts.map +1 -1
  53. package/dist/hub/benchmark-hub.d.ts +65 -0
  54. package/dist/hub/benchmark-hub.d.ts.map +1 -0
  55. package/dist/hub/editor-hub.d.ts +12 -9
  56. package/dist/hub/editor-hub.d.ts.map +1 -1
  57. package/dist/hub/index.d.ts +38 -0
  58. package/dist/hub/index.d.ts.map +1 -0
  59. package/dist/hub/viewer-hub.d.ts +30 -0
  60. package/dist/hub/viewer-hub.d.ts.map +1 -0
  61. package/dist/index.cjs.js +20 -2
  62. package/dist/index.d.ts +15 -22
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.es.js +2838 -1041
  65. package/dist/index.full.d.ts +275 -97
  66. package/dist/index.public.d.ts +275 -97
  67. package/dist/index.umd.js +20 -2
  68. package/dist/interfaces/api/index.d.ts +12 -0
  69. package/dist/interfaces/api/index.d.ts.map +1 -0
  70. package/dist/interfaces/api/interaction-api.d.ts +26 -0
  71. package/dist/interfaces/api/interaction-api.d.ts.map +1 -0
  72. package/dist/interfaces/api/metrics-api.d.ts +49 -0
  73. package/dist/interfaces/api/metrics-api.d.ts.map +1 -0
  74. package/dist/interfaces/api/renderer/index.d.ts +7 -0
  75. package/dist/interfaces/api/renderer/index.d.ts.map +1 -0
  76. package/dist/interfaces/api/renderer/renderer-info-access.d.ts +20 -0
  77. package/dist/interfaces/api/renderer/renderer-info-access.d.ts.map +1 -0
  78. package/dist/interfaces/api/renderer-info-api.d.ts +19 -0
  79. package/dist/interfaces/api/renderer-info-api.d.ts.map +1 -0
  80. package/dist/interfaces/api/scene-api.d.ts +2 -1
  81. package/dist/interfaces/api/scene-api.d.ts.map +1 -1
  82. package/dist/interfaces/api/transform-api.d.ts +1 -1
  83. package/dist/interfaces/api/transform-api.d.ts.map +1 -1
  84. package/dist/interfaces/command/index.d.ts +1 -1
  85. package/dist/interfaces/command/index.d.ts.map +1 -1
  86. package/dist/interfaces/handler/benchmark-handler.d.ts +22 -0
  87. package/dist/interfaces/handler/benchmark-handler.d.ts.map +1 -0
  88. package/dist/interfaces/handler/index.d.ts +7 -0
  89. package/dist/interfaces/handler/index.d.ts.map +1 -0
  90. package/dist/interfaces/manager/benchmark-manager.d.ts +10 -0
  91. package/dist/interfaces/manager/benchmark-manager.d.ts.map +1 -0
  92. package/dist/interfaces/manager/display-manager.d.ts.map +1 -1
  93. package/dist/interfaces/manager/index.d.ts +7 -0
  94. package/dist/interfaces/manager/index.d.ts.map +1 -0
  95. package/dist/interfaces/manager/manager.d.ts +1 -1
  96. package/dist/interfaces/manager/manager.d.ts.map +1 -1
  97. package/dist/interfaces/manager/select-manager.d.ts.map +1 -1
  98. package/dist/interfaces/manager/tool-manager.d.ts.map +1 -1
  99. package/dist/interfaces/mediator/index.d.ts +1 -1
  100. package/dist/interfaces/mediator/index.d.ts.map +1 -1
  101. package/dist/interfaces/middleware/index.d.ts +1 -1
  102. package/dist/interfaces/middleware/index.d.ts.map +1 -1
  103. package/dist/interfaces/module/index.d.ts +6 -0
  104. package/dist/interfaces/module/index.d.ts.map +1 -0
  105. package/dist/interfaces/module/interactive-module.d.ts +32 -0
  106. package/dist/interfaces/module/interactive-module.d.ts.map +1 -0
  107. package/dist/interfaces/module/observer-module.d.ts +27 -0
  108. package/dist/interfaces/module/observer-module.d.ts.map +1 -0
  109. package/dist/interfaces/module/renderable-module.d.ts +1 -1
  110. package/dist/interfaces/module/renderable-module.d.ts.map +1 -1
  111. package/dist/interfaces/store/export-store.d.ts +8 -0
  112. package/dist/interfaces/store/export-store.d.ts.map +1 -0
  113. package/dist/interfaces/store/index.d.ts +7 -0
  114. package/dist/interfaces/store/index.d.ts.map +1 -0
  115. package/dist/interfaces/store/metrics-store.d.ts +60 -0
  116. package/dist/interfaces/store/metrics-store.d.ts.map +1 -0
  117. package/dist/interfaces/store/select-store.d.ts +1 -1
  118. package/dist/interfaces/store/select-store.d.ts.map +1 -1
  119. package/dist/interfaces/store/tool-store.d.ts +1 -1
  120. package/dist/interfaces/store/tool-store.d.ts.map +1 -1
  121. package/dist/interfaces/validator/index.d.ts +21 -0
  122. package/dist/interfaces/validator/index.d.ts.map +1 -0
  123. package/dist/interfaces/{controller/controller.d.ts → worker/index.d.ts} +5 -5
  124. package/dist/interfaces/worker/index.d.ts.map +1 -0
  125. package/dist/managers/benchmark/benchmark-manager.d.ts +27 -0
  126. package/dist/managers/benchmark/benchmark-manager.d.ts.map +1 -0
  127. package/dist/managers/benchmark/index.d.ts +2 -0
  128. package/dist/managers/benchmark/index.d.ts.map +1 -0
  129. package/dist/managers/display/display-manager.d.ts +4 -4
  130. package/dist/managers/display/display-manager.d.ts.map +1 -1
  131. package/dist/managers/display/index.d.ts +2 -0
  132. package/dist/managers/display/index.d.ts.map +1 -0
  133. package/dist/managers/index.d.ts +6 -0
  134. package/dist/managers/index.d.ts.map +1 -0
  135. package/dist/managers/scene/index.d.ts +2 -0
  136. package/dist/managers/scene/index.d.ts.map +1 -0
  137. package/dist/managers/scene/scene-manager.d.ts +5 -5
  138. package/dist/managers/scene/scene-manager.d.ts.map +1 -1
  139. package/dist/managers/select/index.d.ts +2 -0
  140. package/dist/managers/select/index.d.ts.map +1 -0
  141. package/dist/managers/select/select-manager.d.ts +5 -5
  142. package/dist/managers/select/select-manager.d.ts.map +1 -1
  143. package/dist/managers/tool/index.d.ts +2 -0
  144. package/dist/managers/tool/index.d.ts.map +1 -0
  145. package/dist/managers/tool/tool-manager.d.ts +4 -4
  146. package/dist/managers/tool/tool-manager.d.ts.map +1 -1
  147. package/dist/mediator/index.d.ts +2 -2
  148. package/dist/mediator/index.d.ts.map +1 -1
  149. package/dist/middlewares/exception-middleware.d.ts +7 -2
  150. package/dist/middlewares/exception-middleware.d.ts.map +1 -1
  151. package/dist/middlewares/index.d.ts +2 -0
  152. package/dist/middlewares/index.d.ts.map +1 -0
  153. package/dist/modules/controls-module.d.ts +40 -13
  154. package/dist/modules/controls-module.d.ts.map +1 -1
  155. package/dist/modules/gizmo-module.d.ts +18 -6
  156. package/dist/modules/gizmo-module.d.ts.map +1 -1
  157. package/dist/modules/index.d.ts +7 -0
  158. package/dist/modules/index.d.ts.map +1 -0
  159. package/dist/modules/metrics-module.d.ts +156 -0
  160. package/dist/modules/metrics-module.d.ts.map +1 -0
  161. package/dist/modules/raycast-module.d.ts +23 -10
  162. package/dist/modules/raycast-module.d.ts.map +1 -1
  163. package/dist/modules/scene-module.d.ts +2 -3
  164. package/dist/modules/scene-module.d.ts.map +1 -1
  165. package/dist/modules/scene-preview-module.d.ts +26 -0
  166. package/dist/modules/scene-preview-module.d.ts.map +1 -0
  167. package/dist/{api → shared/api}/modules/controls-state-api.d.ts +1 -1
  168. package/dist/shared/api/modules/controls-state-api.d.ts.map +1 -0
  169. package/dist/shared/api/modules/index.d.ts +6 -0
  170. package/dist/shared/api/modules/index.d.ts.map +1 -0
  171. package/dist/shared/api/modules/interaction-api.d.ts +21 -0
  172. package/dist/shared/api/modules/interaction-api.d.ts.map +1 -0
  173. package/dist/{api → shared/api}/modules/mesh-api.d.ts +1 -1
  174. package/dist/shared/api/modules/mesh-api.d.ts.map +1 -0
  175. package/dist/{api → shared/api}/modules/raycast-api.d.ts +1 -1
  176. package/dist/shared/api/modules/raycast-api.d.ts.map +1 -0
  177. package/dist/{api → shared/api}/modules/transform-api.d.ts +2 -2
  178. package/dist/shared/api/modules/transform-api.d.ts.map +1 -0
  179. package/dist/{api → shared/api}/renderer/camera-api.d.ts +2 -2
  180. package/dist/shared/api/renderer/camera-api.d.ts.map +1 -0
  181. package/dist/{api → shared/api}/renderer/dom-api.d.ts +2 -2
  182. package/dist/shared/api/renderer/dom-api.d.ts.map +1 -0
  183. package/dist/shared/api/renderer/index.d.ts +5 -0
  184. package/dist/shared/api/renderer/index.d.ts.map +1 -0
  185. package/dist/shared/api/renderer/renderer-info-api.d.ts +25 -0
  186. package/dist/shared/api/renderer/renderer-info-api.d.ts.map +1 -0
  187. package/dist/{api → shared/api}/renderer/scene-api.d.ts +21 -3
  188. package/dist/shared/api/renderer/scene-api.d.ts.map +1 -0
  189. package/dist/shared/constants/benchmark.d.ts +5 -0
  190. package/dist/shared/constants/benchmark.d.ts.map +1 -0
  191. package/dist/shared/constants/colors.d.ts.map +1 -0
  192. package/dist/shared/constants/figure-geometries.d.ts.map +1 -0
  193. package/dist/shared/constants/index.d.ts +7 -0
  194. package/dist/shared/constants/index.d.ts.map +1 -0
  195. package/dist/shared/constants/layers.d.ts.map +1 -0
  196. package/dist/shared/constants/messages.d.ts.map +1 -0
  197. package/dist/shared/constants/threshold.d.ts.map +1 -0
  198. package/dist/shared/decorators/index.d.ts +3 -0
  199. package/dist/shared/decorators/index.d.ts.map +1 -0
  200. package/dist/{decorators → shared/decorators}/use-policy.d.ts +1 -1
  201. package/dist/shared/decorators/use-policy.d.ts.map +1 -0
  202. package/dist/shared/decorators/use-validator.d.ts +5 -0
  203. package/dist/shared/decorators/use-validator.d.ts.map +1 -0
  204. package/dist/shared/errors/index.d.ts +3 -0
  205. package/dist/shared/errors/index.d.ts.map +1 -0
  206. package/dist/{errors → shared/errors}/policy-error.d.ts +1 -1
  207. package/dist/shared/errors/policy-error.d.ts.map +1 -0
  208. package/dist/shared/errors/validation-error.d.ts +9 -0
  209. package/dist/shared/errors/validation-error.d.ts.map +1 -0
  210. package/dist/{events → shared/events}/editor-events.d.ts +1 -1
  211. package/dist/shared/events/editor-events.d.ts.map +1 -0
  212. package/dist/{events → shared/events}/event-bus.d.ts +1 -1
  213. package/dist/shared/events/event-bus.d.ts.map +1 -0
  214. package/dist/shared/events/event-topics.d.ts.map +1 -0
  215. package/dist/shared/events/index.d.ts +4 -0
  216. package/dist/shared/events/index.d.ts.map +1 -0
  217. package/dist/shared/ioc/container.d.ts +10 -0
  218. package/dist/shared/ioc/container.d.ts.map +1 -0
  219. package/dist/shared/loaders/obj-loader.d.ts.map +1 -0
  220. package/dist/shared/policy/index.d.ts +2 -0
  221. package/dist/shared/policy/index.d.ts.map +1 -0
  222. package/dist/{policy → shared/policy}/tool-policy.d.ts +2 -2
  223. package/dist/shared/policy/tool-policy.d.ts.map +1 -0
  224. package/dist/shared/utils/default-renderer-config.d.ts +9 -0
  225. package/dist/shared/utils/default-renderer-config.d.ts.map +1 -0
  226. package/dist/shared/utils/helpers.d.ts +26 -0
  227. package/dist/shared/utils/helpers.d.ts.map +1 -0
  228. package/dist/shared/utils/index.d.ts +3 -0
  229. package/dist/shared/utils/index.d.ts.map +1 -0
  230. package/dist/shared/validators/index.d.ts +2 -0
  231. package/dist/shared/validators/index.d.ts.map +1 -0
  232. package/dist/shared/validators/obj-validator.d.ts +12 -0
  233. package/dist/shared/validators/obj-validator.d.ts.map +1 -0
  234. package/dist/store/editor-store.d.ts +33 -0
  235. package/dist/store/editor-store.d.ts.map +1 -0
  236. package/dist/store/export-store.d.ts +12 -0
  237. package/dist/store/export-store.d.ts.map +1 -0
  238. package/dist/store/index.d.ts +3 -35
  239. package/dist/store/index.d.ts.map +1 -1
  240. package/dist/store/metrics-store.d.ts +32 -0
  241. package/dist/store/metrics-store.d.ts.map +1 -0
  242. package/dist/types/camera/index.d.ts +2 -0
  243. package/dist/types/camera/index.d.ts.map +1 -0
  244. package/dist/types/event/index.d.ts +2 -0
  245. package/dist/types/event/index.d.ts.map +1 -0
  246. package/dist/types/feature/feature-type.d.ts +3 -1
  247. package/dist/types/feature/feature-type.d.ts.map +1 -1
  248. package/dist/types/feature/index.d.ts +2 -0
  249. package/dist/types/feature/index.d.ts.map +1 -0
  250. package/dist/types/listener/index.d.ts +4 -0
  251. package/dist/types/listener/index.d.ts.map +1 -0
  252. package/dist/types/listener/metrics-listener.d.ts +4 -0
  253. package/dist/types/listener/metrics-listener.d.ts.map +1 -0
  254. package/dist/types/renderer/index.d.ts +2 -0
  255. package/dist/types/renderer/index.d.ts.map +1 -0
  256. package/dist/types/renderer/renderer-info-metrics.d.ts +8 -0
  257. package/dist/types/renderer/renderer-info-metrics.d.ts.map +1 -0
  258. package/dist/types/select/index.d.ts +2 -0
  259. package/dist/types/select/index.d.ts.map +1 -0
  260. package/dist/workers/index.d.ts +2 -0
  261. package/dist/workers/index.d.ts.map +1 -0
  262. package/dist/{controllers/renderer-controller.d.ts → workers/renderer-worker.d.ts} +15 -14
  263. package/dist/workers/renderer-worker.d.ts.map +1 -0
  264. package/package.json +3 -3
  265. package/dist/api/modules/controls-state-api.d.ts.map +0 -1
  266. package/dist/api/modules/mesh-api.d.ts.map +0 -1
  267. package/dist/api/modules/raycast-api.d.ts.map +0 -1
  268. package/dist/api/modules/transform-api.d.ts.map +0 -1
  269. package/dist/api/renderer/camera-api.d.ts.map +0 -1
  270. package/dist/api/renderer/dom-api.d.ts.map +0 -1
  271. package/dist/api/renderer/scene-api.d.ts.map +0 -1
  272. package/dist/constants/colors.d.ts.map +0 -1
  273. package/dist/constants/figure-geometries.d.ts.map +0 -1
  274. package/dist/constants/layers.d.ts.map +0 -1
  275. package/dist/constants/messages.d.ts.map +0 -1
  276. package/dist/constants/threshold.d.ts.map +0 -1
  277. package/dist/controllers/renderer-controller.d.ts.map +0 -1
  278. package/dist/decorators/use-policy.d.ts.map +0 -1
  279. package/dist/errors/policy-error.d.ts.map +0 -1
  280. package/dist/events/editor-events.d.ts.map +0 -1
  281. package/dist/events/event-bus.d.ts.map +0 -1
  282. package/dist/events/event-topics.d.ts.map +0 -1
  283. package/dist/hub/app-hub.d.ts +0 -13
  284. package/dist/hub/app-hub.d.ts.map +0 -1
  285. package/dist/interfaces/controller/controller.d.ts.map +0 -1
  286. package/dist/interfaces/response/index.d.ts +0 -22
  287. package/dist/interfaces/response/index.d.ts.map +0 -1
  288. package/dist/ioc/container.d.ts +0 -5
  289. package/dist/ioc/container.d.ts.map +0 -1
  290. package/dist/loaders/obj-loader.d.ts.map +0 -1
  291. package/dist/policy/tool-policy.d.ts.map +0 -1
  292. package/dist/types/response/response-type.d.ts +0 -19
  293. package/dist/types/response/response-type.d.ts.map +0 -1
  294. package/dist/utils/helpers.d.ts +0 -13
  295. package/dist/utils/helpers.d.ts.map +0 -1
  296. /package/dist/{constants → shared/constants}/colors.d.ts +0 -0
  297. /package/dist/{constants → shared/constants}/figure-geometries.d.ts +0 -0
  298. /package/dist/{constants → shared/constants}/layers.d.ts +0 -0
  299. /package/dist/{constants → shared/constants}/messages.d.ts +0 -0
  300. /package/dist/{constants → shared/constants}/threshold.d.ts +0 -0
  301. /package/dist/{events → shared/events}/event-topics.d.ts +0 -0
  302. /package/dist/{loaders → shared/loaders}/obj-loader.d.ts +0 -0
package/dist/index.es.js CHANGED
@@ -1,16 +1,648 @@
1
1
  import "reflect-metadata";
2
2
  import * as a from "three";
3
- import { injectable as d, inject as l, injectAll as D, container as et } from "tsyringe";
4
- import { FigureType as O, Figure as tt, SelectMode as M, DisplayMode as F, ToolType as j, SceneMode as W, DEFAULT_TOOL_RULES as st } from "@planara/types";
5
- import { OrbitWithState as rt, ModelingTransformControls as it, CameraAxesGizmo as ot, SymmetricAxesHelper as nt } from "@planara/three";
6
- import { EventEmitter as at } from "events";
7
- import { makeAutoObservable as ct } from "mobx";
8
- var lt = Object.getOwnPropertyDescriptor, ht = (e, t, r, s) => {
9
- for (var i = s > 1 ? void 0 : s ? lt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
10
- (n = e[o]) && (i = n(i) || i);
3
+ import { Loader as wr, FileLoader as Sr, Color as Kt, SRGBColorSpace as qt, Group as xr, BufferGeometry as Ct, Float32BufferAttribute as U, LineBasicMaterial as we, Material as Ot, PointsMaterial as te, MeshPhongMaterial as Ar, LineSegments as Et, Points as Se, Mesh as Pt, Vector3 as z, Vector2 as Ir, Matrix3 as Cr, ColorManagement as Or } from "three";
4
+ import { injectable as v, inject as c, injectAll as H, container as Er } from "tsyringe";
5
+ import { FigureType as E, Figure as Pr, SelectMode as O, DisplayMode as J, SceneMode as T, ToolType as W, BenchmarkTestType as X, BenchmarkTestStatus as Pe, DEFAULT_TOOL_RULES as Lr, ResponseType as G } from "@planara/types";
6
+ import { OrbitWithState as Tr, ModelingTransformControls as Dr, CameraAxesGizmo as jr, SymmetricAxesHelper as Vr } from "@planara/three";
7
+ import { EventEmitter as Hr } from "events";
8
+ import { makeAutoObservable as bt, observable as $r } from "mobx";
9
+ const Rr = /^[og]\s*(.+)?/, Br = /^mtllib /, Fr = /^usemtl /, kr = /^usemap /, Lt = /\s+/, Tt = new z(), xe = new z(), Dt = new z(), jt = new z(), V = new z(), re = new Kt();
10
+ function Gr() {
11
+ const e = {
12
+ objects: [],
13
+ object: {},
14
+ vertices: [],
15
+ normals: [],
16
+ colors: [],
17
+ uvs: [],
18
+ materials: {},
19
+ materialLibraries: [],
20
+ startObject: function(t, r) {
21
+ if (this.object && this.object.fromDeclaration === !1) {
22
+ this.object.name = t, this.object.fromDeclaration = r !== !1;
23
+ return;
24
+ }
25
+ const s = this.object && typeof this.object.currentMaterial == "function" ? this.object.currentMaterial() : void 0;
26
+ if (this.object && typeof this.object._finalize == "function" && this.object._finalize(!0), this.object = {
27
+ name: t || "",
28
+ fromDeclaration: r !== !1,
29
+ geometry: {
30
+ vertices: [],
31
+ normals: [],
32
+ colors: [],
33
+ uvs: [],
34
+ hasUVIndices: !1
35
+ },
36
+ materials: [],
37
+ smooth: !0,
38
+ startMaterial: function(i, n) {
39
+ const o = this._finalize(!1);
40
+ o && (o.inherited || o.groupCount <= 0) && this.materials.splice(o.index, 1);
41
+ const l = {
42
+ index: this.materials.length,
43
+ name: i || "",
44
+ mtllib: Array.isArray(n) && n.length > 0 ? n[n.length - 1] : "",
45
+ smooth: o !== void 0 ? o.smooth : this.smooth,
46
+ groupStart: o !== void 0 ? o.groupEnd : 0,
47
+ groupEnd: -1,
48
+ groupCount: -1,
49
+ inherited: !1,
50
+ clone: function(h) {
51
+ const d = {
52
+ index: typeof h == "number" ? h : this.index,
53
+ name: this.name,
54
+ mtllib: this.mtllib,
55
+ smooth: this.smooth,
56
+ groupStart: 0,
57
+ groupEnd: -1,
58
+ groupCount: -1,
59
+ inherited: !1
60
+ };
61
+ return d.clone = this.clone.bind(d), d;
62
+ }
63
+ };
64
+ return this.materials.push(l), l;
65
+ },
66
+ currentMaterial: function() {
67
+ if (this.materials.length > 0)
68
+ return this.materials[this.materials.length - 1];
69
+ },
70
+ _finalize: function(i) {
71
+ const n = this.currentMaterial();
72
+ if (n && n.groupEnd === -1 && (n.groupEnd = this.geometry.vertices.length / 3, n.groupCount = n.groupEnd - n.groupStart, n.inherited = !1), i && this.materials.length > 1)
73
+ for (let o = this.materials.length - 1; o >= 0; o--)
74
+ this.materials[o].groupCount <= 0 && this.materials.splice(o, 1);
75
+ return i && this.materials.length === 0 && this.materials.push({
76
+ name: "",
77
+ smooth: this.smooth
78
+ }), n;
79
+ }
80
+ }, s && s.name && typeof s.clone == "function") {
81
+ const i = s.clone(0);
82
+ i.inherited = !0, this.object.materials.push(i);
83
+ }
84
+ this.objects.push(this.object);
85
+ },
86
+ finalize: function() {
87
+ this.object && typeof this.object._finalize == "function" && this.object._finalize(!0);
88
+ },
89
+ parseVertexIndex: function(t, r) {
90
+ const s = parseInt(t, 10);
91
+ return (s >= 0 ? s - 1 : s + r / 3) * 3;
92
+ },
93
+ parseNormalIndex: function(t, r) {
94
+ const s = parseInt(t, 10);
95
+ return (s >= 0 ? s - 1 : s + r / 3) * 3;
96
+ },
97
+ parseUVIndex: function(t, r) {
98
+ const s = parseInt(t, 10);
99
+ return (s >= 0 ? s - 1 : s + r / 2) * 2;
100
+ },
101
+ addVertex: function(t, r, s) {
102
+ const i = this.vertices, n = this.object.geometry.vertices;
103
+ n.push(i[t + 0], i[t + 1], i[t + 2]), n.push(i[r + 0], i[r + 1], i[r + 2]), n.push(i[s + 0], i[s + 1], i[s + 2]);
104
+ },
105
+ addVertexPoint: function(t) {
106
+ const r = this.vertices;
107
+ this.object.geometry.vertices.push(r[t + 0], r[t + 1], r[t + 2]);
108
+ },
109
+ addVertexLine: function(t) {
110
+ const r = this.vertices;
111
+ this.object.geometry.vertices.push(r[t + 0], r[t + 1], r[t + 2]);
112
+ },
113
+ addNormal: function(t, r, s) {
114
+ const i = this.normals, n = this.object.geometry.normals;
115
+ n.push(i[t + 0], i[t + 1], i[t + 2]), n.push(i[r + 0], i[r + 1], i[r + 2]), n.push(i[s + 0], i[s + 1], i[s + 2]);
116
+ },
117
+ addFaceNormal: function(t, r, s) {
118
+ const i = this.vertices, n = this.object.geometry.normals;
119
+ Tt.fromArray(i, t), xe.fromArray(i, r), Dt.fromArray(i, s), V.subVectors(Dt, xe), jt.subVectors(Tt, xe), V.cross(jt), V.normalize(), n.push(V.x, V.y, V.z), n.push(V.x, V.y, V.z), n.push(V.x, V.y, V.z);
120
+ },
121
+ addColor: function(t, r, s) {
122
+ const i = this.colors, n = this.object.geometry.colors;
123
+ i[t] !== void 0 && n.push(i[t + 0], i[t + 1], i[t + 2]), i[r] !== void 0 && n.push(i[r + 0], i[r + 1], i[r + 2]), i[s] !== void 0 && n.push(i[s + 0], i[s + 1], i[s + 2]);
124
+ },
125
+ addUV: function(t, r, s) {
126
+ const i = this.uvs, n = this.object.geometry.uvs;
127
+ n.push(i[t + 0], i[t + 1]), n.push(i[r + 0], i[r + 1]), n.push(i[s + 0], i[s + 1]);
128
+ },
129
+ addDefaultUV: function() {
130
+ const t = this.object.geometry.uvs;
131
+ t.push(0, 0), t.push(0, 0), t.push(0, 0);
132
+ },
133
+ addUVLine: function(t) {
134
+ const r = this.uvs;
135
+ this.object.geometry.uvs.push(r[t + 0], r[t + 1]);
136
+ },
137
+ addFace: function(t, r, s, i, n, o, l, h, d) {
138
+ const p = this.vertices.length;
139
+ let u = this.parseVertexIndex(t, p), m = this.parseVertexIndex(r, p), f = this.parseVertexIndex(s, p);
140
+ if (this.addVertex(u, m, f), this.addColor(u, m, f), l !== void 0 && l !== "") {
141
+ const _ = this.normals.length;
142
+ u = this.parseNormalIndex(l, _), m = this.parseNormalIndex(h, _), f = this.parseNormalIndex(d, _), this.addNormal(u, m, f);
143
+ } else
144
+ this.addFaceNormal(u, m, f);
145
+ if (i !== void 0 && i !== "") {
146
+ const _ = this.uvs.length;
147
+ u = this.parseUVIndex(i, _), m = this.parseUVIndex(n, _), f = this.parseUVIndex(o, _), this.addUV(u, m, f), this.object.geometry.hasUVIndices = !0;
148
+ } else
149
+ this.addDefaultUV();
150
+ },
151
+ addPointGeometry: function(t) {
152
+ this.object.geometry.type = "Points";
153
+ const r = this.vertices.length;
154
+ for (let s = 0, i = t.length; s < i; s++) {
155
+ const n = this.parseVertexIndex(t[s], r);
156
+ this.addVertexPoint(n), this.addColor(n);
157
+ }
158
+ },
159
+ addLineGeometry: function(t, r) {
160
+ this.object.geometry.type = "Line";
161
+ const s = this.vertices.length, i = this.uvs.length;
162
+ for (let n = 0, o = t.length; n < o; n++)
163
+ this.addVertexLine(this.parseVertexIndex(t[n], s));
164
+ for (let n = 0, o = r.length; n < o; n++)
165
+ this.addUVLine(this.parseUVIndex(r[n], i));
166
+ }
167
+ };
168
+ return e.startObject("", !1), e;
169
+ }
170
+ class zr extends wr {
171
+ /**
172
+ * Constructs a new OBJ loader.
173
+ *
174
+ * @param {LoadingManager} [manager] - The loading manager.
175
+ */
176
+ constructor(t) {
177
+ super(t), this.materials = null;
178
+ }
179
+ /**
180
+ * Starts loading from the given URL and passes the loaded OBJ asset
181
+ * to the `onLoad()` callback.
182
+ *
183
+ * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
184
+ * @param {function(Group)} onLoad - Executed when the loading process has been finished.
185
+ * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
186
+ * @param {onErrorCallback} onError - Executed when errors occur.
187
+ */
188
+ load(t, r, s, i) {
189
+ const n = this, o = new Sr(this.manager);
190
+ o.setPath(this.path), o.setRequestHeader(this.requestHeader), o.setWithCredentials(this.withCredentials), o.load(t, function(l) {
191
+ try {
192
+ r(n.parse(l));
193
+ } catch (h) {
194
+ i ? i(h) : console.error(h), n.manager.itemError(t);
195
+ }
196
+ }, s, i);
197
+ }
198
+ /**
199
+ * Sets the material creator for this OBJ. This object is loaded via {@link MTLLoader}.
200
+ *
201
+ * @param {MaterialCreator} materials - An object that creates the materials for this OBJ.
202
+ * @return {OBJLoader} A reference to this loader.
203
+ */
204
+ setMaterials(t) {
205
+ return this.materials = t, this;
206
+ }
207
+ /**
208
+ * Parses the given OBJ data and returns the resulting group.
209
+ *
210
+ * @param {string} text - The raw OBJ data as a string.
211
+ * @return {Group} The parsed OBJ.
212
+ */
213
+ parse(t) {
214
+ const r = new Gr();
215
+ t.indexOf(`\r
216
+ `) !== -1 && (t = t.replace(/\r\n/g, `
217
+ `)), t.indexOf(`\\
218
+ `) !== -1 && (t = t.replace(/\\\n/g, ""));
219
+ const s = t.split(`
220
+ `);
221
+ let i = [];
222
+ for (let l = 0, h = s.length; l < h; l++) {
223
+ const d = s[l].trimStart();
224
+ if (d.length === 0) continue;
225
+ const p = d.charAt(0);
226
+ if (p !== "#")
227
+ if (p === "v") {
228
+ const u = d.split(Lt);
229
+ switch (u[0]) {
230
+ case "v":
231
+ r.vertices.push(
232
+ parseFloat(u[1]),
233
+ parseFloat(u[2]),
234
+ parseFloat(u[3])
235
+ ), u.length >= 7 ? (re.setRGB(
236
+ parseFloat(u[4]),
237
+ parseFloat(u[5]),
238
+ parseFloat(u[6]),
239
+ qt
240
+ ), r.colors.push(re.r, re.g, re.b)) : r.colors.push(void 0, void 0, void 0);
241
+ break;
242
+ case "vn":
243
+ r.normals.push(
244
+ parseFloat(u[1]),
245
+ parseFloat(u[2]),
246
+ parseFloat(u[3])
247
+ );
248
+ break;
249
+ case "vt":
250
+ r.uvs.push(
251
+ parseFloat(u[1]),
252
+ parseFloat(u[2])
253
+ );
254
+ break;
255
+ }
256
+ } else if (p === "f") {
257
+ const m = d.slice(1).trim().split(Lt), f = [];
258
+ for (let g = 0, b = m.length; g < b; g++) {
259
+ const x = m[g];
260
+ if (x.length > 0) {
261
+ const S = x.split("/");
262
+ f.push(S);
263
+ }
264
+ }
265
+ const _ = f[0];
266
+ for (let g = 1, b = f.length - 1; g < b; g++) {
267
+ const x = f[g], S = f[g + 1];
268
+ r.addFace(
269
+ _[0],
270
+ x[0],
271
+ S[0],
272
+ _[1],
273
+ x[1],
274
+ S[1],
275
+ _[2],
276
+ x[2],
277
+ S[2]
278
+ );
279
+ }
280
+ } else if (p === "l") {
281
+ const u = d.substring(1).trim().split(" ");
282
+ let m = [];
283
+ const f = [];
284
+ if (d.indexOf("/") === -1)
285
+ m = u;
286
+ else
287
+ for (let _ = 0, g = u.length; _ < g; _++) {
288
+ const b = u[_].split("/");
289
+ b[0] !== "" && m.push(b[0]), b[1] !== "" && f.push(b[1]);
290
+ }
291
+ r.addLineGeometry(m, f);
292
+ } else if (p === "p") {
293
+ const m = d.slice(1).trim().split(" ");
294
+ r.addPointGeometry(m);
295
+ } else if ((i = Rr.exec(d)) !== null) {
296
+ const u = (" " + i[0].slice(1).trim()).slice(1);
297
+ r.startObject(u);
298
+ } else if (Fr.test(d))
299
+ r.object.startMaterial(d.substring(7).trim(), r.materialLibraries);
300
+ else if (Br.test(d))
301
+ r.materialLibraries.push(d.substring(7).trim());
302
+ else if (kr.test(d))
303
+ console.warn('THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');
304
+ else if (p === "s") {
305
+ if (i = d.split(" "), i.length > 1) {
306
+ const m = i[1].trim().toLowerCase();
307
+ r.object.smooth = m !== "0" && m !== "off";
308
+ } else
309
+ r.object.smooth = !0;
310
+ const u = r.object.currentMaterial();
311
+ u && (u.smooth = r.object.smooth);
312
+ } else {
313
+ if (d === "\0") continue;
314
+ console.warn('THREE.OBJLoader: Unexpected line: "' + d + '"');
315
+ }
316
+ }
317
+ r.finalize();
318
+ const n = new xr();
319
+ if (n.materialLibraries = [].concat(r.materialLibraries), !(r.objects.length === 1 && r.objects[0].geometry.vertices.length === 0) === !0)
320
+ for (let l = 0, h = r.objects.length; l < h; l++) {
321
+ const d = r.objects[l], p = d.geometry, u = d.materials, m = p.type === "Line", f = p.type === "Points";
322
+ let _ = !1;
323
+ if (p.vertices.length === 0) continue;
324
+ const g = new Ct();
325
+ g.setAttribute("position", new U(p.vertices, 3)), p.normals.length > 0 && g.setAttribute("normal", new U(p.normals, 3)), p.colors.length > 0 && (_ = !0, g.setAttribute("color", new U(p.colors, 3))), p.hasUVIndices === !0 && g.setAttribute("uv", new U(p.uvs, 2));
326
+ const b = [];
327
+ for (let S = 0, w = u.length; S < w; S++) {
328
+ const M = u[S], I = M.name + "_" + M.smooth + "_" + _;
329
+ let y = r.materials[I];
330
+ if (this.materials !== null) {
331
+ if (y = this.materials.create(M.name), m && y && !(y instanceof we)) {
332
+ const C = new we();
333
+ Ot.prototype.copy.call(C, y), C.color.copy(y.color), y = C;
334
+ } else if (f && y && !(y instanceof te)) {
335
+ const C = new te({ size: 10, sizeAttenuation: !1 });
336
+ Ot.prototype.copy.call(C, y), C.color.copy(y.color), C.map = y.map, y = C;
337
+ }
338
+ }
339
+ y === void 0 && (m ? y = new we() : f ? y = new te({ size: 1, sizeAttenuation: !1 }) : y = new Ar(), y.name = M.name, y.flatShading = !M.smooth, y.vertexColors = _, r.materials[I] = y), b.push(y);
340
+ }
341
+ let x;
342
+ if (b.length > 1) {
343
+ for (let S = 0, w = u.length; S < w; S++) {
344
+ const M = u[S];
345
+ g.addGroup(M.groupStart, M.groupCount, S);
346
+ }
347
+ m ? x = new Et(g, b) : f ? x = new Se(g, b) : x = new Pt(g, b);
348
+ } else
349
+ m ? x = new Et(g, b[0]) : f ? x = new Se(g, b[0]) : x = new Pt(g, b[0]);
350
+ x.name = d.name, n.add(x);
351
+ }
352
+ else if (r.vertices.length > 0) {
353
+ const l = new te({ size: 1, sizeAttenuation: !1 }), h = new Ct();
354
+ h.setAttribute("position", new U(r.vertices, 3)), r.colors.length > 0 && r.colors[0] !== void 0 && (h.setAttribute("color", new U(r.colors, 3)), l.vertexColors = !0);
355
+ const d = new Se(h, l);
356
+ n.add(d);
357
+ }
358
+ return n;
359
+ }
360
+ }
361
+ const be = 16776960, Me = 16755200, Wr = 2236962, Nr = 2236962, Ur = {
362
+ /**
363
+ * Плоскость (PlaneGeometry)
364
+ * @returns Плоскость размером 1x1 с одной сегментацией
365
+ */
366
+ [E.Plane]: () => new a.PlaneGeometry(1, 1, 1, 1),
367
+ /**
368
+ * Куб (BoxGeometry)
369
+ * @returns Куб размером 1x1x1 с одной сегментацией по каждой оси
370
+ */
371
+ [E.Cube]: () => new a.BoxGeometry(1, 1, 1, 1, 1, 1),
372
+ /**
373
+ * Сфера (SphereGeometry)
374
+ * @returns Сфера радиусом 0.5, 32 сегмента по ширине, 16 по высоте
375
+ */
376
+ [E.Sphere]: () => new a.SphereGeometry(0.5, 32, 16),
377
+ /**
378
+ * UV-сфера (SphereGeometry) с гладкой поверхностью
379
+ * @returns Сфера радиусом 0.5, 32 сегмента по ширине, 16 по высоте
380
+ */
381
+ [E.UVSphere]: () => new a.SphereGeometry(0.5, 32, 16),
382
+ /**
383
+ * Икосфера (IcosahedronGeometry) — сфера из треугольников
384
+ * @returns Икосфера радиусом 0.5, уровень детализации 0
385
+ */
386
+ [E.Icosphere]: () => new a.IcosahedronGeometry(0.5, 0),
387
+ /**
388
+ * Цилиндр (CylinderGeometry)
389
+ * @returns Цилиндр радиусом 0.5, высотой 1, 32 сегмента
390
+ */
391
+ [E.Cylinder]: () => new a.CylinderGeometry(0.5, 0.5, 1, 32, 1, !1),
392
+ /**
393
+ * Конус (ConeGeometry)
394
+ * @returns Конус радиусом 0.5, высотой 1, 32 сегмента
395
+ */
396
+ [E.Cone]: () => new a.ConeGeometry(0.5, 1, 32, 1, !1),
397
+ /**
398
+ * Пирамида с квадратным основанием.
399
+ * @returns Пирамида высотой 1 и радиусом основания 0.5
400
+ */
401
+ [E.Pyramid]: () => new a.ConeGeometry(0.5, 1, 4, 1, !1),
402
+ /**
403
+ * Тетраэдр (TetrahedronGeometry)
404
+ * @returns Тетраэдр радиусом 0.5
405
+ */
406
+ [E.Tetrahedron]: () => new a.TetrahedronGeometry(0.5, 0),
407
+ /**
408
+ * Октаэдр (OctahedronGeometry)
409
+ * @returns Октаэдр радиусом 0.5
410
+ */
411
+ [E.Octahedron]: () => new a.OctahedronGeometry(0.5, 0),
412
+ /**
413
+ * Додекаэдр (DodecahedronGeometry)
414
+ * @returns Додекаэдр радиусом 0.5
415
+ */
416
+ [E.Dodecahedron]: () => new a.DodecahedronGeometry(0.5, 0),
417
+ /**
418
+ * Тор (TorusGeometry)
419
+ * @returns Тор радиусом 0.5, толщиной 0.2, 16 сегментов по радиусу, 64 по трубке
420
+ */
421
+ [E.Torus]: () => new a.TorusGeometry(0.5, 0.2, 16, 64),
422
+ /**
423
+ * Тор-кнот (TorusKnotGeometry)
424
+ * @returns Тор-кнот радиусом 0.4 и толщиной 0.12
425
+ */
426
+ [E.TorusKnot]: () => new a.TorusKnotGeometry(0.4, 0.12, 96, 16),
427
+ /**
428
+ * Круг (CircleGeometry)
429
+ * @returns Круг радиусом 0.5, 32 сегмента
430
+ */
431
+ [E.Circle]: () => new a.CircleGeometry(0.5, 32),
432
+ /**
433
+ * Кольцо (RingGeometry)
434
+ * @returns Кольцо с внутренним радиусом 0.25 и внешним радиусом 0.5
435
+ */
436
+ [E.Ring]: () => new a.RingGeometry(0.25, 0.5, 32),
437
+ /**
438
+ * Капсула (CapsuleGeometry)
439
+ * @returns Капсула радиусом 0.3 и длиной 0.8
440
+ */
441
+ [E.Capsule]: () => new a.CapsuleGeometry(0.3, 0.8, 8, 16),
442
+ /**
443
+ * Кастомная геометрия (не реализовано в фабрике)
444
+ * @throws {Error} Всегда выбрасывает ошибку
445
+ */
446
+ [E.Custom]: function() {
447
+ throw new Error("Custom geometry is not generated here.");
448
+ }
449
+ }, Zt = new a.MeshStandardMaterial({
450
+ color: 12566463,
451
+ metalness: 0,
452
+ roughness: 0.6
453
+ }), Xr = 8, k = 0, Jt = 1, Qt = 2, $ = 31, Yr = 0.03, Kr = 0.05, Mt = 900, Vt = 300, Ht = 300, $t = 300, yt = (e) => !!e && e.isMesh, er = (e) => {
454
+ let t = e;
455
+ for (; t; ) {
456
+ if (t.isMesh) return t;
457
+ t = t.parent;
458
+ }
459
+ return null;
460
+ }, tr = (e) => {
461
+ const t = new a.BufferGeometry();
462
+ t.setAttribute("position", e.getAttribute("position")), t.computeBoundingSphere(), t.computeBoundingBox();
463
+ const r = new a.PointsMaterial({
464
+ color: Nr,
465
+ size: 6,
466
+ sizeAttenuation: !1,
467
+ depthTest: !1,
468
+ depthWrite: !1,
469
+ transparent: !0,
470
+ opacity: 0.9
471
+ }), s = new a.Points(t, r);
472
+ return s.layers.set(Qt), s.renderOrder = 1e3, s.visible = !1, s;
473
+ }, rr = (e) => {
474
+ const t = new a.EdgesGeometry(e), r = new a.LineSegments(
475
+ t,
476
+ new a.LineBasicMaterial({ color: Wr, linewidth: 1 })
477
+ );
478
+ return r.layers.set(Jt), r;
479
+ }, qr = (e) => {
480
+ const t = { x: e.position.x, y: e.position.y, z: e.position.z }, r = { x: e.rotation.x, y: e.rotation.y, z: e.rotation.z }, s = { x: e.scale.x, y: e.scale.y, z: e.scale.z }, i = new a.Box3().setFromObject(e), n = new a.Vector3();
481
+ i.getSize(n);
482
+ const o = { x: n.x, y: n.y, z: n.z };
483
+ return { position: t, rotation: r, scale: s, size: o };
484
+ }, Zr = (e, t) => t ? {
485
+ background: {
486
+ ...e.background,
487
+ ...t.background
488
+ },
489
+ camera: {
490
+ ...e.camera,
491
+ ...t.camera,
492
+ position: {
493
+ ...e.camera.position,
494
+ ...t.camera?.position
495
+ }
496
+ },
497
+ renderer: {
498
+ ...e.renderer,
499
+ ...t.renderer
500
+ },
501
+ lights: {
502
+ ambient: {
503
+ ...e.lights.ambient,
504
+ ...t.lights?.ambient
505
+ },
506
+ directional: {
507
+ ...e.lights.directional,
508
+ ...t.lights?.directional,
509
+ position: {
510
+ ...e.lights.directional.position,
511
+ ...t.lights?.directional?.position
512
+ }
513
+ }
514
+ }
515
+ } : e, Y = (e) => (e.userData.isProxy = !0, e.userData.isExportable = !1, e), N = (e) => (e.userData.isExportable = !1, e), sr = (e) => e.userData.isProxy === !0, Jr = (e) => {
516
+ let t = e;
517
+ for (; t; ) {
518
+ if (t.userData.isExportable === !1)
519
+ return !0;
520
+ t = t.parent;
521
+ }
522
+ return !1;
523
+ }, Qr = (e) => !yt(e) || !e.visible || sr(e) || Jr(e) ? !1 : e.userData.isExportable !== !1, es = (e) => {
524
+ const t = new a.Group();
525
+ return t.name = "Planara_OBJ_Export", e.updateMatrixWorld(!0), e.traverse((r) => {
526
+ if (!Qr(r))
527
+ return;
528
+ const s = r.clone(!1);
529
+ s.geometry = r.geometry.clone(), Array.isArray(r.material) ? s.material = r.material.map((i) => i.clone()) : s.material = r.material.clone(), s.matrix.copy(r.matrixWorld), s.matrixAutoUpdate = !1, t.add(s);
530
+ }), t;
531
+ }, ir = (e) => {
532
+ const r = new zr().parse(e);
533
+ r.updateMatrixWorld(!0);
534
+ const s = [];
535
+ return r.traverse((i) => {
536
+ if (!yt(i))
537
+ return;
538
+ const n = i.geometry.clone();
539
+ n.applyMatrix4(i.matrixWorld), n.computeBoundingBox();
540
+ const o = n.boundingBox;
541
+ if (!o)
542
+ return;
543
+ const l = new a.Vector3();
544
+ o.getCenter(l), n.translate(-l.x, -l.y, -l.z), n.computeBoundingBox(), n.computeBoundingSphere(), n.computeVertexNormals();
545
+ const h = n.getAttribute("position");
546
+ h && h.setUsage && h.setUsage(a.DynamicDrawUsage);
547
+ const d = new a.Mesh(n, Zt.clone());
548
+ d.position.copy(l), d.layers.enable(k);
549
+ const p = n.index ? n.toNonIndexed() : n, u = N(rr(p));
550
+ u.layers.enable(k), d.add(u);
551
+ const m = N(tr(p));
552
+ m.layers.enable(k), d.add(m), s.push(d);
553
+ }), s;
554
+ }, ts = {
555
+ background: {
556
+ color: 1710618,
557
+ transparent: !1
558
+ },
559
+ camera: {
560
+ fov: 45,
561
+ near: 0.1,
562
+ far: 1e3,
563
+ position: {
564
+ x: 1,
565
+ y: 1,
566
+ z: 7
567
+ }
568
+ },
569
+ renderer: {
570
+ antialias: !0,
571
+ alpha: !1
572
+ },
573
+ lights: {
574
+ ambient: {
575
+ enabled: !0,
576
+ color: 16777215,
577
+ intensity: 0.5
578
+ },
579
+ directional: {
580
+ enabled: !0,
581
+ color: 16777215,
582
+ intensity: 1,
583
+ position: {
584
+ x: 5,
585
+ y: 10,
586
+ z: 7
587
+ }
588
+ }
589
+ }
590
+ };
591
+ var rs = Object.getOwnPropertyDescriptor, ss = (e, t, r, s) => {
592
+ for (var i = s > 1 ? void 0 : s ? rs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
593
+ (o = e[n]) && (i = o(i) || i);
11
594
  return i;
12
- }, _t = (e, t) => (r, s) => t(r, s, e);
13
- let te = class {
595
+ }, Rt = (e, t) => (r, s) => t(r, s, e);
596
+ let Le = class {
597
+ /**
598
+ * Конструктор рендерера.
599
+ *
600
+ * @param _canvas - HTMLCanvasElement для рендеринга
601
+ * @param _config - Конфиг для настройки рендерера
602
+ *
603
+ * @remarks
604
+ * Инициализирует сцену, камеру, WebGLRenderer и базовое освещение
605
+ * на основе переданного `RendererConfig`.
606
+ *
607
+ * По умолчанию используется тёмный фон, перспективная камера
608
+ * и два источника света: AmbientLight и DirectionalLight.
609
+ *
610
+ * @public
611
+ * @constructor
612
+ */
613
+ constructor(e, t) {
614
+ if (this._config = t, this.canvas = e, this.scene = new a.Scene(), this._config.background.transparent ? this.scene.background = null : this.scene.background = new a.Color(this._config.background.color), this.camera = new a.PerspectiveCamera(
615
+ this._config.camera.fov,
616
+ this.canvas.clientWidth / this.canvas.clientHeight,
617
+ this._config.camera.near,
618
+ this._config.camera.far
619
+ ), this.camera.position.set(
620
+ this._config.camera.position.x,
621
+ this._config.camera.position.y,
622
+ this._config.camera.position.z
623
+ ), this.renderer = new a.WebGLRenderer({
624
+ canvas: this.canvas,
625
+ antialias: this._config.renderer.antialias,
626
+ alpha: this._config.background.transparent || this._config.renderer.alpha
627
+ }), this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight), this._config.background.transparent ? this.renderer.setClearAlpha(0) : this.renderer.setClearColor(this._config.background.color, 1), this._config.lights.ambient.enabled) {
628
+ const r = new a.AmbientLight(
629
+ this._config.lights.ambient.color,
630
+ this._config.lights.ambient.intensity
631
+ );
632
+ this.scene.add(N(r));
633
+ }
634
+ if (this._config.lights.directional.enabled) {
635
+ const r = new a.DirectionalLight(
636
+ this._config.lights.directional.color,
637
+ this._config.lights.directional.intensity
638
+ );
639
+ r.position.set(
640
+ this._config.lights.directional.position.x,
641
+ this._config.lights.directional.position.y,
642
+ this._config.lights.directional.position.z
643
+ ), this.scene.add(N(r));
644
+ }
645
+ }
14
646
  /**
15
647
  * Корневой объект сцены Three.js.
16
648
  *
@@ -39,37 +671,6 @@ let te = class {
39
671
  * @member
40
672
  */
41
673
  canvas;
42
- /**
43
- * Конструктор рендерера.
44
- *
45
- * @param _canvas - HTMLCanvasElement для рендеринга
46
- *
47
- * @remarks
48
- * Инициализирует сцену с тёмным фоном, перспективную камеру
49
- * (45° FOV, near 0.1, far 1000) и базовое освещение:
50
- * - `AmbientLight` (0xffffff, 0.5) — общий свет
51
- * - `DirectionalLight` (0xffffff, 1) — направленный свет
52
- *
53
- * @example
54
- * ```typescript
55
- * const renderer = new Renderer(canvas);
56
- * ```
57
- *
58
- * @public
59
- * @constructor
60
- */
61
- constructor(e) {
62
- this.canvas = e, this.scene = new a.Scene(), this.scene.background = new a.Color(1710618), this.camera = new a.PerspectiveCamera(
63
- 45,
64
- this.canvas.clientWidth / this.canvas.clientHeight,
65
- 0.1,
66
- 1e3
67
- ), this.camera.position.set(1, 1, 7), this.renderer = new a.WebGLRenderer({ canvas: this.canvas, antialias: !0 }), this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
68
- const t = new a.AmbientLight(16777215, 0.5);
69
- this.scene.add(t);
70
- const r = new a.DirectionalLight(16777215, 1);
71
- r.position.set(5, 10, 7), this.scene.add(r);
72
- }
73
674
  /**
74
675
  * Обновляет размер рендерера и пропорции камеры.
75
676
  *
@@ -77,11 +678,11 @@ let te = class {
77
678
  * Вызывается при изменении размеров canvas (например, при ресайзе окна браузера).
78
679
  *
79
680
  * @example
80
- * ```typescript
681
+ * ```ts
81
682
  * window.addEventListener('resize', () => renderer.resize());
82
683
  * ```
83
684
  *
84
- * @oublic
685
+ * @public
85
686
  * @method
86
687
  */
87
688
  resize() {
@@ -121,7 +722,7 @@ let te = class {
121
722
  * **Важно:** вызывать метод только один раз.
122
723
  *
123
724
  * @example
124
- * ```typescript
725
+ * ```ts
125
726
  * renderer.loop();
126
727
  * ```
127
728
  *
@@ -146,6 +747,15 @@ let te = class {
146
747
  getScene() {
147
748
  return this.scene;
148
749
  }
750
+ getRendererInfo() {
751
+ const e = this.renderer.info;
752
+ return {
753
+ drawCalls: e.render.calls,
754
+ triangles: e.render.triangles,
755
+ geometries: e.memory.geometries,
756
+ textures: e.memory.textures
757
+ };
758
+ }
149
759
  /**
150
760
  * Освобождает ресурсы рендерера.
151
761
  *
@@ -160,11 +770,12 @@ let te = class {
160
770
  this.scene = null, this.camera = null, this.renderer?.dispose(), this.canvas = null;
161
771
  }
162
772
  };
163
- te = ht([
164
- d(),
165
- _t(0, l("Canvas"))
166
- ], te);
167
- class Js {
773
+ Le = ss([
774
+ v(),
775
+ Rt(0, c("Canvas")),
776
+ Rt(1, c("RendererConfig"))
777
+ ], Le);
778
+ class Yn {
168
779
  /** Позиции вершин */
169
780
  _positions = [];
170
781
  /** Нормали вершин */
@@ -184,29 +795,29 @@ class Js {
184
795
  `);
185
796
  for (const i of r) {
186
797
  if (!i.trim() || i.startsWith("#")) continue;
187
- const o = i.trim().split(/\s+/);
188
- switch (o[0]) {
798
+ const n = i.trim().split(/\s+/);
799
+ switch (n[0]) {
189
800
  case "v":
190
- this._tmpPositions.push(o.slice(1).map(Number));
801
+ this._tmpPositions.push(n.slice(1).map(Number));
191
802
  break;
192
803
  case "vn":
193
- this._tmpNormals.push(o.slice(1).map(Number));
804
+ this._tmpNormals.push(n.slice(1).map(Number));
194
805
  break;
195
806
  case "vt":
196
- this._tmpUVs.push(o.slice(1).map(Number));
807
+ this._tmpUVs.push(n.slice(1).map(Number));
197
808
  break;
198
809
  case "f":
199
- this.processFaceLine(o);
810
+ this.processFaceLine(n);
200
811
  break;
201
812
  }
202
813
  }
203
814
  const s = {
204
- type: O.Custom,
815
+ type: E.Custom,
205
816
  position: this._positions,
206
817
  ...this._normals.length > 0 && { normal: this._normals },
207
818
  ...this._uvs.length > 0 && { uv: this._uvs }
208
819
  };
209
- return new tt(s);
820
+ return new Pr(s);
210
821
  }
211
822
  /**
212
823
  * Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
@@ -215,41 +826,42 @@ class Js {
215
826
  for (let r = 1; r < t.length; r++) {
216
827
  const s = t[r];
217
828
  if (!s) continue;
218
- const [i, o, n] = s.split("/"), c = i ? parseInt(i, 10) : void 0, _ = o ? parseInt(o, 10) : void 0, u = n ? parseInt(n, 10) : void 0;
219
- if (c !== void 0) {
220
- const p = this._tmpPositions[c - 1];
829
+ const [i, n, o] = s.split("/"), l = i ? parseInt(i, 10) : void 0, h = n ? parseInt(n, 10) : void 0, d = o ? parseInt(o, 10) : void 0;
830
+ if (l !== void 0) {
831
+ const p = this._tmpPositions[l - 1];
221
832
  p && this._positions.push(...p);
222
833
  }
223
- if (_ !== void 0) {
224
- const p = this._tmpUVs[_ - 1];
834
+ if (h !== void 0) {
835
+ const p = this._tmpUVs[h - 1];
225
836
  p && this._uvs.push(...p);
226
837
  }
227
- if (u !== void 0) {
228
- const p = this._tmpNormals[u - 1];
838
+ if (d !== void 0) {
839
+ const p = this._tmpNormals[d - 1];
229
840
  p && this._normals.push(...p);
230
841
  }
231
842
  }
232
843
  }
233
844
  }
234
- var dt = Object.getOwnPropertyDescriptor, ut = (e, t, r, s) => {
235
- for (var i = s > 1 ? void 0 : s ? dt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
236
- (n = e[o]) && (i = n(i) || i);
845
+ var is = Object.getOwnPropertyDescriptor, ns = (e, t, r, s) => {
846
+ for (var i = s > 1 ? void 0 : s ? is(t, r) : t, n = e.length - 1, o; n >= 0; n--)
847
+ (o = e[n]) && (i = o(i) || i);
237
848
  return i;
238
- }, B = (e, t) => (r, s) => t(r, s, e);
239
- let se = class {
849
+ }, K = (e, t) => (r, s) => t(r, s, e);
850
+ let Te = class {
240
851
  /**
241
852
  * Конструктор контроллера.
242
853
  *
243
854
  * @param _updatable - модули, требующие обновления каждый кадр
244
855
  * @param _renderable - модули, требующие кастомного рендеринга
856
+ * @param _observers - модули, наблюдающие за приложением
245
857
  * @param _runtime - модули, требующие инициализации
246
858
  * @param _renderer - рендерер (должен реализовывать `IRenderable`)
247
859
  *
248
860
  * @internal
249
861
  * @constructor
250
862
  */
251
- constructor(e, t, r, s) {
252
- this._updatable = e, this._renderable = t, this._runtime = r, this._renderer = s;
863
+ constructor(e, t, r, s, i) {
864
+ this._updatable = e, this._renderable = t, this._observers = r, this._runtime = s, this._renderer = i;
253
865
  }
254
866
  /**
255
867
  * ID анимационного цикла (для остановки)
@@ -270,12 +882,13 @@ let se = class {
270
882
  * 1. Обновляет модули (`update()`)
271
883
  * 2. Рендерит сцену
272
884
  * 3. Рендерит дополнительные модули (`render()`)
885
+ * 4. Наблюдает за общим состоянием приложения, собирает метрики
273
886
  *
274
887
  * @private
275
888
  * @method
276
889
  */
277
890
  _loop() {
278
- this._updatable.forEach((e) => e.update()), this._renderer.render(), this._renderable.forEach((e) => e.render()), this._animationId = requestAnimationFrame(() => this._loop());
891
+ this._updatable.forEach((e) => e.update()), this._renderer.render(), this._renderable.forEach((e) => e.render()), this._observers.forEach((e) => e.observe()), this._animationId = requestAnimationFrame(() => this._loop());
279
892
  }
280
893
  stop() {
281
894
  this._animationId && (cancelAnimationFrame(this._animationId), this._animationId = null);
@@ -290,19 +903,41 @@ let se = class {
290
903
  this._animationId = null;
291
904
  }
292
905
  };
293
- se = ut([
294
- d(),
295
- B(0, D("IUpdatableModule")),
296
- B(1, D("IRenderableModule")),
297
- B(2, D("IRuntimeModule")),
298
- B(3, l("IRenderable"))
299
- ], se);
300
- var pt = Object.getOwnPropertyDescriptor, mt = (e, t, r, s) => {
301
- for (var i = s > 1 ? void 0 : s ? pt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
302
- (n = e[o]) && (i = n(i) || i);
906
+ Te = ns([
907
+ v(),
908
+ K(0, H("IUpdatableModule", { isOptional: !0 })),
909
+ K(1, H("IRenderableModule", { isOptional: !0 })),
910
+ K(2, H("IObserverModule", { isOptional: !0 })),
911
+ K(3, H("IRuntimeModule", { isOptional: !0 })),
912
+ K(4, c("IRenderable"))
913
+ ], Te);
914
+ var os = Object.getOwnPropertyDescriptor, as = (e, t, r, s) => {
915
+ for (var i = s > 1 ? void 0 : s ? os(t, r) : t, n = e.length - 1, o; n >= 0; n--)
916
+ (o = e[n]) && (i = o(i) || i);
917
+ return i;
918
+ }, ls = (e, t) => (r, s) => t(r, s, e);
919
+ let De = class {
920
+ /** @constructor */
921
+ constructor(e) {
922
+ this._controlsModule = e;
923
+ }
924
+ isOrbitInteracting() {
925
+ return this._controlsModule.isOrbitInteracting();
926
+ }
927
+ isTransformDragging() {
928
+ return this._controlsModule.isTransformDragging();
929
+ }
930
+ };
931
+ De = as([
932
+ v(),
933
+ ls(0, c("ControlsModule"))
934
+ ], De);
935
+ var cs = Object.getOwnPropertyDescriptor, hs = (e, t, r, s) => {
936
+ for (var i = s > 1 ? void 0 : s ? cs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
937
+ (o = e[n]) && (i = o(i) || i);
303
938
  return i;
304
- }, gt = (e, t) => (r, s) => t(r, s, e);
305
- let re = class {
939
+ }, ds = (e, t) => (r, s) => t(r, s, e);
940
+ let je = class {
306
941
  /** @constructor */
307
942
  constructor(e) {
308
943
  this._sceneModule = e;
@@ -323,16 +958,16 @@ let re = class {
323
958
  return this._sceneModule.getMeshes();
324
959
  }
325
960
  };
326
- re = mt([
327
- d(),
328
- gt(0, l("SceneModule"))
329
- ], re);
330
- var vt = Object.getOwnPropertyDescriptor, ft = (e, t, r, s) => {
331
- for (var i = s > 1 ? void 0 : s ? vt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
332
- (n = e[o]) && (i = n(i) || i);
961
+ je = hs([
962
+ v(),
963
+ ds(0, c("SceneModule"))
964
+ ], je);
965
+ var _s = Object.getOwnPropertyDescriptor, us = (e, t, r, s) => {
966
+ for (var i = s > 1 ? void 0 : s ? _s(t, r) : t, n = e.length - 1, o; n >= 0; n--)
967
+ (o = e[n]) && (i = o(i) || i);
333
968
  return i;
334
- }, Mt = (e, t) => (r, s) => t(r, s, e);
335
- let ie = class {
969
+ }, ps = (e, t) => (r, s) => t(r, s, e);
970
+ let Ve = class {
336
971
  /** @constructor */
337
972
  constructor(e) {
338
973
  this._raycastModule = e;
@@ -341,16 +976,16 @@ let ie = class {
341
976
  this._raycastModule.setRaycastMode(e);
342
977
  }
343
978
  };
344
- ie = ft([
345
- d(),
346
- Mt(0, l("RaycastModule"))
347
- ], ie);
348
- var yt = Object.getOwnPropertyDescriptor, bt = (e, t, r, s) => {
349
- for (var i = s > 1 ? void 0 : s ? yt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
350
- (n = e[o]) && (i = n(i) || i);
979
+ Ve = us([
980
+ v(),
981
+ ps(0, c("RaycastModule"))
982
+ ], Ve);
983
+ var ms = Object.getOwnPropertyDescriptor, fs = (e, t, r, s) => {
984
+ for (var i = s > 1 ? void 0 : s ? ms(t, r) : t, n = e.length - 1, o; n >= 0; n--)
985
+ (o = e[n]) && (i = o(i) || i);
351
986
  return i;
352
- }, St = (e, t) => (r, s) => t(r, s, e);
353
- let oe = class {
987
+ }, gs = (e, t) => (r, s) => t(r, s, e);
988
+ let He = class {
354
989
  /** @constructor */
355
990
  constructor(e) {
356
991
  this._controlsModule = e;
@@ -368,16 +1003,36 @@ let oe = class {
368
1003
  return this._controlsModule.onTransformChange(e);
369
1004
  }
370
1005
  };
371
- oe = bt([
372
- d(),
373
- St(0, l("ControlsModule"))
374
- ], oe);
375
- var At = Object.getOwnPropertyDescriptor, wt = (e, t, r, s) => {
376
- for (var i = s > 1 ? void 0 : s ? At(t, r) : t, o = e.length - 1, n; o >= 0; o--)
377
- (n = e[o]) && (i = n(i) || i);
1006
+ He = fs([
1007
+ v(),
1008
+ gs(0, c("ControlsModule"))
1009
+ ], He);
1010
+ var vs = Object.getOwnPropertyDescriptor, bs = (e, t, r, s) => {
1011
+ for (var i = s > 1 ? void 0 : s ? vs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1012
+ (o = e[n]) && (i = o(i) || i);
1013
+ return i;
1014
+ }, Ms = (e, t) => (r, s) => t(r, s, e);
1015
+ let $e = class {
1016
+ constructor(e) {
1017
+ this._interactive = e;
1018
+ }
1019
+ isInteractionEnabled() {
1020
+ return this._interactive.every((e) => e.isInteractionEnabled());
1021
+ }
1022
+ setInteractionEnabled(e) {
1023
+ this._interactive.forEach((t) => t.setInteractionEnabled(e));
1024
+ }
1025
+ };
1026
+ $e = bs([
1027
+ v(),
1028
+ Ms(0, H("IInteractiveModule"))
1029
+ ], $e);
1030
+ var ys = Object.getOwnPropertyDescriptor, ws = (e, t, r, s) => {
1031
+ for (var i = s > 1 ? void 0 : s ? ys(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1032
+ (o = e[n]) && (i = o(i) || i);
378
1033
  return i;
379
- }, xt = (e, t) => (r, s) => t(r, s, e);
380
- let ne = class {
1034
+ }, Ss = (e, t) => (r, s) => t(r, s, e);
1035
+ let Re = class {
381
1036
  constructor(e) {
382
1037
  this._cameraAccessApi = e;
383
1038
  }
@@ -391,16 +1046,16 @@ let ne = class {
391
1046
  this._cameraAccessApi.getCamera().layers.disable(e);
392
1047
  }
393
1048
  };
394
- ne = wt([
395
- d(),
396
- xt(0, l("IRendererCameraAccess"))
397
- ], ne);
398
- var Ot = Object.getOwnPropertyDescriptor, Ct = (e, t, r, s) => {
399
- for (var i = s > 1 ? void 0 : s ? Ot(t, r) : t, o = e.length - 1, n; o >= 0; o--)
400
- (n = e[o]) && (i = n(i) || i);
1049
+ Re = ws([
1050
+ v(),
1051
+ Ss(0, c("IRendererCameraAccess"))
1052
+ ], Re);
1053
+ var xs = Object.getOwnPropertyDescriptor, As = (e, t, r, s) => {
1054
+ for (var i = s > 1 ? void 0 : s ? xs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1055
+ (o = e[n]) && (i = o(i) || i);
401
1056
  return i;
402
- }, It = (e, t) => (r, s) => t(r, s, e);
403
- let ae = class {
1057
+ }, Is = (e, t) => (r, s) => t(r, s, e);
1058
+ let Be = class {
404
1059
  constructor(e) {
405
1060
  this._domAccessApi = e;
406
1061
  }
@@ -411,16 +1066,16 @@ let ae = class {
411
1066
  return this._domAccessApi.getDomElement();
412
1067
  }
413
1068
  };
414
- ae = Ct([
415
- d(),
416
- It(0, l("IRendererDomAccess"))
417
- ], ae);
418
- var Pt = Object.getOwnPropertyDescriptor, Lt = (e, t, r, s) => {
419
- for (var i = s > 1 ? void 0 : s ? Pt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
420
- (n = e[o]) && (i = n(i) || i);
1069
+ Be = As([
1070
+ v(),
1071
+ Is(0, c("IRendererDomAccess"))
1072
+ ], Be);
1073
+ var Cs = Object.getOwnPropertyDescriptor, Os = (e, t, r, s) => {
1074
+ for (var i = s > 1 ? void 0 : s ? Cs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1075
+ (o = e[n]) && (i = o(i) || i);
421
1076
  return i;
422
- }, Et = (e, t) => (r, s) => t(r, s, e);
423
- let ce = class {
1077
+ }, Es = (e, t) => (r, s) => t(r, s, e);
1078
+ let Fe = class {
424
1079
  constructor(e) {
425
1080
  this._sceneAccessApi = e;
426
1081
  }
@@ -430,61 +1085,121 @@ let ce = class {
430
1085
  addToScene(e) {
431
1086
  this._sceneAccessApi.getScene().add(e);
432
1087
  }
433
- removeFromScene(e) {
434
- this._sceneAccessApi.getScene().remove(e);
1088
+ removeFromScene(e, t) {
1089
+ this._sceneAccessApi.getScene().remove(e), t && this._disposeObject(e);
435
1090
  }
436
1091
  addObject(e, t) {
437
1092
  const r = this._sceneAccessApi.getScene();
438
1093
  r && (typeof t == "number" && e.layers.set(t), r.add(e));
439
1094
  }
1095
+ /**
1096
+ * Освобождает ресурсы объекта и его дочерних элементов.
1097
+ *
1098
+ * @param object - объект для очистки
1099
+ *
1100
+ * @private
1101
+ * @method
1102
+ */
1103
+ _disposeObject(e) {
1104
+ e.traverse((t) => {
1105
+ if (t instanceof a.Mesh) {
1106
+ if (t.geometry.dispose(), Array.isArray(t.material)) {
1107
+ t.material.forEach((r) => this._disposeMaterial(r));
1108
+ return;
1109
+ }
1110
+ this._disposeMaterial(t.material);
1111
+ }
1112
+ });
1113
+ }
1114
+ /**
1115
+ * Освобождает ресурсы материала.
1116
+ *
1117
+ * @param material - материал для очистки
1118
+ *
1119
+ * @private
1120
+ * @method
1121
+ */
1122
+ _disposeMaterial(e) {
1123
+ Object.values(e).forEach((t) => {
1124
+ t instanceof a.Texture && t.dispose();
1125
+ }), e.dispose();
1126
+ }
440
1127
  };
441
- ce = Lt([
442
- d(),
443
- Et(0, l("IRendererSceneAccess"))
444
- ], ce);
445
- var Tt = Object.getOwnPropertyDescriptor, Dt = (e, t, r, s) => {
446
- for (var i = s > 1 ? void 0 : s ? Tt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
447
- (n = e[o]) && (i = n(i) || i);
1128
+ Fe = Os([
1129
+ v(),
1130
+ Es(0, c("IRendererSceneAccess"))
1131
+ ], Fe);
1132
+ var Ps = Object.getOwnPropertyDescriptor, Ls = (e, t, r, s) => {
1133
+ for (var i = s > 1 ? void 0 : s ? Ps(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1134
+ (o = e[n]) && (i = o(i) || i);
448
1135
  return i;
449
- }, Vt = (e, t) => (r, s) => t(r, s, e);
450
- let le = class {
451
- /** @constructor */
1136
+ }, Ts = (e, t) => (r, s) => t(r, s, e);
1137
+ let ke = class {
1138
+ /**
1139
+ * Конструктор API статистики рендерера.
1140
+ *
1141
+ * @param _rendererInfoAccess - внутренний доступ к информации о рендерере
1142
+ */
452
1143
  constructor(e) {
453
- this._controlsModule = e;
454
- }
455
- isOrbitInteracting() {
456
- return this._controlsModule.isOrbitInteracting();
1144
+ this._rendererInfoAccess = e;
457
1145
  }
458
- isTransformDragging() {
459
- return this._controlsModule.isTransformDragging();
1146
+ /**
1147
+ * Возвращает текущую статистику рендерера.
1148
+ *
1149
+ * @returns Метрики WebGL-рендера за текущий кадр
1150
+ */
1151
+ getRendererInfo() {
1152
+ return this._rendererInfoAccess.getRendererInfo();
460
1153
  }
461
1154
  };
462
- le = Dt([
463
- d(),
464
- Vt(0, l("ControlsModule"))
465
- ], le);
466
- var $t = Object.getOwnPropertyDescriptor, jt = (e, t, r, s) => {
467
- for (var i = s > 1 ? void 0 : s ? $t(t, r) : t, o = e.length - 1, n; o >= 0; o--)
468
- (n = e[o]) && (i = n(i) || i);
1155
+ ke = Ls([
1156
+ v(),
1157
+ Ts(0, c("IRendererInfoAccess"))
1158
+ ], ke);
1159
+ var Ds = Object.getOwnPropertyDescriptor, js = (e, t, r, s) => {
1160
+ for (var i = s > 1 ? void 0 : s ? Ds(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1161
+ (o = e[n]) && (i = o(i) || i);
469
1162
  return i;
470
- }, K = (e, t) => (r, s) => t(r, s, e);
471
- let he = class {
1163
+ }, Ae = (e, t) => (r, s) => t(r, s, e);
1164
+ let me = class {
472
1165
  constructor(e, t, r) {
473
1166
  this._cameraApi = e, this._domApi = t, this._sceneApi = r;
474
1167
  }
475
- /** Orbit-контроллер для управления камерой */
1168
+ /**
1169
+ * Orbit-контроллер для управления камерой
1170
+ *
1171
+ * @private
1172
+ * @member
1173
+ */
476
1174
  _orbit = null;
477
- /** Transform-контроллер для редактирования */
1175
+ /**
1176
+ * Transform-контроллер для редактирования
1177
+ *
1178
+ * @private
1179
+ * @member
1180
+ */
478
1181
  _transform = null;
479
1182
  _transformHelper = null;
480
1183
  _transformListeners = /* @__PURE__ */ new Set();
481
- /** Были ли инициализированы обработчики событий (hover/click) */
1184
+ /**
1185
+ * Были ли инициализированы обработчики событий (hover/click)
1186
+ *
1187
+ * @private
1188
+ * @member
1189
+ */
482
1190
  _isEventListenersAdded = !1;
1191
+ /**
1192
+ * Доступно ли пользовательское взаимодействие с контроллерами
1193
+ *
1194
+ * @private
1195
+ * @member
1196
+ */
1197
+ _isInteractionEnabled = !0;
483
1198
  init() {
484
- this._orbit = new rt(this._cameraApi.getCamera(), this._domApi.getDomElement()), this._orbit.enableDamping = !0, this._orbit.dampingFactor = 0.05, this._transform = new it(
1199
+ this._orbit = new Tr(this._cameraApi.getCamera(), this._domApi.getDomElement()), this._orbit.enableDamping = !0, this._orbit.dampingFactor = 0.05, this._transform = new Dr(
485
1200
  this._cameraApi.getCamera(),
486
1201
  this._domApi.getDomElement()
487
- ), this._transformHelper = this._transform.getHelper(), this._sceneApi.addToScene(this._transformHelper), this._initMouseListeners();
1202
+ ), this._transformHelper = this._transform.getHelper(), this._sceneApi.addToScene(N(this._transformHelper)), this._initMouseListeners();
488
1203
  }
489
1204
  attachTransform(e) {
490
1205
  this._transform?.attach(e);
@@ -507,47 +1222,83 @@ let he = class {
507
1222
  isTransformDragging() {
508
1223
  return !!this._transform?.dragging;
509
1224
  }
510
- /** Освобождает ресурсы модуля */
511
- dispose() {
512
- if (this._isEventListenersAdded) {
513
- const e = this._domApi.getCanvas();
514
- if (!this._transform || !this._orbit) return;
515
- e.removeEventListener("pointerdown", (t) => this._transform?.pointerDown(t)), e.removeEventListener("pointermove", (t) => this._transform?.pointerMove(t)), e.removeEventListener("pointerup", (t) => this._transform?.pointerUp(t)), e.removeEventListener("pointerleave", () => this._transform?.pointerHover(null)), this._transform.removeEventListener("dragging-changed", () => {
516
- this._orbit.enabled = !this._transform?.dragging;
517
- }), this._transformListeners.clear(), this._isEventListenersAdded = !1;
518
- }
519
- this._orbit?.dispose(), this._orbit = null, this._transform?.dispose(), this._transform = null, this._transformHelper?.parent && this._transformHelper.parent.remove(this._transformHelper);
1225
+ setInteractionEnabled(e) {
1226
+ this._isInteractionEnabled = e, this._orbit && (this._orbit.enabled = e), this._transform && (this._transform.enabled = e), e || this._transform?.detach();
520
1227
  }
521
- /** Инициализация обработчиков событий на hover/click */
1228
+ isInteractionEnabled() {
1229
+ return this._isInteractionEnabled;
1230
+ }
1231
+ _handlePointerDown = (e) => {
1232
+ this._isInteractionEnabled && this._transform?.pointerDown(e);
1233
+ };
1234
+ _handlePointerMove = (e) => {
1235
+ this._isInteractionEnabled && this._transform?.pointerMove(e);
1236
+ };
1237
+ _handlePointerUp = (e) => {
1238
+ this._isInteractionEnabled && this._transform?.pointerUp(e);
1239
+ };
1240
+ _handlePointerLeave = () => {
1241
+ this._isInteractionEnabled && this._transform?.pointerHover(null);
1242
+ };
1243
+ _handleDraggingChanged = () => {
1244
+ this._orbit && (this._orbit.enabled = this._isInteractionEnabled && !this._transform?.dragging);
1245
+ };
1246
+ _handleObjectChange = () => {
1247
+ for (const e of this._transformListeners)
1248
+ e();
1249
+ };
1250
+ /** Инициализация обработчиков событий на hover/click */
522
1251
  _initMouseListeners() {
523
1252
  const e = this._domApi.getCanvas();
524
- !this._transform || !this._orbit || (e.addEventListener("pointerdown", (t) => this._transform?.pointerDown(t)), e.addEventListener("pointermove", (t) => this._transform?.pointerMove(t)), e.addEventListener("pointerup", (t) => this._transform?.pointerUp(t)), e.addEventListener("pointerleave", () => this._transform?.pointerHover(null)), this._transform.addEventListener("dragging-changed", () => {
525
- this._orbit.enabled = !this._transform?.dragging;
526
- }), this._transform.addEventListener("objectChange", () => {
527
- for (const t of this._transformListeners) t();
528
- }), this._isEventListenersAdded = !0);
1253
+ !this._transform || !this._orbit || (e.addEventListener("pointerdown", this._handlePointerDown), e.addEventListener("pointermove", this._handlePointerMove), e.addEventListener("pointerup", this._handlePointerUp), e.addEventListener("pointerleave", this._handlePointerLeave), this._transform.addEventListener("dragging-changed", this._handleDraggingChanged), this._transform.addEventListener("objectChange", this._handleObjectChange), this._isEventListenersAdded = !0);
1254
+ }
1255
+ /** Освобождает ресурсы модуля */
1256
+ dispose() {
1257
+ if (this._isEventListenersAdded) {
1258
+ const e = this._domApi.getCanvas();
1259
+ this._transform && (this._transform.removeEventListener("dragging-changed", this._handleDraggingChanged), this._transform.removeEventListener("objectChange", this._handleObjectChange)), e.removeEventListener("pointerdown", this._handlePointerDown), e.removeEventListener("pointermove", this._handlePointerMove), e.removeEventListener("pointerup", this._handlePointerUp), e.removeEventListener("pointerleave", this._handlePointerLeave), this._transformListeners.clear(), this._isEventListenersAdded = !1, this._isInteractionEnabled = !0;
1260
+ }
1261
+ this._orbit?.dispose(), this._orbit = null, this._transform?.dispose(), this._transform = null, this._transformHelper?.parent && this._transformHelper.parent.remove(this._transformHelper);
529
1262
  }
530
1263
  };
531
- he = jt([
532
- d(),
533
- K(0, l("ICameraApi")),
534
- K(1, l("IDomApi")),
535
- K(2, l("ISceneApi"))
536
- ], he);
537
- var Ht = Object.getOwnPropertyDescriptor, Rt = (e, t, r, s) => {
538
- for (var i = s > 1 ? void 0 : s ? Ht(t, r) : t, o = e.length - 1, n; o >= 0; o--)
539
- (n = e[o]) && (i = n(i) || i);
1264
+ me = js([
1265
+ v(),
1266
+ Ae(0, c("ICameraApi")),
1267
+ Ae(1, c("IDomApi")),
1268
+ Ae(2, c("ISceneApi"))
1269
+ ], me);
1270
+ var Vs = Object.getOwnPropertyDescriptor, Hs = (e, t, r, s) => {
1271
+ for (var i = s > 1 ? void 0 : s ? Vs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1272
+ (o = e[n]) && (i = o(i) || i);
540
1273
  return i;
541
- }, Q = (e, t) => (r, s) => t(r, s, e);
542
- let _e = class {
1274
+ }, Ie = (e, t) => (r, s) => t(r, s, e);
1275
+ let Ge = class {
543
1276
  constructor(e, t, r) {
544
1277
  this._cameraApi = e, this._domApi = t, this._rendererApi = r;
545
1278
  }
546
- /** Gizmo для управления отображением perspective camera */
1279
+ /**
1280
+ * Gizmo для управления отображением perspective camera
1281
+ *
1282
+ * @private
1283
+ * @member
1284
+ */
547
1285
  _cameraGizmo = null;
1286
+ /**
1287
+ * Доступно ли пользовательское взаимодействие с контроллерами
1288
+ *
1289
+ * @private
1290
+ * @member
1291
+ */
1292
+ _isInteractionEnabled = !0;
1293
+ setInteractionEnabled(e) {
1294
+ this._isInteractionEnabled = e, this._cameraGizmo?.setVisible(e);
1295
+ }
1296
+ isInteractionEnabled() {
1297
+ return this._isInteractionEnabled;
1298
+ }
548
1299
  init() {
549
1300
  const e = this._cameraApi.getCamera(), t = this._rendererApi.getRenderer();
550
- this._cameraGizmo = new ot(t, e, {
1301
+ this._cameraGizmo = new jr(t, e, {
551
1302
  size: 96,
552
1303
  // Размер квадрата
553
1304
  margin: 36
@@ -555,6 +1306,7 @@ let _e = class {
555
1306
  });
556
1307
  }
557
1308
  render() {
1309
+ if (!this._isInteractionEnabled) return;
558
1310
  const e = this._domApi.getCanvas();
559
1311
  this._cameraGizmo?.render(e.width, e.height);
560
1312
  }
@@ -563,20 +1315,125 @@ let _e = class {
563
1315
  this._cameraGizmo?.dispose(), this._cameraGizmo = null;
564
1316
  }
565
1317
  };
566
- _e = Rt([
567
- d(),
568
- Q(0, l("ICameraApi")),
569
- Q(1, l("IDomApi")),
570
- Q(2, l("IRendererAccess"))
571
- ], _e);
572
- var V = /* @__PURE__ */ ((e) => (e.SelectHover = "select.hover", e.SelectClick = "select.click", e))(V || {});
573
- const Ft = 0.03, Wt = 0.05, k = 0, Ue = 1, Xe = 2, x = 31;
574
- var kt = Object.getOwnPropertyDescriptor, Gt = (e, t, r, s) => {
575
- for (var i = s > 1 ? void 0 : s ? kt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
576
- (n = e[o]) && (i = n(i) || i);
1318
+ Ge = Hs([
1319
+ v(),
1320
+ Ie(0, c("ICameraApi")),
1321
+ Ie(1, c("IDomApi")),
1322
+ Ie(2, c("IRendererAccess"))
1323
+ ], Ge);
1324
+ var $s = Object.getOwnPropertyDescriptor, Rs = (e, t, r, s) => {
1325
+ for (var i = s > 1 ? void 0 : s ? $s(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1326
+ (o = e[n]) && (i = o(i) || i);
1327
+ return i;
1328
+ };
1329
+ let ze = class {
1330
+ /**
1331
+ * Внутренний эмиттер событий Node.js.
1332
+ *
1333
+ * @private
1334
+ * @member
1335
+ */
1336
+ _emitter;
1337
+ /** @constructor */
1338
+ constructor() {
1339
+ this._emitter = new Hr();
1340
+ }
1341
+ /**
1342
+ * Публикует событие в шину.
1343
+ *
1344
+ * @param event - название события (из `EventTopics`)
1345
+ * @param payload - данные события (тип зависит от события)
1346
+ *
1347
+ * @typeParam K - ключ события из `EditorEvents`
1348
+ *
1349
+ * @remarks
1350
+ * Все подписчики, зарегистрированные на это событие, получат payload.
1351
+ *
1352
+ * @example
1353
+ * ```typescript
1354
+ * // Публикация события клика
1355
+ * eventBus.emit(EventTopics.SelectClick, { intersection: hit });
1356
+ *
1357
+ * // Публикация события сброса выделения
1358
+ * eventBus.emit(EventTopics.SelectClick, null);
1359
+ * ```
1360
+ *
1361
+ * @public
1362
+ * @method
1363
+ */
1364
+ emit(e, t) {
1365
+ this._emitter.emit(e, t);
1366
+ }
1367
+ /**
1368
+ * Подписывается на событие.
1369
+ *
1370
+ * @param event - название события (из `EventTopics`)
1371
+ * @param listener - функция-обработчик, получающая payload
1372
+ *
1373
+ * @typeParam K - ключ события из `EditorEvents`
1374
+ *
1375
+ * @remarks
1376
+ * **Важно:** для предотвращения утечек памяти необходимо отписываться от событий
1377
+ * в `dispose()` методах компонентов.
1378
+ *
1379
+ * @example
1380
+ * ```typescript
1381
+ * // Подписка на событие hover
1382
+ * this._eventBus.on(EventTopics.SelectHover, (payload) => {
1383
+ * if (payload) {
1384
+ * this._handleHover(payload.intersection);
1385
+ * } else {
1386
+ * this._clearHover();
1387
+ * }
1388
+ * });
1389
+ * ```
1390
+ *
1391
+ * @public
1392
+ * @method
1393
+ */
1394
+ on(e, t) {
1395
+ this._emitter.on(e, t);
1396
+ }
1397
+ /**
1398
+ * Отписывается от события.
1399
+ *
1400
+ * @param event - название события (из `EventTopics`)
1401
+ * @param listener - функция-обработчик, которую нужно отписать
1402
+ *
1403
+ * @typeParam K - ключ события из `EditorEvents`
1404
+ *
1405
+ * @remarks
1406
+ * Для корректной отписки необходимо передать ту же самую функцию,
1407
+ * которая использовалась при подписке.
1408
+ *
1409
+ * @example
1410
+ * ```typescript
1411
+ * // Сохранение ссылки на обработчик
1412
+ * private _handleClick = (payload) => { ... };
1413
+ *
1414
+ * // Подписка
1415
+ * eventBus.on(EventTopics.SelectClick, this._handleClick);
1416
+ *
1417
+ * // Отписка (в dispose)
1418
+ * eventBus.off(EventTopics.SelectClick, this._handleClick);
1419
+ * ```
1420
+ *
1421
+ * @public
1422
+ * @method
1423
+ */
1424
+ off(e, t) {
1425
+ this._emitter.off(e, t);
1426
+ }
1427
+ };
1428
+ ze = Rs([
1429
+ v()
1430
+ ], ze);
1431
+ var B = /* @__PURE__ */ ((e) => (e.SelectHover = "select.hover", e.SelectClick = "select.click", e))(B || {}), Bs = Object.getOwnPropertyDescriptor, Fs = (e, t, r, s) => {
1432
+ for (var i = s > 1 ? void 0 : s ? Bs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1433
+ (o = e[n]) && (i = o(i) || i);
577
1434
  return i;
578
- }, R = (e, t) => (r, s) => t(r, s, e);
579
- let de = class {
1435
+ }, q = (e, t) => (r, s) => t(r, s, e);
1436
+ let We = class {
580
1437
  constructor(e, t, r, s, i) {
581
1438
  this._domApi = e, this._cameraApi = t, this._meshApi = r, this._controlsState = s, this._bus = i;
582
1439
  }
@@ -603,12 +1460,12 @@ let de = class {
603
1460
  */
604
1461
  _lastHoverKey = null;
605
1462
  /**
606
- * Текуший режим для raycaster
1463
+ * Текущий режим для raycaster
607
1464
  *
608
1465
  * @private
609
1466
  * @member
610
1467
  */
611
- _currentRaycastMode = M.Mesh;
1468
+ _currentRaycastMode = O.Mesh;
612
1469
  /**
613
1470
  * Были ли инициализированы обработчики событий (hover/click)
614
1471
  *
@@ -616,6 +1473,13 @@ let de = class {
616
1473
  * @member
617
1474
  */
618
1475
  _isEventListenersAdded = !1;
1476
+ /**
1477
+ * Доступно ли пользовательское взаимодействие через raycast.
1478
+ *
1479
+ * @private
1480
+ * @member
1481
+ */
1482
+ _isInteractionEnabled = !0;
619
1483
  init() {
620
1484
  this._raycaster = new a.Raycaster(), this._mouse = new a.Vector2(), this._applyRaycastParamsByMode(), this._isEventListenersAdded || (this._initMouseListeners(), this._isEventListenersAdded = !0);
621
1485
  }
@@ -624,19 +1488,36 @@ let de = class {
624
1488
  const t = this._raycaster;
625
1489
  t.params.Line.threshold = 0, t.params.Points.threshold = 0, this._currentRaycastMode = e, this._lastHoverKey = null, this._applyRaycastParamsByMode();
626
1490
  }
1491
+ setInteractionEnabled(e) {
1492
+ this._isInteractionEnabled = e, e || this._clearState();
1493
+ }
1494
+ isInteractionEnabled() {
1495
+ return this._isInteractionEnabled;
1496
+ }
1497
+ /**
1498
+ * Сбрасывает текущее состояние
1499
+ *
1500
+ * @private
1501
+ * @method
1502
+ */
1503
+ _clearState() {
1504
+ this._meshApi.getMeshes().forEach((t) => {
1505
+ t.userData.isHit = !1;
1506
+ }), this._lastHoverKey = null, this._bus.emit(B.SelectHover, null), this._bus.emit(B.SelectClick, null);
1507
+ }
627
1508
  /** Применяет параметры raycaster в зависимости от текущего режима */
628
1509
  _applyRaycastParamsByMode() {
629
1510
  const e = this._raycaster;
630
1511
  switch (e.params.Line.threshold = 0, e.params.Points.threshold = 0, this._currentRaycastMode) {
631
- case M.Mesh:
632
- case M.Face:
1512
+ case O.Mesh:
1513
+ case O.Face:
633
1514
  e.layers.set(k);
634
1515
  break;
635
- case M.Edge:
636
- e.layers.set(Ue), e.params.Line.threshold = Ft;
1516
+ case O.Edge:
1517
+ e.layers.set(Jt), e.params.Line.threshold = Yr;
637
1518
  break;
638
- case M.Vertex:
639
- e.layers.set(Xe), e.params.Points.threshold = Wt;
1519
+ case O.Vertex:
1520
+ e.layers.set(Qt), e.params.Points.threshold = Kr;
640
1521
  break;
641
1522
  }
642
1523
  }
@@ -644,15 +1525,15 @@ let de = class {
644
1525
  _getHitIntersection(e) {
645
1526
  const t = this._controlsState.isOrbitInteracting() || this._controlsState.isTransformDragging(), r = this._domApi.getCanvas(), s = this._cameraApi.getCamera(), i = this._meshApi.getMeshes();
646
1527
  if (t) return;
647
- const o = r.getBoundingClientRect();
648
- this._mouse.x = (e.clientX - o.left) / o.width * 2 - 1, this._mouse.y = -((e.clientY - o.top) / o.height) * 2 + 1, this._raycaster.setFromCamera(this._mouse, s);
649
- const n = this._raycaster.intersectObjects(i, !0)[0] ?? null;
650
- if (this._currentRaycastMode === M.Mesh || this._currentRaycastMode === M.Face)
651
- return n;
652
- const c = this._raycaster.layers.mask;
1528
+ const n = r.getBoundingClientRect();
1529
+ this._mouse.x = (e.clientX - n.left) / n.width * 2 - 1, this._mouse.y = -((e.clientY - n.top) / n.height) * 2 + 1, this._raycaster.setFromCamera(this._mouse, s);
1530
+ const o = this._raycaster.intersectObjects(i, !0)[0] ?? null;
1531
+ if (this._currentRaycastMode === O.Mesh || this._currentRaycastMode === O.Face)
1532
+ return o;
1533
+ const l = this._raycaster.layers.mask;
653
1534
  this._raycaster.layers.set(k);
654
- const _ = this._raycaster.intersectObjects(i, !0)[0] ?? null;
655
- return this._raycaster.layers.mask = c, this._getVisibleHit(n, _);
1535
+ const h = this._raycaster.intersectObjects(i, !0)[0] ?? null;
1536
+ return this._raycaster.layers.mask = l, this._getVisibleHit(o, h);
656
1537
  }
657
1538
  // Hover сравнивается не только по object, но и по режимному ключу попадания.
658
1539
  // Это нужно для Face/Edge/Vertex режимов, где разные элементы могут принадлежать одному и тому же Object3D.
@@ -660,19 +1541,20 @@ let de = class {
660
1541
  _processRaycastEvent(e, t, r) {
661
1542
  const s = this._getHitIntersection(e), i = this._meshApi.getMeshes();
662
1543
  if (s === void 0) return;
663
- const o = s?.object ?? null;
1544
+ const n = s?.object ?? null;
664
1545
  if (r) {
665
1546
  if (!s) {
666
- i.forEach((c) => c.userData.isHit = !1), this._lastHoverKey = null, this._bus.emit(t, null);
1547
+ i.forEach((l) => l.userData.isHit = !1), this._lastHoverKey = null, this._bus.emit(t, null);
667
1548
  return;
668
1549
  }
669
- const n = this._makeHoverKey(s);
670
- n !== this._lastHoverKey && (i.forEach((c) => c.userData.isHit = !1), o && (o.userData.isHit = !0), this._lastHoverKey = n, this._bus.emit(t, { intersection: s }));
1550
+ const o = this._makeHoverKey(s);
1551
+ o !== this._lastHoverKey && (i.forEach((l) => l.userData.isHit = !1), n && (n.userData.isHit = !0), this._lastHoverKey = o, this._bus.emit(t, { intersection: s }));
671
1552
  return;
672
1553
  }
673
1554
  s && this._bus.emit(t, { intersection: s });
674
1555
  }
675
- /** Поиск видимой части меша
1556
+ /**
1557
+ * Поиск видимой части меша
676
1558
  * необходимо это для того, чтобы отправлять только видимые элементы модели, а не все попадания
677
1559
  */
678
1560
  _getVisibleHit(e, t, r = 1e-4) {
@@ -683,33 +1565,34 @@ let de = class {
683
1565
  if (!e) return null;
684
1566
  const t = e.object.uuid;
685
1567
  switch (this._currentRaycastMode) {
686
- case M.Face:
1568
+ case O.Face:
687
1569
  return `${t}:face:${e.faceIndex ?? -1}`;
688
- case M.Edge:
1570
+ case O.Edge:
689
1571
  return `${t}:edge:${Math.floor((e.index ?? -1) / 2)}`;
690
- case M.Vertex:
1572
+ case O.Vertex:
691
1573
  return `${t}:vertex:${e.index ?? -1}`;
692
- case M.Mesh:
1574
+ case O.Mesh:
693
1575
  default:
694
1576
  return `${t}:mesh`;
695
1577
  }
696
1578
  }
697
1579
  /** Обработчик события для hover */
698
1580
  _handleMouseMove = (e) => {
699
- this._processRaycastEvent(e, V.SelectHover, !0);
1581
+ this._isInteractionEnabled && this._processRaycastEvent(e, B.SelectHover, !0);
700
1582
  };
701
1583
  /** Обработчик события на click */
702
1584
  _handleMouseClick = (e) => {
703
- this._processRaycastEvent(e, V.SelectClick, !1);
1585
+ this._isInteractionEnabled && this._processRaycastEvent(e, B.SelectClick, !1);
704
1586
  };
705
1587
  /** Обработчик двойного клика */
706
1588
  _handleDoubleClick = (e) => {
1589
+ if (!this._isInteractionEnabled) return;
707
1590
  const t = this._getHitIntersection(e);
708
- t !== void 0 && (t || this._bus.emit(V.SelectClick, null));
1591
+ t !== void 0 && (t || this._bus.emit(B.SelectClick, null));
709
1592
  };
710
1593
  /** Обработчик ухода курсора с canvas */
711
1594
  _handleMouseLeave = () => {
712
- this._lastHoverKey = null, this._bus.emit(V.SelectHover, null);
1595
+ this._isInteractionEnabled && (this._lastHoverKey = null, this._bus.emit(B.SelectHover, null));
713
1596
  };
714
1597
  /** Инициализация обработчиков событий на hover/click */
715
1598
  _initMouseListeners() {
@@ -721,23 +1604,23 @@ let de = class {
721
1604
  e.removeEventListener("mousemove", this._handleMouseMove), e.removeEventListener("click", this._handleMouseClick), e.removeEventListener("dblclick", this._handleDoubleClick), e.removeEventListener("mouseleave", this._handleMouseLeave);
722
1605
  }
723
1606
  dispose() {
724
- this._removeMouseListeners(), this._isEventListenersAdded = !1, this._lastHoverKey = null;
1607
+ this._removeMouseListeners(), this._isEventListenersAdded = !1, this._isInteractionEnabled = !0, this._lastHoverKey = null;
725
1608
  }
726
1609
  };
727
- de = Gt([
728
- d(),
729
- R(0, l("IDomApi")),
730
- R(1, l("ICameraApi")),
731
- R(2, l("IMeshApi")),
732
- R(3, l("IControlsStateApi")),
733
- R(4, l("EventBus"))
734
- ], de);
735
- var Bt = Object.getOwnPropertyDescriptor, zt = (e, t, r, s) => {
736
- for (var i = s > 1 ? void 0 : s ? Bt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
737
- (n = e[o]) && (i = n(i) || i);
1610
+ We = Fs([
1611
+ v(),
1612
+ q(0, c("IDomApi")),
1613
+ q(1, c("ICameraApi")),
1614
+ q(2, c("IMeshApi")),
1615
+ q(3, c("IControlsStateApi")),
1616
+ q(4, c("EventBus"))
1617
+ ], We);
1618
+ var ks = Object.getOwnPropertyDescriptor, Gs = (e, t, r, s) => {
1619
+ for (var i = s > 1 ? void 0 : s ? ks(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1620
+ (o = e[n]) && (i = o(i) || i);
738
1621
  return i;
739
- }, Nt = (e, t) => (r, s) => t(r, s, e);
740
- let ue = class {
1622
+ }, zs = (e, t) => (r, s) => t(r, s, e);
1623
+ let Ne = class {
741
1624
  constructor(e) {
742
1625
  this._api = e;
743
1626
  }
@@ -750,7 +1633,7 @@ let ue = class {
750
1633
  /** Базовый свет сцены */
751
1634
  _light = null;
752
1635
  init() {
753
- this._grid = new a.GridHelper(10, 10), this._grid.position.y = -1e-3, this._api.addToScene(this._grid), this._axes = new nt(6), this._api.addToScene(this._axes), this._light = new a.HemisphereLight(16777215, 4473924, 0.6), this._api.addToScene(this._light);
1636
+ this._grid = new a.GridHelper(10, 10), this._grid.position.y = -1e-3, this._api.addToScene(this._grid), this._axes = new Vr(6), this._api.addToScene(this._axes), this._light = new a.HemisphereLight(16777215, 4473924, 0.6), this._api.addToScene(this._light);
754
1637
  }
755
1638
  getMeshes() {
756
1639
  return this._meshes;
@@ -777,160 +1660,440 @@ let ue = class {
777
1660
  this._meshes.length = 0, this._grid && (this._api.removeFromScene(this._grid), this._grid.geometry.dispose(), this._grid.material.dispose(), this._grid = null), this._axes && (this._api.removeFromScene(this._axes), this._axes = null), this._light && (this._api.removeFromScene(this._light), this._light = null);
778
1661
  }
779
1662
  };
780
- ue = zt([
781
- d(),
782
- Nt(0, l("ISceneApi"))
783
- ], ue);
784
- var P = /* @__PURE__ */ ((e) => (e[e.Display = 0] = "Display", e[e.Scene = 1] = "Scene", e[e.Select = 2] = "Select", e[e.Tool = 3] = "Tool", e))(P || {}), Ut = Object.getOwnPropertyDescriptor, Xt = (e, t, r, s) => {
785
- for (var i = s > 1 ? void 0 : s ? Ut(t, r) : t, o = e.length - 1, n; o >= 0; o--)
786
- (n = e[o]) && (i = n(i) || i);
1663
+ Ne = Gs([
1664
+ v(),
1665
+ zs(0, c("ISceneApi"))
1666
+ ], Ne);
1667
+ var Ws = Object.getOwnPropertyDescriptor, Ns = (e, t, r, s) => {
1668
+ for (var i = s > 1 ? void 0 : s ? Ws(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1669
+ (o = e[n]) && (i = o(i) || i);
787
1670
  return i;
788
- }, Re = (e, t) => (r, s) => t(r, s, e);
789
- let pe = class {
790
- constructor(e, t) {
791
- this._store = t, this._handlers = new Map(e.map((r) => [r.mode, r]));
792
- }
793
- /** Текущий режим отображения */
794
- _currentMode = F.Plane;
795
- /** Хендлеры, которые управляют отображением */
796
- _handlers;
797
- /** Тип фичи, за которую отвечает менеджер. */
798
- type = P.Display;
799
- /** Установка режима отображения */
800
- manage(e) {
801
- e !== this._currentMode && (this._handlers.get(this._currentMode)?.rollback(), e !== F.Plane && this._handlers.get(e)?.handle(), this._currentMode = e, this._store.setDisplayMode(this._currentMode));
1671
+ }, Us = (e, t) => (r, s) => t(r, s, e);
1672
+ let Ue = class {
1673
+ constructor(e) {
1674
+ this._api = e;
802
1675
  }
803
- /** Освобождает ресурсы менеджера. */
804
- dispose() {
805
- this._handlers && this._handlers.clear(), this._currentMode = F.Plane, this._store.setDisplayMode(this._currentMode);
1676
+ /** Объекты вьювера */
1677
+ _meshes = [];
1678
+ /** Базовый свет сцены */
1679
+ _light = null;
1680
+ init() {
1681
+ this._light = new a.HemisphereLight(16777215, 4473924, 0.6), this._api.addToScene(this._light);
806
1682
  }
807
- };
808
- pe = Xt([
809
- d(),
810
- Re(0, D("IDisplayHandler")),
811
- Re(1, l("EditorStore"))
812
- ], pe);
813
- var C = /* @__PURE__ */ ((e) => (e.Hover = "hover", e.Click = "click", e))(C || {}), Yt = Object.getOwnPropertyDescriptor, Zt = (e, t, r, s) => {
814
- for (var i = s > 1 ? void 0 : s ? Yt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
815
- (n = e[o]) && (i = n(i) || i);
816
- return i;
817
- }, J = (e, t) => (r, s) => t(r, s, e);
818
- let me = class {
819
- constructor(e, t, r) {
820
- this._eventBus = e, this._store = r, this._handlers = new Map(t.map((s) => [s.mode, s])), this._eventBus.on(V.SelectHover, this._onHover), this._eventBus.on(V.SelectClick, this._onClick);
1683
+ getMeshes() {
1684
+ return this._meshes;
821
1685
  }
822
- /** Текущий режим выборки */
823
- _currentMode = M.Mesh;
824
- /** Хендлеры, которые управляют выборкой */
825
- _handlers;
826
- /** Тип фичи, за которую отвечает менеджер. */
827
- type = P.Select;
828
- /** Переключает режим выбора */
829
- manage(e) {
830
- e !== this._currentMode && (this._handlers.get(this._currentMode)?.rollback(), this._currentMode = e, this._store.setSelectMode(this._currentMode));
1686
+ addMesh(e) {
1687
+ this._meshes.includes(e) || (this._meshes.push(e), this._api.addToScene(e));
831
1688
  }
832
- /** Обработчик события наведения на модель */
833
- _onHover = (e) => {
834
- this._handlers.get(this._currentMode)?.handle(e, C.Hover);
835
- };
836
- /** Обработчик события клика на модель */
837
- _onClick = (e) => {
838
- this._handlers.get(this._currentMode)?.handle(e, C.Click);
839
- };
840
- /** Освобождает ресурсы менеджера. */
841
- dispose() {
842
- this._handlers && this._handlers.clear(), this._eventBus.off(V.SelectHover, this._onHover), this._currentMode = M.Mesh, this._store.setSelectMode(this._currentMode);
1689
+ removeMesh(e) {
1690
+ const t = this._meshes.indexOf(e);
1691
+ t >= 0 && this._meshes.splice(t, 1), this._api.removeFromScene(e);
843
1692
  }
844
- };
845
- me = Zt([
846
- d(),
847
- J(0, l("EventBus")),
848
- J(1, D("ISelectHandler")),
849
- J(2, l("EditorStore"))
850
- ], me);
851
- const qt = (e) => (t, r, s) => {
852
- const i = s.value;
853
- if (!i)
854
- throw new Error("usePolicy can only be applied to method");
855
- return s.value = function(...o) {
856
- return e(this).check(...o), i.apply(this, o);
857
- }, s;
858
- };
859
- var Kt = Object.defineProperty, Qt = Object.getOwnPropertyDescriptor, Ye = (e, t, r, s) => {
860
- for (var i = s > 1 ? void 0 : s ? Qt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
861
- (n = e[o]) && (i = (s ? n(t, r, i) : n(i)) || i);
862
- return s && i && Kt(t, r, i), i;
863
- }, ee = (e, t) => (r, s) => t(r, s, e);
864
- let Y = class {
865
- constructor(e, t, r) {
866
- this._store = t, this._policy = r, this._handlers = new Map(e.map((s) => [s.mode, s])), this._unsubSelected = this._store.onSelectedObjectChange(() => {
867
- this._handlers.get(this._currentTool)?.handle();
868
- });
1693
+ addMeshes(e) {
1694
+ for (const t of e)
1695
+ this.addMesh(t);
869
1696
  }
870
- /** Текущий выбранный инструмент */
871
- _currentTool = j.Translate;
872
- /** Хендлеры, которые управляют инструментами */
873
- _handlers;
874
- /** Событие обновления выбора объекта */
875
- _unsubSelected;
876
- /** Тип фичи, за которую отвечает менеджер. */
877
- type = P.Tool;
878
- manage(e) {
879
- this._currentTool !== e && (this._handlers.get(this._currentTool)?.rollback(), this._currentTool = e, this._store.setToolType(this._currentTool), this._handlers.get(this._currentTool)?.handle());
1697
+ removeMeshes(e) {
1698
+ for (const t of e)
1699
+ this.removeMesh(t);
880
1700
  }
881
- /** Освобождает ресурсы менеджера. */
1701
+ /** Освобождает ресурсы модуля */
882
1702
  dispose() {
883
- this._unsubSelected?.(), this._handlers && this._handlers.clear(), this._currentTool = j.Translate, this._store.setToolType(this._currentTool);
1703
+ for (const e of this._meshes)
1704
+ this._api.removeFromScene(e);
1705
+ this._meshes.length = 0, this._light && (this._api.removeFromScene(this._light), this._light = null);
884
1706
  }
885
1707
  };
886
- Ye([
887
- qt((e) => e._policy)
888
- ], Y.prototype, "manage", 1);
889
- Y = Ye([
890
- d(),
891
- ee(0, D("IToolHandler")),
892
- ee(1, l("EditorStore")),
893
- ee(2, l("ToolPolicy"))
894
- ], Y);
895
- var Jt = Object.getOwnPropertyDescriptor, es = (e, t, r, s) => {
896
- for (var i = s > 1 ? void 0 : s ? Jt(t, r) : t, o = e.length - 1, n; o >= 0; o--)
897
- (n = e[o]) && (i = n(i) || i);
1708
+ Ue = Ns([
1709
+ v(),
1710
+ Us(0, c("ISceneApi"))
1711
+ ], Ue);
1712
+ var Xs = Object.getOwnPropertyDescriptor, Ys = (e, t, r, s) => {
1713
+ for (var i = s > 1 ? void 0 : s ? Xs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1714
+ (o = e[n]) && (i = o(i) || i);
898
1715
  return i;
899
- }, ts = (e, t) => (r, s) => t(r, s, e);
900
- let ge = class {
901
- /** Текущий режим редактирования сцены */
902
- _currentMode = W.AddFigure;
903
- /** Хендлеры, которые управляют отображением */
904
- _handlers;
905
- /** Тип фичи, за которую отвечает менеджер. */
906
- type = P.Scene;
1716
+ }, Ks = (e, t) => (r, s) => t(r, s, e);
1717
+ let Xe = class {
1718
+ /**
1719
+ * Конструктор модуля метрик.
1720
+ *
1721
+ * @param _rendererInfoApi - доступ к информации рендерера за кадр
1722
+ *
1723
+ * @internal
1724
+ * @constructor
1725
+ */
907
1726
  constructor(e) {
908
- this._handlers = new Map(e.map((t) => [t.mode, t]));
1727
+ this._rendererInfoApi = e;
1728
+ }
1729
+ /** Выполняется ли сбор метрик */
1730
+ _isRunning = !1;
1731
+ /** Время запуска сбора метрик */
1732
+ _startedAt = 0;
1733
+ /** Время остановки сбора метрик */
1734
+ _stoppedAt = 0;
1735
+ /** Время предыдущего кадра */
1736
+ _lastFrameAt = 0;
1737
+ /** Количество обработанных кадров */
1738
+ _frames = 0;
1739
+ /** Суммарное время кадров */
1740
+ _frameTimeSum = 0;
1741
+ /** Максимальное время кадра */
1742
+ _maxFrameTime = 0;
1743
+ /** Количество объектов в тестовой сцене */
1744
+ _objectsCount = 0;
1745
+ /** Максимальное количество draw calls за время измерения */
1746
+ _drawCalls = 0;
1747
+ /** Максимальное количество треугольников за время измерения */
1748
+ _triangles = 0;
1749
+ /** Максимальное количество геометрий в памяти рендерера */
1750
+ _geometries = 0;
1751
+ /** Максимальное количество текстур в памяти рендерера */
1752
+ _textures = 0;
1753
+ /** Используемый объем памяти в мегабайтах */
1754
+ _memoryUsedMb = void 0;
1755
+ /** Слушатели обновления метрик */
1756
+ _listeners = /* @__PURE__ */ new Set();
1757
+ /** Время последнего уведомления слушателей */
1758
+ _lastNotifyAt = 0;
1759
+ /** Минимальный интервал уведомлений слушателей */
1760
+ _notifyIntervalMs = 250;
1761
+ /**
1762
+ * Инициализирует модуль.
1763
+ *
1764
+ * @internal
1765
+ * @method
1766
+ */
1767
+ init() {
1768
+ this.reset();
909
1769
  }
910
- /** Установка режима редактирования сцены */
911
- manage(e, t) {
912
- e === W.AddFigure ? this._handlers.get(e)?.handle(t) : this._handlers.get(e)?.handle(), this._currentMode = e;
1770
+ /**
1771
+ * Запускает сбор метрик.
1772
+ *
1773
+ * @param objectsCount - количество объектов, участвующих в текущем тесте
1774
+ *
1775
+ * @internal
1776
+ * @method
1777
+ */
1778
+ start(e = 0) {
1779
+ this.reset();
1780
+ const t = performance.now();
1781
+ this._isRunning = !0, this._startedAt = t, this._lastFrameAt = t, this._objectsCount = e;
913
1782
  }
914
- /** Освобождает ресурсы менеджера. */
915
- dispose() {
916
- this._handlers && this._handlers.clear(), this._currentMode = W.AddFigure;
1783
+ /**
1784
+ * Останавливает сбор метрик.
1785
+ *
1786
+ * @internal
1787
+ * @method
1788
+ */
1789
+ stop() {
1790
+ this._isRunning && (this._isRunning = !1, this._stoppedAt = performance.now(), this._captureRendererInfo(), this._captureMemoryInfo());
917
1791
  }
918
- };
919
- ge = es([
920
- d(),
921
- ts(0, D("ISceneHandler"))
922
- ], ge);
923
- var ss = Object.getOwnPropertyDescriptor, rs = (e, t, r, s) => {
924
- for (var i = s > 1 ? void 0 : s ? ss(t, r) : t, o = e.length - 1, n; o >= 0; o--)
925
- (n = e[o]) && (i = n(i) || i);
926
- return i;
927
- }, is = (e, t) => (r, s) => t(r, s, e);
928
- let ve = class {
1792
+ /**
1793
+ * Сбрасывает накопленные метрики.
1794
+ *
1795
+ * @internal
1796
+ * @method
1797
+ */
1798
+ reset() {
1799
+ this._isRunning = !1, this._startedAt = 0, this._stoppedAt = 0, this._lastFrameAt = 0, this._frames = 0, this._frameTimeSum = 0, this._maxFrameTime = 0, this._objectsCount = 0, this._drawCalls = 0, this._triangles = 0, this._geometries = 0, this._textures = 0, this._memoryUsedMb = void 0, this._lastNotifyAt = 0;
1800
+ }
1801
+ /**
1802
+ * Выполняет наблюдение за текущим состоянием runtime.
1803
+ *
1804
+ * @remarks
1805
+ * Метод вызывается каждый кадр в отдельной фазе render loop.
1806
+ *
1807
+ * @internal
1808
+ * @method
1809
+ */
1810
+ observe() {
1811
+ if (!this._isRunning) return;
1812
+ const e = performance.now(), t = e - this._lastFrameAt;
1813
+ this._lastFrameAt = e, !(t <= 0) && (this._frames += 1, this._frameTimeSum += t, this._maxFrameTime = Math.max(this._maxFrameTime, t), this._captureRendererInfo(), this._captureMemoryInfo(), this._notify());
1814
+ }
1815
+ /**
1816
+ * Возвращает текущие или последние собранные метрики.
1817
+ *
1818
+ * @returns Метрики производительности
1819
+ *
1820
+ * @internal
1821
+ * @method
1822
+ */
1823
+ getMetrics() {
1824
+ const e = this._getDurationMs(), t = this._frames > 0 ? this._frameTimeSum / this._frames : 0, r = {
1825
+ durationMs: e,
1826
+ frames: this._frames,
1827
+ averageFps: t > 0 ? 1e3 / t : 0,
1828
+ minFps: this._maxFrameTime > 0 ? 1e3 / this._maxFrameTime : 0,
1829
+ averageFrameTime: t,
1830
+ maxFrameTime: this._maxFrameTime,
1831
+ objectsCount: this._objectsCount,
1832
+ drawCalls: this._drawCalls,
1833
+ triangles: this._triangles,
1834
+ geometries: this._geometries,
1835
+ textures: this._textures
1836
+ };
1837
+ return this._memoryUsedMb !== void 0 && (r.memoryUsedMb = this._memoryUsedMb), r;
1838
+ }
1839
+ /**
1840
+ * Регистрирует слушатель изменения метрик.
1841
+ *
1842
+ * @param listener - обработчик обновления метрик
1843
+ *
1844
+ * @returns Функция отписки
1845
+ *
1846
+ * @internal
1847
+ */
1848
+ subscribe(e) {
1849
+ return this._listeners.add(e), () => {
1850
+ this._listeners.delete(e);
1851
+ };
1852
+ }
1853
+ /**
1854
+ * Освобождает ресурсы модуля.
1855
+ *
1856
+ * @internal
1857
+ * @method
1858
+ */
1859
+ dispose() {
1860
+ this.reset();
1861
+ }
1862
+ /**
1863
+ * Возвращает фактическую длительность сбора метрик.
1864
+ *
1865
+ * @returns Длительность измерения в миллисекундах
1866
+ *
1867
+ * @private
1868
+ * @method
1869
+ */
1870
+ _getDurationMs() {
1871
+ if (!this._startedAt) return 0;
1872
+ const e = this._isRunning ? performance.now() : this._stoppedAt;
1873
+ return Math.max(0, e - this._startedAt);
1874
+ }
1875
+ /**
1876
+ * Сохраняет статистику WebGL-рендерера.
1877
+ *
1878
+ * @private
1879
+ * @method
1880
+ */
1881
+ _captureRendererInfo() {
1882
+ const e = this._rendererInfoApi.getRendererInfo();
1883
+ this._drawCalls = Math.max(this._drawCalls, e.drawCalls), this._triangles = Math.max(this._triangles, e.triangles), this._geometries = Math.max(this._geometries, e.geometries), this._textures = Math.max(this._textures, e.textures);
1884
+ }
1885
+ /**
1886
+ * Сохраняет информацию об используемой памяти, если она доступна.
1887
+ *
1888
+ * @private
1889
+ * @method
1890
+ */
1891
+ _captureMemoryInfo() {
1892
+ const e = performance.memory;
1893
+ e && (this._memoryUsedMb = e.usedJSHeapSize / 1024 / 1024);
1894
+ }
1895
+ /**
1896
+ * Уведомляет слушателей об обновлении метрик.
1897
+ *
1898
+ * @private
1899
+ * @method
1900
+ */
1901
+ _notify() {
1902
+ if (this._listeners.size === 0) return;
1903
+ const e = performance.now();
1904
+ if (e - this._lastNotifyAt < this._notifyIntervalMs) return;
1905
+ this._lastNotifyAt = e;
1906
+ const t = this.getMetrics();
1907
+ this._listeners.forEach((r) => r(t));
1908
+ }
1909
+ };
1910
+ Xe = Ys([
1911
+ v(),
1912
+ Ks(0, c("IRendererInfoApi"))
1913
+ ], Xe);
1914
+ var P = /* @__PURE__ */ ((e) => (e[e.Display = 0] = "Display", e[e.Scene = 1] = "Scene", e[e.Select = 2] = "Select", e[e.Tool = 3] = "Tool", e[e.Benchmark = 4] = "Benchmark", e))(P || {}), qs = Object.getOwnPropertyDescriptor, Zs = (e, t, r, s) => {
1915
+ for (var i = s > 1 ? void 0 : s ? qs(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1916
+ (o = e[n]) && (i = o(i) || i);
1917
+ return i;
1918
+ }, Bt = (e, t) => (r, s) => t(r, s, e);
1919
+ let Ye = class {
1920
+ constructor(e, t) {
1921
+ this._store = t, this._handlers = new Map(e.map((r) => [r.mode, r]));
1922
+ }
1923
+ /** Текущий режим отображения */
1924
+ _currentMode = J.Plane;
1925
+ /** Хендлеры, которые управляют отображением */
1926
+ _handlers;
1927
+ /** Тип фичи, за которую отвечает менеджер. */
1928
+ type = P.Display;
1929
+ /** Установка режима отображения */
1930
+ manage(e) {
1931
+ e !== this._currentMode && (this._handlers.get(this._currentMode)?.rollback(), e !== J.Plane && this._handlers.get(e)?.handle(), this._currentMode = e, this._store.setDisplayMode(this._currentMode));
1932
+ }
1933
+ /** Освобождает ресурсы менеджера. */
1934
+ dispose() {
1935
+ this._handlers && this._handlers.clear(), this._currentMode = J.Plane, this._store.setDisplayMode(this._currentMode);
1936
+ }
1937
+ };
1938
+ Ye = Zs([
1939
+ v(),
1940
+ Bt(0, H("IDisplayHandler")),
1941
+ Bt(1, c("EditorStore"))
1942
+ ], Ye);
1943
+ var Js = Object.getOwnPropertyDescriptor, Qs = (e, t, r, s) => {
1944
+ for (var i = s > 1 ? void 0 : s ? Js(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1945
+ (o = e[n]) && (i = o(i) || i);
1946
+ return i;
1947
+ }, ei = (e, t) => (r, s) => t(r, s, e);
1948
+ let Ke = class {
1949
+ /** Текущий режим редактирования сцены */
1950
+ _currentMode = T.AddFigure;
1951
+ /** Хендлеры, которые управляют отображением */
1952
+ _handlers;
1953
+ /** Тип фичи, за которую отвечает менеджер. */
1954
+ type = P.Scene;
1955
+ constructor(e) {
1956
+ this._handlers = new Map(e.map((t) => [t.mode, t]));
1957
+ }
1958
+ /** Установка режима редактирования сцены */
1959
+ manage(e, t) {
1960
+ this._handlers.get(e)?.handle(t), this._currentMode = e;
1961
+ }
1962
+ /** Освобождает ресурсы менеджера. */
1963
+ dispose() {
1964
+ this._handlers && this._handlers.clear(), this._currentMode = T.AddFigure;
1965
+ }
1966
+ };
1967
+ Ke = Qs([
1968
+ v(),
1969
+ ei(0, H("ISceneHandler"))
1970
+ ], Ke);
1971
+ var R = /* @__PURE__ */ ((e) => (e.Hover = "hover", e.Click = "click", e))(R || {}), ti = Object.getOwnPropertyDescriptor, ri = (e, t, r, s) => {
1972
+ for (var i = s > 1 ? void 0 : s ? ti(t, r) : t, n = e.length - 1, o; n >= 0; n--)
1973
+ (o = e[n]) && (i = o(i) || i);
1974
+ return i;
1975
+ }, Ce = (e, t) => (r, s) => t(r, s, e);
1976
+ let qe = class {
1977
+ constructor(e, t, r) {
1978
+ this._eventBus = e, this._store = r, this._handlers = new Map(t.map((s) => [s.mode, s])), this._eventBus.on(B.SelectHover, this._onHover), this._eventBus.on(B.SelectClick, this._onClick);
1979
+ }
1980
+ /** Текущий режим выборки */
1981
+ _currentMode = O.Mesh;
1982
+ /** Хендлеры, которые управляют выборкой */
1983
+ _handlers;
1984
+ /** Тип фичи, за которую отвечает менеджер. */
1985
+ type = P.Select;
1986
+ /** Переключает режим выбора */
1987
+ manage(e) {
1988
+ e !== this._currentMode && (this._handlers.get(this._currentMode)?.rollback(), this._currentMode = e, this._store.setSelectMode(this._currentMode));
1989
+ }
1990
+ /** Обработчик события наведения на модель */
1991
+ _onHover = (e) => {
1992
+ this._handlers.get(this._currentMode)?.handle(e, R.Hover);
1993
+ };
1994
+ /** Обработчик события клика на модель */
1995
+ _onClick = (e) => {
1996
+ this._handlers.get(this._currentMode)?.handle(e, R.Click);
1997
+ };
1998
+ /** Освобождает ресурсы менеджера. */
1999
+ dispose() {
2000
+ this._handlers && this._handlers.clear(), this._eventBus.off(B.SelectHover, this._onHover), this._currentMode = O.Mesh, this._store.setSelectMode(this._currentMode);
2001
+ }
2002
+ };
2003
+ qe = ri([
2004
+ v(),
2005
+ Ce(0, c("EventBus")),
2006
+ Ce(1, H("ISelectHandler")),
2007
+ Ce(2, c("EditorStore"))
2008
+ ], qe);
2009
+ const si = (e) => (t, r, s) => {
2010
+ const i = s.value;
2011
+ if (!i)
2012
+ throw new Error("usePolicy can only be applied to method");
2013
+ return s.value = function(...n) {
2014
+ return e(this).check(...n), i.apply(this, n);
2015
+ }, s;
2016
+ }, nr = (e) => (t, r, s) => {
2017
+ const i = s.value;
2018
+ if (!i)
2019
+ throw new Error("useValidator can only be applied to method");
2020
+ return s.value = function(...n) {
2021
+ return e(this).validate(...n), i.apply(this, n);
2022
+ }, s;
2023
+ };
2024
+ var ii = Object.defineProperty, ni = Object.getOwnPropertyDescriptor, or = (e, t, r, s) => {
2025
+ for (var i = s > 1 ? void 0 : s ? ni(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2026
+ (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
2027
+ return s && i && ii(t, r, i), i;
2028
+ }, Oe = (e, t) => (r, s) => t(r, s, e);
2029
+ let fe = class {
2030
+ constructor(e, t, r) {
2031
+ this._store = t, this._policy = r, this._handlers = new Map(e.map((s) => [s.mode, s])), this._unsubSelected = this._store.onSelectedObjectChange(() => {
2032
+ this._handlers.get(this._currentTool)?.handle();
2033
+ });
2034
+ }
2035
+ /** Текущий выбранный инструмент */
2036
+ _currentTool = W.Translate;
2037
+ /** Хендлеры, которые управляют инструментами */
2038
+ _handlers;
2039
+ /** Событие обновления выбора объекта */
2040
+ _unsubSelected;
2041
+ /** Тип фичи, за которую отвечает менеджер. */
2042
+ type = P.Tool;
2043
+ manage(e) {
2044
+ this._currentTool !== e && (this._handlers.get(this._currentTool)?.rollback(), this._currentTool = e, this._store.setToolType(this._currentTool), this._handlers.get(this._currentTool)?.handle());
2045
+ }
2046
+ /** Освобождает ресурсы менеджера. */
2047
+ dispose() {
2048
+ this._unsubSelected?.(), this._handlers && this._handlers.clear(), this._currentTool = W.Translate, this._store.setToolType(this._currentTool);
2049
+ }
2050
+ };
2051
+ or([
2052
+ si((e) => e._policy)
2053
+ ], fe.prototype, "manage", 1);
2054
+ fe = or([
2055
+ v(),
2056
+ Oe(0, H("IToolHandler")),
2057
+ Oe(1, c("EditorStore")),
2058
+ Oe(2, c("ToolPolicy"))
2059
+ ], fe);
2060
+ var oi = Object.getOwnPropertyDescriptor, ai = (e, t, r, s) => {
2061
+ for (var i = s > 1 ? void 0 : s ? oi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2062
+ (o = e[n]) && (i = o(i) || i);
2063
+ return i;
2064
+ }, li = (e, t) => (r, s) => t(r, s, e);
2065
+ let Ze = class {
2066
+ /** Тип фичи, за которую отвечает менеджер. */
2067
+ type = P.Benchmark;
2068
+ /** Текущий режим тестирования */
2069
+ _currentMode = X.Light;
2070
+ /** Хендлеры, которые управляют тестированием */
2071
+ _handlers;
2072
+ constructor(e) {
2073
+ this._handlers = new Map(e.map((t) => [t.mode, t]));
2074
+ }
2075
+ manage(e, t) {
2076
+ this._handlers.get(this._currentMode)?.rollback(), this._currentMode = e, this._handlers.get(this._currentMode)?.handle(t);
2077
+ }
2078
+ dispose() {
2079
+ this._handlers && this._handlers.clear(), this._currentMode = X.Light;
2080
+ }
2081
+ };
2082
+ Ze = ai([
2083
+ v(),
2084
+ li(0, H("IBenchmarkHandler"))
2085
+ ], Ze);
2086
+ var ci = Object.getOwnPropertyDescriptor, hi = (e, t, r, s) => {
2087
+ for (var i = s > 1 ? void 0 : s ? ci(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2088
+ (o = e[n]) && (i = o(i) || i);
2089
+ return i;
2090
+ }, di = (e, t) => (r, s) => t(r, s, e);
2091
+ let Je = class {
929
2092
  constructor(e) {
930
2093
  this._api = e;
931
2094
  }
932
2095
  /** Режим отображения. */
933
- mode = F.Wireframe;
2096
+ mode = J.Wireframe;
934
2097
  /** Сохраняем предыдущие значения wireframe для отката. */
935
2098
  _prevWireframe = /* @__PURE__ */ new Map();
936
2099
  /** Сохраняем исходные цвета материалов для отката */
@@ -948,11 +2111,11 @@ let ve = class {
948
2111
  if (s.isLineSegments) {
949
2112
  const i = s;
950
2113
  if (!this._prevColorLines.has(i.material)) {
951
- const n = i.material;
952
- this._prevColorLines.set(n, n.color.clone());
2114
+ const o = i.material;
2115
+ this._prevColorLines.set(o, o.color.clone());
953
2116
  }
954
- const o = i.material;
955
- o.color.copy(this._wireColor), o.needsUpdate = !0;
2117
+ const n = i.material;
2118
+ n.color.copy(this._wireColor), n.needsUpdate = !0;
956
2119
  }
957
2120
  });
958
2121
  }
@@ -981,103 +2144,156 @@ let ve = class {
981
2144
  "wireframe" in t && !this._prevWireframe.has(e) && (this._prevWireframe.set(e, !!t.wireframe), t.wireframe = !0, e.needsUpdate = !0), t.color?.isColor && (this._prevColorMesh.has(e) || this._prevColorMesh.set(e, t.color.clone()), t.color.copy(this._wireColor));
982
2145
  }
983
2146
  };
984
- ve = rs([
985
- d(),
986
- is(0, l("IMeshApi"))
987
- ], ve);
988
- const Z = 16776960, q = 16755200, os = 2236962, ns = 2236962;
989
- var as = Object.getOwnPropertyDescriptor, cs = (e, t, r, s) => {
990
- for (var i = s > 1 ? void 0 : s ? as(t, r) : t, o = e.length - 1, n; o >= 0; o--)
991
- (n = e[o]) && (i = n(i) || i);
2147
+ Je = hi([
2148
+ v(),
2149
+ di(0, c("IMeshApi"))
2150
+ ], Je);
2151
+ var _i = Object.getOwnPropertyDescriptor, ui = (e, t, r, s) => {
2152
+ for (var i = s > 1 ? void 0 : s ? _i(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2153
+ (o = e[n]) && (i = o(i) || i);
992
2154
  return i;
993
- }, Fe = (e, t) => (r, s) => t(r, s, e);
994
- let fe = class {
995
- constructor(e, t) {
996
- this._api = e, this._store = t;
2155
+ }, se = (e, t) => (r, s) => t(r, s, e);
2156
+ let Qe = class {
2157
+ constructor(e, t, r, s) {
2158
+ this._sceneApi = e, this._cameraApi = t, this._raycastApi = r, this._store = s, this._cameraApi.enableCameraLayer($), this._hoverLine = Y(this._makeOverlayLine(this._hoverColor)), this._selectLine = Y(this._makeOverlayLine(this._selectColor)), this._sceneApi.addObject(this._hoverLine, $), this._sceneApi.addObject(this._selectLine, $);
997
2159
  }
998
2160
  /** Режим, которым управляет хендлер, нужен только менеджеру */
999
- mode = M.Mesh;
1000
- /** Фигура, на которую навелись в данный момент */
1001
- _hoveredMesh = null;
1002
- /** Фигура, которую выбрали в данный момент */
1003
- _selectedMesh = null;
2161
+ mode = O.Edge;
2162
+ /** Текущее наведённое ребро. */
2163
+ _hoverLine;
2164
+ /** Текущее выбранное ребро. */
2165
+ _selectLine;
2166
+ /** Текущее наведённое ребро из массива `LineSegments` модели. */
2167
+ _hovered = null;
2168
+ /** Текущее выбранное ребро из массива `LineSegments` модели. */
2169
+ _selected = null;
1004
2170
  // Цвета, необходимые для переключения
1005
- /** Цвет ребер для фигуры, на которую навелись */
1006
- _hoverColor = Z;
1007
- /** Цвет ребер для выделенной фигуры */
1008
- _selectColor = q;
1009
- /** Исходные цвета материалов линий для отката */
1010
- _origLineColors = /* @__PURE__ */ new WeakMap();
2171
+ /** Цвет ребра, на которое навелись */
2172
+ _hoverColor = be;
2173
+ /** Цвет выделенного ребра */
2174
+ _selectColor = Me;
2175
+ /** Обработка текущего режима выборки. */
1011
2176
  handle(e, t) {
1012
- if (this._api.setRaycastMode(this.mode), t === C.Hover) {
2177
+ if (this._raycastApi.setRaycastMode(this.mode), t === R.Hover) {
1013
2178
  if (!e) {
1014
- this._hoveredMesh && this._hoveredMesh !== this._selectedMesh && this._restoreEdgesColor(this._hoveredMesh), this._hoveredMesh = null;
2179
+ this._hoverLine.visible = !1, this._hovered = null;
1015
2180
  return;
1016
2181
  }
1017
2182
  const r = e.intersection.object;
1018
- this._hoveredMesh !== r && (this._hoveredMesh && this._hoveredMesh !== this._selectedMesh && this._restoreEdgesColor(this._hoveredMesh), r !== this._selectedMesh && this._paintEdges(r, this._hoverColor), this._hoveredMesh = r);
2183
+ if (!r?.isLineSegments) return;
2184
+ const s = r, i = Math.floor((e.intersection.index ?? -1) / 2);
2185
+ if (i < 0) return;
2186
+ this._selected && this._same({ lines: s, seg: i }, this._selected) ? this._hoverLine.visible = !1 : (this._writeWorldSegment(this._hoverLine, s, i), this._hoverLine.visible = !0), this._hovered = { lines: s, seg: i };
2187
+ return;
1019
2188
  }
1020
- if (t === C.Click) {
2189
+ if (t === R.Click) {
1021
2190
  if (!e) {
1022
- this._selectedMesh && (this._restoreEdgesColor(this._selectedMesh), this._selectedMesh = null, this._store.setSelectedObject(null));
2191
+ this._selectLine.visible = !1, this._selected = null, this._store.setSelectedObject(null);
1023
2192
  return;
1024
2193
  }
1025
2194
  const r = e.intersection.object;
1026
- this._selectedMesh && this._selectedMesh !== r && this._restoreEdgesColor(this._selectedMesh), this._paintEdges(r, this._selectColor), this._selectedMesh = r, this._store.setSelectedObject(r);
2195
+ if (!r?.isLineSegments) return;
2196
+ const s = r, i = Math.floor((e.intersection.index ?? -1) / 2);
2197
+ if (i < 0) return;
2198
+ this._writeWorldSegment(this._selectLine, s, i), this._centerAndOrientLineOnSegment(this._selectLine, s, i), this._selectLine.visible = !0, this._prepareEdgeMetadata(s, i), this._store.setSelectedObject(this._selectLine), this._selected = { lines: s, seg: i }, this._hovered && this._same(this._hovered, this._selected) && (this._hoverLine.visible = !1);
1027
2199
  }
1028
2200
  }
2201
+ /** Откат текущего режима выборки */
1029
2202
  rollback() {
1030
- this._hoveredMesh && this._restoreEdgesColor(this._hoveredMesh), this._selectedMesh && this._restoreEdgesColor(this._selectedMesh), this._hoveredMesh = this._selectedMesh = null, this._store.setSelectedObject(null);
2203
+ this._hoverLine.visible = !1, this._selectLine.visible = !1, this._hovered = this._selected = null, this._store.setSelectedObject(null);
1031
2204
  }
1032
2205
  /** Освобождает ресурсы хендлера, удаляет слушатели и очищает внутренние данные. */
1033
2206
  dispose() {
1034
- this.rollback();
2207
+ this.rollback(), this._sceneApi.removeFromScene(this._hoverLine), this._sceneApi.removeFromScene(this._selectLine), this._hoverLine.geometry.dispose(), this._hoverLine.material.dispose(), this._selectLine.geometry.dispose(), this._selectLine.material.dispose();
1035
2208
  }
1036
- /**
1037
- * Перекрасить рёбра меша и запомнить оригинальный цвет (один раз на LineSegments).
2209
+ /** Инициализация буферных линий для режима (hover и click).
2210
+ * На весь режим будет использовано 2 глобальных линии на сцене,
2211
+ * использоваться они будут только для обозначения геометрии ребер конкретной фигуры.
1038
2212
  */
1039
- _paintEdges(e, t) {
1040
- e.children.forEach((r) => {
1041
- const s = r;
1042
- if (s.isLineSegments && s.material) {
1043
- const i = s.material;
1044
- this._origLineColors.has(s) || this._origLineColors.set(s, i.color.clone()), i.color.setHex(t), i.needsUpdate = !0;
1045
- }
1046
- });
2213
+ _makeOverlayLine(e) {
2214
+ const t = new a.BufferGeometry();
2215
+ t.setAttribute("position", new a.Float32BufferAttribute(6, 3));
2216
+ const r = new a.LineBasicMaterial({
2217
+ color: e,
2218
+ depthTest: !1,
2219
+ depthWrite: !1,
2220
+ transparent: !0,
2221
+ opacity: 1
2222
+ }), s = new a.Line(t, r);
2223
+ return s.renderOrder = 1e3, s.raycast = () => {
2224
+ }, s.layers.set($), s.visible = !1, s;
1047
2225
  }
1048
- /**
1049
- * Восстановить исходный цвет рёбер меша из WeakMap.
1050
- * Если исходный цвет не сохранён (на всякий случай) ничего не меняем.
1051
- */
1052
- _restoreEdgesColor(e) {
1053
- e.children.forEach((t) => {
1054
- const r = t;
1055
- if (r.isLineSegments && r.material) {
1056
- const s = this._origLineColors.get(r);
1057
- if (s) {
1058
- const i = r.material;
1059
- i.color.copy(s), i.needsUpdate = !0;
1060
- }
1061
- }
1062
- });
2226
+ /** Локальные точки сегмента переводим в target (который висит на сцене) */
2227
+ _writeWorldSegment(e, t, r) {
2228
+ const s = t.geometry.getAttribute("position"), i = r * 2, n = i + 1, o = new a.Vector3(s.getX(i), s.getY(i), s.getZ(i)).applyMatrix4(
2229
+ t.matrixWorld
2230
+ ), l = new a.Vector3(s.getX(n), s.getY(n), s.getZ(n)).applyMatrix4(
2231
+ t.matrixWorld
2232
+ ), h = e.geometry.getAttribute("position");
2233
+ h.setXYZ(0, o.x, o.y, o.z), h.setXYZ(1, l.x, l.y, l.z), h.needsUpdate = !0;
2234
+ }
2235
+ _same(e, t) {
2236
+ return !!e && !!t && e.lines === t.lines && e.seg === t.seg;
2237
+ }
2238
+ /** Центрует `THREE.Line` на сегменте и ориентирует её вдоль ребра */
2239
+ _centerAndOrientLineOnSegment(e, t, r) {
2240
+ const s = t.geometry.getAttribute("position"), i = r * 2, n = i + 1, o = new a.Vector3(s.getX(i), s.getY(i), s.getZ(i)).applyMatrix4(
2241
+ t.matrixWorld
2242
+ ), l = new a.Vector3(s.getX(n), s.getY(n), s.getZ(n)).applyMatrix4(
2243
+ t.matrixWorld
2244
+ ), h = new a.Vector3().subVectors(l, o), d = h.length();
2245
+ if (!isFinite(d) || d === 0) return;
2246
+ const p = new a.Vector3().addVectors(o, l).multiplyScalar(0.5);
2247
+ e.position.copy(p);
2248
+ const u = e.geometry;
2249
+ let m = u.getAttribute("position");
2250
+ (!m || m.count < 2) && (u.setAttribute("position", new a.BufferAttribute(new Float32Array(6), 3)), m = u.getAttribute("position")), m.setXYZ(0, -d / 2, 0, 0), m.setXYZ(1, d / 2, 0, 0), m.needsUpdate = !0, h.normalize();
2251
+ const f = new a.Quaternion().setFromUnitVectors(new a.Vector3(1, 0, 0), h);
2252
+ e.quaternion.copy(f), e.updateMatrixWorld(!0);
2253
+ }
2254
+ /** Запись метаданных выбранного ребра для использования инструментов */
2255
+ _prepareEdgeMetadata(e, t) {
2256
+ const r = er(e);
2257
+ if (!r) return;
2258
+ const s = e.geometry.getAttribute("position"), i = t * 2, n = i + 1, o = new a.Vector3(s.getX(i), s.getY(i), s.getZ(i)).applyMatrix4(
2259
+ e.matrixWorld
2260
+ ), l = new a.Vector3(s.getX(n), s.getY(n), s.getZ(n)).applyMatrix4(
2261
+ e.matrixWorld
2262
+ ), h = new a.Matrix4().copy(r.matrixWorld).invert(), d = o.clone().applyMatrix4(h), p = l.clone().applyMatrix4(h), m = r.geometry.getAttribute("position"), f = new a.Vector3(), _ = 1e-6, g = [], b = [];
2263
+ for (let A = 0; A < m.count; A++)
2264
+ f.fromBufferAttribute(m, A), f.distanceToSquared(d) < _ * _ ? g.push(A) : f.distanceToSquared(p) < _ * _ && b.push(A);
2265
+ const x = new a.Matrix4().copy(e.matrixWorld).invert(), S = o.clone().applyMatrix4(x), w = l.clone().applyMatrix4(x), M = e.geometry.getAttribute("position"), I = new a.Vector3(), y = [], C = [];
2266
+ for (let A = 0; A < M.count; A++)
2267
+ I.fromBufferAttribute(M, A), I.distanceToSquared(S) < _ * _ ? y.push(A) : I.distanceToSquared(w) < _ * _ && C.push(A);
2268
+ this._selectLine.userData.edgeInfo = {
2269
+ lines: e,
2270
+ seg: t,
2271
+ mesh: r,
2272
+ aIndices: g,
2273
+ bIndices: b,
2274
+ aEdgeIndices: y,
2275
+ bEdgeIndices: C
2276
+ };
1063
2277
  }
1064
2278
  };
1065
- fe = cs([
1066
- d(),
1067
- Fe(0, l("IRaycastApi")),
1068
- Fe(1, l("EditorStore"))
1069
- ], fe);
1070
- var ls = Object.getOwnPropertyDescriptor, hs = (e, t, r, s) => {
1071
- for (var i = s > 1 ? void 0 : s ? ls(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1072
- (n = e[o]) && (i = n(i) || i);
2279
+ Qe = ui([
2280
+ v(),
2281
+ se(0, c("ISceneApi")),
2282
+ se(1, c("ICameraApi")),
2283
+ se(2, c("IRaycastApi")),
2284
+ se(3, c("EditorStore"))
2285
+ ], Qe);
2286
+ var pi = Object.getOwnPropertyDescriptor, mi = (e, t, r, s) => {
2287
+ for (var i = s > 1 ? void 0 : s ? pi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2288
+ (o = e[n]) && (i = o(i) || i);
1073
2289
  return i;
1074
- }, z = (e, t) => (r, s) => t(r, s, e);
1075
- let Me = class {
2290
+ }, ie = (e, t) => (r, s) => t(r, s, e);
2291
+ let et = class {
1076
2292
  constructor(e, t, r, s) {
1077
- this._cameraApi = e, this._sceneApi = t, this._raycastApi = r, this._store = s, this._cameraApi.enableCameraLayer(x), this._hoverFace = this._makeOverlayFace(this._hoverColor), this._selectFace = this._makeOverlayFace(this._selectColor), this._sceneApi.addObject(this._hoverFace, x), this._sceneApi.addObject(this._selectFace, x);
2293
+ this._cameraApi = e, this._sceneApi = t, this._raycastApi = r, this._store = s, this._cameraApi.enableCameraLayer($), this._hoverFace = Y(this._makeOverlayFace(this._hoverColor)), this._selectFace = Y(this._makeOverlayFace(this._selectColor)), this._sceneApi.addObject(this._hoverFace, $), this._sceneApi.addObject(this._selectFace, $);
1078
2294
  }
1079
2295
  /** Режим, которым управляет хендлер, нужен только менеджеру */
1080
- mode = M.Face;
2296
+ mode = O.Face;
1081
2297
  /** Текущая наведённая грань */
1082
2298
  _hoverFace;
1083
2299
  /** Текущая выбранная грань */
@@ -1092,9 +2308,9 @@ let Me = class {
1092
2308
  _selected = null;
1093
2309
  // Цвета, необходимые для переключения
1094
2310
  /** Цвет грани, на которую навелись */
1095
- _hoverColor = Z;
2311
+ _hoverColor = be;
1096
2312
  /** Цвет выделенной граней */
1097
- _selectColor = q;
2313
+ _selectColor = Me;
1098
2314
  // Погрешности для поиска треугольников и сборки граней
1099
2315
  /** Погрешность на сравнение нормалей */
1100
2316
  _normalEps = 1e-4;
@@ -1102,7 +2318,7 @@ let Me = class {
1102
2318
  _planeEps = 1e-4;
1103
2319
  /** Обработка текущего режима выборки. */
1104
2320
  handle(e, t) {
1105
- if (this._raycastApi.setRaycastMode(this.mode), t === C.Hover) {
2321
+ if (this._raycastApi.setRaycastMode(this.mode), t === R.Hover) {
1106
2322
  if (!e) {
1107
2323
  this._hoverFace.visible = !1, this._hovered = null;
1108
2324
  return;
@@ -1111,12 +2327,12 @@ let Me = class {
1111
2327
  if (!r?.isMesh) return;
1112
2328
  const s = r, i = e.intersection.faceIndex ?? -1;
1113
2329
  if (i < 0) return;
1114
- const o = this._collectFaceGroup(s, i);
1115
- if (!o) return;
1116
- this._selected && this._same(o, this._selected) ? this._hoverFace.visible = !1 : (this._writeWorldFaceGroup(this._hoverFace, o), this._hoverFace.visible = !0), this._hovered = o;
2330
+ const n = this._collectFaceGroup(s, i);
2331
+ if (!n) return;
2332
+ this._selected && this._same(n, this._selected) ? this._hoverFace.visible = !1 : (this._writeWorldFaceGroup(this._hoverFace, n), this._hoverFace.visible = !0), this._hovered = n;
1117
2333
  return;
1118
2334
  }
1119
- if (t === C.Click) {
2335
+ if (t === R.Click) {
1120
2336
  if (!e) {
1121
2337
  this._selectFace.visible = !1, this._selected = null, this._store.setSelectedObject(null);
1122
2338
  return;
@@ -1125,9 +2341,9 @@ let Me = class {
1125
2341
  if (!r?.isMesh) return;
1126
2342
  const s = r, i = e.intersection.faceIndex ?? -1;
1127
2343
  if (i < 0) return;
1128
- const o = this._collectFaceGroup(s, i);
1129
- if (!o) return;
1130
- this._writeWorldFaceGroup(this._selectFace, o), this._centerFaceProxy(this._selectFace), this._selectFace.visible = !0, this._prepareFaceMetadata(o), this._store.setSelectedObject(this._selectFace), this._selected = o, this._hovered && this._same(this._hovered, this._selected) && (this._hoverFace.visible = !1);
2344
+ const n = this._collectFaceGroup(s, i);
2345
+ if (!n) return;
2346
+ this._writeWorldFaceGroup(this._selectFace, n), this._centerFaceProxy(this._selectFace), this._selectFace.visible = !0, this._prepareFaceMetadata(n), this._store.setSelectedObject(this._selectFace), this._selected = n, this._hovered && this._same(this._hovered, this._selected) && (this._hoverFace.visible = !1);
1131
2347
  }
1132
2348
  }
1133
2349
  /** Откат текущего режима выборки */
@@ -1155,7 +2371,7 @@ let Me = class {
1155
2371
  polygonOffsetFactor: -1,
1156
2372
  polygonOffsetUnits: -1
1157
2373
  }), s = new a.Mesh(t, r);
1158
- return s.renderOrder = 1e3, s.layers.set(x), s.visible = !1, s.raycast = () => {
2374
+ return s.renderOrder = 1e3, s.layers.set($), s.visible = !1, s.raycast = () => {
1159
2375
  }, s;
1160
2376
  }
1161
2377
  /**
@@ -1167,56 +2383,56 @@ let Me = class {
1167
2383
  if (!s) return null;
1168
2384
  const i = r.index;
1169
2385
  if (!i) {
1170
- const S = t * 3, w = t * 3 + 1, I = t * 3 + 2;
2386
+ const M = t * 3, I = t * 3 + 1, y = t * 3 + 2;
1171
2387
  return {
1172
2388
  mesh: e,
1173
2389
  faceIndex: t,
1174
2390
  triangleIndices: [t],
1175
- vertexIndices: [S, w, I],
1176
- proxyVertexMap: [S, w, I]
2391
+ vertexIndices: [M, I, y],
2392
+ proxyVertexMap: [M, I, y]
1177
2393
  };
1178
2394
  }
1179
- const o = Math.floor(i.count / 3);
1180
- if (t < 0 || t >= o) return null;
1181
- const n = this._buildTriangleAdjacency(i, s), [c, _, u] = this._getTriangleIndices(i, t), p = this._readVertex(s, c), f = this._readVertex(s, _), g = this._readVertex(s, u), v = new a.Vector3().subVectors(f, p).cross(new a.Vector3().subVectors(g, p)).normalize(), m = new a.Plane().setFromNormalAndCoplanarPoint(v, p), y = /* @__PURE__ */ new Set(), b = [], L = [t];
1182
- for (; L.length > 0; ) {
1183
- const S = L.pop();
1184
- if (y.has(S)) continue;
1185
- y.add(S);
1186
- const [w, I, $] = this._getTriangleIndices(i, S), A = this._readVertex(s, w), Ve = this._readVertex(s, I), $e = this._readVertex(s, $), Ke = new a.Vector3().subVectors(Ve, A).cross(new a.Vector3().subVectors($e, A)).normalize(), Qe = Math.abs(Ke.dot(v)) >= 1 - this._normalEps, Je = Math.abs(m.distanceToPoint(A)) < this._planeEps && Math.abs(m.distanceToPoint(Ve)) < this._planeEps && Math.abs(m.distanceToPoint($e)) < this._planeEps;
1187
- if (!Qe || !Je) continue;
1188
- b.push(S);
1189
- const je = n.get(S);
1190
- if (je)
1191
- for (const He of je)
1192
- y.has(He) || L.push(He);
2395
+ const n = Math.floor(i.count / 3);
2396
+ if (t < 0 || t >= n) return null;
2397
+ const o = this._buildTriangleAdjacency(i, s), [l, h, d] = this._getTriangleIndices(i, t), p = this._readVertex(s, l), u = this._readVertex(s, h), m = this._readVertex(s, d), f = new a.Vector3().subVectors(u, p).cross(new a.Vector3().subVectors(m, p)).normalize(), _ = new a.Plane().setFromNormalAndCoplanarPoint(f, p), g = /* @__PURE__ */ new Set(), b = [], x = [t];
2398
+ for (; x.length > 0; ) {
2399
+ const M = x.pop();
2400
+ if (g.has(M)) continue;
2401
+ g.add(M);
2402
+ const [I, y, C] = this._getTriangleIndices(i, M), A = this._readVertex(s, I), D = this._readVertex(s, y), j = this._readVertex(s, C), F = new a.Vector3().subVectors(D, A).cross(new a.Vector3().subVectors(j, A)).normalize(), Mr = Math.abs(F.dot(f)) >= 1 - this._normalEps, yr = Math.abs(_.distanceToPoint(A)) < this._planeEps && Math.abs(_.distanceToPoint(D)) < this._planeEps && Math.abs(_.distanceToPoint(j)) < this._planeEps;
2403
+ if (!Mr || !yr) continue;
2404
+ b.push(M);
2405
+ const At = o.get(M);
2406
+ if (At)
2407
+ for (const It of At)
2408
+ g.has(It) || x.push(It);
1193
2409
  }
1194
- b.sort((S, w) => S - w);
1195
- const E = /* @__PURE__ */ new Set(), T = [];
1196
- for (const S of b) {
1197
- const [w, I, $] = this._getTriangleIndices(i, S);
1198
- E.add(w), E.add(I), E.add($), T.push(w, I, $);
2410
+ b.sort((M, I) => M - I);
2411
+ const S = /* @__PURE__ */ new Set(), w = [];
2412
+ for (const M of b) {
2413
+ const [I, y, C] = this._getTriangleIndices(i, M);
2414
+ S.add(I), S.add(y), S.add(C), w.push(I, y, C);
1199
2415
  }
1200
2416
  return {
1201
2417
  mesh: e,
1202
2418
  faceIndex: t,
1203
2419
  triangleIndices: b,
1204
- vertexIndices: Array.from(E),
1205
- proxyVertexMap: T
2420
+ vertexIndices: Array.from(S),
2421
+ proxyVertexMap: w
1206
2422
  };
1207
2423
  }
1208
2424
  /** Перезаписывает overlay mesh world-space треугольниками выбранной грани */
1209
2425
  _writeWorldFaceGroup(e, t) {
1210
- const r = t.mesh.geometry, s = r.getAttribute("position"), i = r.index, o = new Float32Array(t.triangleIndices.length * 9);
1211
- let n = 0;
1212
- for (const _ of t.triangleIndices) {
1213
- let u, p, f;
1214
- i ? [u, p, f] = this._getTriangleIndices(i, _) : (u = _ * 3, p = _ * 3 + 1, f = _ * 3 + 2);
1215
- const g = this._readVertex(s, u).applyMatrix4(t.mesh.matrixWorld), v = this._readVertex(s, p).applyMatrix4(t.mesh.matrixWorld), m = this._readVertex(s, f).applyMatrix4(t.mesh.matrixWorld);
1216
- o[n++] = g.x, o[n++] = g.y, o[n++] = g.z, o[n++] = v.x, o[n++] = v.y, o[n++] = v.z, o[n++] = m.x, o[n++] = m.y, o[n++] = m.z;
2426
+ const r = t.mesh.geometry, s = r.getAttribute("position"), i = r.index, n = new Float32Array(t.triangleIndices.length * 9);
2427
+ let o = 0;
2428
+ for (const h of t.triangleIndices) {
2429
+ let d, p, u;
2430
+ i ? [d, p, u] = this._getTriangleIndices(i, h) : (d = h * 3, p = h * 3 + 1, u = h * 3 + 2);
2431
+ const m = this._readVertex(s, d).applyMatrix4(t.mesh.matrixWorld), f = this._readVertex(s, p).applyMatrix4(t.mesh.matrixWorld), _ = this._readVertex(s, u).applyMatrix4(t.mesh.matrixWorld);
2432
+ n[o++] = m.x, n[o++] = m.y, n[o++] = m.z, n[o++] = f.x, n[o++] = f.y, n[o++] = f.z, n[o++] = _.x, n[o++] = _.y, n[o++] = _.z;
1217
2433
  }
1218
- const c = e.geometry;
1219
- c.setAttribute("position", new a.BufferAttribute(o, 3)), c.setIndex(null), c.computeVertexNormals(), c.computeBoundingBox(), c.computeBoundingSphere();
2434
+ const l = e.geometry;
2435
+ l.setAttribute("position", new a.BufferAttribute(n, 3)), l.setIndex(null), l.computeVertexNormals(), l.computeBoundingBox(), l.computeBoundingSphere();
1220
2436
  }
1221
2437
  /** Сравнение двух логических граней */
1222
2438
  _same(e, t) {
@@ -1253,28 +2469,28 @@ let Me = class {
1253
2469
  }
1254
2470
  /** Регистрирует ребро треугольника в edge map */
1255
2471
  _pushEdge(e, t, r, s) {
1256
- const i = t < r ? `${t}_${r}` : `${r}_${t}`, o = e.get(i);
1257
- o ? o.push(s) : e.set(i, [s]);
2472
+ const i = t < r ? `${t}_${r}` : `${r}_${t}`, n = e.get(i);
2473
+ n ? n.push(s) : e.set(i, [s]);
1258
2474
  }
1259
2475
  /** Строит граф соседства треугольников по общим ребрам */
1260
2476
  _buildTriangleAdjacency(e, t) {
1261
2477
  const r = Math.floor(e.count / 3), s = /* @__PURE__ */ new Map(), i = this._buildWeldMap(e, t);
1262
- for (let c = 0; c < r; c++) {
1263
- const [_, u, p] = this._getTriangleIndices(e, c), f = i.get(_), g = i.get(u), v = i.get(p);
1264
- this._pushEdge(s, f, g, c), this._pushEdge(s, g, v, c), this._pushEdge(s, v, f, c);
2478
+ for (let l = 0; l < r; l++) {
2479
+ const [h, d, p] = this._getTriangleIndices(e, l), u = i.get(h), m = i.get(d), f = i.get(p);
2480
+ this._pushEdge(s, u, m, l), this._pushEdge(s, m, f, l), this._pushEdge(s, f, u, l);
1265
2481
  }
1266
- const o = /* @__PURE__ */ new Map();
1267
- for (let c = 0; c < r; c++)
1268
- o.set(c, /* @__PURE__ */ new Set());
1269
- for (const c of s.values())
1270
- if (!(c.length < 2))
1271
- for (let _ = 0; _ < c.length; _++)
1272
- for (let u = 0; u < c.length; u++)
1273
- _ !== u && o.get(c[_])?.add(c[u]);
1274
2482
  const n = /* @__PURE__ */ new Map();
1275
- for (const [c, _] of o)
1276
- n.set(c, Array.from(_));
1277
- return n;
2483
+ for (let l = 0; l < r; l++)
2484
+ n.set(l, /* @__PURE__ */ new Set());
2485
+ for (const l of s.values())
2486
+ if (!(l.length < 2))
2487
+ for (let h = 0; h < l.length; h++)
2488
+ for (let d = 0; d < l.length; d++)
2489
+ h !== d && n.get(l[h])?.add(l[d]);
2490
+ const o = /* @__PURE__ */ new Map();
2491
+ for (const [l, h] of n)
2492
+ o.set(l, Array.from(h));
2493
+ return o;
1278
2494
  }
1279
2495
  /** Возвращает индексы трех вершин треугольника */
1280
2496
  _getTriangleIndices(e, t) {
@@ -1286,8 +2502,8 @@ let Me = class {
1286
2502
  }
1287
2503
  /** Построение ключа вершины по позиции */
1288
2504
  _vertexKey(e, t, r = 1e-6) {
1289
- const s = Math.round(e.getX(t) / r), i = Math.round(e.getY(t) / r), o = Math.round(e.getZ(t) / r);
1290
- return `${s}_${i}_${o}`;
2505
+ const s = Math.round(e.getX(t) / r), i = Math.round(e.getY(t) / r), n = Math.round(e.getZ(t) / r);
2506
+ return `${s}_${i}_${n}`;
1291
2507
  }
1292
2508
  /**
1293
2509
  * Строит отображение исходных индексов вершин в "сваренные" ids по координате.
@@ -1297,12 +2513,12 @@ let Me = class {
1297
2513
  _buildWeldMap(e, t) {
1298
2514
  const r = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
1299
2515
  let i = 0;
1300
- for (let o = 0; o < e.count; o++) {
1301
- const n = e.getX(o);
1302
- if (s.has(n)) continue;
1303
- const c = this._vertexKey(t, n);
1304
- let _ = r.get(c);
1305
- _ == null && (_ = i++, r.set(c, _)), s.set(n, _);
2516
+ for (let n = 0; n < e.count; n++) {
2517
+ const o = e.getX(n);
2518
+ if (s.has(o)) continue;
2519
+ const l = this._vertexKey(t, o);
2520
+ let h = r.get(l);
2521
+ h == null && (h = i++, r.set(l, h)), s.set(o, h);
1306
2522
  }
1307
2523
  return s;
1308
2524
  }
@@ -1311,26 +2527,26 @@ let Me = class {
1311
2527
  e.position.set(0, 0, 0), e.quaternion.identity(), e.scale.set(1, 1, 1), e.updateMatrixWorld(!0);
1312
2528
  }
1313
2529
  _buildFaceVertexGroups(e) {
1314
- const r = e.mesh.geometry.getAttribute("position"), s = 1e-6, i = new a.Vector3(), o = e.vertexIndices, n = [], c = /* @__PURE__ */ new Map();
1315
- for (const g of o) {
1316
- const v = this._readVertex(r, g), m = [];
2530
+ const r = e.mesh.geometry.getAttribute("position"), s = 1e-6, i = new a.Vector3(), n = e.vertexIndices, o = [], l = /* @__PURE__ */ new Map();
2531
+ for (const m of n) {
2532
+ const f = this._readVertex(r, m), _ = [];
1317
2533
  for (let b = 0; b < r.count; b++)
1318
- i.fromBufferAttribute(r, b), i.distanceToSquared(v) < s * s && m.push(b);
1319
- const y = n.length;
1320
- n.push(m);
1321
- for (const b of m)
1322
- c.set(b, y);
2534
+ i.fromBufferAttribute(r, b), i.distanceToSquared(f) < s * s && _.push(b);
2535
+ const g = o.length;
2536
+ o.push(_);
2537
+ for (const b of _)
2538
+ l.set(b, g);
1323
2539
  }
1324
- const _ = [];
1325
- for (const g of e.proxyVertexMap) {
1326
- const v = c.get(g);
1327
- _.push(v ?? -1);
2540
+ const h = [];
2541
+ for (const m of e.proxyVertexMap) {
2542
+ const f = l.get(m);
2543
+ h.push(f ?? -1);
1328
2544
  }
1329
- const u = this._findChildLines(e.mesh), p = u ? this._buildLineVertexGroups(e, u) : void 0, f = {
1330
- vertexIndexGroups: n,
1331
- proxyVertexMap: _
2545
+ const d = this._findChildLines(e.mesh), p = d ? this._buildLineVertexGroups(e, d) : void 0, u = {
2546
+ vertexIndexGroups: o,
2547
+ proxyVertexMap: h
1332
2548
  };
1333
- return u && (f.lines = u), p && (f.lineVertexIndexGroups = p), f;
2549
+ return d && (u.lines = d), p && (u.lineVertexIndexGroups = p), u;
1334
2550
  }
1335
2551
  _findChildLines(e) {
1336
2552
  for (const t of e.children)
@@ -1339,123 +2555,115 @@ let Me = class {
1339
2555
  return null;
1340
2556
  }
1341
2557
  _buildLineVertexGroups(e, t) {
1342
- const s = t.geometry.getAttribute("position"), o = e.mesh.geometry.getAttribute("position"), n = 1e-6, c = new a.Vector3(), _ = t.matrixWorld, u = e.mesh.matrixWorld, p = [];
1343
- for (const f of e.vertexIndices) {
1344
- const g = this._readVertex(o, f).applyMatrix4(u), v = [];
1345
- for (let m = 0; m < s.count; m++)
1346
- c.fromBufferAttribute(s, m).applyMatrix4(_), c.distanceToSquared(g) < n * n && v.push(m);
1347
- p.push(v);
2558
+ const s = t.geometry.getAttribute("position"), n = e.mesh.geometry.getAttribute("position"), o = 1e-6, l = new a.Vector3(), h = t.matrixWorld, d = e.mesh.matrixWorld, p = [];
2559
+ for (const u of e.vertexIndices) {
2560
+ const m = this._readVertex(n, u).applyMatrix4(d), f = [];
2561
+ for (let _ = 0; _ < s.count; _++)
2562
+ l.fromBufferAttribute(s, _).applyMatrix4(h), l.distanceToSquared(m) < o * o && f.push(_);
2563
+ p.push(f);
1348
2564
  }
1349
2565
  return p;
1350
2566
  }
1351
2567
  };
1352
- Me = hs([
1353
- d(),
1354
- z(0, l("ICameraApi")),
1355
- z(1, l("ISceneApi")),
1356
- z(2, l("IRaycastApi")),
1357
- z(3, l("EditorStore"))
1358
- ], Me);
1359
- const _s = {
1360
- /**
1361
- * Плоскость (PlaneGeometry)
1362
- * @returns Плоскость размером 1x1 с одной сегментацией
1363
- */
1364
- [O.Plane]: () => new a.PlaneGeometry(1, 1, 1, 1),
1365
- /**
1366
- * Куб (BoxGeometry)
1367
- * @returns Куб размером 1x1x1 с одной сегментацией по каждой оси
1368
- */
1369
- [O.Cube]: () => new a.BoxGeometry(1, 1, 1, 1, 1, 1),
1370
- /**
1371
- * Ультра-сфера (SphereGeometry) с гладкой поверхностью
1372
- * @returns Сфера радиусом 0.5, 32 сегмента по ширине, 16 по высоте
1373
- */
1374
- [O.UVSphere]: () => new a.SphereGeometry(0.5, 32, 16),
1375
- /**
1376
- * Икосфера (IcosahedronGeometry) — сфера из треугольников
1377
- * @returns Икосфера радиусом 0.5, уровень детализации 0
1378
- */
1379
- [O.Icosphere]: () => new a.IcosahedronGeometry(0.5, 0),
1380
- /**
1381
- * Цилиндр (CylinderGeometry)
1382
- * @returns Цилиндр радиусом 0.5, высотой 1, 32 сегмента
1383
- */
1384
- [O.Cylinder]: () => new a.CylinderGeometry(0.5, 0.5, 1, 32, 1, !1),
1385
- /**
1386
- * Конус (ConeGeometry)
1387
- * @returns Конус радиусом 0.5, высотой 1, 32 сегмента
1388
- */
1389
- [O.Cone]: () => new a.ConeGeometry(0.5, 1, 32, 1, !1),
1390
- /**
1391
- * Тор (TorusGeometry)
1392
- * @returns Тор радиусом 0.5, толщиной 0.2, 16 сегментов по радиусу, 64 по трубке
1393
- */
1394
- [O.Torus]: () => new a.TorusGeometry(0.5, 0.2, 16, 64),
1395
- /**
1396
- * Круг (CircleGeometry)
1397
- * @returns Круг радиусом 0.5, 32 сегмента
1398
- */
1399
- [O.Circle]: () => new a.CircleGeometry(0.5, 32),
2568
+ et = mi([
2569
+ v(),
2570
+ ie(0, c("ICameraApi")),
2571
+ ie(1, c("ISceneApi")),
2572
+ ie(2, c("IRaycastApi")),
2573
+ ie(3, c("EditorStore"))
2574
+ ], et);
2575
+ var fi = Object.getOwnPropertyDescriptor, gi = (e, t, r, s) => {
2576
+ for (var i = s > 1 ? void 0 : s ? fi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2577
+ (o = e[n]) && (i = o(i) || i);
2578
+ return i;
2579
+ }, Ft = (e, t) => (r, s) => t(r, s, e);
2580
+ let tt = class {
2581
+ constructor(e, t) {
2582
+ this._api = e, this._store = t;
2583
+ }
2584
+ /** Режим, которым управляет хендлер, нужен только менеджеру */
2585
+ mode = O.Mesh;
2586
+ /** Фигура, на которую навелись в данный момент */
2587
+ _hoveredMesh = null;
2588
+ /** Фигура, которую выбрали в данный момент */
2589
+ _selectedMesh = null;
2590
+ // Цвета, необходимые для переключения
2591
+ /** Цвет ребер для фигуры, на которую навелись */
2592
+ _hoverColor = be;
2593
+ /** Цвет ребер для выделенной фигуры */
2594
+ _selectColor = Me;
2595
+ /** Исходные цвета материалов линий для отката */
2596
+ _origLineColors = /* @__PURE__ */ new WeakMap();
2597
+ handle(e, t) {
2598
+ if (this._api.setRaycastMode(this.mode), t === R.Hover) {
2599
+ if (!e) {
2600
+ this._hoveredMesh && this._hoveredMesh !== this._selectedMesh && this._restoreEdgesColor(this._hoveredMesh), this._hoveredMesh = null;
2601
+ return;
2602
+ }
2603
+ const r = e.intersection.object;
2604
+ this._hoveredMesh !== r && (this._hoveredMesh && this._hoveredMesh !== this._selectedMesh && this._restoreEdgesColor(this._hoveredMesh), r !== this._selectedMesh && this._paintEdges(r, this._hoverColor), this._hoveredMesh = r);
2605
+ }
2606
+ if (t === R.Click) {
2607
+ if (!e) {
2608
+ this._selectedMesh && (this._restoreEdgesColor(this._selectedMesh), this._selectedMesh = null, this._store.setSelectedObject(null));
2609
+ return;
2610
+ }
2611
+ const r = e.intersection.object;
2612
+ this._selectedMesh && this._selectedMesh !== r && this._restoreEdgesColor(this._selectedMesh), this._paintEdges(r, this._selectColor), this._selectedMesh = r, this._store.setSelectedObject(r);
2613
+ }
2614
+ }
2615
+ rollback() {
2616
+ this._hoveredMesh && this._restoreEdgesColor(this._hoveredMesh), this._selectedMesh && this._restoreEdgesColor(this._selectedMesh), this._hoveredMesh = this._selectedMesh = null, this._store.setSelectedObject(null);
2617
+ }
2618
+ /** Освобождает ресурсы хендлера, удаляет слушатели и очищает внутренние данные. */
2619
+ dispose() {
2620
+ this.rollback();
2621
+ }
1400
2622
  /**
1401
- * Сфера (SphereGeometry) алиас для UVSphere
1402
- * @returns Сфера радиусом 0.5, 32 сегмента по ширине, 16 по высоте
2623
+ * Перекрасить рёбра меша и запомнить оригинальный цвет (один раз на LineSegments).
1403
2624
  */
1404
- [O.Sphere]: () => new a.SphereGeometry(0.5, 32, 16),
2625
+ _paintEdges(e, t) {
2626
+ e.children.forEach((r) => {
2627
+ const s = r;
2628
+ if (s.isLineSegments && s.material) {
2629
+ const i = s.material;
2630
+ this._origLineColors.has(s) || this._origLineColors.set(s, i.color.clone()), i.color.setHex(t), i.needsUpdate = !0;
2631
+ }
2632
+ });
2633
+ }
1405
2634
  /**
1406
- * Кастомная геометрия (не реализовано в фабрике)
1407
- * @throws {Error} Всегда выбрасывает ошибку
2635
+ * Восстановить исходный цвет рёбер меша из WeakMap.
2636
+ * Если исходный цвет не сохранён (на всякий случай) — ничего не меняем.
1408
2637
  */
1409
- [O.Custom]: function() {
1410
- throw new Error("Custom geometry is not generated here.");
1411
- }
1412
- }, ds = new a.MeshStandardMaterial({
1413
- color: 12566463,
1414
- metalness: 0,
1415
- roughness: 0.6
1416
- }), us = 8, ps = (e) => !!e && e.isMesh, Ze = (e) => {
1417
- let t = e;
1418
- for (; t; ) {
1419
- if (t.isMesh) return t;
1420
- t = t.parent;
2638
+ _restoreEdgesColor(e) {
2639
+ e.children.forEach((t) => {
2640
+ const r = t;
2641
+ if (r.isLineSegments && r.material) {
2642
+ const s = this._origLineColors.get(r);
2643
+ if (s) {
2644
+ const i = r.material;
2645
+ i.color.copy(s), i.needsUpdate = !0;
2646
+ }
2647
+ }
2648
+ });
1421
2649
  }
1422
- return null;
1423
- }, ms = (e) => {
1424
- const t = new a.BufferGeometry();
1425
- t.setAttribute("position", e.getAttribute("position")), t.computeBoundingSphere(), t.computeBoundingBox();
1426
- const r = new a.PointsMaterial({
1427
- color: ns,
1428
- size: 6,
1429
- sizeAttenuation: !1,
1430
- depthTest: !1,
1431
- depthWrite: !1,
1432
- transparent: !0,
1433
- opacity: 0.9
1434
- }), s = new a.Points(t, r);
1435
- return s.layers.set(Xe), s.renderOrder = 1e3, s.visible = !1, s;
1436
- }, gs = (e) => {
1437
- const t = new a.EdgesGeometry(e), r = new a.LineSegments(
1438
- t,
1439
- new a.LineBasicMaterial({ color: os, linewidth: 1 })
1440
- );
1441
- return r.layers.set(Ue), r;
1442
- }, vs = (e) => {
1443
- const t = { x: e.position.x, y: e.position.y, z: e.position.z }, r = { x: e.rotation.x, y: e.rotation.y, z: e.rotation.z }, s = { x: e.scale.x, y: e.scale.y, z: e.scale.z }, i = new a.Box3().setFromObject(e), o = new a.Vector3();
1444
- i.getSize(o);
1445
- const n = { x: o.x, y: o.y, z: o.z };
1446
- return { position: t, rotation: r, scale: s, size: n };
1447
2650
  };
1448
- var fs = Object.getOwnPropertyDescriptor, Ms = (e, t, r, s) => {
1449
- for (var i = s > 1 ? void 0 : s ? fs(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1450
- (n = e[o]) && (i = n(i) || i);
2651
+ tt = gi([
2652
+ v(),
2653
+ Ft(0, c("IRaycastApi")),
2654
+ Ft(1, c("EditorStore"))
2655
+ ], tt);
2656
+ var vi = Object.getOwnPropertyDescriptor, bi = (e, t, r, s) => {
2657
+ for (var i = s > 1 ? void 0 : s ? vi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2658
+ (o = e[n]) && (i = o(i) || i);
1451
2659
  return i;
1452
- }, N = (e, t) => (r, s) => t(r, s, e);
1453
- let ye = class {
2660
+ }, ne = (e, t) => (r, s) => t(r, s, e);
2661
+ let rt = class {
1454
2662
  constructor(e, t, r, s) {
1455
- this._cameraApi = e, this._sceneApi = t, this._raycastApi = r, this._store = s, this._cameraApi.enableCameraLayer(x), this._hoverVertex = this._makeOverlayVertex(this._hoverColor), this._selectVertex = this._makeOverlayVertex(this._selectColor), this._sceneApi.addObject(this._hoverVertex, x), this._sceneApi.addObject(this._selectVertex, x);
2663
+ this._cameraApi = e, this._sceneApi = t, this._raycastApi = r, this._store = s, this._cameraApi.enableCameraLayer($), this._hoverVertex = Y(this._makeOverlayVertex(this._hoverColor)), this._selectVertex = Y(this._makeOverlayVertex(this._selectColor)), this._sceneApi.addObject(this._hoverVertex, $), this._sceneApi.addObject(this._selectVertex, $);
1456
2664
  }
1457
2665
  /** Режим, которым управляет хендлер, нужен только менеджеру */
1458
- mode = M.Vertex;
2666
+ mode = O.Vertex;
1459
2667
  _hovered = null;
1460
2668
  _selected = null;
1461
2669
  /** Текущая наведённая вершина. */
@@ -1464,11 +2672,11 @@ let ye = class {
1464
2672
  _selectVertex;
1465
2673
  // Цвета, необходимые для переключения
1466
2674
  /** Цвет ребра, на которое навелись */
1467
- _hoverColor = Z;
2675
+ _hoverColor = be;
1468
2676
  /** Цвет выделенного ребра */
1469
- _selectColor = q;
2677
+ _selectColor = Me;
1470
2678
  handle(e, t) {
1471
- if (this._raycastApi.setRaycastMode(this.mode), t === C.Hover) {
2679
+ if (this._raycastApi.setRaycastMode(this.mode), t === R.Hover) {
1472
2680
  if (!e) {
1473
2681
  this._hoverVertex.visible = !1, this._hovered = null;
1474
2682
  return;
@@ -1480,7 +2688,7 @@ let ye = class {
1480
2688
  this._selected && this._same({ points: s, index: i }, this._selected) ? this._hoverVertex.visible = !1 : (this._writeWorldVertex(this._hoverVertex, s, i), this._hoverVertex.visible = !0);
1481
2689
  return;
1482
2690
  }
1483
- if (t === C.Click) {
2691
+ if (t === R.Click) {
1484
2692
  if (!e) {
1485
2693
  this._selectVertex.visible = !1, this._selected = null, this._store.setSelectedObject(null);
1486
2694
  return;
@@ -1499,7 +2707,7 @@ let ye = class {
1499
2707
  dispose() {
1500
2708
  this.rollback(), this._sceneApi.removeFromScene(this._hoverVertex), this._sceneApi.removeFromScene(this._selectVertex), this._hoverVertex.geometry.dispose(), this._hoverVertex.material.dispose(), this._selectVertex.geometry.dispose(), this._selectVertex.material.dispose();
1501
2709
  }
1502
- _makeOverlayVertex(e, t = us) {
2710
+ _makeOverlayVertex(e, t = Xr) {
1503
2711
  const r = new a.BufferGeometry();
1504
2712
  r.setAttribute("position", new a.Float32BufferAttribute([0, 0, 0], 3));
1505
2713
  const s = new a.PointsMaterial({
@@ -1512,7 +2720,7 @@ let ye = class {
1512
2720
  opacity: 1
1513
2721
  }), i = new a.Points(r, s);
1514
2722
  return i.renderOrder = 1e3, i.raycast = () => {
1515
- }, i.layers.set(x), i.visible = !1, i;
2723
+ }, i.layers.set($), i.visible = !1, i;
1516
2724
  }
1517
2725
  /** Локальную вершину points переводим в world и пишем в target (прокси-точку) */
1518
2726
  _writeWorldVertex(e, t, r) {
@@ -1520,37 +2728,37 @@ let ye = class {
1520
2728
  s.getX(r),
1521
2729
  s.getY(r),
1522
2730
  s.getZ(r)
1523
- ).applyMatrix4(t.matrixWorld), o = e.geometry.getAttribute("position");
1524
- o.setXYZ(0, i.x, i.y, i.z), o.needsUpdate = !0;
2731
+ ).applyMatrix4(t.matrixWorld), n = e.geometry.getAttribute("position");
2732
+ n.setXYZ(0, i.x, i.y, i.z), n.needsUpdate = !0;
1525
2733
  }
1526
2734
  _same(e, t) {
1527
2735
  return !!e && !!t && e.points === t.points && e.index === t.index;
1528
2736
  }
1529
2737
  /** Готовит метаданные для выбранной вершины и пишет их в _selectVertex.userData */
1530
2738
  _prepareVertexMetadata(e, t) {
1531
- const r = Ze(e);
2739
+ const r = er(e);
1532
2740
  if (!r) return;
1533
2741
  const s = e.geometry.getAttribute("position"), i = new a.Vector3(
1534
2742
  s.getX(t),
1535
2743
  s.getY(t),
1536
2744
  s.getZ(t)
1537
- ).applyMatrix4(e.matrixWorld), o = new a.Matrix4().copy(r.matrixWorld).invert(), n = i.clone().applyMatrix4(o), _ = r.geometry.getAttribute("position"), u = 1e-6, p = u * u, f = new a.Vector3(), g = [];
1538
- for (let y = 0; y < _.count; y++)
1539
- f.fromBufferAttribute(_, y), f.distanceToSquared(n) < p && g.push(y);
1540
- const v = r.children.find((y) => y?.isLineSegments);
1541
- let m = [];
1542
- if (v) {
1543
- const y = new a.Matrix4().copy(v.matrixWorld).invert(), b = i.clone().applyMatrix4(y), L = v.geometry.getAttribute("position"), E = new a.Vector3();
1544
- for (let T = 0; T < L.count; T++)
1545
- E.fromBufferAttribute(L, T), E.distanceToSquared(b) < p && m.push(T);
2745
+ ).applyMatrix4(e.matrixWorld), n = new a.Matrix4().copy(r.matrixWorld).invert(), o = i.clone().applyMatrix4(n), h = r.geometry.getAttribute("position"), d = 1e-6, p = d * d, u = new a.Vector3(), m = [];
2746
+ for (let g = 0; g < h.count; g++)
2747
+ u.fromBufferAttribute(h, g), u.distanceToSquared(o) < p && m.push(g);
2748
+ const f = r.children.find((g) => g?.isLineSegments);
2749
+ let _ = [];
2750
+ if (f) {
2751
+ const g = new a.Matrix4().copy(f.matrixWorld).invert(), b = i.clone().applyMatrix4(g), x = f.geometry.getAttribute("position"), S = new a.Vector3();
2752
+ for (let w = 0; w < x.count; w++)
2753
+ S.fromBufferAttribute(x, w), S.distanceToSquared(b) < p && _.push(w);
1546
2754
  }
1547
2755
  this._selectVertex.userData.vertexInfo = {
1548
2756
  points: e,
1549
2757
  index: t,
1550
2758
  mesh: r,
1551
- vertexIndices: g,
1552
- lines: v ?? null,
1553
- edgeVertexIndices: m
2759
+ vertexIndices: m,
2760
+ lines: f ?? null,
2761
+ edgeVertexIndices: _
1554
2762
  };
1555
2763
  }
1556
2764
  /** Центрует прокси-вершину на выбранной точке */
@@ -1561,19 +2769,19 @@ let ye = class {
1561
2769
  s.getZ(r)
1562
2770
  ).applyMatrix4(t.matrixWorld);
1563
2771
  e.position.copy(i);
1564
- const o = e.geometry;
1565
- let n = o.getAttribute("position");
1566
- (!n || n.count < 1) && (o.setAttribute("position", new a.BufferAttribute(new Float32Array(3), 3)), n = o.getAttribute("position")), n.setXYZ(0, 0, 0, 0), n.needsUpdate = !0, e.quaternion.identity(), e.scale.set(1, 1, 1), e.updateMatrixWorld(!0);
2772
+ const n = e.geometry;
2773
+ let o = n.getAttribute("position");
2774
+ (!o || o.count < 1) && (n.setAttribute("position", new a.BufferAttribute(new Float32Array(3), 3)), o = n.getAttribute("position")), o.setXYZ(0, 0, 0, 0), o.needsUpdate = !0, e.quaternion.identity(), e.scale.set(1, 1, 1), e.updateMatrixWorld(!0);
1567
2775
  }
1568
2776
  };
1569
- ye = Ms([
1570
- d(),
1571
- N(0, l("ICameraApi")),
1572
- N(1, l("ISceneApi")),
1573
- N(2, l("IRaycastApi")),
1574
- N(3, l("EditorStore"))
1575
- ], ye);
1576
- class De {
2777
+ rt = bi([
2778
+ v(),
2779
+ ne(0, c("ICameraApi")),
2780
+ ne(1, c("ISceneApi")),
2781
+ ne(2, c("IRaycastApi")),
2782
+ ne(3, c("EditorStore"))
2783
+ ], rt);
2784
+ class wt {
1577
2785
  constructor(t, r) {
1578
2786
  this.api = t, this.store = r, this._unsubscribeTransform = this.api.onTransformChange(() => {
1579
2787
  this.store.getSelectedObject() && this.store.notifySelectedTransformChange?.();
@@ -1600,268 +2808,557 @@ class De {
1600
2808
  this.rollback(), this._unsubscribeTransform && this._unsubscribeTransform();
1601
2809
  }
1602
2810
  }
1603
- var ys = Object.getOwnPropertyDescriptor, bs = (e, t, r, s) => {
1604
- for (var i = s > 1 ? void 0 : s ? ys(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1605
- (n = e[o]) && (i = n(i) || i);
2811
+ var Mi = Object.getOwnPropertyDescriptor, yi = (e, t, r, s) => {
2812
+ for (var i = s > 1 ? void 0 : s ? Mi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2813
+ (o = e[n]) && (i = o(i) || i);
1606
2814
  return i;
1607
- }, We = (e, t) => (r, s) => t(r, s, e);
1608
- let be = class extends De {
2815
+ }, kt = (e, t) => (r, s) => t(r, s, e);
2816
+ let st = class extends wt {
1609
2817
  /** Инструмент, которым управляет хендлер, нужен только менеджеру */
1610
- mode = j.Translate;
2818
+ mode = W.Rotate;
1611
2819
  constructor(e, t) {
1612
2820
  super(e, t);
1613
2821
  }
1614
2822
  };
1615
- be = bs([
1616
- d(),
1617
- We(0, l("ITransformApi")),
1618
- We(1, l("EditorStore"))
1619
- ], be);
1620
- var Ss = Object.getOwnPropertyDescriptor, As = (e, t, r, s) => {
1621
- for (var i = s > 1 ? void 0 : s ? Ss(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1622
- (n = e[o]) && (i = n(i) || i);
2823
+ st = yi([
2824
+ v(),
2825
+ kt(0, c("ITransformApi")),
2826
+ kt(1, c("EditorStore"))
2827
+ ], st);
2828
+ var wi = Object.getOwnPropertyDescriptor, Si = (e, t, r, s) => {
2829
+ for (var i = s > 1 ? void 0 : s ? wi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2830
+ (o = e[n]) && (i = o(i) || i);
1623
2831
  return i;
1624
- }, ke = (e, t) => (r, s) => t(r, s, e);
1625
- let Se = class extends De {
2832
+ }, Gt = (e, t) => (r, s) => t(r, s, e);
2833
+ let it = class extends wt {
1626
2834
  /** Инструмент, которым управляет хендлер, нужен только менеджеру */
1627
- mode = j.Scale;
2835
+ mode = W.Scale;
1628
2836
  constructor(e, t) {
1629
2837
  super(e, t);
1630
2838
  }
1631
2839
  };
1632
- Se = As([
1633
- d(),
1634
- ke(0, l("ITransformApi")),
1635
- ke(1, l("EditorStore"))
1636
- ], Se);
1637
- var ws = Object.getOwnPropertyDescriptor, xs = (e, t, r, s) => {
1638
- for (var i = s > 1 ? void 0 : s ? ws(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1639
- (n = e[o]) && (i = n(i) || i);
2840
+ it = Si([
2841
+ v(),
2842
+ Gt(0, c("ITransformApi")),
2843
+ Gt(1, c("EditorStore"))
2844
+ ], it);
2845
+ var xi = Object.getOwnPropertyDescriptor, Ai = (e, t, r, s) => {
2846
+ for (var i = s > 1 ? void 0 : s ? xi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2847
+ (o = e[n]) && (i = o(i) || i);
1640
2848
  return i;
1641
- }, Ge = (e, t) => (r, s) => t(r, s, e);
1642
- let Ae = class extends De {
2849
+ }, zt = (e, t) => (r, s) => t(r, s, e);
2850
+ let nt = class extends wt {
1643
2851
  /** Инструмент, которым управляет хендлер, нужен только менеджеру */
1644
- mode = j.Rotate;
2852
+ mode = W.Translate;
1645
2853
  constructor(e, t) {
1646
2854
  super(e, t);
1647
2855
  }
1648
2856
  };
1649
- Ae = xs([
1650
- d(),
1651
- Ge(0, l("ITransformApi")),
1652
- Ge(1, l("EditorStore"))
1653
- ], Ae);
1654
- var Os = Object.getOwnPropertyDescriptor, Cs = (e, t, r, s) => {
1655
- for (var i = s > 1 ? void 0 : s ? Os(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1656
- (n = e[o]) && (i = n(i) || i);
2857
+ nt = Ai([
2858
+ v(),
2859
+ zt(0, c("ITransformApi")),
2860
+ zt(1, c("EditorStore"))
2861
+ ], nt);
2862
+ var Ii = Object.getOwnPropertyDescriptor, Ci = (e, t, r, s) => {
2863
+ for (var i = s > 1 ? void 0 : s ? Ii(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2864
+ (o = e[n]) && (i = o(i) || i);
1657
2865
  return i;
1658
- }, U = (e, t) => (r, s) => t(r, s, e);
1659
- let we = class {
1660
- constructor(e, t, r, s) {
1661
- this._sceneApi = e, this._cameraApi = t, this._raycastApi = r, this._store = s, this._cameraApi.enableCameraLayer(x), this._hoverLine = this._makeOverlayLine(this._hoverColor), this._selectLine = this._makeOverlayLine(this._selectColor), this._sceneApi.addObject(this._hoverLine, x), this._sceneApi.addObject(this._selectLine, x);
2866
+ }, Oi = (e, t) => (r, s) => t(r, s, e);
2867
+ let ge = class {
2868
+ constructor(e) {
2869
+ this._api = e;
1662
2870
  }
1663
- /** Режим, которым управляет хендлер, нужен только менеджеру */
1664
- mode = M.Edge;
1665
- /** Текущее наведённое ребро. */
1666
- _hoverLine;
1667
- /** Текущее выбранное ребро. */
1668
- _selectLine;
1669
- /** Текущее наведённое ребро из массива `LineSegments` модели. */
1670
- _hovered = null;
1671
- /** Текущее выбранное ребро из массива `LineSegments` модели. */
1672
- _selected = null;
1673
- // Цвета, необходимые для переключения
1674
- /** Цвет ребра, на которое навелись */
1675
- _hoverColor = Z;
1676
- /** Цвет выделенного ребра */
1677
- _selectColor = q;
1678
- /** Обработка текущего режима выборки. */
1679
- handle(e, t) {
1680
- if (this._raycastApi.setRaycastMode(this.mode), t === C.Hover) {
1681
- if (!e) {
1682
- this._hoverLine.visible = !1, this._hovered = null;
1683
- return;
2871
+ /** Режим редактирования сцены */
2872
+ mode = T.AddFigure;
2873
+ /** Последняя добавленная фигура, нужно для отката через `ctrl + z`. */
2874
+ _lastAddedMesh = null;
2875
+ /** Добавление базовых фигур на сцену, которые приписаны в `FigureType`. */
2876
+ handle(e) {
2877
+ const t = Ur[e](), r = t.getAttribute("position");
2878
+ r && r.setUsage && r.setUsage(a.DynamicDrawUsage);
2879
+ const s = new a.Mesh(t, Zt.clone());
2880
+ s.layers.enable(k);
2881
+ const i = t.index ? t.toNonIndexed() : t, n = N(rr(i));
2882
+ n.layers.enable(k), s.add(n);
2883
+ const o = N(tr(i));
2884
+ o.layers.enable(k), s.add(o), this._api.addMesh(s), this._lastAddedMesh = s;
2885
+ }
2886
+ /** Срабатывает только на `ctrl + z`. */
2887
+ rollback() {
2888
+ this._lastAddedMesh !== null && (this._api.removeMesh(this._lastAddedMesh), this._lastAddedMesh = null);
2889
+ }
2890
+ /** Освобождает ресурсы хендлера. */
2891
+ dispose() {
2892
+ this._lastAddedMesh = null;
2893
+ }
2894
+ };
2895
+ ge = Ci([
2896
+ v(),
2897
+ Oi(0, c("IMeshApi"))
2898
+ ], ge);
2899
+ var Ei = Object.getOwnPropertyDescriptor, Pi = (e, t, r, s) => {
2900
+ for (var i = s > 1 ? void 0 : s ? Ei(t, r) : t, n = e.length - 1, o; n >= 0; n--)
2901
+ (o = e[n]) && (i = o(i) || i);
2902
+ return i;
2903
+ }, Wt = (e, t) => (r, s) => t(r, s, e);
2904
+ let ot = class {
2905
+ constructor(e, t) {
2906
+ this._api = e, this._store = t;
2907
+ }
2908
+ /** Режим редактирования сцены */
2909
+ mode = T.DeleteFigure;
2910
+ /** Последняя удаленная фигура, сохраняем для отката через `ctrl + z` */
2911
+ _lastDeletedMesh = null;
2912
+ handle() {
2913
+ const e = this._store.getSelectedObject();
2914
+ yt(e) && !sr(e) && (this._api.removeMesh(e), this._store.setSelectedObject(null), this._lastDeletedMesh = e);
2915
+ }
2916
+ /** Срабатывает только на `ctrl + z`. */
2917
+ rollback() {
2918
+ this._lastDeletedMesh && (this._api.addMesh(this._lastDeletedMesh), this._lastDeletedMesh = null);
2919
+ }
2920
+ /** Освобождает ресурсы хендлера. */
2921
+ dispose() {
2922
+ this._lastDeletedMesh = null;
2923
+ }
2924
+ };
2925
+ ot = Pi([
2926
+ v(),
2927
+ Wt(0, c("IMeshApi")),
2928
+ Wt(1, c("EditorStore"))
2929
+ ], ot);
2930
+ class Li {
2931
+ /**
2932
+ * Parses the given 3D object and generates the OBJ output.
2933
+ *
2934
+ * If the 3D object is composed of multiple children and geometry, they are merged into a single mesh in the file.
2935
+ *
2936
+ * @param {Object3D} object - The 3D object to export.
2937
+ * @return {string} The exported OBJ.
2938
+ */
2939
+ parse(t) {
2940
+ let r = "", s = 0, i = 0, n = 0;
2941
+ const o = new z(), l = new Kt(), h = new z(), d = new Ir(), p = [];
2942
+ function u(_) {
2943
+ let g = 0, b = 0, x = 0;
2944
+ const S = _.geometry, w = new Cr(), M = S.getAttribute("position"), I = S.getAttribute("normal"), y = S.getAttribute("uv"), C = S.getIndex();
2945
+ if (r += "o " + _.name + `
2946
+ `, _.material && _.material.name && (r += "usemtl " + _.material.name + `
2947
+ `), M !== void 0)
2948
+ for (let A = 0, D = M.count; A < D; A++, g++)
2949
+ o.fromBufferAttribute(M, A), o.applyMatrix4(_.matrixWorld), r += "v " + o.x + " " + o.y + " " + o.z + `
2950
+ `;
2951
+ if (y !== void 0)
2952
+ for (let A = 0, D = y.count; A < D; A++, x++)
2953
+ d.fromBufferAttribute(y, A), r += "vt " + d.x + " " + d.y + `
2954
+ `;
2955
+ if (I !== void 0) {
2956
+ w.getNormalMatrix(_.matrixWorld);
2957
+ for (let A = 0, D = I.count; A < D; A++, b++)
2958
+ h.fromBufferAttribute(I, A), h.applyMatrix3(w).normalize(), r += "vn " + h.x + " " + h.y + " " + h.z + `
2959
+ `;
1684
2960
  }
1685
- const r = e.intersection.object;
1686
- if (!r?.isLineSegments) return;
1687
- const s = r, i = Math.floor((e.intersection.index ?? -1) / 2);
1688
- if (i < 0) return;
1689
- this._selected && this._same({ lines: s, seg: i }, this._selected) ? this._hoverLine.visible = !1 : (this._writeWorldSegment(this._hoverLine, s, i), this._hoverLine.visible = !0), this._hovered = { lines: s, seg: i };
1690
- return;
2961
+ if (C !== null)
2962
+ for (let A = 0, D = C.count; A < D; A += 3) {
2963
+ for (let j = 0; j < 3; j++) {
2964
+ const F = C.getX(A + j) + 1;
2965
+ p[j] = s + F + (I || y ? "/" + (y ? i + F : "") + (I ? "/" + (n + F) : "") : "");
2966
+ }
2967
+ r += "f " + p.join(" ") + `
2968
+ `;
2969
+ }
2970
+ else
2971
+ for (let A = 0, D = M.count; A < D; A += 3) {
2972
+ for (let j = 0; j < 3; j++) {
2973
+ const F = A + j + 1;
2974
+ p[j] = s + F + (I || y ? "/" + (y ? i + F : "") + (I ? "/" + (n + F) : "") : "");
2975
+ }
2976
+ r += "f " + p.join(" ") + `
2977
+ `;
2978
+ }
2979
+ s += g, i += x, n += b;
1691
2980
  }
1692
- if (t === C.Click) {
1693
- if (!e) {
1694
- this._selectLine.visible = !1, this._selected = null, this._store.setSelectedObject(null);
1695
- return;
2981
+ function m(_) {
2982
+ let g = 0;
2983
+ const b = _.geometry, x = _.type, S = b.getAttribute("position");
2984
+ if (r += "o " + _.name + `
2985
+ `, S !== void 0)
2986
+ for (let w = 0, M = S.count; w < M; w++, g++)
2987
+ o.fromBufferAttribute(S, w), o.applyMatrix4(_.matrixWorld), r += "v " + o.x + " " + o.y + " " + o.z + `
2988
+ `;
2989
+ if (x === "Line") {
2990
+ r += "l ";
2991
+ for (let w = 1, M = S.count; w <= M; w++)
2992
+ r += s + w + " ";
2993
+ r += `
2994
+ `;
1696
2995
  }
1697
- const r = e.intersection.object;
1698
- if (!r?.isLineSegments) return;
1699
- const s = r, i = Math.floor((e.intersection.index ?? -1) / 2);
1700
- if (i < 0) return;
1701
- this._writeWorldSegment(this._selectLine, s, i), this._centerAndOrientLineOnSegment(this._selectLine, s, i), this._selectLine.visible = !0, this._prepareEdgeMetadata(s, i), this._store.setSelectedObject(this._selectLine), this._selected = { lines: s, seg: i }, this._hovered && this._same(this._hovered, this._selected) && (this._hoverLine.visible = !1);
2996
+ if (x === "LineSegments")
2997
+ for (let w = 1, M = w + 1, I = S.count; w < I; w += 2, M = w + 1)
2998
+ r += "l " + (s + w) + " " + (s + M) + `
2999
+ `;
3000
+ s += g;
3001
+ }
3002
+ function f(_) {
3003
+ let g = 0;
3004
+ const b = _.geometry, x = b.getAttribute("position"), S = b.getAttribute("color");
3005
+ if (r += "o " + _.name + `
3006
+ `, x !== void 0) {
3007
+ for (let w = 0, M = x.count; w < M; w++, g++)
3008
+ o.fromBufferAttribute(x, w), o.applyMatrix4(_.matrixWorld), r += "v " + o.x + " " + o.y + " " + o.z, S !== void 0 && (l.fromBufferAttribute(S, w), Or.workingToColorSpace(l, qt), r += " " + l.r + " " + l.g + " " + l.b), r += `
3009
+ `;
3010
+ r += "p ";
3011
+ for (let w = 1, M = x.count; w <= M; w++)
3012
+ r += s + w + " ";
3013
+ r += `
3014
+ `;
3015
+ }
3016
+ s += g;
1702
3017
  }
3018
+ return t.traverse(function(_) {
3019
+ _.isMesh === !0 && u(_), _.isLine === !0 && m(_), _.isPoints === !0 && f(_);
3020
+ }), r;
3021
+ }
3022
+ }
3023
+ var Ti = Object.getOwnPropertyDescriptor, Di = (e, t, r, s) => {
3024
+ for (var i = s > 1 ? void 0 : s ? Ti(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3025
+ (o = e[n]) && (i = o(i) || i);
3026
+ return i;
3027
+ }, Nt = (e, t) => (r, s) => t(r, s, e);
3028
+ let ve = class {
3029
+ constructor(e, t) {
3030
+ this._api = e, this._exportStore = t;
3031
+ }
3032
+ /** Режим редактирования сцены */
3033
+ mode = T.Export;
3034
+ /** Экспорт всей сцены в ExportStore для последующей загрузки в виде файла. */
3035
+ handle() {
3036
+ const e = this._api.getScene(), t = es(e), s = new Li().parse(t), i = Date.now();
3037
+ this._exportStore.setResult({
3038
+ format: "obj",
3039
+ filename: `scene-${i}.obj`,
3040
+ mimeType: "text/plain;charset=utf-8",
3041
+ content: s,
3042
+ createdAt: i
3043
+ });
1703
3044
  }
1704
- /** Откат текущего режима выборки */
1705
3045
  rollback() {
1706
- this._hoverLine.visible = !1, this._selectLine.visible = !1, this._hovered = this._selected = null, this._store.setSelectedObject(null);
1707
3046
  }
1708
- /** Освобождает ресурсы хендлера, удаляет слушатели и очищает внутренние данные. */
3047
+ /** Освобождает ресурсы хендлера. */
1709
3048
  dispose() {
1710
- this.rollback(), this._sceneApi.removeFromScene(this._hoverLine), this._sceneApi.removeFromScene(this._selectLine), this._hoverLine.geometry.dispose(), this._hoverLine.material.dispose(), this._selectLine.geometry.dispose(), this._selectLine.material.dispose();
1711
- }
1712
- /** Инициализация буферных линий для режима (hover и click).
1713
- * На весь режим будет использовано 2 глобальных линии на сцене,
1714
- * использоваться они будут только для обозначения геометрии ребер конкретной фигуры.
1715
- */
1716
- _makeOverlayLine(e) {
1717
- const t = new a.BufferGeometry();
1718
- t.setAttribute("position", new a.Float32BufferAttribute(6, 3));
1719
- const r = new a.LineBasicMaterial({
1720
- color: e,
1721
- depthTest: !1,
1722
- depthWrite: !1,
1723
- transparent: !0,
1724
- opacity: 1
1725
- }), s = new a.Line(t, r);
1726
- return s.renderOrder = 1e3, s.raycast = () => {
1727
- }, s.layers.set(x), s.visible = !1, s;
3049
+ this._exportStore.clearResult();
1728
3050
  }
1729
- /** Локальные точки сегмента переводим в target (который висит на сцене) */
1730
- _writeWorldSegment(e, t, r) {
1731
- const s = t.geometry.getAttribute("position"), i = r * 2, o = i + 1, n = new a.Vector3(s.getX(i), s.getY(i), s.getZ(i)).applyMatrix4(
1732
- t.matrixWorld
1733
- ), c = new a.Vector3(s.getX(o), s.getY(o), s.getZ(o)).applyMatrix4(
1734
- t.matrixWorld
1735
- ), _ = e.geometry.getAttribute("position");
1736
- _.setXYZ(0, n.x, n.y, n.z), _.setXYZ(1, c.x, c.y, c.z), _.needsUpdate = !0;
3051
+ };
3052
+ ve = Di([
3053
+ v(),
3054
+ Nt(0, c("ISceneApi")),
3055
+ Nt(1, c("ExportStore"))
3056
+ ], ve);
3057
+ var ji = Object.defineProperty, Vi = Object.getOwnPropertyDescriptor, ar = (e, t, r, s) => {
3058
+ for (var i = s > 1 ? void 0 : s ? Vi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3059
+ (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
3060
+ return s && i && ji(t, r, i), i;
3061
+ }, Ut = (e, t) => (r, s) => t(r, s, e);
3062
+ let Q = class {
3063
+ constructor(e, t) {
3064
+ this._api = e, this._validator = t;
1737
3065
  }
1738
- _same(e, t) {
1739
- return !!e && !!t && e.lines === t.lines && e.seg === t.seg;
3066
+ /** Режим редактирования сцены */
3067
+ mode = T.Load;
3068
+ handle(e) {
3069
+ const t = [...this._api.getMeshes()];
3070
+ this._api.removeMeshes(t);
3071
+ const r = ir(e);
3072
+ this._api.addMeshes(r);
1740
3073
  }
1741
- /** Центрует `THREE.Line` на сегменте и ориентирует её вдоль ребра */
1742
- _centerAndOrientLineOnSegment(e, t, r) {
1743
- const s = t.geometry.getAttribute("position"), i = r * 2, o = i + 1, n = new a.Vector3(s.getX(i), s.getY(i), s.getZ(i)).applyMatrix4(
1744
- t.matrixWorld
1745
- ), c = new a.Vector3(s.getX(o), s.getY(o), s.getZ(o)).applyMatrix4(
1746
- t.matrixWorld
1747
- ), _ = new a.Vector3().subVectors(c, n), u = _.length();
1748
- if (!isFinite(u) || u === 0) return;
1749
- const p = new a.Vector3().addVectors(n, c).multiplyScalar(0.5);
1750
- e.position.copy(p);
1751
- const f = e.geometry;
1752
- let g = f.getAttribute("position");
1753
- (!g || g.count < 2) && (f.setAttribute("position", new a.BufferAttribute(new Float32Array(6), 3)), g = f.getAttribute("position")), g.setXYZ(0, -u / 2, 0, 0), g.setXYZ(1, u / 2, 0, 0), g.needsUpdate = !0, _.normalize();
1754
- const v = new a.Quaternion().setFromUnitVectors(new a.Vector3(1, 0, 0), _);
1755
- e.quaternion.copy(v), e.updateMatrixWorld(!0);
3074
+ rollback() {
1756
3075
  }
1757
- /** Запись метаданных выбранного ребра для использования инструментов */
1758
- _prepareEdgeMetadata(e, t) {
1759
- const r = Ze(e);
1760
- if (!r) return;
1761
- const s = e.geometry.getAttribute("position"), i = t * 2, o = i + 1, n = new a.Vector3(s.getX(i), s.getY(i), s.getZ(i)).applyMatrix4(
1762
- e.matrixWorld
1763
- ), c = new a.Vector3(s.getX(o), s.getY(o), s.getZ(o)).applyMatrix4(
1764
- e.matrixWorld
1765
- ), _ = new a.Matrix4().copy(r.matrixWorld).invert(), u = n.clone().applyMatrix4(_), p = c.clone().applyMatrix4(_), g = r.geometry.getAttribute("position"), v = new a.Vector3(), m = 1e-6, y = [], b = [];
1766
- for (let A = 0; A < g.count; A++)
1767
- v.fromBufferAttribute(g, A), v.distanceToSquared(u) < m * m ? y.push(A) : v.distanceToSquared(p) < m * m && b.push(A);
1768
- const L = new a.Matrix4().copy(e.matrixWorld).invert(), E = n.clone().applyMatrix4(L), T = c.clone().applyMatrix4(L), S = e.geometry.getAttribute("position"), w = new a.Vector3(), I = [], $ = [];
1769
- for (let A = 0; A < S.count; A++)
1770
- w.fromBufferAttribute(S, A), w.distanceToSquared(E) < m * m ? I.push(A) : w.distanceToSquared(T) < m * m && $.push(A);
1771
- this._selectLine.userData.edgeInfo = {
1772
- lines: e,
1773
- seg: t,
1774
- mesh: r,
1775
- aIndices: y,
1776
- bIndices: b,
1777
- aEdgeIndices: I,
1778
- bEdgeIndices: $
1779
- };
3076
+ /** Освобождает ресурсы хендлера. */
3077
+ dispose() {
1780
3078
  }
1781
3079
  };
1782
- we = Cs([
1783
- d(),
1784
- U(0, l("ISceneApi")),
1785
- U(1, l("ICameraApi")),
1786
- U(2, l("IRaycastApi")),
1787
- U(3, l("EditorStore"))
1788
- ], we);
1789
- var Is = Object.getOwnPropertyDescriptor, Ps = (e, t, r, s) => {
1790
- for (var i = s > 1 ? void 0 : s ? Is(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1791
- (n = e[o]) && (i = n(i) || i);
1792
- return i;
1793
- }, Ls = (e, t) => (r, s) => t(r, s, e);
1794
- let xe = class {
1795
- constructor(e) {
1796
- this._api = e;
3080
+ ar([
3081
+ nr((e) => e._validator)
3082
+ ], Q.prototype, "handle", 1);
3083
+ Q = ar([
3084
+ v(),
3085
+ Ut(0, c("IMeshApi")),
3086
+ Ut(1, c("ObjValidator"))
3087
+ ], Q);
3088
+ var Hi = Object.defineProperty, $i = Object.getOwnPropertyDescriptor, lr = (e, t, r, s) => {
3089
+ for (var i = s > 1 ? void 0 : s ? $i(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3090
+ (o = e[n]) && (i = (s ? o(t, r, i) : o(i)) || i);
3091
+ return s && i && Hi(t, r, i), i;
3092
+ }, Xt = (e, t) => (r, s) => t(r, s, e);
3093
+ let ee = class {
3094
+ constructor(e, t) {
3095
+ this._api = e, this._validator = t;
1797
3096
  }
1798
3097
  /** Режим редактирования сцены */
1799
- mode = W.AddFigure;
1800
- /** Последняя добавленная фигура, нужно для отката через `ctrl + z`. */
1801
- _lastAddedMesh = null;
1802
- /** Добавление базовых фигур на сцену, которые приписаны в `FigureType`. */
3098
+ mode = T.LoadFigure;
1803
3099
  handle(e) {
1804
- const t = _s[e](), r = t.getAttribute("position");
1805
- r && r.setUsage && r.setUsage(a.DynamicDrawUsage);
1806
- const s = new a.Mesh(t, ds);
1807
- s.layers.enable(k);
1808
- const i = t.index ? t.toNonIndexed() : t, o = gs(i);
1809
- o.layers.enable(k), s.add(o);
1810
- const n = ms(i);
1811
- n.layers.enable(k), s.add(n), this._api.addMesh(s), this._lastAddedMesh = s;
3100
+ const t = ir(e);
3101
+ this._api.addMeshes(t);
1812
3102
  }
1813
- /** Срабатывает только на `ctrl + z`. */
1814
3103
  rollback() {
1815
- this._lastAddedMesh !== null && (this._api.removeMesh(this._lastAddedMesh), this._lastAddedMesh = null);
1816
3104
  }
1817
3105
  /** Освобождает ресурсы хендлера. */
1818
3106
  dispose() {
1819
- this._lastAddedMesh = null;
1820
3107
  }
1821
3108
  };
1822
- xe = Ps([
1823
- d(),
1824
- Ls(0, l("IMeshApi"))
1825
- ], xe);
1826
- var Es = Object.getOwnPropertyDescriptor, Ts = (e, t, r, s) => {
1827
- for (var i = s > 1 ? void 0 : s ? Es(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1828
- (n = e[o]) && (i = n(i) || i);
3109
+ lr([
3110
+ nr((e) => e._validator)
3111
+ ], ee.prototype, "handle", 1);
3112
+ ee = lr([
3113
+ v(),
3114
+ Xt(0, c("IMeshApi")),
3115
+ Xt(1, c("ObjValidator"))
3116
+ ], ee);
3117
+ class ye {
3118
+ constructor(t, r, s, i) {
3119
+ this._sceneApi = t, this._interactionApi = r, this._metricsApi = s, this._store = i;
3120
+ }
3121
+ /** Группа объектов текущего benchmark-теста. */
3122
+ _group = null;
3123
+ _liveTimerId = null;
3124
+ /**
3125
+ * Выполняет benchmark-тест.
3126
+ *
3127
+ * @param durationMs - длительность выполнения теста в миллисекундах
3128
+ *
3129
+ * @internal
3130
+ * @method
3131
+ */
3132
+ async handle(t) {
3133
+ this._interactionApi.setInteractionEnabled(!1), this._prepareScene(), this._metricsApi.start(this.objectsCount), this._startLiveMetrics(), await this._wait(t), this._stopLiveMetrics(), this._metricsApi.stop();
3134
+ const r = this._metricsApi.getMetrics();
3135
+ this._store.setCurrentMetrics(r), this._store.addMetrics(this.mode, r), this._interactionApi.setInteractionEnabled(!0);
3136
+ }
3137
+ /**
3138
+ * Выполняет откат действий хендлера.
3139
+ *
3140
+ * @internal
3141
+ * @method
3142
+ */
3143
+ rollback() {
3144
+ this._interactionApi.setInteractionEnabled(!0), this._stopLiveMetrics(), this._metricsApi.stop(), this._metricsApi.reset(), this._store.setCurrentMetrics(null), this._group && (this._sceneApi.removeFromScene(this._group, !0), this._group.clear(), this._group = null);
3145
+ }
3146
+ /** Освобождает ресурсы хендлера. */
3147
+ dispose() {
3148
+ this.rollback();
3149
+ }
3150
+ /**
3151
+ * Подготавливает тестовую сцену.
3152
+ *
3153
+ * @private
3154
+ * @method
3155
+ */
3156
+ _prepareScene() {
3157
+ const t = new a.Group();
3158
+ t.name = this.groupName, this.fillGroup(t), this._group = t, this._sceneApi.addToScene(t);
3159
+ }
3160
+ /**
3161
+ * Ожидает указанное количество миллисекунд.
3162
+ *
3163
+ * @param ms - длительность ожидания
3164
+ *
3165
+ * @returns Promise, завершающийся после указанного времени
3166
+ *
3167
+ * @private
3168
+ * @method
3169
+ */
3170
+ _wait(t) {
3171
+ return new Promise((r) => {
3172
+ window.setTimeout(r, t);
3173
+ });
3174
+ }
3175
+ _startLiveMetrics() {
3176
+ this._stopLiveMetrics(), this._liveTimerId = window.setInterval(() => {
3177
+ this._store.setCurrentMetrics(this._metricsApi.getMetrics());
3178
+ }, 250);
3179
+ }
3180
+ _stopLiveMetrics() {
3181
+ this._liveTimerId !== null && (window.clearInterval(this._liveTimerId), this._liveTimerId = null);
3182
+ }
3183
+ }
3184
+ var Ri = Object.getOwnPropertyDescriptor, Bi = (e, t, r, s) => {
3185
+ for (var i = s > 1 ? void 0 : s ? Ri(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3186
+ (o = e[n]) && (i = o(i) || i);
3187
+ return i;
3188
+ }, oe = (e, t) => (r, s) => t(r, s, e);
3189
+ let at = class extends ye {
3190
+ /** Тип benchmark-теста. */
3191
+ mode = X.Light;
3192
+ /** Название группы тестовых объектов. */
3193
+ groupName = "__LIGHT_BENCHMARK__";
3194
+ /** Количество объектов в тестовой сцене. */
3195
+ objectsCount = Mt;
3196
+ constructor(e, t, r, s) {
3197
+ super(e, t, r, s);
3198
+ }
3199
+ /**
3200
+ * Заполняет группу объектами легкого benchmark-теста.
3201
+ *
3202
+ * @param group - группа benchmark-теста
3203
+ *
3204
+ * @internal
3205
+ * @method
3206
+ */
3207
+ fillGroup(e) {
3208
+ const t = Math.ceil(Math.sqrt(this.objectsCount)), r = t / 2;
3209
+ for (let s = 0; s < this.objectsCount; s += 1) {
3210
+ const i = s % t, n = Math.floor(s / t), o = new a.BoxGeometry(0.4, 0.4, 0.4), l = new a.MeshStandardMaterial(), h = new a.Mesh(o, l);
3211
+ h.position.set(i - r, 0.2, n - r), e.add(h);
3212
+ }
3213
+ }
3214
+ };
3215
+ at = Bi([
3216
+ v(),
3217
+ oe(0, c("ISceneApi")),
3218
+ oe(1, c("IInteractionApi")),
3219
+ oe(2, c("IMetricsApi")),
3220
+ oe(3, c("MetricsStore"))
3221
+ ], at);
3222
+ var Fi = Object.getOwnPropertyDescriptor, ki = (e, t, r, s) => {
3223
+ for (var i = s > 1 ? void 0 : s ? Fi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3224
+ (o = e[n]) && (i = o(i) || i);
3225
+ return i;
3226
+ }, ae = (e, t) => (r, s) => t(r, s, e);
3227
+ let lt = class extends ye {
3228
+ /** Тип benchmark-теста. */
3229
+ mode = X.Medium;
3230
+ /** Название группы тестовых объектов. */
3231
+ groupName = "__MEDIUM_BENCHMARK__";
3232
+ /** Количество объектов в тестовой сцене. */
3233
+ objectsCount = Mt;
3234
+ constructor(e, t, r, s) {
3235
+ super(e, t, r, s);
3236
+ }
3237
+ /**
3238
+ * Заполняет группу объектами среднего benchmark-теста.
3239
+ *
3240
+ * @param group - группа benchmark-теста
3241
+ *
3242
+ * @internal
3243
+ * @method
3244
+ */
3245
+ fillGroup(e) {
3246
+ const t = Math.ceil(Math.sqrt(this.objectsCount)), r = t / 2;
3247
+ for (let s = 0; s < this.objectsCount; s += 1) {
3248
+ const i = s % t, n = Math.floor(s / t), o = new a.CylinderGeometry(0.18, 0.18, 0.45, 24), l = new a.MeshStandardMaterial(), h = new a.Mesh(o, l);
3249
+ h.position.set((i - r) * 0.6, 0.225, (n - r) * 0.6), e.add(h);
3250
+ }
3251
+ }
3252
+ };
3253
+ lt = ki([
3254
+ v(),
3255
+ ae(0, c("ISceneApi")),
3256
+ ae(1, c("IInteractionApi")),
3257
+ ae(2, c("IMetricsApi")),
3258
+ ae(3, c("MetricsStore"))
3259
+ ], lt);
3260
+ var Gi = Object.getOwnPropertyDescriptor, zi = (e, t, r, s) => {
3261
+ for (var i = s > 1 ? void 0 : s ? Gi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3262
+ (o = e[n]) && (i = o(i) || i);
1829
3263
  return i;
1830
- }, Be = (e, t) => (r, s) => t(r, s, e);
1831
- let Oe = class {
1832
- constructor(e, t) {
1833
- this._api = e, this._store = t;
3264
+ }, le = (e, t) => (r, s) => t(r, s, e);
3265
+ let ct = class extends ye {
3266
+ /** Тип benchmark-теста. */
3267
+ mode = X.Heavy;
3268
+ /** Название группы тестовых объектов. */
3269
+ groupName = "__HEAVY_BENCHMARK__";
3270
+ /** Количество объектов в тестовой сцене. */
3271
+ objectsCount = Mt;
3272
+ constructor(e, t, r, s) {
3273
+ super(e, t, r, s);
1834
3274
  }
1835
- /** Режим редактирования сцены */
1836
- mode = W.DeleteFigure;
1837
- /** Последняя удаленная фигура, сохраняем для отката через `ctrl + z` */
1838
- _lastDeletedMesh = null;
1839
- handle() {
1840
- const e = this._store.getSelectedObject();
1841
- ps(e) && (this._api.removeMesh(e), this._store.setSelectedObject(null), this._lastDeletedMesh = e);
3275
+ /**
3276
+ * Заполняет группу объектами тяжелого benchmark-теста.
3277
+ *
3278
+ * @param group - группа benchmark-теста
3279
+ *
3280
+ * @internal
3281
+ * @method
3282
+ */
3283
+ fillGroup(e) {
3284
+ const t = Math.ceil(Math.sqrt(this.objectsCount)), r = t / 2;
3285
+ for (let s = 0; s < this.objectsCount; s += 1) {
3286
+ const i = s % t, n = Math.floor(s / t), o = new a.TorusKnotGeometry(0.16, 0.05, 64, 12), l = new a.MeshStandardMaterial(), h = new a.Mesh(o, l);
3287
+ h.position.set((i - r) * 0.7, 0.25, (n - r) * 0.7), e.add(h);
3288
+ }
1842
3289
  }
1843
- /** Срабатывает только на `ctrl + z`. */
1844
- rollback() {
1845
- this._lastDeletedMesh && (this._api.addMesh(this._lastDeletedMesh), this._lastDeletedMesh = null);
3290
+ };
3291
+ ct = zi([
3292
+ v(),
3293
+ le(0, c("ISceneApi")),
3294
+ le(1, c("IInteractionApi")),
3295
+ le(2, c("IMetricsApi")),
3296
+ le(3, c("MetricsStore"))
3297
+ ], ct);
3298
+ var Wi = Object.getOwnPropertyDescriptor, Ni = (e, t, r, s) => {
3299
+ for (var i = s > 1 ? void 0 : s ? Wi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3300
+ (o = e[n]) && (i = o(i) || i);
3301
+ return i;
3302
+ }, ce = (e, t) => (r, s) => t(r, s, e);
3303
+ let ht = class extends ye {
3304
+ /** Тип benchmark-теста. */
3305
+ mode = X.Mixed;
3306
+ /** Название группы тестовых объектов. */
3307
+ groupName = "__MIXED_BENCHMARK__";
3308
+ /** Количество объектов в тестовой сцене. */
3309
+ objectsCount = Vt + Ht + $t;
3310
+ constructor(e, t, r, s) {
3311
+ super(e, t, r, s);
1846
3312
  }
1847
- /** Освобождает ресурсы хендлера. */
1848
- dispose() {
1849
- this._lastDeletedMesh = null;
3313
+ /**
3314
+ * Заполняет группу объектами смешанного benchmark-теста.
3315
+ *
3316
+ * @param group - группа benchmark-теста
3317
+ *
3318
+ * @internal
3319
+ * @method
3320
+ */
3321
+ fillGroup(e) {
3322
+ this._addLightObjects(e, -10), this._addMediumObjects(e, 0), this._addHardObjects(e, 10);
3323
+ }
3324
+ _addLightObjects(e, t) {
3325
+ this._addGrid(e, Vt, t, () => new a.Mesh(new a.BoxGeometry(0.3, 0.3, 0.3), new a.MeshStandardMaterial()));
3326
+ }
3327
+ _addMediumObjects(e, t) {
3328
+ this._addGrid(e, Ht, t, () => new a.Mesh(
3329
+ new a.CylinderGeometry(0.18, 0.18, 0.45, 24),
3330
+ new a.MeshStandardMaterial()
3331
+ ));
3332
+ }
3333
+ _addHardObjects(e, t) {
3334
+ this._addGrid(e, $t, t, () => new a.Mesh(
3335
+ new a.TorusKnotGeometry(0.16, 0.05, 64, 12),
3336
+ new a.MeshStandardMaterial()
3337
+ ));
3338
+ }
3339
+ _addGrid(e, t, r, s) {
3340
+ const i = Math.ceil(Math.sqrt(t)), n = i / 2;
3341
+ for (let o = 0; o < t; o += 1) {
3342
+ const l = o % i, h = Math.floor(o / i), d = s(o);
3343
+ d.position.set(r + (l - n) * 0.65, 0.25, (h - n) * 0.65), e.add(d);
3344
+ }
1850
3345
  }
1851
3346
  };
1852
- Oe = Ts([
1853
- d(),
1854
- Be(0, l("IMeshApi")),
1855
- Be(1, l("EditorStore"))
1856
- ], Oe);
1857
- var Ds = Object.getOwnPropertyDescriptor, Vs = (e, t, r, s) => {
1858
- for (var i = s > 1 ? void 0 : s ? Ds(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1859
- (n = e[o]) && (i = n(i) || i);
3347
+ ht = Ni([
3348
+ v(),
3349
+ ce(0, c("ISceneApi")),
3350
+ ce(1, c("IInteractionApi")),
3351
+ ce(2, c("IMetricsApi")),
3352
+ ce(3, c("MetricsStore"))
3353
+ ], ht);
3354
+ var Ui = Object.getOwnPropertyDescriptor, Xi = (e, t, r, s) => {
3355
+ for (var i = s > 1 ? void 0 : s ? Ui(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3356
+ (o = e[n]) && (i = o(i) || i);
1860
3357
  return i;
1861
- }, X = (e, t) => (r, s) => t(r, s, e);
1862
- let Ce = class {
1863
- constructor(e, t, r, s) {
1864
- this._renderer = e, this._mediator = t, this._store = r, this._controller = s, this.setSelectMode(M.Mesh), this.setToolMode(j.Translate);
3358
+ }, Z = (e, t) => (r, s) => t(r, s, e);
3359
+ let dt = class {
3360
+ constructor(e, t, r, s, i) {
3361
+ this._renderer = e, this._mediator = t, this._store = r, this._exportStore = s, this._worker = i, this.setSelectMode(O.Mesh), this.setToolMode(W.Translate);
1865
3362
  }
1866
3363
  setDisplayMode(e) {
1867
3364
  return this._mediator.send({
@@ -1869,12 +3366,6 @@ let Ce = class {
1869
3366
  payload: [e]
1870
3367
  });
1871
3368
  }
1872
- setSceneMode(e) {
1873
- return this._mediator.send({
1874
- type: P.Scene,
1875
- payload: [e]
1876
- });
1877
- }
1878
3369
  setSelectMode(e) {
1879
3370
  return this._mediator.send({
1880
3371
  type: P.Select,
@@ -1887,12 +3378,39 @@ let Ce = class {
1887
3378
  payload: [e]
1888
3379
  });
1889
3380
  }
1890
- addFigure(e, t) {
3381
+ addFigure(e) {
3382
+ return this._mediator.send({
3383
+ type: P.Scene,
3384
+ payload: [T.AddFigure, e]
3385
+ });
3386
+ }
3387
+ deleteFigure() {
3388
+ return this._mediator.send({
3389
+ type: P.Scene,
3390
+ payload: [T.DeleteFigure]
3391
+ });
3392
+ }
3393
+ loadFigure(e) {
3394
+ return this._mediator.send({
3395
+ type: P.Scene,
3396
+ payload: [T.LoadFigure, e]
3397
+ });
3398
+ }
3399
+ loadScene(e) {
1891
3400
  return this._mediator.send({
1892
3401
  type: P.Scene,
1893
- payload: [e, t]
3402
+ payload: [T.Load, e]
1894
3403
  });
1895
3404
  }
3405
+ exportScene() {
3406
+ return this._exportStore.clearResult(), {
3407
+ response: this._mediator.send({
3408
+ type: P.Scene,
3409
+ payload: [T.Export]
3410
+ }),
3411
+ result: this._exportStore.getResult()
3412
+ };
3413
+ }
1896
3414
  resizeRenderer() {
1897
3415
  this._renderer.resize();
1898
3416
  }
@@ -1901,13 +3419,13 @@ let Ce = class {
1901
3419
  * Вызывается после создания хаба.
1902
3420
  */
1903
3421
  start() {
1904
- this._controller.start();
3422
+ this._worker.start();
1905
3423
  }
1906
3424
  /**
1907
3425
  * Останавливает редактор.
1908
3426
  */
1909
3427
  stop() {
1910
- this._controller.stop();
3428
+ this._worker.stop();
1911
3429
  }
1912
3430
  getSelectionStats() {
1913
3431
  return this._store.getSelectionStats();
@@ -1926,132 +3444,161 @@ let Ce = class {
1926
3444
  this._mediator.dispose();
1927
3445
  }
1928
3446
  };
1929
- Ce = Vs([
1930
- d(),
1931
- X(0, l("Renderer")),
1932
- X(1, l("IMediator")),
1933
- X(2, l("EditorStore")),
1934
- X(3, l("IController"))
1935
- ], Ce);
1936
- var $s = Object.getOwnPropertyDescriptor, js = (e, t, r, s) => {
1937
- for (var i = s > 1 ? void 0 : s ? $s(t, r) : t, o = e.length - 1, n; o >= 0; o--)
1938
- (n = e[o]) && (i = n(i) || i);
3447
+ dt = Xi([
3448
+ v(),
3449
+ Z(0, c("Renderer")),
3450
+ Z(1, c("IMediator")),
3451
+ Z(2, c("EditorStore")),
3452
+ Z(3, c("ExportStore")),
3453
+ Z(4, c("IWorker"))
3454
+ ], dt);
3455
+ var Yi = Object.getOwnPropertyDescriptor, Ki = (e, t, r, s) => {
3456
+ for (var i = s > 1 ? void 0 : s ? Yi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3457
+ (o = e[n]) && (i = o(i) || i);
1939
3458
  return i;
1940
- };
1941
- let Ie = class {
3459
+ }, Ee = (e, t) => (r, s) => t(r, s, e);
3460
+ let _t = class {
3461
+ constructor(e, t, r) {
3462
+ this._renderer = e, this._mediator = t, this._worker = r;
3463
+ }
3464
+ addFigure(e) {
3465
+ return this._mediator.send({
3466
+ type: P.Scene,
3467
+ payload: [T.AddFigure, e]
3468
+ });
3469
+ }
3470
+ loadFigure(e) {
3471
+ return this._mediator.send({
3472
+ type: P.Scene,
3473
+ payload: [T.LoadFigure, e]
3474
+ });
3475
+ }
3476
+ loadScene(e) {
3477
+ return this._mediator.send({
3478
+ type: P.Scene,
3479
+ payload: [T.Load, e]
3480
+ });
3481
+ }
3482
+ resizeRenderer() {
3483
+ this._renderer.resize();
3484
+ }
1942
3485
  /**
1943
- * Внутренний эмиттер событий Node.js.
1944
- *
1945
- * @private
1946
- * @member
3486
+ * Запускает вьювер.
3487
+ * Вызывается после создания хаба.
1947
3488
  */
1948
- _emitter;
1949
- /** @constructor */
1950
- constructor() {
1951
- this._emitter = new at();
3489
+ start() {
3490
+ this._worker.start();
1952
3491
  }
1953
3492
  /**
1954
- * Публикует событие в шину.
1955
- *
1956
- * @param event - название события (из `EventTopics`)
1957
- * @param payload - данные события (тип зависит от события)
1958
- *
1959
- * @typeParam K - ключ события из `EditorEvents`
1960
- *
1961
- * @remarks
1962
- * Все подписчики, зарегистрированные на это событие, получат payload.
3493
+ * Останавливает вьювер.
3494
+ */
3495
+ stop() {
3496
+ this._worker.stop();
3497
+ }
3498
+ dispose() {
3499
+ this._mediator.dispose();
3500
+ }
3501
+ };
3502
+ _t = Ki([
3503
+ v(),
3504
+ Ee(0, c("Renderer")),
3505
+ Ee(1, c("IMediator")),
3506
+ Ee(2, c("IWorker"))
3507
+ ], _t);
3508
+ var qi = Object.getOwnPropertyDescriptor, Zi = (e, t, r, s) => {
3509
+ for (var i = s > 1 ? void 0 : s ? qi(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3510
+ (o = e[n]) && (i = o(i) || i);
3511
+ return i;
3512
+ }, he = (e, t) => (r, s) => t(r, s, e);
3513
+ let ut = class {
3514
+ constructor(e, t, r, s) {
3515
+ this._renderer = e, this._mediator = t, this._store = r, this._worker = s;
3516
+ }
3517
+ /**
3518
+ * Запускает benchmark-тестирование.
1963
3519
  *
1964
- * @example
1965
- * ```typescript
1966
- * // Публикация события клика
1967
- * eventBus.emit(EventTopics.SelectClick, { intersection: hit });
3520
+ * @param config - конфигурация benchmark-тестирования
1968
3521
  *
1969
- * // Публикация события сброса выделения
1970
- * eventBus.emit(EventTopics.SelectClick, null);
1971
- * ```
3522
+ * @returns Краткий результат выполнения запрошенных тестов
1972
3523
  *
1973
3524
  * @public
1974
3525
  * @method
1975
3526
  */
1976
- emit(e, t) {
1977
- this._emitter.emit(e, t);
3527
+ run(e) {
3528
+ this._store.clear();
3529
+ const t = [];
3530
+ for (const r of e.tests) {
3531
+ const s = this._mediator.send({
3532
+ type: P.Benchmark,
3533
+ payload: [r, e.durationMs]
3534
+ });
3535
+ t.push({
3536
+ type: r,
3537
+ status: s === null ? Pe.Success : Pe.Failed
3538
+ });
3539
+ }
3540
+ return { tests: t };
1978
3541
  }
1979
3542
  /**
1980
- * Подписывается на событие.
1981
- *
1982
- * @param event - название события (из `EventTopics`)
1983
- * @param listener - функция-обработчик, получающая payload
1984
- *
1985
- * @typeParam K - ключ события из `EditorEvents`
3543
+ * Возвращает отчет по успешно выполненным benchmark-тестам.
1986
3544
  *
1987
- * @remarks
1988
- * **Важно:** для предотвращения утечек памяти необходимо отписываться от событий
1989
- * в `dispose()` методах компонентов.
1990
- *
1991
- * @example
1992
- * ```typescript
1993
- * // Подписка на событие hover
1994
- * this._eventBus.on(EventTopics.SelectHover, (payload) => {
1995
- * if (payload) {
1996
- * this._handleHover(payload.intersection);
1997
- * } else {
1998
- * this._clearHover();
1999
- * }
2000
- * });
2001
- * ```
3545
+ * @returns Отчет benchmark-тестирования
2002
3546
  *
2003
3547
  * @public
2004
3548
  * @method
2005
3549
  */
2006
- on(e, t) {
2007
- this._emitter.on(e, t);
3550
+ getReport() {
3551
+ return this._store.getReport();
2008
3552
  }
2009
3553
  /**
2010
- * Отписывается от события.
2011
- *
2012
- * @param event - название события (из `EventTopics`)
2013
- * @param listener - функция-обработчик, которую нужно отписать
2014
- *
2015
- * @typeParam K - ключ события из `EditorEvents`
2016
- *
2017
- * @remarks
2018
- * Для корректной отписки необходимо передать ту же самую функцию,
2019
- * которая использовалась при подписке.
2020
- *
2021
- * @example
2022
- * ```typescript
2023
- * // Сохранение ссылки на обработчик
2024
- * private _handleClick = (payload) => { ... };
3554
+ * Регистрирует слушатель обновления live-метрик.
2025
3555
  *
2026
- * // Подписка
2027
- * eventBus.on(EventTopics.SelectClick, this._handleClick);
3556
+ * @param listener - обработчик обновления метрик
2028
3557
  *
2029
- * // Отписка dispose)
2030
- * eventBus.off(EventTopics.SelectClick, this._handleClick);
2031
- * ```
3558
+ * @returns Функция отписки от обновлений
2032
3559
  *
2033
3560
  * @public
2034
3561
  * @method
2035
3562
  */
2036
- off(e, t) {
2037
- this._emitter.off(e, t);
3563
+ subscribeMetrics(e) {
3564
+ return this._store.subscribe(e);
3565
+ }
3566
+ resizeRenderer() {
3567
+ this._renderer.resize();
3568
+ }
3569
+ /**
3570
+ * Запускает редактор.
3571
+ * Вызывается после создания хаба.
3572
+ */
3573
+ start() {
3574
+ this._worker.start();
3575
+ }
3576
+ /**
3577
+ * Останавливает редактор.
3578
+ */
3579
+ stop() {
3580
+ this._worker.stop();
2038
3581
  }
2039
3582
  };
2040
- Ie = js([
2041
- d()
2042
- ], Ie);
2043
- var Hs = Object.getOwnPropertyDescriptor, Rs = (e, t, r, s) => {
2044
- for (var i = s > 1 ? void 0 : s ? Hs(t, r) : t, o = e.length - 1, n; o >= 0; o--)
2045
- (n = e[o]) && (i = n(i) || i);
3583
+ ut = Zi([
3584
+ v(),
3585
+ he(0, c("Renderer")),
3586
+ he(1, c("IMediator")),
3587
+ he(2, c("MetricsStore")),
3588
+ he(3, c("IWorker"))
3589
+ ], ut);
3590
+ var Ji = Object.getOwnPropertyDescriptor, Qi = (e, t, r, s) => {
3591
+ for (var i = s > 1 ? void 0 : s ? Ji(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3592
+ (o = e[n]) && (i = o(i) || i);
2046
3593
  return i;
2047
3594
  };
2048
- let Pe = class {
3595
+ let pt = class {
2049
3596
  /** Текущий режим выборки. */
2050
- _selectMode = M.Mesh;
3597
+ _selectMode = O.Mesh;
2051
3598
  /** Текущий выбранный инструмент. */
2052
- _toolType = j.Translate;
3599
+ _toolType = W.Translate;
2053
3600
  /** Выбранный режим отображения. */
2054
- _displayMode = F.Plane;
3601
+ _displayMode = J.Plane;
2055
3602
  /** Выбранный объект на сцене. */
2056
3603
  _selectedObject = null;
2057
3604
  /** Слушатели событий по изменению выбранного объекта. */
@@ -2059,7 +3606,7 @@ let Pe = class {
2059
3606
  /** Слушатели событий трансформации выбранного объекта. */
2060
3607
  _transformListeners = /* @__PURE__ */ new Set();
2061
3608
  constructor() {
2062
- ct(this, {}, { autoBind: !0 });
3609
+ bt(this, {}, { autoBind: !0 });
2063
3610
  }
2064
3611
  getSelectMode() {
2065
3612
  return this._selectMode;
@@ -2084,7 +3631,7 @@ let Pe = class {
2084
3631
  }
2085
3632
  getSelectionStats() {
2086
3633
  const e = this._selectedObject;
2087
- return e ? vs(e) : null;
3634
+ return e ? qr(e) : null;
2088
3635
  }
2089
3636
  setSelectedObject(e) {
2090
3637
  if (this._selectedObject !== e) {
@@ -2102,50 +3649,165 @@ let Pe = class {
2102
3649
  for (const e of this._transformListeners) e();
2103
3650
  }
2104
3651
  };
2105
- Pe = Rs([
2106
- d()
2107
- ], Pe);
2108
- var G = /* @__PURE__ */ ((e) => (e.ToolNotAllowed = "TOOL_NOT_ALLOWED", e.Success = "SUCCESS", e.NoChange = "NO_CHANGE", e.Error = "ERROR", e))(G || {});
2109
- class qe extends Error {
3652
+ pt = Qi([
3653
+ v()
3654
+ ], pt);
3655
+ class cr {
3656
+ _result = null;
3657
+ constructor() {
3658
+ bt(
3659
+ this,
3660
+ {
3661
+ _result: $r.ref
3662
+ },
3663
+ {
3664
+ autoBind: !0
3665
+ }
3666
+ );
3667
+ }
3668
+ get result() {
3669
+ return this._result;
3670
+ }
3671
+ get hasResult() {
3672
+ return this._result !== null;
3673
+ }
3674
+ setResult(t) {
3675
+ this._result = t;
3676
+ }
3677
+ getResult() {
3678
+ return this._result;
3679
+ }
3680
+ clearResult() {
3681
+ this._result = null;
3682
+ }
3683
+ }
3684
+ var en = Object.getOwnPropertyDescriptor, tn = (e, t, r, s) => {
3685
+ for (var i = s > 1 ? void 0 : s ? en(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3686
+ (o = e[n]) && (i = o(i) || i);
3687
+ return i;
3688
+ };
3689
+ let mt = class {
3690
+ /** Дата создания текущего отчета. */
3691
+ _createdAt = (/* @__PURE__ */ new Date()).toISOString();
3692
+ /** Метрики успешно выполненных тестов. */
3693
+ _metrics = /* @__PURE__ */ new Map();
3694
+ /** Текущие live-метрики. */
3695
+ _currentMetrics = null;
3696
+ /** Слушатели обновления live-метрик. */
3697
+ _listeners = /* @__PURE__ */ new Set();
3698
+ constructor() {
3699
+ bt(this, {}, { autoBind: !0 });
3700
+ }
3701
+ clear() {
3702
+ this._createdAt = (/* @__PURE__ */ new Date()).toISOString(), this._metrics.clear(), this.setCurrentMetrics(null);
3703
+ }
3704
+ addMetrics(e, t) {
3705
+ this._metrics.set(e, t);
3706
+ }
3707
+ setCurrentMetrics(e) {
3708
+ this._currentMetrics = e;
3709
+ for (const t of this._listeners)
3710
+ t(this._currentMetrics);
3711
+ }
3712
+ getCurrentMetrics() {
3713
+ return this._currentMetrics;
3714
+ }
3715
+ subscribe(e) {
3716
+ return this._listeners.add(e), () => {
3717
+ this._listeners.delete(e);
3718
+ };
3719
+ }
3720
+ getReport() {
3721
+ const e = [...this._metrics.entries()].map(([t, r]) => ({
3722
+ type: t,
3723
+ status: Pe.Success,
3724
+ metrics: r
3725
+ }));
3726
+ return {
3727
+ createdAt: this._createdAt,
3728
+ tests: e
3729
+ };
3730
+ }
3731
+ };
3732
+ mt = tn([
3733
+ v()
3734
+ ], mt);
3735
+ class hr extends Error {
2110
3736
  constructor(t, r, s, i) {
2111
3737
  super(r), this.type = t, this.code = s, this.meta = i, this.name = this._name;
2112
3738
  }
2113
3739
  _name = "PolicyException";
2114
3740
  }
2115
- var Fs = Object.getOwnPropertyDescriptor, Ws = (e, t, r, s) => {
2116
- for (var i = s > 1 ? void 0 : s ? Fs(t, r) : t, o = e.length - 1, n; o >= 0; o--)
2117
- (n = e[o]) && (i = n(i) || i);
3741
+ class pe extends Error {
3742
+ constructor(t, r, s, i) {
3743
+ super(r), this.type = t, this.code = s, this.meta = i, this.name = this._name;
3744
+ }
3745
+ _name = "ValidationException";
3746
+ }
3747
+ var rn = Object.getOwnPropertyDescriptor, sn = (e, t, r, s) => {
3748
+ for (var i = s > 1 ? void 0 : s ? rn(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3749
+ (o = e[n]) && (i = o(i) || i);
2118
3750
  return i;
2119
- }, ks = (e, t) => (r, s) => t(r, s, e);
2120
- let Le = class {
3751
+ }, nn = (e, t) => (r, s) => t(r, s, e);
3752
+ let ft = class {
2121
3753
  constructor(e) {
2122
3754
  this._store = e;
2123
3755
  }
2124
3756
  check(e) {
2125
3757
  const t = this._store.getSelectMode();
2126
- if (!st[t].includes(e))
2127
- throw new qe(
2128
- G.ToolNotAllowed,
3758
+ if (!Lr[t].includes(e))
3759
+ throw new hr(
3760
+ G.NotAllowed,
2129
3761
  `Tool ${e} is not allowed`,
2130
3762
  "TOOL_NOT_ALLOWED"
2131
3763
  );
2132
3764
  }
2133
3765
  };
2134
- Le = Ws([
2135
- d(),
2136
- ks(0, l("EditorStore"))
2137
- ], Le);
2138
- var Gs = Object.getOwnPropertyDescriptor, Bs = (e, t, r, s) => {
2139
- for (var i = s > 1 ? void 0 : s ? Gs(t, r) : t, o = e.length - 1, n; o >= 0; o--)
2140
- (n = e[o]) && (i = n(i) || i);
3766
+ ft = sn([
3767
+ v(),
3768
+ nn(0, c("EditorStore"))
3769
+ ], ft);
3770
+ class on {
3771
+ constructor() {
3772
+ }
3773
+ validate(t) {
3774
+ const r = t.trim();
3775
+ if (!r)
3776
+ throw new pe(
3777
+ G.ValidationError,
3778
+ "File content is empty.",
3779
+ "FILE_CONTENT_EMPTY"
3780
+ );
3781
+ if (!/^v\s+[-+.\deE]+\s+[-+.\deE]+\s+[-+.\deE]+/m.test(r))
3782
+ throw new pe(
3783
+ G.ValidationError,
3784
+ "OBJ content does not contain vertices.",
3785
+ "WRONG_FILE_CONTENT"
3786
+ );
3787
+ if (!/^f\s+/m.test(r))
3788
+ throw new pe(
3789
+ G.ValidationError,
3790
+ "OBJ content does not contain faces.",
3791
+ "WRONG_FILE_CONTENT"
3792
+ );
3793
+ }
3794
+ }
3795
+ var an = Object.getOwnPropertyDescriptor, ln = (e, t, r, s) => {
3796
+ for (var i = s > 1 ? void 0 : s ? an(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3797
+ (o = e[n]) && (i = o(i) || i);
2141
3798
  return i;
2142
3799
  };
2143
- let Ee = class {
3800
+ let gt = class {
2144
3801
  handle(e) {
2145
3802
  try {
2146
3803
  return e();
2147
3804
  } catch (t) {
2148
- return t instanceof qe ? {
3805
+ return t instanceof hr ? {
3806
+ type: t.type,
3807
+ message: t.message,
3808
+ code: t.code,
3809
+ blocked: !0
3810
+ } : t instanceof pe ? {
2149
3811
  type: t.type,
2150
3812
  message: t.message,
2151
3813
  code: t.code,
@@ -2164,15 +3826,15 @@ let Ee = class {
2164
3826
  }
2165
3827
  }
2166
3828
  };
2167
- Ee = Bs([
2168
- d()
2169
- ], Ee);
2170
- var zs = Object.getOwnPropertyDescriptor, Ns = (e, t, r, s) => {
2171
- for (var i = s > 1 ? void 0 : s ? zs(t, r) : t, o = e.length - 1, n; o >= 0; o--)
2172
- (n = e[o]) && (i = n(i) || i);
3829
+ gt = ln([
3830
+ v()
3831
+ ], gt);
3832
+ var cn = Object.getOwnPropertyDescriptor, hn = (e, t, r, s) => {
3833
+ for (var i = s > 1 ? void 0 : s ? cn(t, r) : t, n = e.length - 1, o; n >= 0; n--)
3834
+ (o = e[n]) && (i = o(i) || i);
2173
3835
  return i;
2174
- }, ze = (e, t) => (r, s) => t(r, s, e);
2175
- let Te = class {
3836
+ }, Yt = (e, t) => (r, s) => t(r, s, e);
3837
+ let vt = class {
2176
3838
  constructor(e, t) {
2177
3839
  this._middlewares = t, this._managers = new Map(e.map((r) => [r.type, r]));
2178
3840
  }
@@ -2187,36 +3849,171 @@ let Te = class {
2187
3849
  blocked: !0
2188
3850
  };
2189
3851
  const r = () => (t.manage(...e.payload), null);
2190
- return this._middlewares.reduceRight((i, o) => () => o.handle(i), r)();
3852
+ return this._middlewares.reduceRight((i, n) => () => n.handle(i), r)();
2191
3853
  }
2192
3854
  dispose() {
2193
3855
  this._managers && this._managers.clear();
2194
3856
  }
2195
3857
  };
2196
- Te = Ns([
2197
- d(),
2198
- ze(0, D("IManager")),
2199
- ze(1, D("IMiddleware"))
2200
- ], Te);
2201
- let Ne = !1;
2202
- const h = et.createChildContainer();
2203
- function Us(e) {
2204
- return Ne || (h.registerInstance("Canvas", e), h.registerSingleton("EventBus", Ie), h.registerSingleton("IController", se), h.registerSingleton("Renderer", te), h.register("IRenderable", { useToken: "Renderer" }), h.register("IRendererAccess", { useToken: "Renderer" }), h.register("IRendererCameraAccess", { useToken: "Renderer" }), h.register("IRendererDomAccess", { useToken: "Renderer" }), h.register("IRendererSceneAccess", { useToken: "Renderer" }), h.registerSingleton("ToolPolicy", Le), h.registerSingleton("IMeshApi", re), h.registerSingleton("IControlsStateApi", le), h.registerSingleton("IRaycastApi", ie), h.registerSingleton("ITransformApi", oe), h.registerSingleton("ICameraApi", ne), h.registerSingleton("IDomApi", ae), h.registerSingleton("ISceneApi", ce), h.registerSingleton("ControlsModule", he), h.registerSingleton("GizmoModule", _e), h.registerSingleton("RaycastModule", de), h.registerSingleton("SceneModule", ue), h.register("IUpdatableModule", { useToken: "ControlsModule" }), h.register("IRenderableModule", { useToken: "GizmoModule" }), h.register("IRuntimeModule", { useToken: "RaycastModule" }), h.register("IRuntimeModule", { useToken: "SceneModule" }), h.registerSingleton("IDisplayHandler", ve), h.registerSingleton("ISelectHandler", fe), h.registerSingleton("ISelectHandler", Me), h.registerSingleton("ISelectHandler", we), h.registerSingleton("ISelectHandler", ye), h.registerSingleton("IToolHandler", be), h.registerSingleton("IToolHandler", Se), h.registerSingleton("IToolHandler", Ae), h.registerSingleton("ISceneHandler", xe), h.registerSingleton("ISceneHandler", Oe), h.registerSingleton("DisplayManager", pe), h.register("IDisplayManager", { useToken: "DisplayManager" }), h.register("IManager", { useToken: "DisplayManager" }), h.registerSingleton("SelectManager", me), h.register("ISelectManager", { useToken: "SelectManager" }), h.register("IManager", { useToken: "SelectManager" }), h.registerSingleton("ToolManager", Y), h.register("IToolManager", { useToken: "ToolManager" }), h.register("IManager", { useToken: "ToolManager" }), h.registerSingleton("SceneManager", ge), h.register("ISceneManager", { useToken: "SceneManager" }), h.register("IManager", { useToken: "SceneManager" }), h.registerSingleton("IMiddleware", Ee), h.registerSingleton("IMediator", Te), h.registerSingleton("EditorHub", Ce), h.registerSingleton("EditorStore", Pe), Ne = !0), h;
3858
+ vt = hn([
3859
+ v(),
3860
+ Yt(0, H("IManager")),
3861
+ Yt(1, H("IMiddleware"))
3862
+ ], vt);
3863
+ let de = null, _e = null, ue = null;
3864
+ function St() {
3865
+ return Er.createChildContainer();
3866
+ }
3867
+ function dr(e, t) {
3868
+ e.registerInstance("Canvas", t);
3869
+ }
3870
+ function _r(e, t) {
3871
+ e.registerInstance(
3872
+ "RendererConfig",
3873
+ Zr(ts, t)
3874
+ );
3875
+ }
3876
+ function xt(e) {
3877
+ e.registerSingleton("IWorker", Te), e.registerSingleton("Renderer", Le), e.register("IRenderable", { useToken: "Renderer" }), e.register("IRendererAccess", { useToken: "Renderer" }), e.register("IRendererCameraAccess", { useToken: "Renderer" }), e.register("IRendererDomAccess", { useToken: "Renderer" }), e.register("IRendererSceneAccess", { useToken: "Renderer" });
3878
+ }
3879
+ function dn(e) {
3880
+ xt(e), e.register("IRendererInfoAccess", { useToken: "Renderer" });
3881
+ }
3882
+ function _n(e) {
3883
+ e.registerSingleton("EventBus", ze);
3884
+ }
3885
+ function un(e) {
3886
+ e.registerSingleton("ToolPolicy", ft);
3887
+ }
3888
+ function ur(e) {
3889
+ e.registerSingleton("ObjValidator", on);
3890
+ }
3891
+ function pr(e) {
3892
+ e.registerSingleton("IMeshApi", je), e.registerSingleton("ICameraApi", Re), e.registerSingleton("IDomApi", Be), e.registerSingleton("ISceneApi", Fe);
3893
+ }
3894
+ function mr(e) {
3895
+ pr(e), e.registerSingleton("IControlsStateApi", De), e.registerSingleton("IRaycastApi", Ve), e.registerSingleton("ITransformApi", He), e.registerSingleton("IInteractionApi", $e);
3896
+ }
3897
+ function pn(e) {
3898
+ pr(e);
3899
+ }
3900
+ function mn(e) {
3901
+ mr(e), e.registerSingleton("IRendererInfoApi", ke);
3902
+ }
3903
+ function fr(e) {
3904
+ e.registerSingleton("ControlsModule", me), e.registerSingleton("GizmoModule", Ge), e.registerSingleton("RaycastModule", We), e.registerSingleton("SceneModule", Ne), e.register("IUpdatableModule", { useToken: "ControlsModule" }), e.register("IRenderableModule", { useToken: "GizmoModule" }), e.register("IRuntimeModule", { useToken: "RaycastModule" }), e.register("IRuntimeModule", { useToken: "SceneModule" }), e.register("IInteractiveModule", { useToken: "ControlsModule" }), e.register("IInteractiveModule", { useToken: "RaycastModule" }), e.register("IInteractiveModule", { useToken: "GizmoModule" });
3905
+ }
3906
+ function fn(e) {
3907
+ e.registerSingleton("ControlsModule", me), e.registerSingleton("SceneModule", Ue), e.register("IUpdatableModule", { useToken: "ControlsModule" }), e.register("IRuntimeModule", { useToken: "SceneModule" }), e.register("IInteractiveModule", { useToken: "ControlsModule" });
3908
+ }
3909
+ function gn(e) {
3910
+ fr(e), e.registerSingleton("MetricsModule", Xe), e.register("IObserverModule", { useToken: "MetricsModule" }), e.register("IMetricsApi", { useToken: "MetricsModule" });
3911
+ }
3912
+ function vn(e) {
3913
+ e.registerSingleton("IDisplayHandler", Je);
3914
+ }
3915
+ function bn(e) {
3916
+ e.registerSingleton("ISelectHandler", tt), e.registerSingleton("ISelectHandler", et), e.registerSingleton("ISelectHandler", Qe), e.registerSingleton("ISelectHandler", rt);
3917
+ }
3918
+ function Mn(e) {
3919
+ e.registerSingleton("IToolHandler", nt), e.registerSingleton("IToolHandler", it), e.registerSingleton("IToolHandler", st);
3920
+ }
3921
+ function yn(e) {
3922
+ e.registerSingleton("ISceneHandler", ge), e.registerSingleton("ISceneHandler", ot), e.registerSingleton("ISceneHandler", ve), e.registerSingleton("ISceneHandler", ee), e.registerSingleton("ISceneHandler", Q);
3923
+ }
3924
+ function wn(e) {
3925
+ e.registerSingleton("ISceneHandler", ge), e.registerSingleton("ISceneHandler", ve), e.registerSingleton("ISceneHandler", ee), e.registerSingleton("ISceneHandler", Q);
3926
+ }
3927
+ function Sn(e) {
3928
+ e.registerSingleton("IBenchmarkHandler", at), e.registerSingleton("IBenchmarkHandler", lt), e.registerSingleton("IBenchmarkHandler", ct), e.registerSingleton("IBenchmarkHandler", ht);
3929
+ }
3930
+ function xn(e) {
3931
+ e.registerSingleton("DisplayManager", Ye), e.register("IDisplayManager", { useToken: "DisplayManager" }), e.register("IManager", { useToken: "DisplayManager" });
3932
+ }
3933
+ function An(e) {
3934
+ e.registerSingleton("SelectManager", qe), e.register("ISelectManager", { useToken: "SelectManager" }), e.register("IManager", { useToken: "SelectManager" });
3935
+ }
3936
+ function In(e) {
3937
+ e.registerSingleton("ToolManager", fe), e.register("IToolManager", { useToken: "ToolManager" }), e.register("IManager", { useToken: "ToolManager" });
3938
+ }
3939
+ function gr(e) {
3940
+ e.registerSingleton("SceneManager", Ke), e.register("ISceneManager", { useToken: "SceneManager" }), e.register("IManager", { useToken: "SceneManager" });
3941
+ }
3942
+ function Cn(e) {
3943
+ e.registerSingleton("BenchmarkManager", Ze), e.register("IBenchmarkManager", { useToken: "BenchmarkManager" }), e.register("IManager", { useToken: "BenchmarkManager" });
3944
+ }
3945
+ function On(e) {
3946
+ xn(e), An(e), In(e), gr(e);
3947
+ }
3948
+ function En(e) {
3949
+ gr(e);
3950
+ }
3951
+ function vr(e) {
3952
+ e.registerSingleton("IMiddleware", gt), e.registerSingleton("IMediator", vt);
3953
+ }
3954
+ function Pn(e) {
3955
+ e.registerSingleton("EditorStore", pt), e.registerSingleton("ExportStore", cr);
3956
+ }
3957
+ function Ln(e) {
3958
+ e.registerSingleton("ExportStore", cr);
3959
+ }
3960
+ function Tn(e) {
3961
+ e.registerSingleton("MetricsStore", mt);
3962
+ }
3963
+ function Dn(e) {
3964
+ e.registerSingleton("EditorHub", dt);
3965
+ }
3966
+ function jn(e) {
3967
+ e.registerSingleton("ViewerHub", _t);
3968
+ }
3969
+ function Vn(e) {
3970
+ e.registerSingleton("BenchmarkHub", ut);
3971
+ }
3972
+ function br(e, t, r) {
3973
+ return dr(e, t), _r(e, r), _n(e), xt(e), un(e), ur(e), mr(e), fr(e), vn(e), bn(e), Mn(e), yn(e), On(e), vr(e), Dn(e), Pn(e), e;
3974
+ }
3975
+ function Hn(e, t, r) {
3976
+ return br(e, t, r), dn(e), gn(e), mn(e), Sn(e), Cn(e), Tn(e), Vn(e), e;
3977
+ }
3978
+ function $n(e, t, r) {
3979
+ return dr(e, t), _r(e, r), xt(e), ur(e), pn(e), fn(e), wn(e), En(e), vr(e), jn(e), Ln(e), e;
3980
+ }
3981
+ function Rn(e, t) {
3982
+ return de || (de = br(St(), e, t), de);
3983
+ }
3984
+ function Bn(e, t) {
3985
+ return _e || (_e = $n(St(), e, t), _e);
3986
+ }
3987
+ function Fn(e, t) {
3988
+ return ue || (ue = Hn(St(), e, t), ue);
2205
3989
  }
2206
- let H = null;
2207
- const er = (e) => (H || (H = Us(e)), H.resolve("EditorHub")), tr = () => {
2208
- if (!H)
2209
- throw new Error("EditorHub is not initialized. Call createAppHub(canvas) first.");
2210
- return H.resolve("EditorHub");
3990
+ let L = null;
3991
+ const Kn = (e, t) => (L || (L = Rn(e, t)), L.resolve("EditorHub")), qn = () => {
3992
+ if (!L)
3993
+ throw new Error("EditorHub is not initialized. Call createEditorHub(canvas) first.");
3994
+ return L.resolve("EditorHub");
3995
+ }, Zn = (e, t) => (L || (L = Bn(e, t)), L.resolve("ViewerHub")), Jn = () => {
3996
+ if (!L)
3997
+ throw new Error("ViewerHub is not initialized. Call createViewerHub(canvas) first.");
3998
+ return L.resolve("ViewerHub");
3999
+ }, Qn = (e, t) => (L || (L = Fn(e, t)), L.resolve("BenchmarkHub")), eo = () => {
4000
+ if (!L)
4001
+ throw new Error("ViewerHub is not initialized. Call createBenchmarkHub(canvas) first.");
4002
+ return L.resolve("BenchmarkHub");
2211
4003
  };
2212
4004
  export {
2213
- Ce as EditorHub,
2214
- Ie as EventBus,
2215
- V as EventTopics,
4005
+ ut as BenchmarkHub,
4006
+ dt as EditorHub,
4007
+ ze as EventBus,
4008
+ B as EventTopics,
2216
4009
  P as FeatureType,
2217
- Js as ObjLoader,
2218
- te as Renderer,
2219
- G as ResponseType,
2220
- er as createAppHub,
2221
- tr as getAppHub
4010
+ Yn as ObjLoader,
4011
+ Le as Renderer,
4012
+ _t as ViewerHub,
4013
+ Qn as createBenchmarkHub,
4014
+ Kn as createEditorHub,
4015
+ Zn as createViewerHub,
4016
+ eo as getBenchmarkHub,
4017
+ qn as getEditorHub,
4018
+ Jn as getViewerHub
2222
4019
  };