@woosh/meep-engine 2.46.29 → 2.46.30

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 (165) hide show
  1. package/editor/Editor.js +793 -0
  2. package/editor/SelectionVisualizer.js +148 -0
  3. package/editor/actions/concrete/ActionUpdateTexture.js +21 -0
  4. package/editor/actions/concrete/ArrayCopyAction.js +39 -0
  5. package/editor/actions/concrete/ComponentAddAction.js +47 -0
  6. package/editor/actions/concrete/ComponentRemoveAction.js +38 -0
  7. package/editor/actions/concrete/EntityCreateAction.js +47 -0
  8. package/editor/actions/concrete/EntityRemoveAction.js +51 -0
  9. package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
  10. package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
  11. package/editor/actions/concrete/ModifyPatchTextureArray2DAction.js +182 -0
  12. package/editor/actions/concrete/PaintTerrainOverlayAction.js +45 -0
  13. package/editor/actions/concrete/PatchTerrainHeightAction.js +67 -0
  14. package/editor/actions/concrete/PatchTerrainTextureAction.js +152 -0
  15. package/editor/actions/concrete/SelectionAddAction.js +36 -0
  16. package/editor/actions/concrete/SelectionClearAction.js +22 -0
  17. package/editor/actions/concrete/SelectionRemoveAction.js +30 -0
  18. package/editor/actions/concrete/TransformModifyAction.js +46 -0
  19. package/editor/actions/concrete/WriteGridValueAction.js +46 -0
  20. package/editor/ecs/EditorEntity.js +12 -0
  21. package/editor/ecs/EditorEntitySystem.js +14 -0
  22. package/editor/ecs/component/FieldDescriptor.js +34 -0
  23. package/editor/ecs/component/FieldValueAdapter.js +20 -0
  24. package/editor/ecs/component/TypeEditor.js +33 -0
  25. package/editor/ecs/component/TypeSchema.d.ts +38 -0
  26. package/editor/ecs/component/createFieldEditor.js +92 -0
  27. package/editor/ecs/component/createObjectEditor.js +361 -0
  28. package/editor/ecs/component/editors/ColorEditor.js +39 -0
  29. package/editor/ecs/component/editors/HTMLElementEditor.js +17 -0
  30. package/editor/ecs/component/editors/ImagePathEditor.js +82 -0
  31. package/editor/ecs/component/editors/LargeStrongEditor.js +107 -0
  32. package/editor/ecs/component/editors/NumericIntervalEditor.js +86 -0
  33. package/editor/ecs/component/editors/ObservedBooleanEditor.js +13 -0
  34. package/editor/ecs/component/editors/ObservedEnumEditor.js +32 -0
  35. package/editor/ecs/component/editors/ObservedIntegerEditor.js +43 -0
  36. package/editor/ecs/component/editors/ObservedStringEditor.js +51 -0
  37. package/editor/ecs/component/editors/Sampler2DEditor.js +221 -0
  38. package/editor/ecs/component/editors/collection/ListEditor.js +83 -0
  39. package/editor/ecs/component/editors/common/BitFlagsEditor.js +80 -0
  40. package/editor/ecs/component/editors/common/EnumEditor.js +41 -0
  41. package/editor/ecs/component/editors/common/makeV3_editor.js +85 -0
  42. package/editor/ecs/component/editors/common/noEditor.js +9 -0
  43. package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +17 -0
  44. package/editor/ecs/component/editors/ecs/MinimapMarkerEditor.js +16 -0
  45. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +225 -0
  46. package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -0
  47. package/editor/ecs/component/editors/ecs/ParameterTrackSetEditor.js +18 -0
  48. package/editor/ecs/component/editors/ecs/ParticleEmitterEditor.js +58 -0
  49. package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +58 -0
  50. package/editor/ecs/component/editors/ecs/SimulationStepDefinitionEditor.js +21 -0
  51. package/editor/ecs/component/editors/ecs/Trail2DEditor.js +33 -0
  52. package/editor/ecs/component/editors/ecs/TransformEditor.js +23 -0
  53. package/editor/ecs/component/editors/ecs/terrain/SplatMappingEditor.js +21 -0
  54. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +95 -0
  55. package/editor/ecs/component/editors/ecs/terrain/TerrainLayerEditor.js +18 -0
  56. package/editor/ecs/component/editors/ecs/terrain/TerrainLayersEditor.js +22 -0
  57. package/editor/ecs/component/editors/ecs/terrain/TerrainOverlayEditor.js +20 -0
  58. package/editor/ecs/component/editors/geom/QuaternionEditor.js +63 -0
  59. package/editor/ecs/component/editors/geom/Vector1Editor.js +57 -0
  60. package/editor/ecs/component/editors/geom/Vector2Editor.js +11 -0
  61. package/editor/ecs/component/editors/geom/Vector3Editor.js +13 -0
  62. package/editor/ecs/component/editors/geom/Vector4Editor.js +12 -0
  63. package/editor/ecs/component/editors/primitive/ArrayEditor.js +46 -0
  64. package/editor/ecs/component/editors/primitive/BooleanEditor.js +27 -0
  65. package/editor/ecs/component/editors/primitive/FunctionEditor.js +29 -0
  66. package/editor/ecs/component/editors/primitive/NumberEditor.js +60 -0
  67. package/editor/ecs/component/editors/primitive/ObjectEditor.js +12 -0
  68. package/editor/ecs/component/editors/primitive/StringEditor.js +31 -0
  69. package/editor/ecs/component/editors/three/BufferGeometryEditor.js +28 -0
  70. package/editor/ecs/component/editors/three/MaterialEditor.js +27 -0
  71. package/editor/ecs/component/editors/three/MeshEditor.js +35 -0
  72. package/editor/ecs/component/editors/three/TextureEditor.js +112 -0
  73. package/editor/ecs/component/findNearestRegisteredType.js +59 -0
  74. package/editor/ecs/component/prototypeObjectEditor.js +379 -0
  75. package/editor/enableEditor.js +85 -0
  76. package/editor/library/MeshLibrary.js +33 -0
  77. package/editor/process/DisableGameUIProcess.js +43 -0
  78. package/editor/process/EditorProcess.js +35 -0
  79. package/editor/process/ObstacleGridDisplayProcess.js +120 -0
  80. package/editor/process/ProcessEngine.js +123 -0
  81. package/editor/process/SymbolicDisplayProcess.js +132 -0
  82. package/editor/process/symbolic/ComponentSymbolicDisplay.js +34 -0
  83. package/editor/process/symbolic/SymbolicDisplayInternalAPI.js +159 -0
  84. package/editor/process/symbolic/buildThreeJSHelperEntity.js +36 -0
  85. package/editor/process/symbolic/make3DSymbolicDisplay.js +91 -0
  86. package/editor/process/symbolic/makeCameraSymbolicDisplay.js +32 -0
  87. package/editor/process/symbolic/makeGridPositionSymbolDisplay.js +176 -0
  88. package/editor/process/symbolic/makeHelperBoxGeometry.js +44 -0
  89. package/editor/process/symbolic/makeHelperSphereGeometry.js +73 -0
  90. package/editor/process/symbolic/makeLightSymbolicDisplay.js +77 -0
  91. package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +146 -0
  92. package/editor/process/symbolic/makePathSymbolicDisplay.js +105 -0
  93. package/editor/process/symbolic/makePositionedIconDisplaySymbol.js +74 -0
  94. package/editor/process/symbolic/makeSocketsSymbolicDisplay.js +153 -0
  95. package/editor/process/symbolic/makeSolidArrowGeometry.js +391 -0
  96. package/editor/process/symbolic/makeSoundEmitterSymbolicDisplay.js +89 -0
  97. package/editor/process/symbolic/makeStoryTriggerSetAreaDisplay.js +114 -0
  98. package/editor/process/symbolic/synchronizeTransform.js +50 -0
  99. package/editor/tools/FoliagePaintTool.js +168 -0
  100. package/editor/tools/GridPaintTool.js +247 -0
  101. package/editor/tools/SelectionTool.js +407 -0
  102. package/editor/tools/TopDownCameraControlTool.js +59 -0
  103. package/editor/tools/TransformTool.js +370 -0
  104. package/editor/tools/engine/Tool.js +121 -0
  105. package/editor/tools/engine/ToolEngine.js +193 -0
  106. package/editor/tools/engine/ToolState.js +9 -0
  107. package/editor/tools/engine/ToolStateMachine.js +53 -0
  108. package/editor/tools/paint/TerrainHeightPaintTool.js +297 -0
  109. package/editor/tools/paint/TerrainPaintTool.js +211 -0
  110. package/editor/tools/paint/TerrainTexturePaintTool.js +193 -0
  111. package/editor/tools/paint/prototypeTerrainEditor.js +135 -0
  112. package/editor/tools/v2/BlenderCameraOrientationGizmo.d.ts +50 -0
  113. package/editor/tools/v2/BlenderCameraOrientationGizmo.js +500 -0
  114. package/editor/tools/v2/TransformControls.d.ts +20 -0
  115. package/editor/tools/v2/TransformControls.js +1782 -0
  116. package/editor/tools/v2/prototypeTransformControls.js +92 -0
  117. package/editor/view/EditorView.js +462 -0
  118. package/editor/view/GridPickCoordinateView.js +88 -0
  119. package/editor/view/ecs/ComponentControlFactory.js +48 -0
  120. package/editor/view/ecs/ComponentControlView.js +214 -0
  121. package/editor/view/ecs/EntityEditor.js +258 -0
  122. package/editor/view/ecs/EntityList.js +258 -0
  123. package/editor/view/ecs/components/BlackboardController.js +50 -0
  124. package/editor/view/ecs/components/DatGuiController.js +216 -0
  125. package/editor/view/ecs/components/FogOfWarController.js +78 -0
  126. package/editor/view/ecs/components/FogOfWarRevealerController.js +44 -0
  127. package/editor/view/ecs/components/GeneratedArmyController.js +42 -0
  128. package/editor/view/ecs/components/GridObstacleController.js +72 -0
  129. package/editor/view/ecs/components/GridPositionController.js +40 -0
  130. package/editor/view/ecs/components/HeadsUpDisplayController.js +30 -0
  131. package/editor/view/ecs/components/HighlightController.js +47 -0
  132. package/editor/view/ecs/components/MeshController.js +125 -0
  133. package/editor/view/ecs/components/PathFollowerController.js +87 -0
  134. package/editor/view/ecs/components/TagController.js +80 -0
  135. package/editor/view/ecs/components/TerrainController.js +225 -0
  136. package/editor/view/ecs/components/TransformController.js +103 -0
  137. package/editor/view/ecs/components/UnitShopController.js +112 -0
  138. package/editor/view/ecs/components/army/ArmyController.js +130 -0
  139. package/editor/view/ecs/components/color/GaugeView.js +107 -0
  140. package/editor/view/ecs/components/common/AutoCanvasView.js +53 -0
  141. package/editor/view/ecs/components/common/LineView.js +17 -0
  142. package/editor/view/ecs/components/common/NumberController.js +112 -0
  143. package/editor/view/ecs/components/common/NumericIntervalController.js +64 -0
  144. package/editor/view/ecs/components/gui/GUIElementController.js +117 -0
  145. package/editor/view/ecs/components/items/ItemContainerController.js +132 -0
  146. package/editor/view/ecs/components/items/ItemContainerController.stories.js +50 -0
  147. package/editor/view/ecs/components/items/ItemController.js +52 -0
  148. package/editor/view/ecs/components/particles/ColorParameterLUTController.js +444 -0
  149. package/editor/view/ecs/components/particles/ParameterTrackController.js +51 -0
  150. package/editor/view/ecs/components/particles/ParticleEmitterController.js +213 -0
  151. package/editor/view/ecs/components/particles/ParticleLayerController.js +213 -0
  152. package/editor/view/ecs/components/particles/ScalarParameterLUTController.js +401 -0
  153. package/editor/view/ecs/components/sockets/AttachmentSocketsController.js +51 -0
  154. package/editor/view/ecs/components/sound/SoundEmitterController.js +137 -0
  155. package/editor/view/ecs/components/story/StoryTriggerSetController.js +214 -0
  156. package/editor/view/ecs/components/unit/AuraController.js +45 -0
  157. package/editor/view/library/MeshLibraryView.js +164 -0
  158. package/editor/view/node-graph/NodeGraphEditorView.js +170 -0
  159. package/editor/view/node-graph/NodeGraphView.js +453 -0
  160. package/editor/view/node-graph/NodeView.js +135 -0
  161. package/editor/view/node-graph/PortView.js +69 -0
  162. package/editor/view/process/ProcessView.js +63 -0
  163. package/editor/view/tools/ToolSettingsView.js +143 -0
  164. package/editor/view/tools/ToolView.js +58 -0
  165. package/package.json +2 -1
@@ -0,0 +1,53 @@
1
+ import { SimpleStateMachineDescription } from "../../../src/core/fsm/simple/SimpleStateMachineDescription.js";
2
+ import { ToolState } from "./ToolState.js";
3
+ import { StateMachine } from "../../../src/core/fsm/StateMachine.js";
4
+
5
+ const smd = new SimpleStateMachineDescription();
6
+
7
+ smd.createState(ToolState.Initial);
8
+ smd.createState(ToolState.Ready);
9
+ smd.createState(ToolState.Running);
10
+
11
+ smd.createEdge(ToolState.Initial, ToolState.Ready);
12
+ smd.createEdge(ToolState.Ready, ToolState.Initial);
13
+ smd.createEdge(ToolState.Ready, ToolState.Running);
14
+ smd.createEdge(ToolState.Running, ToolState.Ready);
15
+
16
+
17
+ /**
18
+ * @param {Tool} tool
19
+ * @returns {StateMachine}
20
+ */
21
+ export function buildToolStateMachine(tool) {
22
+ const sm = new StateMachine(smd);
23
+
24
+ sm.addState(ToolState.Initial);
25
+ sm.addState(ToolState.Ready);
26
+ sm.addState(ToolState.Running);
27
+
28
+
29
+ sm.createTransition(ToolState.Initial, ToolState.Ready, () => {
30
+ tool.initialize();
31
+ return Promise.resolve();
32
+ });
33
+
34
+ sm.createTransition(ToolState.Ready, ToolState.Initial, () => {
35
+ tool.shutdown();
36
+ return Promise.resolve();
37
+ });
38
+
39
+ sm.createTransition(ToolState.Ready, ToolState.Running, () => {
40
+ tool.start();
41
+ return Promise.resolve();
42
+ });
43
+
44
+ sm.createTransition(ToolState.Running, ToolState.Ready, () => {
45
+ tool.stop();
46
+ return Promise.resolve();
47
+ });
48
+
49
+ sm.setState(ToolState.Initial);
50
+
51
+
52
+ return sm;
53
+ }
@@ -0,0 +1,297 @@
1
+ import { clamp } from "../../../src/core/math/clamp.js";
2
+ import { inverseLerp } from "../../../src/core/math/inverseLerp.js";
3
+ import { lerp } from "../../../src/core/math/lerp.js";
4
+ import { TerrainPaintTool } from "./TerrainPaintTool.js";
5
+ import { PatchTerrainHeightAction } from "../../actions/concrete/PatchTerrainHeightAction.js";
6
+ import { QuadTreeNode } from "../../../src/core/geom/2d/quad-tree/QuadTreeNode.js";
7
+ import { Transform } from "../../../src/engine/ecs/transform/Transform.js";
8
+ import TransformModifyAction from "../../actions/concrete/TransformModifyAction.js";
9
+ import EditorEntity from "../../ecs/EditorEntity.js";
10
+ import { uint82float } from "../../../src/core/binary/uint82float.js";
11
+
12
+ const LIMIT_VALUE = 1000;
13
+
14
+ /**
15
+ *
16
+ * @param {Terrain} terrain
17
+ * @param {number} uv_x0
18
+ * @param {number} uv_y0
19
+ * @param {number} uv_x1
20
+ * @param {number} uv_y1
21
+ * @param {Sampler2D} marker
22
+ * @param {number} value_delta
23
+ * @param {number} limitMin
24
+ * @param {number} limitMax
25
+ * @returns {PatchTerrainHeightAction}
26
+ */
27
+ function make_mod_action(terrain, uv_x0, uv_y0, uv_x1, uv_y1, marker, value_delta, limitMin, limitMax) {
28
+
29
+ const heightMap = terrain.samplerHeight;
30
+
31
+ const h_x0 = uv_x0 * heightMap.width;
32
+ const h_x1 = uv_x1 * heightMap.width;
33
+
34
+ const h_y0 = uv_y0 * heightMap.height;
35
+ const h_y1 = uv_y1 * heightMap.height;
36
+
37
+ const x0 = Math.ceil(h_x0);
38
+ const x1 = Math.floor(h_x1);
39
+
40
+ const y0 = Math.ceil(h_y0);
41
+ const y1 = Math.floor(h_y1);
42
+
43
+ const action = new PatchTerrainHeightAction(terrain, x0, y0, (x1 - x0), (y1 - y0));
44
+
45
+ const patch_destination_data = action.patch.data;
46
+
47
+ for (let y = y0; y < y1; y++) {
48
+
49
+ const v = inverseLerp(h_y0, h_y1 - 1, y);
50
+
51
+
52
+ for (let x = x0; x < x1; x++) {
53
+
54
+ const u = inverseLerp(h_x0, h_x1 - 1, x);
55
+
56
+ //Get alpha
57
+ const markerValue = marker.sampleChannelBilinearUV(u, v, 3);
58
+
59
+ const marker_value_normalized = uint82float(markerValue);
60
+
61
+ const source_address = y * heightMap.width + x;
62
+
63
+ const base = heightMap.data[source_address];
64
+
65
+ const patchAddress = (y - y0) * action.patch.width + (x - x0);
66
+
67
+ const targetValue = clamp(base + value_delta, limitMin, limitMax);
68
+
69
+
70
+ const value = lerp(base, targetValue, marker_value_normalized);
71
+
72
+ if (Number.isNaN(value)) {
73
+ // console.warn('.');
74
+
75
+ patch_destination_data[patchAddress] = base;
76
+
77
+ } else {
78
+
79
+ patch_destination_data[patchAddress] = value;
80
+
81
+ }
82
+ }
83
+
84
+ }
85
+ return action;
86
+ }
87
+
88
+ export class TerrainHeightPaintTool extends TerrainPaintTool {
89
+
90
+ constructor() {
91
+ super();
92
+
93
+ this.settings.limitMin = -LIMIT_VALUE;
94
+ this.settings.limitMax = LIMIT_VALUE;
95
+
96
+ /**
97
+ *
98
+ * @type {QuadTreeNode<number>}
99
+ */
100
+ this.transform_index = new QuadTreeNode();
101
+ }
102
+
103
+ buildTransformIndex() {
104
+ /**
105
+ *
106
+ * @type {Engine}
107
+ */
108
+ const engine = this.engine;
109
+
110
+ /**
111
+ *
112
+ * @type {EntityManager}
113
+ */
114
+ const entityManager = engine.entityManager;
115
+
116
+ /**
117
+ *
118
+ * @type {EntityComponentDataset}
119
+ */
120
+ const dataset = entityManager.dataset;
121
+
122
+ //purge existing data
123
+ this.transform_index.clear();
124
+
125
+ /**
126
+ *
127
+ * @type {number}
128
+ */
129
+ const gridScale = this.terrain.gridScale;
130
+
131
+ const uS = 1 / (this.terrain.size.x * gridScale);
132
+ const vS = 1 / (this.terrain.size.y * gridScale);
133
+
134
+ dataset.traverseComponents(Transform, (transform, entity) => {
135
+ if (dataset.getComponent(entity, EditorEntity) !== undefined) {
136
+ //it's an editor entity
137
+ return;
138
+ }
139
+
140
+ const position = transform.position;
141
+
142
+ const x = position.x;
143
+ const z = position.z;
144
+
145
+ const u = x * uS;
146
+ const v = z * vS;
147
+
148
+ const datum = this.transform_index.add(transform, u, v, u, v);
149
+
150
+ datum.entity = entity;
151
+ });
152
+ }
153
+
154
+ initialize() {
155
+ super.initialize();
156
+
157
+ this.buildTransformIndex();
158
+
159
+ }
160
+
161
+ shutdown() {
162
+ super.shutdown();
163
+ }
164
+
165
+ /**
166
+ *
167
+ * @param {number} timeDelta
168
+ */
169
+ async paint(timeDelta) {
170
+ const power = this.settings.brushStrength * timeDelta;
171
+
172
+ /**
173
+ *
174
+ * @type {Terrain}
175
+ */
176
+ const terrain = this.terrain;
177
+
178
+ const brushPosition = this.__brushPosition;
179
+ const brushSize = this.settings.brushSize;
180
+
181
+ const terrainSize = terrain.size;
182
+
183
+ const uv_x = brushPosition.x / terrainSize.x;
184
+ const uv_y = brushPosition.y / terrainSize.y;
185
+
186
+ const uv_w = brushSize / terrainSize.x;
187
+ const uv_h = brushSize / terrainSize.y;
188
+
189
+ const uv_x0 = uv_x - uv_w / 2;
190
+ const uv_x1 = uv_x + uv_w / 2;
191
+
192
+ const uv_y0 = uv_y - uv_h / 2;
193
+ const uv_y1 = uv_y + uv_h / 2;
194
+
195
+
196
+ const marker = this.settings.marker;
197
+
198
+ const direction = this.modifiers.shift ? -1 : 1;
199
+
200
+ const value_delta = power * direction;
201
+
202
+ const limitMin = this.settings.limitMin;
203
+ const limitMax = this.settings.limitMax;
204
+
205
+ const action = make_mod_action(terrain, uv_x0, uv_y0, uv_x1, uv_y1, marker, value_delta, limitMin, limitMax);
206
+
207
+ this.editor.actions.do(action);
208
+
209
+ const objectMoveActions = this.createObjectMoveActions(action);
210
+
211
+ this.editor.actions.doMany(objectMoveActions);
212
+ }
213
+
214
+ /**
215
+ *
216
+ * @param {PatchTerrainHeightAction} action
217
+ * @returns {Action[]}
218
+ */
219
+ createObjectMoveActions(action) {
220
+
221
+ const heightSampler = this.terrain.samplerHeight;
222
+
223
+ const x0 = action.x;
224
+ const y0 = action.y;
225
+
226
+ const patch = action.patch;
227
+
228
+ const patch_width = patch.width;
229
+ const patch_height = patch.height;
230
+
231
+ const x1 = x0 + patch_width;
232
+ const y1 = y0 + patch_height;
233
+
234
+
235
+ const u0 = x0 / heightSampler.width;
236
+ const v0 = y0 / heightSampler.height;
237
+
238
+ const u1 = x1 / heightSampler.width;
239
+ const v1 = y1 / heightSampler.height;
240
+
241
+ /**
242
+ *
243
+ * @type {QuadTreeDatum<Transform>[]}
244
+ */
245
+ const leaves = [];
246
+
247
+ /**
248
+ *
249
+ * @type {Action[]}
250
+ */
251
+ const result = [];
252
+
253
+ const overlaps = this.transform_index.requestDatumIntersectionsRectangle(leaves, u0, v0, u1, v1);
254
+
255
+ for (let i = 0; i < overlaps; i++) {
256
+ const leaf = leaves[i];
257
+
258
+ /**
259
+ *
260
+ * @type {Transform}
261
+ */
262
+ const transform = leaf.data;
263
+
264
+ const tX = leaf.x0 * heightSampler.width;
265
+ const tY = leaf.y0 * heightSampler.height;
266
+
267
+ const action_value = action.patch.sampleChannelBicubic(tX - action.x, tY - action.y, 0);
268
+ const existing_value = heightSampler.sampleChannelBicubic(tY, tY, 0);
269
+
270
+ const delta = action_value - existing_value;
271
+
272
+ if (delta === 0) {
273
+ continue;
274
+ }
275
+
276
+ if (Number.isNaN(delta)) {
277
+ console.error('Delta is NaN, skipping.', action, tX, tY);
278
+ continue;
279
+ }
280
+
281
+ const tM = new Transform();
282
+ tM.copy(transform);
283
+ tM.position._add(0, delta, 0);
284
+ const a = new TransformModifyAction(leaf.entity, tM);
285
+ result.push(a);
286
+ }
287
+
288
+ return result;
289
+ }
290
+
291
+ start() {
292
+ super.start();
293
+
294
+ this.editor.actions.mark('terrain height paint');
295
+ }
296
+
297
+ }
@@ -0,0 +1,211 @@
1
+ import { max2 } from "../../../src/core/math/max2.js";
2
+ import Tool from "../engine/Tool.js";
3
+ import { Color } from "../../../src/core/color/Color.js";
4
+ import { Sampler2D } from "../../../src/engine/graphics/texture/sampler/Sampler2D.js";
5
+ import Vector2 from "../../../src/core/geom/Vector2.js";
6
+ import convertSampler2D2Canvas from "../../../src/engine/graphics/texture/sampler/Sampler2D2Canvas.js";
7
+ import ObservedString from "../../../src/core/model/ObservedString.js";
8
+ import { GameAssetType } from "../../../src/engine/asset/GameAssetType.js";
9
+ import Vector1 from "../../../src/core/geom/Vector1.js";
10
+ import { obtainTerrain } from "../../../src/engine/ecs/terrain/util/obtainTerrain.js";
11
+ import { pick } from "../../../src/ecs/grid/pick.js";
12
+
13
+ export class TerrainPaintTool extends Tool {
14
+ constructor() {
15
+ super();
16
+
17
+ this.name = 'paint-terrain';
18
+
19
+ const marker = Sampler2D.uint8(4, 1, 1);
20
+
21
+ marker.data.fill(255);
22
+
23
+ this.settings.markerColor = new Color(0, 1, 0.8);
24
+ this.settings.markerOpacity = new Vector1(1);
25
+
26
+ this.settings.marker = marker;
27
+ this.settings.brushSize = 5;
28
+ this.settings.brushStrength = 1;
29
+ this.settings.brushURL = new ObservedString("data/textures/particle/UETools/x64/Circle_04.png");
30
+
31
+ this.__brushPosition = new Vector2();
32
+
33
+ this.__brushImage = document.createElement('canvas');
34
+
35
+ this.__paint_debt = 0;
36
+ this.__paint_pending = false;
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @param {number} timeDelta
42
+ */
43
+ async paint(timeDelta) {
44
+
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @param {number} timeDelta
50
+ */
51
+ update(timeDelta) {
52
+ this.updateBrushPosition();
53
+ this.updateOverlay();
54
+
55
+ if (this.isRunning()) {
56
+
57
+ this.__paint_debt += timeDelta;
58
+
59
+ if (this.__paint_pending) {
60
+ return;
61
+ }
62
+
63
+ this.__paint_pending = true;
64
+
65
+ const paint_promise = this.paint(timeDelta);
66
+ this.__paint_debt = 0;
67
+
68
+ paint_promise.finally(() => {
69
+ this.__paint_pending = false;
70
+ });
71
+ }
72
+
73
+ }
74
+
75
+ updateBrushImage() {
76
+ /**
77
+ *
78
+ * @type {Sampler2D}
79
+ */
80
+ const marker = this.settings.marker;
81
+
82
+ const temp = new Sampler2D(new Uint8ClampedArray(marker.data), marker.itemSize, marker.width, marker.height);
83
+
84
+ const markerColor = this.settings.markerColor;
85
+ const markerAlpha = this.settings.markerOpacity.getValue();
86
+
87
+ const brushData = temp.data;
88
+
89
+ //apply tint
90
+ for (let y = 0; y < temp.height; y++) {
91
+ const lineAddress = y * temp.itemSize * temp.width;
92
+
93
+ for (let x = 0; x < temp.width; x++) {
94
+
95
+ const address = lineAddress + x * temp.itemSize;
96
+
97
+ brushData[address] = brushData[address] * markerColor.r;
98
+ brushData[address + 1] = brushData[address + 1] * markerColor.g;
99
+ brushData[address + 2] = brushData[address + 2] * markerColor.b;
100
+ brushData[address + 3] = brushData[address + 3] * markerAlpha;
101
+ }
102
+ }
103
+
104
+ const brushImage = this.__brushImage;
105
+
106
+ convertSampler2D2Canvas(temp, 1, 0, brushImage);
107
+
108
+ }
109
+
110
+ updateBrushPosition() {
111
+
112
+ const p = new Vector2(0, 0);
113
+ const engine = this.engine;
114
+
115
+ engine.gameView.positionGlobalToLocal(engine.devices.pointer.position, p);
116
+
117
+ pick(p.x, p.y, engine.graphics, this.terrain, (gridPosition) => {
118
+
119
+ this.__brushPosition.set(gridPosition.x, gridPosition.y);
120
+
121
+ });
122
+ }
123
+
124
+ updateOverlay() {
125
+
126
+ const terrain = this.terrain;
127
+
128
+ const overlay = terrain.overlay;
129
+
130
+ overlay.clear();
131
+
132
+ const dx = overlay.size.x / terrain.size.x;
133
+ const dy = overlay.size.y / terrain.size.y;
134
+
135
+ const overlayPositionX = this.__brushPosition.x * dx;
136
+ const overlayPositionY = this.__brushPosition.y * dy;
137
+
138
+ const brushSize = this.settings.brushSize;
139
+
140
+ const brushRadius = brushSize / 2;
141
+
142
+ const brushSizeX = brushRadius * dx;
143
+ const brushSizeY = brushRadius * dy;
144
+
145
+
146
+ overlay.paintImage(this.__brushImage, overlayPositionX - brushSizeX, overlayPositionY - brushSizeY, brushSize * dx, brushSize * dy);
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param {Vector3} delta
152
+ * @private
153
+ */
154
+ __handleMouseWheel(delta) {
155
+
156
+ const settings = this.settings;
157
+
158
+ const brushSize = settings.brushSize;
159
+
160
+ settings.brushSize = max2(1, brushSize + delta.y);
161
+
162
+ // this.updateBrushImage();
163
+ this.updateOverlay();
164
+
165
+ }
166
+
167
+ initialize() {
168
+ super.initialize();
169
+
170
+ const engine = this.engine;
171
+ const editor = this.editor;
172
+
173
+ this.__paint_debt = 0;
174
+
175
+ this.terrain = obtainTerrain(engine.entityManager.dataset, (t, entity) => {
176
+ this.terrainEntity = entity;
177
+ });
178
+
179
+ const overlay = this.terrain.overlay;
180
+
181
+ overlay.push();
182
+
183
+ overlay.size.set(this.terrain.size.x * 16, this.terrain.size.y * 16);
184
+ overlay.borderWidth.set(0);
185
+ overlay.tileImage.set("data/textures/utility/white_pixel.png");
186
+
187
+ engine.assetManager.promise('data/textures/particle/UETools/x64/Circle_04.png', GameAssetType.Image)
188
+ .then(asset => {
189
+ const image = asset.create();
190
+
191
+ this.settings.marker = new Sampler2D(image.data, 4, image.width, image.height);
192
+
193
+ this.updateBrushImage();
194
+ });
195
+
196
+ this.updateBrushImage();
197
+
198
+ engine.devices.pointer.on.wheel.add(this.__handleMouseWheel, this);
199
+ }
200
+
201
+ shutdown() {
202
+ super.shutdown();
203
+
204
+
205
+ this.terrain.overlay.pop();
206
+
207
+
208
+ engine.devices.pointer.on.wheel.remove(this.__handleMouseWheel, this);
209
+ }
210
+
211
+ }