@woosh/meep-engine 2.46.29 → 2.46.31

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 (169) 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
  166. package/src/engine/intelligence/behavior/composite/CompositeBehavior.js +18 -2
  167. package/src/engine/intelligence/behavior/composite/ParallelBehavior.js +21 -9
  168. package/src/engine/intelligence/behavior/composite/SequenceBehavior.js +5 -1
  169. package/src/engine/intelligence/behavior/util/DelayBehavior.js +8 -3
@@ -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
+ }