@planara/core 2.8.0 → 3.0.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.
- package/README.md +5 -0
- package/dist/api/modules/controls-state-api.d.ts +23 -0
- package/dist/api/modules/controls-state-api.d.ts.map +1 -0
- package/dist/api/modules/mesh-api.d.ts +30 -0
- package/dist/api/modules/mesh-api.d.ts.map +1 -0
- package/dist/api/modules/raycast-api.d.ts +28 -0
- package/dist/api/modules/raycast-api.d.ts.map +1 -0
- package/dist/api/modules/transform-api.d.ts +33 -0
- package/dist/api/modules/transform-api.d.ts.map +1 -0
- package/dist/api/renderer/camera-api.d.ts +26 -0
- package/dist/api/renderer/camera-api.d.ts.map +1 -0
- package/dist/api/renderer/dom-api.d.ts +24 -0
- package/dist/api/renderer/dom-api.d.ts.map +1 -0
- package/dist/api/renderer/scene-api.d.ts +26 -0
- package/dist/api/renderer/scene-api.d.ts.map +1 -0
- package/dist/constants/colors.d.ts +12 -0
- package/dist/constants/colors.d.ts.map +1 -1
- package/dist/constants/figure-geometries.d.ts +55 -4
- package/dist/constants/figure-geometries.d.ts.map +1 -1
- package/dist/constants/layers.d.ts +12 -0
- package/dist/constants/layers.d.ts.map +1 -1
- package/dist/constants/messages.d.ts +18 -0
- package/dist/constants/messages.d.ts.map +1 -0
- package/dist/constants/threshold.d.ts +42 -2
- package/dist/constants/threshold.d.ts.map +1 -1
- package/dist/controllers/renderer-controller.d.ts +74 -0
- package/dist/controllers/renderer-controller.d.ts.map +1 -0
- package/dist/core/renderer.d.ts +110 -78
- package/dist/core/renderer.d.ts.map +1 -1
- package/dist/decorators/use-policy.d.ts +5 -0
- package/dist/decorators/use-policy.d.ts.map +1 -0
- package/dist/errors/policy-error.d.ts +9 -0
- package/dist/errors/policy-error.d.ts.map +1 -0
- package/dist/events/editor-events.d.ts +2 -6
- package/dist/events/editor-events.d.ts.map +1 -1
- package/dist/events/event-bus.d.ts +102 -5
- package/dist/events/event-bus.d.ts.map +1 -1
- package/dist/events/event-topics.d.ts +3 -3
- package/dist/events/event-topics.d.ts.map +1 -1
- package/dist/handlers/display/wireframe-handler.d.ts +3 -1
- package/dist/handlers/display/wireframe-handler.d.ts.map +1 -1
- package/dist/handlers/scene/add-figure-scene-handler.d.ts +2 -0
- package/dist/handlers/scene/add-figure-scene-handler.d.ts.map +1 -1
- package/dist/handlers/scene/delete-figure-scene-handler.d.ts +2 -2
- package/dist/handlers/scene/delete-figure-scene-handler.d.ts.map +1 -1
- package/dist/handlers/select/edge-select-handler.d.ts +10 -4
- package/dist/handlers/select/edge-select-handler.d.ts.map +1 -1
- package/dist/handlers/select/face-select-handler.d.ts +10 -4
- package/dist/handlers/select/face-select-handler.d.ts.map +1 -1
- package/dist/handlers/select/mesh-select-handler.d.ts +5 -3
- package/dist/handlers/select/mesh-select-handler.d.ts.map +1 -1
- package/dist/handlers/select/vertex-select-handler.d.ts +10 -4
- package/dist/handlers/select/vertex-select-handler.d.ts.map +1 -1
- package/dist/handlers/tool/base-tool-handler.d.ts +9 -6
- package/dist/handlers/tool/base-tool-handler.d.ts.map +1 -1
- package/dist/handlers/tool/rotate-tool-handler.d.ts +4 -3
- package/dist/handlers/tool/rotate-tool-handler.d.ts.map +1 -1
- package/dist/handlers/tool/scale-tool-handler.d.ts +4 -3
- package/dist/handlers/tool/scale-tool-handler.d.ts.map +1 -1
- package/dist/handlers/tool/translate-tool-handler.d.ts +4 -3
- package/dist/handlers/tool/translate-tool-handler.d.ts.map +1 -1
- package/dist/hub/editor-hub.d.ts +22 -17
- package/dist/hub/editor-hub.d.ts.map +1 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.d.ts +15 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +1635 -1563
- package/dist/index.full.d.ts +637 -242
- package/dist/index.public.d.ts +652 -157
- package/dist/index.umd.js +2 -2
- package/dist/interfaces/api/camera-api.d.ts +64 -0
- package/dist/interfaces/api/camera-api.d.ts.map +1 -0
- package/dist/interfaces/api/controls-state-api.d.ts +63 -0
- package/dist/interfaces/api/controls-state-api.d.ts.map +1 -0
- package/dist/interfaces/api/dom-api.d.ts +49 -0
- package/dist/interfaces/api/dom-api.d.ts.map +1 -0
- package/dist/interfaces/api/mesh-api.d.ts +93 -12
- package/dist/interfaces/api/mesh-api.d.ts.map +1 -1
- package/dist/interfaces/api/raycast-api.d.ts +6 -1
- package/dist/interfaces/api/raycast-api.d.ts.map +1 -1
- package/dist/interfaces/api/renderer/renderable.d.ts +45 -0
- package/dist/interfaces/api/renderer/renderable.d.ts.map +1 -0
- package/dist/interfaces/api/renderer/renderer-access.d.ts +34 -0
- package/dist/interfaces/api/renderer/renderer-access.d.ts.map +1 -0
- package/dist/interfaces/api/renderer/renderer-camera-access.d.ts +37 -0
- package/dist/interfaces/api/renderer/renderer-camera-access.d.ts.map +1 -0
- package/dist/interfaces/api/renderer/renderer-dom-access.d.ts +51 -0
- package/dist/interfaces/api/renderer/renderer-dom-access.d.ts.map +1 -0
- package/dist/interfaces/api/renderer/renderer-scene-access.d.ts +45 -0
- package/dist/interfaces/api/renderer/renderer-scene-access.d.ts.map +1 -0
- package/dist/interfaces/api/renderer-api.d.ts +35 -0
- package/dist/interfaces/api/renderer-api.d.ts.map +1 -0
- package/dist/interfaces/api/scene-api.d.ts +66 -26
- package/dist/interfaces/api/scene-api.d.ts.map +1 -1
- package/dist/interfaces/api/transform-api.d.ts +120 -0
- package/dist/interfaces/api/transform-api.d.ts.map +1 -0
- package/dist/interfaces/command/index.d.ts +9 -0
- package/dist/interfaces/command/index.d.ts.map +1 -0
- package/dist/interfaces/controller/controller.d.ts +38 -0
- package/dist/interfaces/controller/controller.d.ts.map +1 -0
- package/dist/interfaces/handler/display-handler.d.ts +9 -1
- package/dist/interfaces/handler/display-handler.d.ts.map +1 -1
- package/dist/interfaces/handler/handler.d.ts +2 -0
- package/dist/interfaces/handler/handler.d.ts.map +1 -1
- package/dist/interfaces/handler/scene-handler.d.ts +1 -0
- package/dist/interfaces/handler/scene-handler.d.ts.map +1 -1
- package/dist/interfaces/handler/select-handler.d.ts +1 -0
- package/dist/interfaces/handler/select-handler.d.ts.map +1 -1
- package/dist/interfaces/handler/tool-handler.d.ts +1 -0
- package/dist/interfaces/handler/tool-handler.d.ts.map +1 -1
- package/dist/interfaces/manager/display-manager.d.ts +3 -1
- package/dist/interfaces/manager/display-manager.d.ts.map +1 -1
- package/dist/interfaces/manager/manager.d.ts +12 -1
- package/dist/interfaces/manager/manager.d.ts.map +1 -1
- package/dist/interfaces/manager/scene-manager.d.ts +3 -1
- package/dist/interfaces/manager/scene-manager.d.ts.map +1 -1
- package/dist/interfaces/manager/select-manager.d.ts +3 -1
- package/dist/interfaces/manager/select-manager.d.ts.map +1 -1
- package/dist/interfaces/manager/tool-manager.d.ts +3 -1
- package/dist/interfaces/manager/tool-manager.d.ts.map +1 -1
- package/dist/interfaces/mediator/index.d.ts +51 -0
- package/dist/interfaces/mediator/index.d.ts.map +1 -0
- package/dist/interfaces/middleware/index.d.ts +50 -0
- package/dist/interfaces/middleware/index.d.ts.map +1 -0
- package/dist/interfaces/module/renderable-module.d.ts +27 -0
- package/dist/interfaces/module/renderable-module.d.ts.map +1 -0
- package/dist/interfaces/module/runtime-module.d.ts +54 -0
- package/dist/interfaces/module/runtime-module.d.ts.map +1 -0
- package/dist/interfaces/module/updatable-module.d.ts +48 -0
- package/dist/interfaces/module/updatable-module.d.ts.map +1 -0
- package/dist/interfaces/policy/index.d.ts +21 -0
- package/dist/interfaces/policy/index.d.ts.map +1 -0
- package/dist/interfaces/response/index.d.ts +22 -0
- package/dist/interfaces/response/index.d.ts.map +1 -0
- package/dist/interfaces/store/display-store.d.ts +21 -0
- package/dist/interfaces/store/display-store.d.ts.map +1 -0
- package/dist/interfaces/store/{editor-store.d.ts → select-store.d.ts} +16 -24
- package/dist/interfaces/store/select-store.d.ts.map +1 -0
- package/dist/interfaces/store/tool-store.d.ts +27 -0
- package/dist/interfaces/store/tool-store.d.ts.map +1 -0
- package/dist/interfaces/store/transform-store.d.ts +11 -0
- package/dist/interfaces/store/transform-store.d.ts.map +1 -0
- package/dist/ioc/container.d.ts.map +1 -1
- package/dist/managers/display/display-manager.d.ts +5 -2
- package/dist/managers/display/display-manager.d.ts.map +1 -1
- package/dist/managers/scene/scene-manager.d.ts +3 -0
- package/dist/managers/scene/scene-manager.d.ts.map +1 -1
- package/dist/managers/select/select-manager.d.ts +5 -2
- package/dist/managers/select/select-manager.d.ts.map +1 -1
- package/dist/managers/tool/tool-manager.d.ts +7 -4
- package/dist/managers/tool/tool-manager.d.ts.map +1 -1
- package/dist/mediator/index.d.ts +14 -0
- package/dist/mediator/index.d.ts.map +1 -0
- package/dist/middlewares/exception-middleware.d.ts +7 -0
- package/dist/middlewares/exception-middleware.d.ts.map +1 -0
- package/dist/modules/controls-module.d.ts +58 -0
- package/dist/modules/controls-module.d.ts.map +1 -0
- package/dist/modules/gizmo-module.d.ts +34 -0
- package/dist/modules/gizmo-module.d.ts.map +1 -0
- package/dist/modules/raycast-module.d.ts +91 -0
- package/dist/modules/raycast-module.d.ts.map +1 -0
- package/dist/modules/scene-module.d.ts +32 -0
- package/dist/modules/scene-module.d.ts.map +1 -0
- package/dist/policy/tool-policy.d.ts +18 -0
- package/dist/policy/tool-policy.d.ts.map +1 -0
- package/dist/store/index.d.ts +4 -14
- package/dist/store/index.d.ts.map +1 -1
- package/dist/types/feature/feature-type.d.ts +16 -0
- package/dist/types/feature/feature-type.d.ts.map +1 -0
- package/dist/types/response/response-type.d.ts +19 -0
- package/dist/types/response/response-type.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/core/editor-renderer.d.ts +0 -89
- package/dist/core/editor-renderer.d.ts.map +0 -1
- package/dist/core/preview-renderer.d.ts +0 -16
- package/dist/core/preview-renderer.d.ts.map +0 -1
- package/dist/interfaces/api/transform-helpers-api.d.ts +0 -26
- package/dist/interfaces/api/transform-helpers-api.d.ts.map +0 -1
- package/dist/interfaces/policy/tool-availability-policy.d.ts +0 -12
- package/dist/interfaces/policy/tool-availability-policy.d.ts.map +0 -1
- package/dist/interfaces/store/editor-store.d.ts.map +0 -1
- package/dist/policy/tool-availability-policy.d.ts +0 -13
- package/dist/policy/tool-availability-policy.d.ts.map +0 -1
- package/dist/types/api/editor-api.d.ts +0 -4
- package/dist/types/api/editor-api.d.ts.map +0 -1
- package/dist/utils/renderer-api.d.ts +0 -43
- package/dist/utils/renderer-api.d.ts.map +0 -1
package/dist/index.es.js
CHANGED
|
@@ -1,1103 +1,936 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import * as a from "three";
|
|
3
|
-
import {
|
|
4
|
-
import { FigureType as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
throw new Error("Custom geometry is not generated here.");
|
|
21
|
-
}
|
|
22
|
-
}, ze = new a.MeshStandardMaterial({
|
|
23
|
-
color: 12566463,
|
|
24
|
-
metalness: 0,
|
|
25
|
-
roughness: 0.6
|
|
26
|
-
}), lt = 8;
|
|
27
|
-
class Ne {
|
|
28
|
-
/** Корневой объект сцены */
|
|
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);
|
|
11
|
+
return i;
|
|
12
|
+
}, _t = (e, t) => (r, s) => t(r, s, e);
|
|
13
|
+
let te = class {
|
|
14
|
+
/**
|
|
15
|
+
* Корневой объект сцены Three.js.
|
|
16
|
+
*
|
|
17
|
+
* @protected
|
|
18
|
+
* @member
|
|
19
|
+
*/
|
|
29
20
|
scene;
|
|
30
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Камера для сцены Three.js.
|
|
23
|
+
*
|
|
24
|
+
* @protected
|
|
25
|
+
* @member
|
|
26
|
+
*/
|
|
31
27
|
camera;
|
|
32
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Экземпляр Three.js WebGLRenderer.
|
|
30
|
+
*
|
|
31
|
+
* @protected
|
|
32
|
+
* @member
|
|
33
|
+
*/
|
|
33
34
|
renderer;
|
|
34
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* HTML-элемент canvas, на котором рендерится сцена.
|
|
37
|
+
*
|
|
38
|
+
* @protected
|
|
39
|
+
* @member
|
|
40
|
+
*/
|
|
35
41
|
canvas;
|
|
36
|
-
/** Массив моделей на сцене */
|
|
37
|
-
meshes = [];
|
|
38
42
|
/**
|
|
39
|
-
* Конструктор
|
|
40
|
-
*
|
|
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
|
|
41
60
|
*/
|
|
42
61
|
constructor(e) {
|
|
43
62
|
this.canvas = e, this.scene = new a.Scene(), this.scene.background = new a.Color(1710618), this.camera = new a.PerspectiveCamera(
|
|
44
63
|
45,
|
|
45
|
-
|
|
64
|
+
this.canvas.clientWidth / this.canvas.clientHeight,
|
|
46
65
|
0.1,
|
|
47
66
|
1e3
|
|
48
|
-
), this.camera.position.set(1, 1, 7), this.renderer = new a.WebGLRenderer({ canvas:
|
|
49
|
-
const
|
|
50
|
-
this.scene.add(
|
|
51
|
-
const
|
|
52
|
-
|
|
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);
|
|
53
72
|
}
|
|
54
73
|
/**
|
|
55
|
-
* Обновляет размер рендерера и
|
|
74
|
+
* Обновляет размер рендерера и пропорции камеры.
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* Вызывается при изменении размеров canvas (например, при ресайзе окна браузера).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* window.addEventListener('resize', () => renderer.resize());
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @oublic
|
|
85
|
+
* @method
|
|
56
86
|
*/
|
|
57
87
|
resize() {
|
|
58
88
|
this.camera.aspect = this.canvas.clientWidth / this.canvas.clientHeight, this.camera.updateProjectionMatrix(), this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
|
|
59
89
|
}
|
|
60
90
|
/**
|
|
61
|
-
* Выполняет рендеринг
|
|
91
|
+
* Выполняет рендеринг текущего кадра.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* Рендерит сцену с текущей камерой.
|
|
95
|
+
* Вызывается автоматически в цикле `loop()`.
|
|
96
|
+
*
|
|
97
|
+
* @public
|
|
98
|
+
* @method
|
|
62
99
|
*/
|
|
63
100
|
render() {
|
|
64
101
|
this.renderer.render(this.scene, this.camera);
|
|
65
102
|
}
|
|
66
103
|
/**
|
|
67
|
-
*
|
|
104
|
+
* Обновляет состояние рендерера перед рендерингом.
|
|
105
|
+
*
|
|
106
|
+
* @remarks
|
|
107
|
+
* Пустой метод, предназначен для переопределения в наследниках
|
|
108
|
+
* (например, для обновления контролов камеры).
|
|
109
|
+
*
|
|
110
|
+
* @protected
|
|
111
|
+
* @method
|
|
112
|
+
* @virtual
|
|
68
113
|
*/
|
|
69
114
|
update() {
|
|
70
115
|
}
|
|
71
116
|
/**
|
|
72
117
|
* Запускает основной цикл рендеринга.
|
|
118
|
+
*
|
|
119
|
+
* @remarks
|
|
120
|
+
* Вызывает `update()` и `render()` каждый кадр с помощью `requestAnimationFrame`.
|
|
121
|
+
* **Важно:** вызывать метод только один раз.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* renderer.loop();
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @public
|
|
129
|
+
* @method
|
|
73
130
|
*/
|
|
74
131
|
loop() {
|
|
75
132
|
this.update(), this.render(), requestAnimationFrame(() => this.loop());
|
|
76
133
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
134
|
+
getCamera() {
|
|
135
|
+
return this.camera;
|
|
136
|
+
}
|
|
137
|
+
getRenderer() {
|
|
138
|
+
return this.renderer;
|
|
139
|
+
}
|
|
140
|
+
getCanvas() {
|
|
141
|
+
return this.canvas;
|
|
142
|
+
}
|
|
143
|
+
getDomElement() {
|
|
144
|
+
return this.renderer.domElement;
|
|
145
|
+
}
|
|
146
|
+
getScene() {
|
|
147
|
+
return this.scene;
|
|
86
148
|
}
|
|
87
149
|
/**
|
|
88
|
-
*
|
|
150
|
+
* Освобождает ресурсы рендерера.
|
|
89
151
|
*
|
|
90
|
-
* @
|
|
91
|
-
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* Удаляет ссылки на сцену, камеру и canvas, вызывает `dispose()` у WebGLRenderer.
|
|
154
|
+
* Вызывается при уничтожении редактора IOC-контейнером.
|
|
155
|
+
*
|
|
156
|
+
* @public
|
|
157
|
+
* @method
|
|
92
158
|
*/
|
|
93
|
-
|
|
94
|
-
this.scene
|
|
159
|
+
dispose() {
|
|
160
|
+
this.scene = null, this.camera = null, this.renderer?.dispose(), this.canvas = null;
|
|
95
161
|
}
|
|
162
|
+
};
|
|
163
|
+
te = ht([
|
|
164
|
+
d(),
|
|
165
|
+
_t(0, l("Canvas"))
|
|
166
|
+
], te);
|
|
167
|
+
class Js {
|
|
168
|
+
/** Позиции вершин */
|
|
169
|
+
_positions = [];
|
|
170
|
+
/** Нормали вершин */
|
|
171
|
+
_normals = [];
|
|
172
|
+
/** UV-координаты (опционально) */
|
|
173
|
+
_uvs = [];
|
|
174
|
+
// Временные поля для парсинга файла
|
|
175
|
+
_tmpPositions = [];
|
|
176
|
+
_tmpNormals = [];
|
|
177
|
+
_tmpUVs = [];
|
|
96
178
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* @param mesh - Фигура для удаления со сцены.
|
|
100
|
-
* @internal
|
|
179
|
+
* Загружает OBJ-модель в Figure
|
|
180
|
+
* @param objContent - Строка содержимого .obj файла
|
|
101
181
|
*/
|
|
102
|
-
|
|
103
|
-
|
|
182
|
+
load(t) {
|
|
183
|
+
const r = t.split(`
|
|
184
|
+
`);
|
|
185
|
+
for (const i of r) {
|
|
186
|
+
if (!i.trim() || i.startsWith("#")) continue;
|
|
187
|
+
const o = i.trim().split(/\s+/);
|
|
188
|
+
switch (o[0]) {
|
|
189
|
+
case "v":
|
|
190
|
+
this._tmpPositions.push(o.slice(1).map(Number));
|
|
191
|
+
break;
|
|
192
|
+
case "vn":
|
|
193
|
+
this._tmpNormals.push(o.slice(1).map(Number));
|
|
194
|
+
break;
|
|
195
|
+
case "vt":
|
|
196
|
+
this._tmpUVs.push(o.slice(1).map(Number));
|
|
197
|
+
break;
|
|
198
|
+
case "f":
|
|
199
|
+
this.processFaceLine(o);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const s = {
|
|
204
|
+
type: O.Custom,
|
|
205
|
+
position: this._positions,
|
|
206
|
+
...this._normals.length > 0 && { normal: this._normals },
|
|
207
|
+
...this._uvs.length > 0 && { uv: this._uvs }
|
|
208
|
+
};
|
|
209
|
+
return new tt(s);
|
|
104
210
|
}
|
|
105
211
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* @returns Массив текущих фигур.
|
|
109
|
-
* @internal
|
|
212
|
+
* Обрабатывает строку face (f) и разворачивает индексы в массивы для рендеринга
|
|
110
213
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
214
|
+
processFaceLine(t) {
|
|
215
|
+
for (let r = 1; r < t.length; r++) {
|
|
216
|
+
const s = t[r];
|
|
217
|
+
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];
|
|
221
|
+
p && this._positions.push(...p);
|
|
222
|
+
}
|
|
223
|
+
if (_ !== void 0) {
|
|
224
|
+
const p = this._tmpUVs[_ - 1];
|
|
225
|
+
p && this._uvs.push(...p);
|
|
226
|
+
}
|
|
227
|
+
if (u !== void 0) {
|
|
228
|
+
const p = this._tmpNormals[u - 1];
|
|
229
|
+
p && this._normals.push(...p);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
113
232
|
}
|
|
233
|
+
}
|
|
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);
|
|
237
|
+
return i;
|
|
238
|
+
}, B = (e, t) => (r, s) => t(r, s, e);
|
|
239
|
+
let se = class {
|
|
114
240
|
/**
|
|
115
|
-
*
|
|
241
|
+
* Конструктор контроллера.
|
|
116
242
|
*
|
|
117
|
-
* @param
|
|
118
|
-
* @param
|
|
119
|
-
*
|
|
120
|
-
* @
|
|
121
|
-
* Если рендерер уже диспоузнут (scene отсутствует), метод тихо завершится.
|
|
122
|
-
* Слой задаётся через `obj.layers.set(layer)`, после чего объект добавляется в `this.scene`.
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* // Добавить оверлей на слой подсветок:
|
|
126
|
-
* add(overlayLine, OVERLAY_LAYER);
|
|
243
|
+
* @param _updatable - модули, требующие обновления каждый кадр
|
|
244
|
+
* @param _renderable - модули, требующие кастомного рендеринга
|
|
245
|
+
* @param _runtime - модули, требующие инициализации
|
|
246
|
+
* @param _renderer - рендерер (должен реализовывать `IRenderable`)
|
|
127
247
|
*
|
|
128
248
|
* @internal
|
|
249
|
+
* @constructor
|
|
129
250
|
*/
|
|
130
|
-
|
|
131
|
-
this.
|
|
251
|
+
constructor(e, t, r, s) {
|
|
252
|
+
this._updatable = e, this._renderable = t, this._runtime = r, this._renderer = s;
|
|
132
253
|
}
|
|
133
254
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* @param obj - Объект, который необходимо удалить.
|
|
255
|
+
* ID анимационного цикла (для остановки)
|
|
137
256
|
*
|
|
138
|
-
* @
|
|
139
|
-
*
|
|
140
|
-
* удалить его напрямую из `this.scene`. В рамках данного API метод не отвечает за
|
|
141
|
-
* освобождение GPU-ресурсов; освобождайте геометрию/материалы отдельно при необходимости.
|
|
142
|
-
*
|
|
143
|
-
* @example
|
|
144
|
-
* // Снять оверлей со сцены:
|
|
145
|
-
* removeObject(overlayLine);
|
|
146
|
-
*
|
|
147
|
-
* @internal
|
|
257
|
+
* @private
|
|
258
|
+
* @member
|
|
148
259
|
*/
|
|
149
|
-
|
|
150
|
-
|
|
260
|
+
_animationId = null;
|
|
261
|
+
start() {
|
|
262
|
+
const e = [...this._runtime, ...this._updatable, ...this._renderable];
|
|
263
|
+
new Set(e).forEach((t) => t.init()), this._loop();
|
|
151
264
|
}
|
|
152
265
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* @param layer - Номер слоя, который требуется сделать видимым для камеры.
|
|
266
|
+
* Внутренний анимационный цикл.
|
|
156
267
|
*
|
|
157
268
|
* @remarks
|
|
158
|
-
*
|
|
159
|
-
*
|
|
269
|
+
* Каждый кадр:
|
|
270
|
+
* 1. Обновляет модули (`update()`)
|
|
271
|
+
* 2. Рендерит сцену
|
|
272
|
+
* 3. Рендерит дополнительные модули (`render()`)
|
|
160
273
|
*
|
|
161
|
-
* @
|
|
162
|
-
*
|
|
163
|
-
|
|
274
|
+
* @private
|
|
275
|
+
* @method
|
|
276
|
+
*/
|
|
277
|
+
_loop() {
|
|
278
|
+
this._updatable.forEach((e) => e.update()), this._renderer.render(), this._renderable.forEach((e) => e.render()), this._animationId = requestAnimationFrame(() => this._loop());
|
|
279
|
+
}
|
|
280
|
+
stop() {
|
|
281
|
+
this._animationId && (cancelAnimationFrame(this._animationId), this._animationId = null);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Освобождает ресурсы контроллера.
|
|
164
285
|
*
|
|
165
|
-
* @
|
|
286
|
+
* @public
|
|
287
|
+
* @method
|
|
166
288
|
*/
|
|
289
|
+
dispose() {
|
|
290
|
+
this._animationId = null;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
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);
|
|
303
|
+
return i;
|
|
304
|
+
}, gt = (e, t) => (r, s) => t(r, s, e);
|
|
305
|
+
let re = class {
|
|
306
|
+
/** @constructor */
|
|
307
|
+
constructor(e) {
|
|
308
|
+
this._sceneModule = e;
|
|
309
|
+
}
|
|
310
|
+
addMesh(e) {
|
|
311
|
+
this._sceneModule.addMesh(e);
|
|
312
|
+
}
|
|
313
|
+
addMeshes(e) {
|
|
314
|
+
this._sceneModule.addMeshes(e);
|
|
315
|
+
}
|
|
316
|
+
removeMesh(e) {
|
|
317
|
+
this._sceneModule.removeMesh(e);
|
|
318
|
+
}
|
|
319
|
+
removeMeshes(e) {
|
|
320
|
+
this._sceneModule.removeMeshes(e);
|
|
321
|
+
}
|
|
322
|
+
getMeshes() {
|
|
323
|
+
return this._sceneModule.getMeshes();
|
|
324
|
+
}
|
|
325
|
+
};
|
|
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);
|
|
333
|
+
return i;
|
|
334
|
+
}, Mt = (e, t) => (r, s) => t(r, s, e);
|
|
335
|
+
let ie = class {
|
|
336
|
+
/** @constructor */
|
|
337
|
+
constructor(e) {
|
|
338
|
+
this._raycastModule = e;
|
|
339
|
+
}
|
|
340
|
+
setRaycastMode(e) {
|
|
341
|
+
this._raycastModule.setRaycastMode(e);
|
|
342
|
+
}
|
|
343
|
+
};
|
|
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);
|
|
351
|
+
return i;
|
|
352
|
+
}, St = (e, t) => (r, s) => t(r, s, e);
|
|
353
|
+
let oe = class {
|
|
354
|
+
/** @constructor */
|
|
355
|
+
constructor(e) {
|
|
356
|
+
this._controlsModule = e;
|
|
357
|
+
}
|
|
358
|
+
attachTransform(e) {
|
|
359
|
+
this._controlsModule.attachTransform(e);
|
|
360
|
+
}
|
|
361
|
+
detachTransform() {
|
|
362
|
+
this._controlsModule.detachTransform();
|
|
363
|
+
}
|
|
364
|
+
setTransformMode(e) {
|
|
365
|
+
this._controlsModule.setTransformMode(e);
|
|
366
|
+
}
|
|
367
|
+
onTransformChange(e) {
|
|
368
|
+
return this._controlsModule.onTransformChange(e);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
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);
|
|
378
|
+
return i;
|
|
379
|
+
}, xt = (e, t) => (r, s) => t(r, s, e);
|
|
380
|
+
let ne = class {
|
|
381
|
+
constructor(e) {
|
|
382
|
+
this._cameraAccessApi = e;
|
|
383
|
+
}
|
|
384
|
+
getCamera() {
|
|
385
|
+
return this._cameraAccessApi.getCamera();
|
|
386
|
+
}
|
|
167
387
|
enableCameraLayer(e) {
|
|
168
|
-
this.
|
|
388
|
+
this._cameraAccessApi.getCamera().layers.enable(e);
|
|
169
389
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this.meshes && (this.meshes.length = 0, this.meshes = []), this.scene = null, this.camera = null, this.renderer?.dispose(), this.canvas = null;
|
|
390
|
+
disableCameraLayer(e) {
|
|
391
|
+
this._cameraAccessApi.getCamera().layers.disable(e);
|
|
173
392
|
}
|
|
174
|
-
}
|
|
175
|
-
var ct = Object.getOwnPropertyDescriptor, dt = (t, e, s, i) => {
|
|
176
|
-
for (var r = i > 1 ? void 0 : i ? ct(e, s) : e, o = t.length - 1, n; o >= 0; o--)
|
|
177
|
-
(n = t[o]) && (r = n(r) || r);
|
|
178
|
-
return r;
|
|
179
393
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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);
|
|
401
|
+
return i;
|
|
402
|
+
}, It = (e, t) => (r, s) => t(r, s, e);
|
|
403
|
+
let ae = class {
|
|
404
|
+
constructor(e) {
|
|
405
|
+
this._domAccessApi = e;
|
|
406
|
+
}
|
|
407
|
+
getCanvas() {
|
|
408
|
+
return this._domAccessApi.getCanvas();
|
|
409
|
+
}
|
|
410
|
+
getDomElement() {
|
|
411
|
+
return this._domAccessApi.getDomElement();
|
|
412
|
+
}
|
|
413
|
+
};
|
|
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);
|
|
421
|
+
return i;
|
|
422
|
+
}, Et = (e, t) => (r, s) => t(r, s, e);
|
|
423
|
+
let ce = class {
|
|
424
|
+
constructor(e) {
|
|
425
|
+
this._sceneAccessApi = e;
|
|
184
426
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
this._emitter.emit(t, e);
|
|
427
|
+
getScene() {
|
|
428
|
+
return this._sceneAccessApi.getScene();
|
|
188
429
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
this._emitter.on(t, e);
|
|
430
|
+
addToScene(e) {
|
|
431
|
+
this._sceneAccessApi.getScene().add(e);
|
|
192
432
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
433
|
+
removeFromScene(e) {
|
|
434
|
+
this._sceneAccessApi.getScene().remove(e);
|
|
435
|
+
}
|
|
436
|
+
addObject(e, t) {
|
|
437
|
+
const r = this._sceneAccessApi.getScene();
|
|
438
|
+
r && (typeof t == "number" && e.layers.set(t), r.add(e));
|
|
196
439
|
}
|
|
197
440
|
};
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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);
|
|
448
|
+
return i;
|
|
449
|
+
}, Vt = (e, t) => (r, s) => t(r, s, e);
|
|
450
|
+
let le = class {
|
|
451
|
+
/** @constructor */
|
|
452
|
+
constructor(e) {
|
|
453
|
+
this._controlsModule = e;
|
|
454
|
+
}
|
|
455
|
+
isOrbitInteracting() {
|
|
456
|
+
return this._controlsModule.isOrbitInteracting();
|
|
457
|
+
}
|
|
458
|
+
isTransformDragging() {
|
|
459
|
+
return this._controlsModule.isTransformDragging();
|
|
207
460
|
}
|
|
208
|
-
return null;
|
|
209
|
-
}, $e = (t) => {
|
|
210
|
-
const e = new a.BufferGeometry();
|
|
211
|
-
e.setAttribute("position", t.getAttribute("position")), e.computeBoundingSphere(), e.computeBoundingBox();
|
|
212
|
-
const s = new a.PointsMaterial({
|
|
213
|
-
color: gt,
|
|
214
|
-
size: 6,
|
|
215
|
-
sizeAttenuation: !1,
|
|
216
|
-
depthTest: !1,
|
|
217
|
-
depthWrite: !1,
|
|
218
|
-
transparent: !0,
|
|
219
|
-
opacity: 0.9
|
|
220
|
-
}), i = new a.Points(e, s);
|
|
221
|
-
return i.layers.set(mt), i.renderOrder = 1e3, i.visible = !1, i;
|
|
222
|
-
}, Ue = (t) => {
|
|
223
|
-
const e = new a.EdgesGeometry(t), s = new a.LineSegments(
|
|
224
|
-
e,
|
|
225
|
-
new a.LineBasicMaterial({ color: ft, linewidth: 1 })
|
|
226
|
-
);
|
|
227
|
-
return s.layers.set(pt), s;
|
|
228
|
-
}, vt = (t) => {
|
|
229
|
-
const e = { x: t.position.x, y: t.position.y, z: t.position.z }, s = { x: t.rotation.x, y: t.rotation.y, z: t.rotation.z }, i = { x: t.scale.x, y: t.scale.y, z: t.scale.z }, r = new a.Box3().setFromObject(t), o = new a.Vector3();
|
|
230
|
-
r.getSize(o);
|
|
231
|
-
const n = { x: o.x, y: o.y, z: o.z };
|
|
232
|
-
return { position: e, rotation: s, scale: i, size: n };
|
|
233
461
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.
|
|
246
|
-
size: 96,
|
|
247
|
-
// Размер квадрата
|
|
248
|
-
margin: 36
|
|
249
|
-
// Отступы по сторонам (снизу и справа)
|
|
250
|
-
}), this._raycaster = new a.Raycaster(), this._mouse = new a.Vector2(), this.scene.add(new a.HemisphereLight(16777215, 4473924, 0.6)), this.camera.layers.enable(0), this.camera.layers.enable(1), this._transform = new rt(this.camera, this.renderer.domElement), this._transformHelper = this._transform.getHelper(), this.scene.add(this._transformHelper), this._isEventListenersAdded || this._initMouseListeners();
|
|
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);
|
|
469
|
+
return i;
|
|
470
|
+
}, K = (e, t) => (r, s) => t(r, s, e);
|
|
471
|
+
let he = class {
|
|
472
|
+
constructor(e, t, r) {
|
|
473
|
+
this._cameraApi = e, this._domApi = t, this._sceneApi = r;
|
|
251
474
|
}
|
|
252
475
|
/** Orbit-контроллер для управления камерой */
|
|
253
|
-
_orbit;
|
|
476
|
+
_orbit = null;
|
|
254
477
|
/** Transform-контроллер для редактирования */
|
|
255
|
-
_transform;
|
|
256
|
-
_transformHelper;
|
|
257
|
-
|
|
258
|
-
_raycaster;
|
|
259
|
-
/** Курсор мыши */
|
|
260
|
-
_mouse;
|
|
478
|
+
_transform = null;
|
|
479
|
+
_transformHelper = null;
|
|
480
|
+
_transformListeners = /* @__PURE__ */ new Set();
|
|
261
481
|
/** Были ли инициализированы обработчики событий (hover/click) */
|
|
262
482
|
_isEventListenersAdded = !1;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
_currentRaycastMode = y.Mesh;
|
|
269
|
-
/** Gizmo для управления отображением perspective camera */
|
|
270
|
-
_cameraGizmo;
|
|
271
|
-
_transformListeners = /* @__PURE__ */ new Set();
|
|
272
|
-
/**
|
|
273
|
-
* Обновление состояния рендерера.
|
|
274
|
-
*/
|
|
275
|
-
update() {
|
|
276
|
-
this._orbit.update();
|
|
483
|
+
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(
|
|
485
|
+
this._cameraApi.getCamera(),
|
|
486
|
+
this._domApi.getDomElement()
|
|
487
|
+
), this._transformHelper = this._transform.getHelper(), this._sceneApi.addToScene(this._transformHelper), this._initMouseListeners();
|
|
277
488
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const e = super.addFigure(t);
|
|
281
|
-
e.layers.enable(J);
|
|
282
|
-
const s = Ue(e.geometry);
|
|
283
|
-
e.add(s);
|
|
284
|
-
const i = $e(e.geometry);
|
|
285
|
-
return e.add(i), e;
|
|
489
|
+
attachTransform(e) {
|
|
490
|
+
this._transform?.attach(e);
|
|
286
491
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
* @param mode - тип инструмента для отображения `TransformControls`.
|
|
290
|
-
* @internal
|
|
291
|
-
*/
|
|
292
|
-
setTransformControlsMode(t) {
|
|
293
|
-
this._transform.setMode(t);
|
|
492
|
+
detachTransform() {
|
|
493
|
+
this._transform?.detach();
|
|
294
494
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
* @param object - объект, к которому добавляются `TransformControls`.
|
|
298
|
-
* @internal
|
|
299
|
-
*/
|
|
300
|
-
attachTransformControls(t) {
|
|
301
|
-
this._transform.attach(t);
|
|
495
|
+
update() {
|
|
496
|
+
this._orbit?.update();
|
|
302
497
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
* @internal
|
|
306
|
-
*/
|
|
307
|
-
detachTransformControls() {
|
|
308
|
-
this._transform.detach();
|
|
498
|
+
setTransformMode(e) {
|
|
499
|
+
this._transform?.setMode(e);
|
|
309
500
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
* @internal
|
|
313
|
-
*/
|
|
314
|
-
onTransformChange(t) {
|
|
315
|
-
return this._transformListeners.add(t), () => this._transformListeners.delete(t);
|
|
501
|
+
onTransformChange(e) {
|
|
502
|
+
return this._transformListeners.add(e), () => this._transformListeners.delete(e);
|
|
316
503
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
* @internal
|
|
320
|
-
*/
|
|
321
|
-
setRaycastMode(t) {
|
|
322
|
-
const e = this._raycaster;
|
|
323
|
-
switch (e.params.Line.threshold = 0, e.params.Points.threshold = 0, this._currentRaycastMode = t, this._lastHoverKey = null, t) {
|
|
324
|
-
case y.Mesh:
|
|
325
|
-
case y.Face:
|
|
326
|
-
e.layers.set(0);
|
|
327
|
-
break;
|
|
328
|
-
case y.Edge:
|
|
329
|
-
e.layers.set(1), e.params.Line.threshold = _t;
|
|
330
|
-
break;
|
|
331
|
-
case y.Vertex:
|
|
332
|
-
e.layers.set(2), e.params.Points.threshold = ut;
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
504
|
+
isOrbitInteracting() {
|
|
505
|
+
return !!this._orbit?.isInteracting;
|
|
335
506
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
this._orbit.enabled = !this._transform.dragging;
|
|
339
|
-
}), this._transformListeners.clear(), this._isEventListenersAdded = !1), this._orbit?.dispose(), this._transform?.dispose(), this._transformHelper?.parent && this._transformHelper.parent.remove(this._transformHelper), this._lastHoverKey = null, super.dispose();
|
|
507
|
+
isTransformDragging() {
|
|
508
|
+
return !!this._transform?.dragging;
|
|
340
509
|
}
|
|
341
|
-
|
|
342
|
-
|
|
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);
|
|
343
520
|
}
|
|
344
521
|
/** Инициализация обработчиков событий на hover/click */
|
|
345
522
|
_initMouseListeners() {
|
|
346
|
-
|
|
347
|
-
|
|
523
|
+
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;
|
|
348
526
|
}), this._transform.addEventListener("objectChange", () => {
|
|
349
527
|
for (const t of this._transformListeners) t();
|
|
350
|
-
}), this._isEventListenersAdded = !0;
|
|
351
|
-
}
|
|
352
|
-
/** Обработчик события для hover */
|
|
353
|
-
_handleMouseMove = (t) => {
|
|
354
|
-
this._processRaycastEvent(t, H.SelectHover, !0);
|
|
355
|
-
};
|
|
356
|
-
/** Обработчик события на click */
|
|
357
|
-
_handleMouseClick = (t) => {
|
|
358
|
-
this._processRaycastEvent(t, H.SelectClick, !1);
|
|
359
|
-
};
|
|
360
|
-
/** Возвращает ближайшее пересечение по текущему положению курсора */
|
|
361
|
-
_getHitIntersection(t) {
|
|
362
|
-
if (this._orbit.isInteracting || this._transform.dragging) return;
|
|
363
|
-
const e = this._canvas.getBoundingClientRect();
|
|
364
|
-
this._mouse.x = (t.clientX - e.left) / e.width * 2 - 1, this._mouse.y = -((t.clientY - e.top) / e.height) * 2 + 1, this._raycaster.setFromCamera(this._mouse, this.camera);
|
|
365
|
-
const s = this._raycaster.intersectObjects(this.meshes, !0)[0] ?? null;
|
|
366
|
-
if (this._currentRaycastMode === y.Mesh || this._currentRaycastMode === y.Face)
|
|
367
|
-
return s;
|
|
368
|
-
const i = this._raycaster.layers.mask;
|
|
369
|
-
this._raycaster.layers.set(J);
|
|
370
|
-
const r = this._raycaster.intersectObjects(this.meshes, !0)[0] ?? null;
|
|
371
|
-
return this._raycaster.layers.mask = i, this._getVisibleHit(s, r);
|
|
372
|
-
}
|
|
373
|
-
_handleDoubleClick = (t) => {
|
|
374
|
-
const e = this._getHitIntersection(t);
|
|
375
|
-
e !== void 0 && (e || this._bus.emit(H.SelectClick, null));
|
|
376
|
-
};
|
|
377
|
-
// Hover сравнивается не только по object, но и по режимному ключу попадания.
|
|
378
|
-
// Это нужно для Face/Edge/Vertex режимов, где разные элементы могут принадлежать одному и тому же Object3D.
|
|
379
|
-
/** Вспомогательный метод для получения модели, которую выбрали и отправки события в event bus */
|
|
380
|
-
_processRaycastEvent(t, e, s) {
|
|
381
|
-
const i = this._getHitIntersection(t);
|
|
382
|
-
if (i === void 0) return;
|
|
383
|
-
const r = i?.object ?? null;
|
|
384
|
-
if (s) {
|
|
385
|
-
if (!i) {
|
|
386
|
-
this.meshes.forEach((n) => n.userData.isHit = !1), this._lastHoverKey = null, this._bus.emit(e, null);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
const o = this._makeHoverKey(i);
|
|
390
|
-
o !== this._lastHoverKey && (this.meshes.forEach((n) => n.userData.isHit = !1), r && (r.userData.isHit = !0), this._lastHoverKey = o, this._bus.emit(e, { intersection: i }));
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
i && this._bus.emit(e, { intersection: i });
|
|
394
|
-
}
|
|
395
|
-
/** Поиск видимой части меша
|
|
396
|
-
* необходимо это для того, чтобы отправлять только видимые элементы модели, а не все попадания
|
|
397
|
-
*/
|
|
398
|
-
_getVisibleHit(t, e, s = 1e-4) {
|
|
399
|
-
return t ? e ? t.distance <= e.distance + s ? t : null : t : null;
|
|
400
|
-
}
|
|
401
|
-
/** Строит ключ hover-пересечения с учетом текущего режима выборки */
|
|
402
|
-
_makeHoverKey(t) {
|
|
403
|
-
if (!t) return null;
|
|
404
|
-
const e = t.object.uuid;
|
|
405
|
-
switch (this._currentRaycastMode) {
|
|
406
|
-
case y.Face:
|
|
407
|
-
return `${e}:face:${t.faceIndex ?? -1}`;
|
|
408
|
-
case y.Edge:
|
|
409
|
-
return `${e}:edge:${Math.floor((t.index ?? -1) / 2)}`;
|
|
410
|
-
case y.Vertex:
|
|
411
|
-
return `${e}:vertex:${t.index ?? -1}`;
|
|
412
|
-
case y.Mesh:
|
|
413
|
-
default:
|
|
414
|
-
return `${e}:mesh`;
|
|
415
|
-
}
|
|
528
|
+
}), this._isEventListenersAdded = !0);
|
|
416
529
|
}
|
|
417
530
|
};
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}, K = 1e-6;
|
|
433
|
-
class St extends Ke {
|
|
434
|
-
/**
|
|
435
|
-
* Constructs a new controls instance.
|
|
436
|
-
*
|
|
437
|
-
* @param {Object3D} object - The object that is managed by the controls.
|
|
438
|
-
* @param {?HTMLElement} domElement - The HTML element used for event listeners.
|
|
439
|
-
*/
|
|
440
|
-
constructor(e, s = null) {
|
|
441
|
-
super(e, s), this.state = p.NONE, this.target = new I(), this.cursor = new I(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.keyRotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: Y.ROTATE, MIDDLE: Y.DOLLY, RIGHT: Y.PAN }, this.touches = { ONE: z.ROTATE, TWO: z.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this._lastPosition = new I(), this._lastQuaternion = new Ee(), this._lastTargetPosition = new I(), this._quat = new Ee().setFromUnitVectors(e.up, new I(0, 1, 0)), this._quatInverse = this._quat.clone().invert(), this._spherical = new xe(), this._sphericalDelta = new xe(), this._scale = 1, this._panOffset = new I(), this._rotateStart = new L(), this._rotateEnd = new L(), this._rotateDelta = new L(), this._panStart = new L(), this._panEnd = new L(), this._panDelta = new L(), this._dollyStart = new L(), this._dollyEnd = new L(), this._dollyDelta = new L(), this._dollyDirection = new I(), this._mouse = new L(), this._performCursorZoom = !1, this._pointers = [], this._pointerPositions = {}, this._controlActive = !1, this._onPointerMove = xt.bind(this), this._onPointerDown = Et.bind(this), this._onPointerUp = Pt.bind(this), this._onContextMenu = It.bind(this), this._onMouseWheel = Lt.bind(this), this._onKeyDown = Dt.bind(this), this._onTouchStart = Ct.bind(this), this._onTouchMove = At.bind(this), this._onMouseDown = Ot.bind(this), this._onMouseMove = Tt.bind(this), this._interceptControlDown = jt.bind(this), this._interceptControlUp = Rt.bind(this), this.domElement !== null && this.connect(this.domElement), this.update();
|
|
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);
|
|
540
|
+
return i;
|
|
541
|
+
}, Q = (e, t) => (r, s) => t(r, s, e);
|
|
542
|
+
let _e = class {
|
|
543
|
+
constructor(e, t, r) {
|
|
544
|
+
this._cameraApi = e, this._domApi = t, this._rendererApi = r;
|
|
442
545
|
}
|
|
443
|
-
|
|
444
|
-
|
|
546
|
+
/** Gizmo для управления отображением perspective camera */
|
|
547
|
+
_cameraGizmo = null;
|
|
548
|
+
init() {
|
|
549
|
+
const e = this._cameraApi.getCamera(), t = this._rendererApi.getRenderer();
|
|
550
|
+
this._cameraGizmo = new ot(t, e, {
|
|
551
|
+
size: 96,
|
|
552
|
+
// Размер квадрата
|
|
553
|
+
margin: 36
|
|
554
|
+
// Отступы по сторонам (снизу и справа)
|
|
555
|
+
});
|
|
445
556
|
}
|
|
446
|
-
|
|
447
|
-
|
|
557
|
+
render() {
|
|
558
|
+
const e = this._domApi.getCanvas();
|
|
559
|
+
this._cameraGizmo?.render(e.width, e.height);
|
|
448
560
|
}
|
|
561
|
+
/** Освобождение ресурсов модуля */
|
|
449
562
|
dispose() {
|
|
450
|
-
this.
|
|
563
|
+
this._cameraGizmo?.dispose(), this._cameraGizmo = null;
|
|
451
564
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
565
|
+
};
|
|
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);
|
|
577
|
+
return i;
|
|
578
|
+
}, R = (e, t) => (r, s) => t(r, s, e);
|
|
579
|
+
let de = class {
|
|
580
|
+
constructor(e, t, r, s, i) {
|
|
581
|
+
this._domApi = e, this._cameraApi = t, this._meshApi = r, this._controlsState = s, this._bus = i;
|
|
459
582
|
}
|
|
460
583
|
/**
|
|
461
|
-
*
|
|
584
|
+
* Raycast для получения событий наведения/клика по модели
|
|
462
585
|
*
|
|
463
|
-
* @
|
|
586
|
+
* @private
|
|
587
|
+
* @member
|
|
464
588
|
*/
|
|
465
|
-
|
|
466
|
-
return this._spherical.theta;
|
|
467
|
-
}
|
|
589
|
+
_raycaster;
|
|
468
590
|
/**
|
|
469
|
-
*
|
|
591
|
+
* Курсор мыши
|
|
470
592
|
*
|
|
471
|
-
* @
|
|
593
|
+
* @private
|
|
594
|
+
* @member
|
|
472
595
|
*/
|
|
473
|
-
|
|
474
|
-
return this.object.position.distanceTo(this.target);
|
|
475
|
-
}
|
|
596
|
+
_mouse;
|
|
476
597
|
/**
|
|
477
|
-
*
|
|
478
|
-
*
|
|
598
|
+
* Ключ последней модели, на которую наводились,
|
|
599
|
+
* необходим для отправки только уникальных событий в event bus
|
|
479
600
|
*
|
|
480
|
-
* @
|
|
601
|
+
* @private
|
|
602
|
+
* @member
|
|
481
603
|
*/
|
|
482
|
-
|
|
483
|
-
e.addEventListener("keydown", this._onKeyDown), this._domElementKeyEvents = e;
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Removes the key event listener previously defined with `listenToKeyEvents()`.
|
|
487
|
-
*/
|
|
488
|
-
stopListenToKeyEvents() {
|
|
489
|
-
this._domElementKeyEvents !== null && (this._domElementKeyEvents.removeEventListener("keydown", this._onKeyDown), this._domElementKeyEvents = null);
|
|
490
|
-
}
|
|
604
|
+
_lastHoverKey = null;
|
|
491
605
|
/**
|
|
492
|
-
*
|
|
606
|
+
* Текуший режим для raycaster
|
|
607
|
+
*
|
|
608
|
+
* @private
|
|
609
|
+
* @member
|
|
493
610
|
*/
|
|
494
|
-
|
|
495
|
-
this.target0.copy(this.target), this.position0.copy(this.object.position), this.zoom0 = this.object.zoom;
|
|
496
|
-
}
|
|
611
|
+
_currentRaycastMode = M.Mesh;
|
|
497
612
|
/**
|
|
498
|
-
*
|
|
499
|
-
*
|
|
613
|
+
* Были ли инициализированы обработчики событий (hover/click)
|
|
614
|
+
*
|
|
615
|
+
* @private
|
|
616
|
+
* @member
|
|
500
617
|
*/
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
update(e = null) {
|
|
505
|
-
const s = this.object.position;
|
|
506
|
-
v.copy(s).sub(this.target), v.applyQuaternion(this._quat), this._spherical.setFromVector3(v), this.autoRotate && this.state === p.NONE && this._rotateLeft(this._getAutoRotationAngle(e)), this.enableDamping ? (this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor, this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor) : (this._spherical.theta += this._sphericalDelta.theta, this._spherical.phi += this._sphericalDelta.phi);
|
|
507
|
-
let i = this.minAzimuthAngle, r = this.maxAzimuthAngle;
|
|
508
|
-
isFinite(i) && isFinite(r) && (i < -Math.PI ? i += P : i > Math.PI && (i -= P), r < -Math.PI ? r += P : r > Math.PI && (r -= P), i <= r ? this._spherical.theta = Math.max(i, Math.min(r, this._spherical.theta)) : this._spherical.theta = this._spherical.theta > (i + r) / 2 ? Math.max(i, this._spherical.theta) : Math.min(r, this._spherical.theta)), this._spherical.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this._spherical.phi)), this._spherical.makeSafe(), this.enableDamping === !0 ? this.target.addScaledVector(this._panOffset, this.dampingFactor) : this.target.add(this._panOffset), this.target.sub(this.cursor), this.target.clampLength(this.minTargetRadius, this.maxTargetRadius), this.target.add(this.cursor);
|
|
509
|
-
let o = !1;
|
|
510
|
-
if (this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera)
|
|
511
|
-
this._spherical.radius = this._clampDistance(this._spherical.radius);
|
|
512
|
-
else {
|
|
513
|
-
const n = this._spherical.radius;
|
|
514
|
-
this._spherical.radius = this._clampDistance(this._spherical.radius * this._scale), o = n != this._spherical.radius;
|
|
515
|
-
}
|
|
516
|
-
if (v.setFromSpherical(this._spherical), v.applyQuaternion(this._quatInverse), s.copy(this.target).add(v), this.object.lookAt(this.target), this.enableDamping === !0 ? (this._sphericalDelta.theta *= 1 - this.dampingFactor, this._sphericalDelta.phi *= 1 - this.dampingFactor, this._panOffset.multiplyScalar(1 - this.dampingFactor)) : (this._sphericalDelta.set(0, 0, 0), this._panOffset.set(0, 0, 0)), this.zoomToCursor && this._performCursorZoom) {
|
|
517
|
-
let n = null;
|
|
518
|
-
if (this.object.isPerspectiveCamera) {
|
|
519
|
-
const h = v.length();
|
|
520
|
-
n = this._clampDistance(h * this._scale);
|
|
521
|
-
const l = h - n;
|
|
522
|
-
this.object.position.addScaledVector(this._dollyDirection, l), this.object.updateMatrixWorld(), o = !!l;
|
|
523
|
-
} else if (this.object.isOrthographicCamera) {
|
|
524
|
-
const h = new I(this._mouse.x, this._mouse.y, 0);
|
|
525
|
-
h.unproject(this.object);
|
|
526
|
-
const l = this.object.zoom;
|
|
527
|
-
this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)), this.object.updateProjectionMatrix(), o = l !== this.object.zoom;
|
|
528
|
-
const c = new I(this._mouse.x, this._mouse.y, 0);
|
|
529
|
-
c.unproject(this.object), this.object.position.sub(c).add(h), this.object.updateMatrixWorld(), n = v.length();
|
|
530
|
-
} else
|
|
531
|
-
console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), this.zoomToCursor = !1;
|
|
532
|
-
n !== null && (this.screenSpacePanning ? this.target.set(0, 0, -1).transformDirection(this.object.matrix).multiplyScalar(n).add(this.object.position) : (B.origin.copy(this.object.position), B.direction.set(0, 0, -1).transformDirection(this.object.matrix), Math.abs(this.object.up.dot(B.direction)) < wt ? this.object.lookAt(this.target) : (Le.setFromNormalAndCoplanarPoint(this.object.up, this.target), B.intersectPlane(Le, this.target))));
|
|
533
|
-
} else if (this.object.isOrthographicCamera) {
|
|
534
|
-
const n = this.object.zoom;
|
|
535
|
-
this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)), n !== this.object.zoom && (this.object.updateProjectionMatrix(), o = !0);
|
|
536
|
-
}
|
|
537
|
-
return this._scale = 1, this._performCursorZoom = !1, o || this._lastPosition.distanceToSquared(this.object.position) > K || 8 * (1 - this._lastQuaternion.dot(this.object.quaternion)) > K || this._lastTargetPosition.distanceToSquared(this.target) > K ? (this.dispatchEvent(Te), this._lastPosition.copy(this.object.position), this._lastQuaternion.copy(this.object.quaternion), this._lastTargetPosition.copy(this.target), !0) : !1;
|
|
538
|
-
}
|
|
539
|
-
_getAutoRotationAngle(e) {
|
|
540
|
-
return e !== null ? P / 60 * this.autoRotateSpeed * e : P / 60 / 60 * this.autoRotateSpeed;
|
|
541
|
-
}
|
|
542
|
-
_getZoomScale(e) {
|
|
543
|
-
const s = Math.abs(e * 0.01);
|
|
544
|
-
return Math.pow(0.95, this.zoomSpeed * s);
|
|
545
|
-
}
|
|
546
|
-
_rotateLeft(e) {
|
|
547
|
-
this._sphericalDelta.theta -= e;
|
|
548
|
-
}
|
|
549
|
-
_rotateUp(e) {
|
|
550
|
-
this._sphericalDelta.phi -= e;
|
|
551
|
-
}
|
|
552
|
-
_panLeft(e, s) {
|
|
553
|
-
v.setFromMatrixColumn(s, 0), v.multiplyScalar(-e), this._panOffset.add(v);
|
|
554
|
-
}
|
|
555
|
-
_panUp(e, s) {
|
|
556
|
-
this.screenSpacePanning === !0 ? v.setFromMatrixColumn(s, 1) : (v.setFromMatrixColumn(s, 0), v.crossVectors(this.object.up, v)), v.multiplyScalar(e), this._panOffset.add(v);
|
|
557
|
-
}
|
|
558
|
-
// deltaX and deltaY are in pixels; right and down are positive
|
|
559
|
-
_pan(e, s) {
|
|
560
|
-
const i = this.domElement;
|
|
561
|
-
if (this.object.isPerspectiveCamera) {
|
|
562
|
-
const r = this.object.position;
|
|
563
|
-
v.copy(r).sub(this.target);
|
|
564
|
-
let o = v.length();
|
|
565
|
-
o *= Math.tan(this.object.fov / 2 * Math.PI / 180), this._panLeft(2 * e * o / i.clientHeight, this.object.matrix), this._panUp(2 * s * o / i.clientHeight, this.object.matrix);
|
|
566
|
-
} else this.object.isOrthographicCamera ? (this._panLeft(e * (this.object.right - this.object.left) / this.object.zoom / i.clientWidth, this.object.matrix), this._panUp(s * (this.object.top - this.object.bottom) / this.object.zoom / i.clientHeight, this.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), this.enablePan = !1);
|
|
567
|
-
}
|
|
568
|
-
_dollyOut(e) {
|
|
569
|
-
this.object.isPerspectiveCamera || this.object.isOrthographicCamera ? this._scale /= e : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), this.enableZoom = !1);
|
|
570
|
-
}
|
|
571
|
-
_dollyIn(e) {
|
|
572
|
-
this.object.isPerspectiveCamera || this.object.isOrthographicCamera ? this._scale *= e : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), this.enableZoom = !1);
|
|
573
|
-
}
|
|
574
|
-
_updateZoomParameters(e, s) {
|
|
575
|
-
if (!this.zoomToCursor)
|
|
576
|
-
return;
|
|
577
|
-
this._performCursorZoom = !0;
|
|
578
|
-
const i = this.domElement.getBoundingClientRect(), r = e - i.left, o = s - i.top, n = i.width, h = i.height;
|
|
579
|
-
this._mouse.x = r / n * 2 - 1, this._mouse.y = -(o / h) * 2 + 1, this._dollyDirection.set(this._mouse.x, this._mouse.y, 1).unproject(this.object).sub(this.object.position).normalize();
|
|
580
|
-
}
|
|
581
|
-
_clampDistance(e) {
|
|
582
|
-
return Math.max(this.minDistance, Math.min(this.maxDistance, e));
|
|
583
|
-
}
|
|
584
|
-
//
|
|
585
|
-
// event callbacks - update the object state
|
|
586
|
-
//
|
|
587
|
-
_handleMouseDownRotate(e) {
|
|
588
|
-
this._rotateStart.set(e.clientX, e.clientY);
|
|
589
|
-
}
|
|
590
|
-
_handleMouseDownDolly(e) {
|
|
591
|
-
this._updateZoomParameters(e.clientX, e.clientX), this._dollyStart.set(e.clientX, e.clientY);
|
|
592
|
-
}
|
|
593
|
-
_handleMouseDownPan(e) {
|
|
594
|
-
this._panStart.set(e.clientX, e.clientY);
|
|
595
|
-
}
|
|
596
|
-
_handleMouseMoveRotate(e) {
|
|
597
|
-
this._rotateEnd.set(e.clientX, e.clientY), this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed);
|
|
598
|
-
const s = this.domElement;
|
|
599
|
-
this._rotateLeft(P * this._rotateDelta.x / s.clientHeight), this._rotateUp(P * this._rotateDelta.y / s.clientHeight), this._rotateStart.copy(this._rotateEnd), this.update();
|
|
600
|
-
}
|
|
601
|
-
_handleMouseMoveDolly(e) {
|
|
602
|
-
this._dollyEnd.set(e.clientX, e.clientY), this._dollyDelta.subVectors(this._dollyEnd, this._dollyStart), this._dollyDelta.y > 0 ? this._dollyOut(this._getZoomScale(this._dollyDelta.y)) : this._dollyDelta.y < 0 && this._dollyIn(this._getZoomScale(this._dollyDelta.y)), this._dollyStart.copy(this._dollyEnd), this.update();
|
|
603
|
-
}
|
|
604
|
-
_handleMouseMovePan(e) {
|
|
605
|
-
this._panEnd.set(e.clientX, e.clientY), this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed), this._pan(this._panDelta.x, this._panDelta.y), this._panStart.copy(this._panEnd), this.update();
|
|
618
|
+
_isEventListenersAdded = !1;
|
|
619
|
+
init() {
|
|
620
|
+
this._raycaster = new a.Raycaster(), this._mouse = new a.Vector2(), this._applyRaycastParamsByMode(), this._isEventListenersAdded || (this._initMouseListeners(), this._isEventListenersAdded = !0);
|
|
606
621
|
}
|
|
607
|
-
|
|
608
|
-
|
|
622
|
+
setRaycastMode(e) {
|
|
623
|
+
if (this._currentRaycastMode === e) return;
|
|
624
|
+
const t = this._raycaster;
|
|
625
|
+
t.params.Line.threshold = 0, t.params.Points.threshold = 0, this._currentRaycastMode = e, this._lastHoverKey = null, this._applyRaycastParamsByMode();
|
|
609
626
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateUp(-P * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(0, -this.keyPanSpeed), s = !0;
|
|
627
|
+
/** Применяет параметры raycaster в зависимости от текущего режима */
|
|
628
|
+
_applyRaycastParamsByMode() {
|
|
629
|
+
const e = this._raycaster;
|
|
630
|
+
switch (e.params.Line.threshold = 0, e.params.Points.threshold = 0, this._currentRaycastMode) {
|
|
631
|
+
case M.Mesh:
|
|
632
|
+
case M.Face:
|
|
633
|
+
e.layers.set(k);
|
|
618
634
|
break;
|
|
619
|
-
case
|
|
620
|
-
e.
|
|
635
|
+
case M.Edge:
|
|
636
|
+
e.layers.set(Ue), e.params.Line.threshold = Ft;
|
|
621
637
|
break;
|
|
622
|
-
case
|
|
623
|
-
e.
|
|
638
|
+
case M.Vertex:
|
|
639
|
+
e.layers.set(Xe), e.params.Points.threshold = Wt;
|
|
624
640
|
break;
|
|
625
641
|
}
|
|
626
|
-
s && (e.preventDefault(), this.update());
|
|
627
|
-
}
|
|
628
|
-
_handleTouchStartRotate(e) {
|
|
629
|
-
if (this._pointers.length === 1)
|
|
630
|
-
this._rotateStart.set(e.pageX, e.pageY);
|
|
631
|
-
else {
|
|
632
|
-
const s = this._getSecondPointerPosition(e), i = 0.5 * (e.pageX + s.x), r = 0.5 * (e.pageY + s.y);
|
|
633
|
-
this._rotateStart.set(i, r);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
_handleTouchStartPan(e) {
|
|
637
|
-
if (this._pointers.length === 1)
|
|
638
|
-
this._panStart.set(e.pageX, e.pageY);
|
|
639
|
-
else {
|
|
640
|
-
const s = this._getSecondPointerPosition(e), i = 0.5 * (e.pageX + s.x), r = 0.5 * (e.pageY + s.y);
|
|
641
|
-
this._panStart.set(i, r);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
_handleTouchStartDolly(e) {
|
|
645
|
-
const s = this._getSecondPointerPosition(e), i = e.pageX - s.x, r = e.pageY - s.y, o = Math.sqrt(i * i + r * r);
|
|
646
|
-
this._dollyStart.set(0, o);
|
|
647
|
-
}
|
|
648
|
-
_handleTouchStartDollyPan(e) {
|
|
649
|
-
this.enableZoom && this._handleTouchStartDolly(e), this.enablePan && this._handleTouchStartPan(e);
|
|
650
|
-
}
|
|
651
|
-
_handleTouchStartDollyRotate(e) {
|
|
652
|
-
this.enableZoom && this._handleTouchStartDolly(e), this.enableRotate && this._handleTouchStartRotate(e);
|
|
653
|
-
}
|
|
654
|
-
_handleTouchMoveRotate(e) {
|
|
655
|
-
if (this._pointers.length == 1)
|
|
656
|
-
this._rotateEnd.set(e.pageX, e.pageY);
|
|
657
|
-
else {
|
|
658
|
-
const i = this._getSecondPointerPosition(e), r = 0.5 * (e.pageX + i.x), o = 0.5 * (e.pageY + i.y);
|
|
659
|
-
this._rotateEnd.set(r, o);
|
|
660
|
-
}
|
|
661
|
-
this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed);
|
|
662
|
-
const s = this.domElement;
|
|
663
|
-
this._rotateLeft(P * this._rotateDelta.x / s.clientHeight), this._rotateUp(P * this._rotateDelta.y / s.clientHeight), this._rotateStart.copy(this._rotateEnd);
|
|
664
|
-
}
|
|
665
|
-
_handleTouchMovePan(e) {
|
|
666
|
-
if (this._pointers.length === 1)
|
|
667
|
-
this._panEnd.set(e.pageX, e.pageY);
|
|
668
|
-
else {
|
|
669
|
-
const s = this._getSecondPointerPosition(e), i = 0.5 * (e.pageX + s.x), r = 0.5 * (e.pageY + s.y);
|
|
670
|
-
this._panEnd.set(i, r);
|
|
671
|
-
}
|
|
672
|
-
this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed), this._pan(this._panDelta.x, this._panDelta.y), this._panStart.copy(this._panEnd);
|
|
673
|
-
}
|
|
674
|
-
_handleTouchMoveDolly(e) {
|
|
675
|
-
const s = this._getSecondPointerPosition(e), i = e.pageX - s.x, r = e.pageY - s.y, o = Math.sqrt(i * i + r * r);
|
|
676
|
-
this._dollyEnd.set(0, o), this._dollyDelta.set(0, Math.pow(this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed)), this._dollyOut(this._dollyDelta.y), this._dollyStart.copy(this._dollyEnd);
|
|
677
|
-
const n = (e.pageX + s.x) * 0.5, h = (e.pageY + s.y) * 0.5;
|
|
678
|
-
this._updateZoomParameters(n, h);
|
|
679
642
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
643
|
+
/** Возвращает ближайшее пересечение по текущему положению курсора */
|
|
644
|
+
_getHitIntersection(e) {
|
|
645
|
+
const t = this._controlsState.isOrbitInteracting() || this._controlsState.isTransformDragging(), r = this._domApi.getCanvas(), s = this._cameraApi.getCamera(), i = this._meshApi.getMeshes();
|
|
646
|
+
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;
|
|
653
|
+
this._raycaster.layers.set(k);
|
|
654
|
+
const _ = this._raycaster.intersectObjects(i, !0)[0] ?? null;
|
|
655
|
+
return this._raycaster.layers.mask = c, this._getVisibleHit(n, _);
|
|
689
656
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
657
|
+
// Hover сравнивается не только по object, но и по режимному ключу попадания.
|
|
658
|
+
// Это нужно для Face/Edge/Vertex режимов, где разные элементы могут принадлежать одному и тому же Object3D.
|
|
659
|
+
/** Вспомогательный метод для получения модели, которую выбрали и отправки события в event bus */
|
|
660
|
+
_processRaycastEvent(e, t, r) {
|
|
661
|
+
const s = this._getHitIntersection(e), i = this._meshApi.getMeshes();
|
|
662
|
+
if (s === void 0) return;
|
|
663
|
+
const o = s?.object ?? null;
|
|
664
|
+
if (r) {
|
|
665
|
+
if (!s) {
|
|
666
|
+
i.forEach((c) => c.userData.isHit = !1), this._lastHoverKey = null, this._bus.emit(t, null);
|
|
695
667
|
return;
|
|
696
668
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
if (this._pointers[s] == e.pointerId) return !0;
|
|
701
|
-
return !1;
|
|
702
|
-
}
|
|
703
|
-
_trackPointer(e) {
|
|
704
|
-
let s = this._pointerPositions[e.pointerId];
|
|
705
|
-
s === void 0 && (s = new L(), this._pointerPositions[e.pointerId] = s), s.set(e.pageX, e.pageY);
|
|
706
|
-
}
|
|
707
|
-
_getSecondPointerPosition(e) {
|
|
708
|
-
const s = e.pointerId === this._pointers[0] ? this._pointers[1] : this._pointers[0];
|
|
709
|
-
return this._pointerPositions[s];
|
|
710
|
-
}
|
|
711
|
-
//
|
|
712
|
-
_customWheelEvent(e) {
|
|
713
|
-
const s = e.deltaMode, i = {
|
|
714
|
-
clientX: e.clientX,
|
|
715
|
-
clientY: e.clientY,
|
|
716
|
-
deltaY: e.deltaY
|
|
717
|
-
};
|
|
718
|
-
switch (s) {
|
|
719
|
-
case 1:
|
|
720
|
-
i.deltaY *= 16;
|
|
721
|
-
break;
|
|
722
|
-
case 2:
|
|
723
|
-
i.deltaY *= 100;
|
|
724
|
-
break;
|
|
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 }));
|
|
671
|
+
return;
|
|
725
672
|
}
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
function Et(t) {
|
|
730
|
-
this.enabled !== !1 && (this._pointers.length === 0 && (this.domElement.setPointerCapture(t.pointerId), this.domElement.addEventListener("pointermove", this._onPointerMove), this.domElement.addEventListener("pointerup", this._onPointerUp)), !this._isTrackingPointer(t) && (this._addPointer(t), t.pointerType === "touch" ? this._onTouchStart(t) : this._onMouseDown(t)));
|
|
731
|
-
}
|
|
732
|
-
function xt(t) {
|
|
733
|
-
this.enabled !== !1 && (t.pointerType === "touch" ? this._onTouchMove(t) : this._onMouseMove(t));
|
|
734
|
-
}
|
|
735
|
-
function Pt(t) {
|
|
736
|
-
switch (this._removePointer(t), this._pointers.length) {
|
|
737
|
-
case 0:
|
|
738
|
-
this.domElement.releasePointerCapture(t.pointerId), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.dispatchEvent(Be), this.state = p.NONE;
|
|
739
|
-
break;
|
|
740
|
-
case 1:
|
|
741
|
-
const e = this._pointers[0], s = this._pointerPositions[e];
|
|
742
|
-
this._onTouchStart({ pointerId: e, pageX: s.x, pageY: s.y });
|
|
743
|
-
break;
|
|
673
|
+
s && this._bus.emit(t, { intersection: s });
|
|
744
674
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
e = this.mouseButtons.LEFT;
|
|
751
|
-
break;
|
|
752
|
-
case 1:
|
|
753
|
-
e = this.mouseButtons.MIDDLE;
|
|
754
|
-
break;
|
|
755
|
-
case 2:
|
|
756
|
-
e = this.mouseButtons.RIGHT;
|
|
757
|
-
break;
|
|
758
|
-
default:
|
|
759
|
-
e = -1;
|
|
760
|
-
}
|
|
761
|
-
switch (e) {
|
|
762
|
-
case Y.DOLLY:
|
|
763
|
-
if (this.enableZoom === !1) return;
|
|
764
|
-
this._handleMouseDownDolly(t), this.state = p.DOLLY;
|
|
765
|
-
break;
|
|
766
|
-
case Y.ROTATE:
|
|
767
|
-
if (t.ctrlKey || t.metaKey || t.shiftKey) {
|
|
768
|
-
if (this.enablePan === !1) return;
|
|
769
|
-
this._handleMouseDownPan(t), this.state = p.PAN;
|
|
770
|
-
} else {
|
|
771
|
-
if (this.enableRotate === !1) return;
|
|
772
|
-
this._handleMouseDownRotate(t), this.state = p.ROTATE;
|
|
773
|
-
}
|
|
774
|
-
break;
|
|
775
|
-
case Y.PAN:
|
|
776
|
-
if (t.ctrlKey || t.metaKey || t.shiftKey) {
|
|
777
|
-
if (this.enableRotate === !1) return;
|
|
778
|
-
this._handleMouseDownRotate(t), this.state = p.ROTATE;
|
|
779
|
-
} else {
|
|
780
|
-
if (this.enablePan === !1) return;
|
|
781
|
-
this._handleMouseDownPan(t), this.state = p.PAN;
|
|
782
|
-
}
|
|
783
|
-
break;
|
|
784
|
-
default:
|
|
785
|
-
this.state = p.NONE;
|
|
675
|
+
/** Поиск видимой части меша
|
|
676
|
+
* необходимо это для того, чтобы отправлять только видимые элементы модели, а не все попадания
|
|
677
|
+
*/
|
|
678
|
+
_getVisibleHit(e, t, r = 1e-4) {
|
|
679
|
+
return e ? t ? e.distance <= t.distance + r ? e : null : e : null;
|
|
786
680
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
break;
|
|
681
|
+
/** Строит ключ hover-пересечения с учетом текущего режима выборки */
|
|
682
|
+
_makeHoverKey(e) {
|
|
683
|
+
if (!e) return null;
|
|
684
|
+
const t = e.object.uuid;
|
|
685
|
+
switch (this._currentRaycastMode) {
|
|
686
|
+
case M.Face:
|
|
687
|
+
return `${t}:face:${e.faceIndex ?? -1}`;
|
|
688
|
+
case M.Edge:
|
|
689
|
+
return `${t}:edge:${Math.floor((e.index ?? -1) / 2)}`;
|
|
690
|
+
case M.Vertex:
|
|
691
|
+
return `${t}:vertex:${e.index ?? -1}`;
|
|
692
|
+
case M.Mesh:
|
|
693
|
+
default:
|
|
694
|
+
return `${t}:mesh`;
|
|
695
|
+
}
|
|
803
696
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}
|
|
826
|
-
break;
|
|
827
|
-
case 2:
|
|
828
|
-
switch (this.touches.TWO) {
|
|
829
|
-
case z.DOLLY_PAN:
|
|
830
|
-
if (this.enableZoom === !1 && this.enablePan === !1) return;
|
|
831
|
-
this._handleTouchStartDollyPan(t), this.state = p.TOUCH_DOLLY_PAN;
|
|
832
|
-
break;
|
|
833
|
-
case z.DOLLY_ROTATE:
|
|
834
|
-
if (this.enableZoom === !1 && this.enableRotate === !1) return;
|
|
835
|
-
this._handleTouchStartDollyRotate(t), this.state = p.TOUCH_DOLLY_ROTATE;
|
|
836
|
-
break;
|
|
837
|
-
default:
|
|
838
|
-
this.state = p.NONE;
|
|
839
|
-
}
|
|
840
|
-
break;
|
|
841
|
-
default:
|
|
842
|
-
this.state = p.NONE;
|
|
697
|
+
/** Обработчик события для hover */
|
|
698
|
+
_handleMouseMove = (e) => {
|
|
699
|
+
this._processRaycastEvent(e, V.SelectHover, !0);
|
|
700
|
+
};
|
|
701
|
+
/** Обработчик события на click */
|
|
702
|
+
_handleMouseClick = (e) => {
|
|
703
|
+
this._processRaycastEvent(e, V.SelectClick, !1);
|
|
704
|
+
};
|
|
705
|
+
/** Обработчик двойного клика */
|
|
706
|
+
_handleDoubleClick = (e) => {
|
|
707
|
+
const t = this._getHitIntersection(e);
|
|
708
|
+
t !== void 0 && (t || this._bus.emit(V.SelectClick, null));
|
|
709
|
+
};
|
|
710
|
+
/** Обработчик ухода курсора с canvas */
|
|
711
|
+
_handleMouseLeave = () => {
|
|
712
|
+
this._lastHoverKey = null, this._bus.emit(V.SelectHover, null);
|
|
713
|
+
};
|
|
714
|
+
/** Инициализация обработчиков событий на hover/click */
|
|
715
|
+
_initMouseListeners() {
|
|
716
|
+
const e = this._domApi.getCanvas();
|
|
717
|
+
e.addEventListener("mousemove", this._handleMouseMove, !1), e.addEventListener("click", this._handleMouseClick, !1), e.addEventListener("dblclick", this._handleDoubleClick, !1), e.addEventListener("mouseleave", this._handleMouseLeave), this._isEventListenersAdded = !0;
|
|
843
718
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
switch (this._trackPointer(t), this.state) {
|
|
848
|
-
case p.TOUCH_ROTATE:
|
|
849
|
-
if (this.enableRotate === !1) return;
|
|
850
|
-
this._handleTouchMoveRotate(t), this.update();
|
|
851
|
-
break;
|
|
852
|
-
case p.TOUCH_PAN:
|
|
853
|
-
if (this.enablePan === !1) return;
|
|
854
|
-
this._handleTouchMovePan(t), this.update();
|
|
855
|
-
break;
|
|
856
|
-
case p.TOUCH_DOLLY_PAN:
|
|
857
|
-
if (this.enableZoom === !1 && this.enablePan === !1) return;
|
|
858
|
-
this._handleTouchMoveDollyPan(t), this.update();
|
|
859
|
-
break;
|
|
860
|
-
case p.TOUCH_DOLLY_ROTATE:
|
|
861
|
-
if (this.enableZoom === !1 && this.enableRotate === !1) return;
|
|
862
|
-
this._handleTouchMoveDollyRotate(t), this.update();
|
|
863
|
-
break;
|
|
864
|
-
default:
|
|
865
|
-
this.state = p.NONE;
|
|
719
|
+
_removeMouseListeners() {
|
|
720
|
+
const e = this._domApi.getCanvas();
|
|
721
|
+
e.removeEventListener("mousemove", this._handleMouseMove), e.removeEventListener("click", this._handleMouseClick), e.removeEventListener("dblclick", this._handleDoubleClick), e.removeEventListener("mouseleave", this._handleMouseLeave);
|
|
866
722
|
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
723
|
+
dispose() {
|
|
724
|
+
this._removeMouseListeners(), this._isEventListenersAdded = !1, this._lastHoverKey = null;
|
|
725
|
+
}
|
|
726
|
+
};
|
|
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);
|
|
738
|
+
return i;
|
|
739
|
+
}, Nt = (e, t) => (r, s) => t(r, s, e);
|
|
740
|
+
let ue = class {
|
|
880
741
|
constructor(e) {
|
|
881
|
-
|
|
742
|
+
this._api = e;
|
|
743
|
+
}
|
|
744
|
+
/** Объекты редактора, участвующие в raycast и редактировании */
|
|
745
|
+
_meshes = [];
|
|
746
|
+
/** Сетка сцены */
|
|
747
|
+
_grid = null;
|
|
748
|
+
/** Оси сцены */
|
|
749
|
+
_axes = null;
|
|
750
|
+
/** Базовый свет сцены */
|
|
751
|
+
_light = null;
|
|
752
|
+
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);
|
|
882
754
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
*/
|
|
886
|
-
update() {
|
|
887
|
-
this._orbit?.update();
|
|
755
|
+
getMeshes() {
|
|
756
|
+
return this._meshes;
|
|
888
757
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
/** Позиции вершин */
|
|
892
|
-
_positions = [];
|
|
893
|
-
/** Нормали вершин */
|
|
894
|
-
_normals = [];
|
|
895
|
-
/** UV-координаты (опционально) */
|
|
896
|
-
_uvs = [];
|
|
897
|
-
// Временные поля для парсинга файла
|
|
898
|
-
_tmpPositions = [];
|
|
899
|
-
_tmpNormals = [];
|
|
900
|
-
_tmpUVs = [];
|
|
901
|
-
/**
|
|
902
|
-
* Загружает OBJ-модель в Figure
|
|
903
|
-
* @param objContent - Строка содержимого .obj файла
|
|
904
|
-
*/
|
|
905
|
-
load(e) {
|
|
906
|
-
const s = e.split(`
|
|
907
|
-
`);
|
|
908
|
-
for (const r of s) {
|
|
909
|
-
if (!r.trim() || r.startsWith("#")) continue;
|
|
910
|
-
const o = r.trim().split(/\s+/);
|
|
911
|
-
switch (o[0]) {
|
|
912
|
-
case "v":
|
|
913
|
-
this._tmpPositions.push(o.slice(1).map(Number));
|
|
914
|
-
break;
|
|
915
|
-
case "vn":
|
|
916
|
-
this._tmpNormals.push(o.slice(1).map(Number));
|
|
917
|
-
break;
|
|
918
|
-
case "vt":
|
|
919
|
-
this._tmpUVs.push(o.slice(1).map(Number));
|
|
920
|
-
break;
|
|
921
|
-
case "f":
|
|
922
|
-
this.processFaceLine(o);
|
|
923
|
-
break;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
const i = {
|
|
927
|
-
type: D.Custom,
|
|
928
|
-
position: this._positions,
|
|
929
|
-
...this._normals.length > 0 && { normal: this._normals },
|
|
930
|
-
...this._uvs.length > 0 && { uv: this._uvs }
|
|
931
|
-
};
|
|
932
|
-
return new et(i);
|
|
758
|
+
addMesh(e) {
|
|
759
|
+
this._meshes.includes(e) || (this._meshes.push(e), this._api.addToScene(e));
|
|
933
760
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
processFaceLine(e) {
|
|
938
|
-
for (let s = 1; s < e.length; s++) {
|
|
939
|
-
const i = e[s];
|
|
940
|
-
if (!i) continue;
|
|
941
|
-
const [r, o, n] = i.split("/"), h = r ? parseInt(r, 10) : void 0, l = o ? parseInt(o, 10) : void 0, c = n ? parseInt(n, 10) : void 0;
|
|
942
|
-
if (h !== void 0) {
|
|
943
|
-
const d = this._tmpPositions[h - 1];
|
|
944
|
-
d && this._positions.push(...d);
|
|
945
|
-
}
|
|
946
|
-
if (l !== void 0) {
|
|
947
|
-
const d = this._tmpUVs[l - 1];
|
|
948
|
-
d && this._uvs.push(...d);
|
|
949
|
-
}
|
|
950
|
-
if (c !== void 0) {
|
|
951
|
-
const d = this._tmpNormals[c - 1];
|
|
952
|
-
d && this._normals.push(...d);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
761
|
+
removeMesh(e) {
|
|
762
|
+
const t = this._meshes.indexOf(e);
|
|
763
|
+
t >= 0 && this._meshes.splice(t, 1), this._api.removeFromScene(e);
|
|
955
764
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
765
|
+
addMeshes(e) {
|
|
766
|
+
for (const t of e)
|
|
767
|
+
this.addMesh(t);
|
|
768
|
+
}
|
|
769
|
+
removeMeshes(e) {
|
|
770
|
+
for (const t of e)
|
|
771
|
+
this.removeMesh(t);
|
|
772
|
+
}
|
|
773
|
+
/** Освобождает ресурсы модуля */
|
|
774
|
+
dispose() {
|
|
775
|
+
for (const e of this._meshes)
|
|
776
|
+
this._api.removeFromScene(e);
|
|
777
|
+
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
|
+
}
|
|
779
|
+
};
|
|
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);
|
|
787
|
+
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]));
|
|
965
792
|
}
|
|
966
793
|
/** Текущий режим отображения */
|
|
967
|
-
_currentMode =
|
|
794
|
+
_currentMode = F.Plane;
|
|
968
795
|
/** Хендлеры, которые управляют отображением */
|
|
969
796
|
_handlers;
|
|
797
|
+
/** Тип фичи, за которую отвечает менеджер. */
|
|
798
|
+
type = P.Display;
|
|
970
799
|
/** Установка режима отображения */
|
|
971
|
-
manage(
|
|
972
|
-
|
|
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));
|
|
973
802
|
}
|
|
974
803
|
/** Освобождает ресурсы менеджера. */
|
|
975
804
|
dispose() {
|
|
976
|
-
this._handlers && this._handlers.clear(), this._currentMode =
|
|
805
|
+
this._handlers && this._handlers.clear(), this._currentMode = F.Plane, this._store.setDisplayMode(this._currentMode);
|
|
977
806
|
}
|
|
978
807
|
};
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
],
|
|
984
|
-
var C = /* @__PURE__ */ ((
|
|
985
|
-
for (var
|
|
986
|
-
(n =
|
|
987
|
-
return
|
|
988
|
-
},
|
|
989
|
-
let
|
|
990
|
-
constructor(
|
|
991
|
-
this._eventBus =
|
|
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);
|
|
992
821
|
}
|
|
993
822
|
/** Текущий режим выборки */
|
|
994
|
-
_currentMode =
|
|
823
|
+
_currentMode = M.Mesh;
|
|
995
824
|
/** Хендлеры, которые управляют выборкой */
|
|
996
825
|
_handlers;
|
|
826
|
+
/** Тип фичи, за которую отвечает менеджер. */
|
|
827
|
+
type = P.Select;
|
|
997
828
|
/** Переключает режим выбора */
|
|
998
|
-
manage(
|
|
999
|
-
|
|
829
|
+
manage(e) {
|
|
830
|
+
e !== this._currentMode && (this._handlers.get(this._currentMode)?.rollback(), this._currentMode = e, this._store.setSelectMode(this._currentMode));
|
|
1000
831
|
}
|
|
1001
832
|
/** Обработчик события наведения на модель */
|
|
1002
|
-
_onHover = (
|
|
1003
|
-
this._handlers.get(this._currentMode)?.handle(
|
|
833
|
+
_onHover = (e) => {
|
|
834
|
+
this._handlers.get(this._currentMode)?.handle(e, C.Hover);
|
|
1004
835
|
};
|
|
1005
836
|
/** Обработчик события клика на модель */
|
|
1006
|
-
_onClick = (
|
|
1007
|
-
this._handlers.get(this._currentMode)?.handle(
|
|
837
|
+
_onClick = (e) => {
|
|
838
|
+
this._handlers.get(this._currentMode)?.handle(e, C.Click);
|
|
1008
839
|
};
|
|
1009
840
|
/** Освобождает ресурсы менеджера. */
|
|
1010
841
|
dispose() {
|
|
1011
|
-
this._handlers && this._handlers.clear(), this._eventBus.off(
|
|
842
|
+
this._handlers && this._handlers.clear(), this._eventBus.off(V.SelectHover, this._onHover), this._currentMode = M.Mesh, this._store.setSelectMode(this._currentMode);
|
|
1012
843
|
}
|
|
1013
844
|
};
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
],
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
constructor(t, e) {
|
|
1037
|
-
this._store = e, this._handlers = new Map(t.map((s) => [s.mode, s])), this._unsubSelected = this._store.onSelectedObjectChange(() => {
|
|
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(() => {
|
|
1038
867
|
this._handlers.get(this._currentTool)?.handle();
|
|
1039
|
-
})
|
|
868
|
+
});
|
|
1040
869
|
}
|
|
1041
870
|
/** Текущий выбранный инструмент */
|
|
1042
|
-
_currentTool =
|
|
871
|
+
_currentTool = j.Translate;
|
|
1043
872
|
/** Хендлеры, которые управляют инструментами */
|
|
1044
873
|
_handlers;
|
|
1045
874
|
/** Событие обновления выбора объекта */
|
|
1046
875
|
_unsubSelected;
|
|
1047
|
-
/**
|
|
1048
|
-
|
|
1049
|
-
manage(
|
|
1050
|
-
|
|
1051
|
-
const e = this._store.getSelectMode();
|
|
1052
|
-
this._policy.isToolEnabled(t, e) && (this._handlers.get(this._currentTool)?.rollback(), this._currentTool = t, this._store.setToolType(this._currentTool), this._handlers.get(this._currentTool)?.handle());
|
|
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());
|
|
1053
880
|
}
|
|
1054
881
|
/** Освобождает ресурсы менеджера. */
|
|
1055
882
|
dispose() {
|
|
1056
|
-
this._unsubSelected?.(), this._handlers && this._handlers.clear(), this._currentTool =
|
|
883
|
+
this._unsubSelected?.(), this._handlers && this._handlers.clear(), this._currentTool = j.Translate, this._store.setToolType(this._currentTool);
|
|
1057
884
|
}
|
|
1058
885
|
};
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
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);
|
|
898
|
+
return i;
|
|
899
|
+
}, ts = (e, t) => (r, s) => t(r, s, e);
|
|
900
|
+
let ge = class {
|
|
1070
901
|
/** Текущий режим редактирования сцены */
|
|
1071
|
-
_currentMode =
|
|
902
|
+
_currentMode = W.AddFigure;
|
|
1072
903
|
/** Хендлеры, которые управляют отображением */
|
|
1073
904
|
_handlers;
|
|
1074
|
-
|
|
1075
|
-
|
|
905
|
+
/** Тип фичи, за которую отвечает менеджер. */
|
|
906
|
+
type = P.Scene;
|
|
907
|
+
constructor(e) {
|
|
908
|
+
this._handlers = new Map(e.map((t) => [t.mode, t]));
|
|
1076
909
|
}
|
|
1077
910
|
/** Установка режима редактирования сцены */
|
|
1078
|
-
manage(
|
|
1079
|
-
|
|
911
|
+
manage(e, t) {
|
|
912
|
+
e === W.AddFigure ? this._handlers.get(e)?.handle(t) : this._handlers.get(e)?.handle(), this._currentMode = e;
|
|
1080
913
|
}
|
|
1081
914
|
/** Освобождает ресурсы менеджера. */
|
|
1082
915
|
dispose() {
|
|
1083
|
-
this._handlers && this._handlers.clear(), this._currentMode =
|
|
916
|
+
this._handlers && this._handlers.clear(), this._currentMode = W.AddFigure;
|
|
1084
917
|
}
|
|
1085
918
|
};
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
],
|
|
1090
|
-
var
|
|
1091
|
-
for (var
|
|
1092
|
-
(n =
|
|
1093
|
-
return
|
|
1094
|
-
},
|
|
1095
|
-
let
|
|
1096
|
-
constructor(
|
|
1097
|
-
this._api =
|
|
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 {
|
|
929
|
+
constructor(e) {
|
|
930
|
+
this._api = e;
|
|
1098
931
|
}
|
|
1099
932
|
/** Режим отображения. */
|
|
1100
|
-
mode =
|
|
933
|
+
mode = F.Wireframe;
|
|
1101
934
|
/** Сохраняем предыдущие значения wireframe для отката. */
|
|
1102
935
|
_prevWireframe = /* @__PURE__ */ new Map();
|
|
1103
936
|
/** Сохраняем исходные цвета материалов для отката */
|
|
@@ -1107,18 +940,18 @@ let oe = class {
|
|
|
1107
940
|
_wireColor = new a.Color(65535);
|
|
1108
941
|
/** Применяет wireframe-режим к сцене. */
|
|
1109
942
|
handle() {
|
|
1110
|
-
const
|
|
1111
|
-
for (const
|
|
1112
|
-
const
|
|
1113
|
-
for (const
|
|
1114
|
-
|
|
1115
|
-
if (
|
|
1116
|
-
const
|
|
1117
|
-
if (!this._prevColorLines.has(
|
|
1118
|
-
const n =
|
|
943
|
+
const e = this._api.getMeshes();
|
|
944
|
+
for (const t of e) {
|
|
945
|
+
const r = Array.isArray(t.material) ? t.material : [t.material];
|
|
946
|
+
for (const s of r) this._enableWireframeOnMaterial(s);
|
|
947
|
+
t.traverse((s) => {
|
|
948
|
+
if (s.isLineSegments) {
|
|
949
|
+
const i = s;
|
|
950
|
+
if (!this._prevColorLines.has(i.material)) {
|
|
951
|
+
const n = i.material;
|
|
1119
952
|
this._prevColorLines.set(n, n.color.clone());
|
|
1120
953
|
}
|
|
1121
|
-
const o =
|
|
954
|
+
const o = i.material;
|
|
1122
955
|
o.color.copy(this._wireColor), o.needsUpdate = !0;
|
|
1123
956
|
}
|
|
1124
957
|
});
|
|
@@ -1126,16 +959,16 @@ let oe = class {
|
|
|
1126
959
|
}
|
|
1127
960
|
/** Отключает wireframe-режим и возвращает оригинальные меши. */
|
|
1128
961
|
rollback() {
|
|
1129
|
-
for (const [
|
|
1130
|
-
"wireframe" in
|
|
962
|
+
for (const [e, t] of this._prevWireframe)
|
|
963
|
+
"wireframe" in e && (e.wireframe = t), e.needsUpdate = !0;
|
|
1131
964
|
this._prevWireframe.clear();
|
|
1132
|
-
for (const [
|
|
1133
|
-
const
|
|
1134
|
-
|
|
965
|
+
for (const [e, t] of this._prevColorMesh) {
|
|
966
|
+
const r = e;
|
|
967
|
+
r.color?.isColor && r.color.copy(t);
|
|
1135
968
|
}
|
|
1136
969
|
this._prevColorMesh.clear();
|
|
1137
|
-
for (const [
|
|
1138
|
-
|
|
970
|
+
for (const [e, t] of this._prevColorLines)
|
|
971
|
+
e.color.copy(t);
|
|
1139
972
|
this._prevColorLines.clear();
|
|
1140
973
|
}
|
|
1141
974
|
/** Освобождает ресурсы хендлера, удаляет слушатели и очищает внутренние данные. */
|
|
@@ -1143,26 +976,27 @@ let oe = class {
|
|
|
1143
976
|
this.rollback();
|
|
1144
977
|
}
|
|
1145
978
|
/** Изменить цвет, который будет применяться в режиме wireframe. */
|
|
1146
|
-
_enableWireframeOnMaterial(
|
|
1147
|
-
const
|
|
1148
|
-
"wireframe" in
|
|
979
|
+
_enableWireframeOnMaterial(e) {
|
|
980
|
+
const t = e;
|
|
981
|
+
"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));
|
|
1149
982
|
}
|
|
1150
983
|
};
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
],
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
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);
|
|
992
|
+
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;
|
|
1163
997
|
}
|
|
1164
998
|
/** Режим, которым управляет хендлер, нужен только менеджеру */
|
|
1165
|
-
mode =
|
|
999
|
+
mode = M.Mesh;
|
|
1166
1000
|
/** Фигура, на которую навелись в данный момент */
|
|
1167
1001
|
_hoveredMesh = null;
|
|
1168
1002
|
/** Фигура, которую выбрали в данный момент */
|
|
@@ -1171,25 +1005,25 @@ let ne = class {
|
|
|
1171
1005
|
/** Цвет ребер для фигуры, на которую навелись */
|
|
1172
1006
|
_hoverColor = Z;
|
|
1173
1007
|
/** Цвет ребер для выделенной фигуры */
|
|
1174
|
-
_selectColor =
|
|
1008
|
+
_selectColor = q;
|
|
1175
1009
|
/** Исходные цвета материалов линий для отката */
|
|
1176
1010
|
_origLineColors = /* @__PURE__ */ new WeakMap();
|
|
1177
|
-
handle(
|
|
1178
|
-
if (this._api.setRaycastMode(this.mode),
|
|
1179
|
-
if (!
|
|
1011
|
+
handle(e, t) {
|
|
1012
|
+
if (this._api.setRaycastMode(this.mode), t === C.Hover) {
|
|
1013
|
+
if (!e) {
|
|
1180
1014
|
this._hoveredMesh && this._hoveredMesh !== this._selectedMesh && this._restoreEdgesColor(this._hoveredMesh), this._hoveredMesh = null;
|
|
1181
1015
|
return;
|
|
1182
1016
|
}
|
|
1183
|
-
const
|
|
1184
|
-
this._hoveredMesh !==
|
|
1017
|
+
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);
|
|
1185
1019
|
}
|
|
1186
|
-
if (
|
|
1187
|
-
if (!
|
|
1020
|
+
if (t === C.Click) {
|
|
1021
|
+
if (!e) {
|
|
1188
1022
|
this._selectedMesh && (this._restoreEdgesColor(this._selectedMesh), this._selectedMesh = null, this._store.setSelectedObject(null));
|
|
1189
1023
|
return;
|
|
1190
1024
|
}
|
|
1191
|
-
const
|
|
1192
|
-
this._selectedMesh && this._selectedMesh !==
|
|
1025
|
+
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);
|
|
1193
1027
|
}
|
|
1194
1028
|
}
|
|
1195
1029
|
rollback() {
|
|
@@ -1202,12 +1036,12 @@ let ne = class {
|
|
|
1202
1036
|
/**
|
|
1203
1037
|
* Перекрасить рёбра меша и запомнить оригинальный цвет (один раз на LineSegments).
|
|
1204
1038
|
*/
|
|
1205
|
-
_paintEdges(
|
|
1206
|
-
|
|
1207
|
-
const
|
|
1208
|
-
if (
|
|
1209
|
-
const
|
|
1210
|
-
this._origLineColors.has(
|
|
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;
|
|
1211
1045
|
}
|
|
1212
1046
|
});
|
|
1213
1047
|
}
|
|
@@ -1215,35 +1049,35 @@ let ne = class {
|
|
|
1215
1049
|
* Восстановить исходный цвет рёбер меша из WeakMap.
|
|
1216
1050
|
* Если исходный цвет не сохранён (на всякий случай) — ничего не меняем.
|
|
1217
1051
|
*/
|
|
1218
|
-
_restoreEdgesColor(
|
|
1219
|
-
|
|
1220
|
-
const
|
|
1221
|
-
if (
|
|
1222
|
-
const
|
|
1223
|
-
if (
|
|
1224
|
-
const
|
|
1225
|
-
|
|
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;
|
|
1226
1060
|
}
|
|
1227
1061
|
}
|
|
1228
1062
|
});
|
|
1229
1063
|
}
|
|
1230
1064
|
};
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
],
|
|
1236
|
-
var
|
|
1237
|
-
for (var
|
|
1238
|
-
(n =
|
|
1239
|
-
return
|
|
1240
|
-
},
|
|
1241
|
-
let
|
|
1242
|
-
constructor(t,
|
|
1243
|
-
this.
|
|
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);
|
|
1073
|
+
return i;
|
|
1074
|
+
}, z = (e, t) => (r, s) => t(r, s, e);
|
|
1075
|
+
let Me = class {
|
|
1076
|
+
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);
|
|
1244
1078
|
}
|
|
1245
1079
|
/** Режим, которым управляет хендлер, нужен только менеджеру */
|
|
1246
|
-
mode =
|
|
1080
|
+
mode = M.Face;
|
|
1247
1081
|
/** Текущая наведённая грань */
|
|
1248
1082
|
_hoverFace;
|
|
1249
1083
|
/** Текущая выбранная грань */
|
|
@@ -1260,38 +1094,38 @@ let ae = class {
|
|
|
1260
1094
|
/** Цвет грани, на которую навелись */
|
|
1261
1095
|
_hoverColor = Z;
|
|
1262
1096
|
/** Цвет выделенной граней */
|
|
1263
|
-
_selectColor =
|
|
1097
|
+
_selectColor = q;
|
|
1264
1098
|
// Погрешности для поиска треугольников и сборки граней
|
|
1265
1099
|
/** Погрешность на сравнение нормалей */
|
|
1266
1100
|
_normalEps = 1e-4;
|
|
1267
1101
|
/** Погрешность на принадлежность одной плоскости */
|
|
1268
1102
|
_planeEps = 1e-4;
|
|
1269
1103
|
/** Обработка текущего режима выборки. */
|
|
1270
|
-
handle(
|
|
1271
|
-
if (this.
|
|
1272
|
-
if (!
|
|
1104
|
+
handle(e, t) {
|
|
1105
|
+
if (this._raycastApi.setRaycastMode(this.mode), t === C.Hover) {
|
|
1106
|
+
if (!e) {
|
|
1273
1107
|
this._hoverFace.visible = !1, this._hovered = null;
|
|
1274
1108
|
return;
|
|
1275
1109
|
}
|
|
1276
|
-
const
|
|
1277
|
-
if (!
|
|
1278
|
-
const
|
|
1279
|
-
if (
|
|
1280
|
-
const o = this._collectFaceGroup(
|
|
1110
|
+
const r = e.intersection.object;
|
|
1111
|
+
if (!r?.isMesh) return;
|
|
1112
|
+
const s = r, i = e.intersection.faceIndex ?? -1;
|
|
1113
|
+
if (i < 0) return;
|
|
1114
|
+
const o = this._collectFaceGroup(s, i);
|
|
1281
1115
|
if (!o) return;
|
|
1282
1116
|
this._selected && this._same(o, this._selected) ? this._hoverFace.visible = !1 : (this._writeWorldFaceGroup(this._hoverFace, o), this._hoverFace.visible = !0), this._hovered = o;
|
|
1283
1117
|
return;
|
|
1284
1118
|
}
|
|
1285
|
-
if (
|
|
1286
|
-
if (!
|
|
1119
|
+
if (t === C.Click) {
|
|
1120
|
+
if (!e) {
|
|
1287
1121
|
this._selectFace.visible = !1, this._selected = null, this._store.setSelectedObject(null);
|
|
1288
1122
|
return;
|
|
1289
1123
|
}
|
|
1290
|
-
const
|
|
1291
|
-
if (!
|
|
1292
|
-
const
|
|
1293
|
-
if (
|
|
1294
|
-
const o = this._collectFaceGroup(
|
|
1124
|
+
const r = e.intersection.object;
|
|
1125
|
+
if (!r?.isMesh) return;
|
|
1126
|
+
const s = r, i = e.intersection.faceIndex ?? -1;
|
|
1127
|
+
if (i < 0) return;
|
|
1128
|
+
const o = this._collectFaceGroup(s, i);
|
|
1295
1129
|
if (!o) return;
|
|
1296
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);
|
|
1297
1131
|
}
|
|
@@ -1302,16 +1136,16 @@ let ae = class {
|
|
|
1302
1136
|
}
|
|
1303
1137
|
/** Освобождает ресурсы хендлера, удаляет слушатели и очищает внутренние данные. */
|
|
1304
1138
|
dispose() {
|
|
1305
|
-
this.rollback(), this.
|
|
1139
|
+
this.rollback(), this._sceneApi.removeFromScene(this._hoverFace), this._sceneApi.removeFromScene(this._selectFace), this._hoverFace.geometry.dispose(), this._hoverFace.material.dispose(), this._selectFace.geometry.dispose(), this._selectFace.material.dispose();
|
|
1306
1140
|
}
|
|
1307
1141
|
/**
|
|
1308
1142
|
* Инициализация overlay mesh для режима (hover и click).
|
|
1309
1143
|
* На весь режим используются 2 глобальных mesh на сцене,
|
|
1310
1144
|
* геометрия которых переписывается под текущую грань.
|
|
1311
1145
|
*/
|
|
1312
|
-
_makeOverlayFace(
|
|
1313
|
-
const
|
|
1314
|
-
color:
|
|
1146
|
+
_makeOverlayFace(e) {
|
|
1147
|
+
const t = new a.BufferGeometry(), r = new a.MeshBasicMaterial({
|
|
1148
|
+
color: e,
|
|
1315
1149
|
transparent: !0,
|
|
1316
1150
|
opacity: 0.35,
|
|
1317
1151
|
depthTest: !1,
|
|
@@ -1320,217 +1154,308 @@ let ae = class {
|
|
|
1320
1154
|
polygonOffset: !0,
|
|
1321
1155
|
polygonOffsetFactor: -1,
|
|
1322
1156
|
polygonOffsetUnits: -1
|
|
1323
|
-
}),
|
|
1324
|
-
return
|
|
1325
|
-
},
|
|
1157
|
+
}), s = new a.Mesh(t, r);
|
|
1158
|
+
return s.renderOrder = 1e3, s.layers.set(x), s.visible = !1, s.raycast = () => {
|
|
1159
|
+
}, s;
|
|
1326
1160
|
}
|
|
1327
1161
|
/**
|
|
1328
1162
|
* Сбор логической грани как связной группы компланарных треугольников.
|
|
1329
1163
|
* Если geometry неиндексированная — пока возвращаем только стартовый triangle.
|
|
1330
1164
|
*/
|
|
1331
|
-
_collectFaceGroup(
|
|
1332
|
-
const
|
|
1333
|
-
if (!
|
|
1334
|
-
const
|
|
1335
|
-
if (!
|
|
1336
|
-
const
|
|
1165
|
+
_collectFaceGroup(e, t) {
|
|
1166
|
+
const r = e.geometry, s = r.getAttribute("position");
|
|
1167
|
+
if (!s) return null;
|
|
1168
|
+
const i = r.index;
|
|
1169
|
+
if (!i) {
|
|
1170
|
+
const S = t * 3, w = t * 3 + 1, I = t * 3 + 2;
|
|
1337
1171
|
return {
|
|
1338
|
-
mesh:
|
|
1339
|
-
faceIndex:
|
|
1340
|
-
triangleIndices: [
|
|
1341
|
-
vertexIndices: [
|
|
1342
|
-
proxyVertexMap: [
|
|
1172
|
+
mesh: e,
|
|
1173
|
+
faceIndex: t,
|
|
1174
|
+
triangleIndices: [t],
|
|
1175
|
+
vertexIndices: [S, w, I],
|
|
1176
|
+
proxyVertexMap: [S, w, I]
|
|
1343
1177
|
};
|
|
1344
1178
|
}
|
|
1345
|
-
const o = Math.floor(
|
|
1346
|
-
if (
|
|
1347
|
-
const n = this._buildTriangleAdjacency(
|
|
1348
|
-
for (;
|
|
1349
|
-
const
|
|
1350
|
-
if (
|
|
1351
|
-
|
|
1352
|
-
const [
|
|
1353
|
-
if (!
|
|
1354
|
-
|
|
1355
|
-
const
|
|
1356
|
-
if (
|
|
1357
|
-
for (const
|
|
1358
|
-
|
|
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);
|
|
1359
1193
|
}
|
|
1360
|
-
|
|
1361
|
-
const
|
|
1362
|
-
for (const
|
|
1363
|
-
const [
|
|
1364
|
-
|
|
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, $);
|
|
1365
1199
|
}
|
|
1366
1200
|
return {
|
|
1367
|
-
mesh:
|
|
1368
|
-
faceIndex:
|
|
1369
|
-
triangleIndices:
|
|
1370
|
-
vertexIndices: Array.from(
|
|
1371
|
-
proxyVertexMap:
|
|
1201
|
+
mesh: e,
|
|
1202
|
+
faceIndex: t,
|
|
1203
|
+
triangleIndices: b,
|
|
1204
|
+
vertexIndices: Array.from(E),
|
|
1205
|
+
proxyVertexMap: T
|
|
1372
1206
|
};
|
|
1373
1207
|
}
|
|
1374
1208
|
/** Перезаписывает overlay mesh world-space треугольниками выбранной грани */
|
|
1375
|
-
_writeWorldFaceGroup(
|
|
1376
|
-
const
|
|
1209
|
+
_writeWorldFaceGroup(e, t) {
|
|
1210
|
+
const r = t.mesh.geometry, s = r.getAttribute("position"), i = r.index, o = new Float32Array(t.triangleIndices.length * 9);
|
|
1377
1211
|
let n = 0;
|
|
1378
|
-
for (const
|
|
1379
|
-
let
|
|
1380
|
-
|
|
1381
|
-
const
|
|
1382
|
-
o[n++] =
|
|
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;
|
|
1383
1217
|
}
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1218
|
+
const c = e.geometry;
|
|
1219
|
+
c.setAttribute("position", new a.BufferAttribute(o, 3)), c.setIndex(null), c.computeVertexNormals(), c.computeBoundingBox(), c.computeBoundingSphere();
|
|
1386
1220
|
}
|
|
1387
1221
|
/** Сравнение двух логических граней */
|
|
1388
|
-
_same(
|
|
1389
|
-
return !!
|
|
1222
|
+
_same(e, t) {
|
|
1223
|
+
return !!e && !!t && e.mesh === t.mesh && e.triangleIndices.length === t.triangleIndices.length && e.triangleIndices.every((r, s) => r === t.triangleIndices[s]);
|
|
1390
1224
|
}
|
|
1391
1225
|
/** Подготовка метаданных выбранной грани для инструментов */
|
|
1392
|
-
_prepareFaceMetadata(
|
|
1393
|
-
const { vertexIndexGroups:
|
|
1226
|
+
_prepareFaceMetadata(e) {
|
|
1227
|
+
const { vertexIndexGroups: t, proxyVertexMap: r, lines: s, lineVertexIndexGroups: i } = this._buildFaceVertexGroups(e);
|
|
1394
1228
|
this._selectFace.userData.faceInfo = {
|
|
1395
|
-
mesh:
|
|
1396
|
-
faceIndex:
|
|
1397
|
-
triangleIndices:
|
|
1398
|
-
vertexIndices:
|
|
1399
|
-
vertexIndexGroups:
|
|
1400
|
-
proxyVertexMap:
|
|
1401
|
-
lines:
|
|
1402
|
-
lineVertexIndexGroups:
|
|
1229
|
+
mesh: e.mesh,
|
|
1230
|
+
faceIndex: e.faceIndex,
|
|
1231
|
+
triangleIndices: e.triangleIndices,
|
|
1232
|
+
vertexIndices: e.vertexIndices,
|
|
1233
|
+
vertexIndexGroups: t,
|
|
1234
|
+
proxyVertexMap: r,
|
|
1235
|
+
lines: s,
|
|
1236
|
+
lineVertexIndexGroups: i
|
|
1403
1237
|
};
|
|
1404
1238
|
}
|
|
1405
1239
|
/**
|
|
1406
1240
|
* Центрирует proxy-грань, чтобы TransformControls работали с ней как с обычным объектом.
|
|
1407
1241
|
* После записи world-space вершин переносит геометрию в локальные координаты proxy mesh.
|
|
1408
1242
|
*/
|
|
1409
|
-
_centerFaceProxy(
|
|
1410
|
-
const
|
|
1411
|
-
if (!
|
|
1412
|
-
const
|
|
1413
|
-
for (let
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
for (let
|
|
1417
|
-
|
|
1418
|
-
|
|
1243
|
+
_centerFaceProxy(e) {
|
|
1244
|
+
const t = e.geometry, r = t.getAttribute("position");
|
|
1245
|
+
if (!r || r.count === 0) return;
|
|
1246
|
+
const s = new a.Vector3();
|
|
1247
|
+
for (let i = 0; i < r.count; i++)
|
|
1248
|
+
s.x += r.getX(i), s.y += r.getY(i), s.z += r.getZ(i);
|
|
1249
|
+
s.multiplyScalar(1 / r.count);
|
|
1250
|
+
for (let i = 0; i < r.count; i++)
|
|
1251
|
+
r.setXYZ(i, r.getX(i) - s.x, r.getY(i) - s.y, r.getZ(i) - s.z);
|
|
1252
|
+
r.needsUpdate = !0, e.position.copy(s), e.quaternion.identity(), e.scale.set(1, 1, 1), e.updateMatrixWorld(!0), t.computeBoundingBox(), t.computeBoundingSphere();
|
|
1419
1253
|
}
|
|
1420
1254
|
/** Регистрирует ребро треугольника в edge map */
|
|
1421
|
-
_pushEdge(t,
|
|
1422
|
-
const
|
|
1423
|
-
o ? o.push(
|
|
1255
|
+
_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]);
|
|
1424
1258
|
}
|
|
1425
1259
|
/** Строит граф соседства треугольников по общим ребрам */
|
|
1426
|
-
_buildTriangleAdjacency(
|
|
1427
|
-
const
|
|
1428
|
-
for (let
|
|
1429
|
-
const [
|
|
1430
|
-
this._pushEdge(
|
|
1260
|
+
_buildTriangleAdjacency(e, t) {
|
|
1261
|
+
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);
|
|
1431
1265
|
}
|
|
1432
1266
|
const o = /* @__PURE__ */ new Map();
|
|
1433
|
-
for (let
|
|
1434
|
-
o.set(
|
|
1435
|
-
for (const
|
|
1436
|
-
if (!(
|
|
1437
|
-
for (let
|
|
1438
|
-
for (let
|
|
1439
|
-
|
|
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]);
|
|
1440
1274
|
const n = /* @__PURE__ */ new Map();
|
|
1441
|
-
for (const [
|
|
1442
|
-
n.set(
|
|
1275
|
+
for (const [c, _] of o)
|
|
1276
|
+
n.set(c, Array.from(_));
|
|
1443
1277
|
return n;
|
|
1444
1278
|
}
|
|
1445
1279
|
/** Возвращает индексы трех вершин треугольника */
|
|
1446
|
-
_getTriangleIndices(
|
|
1447
|
-
return [
|
|
1280
|
+
_getTriangleIndices(e, t) {
|
|
1281
|
+
return [e.getX(t * 3), e.getX(t * 3 + 1), e.getX(t * 3 + 2)];
|
|
1448
1282
|
}
|
|
1449
1283
|
/** Читает вершину из position buffer в local space geometry */
|
|
1450
|
-
_readVertex(
|
|
1451
|
-
return new a.Vector3(
|
|
1284
|
+
_readVertex(e, t) {
|
|
1285
|
+
return new a.Vector3(e.getX(t), e.getY(t), e.getZ(t));
|
|
1452
1286
|
}
|
|
1453
1287
|
/** Построение ключа вершины по позиции */
|
|
1454
|
-
_vertexKey(
|
|
1455
|
-
const
|
|
1456
|
-
return `${
|
|
1288
|
+
_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}`;
|
|
1457
1291
|
}
|
|
1458
1292
|
/**
|
|
1459
1293
|
* Строит отображение исходных индексов вершин в "сваренные" ids по координате.
|
|
1460
1294
|
* Нужно для случаев, когда соседние треугольники визуально делят ребро,
|
|
1461
1295
|
* но используют разные индексы вершин (например, цилиндрические крышки, UV seams и т.п.).
|
|
1462
1296
|
*/
|
|
1463
|
-
_buildWeldMap(
|
|
1464
|
-
const
|
|
1465
|
-
let
|
|
1466
|
-
for (let o = 0; o <
|
|
1467
|
-
const n =
|
|
1468
|
-
if (
|
|
1469
|
-
const
|
|
1470
|
-
let
|
|
1471
|
-
|
|
1297
|
+
_buildWeldMap(e, t) {
|
|
1298
|
+
const r = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
|
|
1299
|
+
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, _);
|
|
1472
1306
|
}
|
|
1473
|
-
return
|
|
1307
|
+
return s;
|
|
1474
1308
|
}
|
|
1475
1309
|
/** Сбрасывает transform proxy-граням */
|
|
1476
|
-
_resetFaceProxyTransform(
|
|
1477
|
-
|
|
1478
|
-
}
|
|
1479
|
-
_buildFaceVertexGroups(
|
|
1480
|
-
const
|
|
1481
|
-
for (const
|
|
1482
|
-
const
|
|
1483
|
-
for (let
|
|
1484
|
-
|
|
1485
|
-
const
|
|
1486
|
-
n.push(
|
|
1487
|
-
for (const
|
|
1488
|
-
|
|
1310
|
+
_resetFaceProxyTransform(e) {
|
|
1311
|
+
e.position.set(0, 0, 0), e.quaternion.identity(), e.scale.set(1, 1, 1), e.updateMatrixWorld(!0);
|
|
1312
|
+
}
|
|
1313
|
+
_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 = [];
|
|
1317
|
+
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);
|
|
1489
1323
|
}
|
|
1490
|
-
const
|
|
1491
|
-
for (const
|
|
1492
|
-
const
|
|
1493
|
-
|
|
1324
|
+
const _ = [];
|
|
1325
|
+
for (const g of e.proxyVertexMap) {
|
|
1326
|
+
const v = c.get(g);
|
|
1327
|
+
_.push(v ?? -1);
|
|
1494
1328
|
}
|
|
1495
|
-
const
|
|
1329
|
+
const u = this._findChildLines(e.mesh), p = u ? this._buildLineVertexGroups(e, u) : void 0, f = {
|
|
1496
1330
|
vertexIndexGroups: n,
|
|
1497
|
-
proxyVertexMap:
|
|
1331
|
+
proxyVertexMap: _
|
|
1498
1332
|
};
|
|
1499
|
-
return
|
|
1333
|
+
return u && (f.lines = u), p && (f.lineVertexIndexGroups = p), f;
|
|
1500
1334
|
}
|
|
1501
|
-
_findChildLines(
|
|
1502
|
-
for (const
|
|
1503
|
-
if (
|
|
1504
|
-
return
|
|
1335
|
+
_findChildLines(e) {
|
|
1336
|
+
for (const t of e.children)
|
|
1337
|
+
if (t.isLineSegments)
|
|
1338
|
+
return t;
|
|
1505
1339
|
return null;
|
|
1506
1340
|
}
|
|
1507
|
-
_buildLineVertexGroups(
|
|
1508
|
-
const
|
|
1509
|
-
for (const
|
|
1510
|
-
const
|
|
1511
|
-
for (let
|
|
1512
|
-
|
|
1513
|
-
|
|
1341
|
+
_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);
|
|
1514
1348
|
}
|
|
1515
|
-
return
|
|
1349
|
+
return p;
|
|
1516
1350
|
}
|
|
1517
1351
|
};
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
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),
|
|
1400
|
+
/**
|
|
1401
|
+
* Сфера (SphereGeometry) — алиас для UVSphere
|
|
1402
|
+
* @returns Сфера радиусом 0.5, 32 сегмента по ширине, 16 по высоте
|
|
1403
|
+
*/
|
|
1404
|
+
[O.Sphere]: () => new a.SphereGeometry(0.5, 32, 16),
|
|
1405
|
+
/**
|
|
1406
|
+
* Кастомная геометрия (не реализовано в фабрике)
|
|
1407
|
+
* @throws {Error} Всегда выбрасывает ошибку
|
|
1408
|
+
*/
|
|
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;
|
|
1421
|
+
}
|
|
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
|
+
};
|
|
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);
|
|
1451
|
+
return i;
|
|
1452
|
+
}, N = (e, t) => (r, s) => t(r, s, e);
|
|
1453
|
+
let ye = class {
|
|
1454
|
+
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);
|
|
1531
1456
|
}
|
|
1532
1457
|
/** Режим, которым управляет хендлер, нужен только менеджеру */
|
|
1533
|
-
mode =
|
|
1458
|
+
mode = M.Vertex;
|
|
1534
1459
|
_hovered = null;
|
|
1535
1460
|
_selected = null;
|
|
1536
1461
|
/** Текущая наведённая вершина. */
|
|
@@ -1541,30 +1466,30 @@ let he = class {
|
|
|
1541
1466
|
/** Цвет ребра, на которое навелись */
|
|
1542
1467
|
_hoverColor = Z;
|
|
1543
1468
|
/** Цвет выделенного ребра */
|
|
1544
|
-
_selectColor =
|
|
1545
|
-
handle(
|
|
1546
|
-
if (this.
|
|
1547
|
-
if (!
|
|
1469
|
+
_selectColor = q;
|
|
1470
|
+
handle(e, t) {
|
|
1471
|
+
if (this._raycastApi.setRaycastMode(this.mode), t === C.Hover) {
|
|
1472
|
+
if (!e) {
|
|
1548
1473
|
this._hoverVertex.visible = !1, this._hovered = null;
|
|
1549
1474
|
return;
|
|
1550
1475
|
}
|
|
1551
|
-
const
|
|
1552
|
-
if (!
|
|
1553
|
-
const
|
|
1554
|
-
if (
|
|
1555
|
-
this._selected && this._same({ points:
|
|
1476
|
+
const r = e.intersection.object;
|
|
1477
|
+
if (!r?.isPoints) return;
|
|
1478
|
+
const s = r, i = e.intersection.index ?? -1;
|
|
1479
|
+
if (i < 0) return;
|
|
1480
|
+
this._selected && this._same({ points: s, index: i }, this._selected) ? this._hoverVertex.visible = !1 : (this._writeWorldVertex(this._hoverVertex, s, i), this._hoverVertex.visible = !0);
|
|
1556
1481
|
return;
|
|
1557
1482
|
}
|
|
1558
|
-
if (
|
|
1559
|
-
if (!
|
|
1483
|
+
if (t === C.Click) {
|
|
1484
|
+
if (!e) {
|
|
1560
1485
|
this._selectVertex.visible = !1, this._selected = null, this._store.setSelectedObject(null);
|
|
1561
1486
|
return;
|
|
1562
1487
|
}
|
|
1563
|
-
const
|
|
1564
|
-
if (!
|
|
1565
|
-
const
|
|
1566
|
-
if (
|
|
1567
|
-
this._writeWorldVertex(this._selectVertex,
|
|
1488
|
+
const r = e.intersection.object;
|
|
1489
|
+
if (!r?.isPoints) return;
|
|
1490
|
+
const s = r, i = e.intersection.index ?? -1;
|
|
1491
|
+
if (i < 0) return;
|
|
1492
|
+
this._writeWorldVertex(this._selectVertex, s, i), this._centerVertexOnPoint(this._selectVertex, s, i), this._selectVertex.visible = !0, this._prepareVertexMetadata(s, i), this._store.setSelectedObject(this._selectVertex), this._selected = { points: s, index: i }, this._hovered && this._same(this._hovered, this._selected) && (this._hoverVertex.visible = !1);
|
|
1568
1493
|
return;
|
|
1569
1494
|
}
|
|
1570
1495
|
}
|
|
@@ -1572,83 +1497,85 @@ let he = class {
|
|
|
1572
1497
|
this._hoverVertex.visible = !1, this._selectVertex.visible = !1, this._hovered = this._selected = null, this._store.setSelectedObject(null);
|
|
1573
1498
|
}
|
|
1574
1499
|
dispose() {
|
|
1575
|
-
this.rollback(), this.
|
|
1576
|
-
}
|
|
1577
|
-
_makeOverlayVertex(
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1580
|
-
const
|
|
1581
|
-
color:
|
|
1582
|
-
size:
|
|
1500
|
+
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
|
+
}
|
|
1502
|
+
_makeOverlayVertex(e, t = us) {
|
|
1503
|
+
const r = new a.BufferGeometry();
|
|
1504
|
+
r.setAttribute("position", new a.Float32BufferAttribute([0, 0, 0], 3));
|
|
1505
|
+
const s = new a.PointsMaterial({
|
|
1506
|
+
color: e,
|
|
1507
|
+
size: t,
|
|
1583
1508
|
sizeAttenuation: !1,
|
|
1584
1509
|
depthTest: !1,
|
|
1585
1510
|
depthWrite: !1,
|
|
1586
1511
|
transparent: !0,
|
|
1587
1512
|
opacity: 1
|
|
1588
|
-
}),
|
|
1589
|
-
return
|
|
1590
|
-
},
|
|
1513
|
+
}), i = new a.Points(r, s);
|
|
1514
|
+
return i.renderOrder = 1e3, i.raycast = () => {
|
|
1515
|
+
}, i.layers.set(x), i.visible = !1, i;
|
|
1591
1516
|
}
|
|
1592
1517
|
/** Локальную вершину points переводим в world и пишем в target (прокси-точку) */
|
|
1593
|
-
_writeWorldVertex(
|
|
1594
|
-
const
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
).applyMatrix4(
|
|
1599
|
-
o.setXYZ(0,
|
|
1518
|
+
_writeWorldVertex(e, t, r) {
|
|
1519
|
+
const s = t.geometry.getAttribute("position"), i = new a.Vector3(
|
|
1520
|
+
s.getX(r),
|
|
1521
|
+
s.getY(r),
|
|
1522
|
+
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;
|
|
1600
1525
|
}
|
|
1601
|
-
_same(
|
|
1602
|
-
return !!
|
|
1526
|
+
_same(e, t) {
|
|
1527
|
+
return !!e && !!t && e.points === t.points && e.index === t.index;
|
|
1603
1528
|
}
|
|
1604
1529
|
/** Готовит метаданные для выбранной вершины и пишет их в _selectVertex.userData */
|
|
1605
|
-
_prepareVertexMetadata(
|
|
1606
|
-
const
|
|
1607
|
-
if (!
|
|
1608
|
-
const
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
).applyMatrix4(
|
|
1613
|
-
for (let
|
|
1614
|
-
|
|
1615
|
-
const
|
|
1616
|
-
let
|
|
1617
|
-
if (
|
|
1618
|
-
const
|
|
1619
|
-
for (let
|
|
1620
|
-
|
|
1530
|
+
_prepareVertexMetadata(e, t) {
|
|
1531
|
+
const r = Ze(e);
|
|
1532
|
+
if (!r) return;
|
|
1533
|
+
const s = e.geometry.getAttribute("position"), i = new a.Vector3(
|
|
1534
|
+
s.getX(t),
|
|
1535
|
+
s.getY(t),
|
|
1536
|
+
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);
|
|
1621
1546
|
}
|
|
1622
1547
|
this._selectVertex.userData.vertexInfo = {
|
|
1623
|
-
points:
|
|
1624
|
-
index:
|
|
1625
|
-
mesh:
|
|
1626
|
-
vertexIndices:
|
|
1627
|
-
lines:
|
|
1628
|
-
edgeVertexIndices:
|
|
1548
|
+
points: e,
|
|
1549
|
+
index: t,
|
|
1550
|
+
mesh: r,
|
|
1551
|
+
vertexIndices: g,
|
|
1552
|
+
lines: v ?? null,
|
|
1553
|
+
edgeVertexIndices: m
|
|
1629
1554
|
};
|
|
1630
1555
|
}
|
|
1631
1556
|
/** Центрует прокси-вершину на выбранной точке */
|
|
1632
|
-
_centerVertexOnPoint(
|
|
1633
|
-
const
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
).applyMatrix4(
|
|
1638
|
-
|
|
1639
|
-
const o =
|
|
1557
|
+
_centerVertexOnPoint(e, t, r) {
|
|
1558
|
+
const s = t.geometry.getAttribute("position"), i = new a.Vector3(
|
|
1559
|
+
s.getX(r),
|
|
1560
|
+
s.getY(r),
|
|
1561
|
+
s.getZ(r)
|
|
1562
|
+
).applyMatrix4(t.matrixWorld);
|
|
1563
|
+
e.position.copy(i);
|
|
1564
|
+
const o = e.geometry;
|
|
1640
1565
|
let n = o.getAttribute("position");
|
|
1641
|
-
(!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,
|
|
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);
|
|
1642
1567
|
}
|
|
1643
1568
|
};
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
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 {
|
|
1577
|
+
constructor(t, r) {
|
|
1578
|
+
this.api = t, this.store = r, this._unsubscribeTransform = this.api.onTransformChange(() => {
|
|
1652
1579
|
this.store.getSelectedObject() && this.store.notifySelectedTransformChange?.();
|
|
1653
1580
|
});
|
|
1654
1581
|
}
|
|
@@ -1657,8 +1584,8 @@ class ve {
|
|
|
1657
1584
|
* Обновляет состояние инструмента под текущее выделение.
|
|
1658
1585
|
*/
|
|
1659
1586
|
handle() {
|
|
1660
|
-
const
|
|
1661
|
-
this.api.
|
|
1587
|
+
const t = this.store.getSelectedObject();
|
|
1588
|
+
this.api.setTransformMode(this.mode), t ? this.api.attachTransform(t) : this.api.detachTransform();
|
|
1662
1589
|
}
|
|
1663
1590
|
/**
|
|
1664
1591
|
* Откатывает локальное состояние инструмента при смене инструмента.
|
|
@@ -1666,75 +1593,75 @@ class ve {
|
|
|
1666
1593
|
* Вызывается менеджером перед активацией другого хендлера.
|
|
1667
1594
|
*/
|
|
1668
1595
|
rollback() {
|
|
1669
|
-
this.api.
|
|
1596
|
+
this.api.detachTransform();
|
|
1670
1597
|
}
|
|
1671
1598
|
/** Освобождение ресурсов хендлера. */
|
|
1672
1599
|
dispose() {
|
|
1673
1600
|
this.rollback(), this._unsubscribeTransform && this._unsubscribeTransform();
|
|
1674
1601
|
}
|
|
1675
1602
|
}
|
|
1676
|
-
var
|
|
1677
|
-
for (var
|
|
1678
|
-
(n =
|
|
1679
|
-
return
|
|
1680
|
-
},
|
|
1681
|
-
let
|
|
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);
|
|
1606
|
+
return i;
|
|
1607
|
+
}, We = (e, t) => (r, s) => t(r, s, e);
|
|
1608
|
+
let be = class extends De {
|
|
1682
1609
|
/** Инструмент, которым управляет хендлер, нужен только менеджеру */
|
|
1683
|
-
mode =
|
|
1684
|
-
constructor(
|
|
1685
|
-
super(
|
|
1610
|
+
mode = j.Translate;
|
|
1611
|
+
constructor(e, t) {
|
|
1612
|
+
super(e, t);
|
|
1686
1613
|
}
|
|
1687
1614
|
};
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
],
|
|
1693
|
-
var
|
|
1694
|
-
for (var
|
|
1695
|
-
(n =
|
|
1696
|
-
return
|
|
1697
|
-
},
|
|
1698
|
-
let
|
|
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);
|
|
1623
|
+
return i;
|
|
1624
|
+
}, ke = (e, t) => (r, s) => t(r, s, e);
|
|
1625
|
+
let Se = class extends De {
|
|
1699
1626
|
/** Инструмент, которым управляет хендлер, нужен только менеджеру */
|
|
1700
|
-
mode =
|
|
1701
|
-
constructor(
|
|
1702
|
-
super(
|
|
1627
|
+
mode = j.Scale;
|
|
1628
|
+
constructor(e, t) {
|
|
1629
|
+
super(e, t);
|
|
1703
1630
|
}
|
|
1704
1631
|
};
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
],
|
|
1710
|
-
var
|
|
1711
|
-
for (var
|
|
1712
|
-
(n =
|
|
1713
|
-
return
|
|
1714
|
-
},
|
|
1715
|
-
let
|
|
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);
|
|
1640
|
+
return i;
|
|
1641
|
+
}, Ge = (e, t) => (r, s) => t(r, s, e);
|
|
1642
|
+
let Ae = class extends De {
|
|
1716
1643
|
/** Инструмент, которым управляет хендлер, нужен только менеджеру */
|
|
1717
|
-
mode =
|
|
1718
|
-
constructor(
|
|
1719
|
-
super(
|
|
1644
|
+
mode = j.Rotate;
|
|
1645
|
+
constructor(e, t) {
|
|
1646
|
+
super(e, t);
|
|
1720
1647
|
}
|
|
1721
1648
|
};
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
],
|
|
1727
|
-
var
|
|
1728
|
-
for (var
|
|
1729
|
-
(n =
|
|
1730
|
-
return
|
|
1731
|
-
},
|
|
1732
|
-
let
|
|
1733
|
-
constructor(t,
|
|
1734
|
-
this.
|
|
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);
|
|
1657
|
+
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);
|
|
1735
1662
|
}
|
|
1736
1663
|
/** Режим, которым управляет хендлер, нужен только менеджеру */
|
|
1737
|
-
mode =
|
|
1664
|
+
mode = M.Edge;
|
|
1738
1665
|
/** Текущее наведённое ребро. */
|
|
1739
1666
|
_hoverLine;
|
|
1740
1667
|
/** Текущее выбранное ребро. */
|
|
@@ -1747,31 +1674,31 @@ let _e = class {
|
|
|
1747
1674
|
/** Цвет ребра, на которое навелись */
|
|
1748
1675
|
_hoverColor = Z;
|
|
1749
1676
|
/** Цвет выделенного ребра */
|
|
1750
|
-
_selectColor =
|
|
1677
|
+
_selectColor = q;
|
|
1751
1678
|
/** Обработка текущего режима выборки. */
|
|
1752
|
-
handle(
|
|
1753
|
-
if (this.
|
|
1754
|
-
if (!
|
|
1679
|
+
handle(e, t) {
|
|
1680
|
+
if (this._raycastApi.setRaycastMode(this.mode), t === C.Hover) {
|
|
1681
|
+
if (!e) {
|
|
1755
1682
|
this._hoverLine.visible = !1, this._hovered = null;
|
|
1756
1683
|
return;
|
|
1757
1684
|
}
|
|
1758
|
-
const
|
|
1759
|
-
if (!
|
|
1760
|
-
const
|
|
1761
|
-
if (
|
|
1762
|
-
this._selected && this._same({ lines:
|
|
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 };
|
|
1763
1690
|
return;
|
|
1764
1691
|
}
|
|
1765
|
-
if (
|
|
1766
|
-
if (!
|
|
1692
|
+
if (t === C.Click) {
|
|
1693
|
+
if (!e) {
|
|
1767
1694
|
this._selectLine.visible = !1, this._selected = null, this._store.setSelectedObject(null);
|
|
1768
1695
|
return;
|
|
1769
1696
|
}
|
|
1770
|
-
const
|
|
1771
|
-
if (!
|
|
1772
|
-
const
|
|
1773
|
-
if (
|
|
1774
|
-
this._writeWorldSegment(this._selectLine,
|
|
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);
|
|
1775
1702
|
}
|
|
1776
1703
|
}
|
|
1777
1704
|
/** Откат текущего режима выборки */
|
|
@@ -1780,106 +1707,108 @@ let _e = class {
|
|
|
1780
1707
|
}
|
|
1781
1708
|
/** Освобождает ресурсы хендлера, удаляет слушатели и очищает внутренние данные. */
|
|
1782
1709
|
dispose() {
|
|
1783
|
-
this.rollback(), this.
|
|
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();
|
|
1784
1711
|
}
|
|
1785
1712
|
/** Инициализация буферных линий для режима (hover и click).
|
|
1786
1713
|
* На весь режим будет использовано 2 глобальных линии на сцене,
|
|
1787
1714
|
* использоваться они будут только для обозначения геометрии ребер конкретной фигуры.
|
|
1788
1715
|
*/
|
|
1789
|
-
_makeOverlayLine(
|
|
1790
|
-
const
|
|
1791
|
-
|
|
1792
|
-
const
|
|
1793
|
-
color:
|
|
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,
|
|
1794
1721
|
depthTest: !1,
|
|
1795
1722
|
depthWrite: !1,
|
|
1796
1723
|
transparent: !0,
|
|
1797
1724
|
opacity: 1
|
|
1798
|
-
}),
|
|
1799
|
-
return
|
|
1800
|
-
},
|
|
1725
|
+
}), s = new a.Line(t, r);
|
|
1726
|
+
return s.renderOrder = 1e3, s.raycast = () => {
|
|
1727
|
+
}, s.layers.set(x), s.visible = !1, s;
|
|
1801
1728
|
}
|
|
1802
1729
|
/** Локальные точки сегмента переводим в target (который висит на сцене) */
|
|
1803
|
-
_writeWorldSegment(
|
|
1804
|
-
const
|
|
1805
|
-
|
|
1806
|
-
),
|
|
1807
|
-
|
|
1808
|
-
),
|
|
1809
|
-
|
|
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;
|
|
1810
1737
|
}
|
|
1811
|
-
_same(
|
|
1812
|
-
return !!
|
|
1738
|
+
_same(e, t) {
|
|
1739
|
+
return !!e && !!t && e.lines === t.lines && e.seg === t.seg;
|
|
1813
1740
|
}
|
|
1814
1741
|
/** Центрует `THREE.Line` на сегменте и ориентирует её вдоль ребра */
|
|
1815
|
-
_centerAndOrientLineOnSegment(
|
|
1816
|
-
const
|
|
1817
|
-
e.matrixWorld
|
|
1818
|
-
), h = new a.Vector3(i.getX(o), i.getY(o), i.getZ(o)).applyMatrix4(
|
|
1819
|
-
e.matrixWorld
|
|
1820
|
-
), l = new a.Vector3().subVectors(h, n), c = l.length();
|
|
1821
|
-
if (!isFinite(c) || c === 0) return;
|
|
1822
|
-
const d = new a.Vector3().addVectors(n, h).multiplyScalar(0.5);
|
|
1823
|
-
t.position.copy(d);
|
|
1824
|
-
const g = t.geometry;
|
|
1825
|
-
let m = g.getAttribute("position");
|
|
1826
|
-
(!m || m.count < 2) && (g.setAttribute("position", new a.BufferAttribute(new Float32Array(6), 3)), m = g.getAttribute("position")), m.setXYZ(0, -c / 2, 0, 0), m.setXYZ(1, c / 2, 0, 0), m.needsUpdate = !0, l.normalize();
|
|
1827
|
-
const f = new a.Quaternion().setFromUnitVectors(new a.Vector3(1, 0, 0), l);
|
|
1828
|
-
t.quaternion.copy(f), t.updateMatrixWorld(!0);
|
|
1829
|
-
}
|
|
1830
|
-
/** Запись метаданных выбранного ребра для использования инструментов */
|
|
1831
|
-
_prepareEdgeMetadata(t, e) {
|
|
1832
|
-
const s = Ye(t);
|
|
1833
|
-
if (!s) return;
|
|
1834
|
-
const i = t.geometry.getAttribute("position"), r = e * 2, o = r + 1, n = new a.Vector3(i.getX(r), i.getY(r), i.getZ(r)).applyMatrix4(
|
|
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(
|
|
1835
1744
|
t.matrixWorld
|
|
1836
|
-
),
|
|
1745
|
+
), c = new a.Vector3(s.getX(o), s.getY(o), s.getZ(o)).applyMatrix4(
|
|
1837
1746
|
t.matrixWorld
|
|
1838
|
-
),
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
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);
|
|
1756
|
+
}
|
|
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);
|
|
1844
1771
|
this._selectLine.userData.edgeInfo = {
|
|
1845
|
-
lines:
|
|
1846
|
-
seg:
|
|
1847
|
-
mesh:
|
|
1848
|
-
aIndices:
|
|
1849
|
-
bIndices:
|
|
1850
|
-
aEdgeIndices:
|
|
1851
|
-
bEdgeIndices:
|
|
1772
|
+
lines: e,
|
|
1773
|
+
seg: t,
|
|
1774
|
+
mesh: r,
|
|
1775
|
+
aIndices: y,
|
|
1776
|
+
bIndices: b,
|
|
1777
|
+
aEdgeIndices: I,
|
|
1778
|
+
bEdgeIndices: $
|
|
1852
1779
|
};
|
|
1853
1780
|
}
|
|
1854
1781
|
};
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
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;
|
|
1868
1797
|
}
|
|
1869
1798
|
/** Режим редактирования сцены */
|
|
1870
|
-
mode =
|
|
1799
|
+
mode = W.AddFigure;
|
|
1871
1800
|
/** Последняя добавленная фигура, нужно для отката через `ctrl + z`. */
|
|
1872
1801
|
_lastAddedMesh = null;
|
|
1873
1802
|
/** Добавление базовых фигур на сцену, которые приписаны в `FigureType`. */
|
|
1874
|
-
handle(
|
|
1875
|
-
const
|
|
1876
|
-
|
|
1877
|
-
const
|
|
1878
|
-
|
|
1879
|
-
const
|
|
1880
|
-
|
|
1881
|
-
const
|
|
1882
|
-
|
|
1803
|
+
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;
|
|
1883
1812
|
}
|
|
1884
1813
|
/** Срабатывает только на `ctrl + z`. */
|
|
1885
1814
|
rollback() {
|
|
@@ -1890,26 +1819,26 @@ let ue = class {
|
|
|
1890
1819
|
this._lastAddedMesh = null;
|
|
1891
1820
|
}
|
|
1892
1821
|
};
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
],
|
|
1897
|
-
var
|
|
1898
|
-
for (var
|
|
1899
|
-
(n =
|
|
1900
|
-
return
|
|
1901
|
-
},
|
|
1902
|
-
let
|
|
1903
|
-
constructor(
|
|
1904
|
-
this._api =
|
|
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);
|
|
1829
|
+
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;
|
|
1905
1834
|
}
|
|
1906
1835
|
/** Режим редактирования сцены */
|
|
1907
|
-
mode =
|
|
1836
|
+
mode = W.DeleteFigure;
|
|
1908
1837
|
/** Последняя удаленная фигура, сохраняем для отката через `ctrl + z` */
|
|
1909
1838
|
_lastDeletedMesh = null;
|
|
1910
1839
|
handle() {
|
|
1911
|
-
const
|
|
1912
|
-
|
|
1840
|
+
const e = this._store.getSelectedObject();
|
|
1841
|
+
ps(e) && (this._api.removeMesh(e), this._store.setSelectedObject(null), this._lastDeletedMesh = e);
|
|
1913
1842
|
}
|
|
1914
1843
|
/** Срабатывает только на `ctrl + z`. */
|
|
1915
1844
|
rollback() {
|
|
@@ -1920,147 +1849,209 @@ let pe = class {
|
|
|
1920
1849
|
this._lastDeletedMesh = null;
|
|
1921
1850
|
}
|
|
1922
1851
|
};
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
],
|
|
1928
|
-
var
|
|
1929
|
-
for (var
|
|
1930
|
-
(n =
|
|
1931
|
-
return
|
|
1932
|
-
},
|
|
1933
|
-
let
|
|
1934
|
-
constructor(t) {
|
|
1935
|
-
this._renderer = t;
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
addMeshes(t) {
|
|
1943
|
-
for (const e of t)
|
|
1944
|
-
this._renderer.addMesh(e);
|
|
1945
|
-
}
|
|
1946
|
-
/** @inheritdoc */
|
|
1947
|
-
removeMesh(t) {
|
|
1948
|
-
this._renderer.removeMesh(t);
|
|
1949
|
-
}
|
|
1950
|
-
/** @inheritdoc */
|
|
1951
|
-
removeMeshes(t) {
|
|
1952
|
-
for (const e of t)
|
|
1953
|
-
this._renderer.removeMesh(e);
|
|
1954
|
-
}
|
|
1955
|
-
/** @inheritdoc */
|
|
1956
|
-
getMeshes() {
|
|
1957
|
-
return this._renderer.getMeshes();
|
|
1958
|
-
}
|
|
1959
|
-
/** @inheritdoc */
|
|
1960
|
-
setMode(t) {
|
|
1961
|
-
this._renderer.setTransformControlsMode(t);
|
|
1962
|
-
}
|
|
1963
|
-
/** @inheritdoc */
|
|
1964
|
-
attach(t) {
|
|
1965
|
-
this._renderer.attachTransformControls(t);
|
|
1966
|
-
}
|
|
1967
|
-
/** @inheritdoc */
|
|
1968
|
-
detach() {
|
|
1969
|
-
this._renderer.detachTransformControls();
|
|
1970
|
-
}
|
|
1971
|
-
/** @inheritdoc */
|
|
1972
|
-
setRaycastMode(t) {
|
|
1973
|
-
this._renderer.setRaycastMode(t);
|
|
1974
|
-
}
|
|
1975
|
-
/** @inheritdoc */
|
|
1976
|
-
addObject(t, e) {
|
|
1977
|
-
this._renderer.addObject(t, e);
|
|
1978
|
-
}
|
|
1979
|
-
/** @inheritdoc */
|
|
1980
|
-
removeObject(t) {
|
|
1981
|
-
this._renderer.removeObject(t);
|
|
1982
|
-
}
|
|
1983
|
-
/** @inheritdoc */
|
|
1984
|
-
enableCameraLayer(t) {
|
|
1985
|
-
this._renderer.enableCameraLayer(t);
|
|
1986
|
-
}
|
|
1987
|
-
/** @inheritdoc */
|
|
1988
|
-
onTransformChange(t) {
|
|
1989
|
-
return this._renderer.onTransformChange(t);
|
|
1990
|
-
}
|
|
1991
|
-
};
|
|
1992
|
-
me = ms([
|
|
1993
|
-
M(),
|
|
1994
|
-
fs(0, _("EditorRenderer"))
|
|
1995
|
-
], me);
|
|
1996
|
-
var gs = Object.getOwnPropertyDescriptor, bs = (t, e, s, i) => {
|
|
1997
|
-
for (var r = i > 1 ? void 0 : i ? gs(e, s) : e, o = t.length - 1, n; o >= 0; o--)
|
|
1998
|
-
(n = t[o]) && (r = n(r) || r);
|
|
1999
|
-
return r;
|
|
2000
|
-
}, W = (t, e) => (s, i) => e(s, i, t);
|
|
2001
|
-
let fe = class {
|
|
2002
|
-
constructor(t, e, s, i, r, o) {
|
|
2003
|
-
this._displayManager = t, this._selectManager = e, this._toolManager = s, this._sceneManager = i, this._renderer = r, this._store = o, this.setSelectMode(y.Mesh), this.setToolMode(F.Translate);
|
|
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);
|
|
1860
|
+
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);
|
|
1865
|
+
}
|
|
1866
|
+
setDisplayMode(e) {
|
|
1867
|
+
return this._mediator.send({
|
|
1868
|
+
type: P.Display,
|
|
1869
|
+
payload: [e]
|
|
1870
|
+
});
|
|
2004
1871
|
}
|
|
2005
|
-
|
|
2006
|
-
this.
|
|
1872
|
+
setSceneMode(e) {
|
|
1873
|
+
return this._mediator.send({
|
|
1874
|
+
type: P.Scene,
|
|
1875
|
+
payload: [e]
|
|
1876
|
+
});
|
|
2007
1877
|
}
|
|
2008
|
-
|
|
2009
|
-
this.
|
|
1878
|
+
setSelectMode(e) {
|
|
1879
|
+
return this._mediator.send({
|
|
1880
|
+
type: P.Select,
|
|
1881
|
+
payload: [e]
|
|
1882
|
+
});
|
|
2010
1883
|
}
|
|
2011
|
-
|
|
2012
|
-
this.
|
|
1884
|
+
setToolMode(e) {
|
|
1885
|
+
return this._mediator.send({
|
|
1886
|
+
type: P.Tool,
|
|
1887
|
+
payload: [e]
|
|
1888
|
+
});
|
|
2013
1889
|
}
|
|
2014
|
-
|
|
2015
|
-
this.
|
|
1890
|
+
addFigure(e, t) {
|
|
1891
|
+
return this._mediator.send({
|
|
1892
|
+
type: P.Scene,
|
|
1893
|
+
payload: [e, t]
|
|
1894
|
+
});
|
|
2016
1895
|
}
|
|
2017
1896
|
resizeRenderer() {
|
|
2018
1897
|
this._renderer.resize();
|
|
2019
1898
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
1899
|
+
/**
|
|
1900
|
+
* Запускает редактор.
|
|
1901
|
+
* Вызывается после создания хаба.
|
|
1902
|
+
*/
|
|
1903
|
+
start() {
|
|
1904
|
+
this._controller.start();
|
|
2022
1905
|
}
|
|
2023
|
-
|
|
2024
|
-
|
|
1906
|
+
/**
|
|
1907
|
+
* Останавливает редактор.
|
|
1908
|
+
*/
|
|
1909
|
+
stop() {
|
|
1910
|
+
this._controller.stop();
|
|
2025
1911
|
}
|
|
2026
1912
|
getSelectionStats() {
|
|
2027
1913
|
return this._store.getSelectionStats();
|
|
2028
1914
|
}
|
|
2029
|
-
onSelectionStatsChange(
|
|
2030
|
-
const
|
|
2031
|
-
|
|
2032
|
-
}),
|
|
2033
|
-
|
|
1915
|
+
onSelectionStatsChange(e) {
|
|
1916
|
+
const t = this._store.onSelectedObjectChange(() => {
|
|
1917
|
+
e();
|
|
1918
|
+
}), r = this._store.onSelectedTransformChange(() => {
|
|
1919
|
+
e();
|
|
2034
1920
|
});
|
|
2035
1921
|
return () => {
|
|
2036
|
-
|
|
1922
|
+
t(), r();
|
|
2037
1923
|
};
|
|
2038
1924
|
}
|
|
2039
1925
|
dispose() {
|
|
2040
|
-
this.
|
|
1926
|
+
this._mediator.dispose();
|
|
2041
1927
|
}
|
|
2042
1928
|
};
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
(n = t[o]) && (r = n(r) || r);
|
|
2055
|
-
return r;
|
|
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);
|
|
1939
|
+
return i;
|
|
2056
1940
|
};
|
|
2057
|
-
let
|
|
1941
|
+
let Ie = class {
|
|
1942
|
+
/**
|
|
1943
|
+
* Внутренний эмиттер событий Node.js.
|
|
1944
|
+
*
|
|
1945
|
+
* @private
|
|
1946
|
+
* @member
|
|
1947
|
+
*/
|
|
1948
|
+
_emitter;
|
|
1949
|
+
/** @constructor */
|
|
1950
|
+
constructor() {
|
|
1951
|
+
this._emitter = new at();
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Публикует событие в шину.
|
|
1955
|
+
*
|
|
1956
|
+
* @param event - название события (из `EventTopics`)
|
|
1957
|
+
* @param payload - данные события (тип зависит от события)
|
|
1958
|
+
*
|
|
1959
|
+
* @typeParam K - ключ события из `EditorEvents`
|
|
1960
|
+
*
|
|
1961
|
+
* @remarks
|
|
1962
|
+
* Все подписчики, зарегистрированные на это событие, получат payload.
|
|
1963
|
+
*
|
|
1964
|
+
* @example
|
|
1965
|
+
* ```typescript
|
|
1966
|
+
* // Публикация события клика
|
|
1967
|
+
* eventBus.emit(EventTopics.SelectClick, { intersection: hit });
|
|
1968
|
+
*
|
|
1969
|
+
* // Публикация события сброса выделения
|
|
1970
|
+
* eventBus.emit(EventTopics.SelectClick, null);
|
|
1971
|
+
* ```
|
|
1972
|
+
*
|
|
1973
|
+
* @public
|
|
1974
|
+
* @method
|
|
1975
|
+
*/
|
|
1976
|
+
emit(e, t) {
|
|
1977
|
+
this._emitter.emit(e, t);
|
|
1978
|
+
}
|
|
1979
|
+
/**
|
|
1980
|
+
* Подписывается на событие.
|
|
1981
|
+
*
|
|
1982
|
+
* @param event - название события (из `EventTopics`)
|
|
1983
|
+
* @param listener - функция-обработчик, получающая payload
|
|
1984
|
+
*
|
|
1985
|
+
* @typeParam K - ключ события из `EditorEvents`
|
|
1986
|
+
*
|
|
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
|
+
* ```
|
|
2002
|
+
*
|
|
2003
|
+
* @public
|
|
2004
|
+
* @method
|
|
2005
|
+
*/
|
|
2006
|
+
on(e, t) {
|
|
2007
|
+
this._emitter.on(e, t);
|
|
2008
|
+
}
|
|
2009
|
+
/**
|
|
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) => { ... };
|
|
2025
|
+
*
|
|
2026
|
+
* // Подписка
|
|
2027
|
+
* eventBus.on(EventTopics.SelectClick, this._handleClick);
|
|
2028
|
+
*
|
|
2029
|
+
* // Отписка (в dispose)
|
|
2030
|
+
* eventBus.off(EventTopics.SelectClick, this._handleClick);
|
|
2031
|
+
* ```
|
|
2032
|
+
*
|
|
2033
|
+
* @public
|
|
2034
|
+
* @method
|
|
2035
|
+
*/
|
|
2036
|
+
off(e, t) {
|
|
2037
|
+
this._emitter.off(e, t);
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
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);
|
|
2046
|
+
return i;
|
|
2047
|
+
};
|
|
2048
|
+
let Pe = class {
|
|
2058
2049
|
/** Текущий режим выборки. */
|
|
2059
|
-
_selectMode =
|
|
2050
|
+
_selectMode = M.Mesh;
|
|
2060
2051
|
/** Текущий выбранный инструмент. */
|
|
2061
|
-
_toolType =
|
|
2052
|
+
_toolType = j.Translate;
|
|
2062
2053
|
/** Выбранный режим отображения. */
|
|
2063
|
-
_displayMode =
|
|
2054
|
+
_displayMode = F.Plane;
|
|
2064
2055
|
/** Выбранный объект на сцене. */
|
|
2065
2056
|
_selectedObject = null;
|
|
2066
2057
|
/** Слушатели событий по изменению выбранного объекта. */
|
|
@@ -2068,83 +2059,164 @@ let ge = class {
|
|
|
2068
2059
|
/** Слушатели событий трансформации выбранного объекта. */
|
|
2069
2060
|
_transformListeners = /* @__PURE__ */ new Set();
|
|
2070
2061
|
constructor() {
|
|
2071
|
-
|
|
2062
|
+
ct(this, {}, { autoBind: !0 });
|
|
2072
2063
|
}
|
|
2073
|
-
/** @inheritdoc */
|
|
2074
2064
|
getSelectMode() {
|
|
2075
2065
|
return this._selectMode;
|
|
2076
2066
|
}
|
|
2077
|
-
/** @inheritdoc */
|
|
2078
2067
|
getToolType() {
|
|
2079
2068
|
return this._toolType;
|
|
2080
2069
|
}
|
|
2081
|
-
/** @inheritdoc */
|
|
2082
2070
|
getDisplayMode() {
|
|
2083
2071
|
return this._displayMode;
|
|
2084
2072
|
}
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
this._selectMode = t;
|
|
2073
|
+
setSelectMode(e) {
|
|
2074
|
+
this._selectMode = e;
|
|
2088
2075
|
}
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
this._toolType = t;
|
|
2076
|
+
setToolType(e) {
|
|
2077
|
+
this._toolType = e;
|
|
2092
2078
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
this._displayMode = t;
|
|
2079
|
+
setDisplayMode(e) {
|
|
2080
|
+
this._displayMode = e;
|
|
2096
2081
|
}
|
|
2097
|
-
/** @inheritdoc */
|
|
2098
2082
|
getSelectedObject() {
|
|
2099
2083
|
return this._selectedObject;
|
|
2100
2084
|
}
|
|
2101
|
-
/** @inheritdoc */
|
|
2102
2085
|
getSelectionStats() {
|
|
2103
|
-
const
|
|
2104
|
-
return
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
this.
|
|
2110
|
-
for (const e of this._selectedListeners) e(this._selectedObject);
|
|
2086
|
+
const e = this._selectedObject;
|
|
2087
|
+
return e ? vs(e) : null;
|
|
2088
|
+
}
|
|
2089
|
+
setSelectedObject(e) {
|
|
2090
|
+
if (this._selectedObject !== e) {
|
|
2091
|
+
this._selectedObject = e;
|
|
2092
|
+
for (const t of this._selectedListeners) t(this._selectedObject);
|
|
2111
2093
|
}
|
|
2112
2094
|
}
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
return this._selectedListeners.add(t), () => this._selectedListeners.delete(t);
|
|
2095
|
+
onSelectedObjectChange(e) {
|
|
2096
|
+
return this._selectedListeners.add(e), () => this._selectedListeners.delete(e);
|
|
2116
2097
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
return this._transformListeners.add(t), () => this._transformListeners.delete(t);
|
|
2098
|
+
onSelectedTransformChange(e) {
|
|
2099
|
+
return this._transformListeners.add(e), () => this._transformListeners.delete(e);
|
|
2120
2100
|
}
|
|
2121
|
-
/** @inheritdoc */
|
|
2122
2101
|
notifySelectedTransformChange() {
|
|
2123
|
-
for (const
|
|
2102
|
+
for (const e of this._transformListeners) e();
|
|
2124
2103
|
}
|
|
2125
2104
|
};
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
],
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
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 {
|
|
2110
|
+
constructor(t, r, s, i) {
|
|
2111
|
+
super(r), this.type = t, this.code = s, this.meta = i, this.name = this._name;
|
|
2112
|
+
}
|
|
2113
|
+
_name = "PolicyException";
|
|
2114
|
+
}
|
|
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);
|
|
2118
|
+
return i;
|
|
2119
|
+
}, ks = (e, t) => (r, s) => t(r, s, e);
|
|
2120
|
+
let Le = class {
|
|
2121
|
+
constructor(e) {
|
|
2122
|
+
this._store = e;
|
|
2123
|
+
}
|
|
2124
|
+
check(e) {
|
|
2125
|
+
const t = this._store.getSelectMode();
|
|
2126
|
+
if (!st[t].includes(e))
|
|
2127
|
+
throw new qe(
|
|
2128
|
+
G.ToolNotAllowed,
|
|
2129
|
+
`Tool ${e} is not allowed`,
|
|
2130
|
+
"TOOL_NOT_ALLOWED"
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
};
|
|
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);
|
|
2141
|
+
return i;
|
|
2142
|
+
};
|
|
2143
|
+
let Ee = class {
|
|
2144
|
+
handle(e) {
|
|
2145
|
+
try {
|
|
2146
|
+
return e();
|
|
2147
|
+
} catch (t) {
|
|
2148
|
+
return t instanceof qe ? {
|
|
2149
|
+
type: t.type,
|
|
2150
|
+
message: t.message,
|
|
2151
|
+
code: t.code,
|
|
2152
|
+
blocked: !0
|
|
2153
|
+
} : t instanceof Error ? {
|
|
2154
|
+
type: G.Error,
|
|
2155
|
+
message: t.message,
|
|
2156
|
+
code: "UNHANDLED_EXCEPTION",
|
|
2157
|
+
blocked: !0
|
|
2158
|
+
} : {
|
|
2159
|
+
type: G.Error,
|
|
2160
|
+
message: "Unknown exception",
|
|
2161
|
+
code: "UNKNOWN_EXCEPTION",
|
|
2162
|
+
blocked: !0
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
};
|
|
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);
|
|
2173
|
+
return i;
|
|
2174
|
+
}, ze = (e, t) => (r, s) => t(r, s, e);
|
|
2175
|
+
let Te = class {
|
|
2176
|
+
constructor(e, t) {
|
|
2177
|
+
this._middlewares = t, this._managers = new Map(e.map((r) => [r.type, r]));
|
|
2178
|
+
}
|
|
2179
|
+
_managers;
|
|
2180
|
+
send(e) {
|
|
2181
|
+
const t = this._managers.get(e.type);
|
|
2182
|
+
if (!t)
|
|
2183
|
+
return {
|
|
2184
|
+
type: G.Error,
|
|
2185
|
+
message: `Manager for feature "${String(e.type)}" not found`,
|
|
2186
|
+
code: "MANAGER_NOT_FOUND",
|
|
2187
|
+
blocked: !0
|
|
2188
|
+
};
|
|
2189
|
+
const r = () => (t.manage(...e.payload), null);
|
|
2190
|
+
return this._middlewares.reduceRight((i, o) => () => o.handle(i), r)();
|
|
2191
|
+
}
|
|
2192
|
+
dispose() {
|
|
2193
|
+
this._managers && this._managers.clear();
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
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;
|
|
2133
2205
|
}
|
|
2134
|
-
let
|
|
2135
|
-
const
|
|
2136
|
-
if (!
|
|
2206
|
+
let H = null;
|
|
2207
|
+
const er = (e) => (H || (H = Us(e)), H.resolve("EditorHub")), tr = () => {
|
|
2208
|
+
if (!H)
|
|
2137
2209
|
throw new Error("EditorHub is not initialized. Call createAppHub(canvas) first.");
|
|
2138
|
-
return
|
|
2210
|
+
return H.resolve("EditorHub");
|
|
2139
2211
|
};
|
|
2140
2212
|
export {
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2213
|
+
Ce as EditorHub,
|
|
2214
|
+
Ie as EventBus,
|
|
2215
|
+
V as EventTopics,
|
|
2216
|
+
P as FeatureType,
|
|
2217
|
+
Js as ObjLoader,
|
|
2218
|
+
te as Renderer,
|
|
2219
|
+
G as ResponseType,
|
|
2220
|
+
er as createAppHub,
|
|
2221
|
+
tr as getAppHub
|
|
2150
2222
|
};
|