@fps-games/editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/dist/authoring-apply.d.ts +21 -0
  2. package/dist/authoring-apply.d.ts.map +1 -0
  3. package/dist/authoring-apply.js +45 -0
  4. package/dist/authoring-apply.js.map +1 -0
  5. package/dist/index.d.ts +85 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +539 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/local-editor-harness.d.ts +173 -0
  10. package/dist/local-editor-harness.d.ts.map +1 -0
  11. package/dist/local-editor-harness.js +969 -0
  12. package/dist/local-editor-harness.js.map +1 -0
  13. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.d.ts +20 -0
  14. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.d.ts.map +1 -0
  15. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js +239 -0
  16. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js.map +1 -0
  17. package/node_modules/@fps-games/editor-babylon/dist/edit-session.d.ts +30 -0
  18. package/node_modules/@fps-games/editor-babylon/dist/edit-session.d.ts.map +1 -0
  19. package/node_modules/@fps-games/editor-babylon/dist/edit-session.js +297 -0
  20. package/node_modules/@fps-games/editor-babylon/dist/edit-session.js.map +1 -0
  21. package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts +30 -0
  22. package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts.map +1 -0
  23. package/node_modules/@fps-games/editor-babylon/dist/editor-world.js +67 -0
  24. package/node_modules/@fps-games/editor-babylon/dist/editor-world.js.map +1 -0
  25. package/node_modules/@fps-games/editor-babylon/dist/event-guard.d.ts +13 -0
  26. package/node_modules/@fps-games/editor-babylon/dist/event-guard.d.ts.map +1 -0
  27. package/node_modules/@fps-games/editor-babylon/dist/event-guard.js +101 -0
  28. package/node_modules/@fps-games/editor-babylon/dist/event-guard.js.map +1 -0
  29. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +19 -0
  30. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -0
  31. package/node_modules/@fps-games/editor-babylon/dist/index.js +18 -0
  32. package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -0
  33. package/node_modules/@fps-games/editor-babylon/dist/input-controller.d.ts +3 -0
  34. package/node_modules/@fps-games/editor-babylon/dist/input-controller.d.ts.map +1 -0
  35. package/node_modules/@fps-games/editor-babylon/dist/input-controller.js +182 -0
  36. package/node_modules/@fps-games/editor-babylon/dist/input-controller.js.map +1 -0
  37. package/node_modules/@fps-games/editor-babylon/dist/inspector-adapter.d.ts +13 -0
  38. package/node_modules/@fps-games/editor-babylon/dist/inspector-adapter.d.ts.map +1 -0
  39. package/node_modules/@fps-games/editor-babylon/dist/inspector-adapter.js +94 -0
  40. package/node_modules/@fps-games/editor-babylon/dist/inspector-adapter.js.map +1 -0
  41. package/node_modules/@fps-games/editor-babylon/dist/inspector-host.d.ts +43 -0
  42. package/node_modules/@fps-games/editor-babylon/dist/inspector-host.d.ts.map +1 -0
  43. package/node_modules/@fps-games/editor-babylon/dist/inspector-host.js +510 -0
  44. package/node_modules/@fps-games/editor-babylon/dist/inspector-host.js.map +1 -0
  45. package/node_modules/@fps-games/editor-babylon/dist/legacy-runtime.d.ts +5 -0
  46. package/node_modules/@fps-games/editor-babylon/dist/legacy-runtime.d.ts.map +1 -0
  47. package/node_modules/@fps-games/editor-babylon/dist/legacy-runtime.js +5 -0
  48. package/node_modules/@fps-games/editor-babylon/dist/legacy-runtime.js.map +1 -0
  49. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.d.ts +22 -0
  50. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.d.ts.map +1 -0
  51. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js +408 -0
  52. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js.map +1 -0
  53. package/node_modules/@fps-games/editor-babylon/dist/monitor.d.ts +39 -0
  54. package/node_modules/@fps-games/editor-babylon/dist/monitor.d.ts.map +1 -0
  55. package/node_modules/@fps-games/editor-babylon/dist/monitor.js +780 -0
  56. package/node_modules/@fps-games/editor-babylon/dist/monitor.js.map +1 -0
  57. package/node_modules/@fps-games/editor-babylon/dist/outline-adapter.d.ts +37 -0
  58. package/node_modules/@fps-games/editor-babylon/dist/outline-adapter.d.ts.map +1 -0
  59. package/node_modules/@fps-games/editor-babylon/dist/outline-adapter.js +268 -0
  60. package/node_modules/@fps-games/editor-babylon/dist/outline-adapter.js.map +1 -0
  61. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.d.ts +34 -0
  62. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.d.ts.map +1 -0
  63. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.js +221 -0
  64. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.js.map +1 -0
  65. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +90 -0
  66. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -0
  67. package/node_modules/@fps-games/editor-babylon/dist/projection.js +479 -0
  68. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -0
  69. package/node_modules/@fps-games/editor-babylon/dist/runtime-globals.d.ts +3 -0
  70. package/node_modules/@fps-games/editor-babylon/dist/runtime-globals.d.ts.map +1 -0
  71. package/node_modules/@fps-games/editor-babylon/dist/runtime-globals.js +7 -0
  72. package/node_modules/@fps-games/editor-babylon/dist/runtime-globals.js.map +1 -0
  73. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts +18 -0
  74. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts.map +1 -0
  75. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js +213 -0
  76. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js.map +1 -0
  77. package/node_modules/@fps-games/editor-babylon/dist/scene-view-input-controller.d.ts +36 -0
  78. package/node_modules/@fps-games/editor-babylon/dist/scene-view-input-controller.d.ts.map +1 -0
  79. package/node_modules/@fps-games/editor-babylon/dist/scene-view-input-controller.js +272 -0
  80. package/node_modules/@fps-games/editor-babylon/dist/scene-view-input-controller.js.map +1 -0
  81. package/node_modules/@fps-games/editor-babylon/dist/selection-controller.d.ts +27 -0
  82. package/node_modules/@fps-games/editor-babylon/dist/selection-controller.d.ts.map +1 -0
  83. package/node_modules/@fps-games/editor-babylon/dist/selection-controller.js +308 -0
  84. package/node_modules/@fps-games/editor-babylon/dist/selection-controller.js.map +1 -0
  85. package/node_modules/@fps-games/editor-babylon/dist/tool-controller.d.ts +17 -0
  86. package/node_modules/@fps-games/editor-babylon/dist/tool-controller.d.ts.map +1 -0
  87. package/node_modules/@fps-games/editor-babylon/dist/tool-controller.js +83 -0
  88. package/node_modules/@fps-games/editor-babylon/dist/tool-controller.js.map +1 -0
  89. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts +47 -0
  90. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts.map +1 -0
  91. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js +689 -0
  92. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js.map +1 -0
  93. package/node_modules/@fps-games/editor-babylon/dist/types.d.ts +111 -0
  94. package/node_modules/@fps-games/editor-babylon/dist/types.d.ts.map +1 -0
  95. package/node_modules/@fps-games/editor-babylon/dist/types.js +2 -0
  96. package/node_modules/@fps-games/editor-babylon/dist/types.js.map +1 -0
  97. package/node_modules/@fps-games/editor-babylon/package.json +25 -0
  98. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +28 -0
  99. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -0
  100. package/node_modules/@fps-games/editor-browser/dist/index.js +54 -0
  101. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -0
  102. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts +12 -0
  103. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts.map +1 -0
  104. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js +80 -0
  105. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js.map +1 -0
  106. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.d.ts +11 -0
  107. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.d.ts.map +1 -0
  108. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js +33 -0
  109. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js.map +1 -0
  110. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +9 -0
  111. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -0
  112. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +444 -0
  113. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -0
  114. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts +21 -0
  115. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts.map +1 -0
  116. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js +103 -0
  117. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js.map +1 -0
  118. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts +12 -0
  119. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts.map +1 -0
  120. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js +123 -0
  121. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js.map +1 -0
  122. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.d.ts +2 -0
  123. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.d.ts.map +1 -0
  124. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.js +115 -0
  125. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.js.map +1 -0
  126. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.d.ts +3 -0
  127. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.d.ts.map +1 -0
  128. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.js +68 -0
  129. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.js.map +1 -0
  130. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +183 -0
  131. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -0
  132. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.js +2 -0
  133. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.js.map +1 -0
  134. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +58 -0
  135. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -0
  136. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +136 -0
  137. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -0
  138. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +4 -0
  139. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -0
  140. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +589 -0
  141. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -0
  142. package/node_modules/@fps-games/editor-browser/package.json +16 -0
  143. package/node_modules/@fps-games/editor-core/dist/authoring-source.d.ts +211 -0
  144. package/node_modules/@fps-games/editor-core/dist/authoring-source.d.ts.map +1 -0
  145. package/node_modules/@fps-games/editor-core/dist/authoring-source.js +511 -0
  146. package/node_modules/@fps-games/editor-core/dist/authoring-source.js.map +1 -0
  147. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts +132 -0
  148. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts.map +1 -0
  149. package/node_modules/@fps-games/editor-core/dist/editor-session.js +265 -0
  150. package/node_modules/@fps-games/editor-core/dist/editor-session.js.map +1 -0
  151. package/node_modules/@fps-games/editor-core/dist/host-services.d.ts +24 -0
  152. package/node_modules/@fps-games/editor-core/dist/host-services.d.ts.map +1 -0
  153. package/node_modules/@fps-games/editor-core/dist/host-services.js +2 -0
  154. package/node_modules/@fps-games/editor-core/dist/host-services.js.map +1 -0
  155. package/node_modules/@fps-games/editor-core/dist/index.d.ts +106 -0
  156. package/node_modules/@fps-games/editor-core/dist/index.d.ts.map +1 -0
  157. package/node_modules/@fps-games/editor-core/dist/index.js +217 -0
  158. package/node_modules/@fps-games/editor-core/dist/index.js.map +1 -0
  159. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts +44 -0
  160. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts.map +1 -0
  161. package/node_modules/@fps-games/editor-core/dist/scene-graph.js +86 -0
  162. package/node_modules/@fps-games/editor-core/dist/scene-graph.js.map +1 -0
  163. package/node_modules/@fps-games/editor-core/dist/scene-view-input.d.ts +41 -0
  164. package/node_modules/@fps-games/editor-core/dist/scene-view-input.d.ts.map +1 -0
  165. package/node_modules/@fps-games/editor-core/dist/scene-view-input.js +2 -0
  166. package/node_modules/@fps-games/editor-core/dist/scene-view-input.js.map +1 -0
  167. package/node_modules/@fps-games/editor-core/dist/serialized-object.d.ts +53 -0
  168. package/node_modules/@fps-games/editor-core/dist/serialized-object.d.ts.map +1 -0
  169. package/node_modules/@fps-games/editor-core/dist/serialized-object.js +32 -0
  170. package/node_modules/@fps-games/editor-core/dist/serialized-object.js.map +1 -0
  171. package/node_modules/@fps-games/editor-core/dist/transform-gizmo.d.ts +48 -0
  172. package/node_modules/@fps-games/editor-core/dist/transform-gizmo.d.ts.map +1 -0
  173. package/node_modules/@fps-games/editor-core/dist/transform-gizmo.js +2 -0
  174. package/node_modules/@fps-games/editor-core/dist/transform-gizmo.js.map +1 -0
  175. package/node_modules/@fps-games/editor-core/package.json +19 -0
  176. package/node_modules/@fps-games/editor-forge-play/dist/index.d.ts +46 -0
  177. package/node_modules/@fps-games/editor-forge-play/dist/index.d.ts.map +1 -0
  178. package/node_modules/@fps-games/editor-forge-play/dist/index.js +156 -0
  179. package/node_modules/@fps-games/editor-forge-play/dist/index.js.map +1 -0
  180. package/node_modules/@fps-games/editor-forge-play/package.json +19 -0
  181. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +239 -0
  182. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -0
  183. package/node_modules/@fps-games/editor-protocol/dist/index.js +54 -0
  184. package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -0
  185. package/node_modules/@fps-games/editor-protocol/package.json +16 -0
  186. package/package.json +40 -0
@@ -0,0 +1,689 @@
1
+ export function createBabylonTransformGizmoController(options) {
2
+ const GizmoManager = options.babylon.GizmoManager;
3
+ if (!GizmoManager)
4
+ throw new Error('Babylon runtime missing GizmoManager');
5
+ const manager = new GizmoManager(options.scene);
6
+ manager.usePointerToAttachGizmos = false;
7
+ manager.clearGizmoOnEmptyPointerEvent = false;
8
+ manager.boundingBoxGizmoEnabled = false;
9
+ let tool = options.initialTool ?? 'select';
10
+ let space = options.initialSpace ?? 'world';
11
+ let constraint = 'axis';
12
+ let selectedNodeId = null;
13
+ let selectedNodeIds = [];
14
+ let activeDrag = null;
15
+ let disposed = false;
16
+ let observerDisposers = [];
17
+ let pivotProxy = null;
18
+ const canvas = options.scene.getEngine?.().getRenderingCanvas?.();
19
+ function activeTransformTool() {
20
+ return tool === 'select' ? null : tool;
21
+ }
22
+ function getActiveTargetId() {
23
+ if (selectedNodeId && selectedNodeIds.includes(selectedNodeId))
24
+ return selectedNodeId;
25
+ return selectedNodeIds[selectedNodeIds.length - 1] ?? null;
26
+ }
27
+ function getBatchTransformTargetIds() {
28
+ if ((tool === 'select' || tool == null) || selectedNodeIds.length <= 1)
29
+ return [];
30
+ return selectedNodeIds.filter(nodeId => !!options.projection.getAttachableRoot(nodeId));
31
+ }
32
+ function ensurePivotProxy() {
33
+ if (pivotProxy)
34
+ return pivotProxy;
35
+ const TransformNode = options.babylon.TransformNode;
36
+ if (!TransformNode)
37
+ return null;
38
+ pivotProxy = new TransformNode('editor.selectionPivotProxy', options.scene);
39
+ pivotProxy.metadata = {
40
+ ...(pivotProxy.metadata ?? {}),
41
+ editorProjectionHelper: true,
42
+ };
43
+ return pivotProxy;
44
+ }
45
+ function setPivotProxyTransform(pivot) {
46
+ const proxy = ensurePivotProxy();
47
+ const Vector3 = options.babylon.Vector3;
48
+ if (!proxy || !Vector3)
49
+ return null;
50
+ proxy.position = new Vector3(pivot.position.x, pivot.position.y, pivot.position.z);
51
+ proxy.rotation = new Vector3(0, 0, 0);
52
+ proxy.scaling = new Vector3(1, 1, 1);
53
+ return proxy;
54
+ }
55
+ function clearDragObservers() {
56
+ for (const dispose of observerDisposers)
57
+ dispose();
58
+ observerDisposers = [];
59
+ }
60
+ function addObserver(observable, callback) {
61
+ if (!observable?.add || !observable?.remove)
62
+ return;
63
+ const observer = observable.add(callback);
64
+ observerDisposers.push(() => {
65
+ try {
66
+ observable.remove(observer);
67
+ }
68
+ catch { }
69
+ });
70
+ }
71
+ function registerDragObserversFor(gizmo) {
72
+ const axisGizmos = [
73
+ gizmo?.xGizmo,
74
+ gizmo?.yGizmo,
75
+ gizmo?.zGizmo,
76
+ gizmo?.uniformScaleGizmo,
77
+ gizmo?.xPlaneGizmo,
78
+ gizmo?.yPlaneGizmo,
79
+ gizmo?.zPlaneGizmo,
80
+ ];
81
+ for (const axis of axisGizmos) {
82
+ const behavior = axis?.dragBehavior;
83
+ addObserver(behavior?.onDragStartObservable, beginDrag);
84
+ addObserver(behavior?.onDragObservable, updateDrag);
85
+ addObserver(behavior?.onDragEndObservable, endDrag);
86
+ }
87
+ }
88
+ function registerDragObservers() {
89
+ clearDragObservers();
90
+ registerDragObserversFor(manager.gizmos?.positionGizmo);
91
+ registerDragObserversFor(manager.gizmos?.rotationGizmo);
92
+ registerDragObserversFor(manager.gizmos?.scaleGizmo);
93
+ }
94
+ function applySpacePreference() {
95
+ const matchAttachedMesh = space === 'local';
96
+ const gizmos = [
97
+ manager.gizmos?.positionGizmo,
98
+ manager.gizmos?.rotationGizmo,
99
+ manager.gizmos?.scaleGizmo,
100
+ ];
101
+ for (const gizmo of gizmos) {
102
+ try {
103
+ if ('updateGizmoRotationToMatchAttachedMesh' in (gizmo ?? {})) {
104
+ gizmo.updateGizmoRotationToMatchAttachedMesh = matchAttachedMesh;
105
+ }
106
+ }
107
+ catch { }
108
+ for (const axis of [gizmo?.xGizmo, gizmo?.yGizmo, gizmo?.zGizmo]) {
109
+ try {
110
+ if ('updateGizmoRotationToMatchAttachedMesh' in (axis ?? {})) {
111
+ axis.updateGizmoRotationToMatchAttachedMesh = matchAttachedMesh;
112
+ }
113
+ }
114
+ catch { }
115
+ }
116
+ }
117
+ }
118
+ function attachCurrentSelection() {
119
+ const activeTool = activeTransformTool();
120
+ const viewPlaneMove = activeTool === 'move' && constraint === 'view-plane';
121
+ manager.positionGizmoEnabled = activeTool === 'move' && !viewPlaneMove;
122
+ manager.rotationGizmoEnabled = activeTool === 'rotate';
123
+ manager.scaleGizmoEnabled = activeTool === 'scale';
124
+ applySpacePreference();
125
+ registerDragObservers();
126
+ let target = null;
127
+ if (activeTool && !viewPlaneMove) {
128
+ const batchTransformTargetIds = getBatchTransformTargetIds();
129
+ if (batchTransformTargetIds.length > 1) {
130
+ const pivot = options.projection.getSelectionPivot(batchTransformTargetIds);
131
+ target = pivot ? setPivotProxyTransform(pivot) : null;
132
+ }
133
+ else {
134
+ const activeTargetId = getActiveTargetId();
135
+ target = activeTargetId ? options.projection.getAttachableRoot(activeTargetId) : null;
136
+ }
137
+ }
138
+ try {
139
+ manager.attachToNode?.(target ?? null);
140
+ }
141
+ catch (error) {
142
+ options.logger?.warn?.('[BabylonTransformGizmoController] failed to attach gizmo', error);
143
+ }
144
+ }
145
+ function beginDrag() {
146
+ if (activeDrag)
147
+ return;
148
+ const activeTool = activeTransformTool();
149
+ if (!activeTool)
150
+ return;
151
+ const targetIds = selectedNodeIds.length > 1
152
+ ? getBatchTransformTargetIds()
153
+ : [getActiveTargetId()].filter((nodeId) => !!nodeId);
154
+ const drag = createActiveDrag(activeTool, targetIds, activeTool === 'move' ? constraint : 'axis');
155
+ if (!drag)
156
+ return;
157
+ activeDrag = drag;
158
+ options.onDragStart?.(activeDrag);
159
+ }
160
+ function createActiveDrag(activeTool, targetIds, activeConstraint) {
161
+ if (targetIds.length === 0)
162
+ return null;
163
+ const beforeTransforms = options.projection.readNodeTransforms(targetIds);
164
+ const validTargetIds = targetIds.filter(nodeId => !!beforeTransforms[nodeId]);
165
+ if (validTargetIds.length === 0)
166
+ return null;
167
+ const pivot = validTargetIds.length > 1
168
+ ? options.projection.getSelectionPivot(validTargetIds)
169
+ : {
170
+ mode: 'selection-center',
171
+ position: beforeTransforms[validTargetIds[0]].position,
172
+ };
173
+ if (!pivot)
174
+ return null;
175
+ const before = validTargetIds.length === 1 ? beforeTransforms[validTargetIds[0]] ?? null : null;
176
+ return {
177
+ nodeId: validTargetIds.length === 1 ? validTargetIds[0] : null,
178
+ targetIds: validTargetIds,
179
+ activeId: selectedNodeId && validTargetIds.includes(selectedNodeId) ? selectedNodeId : validTargetIds[validTargetIds.length - 1] ?? null,
180
+ tool: activeTool,
181
+ space,
182
+ constraint: activeConstraint,
183
+ pivot,
184
+ before,
185
+ beforeTransforms,
186
+ };
187
+ }
188
+ function updateDrag() {
189
+ if (!activeDrag)
190
+ return;
191
+ if (activeDrag.targetIds.length > 1) {
192
+ const currentTransforms = previewBatchTransform(activeDrag);
193
+ const current = activeDrag.activeId
194
+ ? currentTransforms[activeDrag.activeId] ?? Object.values(currentTransforms)[0] ?? null
195
+ : Object.values(currentTransforms)[0] ?? null;
196
+ if (!current)
197
+ return;
198
+ options.onDragUpdate?.({ ...activeDrag, current });
199
+ return;
200
+ }
201
+ if (!activeDrag.nodeId)
202
+ return;
203
+ const current = options.projection.readNodeTransform(activeDrag.nodeId);
204
+ if (!current)
205
+ return;
206
+ options.onDragUpdate?.({ ...activeDrag, current });
207
+ }
208
+ function endDrag() {
209
+ const drag = activeDrag;
210
+ if (!drag)
211
+ return;
212
+ activeDrag = null;
213
+ if (drag.targetIds.length > 1) {
214
+ const afterTransforms = previewBatchTransform(drag);
215
+ emitTransformCommit(drag, afterTransforms);
216
+ attachCurrentSelection();
217
+ return;
218
+ }
219
+ if (!drag.nodeId || !drag.before) {
220
+ options.onDragCancel?.(drag);
221
+ return;
222
+ }
223
+ const after = options.projection.readNodeTransform(drag.nodeId);
224
+ if (!after) {
225
+ options.onDragCancel?.(drag);
226
+ return;
227
+ }
228
+ options.onDragEnd?.({
229
+ nodeId: drag.nodeId,
230
+ tool: drag.tool,
231
+ space: drag.space,
232
+ before: drag.before,
233
+ after,
234
+ });
235
+ }
236
+ function emitTransformCommit(drag, afterTransforms) {
237
+ if (drag.targetIds.length === 1) {
238
+ const nodeId = drag.targetIds[0];
239
+ const before = drag.beforeTransforms[nodeId];
240
+ const after = afterTransforms[nodeId];
241
+ if (!before || !after) {
242
+ options.onDragCancel?.(drag);
243
+ return;
244
+ }
245
+ options.onDragEnd?.({
246
+ nodeId,
247
+ tool: drag.tool,
248
+ space: drag.space,
249
+ before,
250
+ after,
251
+ });
252
+ return;
253
+ }
254
+ options.onDragEnd?.({
255
+ targetIds: drag.targetIds,
256
+ activeId: drag.activeId,
257
+ tool: drag.tool,
258
+ space: drag.space,
259
+ constraint: drag.constraint,
260
+ pivot: drag.pivot,
261
+ targets: drag.targetIds
262
+ .map((id) => {
263
+ const before = drag.beforeTransforms[id];
264
+ const after = afterTransforms[id];
265
+ return before && after ? { id, before, after } : null;
266
+ })
267
+ .filter((target) => !!target),
268
+ });
269
+ }
270
+ function previewBatchTransform(drag) {
271
+ const pivotTransform = readProjectionLikeTransform(pivotProxy, {
272
+ position: drag.pivot.position,
273
+ rotation: { x: 0, y: 0, z: 0 },
274
+ scale: { x: 1, y: 1, z: 1 },
275
+ });
276
+ if (drag.tool === 'move') {
277
+ return previewMoveWithDelta(drag, subtractVec3(pivotTransform.position, drag.pivot.position));
278
+ }
279
+ if (drag.tool === 'rotate') {
280
+ return previewRotateWithDelta(drag, pivotTransform.rotation);
281
+ }
282
+ if (drag.tool === 'scale') {
283
+ return previewScaleWithDelta(drag, pivotTransform.scale);
284
+ }
285
+ return {};
286
+ }
287
+ function previewMoveWithDelta(drag, delta) {
288
+ const transforms = {};
289
+ for (const nodeId of drag.targetIds) {
290
+ const before = drag.beforeTransforms[nodeId];
291
+ if (!before)
292
+ continue;
293
+ transforms[nodeId] = translateTransform(before, delta);
294
+ }
295
+ options.projection.setNodeTransformsPreview(transforms);
296
+ return transforms;
297
+ }
298
+ function translateTransform(transform, delta) {
299
+ return {
300
+ position: addVec3(transform.position, delta),
301
+ rotation: transform.rotation,
302
+ scale: transform.scale,
303
+ };
304
+ }
305
+ function previewRotateWithDelta(drag, rotationDelta) {
306
+ const transforms = {};
307
+ for (const nodeId of drag.targetIds) {
308
+ const before = drag.beforeTransforms[nodeId];
309
+ if (!before)
310
+ continue;
311
+ const offset = subtractVec3(before.position, drag.pivot.position);
312
+ transforms[nodeId] = {
313
+ position: addVec3(drag.pivot.position, rotateVec3Euler(offset, rotationDelta)),
314
+ rotation: addVec3(before.rotation, rotationDelta),
315
+ scale: before.scale,
316
+ };
317
+ }
318
+ options.projection.setNodeTransformsPreview(transforms);
319
+ return transforms;
320
+ }
321
+ function previewScaleWithDelta(drag, scaleDelta) {
322
+ const transforms = {};
323
+ const safeScale = {
324
+ x: Number.isFinite(scaleDelta.x) ? scaleDelta.x : 1,
325
+ y: Number.isFinite(scaleDelta.y) ? scaleDelta.y : 1,
326
+ z: Number.isFinite(scaleDelta.z) ? scaleDelta.z : 1,
327
+ };
328
+ for (const nodeId of drag.targetIds) {
329
+ const before = drag.beforeTransforms[nodeId];
330
+ if (!before)
331
+ continue;
332
+ const offset = subtractVec3(before.position, drag.pivot.position);
333
+ transforms[nodeId] = {
334
+ position: addVec3(drag.pivot.position, multiplyVec3(offset, safeScale)),
335
+ rotation: before.rotation,
336
+ scale: multiplyVec3(before.scale, safeScale),
337
+ };
338
+ }
339
+ options.projection.setNodeTransformsPreview(transforms);
340
+ return transforms;
341
+ }
342
+ function readProjectionLikeTransform(node, fallback) {
343
+ const rotation = node?.rotationQuaternion?.toEulerAngles?.() ?? node?.rotation;
344
+ return {
345
+ position: readVec3Like(node?.position) ?? fallback.position,
346
+ rotation: readVec3Like(rotation) ?? fallback.rotation,
347
+ scale: readVec3Like(node?.scaling) ?? fallback.scale,
348
+ };
349
+ }
350
+ function readVec3Like(value) {
351
+ if (!Number.isFinite(value?.x) || !Number.isFinite(value?.y) || !Number.isFinite(value?.z))
352
+ return null;
353
+ return {
354
+ x: Number(value.x),
355
+ y: Number(value.y),
356
+ z: Number(value.z),
357
+ };
358
+ }
359
+ function addVec3(left, right) {
360
+ return {
361
+ x: left.x + right.x,
362
+ y: left.y + right.y,
363
+ z: left.z + right.z,
364
+ };
365
+ }
366
+ function subtractVec3(left, right) {
367
+ return {
368
+ x: left.x - right.x,
369
+ y: left.y - right.y,
370
+ z: left.z - right.z,
371
+ };
372
+ }
373
+ function scaleVec3(value, factor) {
374
+ return {
375
+ x: value.x * factor,
376
+ y: value.y * factor,
377
+ z: value.z * factor,
378
+ };
379
+ }
380
+ function dotVec3(left, right) {
381
+ return left.x * right.x + left.y * right.y + left.z * right.z;
382
+ }
383
+ function multiplyVec3(left, right) {
384
+ return {
385
+ x: left.x * right.x,
386
+ y: left.y * right.y,
387
+ z: left.z * right.z,
388
+ };
389
+ }
390
+ function rotateVec3Euler(value, rotation) {
391
+ return rotateZ(rotateY(rotateX(value, rotation.x), rotation.y), rotation.z);
392
+ }
393
+ function rotateX(value, angle) {
394
+ const cos = Math.cos(angle);
395
+ const sin = Math.sin(angle);
396
+ return {
397
+ x: value.x,
398
+ y: value.y * cos - value.z * sin,
399
+ z: value.y * sin + value.z * cos,
400
+ };
401
+ }
402
+ function rotateY(value, angle) {
403
+ const cos = Math.cos(angle);
404
+ const sin = Math.sin(angle);
405
+ return {
406
+ x: value.x * cos + value.z * sin,
407
+ y: value.y,
408
+ z: -value.x * sin + value.z * cos,
409
+ };
410
+ }
411
+ function rotateZ(value, angle) {
412
+ const cos = Math.cos(angle);
413
+ const sin = Math.sin(angle);
414
+ return {
415
+ x: value.x * cos - value.y * sin,
416
+ y: value.x * sin + value.y * cos,
417
+ z: value.z,
418
+ };
419
+ }
420
+ function isViewPlaneMoveCandidate(event) {
421
+ if (disposed || activeDrag || tool !== 'move' || constraint !== 'view-plane' || event.button !== 0)
422
+ return false;
423
+ const targetIds = selectedNodeIds.length > 1
424
+ ? getBatchTransformTargetIds()
425
+ : [getActiveTargetId()].filter((nodeId) => !!nodeId);
426
+ if (targetIds.length === 0)
427
+ return false;
428
+ const pickedId = options.projection.pickNodeIdAt(event.clientX, event.clientY);
429
+ return !!pickedId && targetIds.includes(pickedId);
430
+ }
431
+ function isGizmoDragCandidate(event) {
432
+ if (disposed || activeDrag || event.button !== 0)
433
+ return false;
434
+ const activeTool = activeTransformTool();
435
+ if (!activeTool || (activeTool === 'move' && constraint === 'view-plane'))
436
+ return false;
437
+ const picked = pickGizmoMeshAt(event.clientX, event.clientY);
438
+ return !!picked && isGizmoNode(picked);
439
+ }
440
+ function beginViewPlaneMove(event) {
441
+ if (!isViewPlaneMoveCandidate(event))
442
+ return false;
443
+ const targetIds = selectedNodeIds.length > 1
444
+ ? getBatchTransformTargetIds()
445
+ : [getActiveTargetId()].filter((nodeId) => !!nodeId);
446
+ const drag = createActiveDrag('move', targetIds, 'view-plane');
447
+ if (!drag)
448
+ return false;
449
+ const startPoint = projectPointerToViewPlane(event.clientX, event.clientY, drag.pivot.position);
450
+ if (!startPoint)
451
+ return false;
452
+ drag.viewPlane = {
453
+ pointerId: event.pointerId,
454
+ startPoint,
455
+ };
456
+ activeDrag = drag;
457
+ options.onDragStart?.(drag);
458
+ return true;
459
+ }
460
+ function updateViewPlaneMove(event) {
461
+ const drag = activeDrag;
462
+ if (!drag?.viewPlane || drag.viewPlane.pointerId !== event.pointerId || disposed)
463
+ return false;
464
+ const currentPoint = projectPointerToViewPlane(event.clientX, event.clientY, drag.pivot.position);
465
+ if (!currentPoint)
466
+ return false;
467
+ const transforms = previewMoveWithDelta(drag, subtractVec3(currentPoint, drag.viewPlane.startPoint));
468
+ const current = drag.activeId
469
+ ? transforms[drag.activeId] ?? Object.values(transforms)[0] ?? null
470
+ : Object.values(transforms)[0] ?? null;
471
+ if (current)
472
+ options.onDragUpdate?.({ ...drag, current });
473
+ return true;
474
+ }
475
+ function endViewPlaneMove(event) {
476
+ const drag = activeDrag;
477
+ if (!drag?.viewPlane || drag.viewPlane.pointerId !== event.pointerId || disposed)
478
+ return false;
479
+ const currentPoint = projectPointerToViewPlane(event.clientX, event.clientY, drag.pivot.position);
480
+ const transforms = currentPoint
481
+ ? previewMoveWithDelta(drag, subtractVec3(currentPoint, drag.viewPlane.startPoint))
482
+ : previewMoveWithDelta(drag, { x: 0, y: 0, z: 0 });
483
+ activeDrag = null;
484
+ emitTransformCommit(drag, transforms);
485
+ attachCurrentSelection();
486
+ return true;
487
+ }
488
+ function projectPointerToViewPlane(clientX, clientY, planePoint) {
489
+ const camera = options.scene.activeCamera ?? options.scene.cameraToUseForPointers ?? null;
490
+ const Vector3 = options.babylon.Vector3;
491
+ const Matrix = options.babylon.Matrix;
492
+ if (!canvas || !camera || !Vector3 || !Matrix?.Identity || !options.scene.createPickingRay)
493
+ return null;
494
+ const rect = canvas.getBoundingClientRect();
495
+ const ray = options.scene.createPickingRay(clientX - rect.left, clientY - rect.top, Matrix.Identity(), camera);
496
+ const origin = readVec3Like(ray?.origin);
497
+ const direction = readVec3Like(ray?.direction);
498
+ const normal = readCameraForward(camera);
499
+ if (!origin || !direction || !normal)
500
+ return null;
501
+ const denominator = dotVec3(direction, normal);
502
+ if (Math.abs(denominator) < 0.000001)
503
+ return null;
504
+ const t = dotVec3(subtractVec3(planePoint, origin), normal) / denominator;
505
+ if (!Number.isFinite(t))
506
+ return null;
507
+ return addVec3(origin, scaleVec3(direction, t));
508
+ }
509
+ function readCameraForward(camera) {
510
+ const forwardRayDirection = readVec3Like(camera?.getForwardRay?.()?.direction);
511
+ if (forwardRayDirection)
512
+ return forwardRayDirection;
513
+ const Vector3 = options.babylon.Vector3;
514
+ if (!Vector3 || typeof camera?.getDirection !== 'function')
515
+ return null;
516
+ const forwardZ = options.scene.useRightHandedSystem ? -1 : 1;
517
+ return readVec3Like(camera.getDirection(new Vector3(0, 0, forwardZ)));
518
+ }
519
+ function pickGizmoMeshAt(clientX, clientY) {
520
+ if (!canvas)
521
+ return null;
522
+ const rect = canvas.getBoundingClientRect();
523
+ const x = clientX - rect.left;
524
+ const y = clientY - rect.top;
525
+ const utilityScene = manager.utilityLayer?.utilityLayerScene;
526
+ const utilityPick = typeof utilityScene?.pick === 'function' ? utilityScene.pick(x, y) : null;
527
+ if (utilityPick?.hit && utilityPick.pickedMesh)
528
+ return utilityPick.pickedMesh;
529
+ const scenePick = typeof options.scene.pick === 'function' ? options.scene.pick(x, y) : null;
530
+ return scenePick?.hit ? scenePick.pickedMesh ?? null : null;
531
+ }
532
+ function isGizmoNode(node) {
533
+ let current = node;
534
+ const roots = collectCurrentGizmoRoots();
535
+ while (current) {
536
+ if (roots.has(current))
537
+ return true;
538
+ if (current.metadata?.editorProjection?.nodeId)
539
+ return false;
540
+ if (current.metadata?.editorProjectionHelper)
541
+ return false;
542
+ const name = String(current.name ?? current.id ?? '').toLowerCase();
543
+ if (name.includes('gizmo'))
544
+ return true;
545
+ current = current.parent ?? null;
546
+ }
547
+ return false;
548
+ }
549
+ function collectCurrentGizmoRoots() {
550
+ const roots = new Set();
551
+ const activeTool = activeTransformTool();
552
+ const gizmo = activeTool === 'move'
553
+ ? manager.gizmos?.positionGizmo
554
+ : activeTool === 'rotate'
555
+ ? manager.gizmos?.rotationGizmo
556
+ : activeTool === 'scale'
557
+ ? manager.gizmos?.scaleGizmo
558
+ : null;
559
+ collectGizmoRoots(gizmo, roots);
560
+ return roots;
561
+ }
562
+ function collectGizmoRoots(value, roots) {
563
+ if (!value || roots.has(value))
564
+ return;
565
+ if (value._rootMesh)
566
+ roots.add(value._rootMesh);
567
+ if (value.rootMesh)
568
+ roots.add(value.rootMesh);
569
+ if (value.attachedMesh)
570
+ roots.add(value.attachedMesh);
571
+ for (const key of ['xGizmo', 'yGizmo', 'zGizmo', 'xPlaneGizmo', 'yPlaneGizmo', 'zPlaneGizmo', 'uniformScaleGizmo']) {
572
+ if (value[key])
573
+ collectGizmoRoots(value[key], roots);
574
+ }
575
+ }
576
+ const controller = {
577
+ getState() {
578
+ return {
579
+ tool,
580
+ space,
581
+ selectedNodeId,
582
+ dragPhase: activeDrag ? 'dragging' : 'idle',
583
+ draggingNodeId: activeDrag?.nodeId ?? null,
584
+ constraint,
585
+ };
586
+ },
587
+ setTool(nextTool) {
588
+ if (disposed)
589
+ return;
590
+ if (tool === nextTool)
591
+ return;
592
+ controller.cancelDrag();
593
+ tool = nextTool;
594
+ attachCurrentSelection();
595
+ },
596
+ setSpace(nextSpace) {
597
+ if (disposed)
598
+ return;
599
+ if (space === nextSpace)
600
+ return;
601
+ controller.cancelDrag();
602
+ space = nextSpace;
603
+ attachCurrentSelection();
604
+ },
605
+ setConstraint(nextConstraint) {
606
+ if (disposed)
607
+ return;
608
+ if (constraint === nextConstraint)
609
+ return;
610
+ controller.cancelDrag();
611
+ constraint = nextConstraint;
612
+ attachCurrentSelection();
613
+ },
614
+ setSelectedNode(nextNodeId) {
615
+ if (disposed)
616
+ return;
617
+ if (selectedNodeId === nextNodeId && selectedNodeIds.length === (nextNodeId ? 1 : 0))
618
+ return;
619
+ controller.cancelDrag();
620
+ selectedNodeId = nextNodeId;
621
+ selectedNodeIds = nextNodeId ? [nextNodeId] : [];
622
+ attachCurrentSelection();
623
+ },
624
+ setSelection(selection) {
625
+ if (disposed)
626
+ return;
627
+ const nextNodeIds = [...selection.selectedIds];
628
+ const nextActiveId = selection.activeId;
629
+ if (selectedNodeId === nextActiveId
630
+ && selectedNodeIds.length === nextNodeIds.length
631
+ && selectedNodeIds.every((id, index) => id === nextNodeIds[index])) {
632
+ return;
633
+ }
634
+ controller.cancelDrag();
635
+ selectedNodeId = nextActiveId;
636
+ selectedNodeIds = nextNodeIds;
637
+ attachCurrentSelection();
638
+ },
639
+ refreshSelection() {
640
+ if (disposed)
641
+ return;
642
+ if (activeDrag)
643
+ return;
644
+ attachCurrentSelection();
645
+ },
646
+ isGizmoDragCandidate,
647
+ isViewPlaneMoveCandidate,
648
+ beginViewPlaneMove,
649
+ updateViewPlaneMove,
650
+ endViewPlaneMove,
651
+ cancelDrag() {
652
+ const drag = activeDrag;
653
+ if (!drag)
654
+ return;
655
+ activeDrag = null;
656
+ if (drag.targetIds.length > 1) {
657
+ options.projection.setNodeTransformsPreview(drag.beforeTransforms);
658
+ attachCurrentSelection();
659
+ }
660
+ else if (drag.nodeId && drag.before) {
661
+ options.projection.setNodeTransformPreview(drag.nodeId, drag.before);
662
+ }
663
+ options.onDragCancel?.(drag);
664
+ },
665
+ dispose() {
666
+ if (disposed)
667
+ return;
668
+ controller.cancelDrag();
669
+ clearDragObservers();
670
+ try {
671
+ manager.attachToNode?.(null);
672
+ }
673
+ catch { }
674
+ try {
675
+ manager.dispose?.();
676
+ }
677
+ catch { }
678
+ try {
679
+ pivotProxy?.dispose?.();
680
+ }
681
+ catch { }
682
+ pivotProxy = null;
683
+ disposed = true;
684
+ },
685
+ };
686
+ attachCurrentSelection();
687
+ return controller;
688
+ }
689
+ //# sourceMappingURL=transform-gizmo-controller.js.map