@woosh/meep-engine 2.76.4 → 2.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/meep.cjs +197 -616
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +197 -616
- package/editor/view/ecs/components/TerrainController.js +9 -16
- package/package.json +1 -1
- package/src/core/collection/heap/Uint32Heap.js +10 -1
- package/src/core/graph/Edge.js +20 -0
- package/src/core/graph/Graph.js +1 -0
- package/src/core/graph/SquareMatrix.js +4 -2
- package/src/core/graph/WeightedEdge.js +5 -9
- package/src/core/graph/coloring/validateGraphColoring.js +1 -1
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.js +21 -0
- package/src/core/graph/eigen/{eigen.spec.js → matrix_eigenvalues_in_place.spec.js} +2 -2
- package/src/core/graph/eigen/matrix_householder_in_place.js +92 -0
- package/src/core/graph/eigen/{eigen.js → matrix_qr_in_place.js} +2 -113
- package/src/core/graph/v2/Graph.js +16 -9
- package/src/core/graph/v2/NodeContainer.js +120 -22
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +8 -6
- package/src/engine/graphics/particles/node-based/codegen/modules/FunctionModuleRegistry.js +1 -1
- package/src/engine/navigation/grid/find_path_on_grid_astar.js +25 -22
- package/src/engine/navigation/grid/find_path_on_grid_astar.spec.js +2 -2
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +17 -33
- package/src/core/graph/GraphUtils.js +0 -284
- package/src/engine/ecs/terrain/ecs/splat/SplatMapMaterialPatch.js +0 -464
- package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizer.js +0 -622
- package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizerDebugger.js +0 -383
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
import { Sampler2D } from "../../../../graphics/texture/sampler/Sampler2D.js";
|
|
2
|
-
import convertSampler2D2Canvas from "../../../../graphics/texture/sampler/Sampler2D2Canvas.js";
|
|
3
|
-
import { CanvasView } from "../../../../../view/elements/CanvasView.js";
|
|
4
|
-
import EmptyView from "../../../../../view/elements/EmptyView.js";
|
|
5
|
-
import { sampler2d_scale } from "../../../../graphics/texture/sampler/resize/sampler2d_scale.js";
|
|
6
|
-
import { passThrough } from "../../../../../core/function/Functions.js";
|
|
7
|
-
import AABB2 from "../../../../../core/geom/2d/aabb/AABB2.js";
|
|
8
|
-
import View from "../../../../../view/View.js";
|
|
9
|
-
import SVG from "../../../../../view/SVG.js";
|
|
10
|
-
import Vector2 from "../../../../../core/geom/Vector2.js";
|
|
11
|
-
import Vector4 from "../../../../../core/geom/Vector4.js";
|
|
12
|
-
import { MersenneTwister } from "../../../../../core/math/random/MersenneTwister.js";
|
|
13
|
-
import { arrayPickBestElement } from "../../../../../core/collection/array/arrayPickBestElement.js";
|
|
14
|
-
import { hsv2rgb } from "../../../../../core/color/hsv/hsv2rgb.js";
|
|
15
|
-
|
|
16
|
-
function removeAllChildren(node) {
|
|
17
|
-
const children = node.children;
|
|
18
|
-
|
|
19
|
-
for (let i = children.length - 1; i >= 0; i--) {
|
|
20
|
-
const element = children.item(i);
|
|
21
|
-
//trash
|
|
22
|
-
try {
|
|
23
|
-
node.removeChild(element);
|
|
24
|
-
} catch (e) {
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @template T
|
|
31
|
-
* @param {SVGElement} svg
|
|
32
|
-
* @param {Edge<T>} edges
|
|
33
|
-
* @param {Graph<T>} graph
|
|
34
|
-
* @param {AABB2[]} boxes
|
|
35
|
-
*/
|
|
36
|
-
function drawConnections(svg, edges, graph, boxes) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
* @param {SplatMapMaterialPatch} node
|
|
42
|
-
* @returns {AABB2}
|
|
43
|
-
*/
|
|
44
|
-
function node2focus(node) {
|
|
45
|
-
const index = graph.nodes.indexOf(node);
|
|
46
|
-
|
|
47
|
-
const box = boxes[index];
|
|
48
|
-
|
|
49
|
-
const focus = box.focus;
|
|
50
|
-
|
|
51
|
-
const x0 = box.x0 + focus.x0;
|
|
52
|
-
const y0 = box.y0 + focus.y0;
|
|
53
|
-
|
|
54
|
-
const bb = new AABB2(x0, y0, x0 + focus.getWidth(), y0 + focus.getHeight());
|
|
55
|
-
|
|
56
|
-
bb.grow(1);
|
|
57
|
-
|
|
58
|
-
return bb;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const p0 = new Vector2();
|
|
63
|
-
const p1 = new Vector2();
|
|
64
|
-
|
|
65
|
-
edges.forEach(edge => {
|
|
66
|
-
const bb0 = node2focus(edge.first);
|
|
67
|
-
const bb1 = node2focus(edge.second);
|
|
68
|
-
|
|
69
|
-
AABB2.computeLineBetweenTwoBoxes(bb0, bb1, p0, p1);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const el = SVG.createElement('path');
|
|
73
|
-
|
|
74
|
-
let pathString = "M";
|
|
75
|
-
|
|
76
|
-
pathString += [p0, p1].map(function (point) {
|
|
77
|
-
return point.x + "," + point.y
|
|
78
|
-
}).join("L");
|
|
79
|
-
pathString += "Z";
|
|
80
|
-
|
|
81
|
-
el.setAttribute("d", pathString);
|
|
82
|
-
el.setAttribute("stroke", 'rgba(255,0,0,0.8)');
|
|
83
|
-
el.setAttribute("stroke-width", "1");
|
|
84
|
-
|
|
85
|
-
svg.appendChild(el);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
*
|
|
91
|
-
* @param {SplatMapMaterialPatch} node
|
|
92
|
-
*/
|
|
93
|
-
function paintPatchOnTerrain(node) {
|
|
94
|
-
if (engine !== undefined) {
|
|
95
|
-
const ecd = engine.entityManager.dataset;
|
|
96
|
-
|
|
97
|
-
const Terrain = ecd.getComponentClassByName('Terrain');
|
|
98
|
-
|
|
99
|
-
const terrain = ecd.getAnyComponent(Terrain).component;
|
|
100
|
-
|
|
101
|
-
if (terrain !== undefined) {
|
|
102
|
-
const overlay = terrain.overlay;
|
|
103
|
-
|
|
104
|
-
overlay.push();
|
|
105
|
-
|
|
106
|
-
overlay.size.set(node.width, node.height);
|
|
107
|
-
|
|
108
|
-
overlay.borderWidth.set(0.1);
|
|
109
|
-
|
|
110
|
-
overlay.tileImage.set("data/textures/utility/white_pixel.png");
|
|
111
|
-
|
|
112
|
-
const color = new Vector4();
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const color0 = new Vector4();
|
|
116
|
-
const color1 = new Vector4();
|
|
117
|
-
|
|
118
|
-
color0.set(0, 0, 1, 0.8);
|
|
119
|
-
color1.set(1, 0, 0, 0.3);
|
|
120
|
-
|
|
121
|
-
const x0 = node.aabb.x0;
|
|
122
|
-
const y0 = node.aabb.y0;
|
|
123
|
-
|
|
124
|
-
const x1 = node.aabb.x1;
|
|
125
|
-
const y1 = node.aabb.y1;
|
|
126
|
-
|
|
127
|
-
const _w = x1 - x0;
|
|
128
|
-
|
|
129
|
-
for (let y = y0; y < y1; y++) {
|
|
130
|
-
for (let x = x0; x < x1; x++) {
|
|
131
|
-
const t = node.test(x, y);
|
|
132
|
-
|
|
133
|
-
if (t) {
|
|
134
|
-
const _x = x - x0;
|
|
135
|
-
const _y = y - y0;
|
|
136
|
-
|
|
137
|
-
const w = node.weights[_y * _w + _x];
|
|
138
|
-
|
|
139
|
-
const nW = w / 255;
|
|
140
|
-
|
|
141
|
-
color.lerpVectors(color0, color1, nW);
|
|
142
|
-
|
|
143
|
-
overlay.paintPoint(x, y, color);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
export class SplatMapOptimizerDebugger {
|
|
153
|
-
constructor() {
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
*
|
|
160
|
-
* @param {SplatMapMaterialPatch} patch
|
|
161
|
-
*/
|
|
162
|
-
buildPatch(patch) {
|
|
163
|
-
|
|
164
|
-
const mersenneTwister = new MersenneTwister(patch.materialIndex);
|
|
165
|
-
|
|
166
|
-
const hue = ((patch.materialIndex) / 5.3111) % 1;
|
|
167
|
-
|
|
168
|
-
const rgb = hsv2rgb(hue, 0.9, 1);
|
|
169
|
-
|
|
170
|
-
const w = patch.width;
|
|
171
|
-
const h = patch.height;
|
|
172
|
-
|
|
173
|
-
const sampler = Sampler2D.uint8(4, w, h);
|
|
174
|
-
|
|
175
|
-
//draw weight
|
|
176
|
-
const aabb = patch.aabb;
|
|
177
|
-
const y0 = aabb.y0;
|
|
178
|
-
const y1 = aabb.y1;
|
|
179
|
-
const x0 = aabb.x0;
|
|
180
|
-
const x1 = aabb.x1;
|
|
181
|
-
|
|
182
|
-
const _w = x1 - x0;
|
|
183
|
-
|
|
184
|
-
for (let y = y0; y < y1; y++) {
|
|
185
|
-
const _y = y - y0;
|
|
186
|
-
|
|
187
|
-
for (let x = x0; x < x1; x++) {
|
|
188
|
-
const _x = x - x0;
|
|
189
|
-
|
|
190
|
-
const weight = patch.weights[_y * _w + _x];
|
|
191
|
-
|
|
192
|
-
const index = y * w + x;
|
|
193
|
-
|
|
194
|
-
const index4 = index * 4;
|
|
195
|
-
|
|
196
|
-
const nW = weight / 255;
|
|
197
|
-
sampler.data[index4] = rgb.r * nW;
|
|
198
|
-
sampler.data[index4 + 1] = rgb.g * nW;
|
|
199
|
-
sampler.data[index4 + 2] = rgb.b * nW;
|
|
200
|
-
sampler.data[index4 + 3] = 255;
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const size = 123;
|
|
207
|
-
|
|
208
|
-
let rW = size;
|
|
209
|
-
let rH = size;
|
|
210
|
-
|
|
211
|
-
if (sampler.width > sampler.height) {
|
|
212
|
-
rW = size;
|
|
213
|
-
rH = (sampler.height / sampler.width) * size;
|
|
214
|
-
} else {
|
|
215
|
-
rW = (sampler.width / sampler.height) * size;
|
|
216
|
-
rH = size;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const s2 = Sampler2D.uint8(4, rW, rH);
|
|
220
|
-
|
|
221
|
-
sampler2d_scale(sampler, s2);
|
|
222
|
-
|
|
223
|
-
const canvasView = new CanvasView();
|
|
224
|
-
canvasView.size.set(rW, rH);
|
|
225
|
-
|
|
226
|
-
convertSampler2D2Canvas(s2, 1, 0, canvasView.el);
|
|
227
|
-
|
|
228
|
-
const ctx = canvasView.context2d;
|
|
229
|
-
|
|
230
|
-
ctx.strokeStyle = 'rgba(255,255,255,0.8)';
|
|
231
|
-
|
|
232
|
-
const scale_x = rW / sampler.width;
|
|
233
|
-
const scale_y = rH / sampler.height;
|
|
234
|
-
|
|
235
|
-
const strokeWidth = 1;
|
|
236
|
-
const halfStrokeWidth = strokeWidth / 2;
|
|
237
|
-
|
|
238
|
-
ctx.strokeRect(x0 * (scale_x) - halfStrokeWidth, y0 * (scale_y) - halfStrokeWidth, aabb.getWidth() * scale_x + strokeWidth, aabb.getHeight() * scale_y + strokeWidth);
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const fontHeight = 8;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
function drawLabel(text, x, y) {
|
|
245
|
-
|
|
246
|
-
ctx.fillStyle = 'black';
|
|
247
|
-
ctx.font = '10px Tahoma';
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
ctx.strokeStyle = `hsla(${hue * 360},90%,70%,0.5)`;
|
|
251
|
-
ctx.lineWidth = 2;
|
|
252
|
-
|
|
253
|
-
ctx.strokeText(text, x, y);
|
|
254
|
-
ctx.fillText(text, x, y);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const maxWeight = arrayPickBestElement(patch.weights, passThrough);
|
|
258
|
-
|
|
259
|
-
//write stats
|
|
260
|
-
drawLabel(`M: ${patch.materialIndex}`, 0, rH - fontHeight * 2);
|
|
261
|
-
drawLabel(`Max: ${maxWeight}`, 0, rH - fontHeight * 1);
|
|
262
|
-
drawLabel(`Area: ${patch.area}`, 0, rH);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return canvasView;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
*
|
|
270
|
-
* @param {Graph<SplatMapMaterialPatch>} graph
|
|
271
|
-
*/
|
|
272
|
-
build(graph) {
|
|
273
|
-
|
|
274
|
-
const patches = graph.nodes;
|
|
275
|
-
|
|
276
|
-
const vContainer = new EmptyView({});
|
|
277
|
-
|
|
278
|
-
vContainer.size.set(1024, 1024);
|
|
279
|
-
|
|
280
|
-
let w = 512;
|
|
281
|
-
let h = 512;
|
|
282
|
-
|
|
283
|
-
const nodeCount = patches.length;
|
|
284
|
-
if (nodeCount > 0) {
|
|
285
|
-
w = patches[0].width;
|
|
286
|
-
h = patches[0].height;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const boxes = [];
|
|
290
|
-
|
|
291
|
-
const columnCount = 8;
|
|
292
|
-
|
|
293
|
-
for (let i = 0; i < nodeCount; i++) {
|
|
294
|
-
const patch = patches[i];
|
|
295
|
-
|
|
296
|
-
const v = this.buildPatch(patch);
|
|
297
|
-
|
|
298
|
-
v.css({
|
|
299
|
-
position: 'absolute',
|
|
300
|
-
border: 'solid 1px black',
|
|
301
|
-
pointerEvents: 'auto'
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
v.el.addEventListener('click', () => {
|
|
305
|
-
focusNode(patch);
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
vContainer.addChild(v);
|
|
309
|
-
|
|
310
|
-
const column = Math.floor(i / columnCount);
|
|
311
|
-
const row = i % columnCount;
|
|
312
|
-
|
|
313
|
-
const y0 = column * v.size.x;
|
|
314
|
-
const x0 = row * v.size.y;
|
|
315
|
-
|
|
316
|
-
const box = new AABB2(x0, y0, x0 + v.size.x, y0 + v.size.y);
|
|
317
|
-
|
|
318
|
-
const sX = v.size.x / patch.width;
|
|
319
|
-
const sY = v.size.y / patch.height;
|
|
320
|
-
|
|
321
|
-
const focus = new AABB2();
|
|
322
|
-
|
|
323
|
-
focus.copy(patch.aabb);
|
|
324
|
-
focus.multiplyScalar(sX);
|
|
325
|
-
|
|
326
|
-
box.view = v;
|
|
327
|
-
box.model = patch;
|
|
328
|
-
box.focus = focus;
|
|
329
|
-
|
|
330
|
-
boxes.push(box);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// forceLayout(boxes, graph);
|
|
334
|
-
|
|
335
|
-
for (let i = 0; i < nodeCount; i++) {
|
|
336
|
-
const box = boxes[i];
|
|
337
|
-
|
|
338
|
-
const view = box.view;
|
|
339
|
-
|
|
340
|
-
view.position.set(box.x0, box.y0);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
//draw connections
|
|
344
|
-
const vConnections = new View();
|
|
345
|
-
|
|
346
|
-
const svg = SVG.createElement('svg');
|
|
347
|
-
vConnections.el = svg;
|
|
348
|
-
|
|
349
|
-
svg.setAttribute("width", vContainer.size.x);
|
|
350
|
-
svg.setAttribute("height", vContainer.size.y);
|
|
351
|
-
vConnections.css({ position: 'absolute', left: '0', top: '0', overflow: 'visible' });
|
|
352
|
-
|
|
353
|
-
vContainer.addChild(vConnections);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
*
|
|
358
|
-
* @param {SplatMapMaterialPatch} node
|
|
359
|
-
*/
|
|
360
|
-
function focusNode(node) {
|
|
361
|
-
removeAllChildren(svg);
|
|
362
|
-
|
|
363
|
-
const attachedEdges = graph.getAttachedEdges(node);
|
|
364
|
-
|
|
365
|
-
drawConnections(svg, attachedEdges, graph, boxes);
|
|
366
|
-
|
|
367
|
-
//paint the patch on terrain
|
|
368
|
-
paintPatchOnTerrain(node);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
vContainer.css({
|
|
372
|
-
pointerEvents: 'none',
|
|
373
|
-
maxWidth: '100vw',
|
|
374
|
-
maxHeight: '100vh',
|
|
375
|
-
overflow: 'scroll',
|
|
376
|
-
flexWrap: 'wrap',
|
|
377
|
-
zIndex: '9999'
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
return vContainer;
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
}
|