@woosh/meep-engine 2.33.65 → 2.33.70
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/core/geom/2d/quad-tree/QuadTreeNode.js +3 -2
- package/core/geom/3d/triangle/computeTriangleRayIntersection.js +3 -9
- package/engine/asset/loaders/GLTFAssetLoader.js +0 -4
- package/engine/ecs/fow/FogOfWarRevealerSystem.js +8 -0
- package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +2 -10
- package/engine/ecs/grid/NormalMap2AOMap.js +10 -13
- package/engine/ecs/terrain/ecs/BuildLightTexture.js +106 -0
- package/engine/ecs/terrain/ecs/PromiseSamplerHeight.js +59 -0
- package/engine/ecs/terrain/ecs/Terrain.js +14 -153
- package/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +10 -0
- package/engine/graphics/filter/ImageFilter.js +6 -2
- package/engine/graphics/geometry/buffered/deinterleaveBufferAttribute.js +3 -2
- package/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +28 -27
- package/engine/graphics/geometry/buffered/query/GeometryVisitor.js +29 -2
- package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +28 -27
- package/engine/graphics/micron/convert_three_object_to_micron.js +14 -3
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +3 -0
- package/engine/graphics/shaders/AmbientOcclusionShader.js +57 -77
- package/engine/graphics/shaders/DenoiseShader.js +119 -0
- package/engine/graphics/texture/noise_octaves.js +33 -0
- package/engine/graphics/texture/sampler/Sampler2D2Texture.js +7 -18
- package/engine/graphics/texture/sampler/debug/paintSamplerOnHTML.js +8 -5
- package/engine/graphics/texture/sampler/sampler2DToFloat32Texture.js +10 -3
- package/generation/example/SampleGenerator0.js +7 -11
- package/generation/example/filters/SampleGroundMoistureFilter.js +2 -1
- package/generation/example/main.js +215 -0
- package/generation/example/themes/SampleTheme0.js +22 -9
- package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +29 -13
- package/generation/grid/GridData.js +17 -2
- package/generation/placement/GridCellPlacementRule.js +3 -5
- package/package.json +1 -1
|
@@ -21,7 +21,6 @@ import { matcher_tag_traversable } from "./rules/matcher_tag_traversable.js";
|
|
|
21
21
|
import { GridTaskGenerateRoads } from "../grid/generation/road/GridTaskGenerateRoads.js";
|
|
22
22
|
import { mir_generator_place_road_decorators } from "./generators/mir_generator_place_road_decorators.js";
|
|
23
23
|
import { MarkerNodeMatcherByType } from "../markers/matcher/MarkerNodeMatcherByType.js";
|
|
24
|
-
import { mir_generator_place_buff_objects } from "./generators/interactive/mir_generator_place_buff_objects.js";
|
|
25
24
|
import { GridTaskDensityMarkerDistribution } from "../grid/generation/GridTaskDensityMarkerDistribution.js";
|
|
26
25
|
import { CellFilterSimplexNoise } from "../filtering/numeric/complex/CellFilterSimplexNoise.js";
|
|
27
26
|
import { NumericInterval } from "../../core/math/interval/NumericInterval.js";
|
|
@@ -211,12 +210,11 @@ const prEnemyCorridorGuard = GridCellPlacementRule.from(
|
|
|
211
210
|
), actions: [
|
|
212
211
|
ACTION_PLACE_ENEMY_MARKER,
|
|
213
212
|
ACTION_PLACE_ENEMY_TAG
|
|
214
|
-
]
|
|
213
|
+
],
|
|
214
|
+
probability: CellFilterLiteralFloat.from(0.5)
|
|
215
215
|
}
|
|
216
216
|
);
|
|
217
217
|
|
|
218
|
-
prEnemyCorridorGuard.probability = 0.5;
|
|
219
|
-
|
|
220
218
|
const gRuleSet2 = GridTaskActionRuleSet.from({ rules: GridActionRuleSet.from({ rules: [prEnemyTreasureGuard, prEnemyCorridorGuard] }) });
|
|
221
219
|
|
|
222
220
|
gRuleSet2.addDependency(gRuleSetTreasureGuards);
|
|
@@ -226,7 +224,11 @@ const gPlaceStartingPoint = mir_generator_place_starting_point();
|
|
|
226
224
|
|
|
227
225
|
gPlaceStartingPoint.addDependency(gConnectRooms);
|
|
228
226
|
|
|
229
|
-
const gBuildDistanceMap = GridTaskBuildSourceDistanceMap.from({
|
|
227
|
+
const gBuildDistanceMap = GridTaskBuildSourceDistanceMap.from({
|
|
228
|
+
source: MATCH_STARTING_POINT,
|
|
229
|
+
pass: MATCH_EMPTY,
|
|
230
|
+
layer: MirGridLayers.DistanceFromStart
|
|
231
|
+
});
|
|
230
232
|
|
|
231
233
|
gBuildDistanceMap.addDependency(gPlaceStartingPoint);
|
|
232
234
|
|
|
@@ -235,11 +237,8 @@ gRuleSet1.addDependency(gBuildDistanceMap);
|
|
|
235
237
|
const gBases = mir_generator_place_bases();
|
|
236
238
|
gBases.addDependency(gMakeEmpty);
|
|
237
239
|
|
|
238
|
-
const gBuffObjects = mir_generator_place_buff_objects();
|
|
239
|
-
gBuffObjects.addDependency(gBases);
|
|
240
240
|
|
|
241
241
|
gConnectRooms.addDependency(gBases);
|
|
242
|
-
gConnectRooms.addDependency(gBuffObjects);
|
|
243
242
|
|
|
244
243
|
gPlaceStartingPoint.addDependency(gBases);
|
|
245
244
|
|
|
@@ -250,7 +249,6 @@ const gRoads = new GridTaskGenerateRoads();
|
|
|
250
249
|
|
|
251
250
|
gRoads.addDependency(gConnectRooms);
|
|
252
251
|
gRoads.addDependency(gBases);
|
|
253
|
-
gRoads.addDependency(gBuffObjects);
|
|
254
252
|
|
|
255
253
|
const gRoadDecorators = mir_generator_place_road_decorators();
|
|
256
254
|
|
|
@@ -540,7 +538,6 @@ gFoliageLarge.addDependencies([
|
|
|
540
538
|
gRuleSet1,
|
|
541
539
|
gRuleSet2,
|
|
542
540
|
gRuleSetTreasureGuards,
|
|
543
|
-
gBuffObjects,
|
|
544
541
|
gBases
|
|
545
542
|
]);
|
|
546
543
|
|
|
@@ -555,7 +552,6 @@ SampleGenerator0.addGenerator(gConnectRooms);
|
|
|
555
552
|
SampleGenerator0.addGenerator(gRoads);
|
|
556
553
|
SampleGenerator0.addGenerator(gRoadDecorators);
|
|
557
554
|
SampleGenerator0.addGenerator(gBases);
|
|
558
|
-
SampleGenerator0.addGenerator(gBuffObjects);
|
|
559
555
|
SampleGenerator0.addGenerator(gPlaceStartingPoint);
|
|
560
556
|
SampleGenerator0.addGenerator(gBuildDistanceMap);
|
|
561
557
|
SampleGenerator0.addGenerator(gRuleSet1);
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { EngineHarness } from "../../engine/EngineHarness.js";
|
|
2
|
+
import RenderSystem from "../../engine/ecs/systems/RenderSystem.js";
|
|
3
|
+
import { Camera } from "../../engine/graphics/ecs/camera/Camera.js";
|
|
4
|
+
import TopDownCameraController from "../../engine/graphics/ecs/camera/topdown/TopDownCameraController.js";
|
|
5
|
+
import Vector3 from "../../core/geom/Vector3.js";
|
|
6
|
+
import { TopDownCameraLander } from "../../engine/graphics/ecs/camera/topdown/TopDownCameraLander.js";
|
|
7
|
+
import Terrain from "../../engine/ecs/terrain/ecs/Terrain.js";
|
|
8
|
+
import { TerrainFlags } from "../../engine/ecs/terrain/ecs/TerrainFlags.js";
|
|
9
|
+
import Water from "../../engine/graphics/ecs/water/Water.js";
|
|
10
|
+
import GridObstacle from "../../engine/grid/components/GridObstacle.js";
|
|
11
|
+
import EntityBuilder from "../../engine/ecs/EntityBuilder.js";
|
|
12
|
+
import GridPosition from "../../engine/grid/components/GridPosition.js";
|
|
13
|
+
import { Transform } from "../../engine/ecs/transform/Transform.js";
|
|
14
|
+
import { GridData } from "../grid/GridData.js";
|
|
15
|
+
import { computeStringHash } from "../../core/primitives/strings/computeStringHash.js";
|
|
16
|
+
import { ThemeEngine } from "../theme/ThemeEngine.js";
|
|
17
|
+
import { AreaTheme } from "../theme/AreaTheme.js";
|
|
18
|
+
import TaskGroup from "../../core/process/task/TaskGroup.js";
|
|
19
|
+
import { actionTask } from "../../core/process/task/TaskUtils.js";
|
|
20
|
+
import { generateTerrainPreview } from "../../../../generator/generator/generateTerrainPreview.js";
|
|
21
|
+
import { SampleTheme0 } from "./themes/SampleTheme0.js";
|
|
22
|
+
import { SampleGenerator0 } from "./SampleGenerator0.js";
|
|
23
|
+
import { configureMirGrid } from "./grid/configureMirGrid.js";
|
|
24
|
+
import { EngineConfiguration } from "../../engine/EngineConfiguration.js";
|
|
25
|
+
import TerrainSystem from "../../engine/ecs/terrain/ecs/TerrainSystem.js";
|
|
26
|
+
import WaterSystem from "../../engine/graphics/ecs/water/WaterSystem.js";
|
|
27
|
+
import { MeshSystem } from "../../engine/graphics/ecs/mesh/MeshSystem.js";
|
|
28
|
+
import TopDownCameraControllerSystem from "../../engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js";
|
|
29
|
+
import { TopDownCameraLanderSystem } from "../../engine/graphics/ecs/camera/topdown/TopDownCameraLanderSystem.js";
|
|
30
|
+
import LightSystem from "../../engine/graphics/ecs/light/LightSystem.js";
|
|
31
|
+
|
|
32
|
+
function makeEngineConfig(engine) {
|
|
33
|
+
const config = new EngineConfiguration();
|
|
34
|
+
|
|
35
|
+
const graphics = engine.graphics;
|
|
36
|
+
|
|
37
|
+
config.addSystem(new RenderSystem(graphics));
|
|
38
|
+
config.addSystem(new TerrainSystem(graphics, engine.assetManager));
|
|
39
|
+
config.addSystem(new WaterSystem(graphics));
|
|
40
|
+
config.addSystem(new MeshSystem(engine));
|
|
41
|
+
config.addSystem(new TopDownCameraControllerSystem());
|
|
42
|
+
config.addSystem(new TopDownCameraLanderSystem());
|
|
43
|
+
config.addSystem(new LightSystem(engine))
|
|
44
|
+
|
|
45
|
+
return config;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param {EngineHarness} harness
|
|
52
|
+
* @return {Promise<void>}
|
|
53
|
+
*/
|
|
54
|
+
async function init(harness) {
|
|
55
|
+
const engine = harness.engine;
|
|
56
|
+
|
|
57
|
+
await makeEngineConfig(engine).apply(engine);
|
|
58
|
+
|
|
59
|
+
await harness.initialize();
|
|
60
|
+
|
|
61
|
+
main(engine);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function prepare_gen_task({
|
|
65
|
+
SIZE_X = 64,
|
|
66
|
+
SIZE_Y = 64,
|
|
67
|
+
ecd
|
|
68
|
+
}) {
|
|
69
|
+
|
|
70
|
+
const camera = EngineHarness.buildCamera({
|
|
71
|
+
engine,
|
|
72
|
+
target: new Vector3(15, 0, 16),
|
|
73
|
+
// pitch: -PI_HALF,
|
|
74
|
+
pitch: 1.1,
|
|
75
|
+
yaw: 3.14,
|
|
76
|
+
distance: 13,
|
|
77
|
+
ecd,
|
|
78
|
+
distanceMin: 5,
|
|
79
|
+
distanceMax: 30
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
camera.add(new TopDownCameraLander());
|
|
83
|
+
|
|
84
|
+
// build lights
|
|
85
|
+
EngineHarness.buildLights({ engine })
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
// build terrain
|
|
89
|
+
const terrain = new Terrain();
|
|
90
|
+
|
|
91
|
+
terrain.resolution = 4;
|
|
92
|
+
|
|
93
|
+
terrain.size.set(SIZE_X, SIZE_Y);
|
|
94
|
+
terrain.samplerHeight.resize(SIZE_X, SIZE_Y);
|
|
95
|
+
terrain.splat.resize(SIZE_X * 4, SIZE_Y * 4, 0);
|
|
96
|
+
|
|
97
|
+
terrain.layers.resolution.set(512, 512);
|
|
98
|
+
|
|
99
|
+
terrain.clearFlag(TerrainFlags.Built);
|
|
100
|
+
terrain.build(engine.assetManager);
|
|
101
|
+
|
|
102
|
+
const water = new Water();
|
|
103
|
+
|
|
104
|
+
water.color.setRGB(0.2, 0.0, 0.5);
|
|
105
|
+
water.shoreColor.setRGB(0.3, 0.3, 1);
|
|
106
|
+
water.shoreDepthTransition.set(0.16, 0.5);
|
|
107
|
+
water.waveFrequency.set(1.3);
|
|
108
|
+
water.waveAmplitude.set(0.15);
|
|
109
|
+
water.waveSpeed.set(1.2);
|
|
110
|
+
water.scattering.set(1.2);
|
|
111
|
+
water.level.set(-0.3);
|
|
112
|
+
|
|
113
|
+
const obstacle = new GridObstacle();
|
|
114
|
+
obstacle.resize(terrain.size.x, terrain.size.y);
|
|
115
|
+
|
|
116
|
+
const terrainBuilder = new EntityBuilder();
|
|
117
|
+
|
|
118
|
+
terrainBuilder
|
|
119
|
+
.add(terrain)
|
|
120
|
+
.add(water)
|
|
121
|
+
.add(obstacle)
|
|
122
|
+
.add(new GridPosition())
|
|
123
|
+
.add(new Transform())
|
|
124
|
+
.build(ecd);
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
const gridData = new GridData();
|
|
128
|
+
|
|
129
|
+
configureMirGrid(gridData);
|
|
130
|
+
|
|
131
|
+
gridData.resize(terrain.size.x, terrain.size.y);
|
|
132
|
+
gridData.computeScale(1);
|
|
133
|
+
|
|
134
|
+
const generator = SampleGenerator0;
|
|
135
|
+
|
|
136
|
+
const tGenerationTask = generator.generate(ecd, gridData, computeStringHash('alexx855'));
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
const themeEngine = new ThemeEngine();
|
|
140
|
+
themeEngine.assetManager = engine.assetManager;
|
|
141
|
+
|
|
142
|
+
const theme0 = new AreaTheme();
|
|
143
|
+
|
|
144
|
+
const width = gridData.width;
|
|
145
|
+
const height = gridData.height;
|
|
146
|
+
|
|
147
|
+
theme0.mask.resize(width, height);
|
|
148
|
+
theme0.mask.mask.fill(0, 0, width, height, [1]);
|
|
149
|
+
theme0.theme = SampleTheme0;
|
|
150
|
+
|
|
151
|
+
themeEngine.add(theme0);
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
themeEngine.random.setCurrentSeed(1);
|
|
155
|
+
const tTheme = themeEngine.apply(gridData, ecd);
|
|
156
|
+
|
|
157
|
+
tTheme.addDependency(tGenerationTask);
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
const tBuildLevel = new TaskGroup([tGenerationTask, tTheme]);
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
const tAddGameplayElements = actionTask(() => {
|
|
164
|
+
// prepare gameplay-specific things on top of the generated level
|
|
165
|
+
|
|
166
|
+
//build minimap
|
|
167
|
+
const terrainPreview = generateTerrainPreview(terrainBuilder.entity, ecd);
|
|
168
|
+
terrain.preview.copy(terrainPreview);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
tAddGameplayElements.addDependency(tBuildLevel);
|
|
172
|
+
|
|
173
|
+
return new TaskGroup([tBuildLevel, tAddGameplayElements]);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param {Engine} engine
|
|
179
|
+
*/
|
|
180
|
+
function main(engine) {
|
|
181
|
+
const ecd = engine.entityManager.dataset;
|
|
182
|
+
|
|
183
|
+
const tBuildLevel = prepare_gen_task({ ecd });
|
|
184
|
+
|
|
185
|
+
engine.loadSlowTask(tBuildLevel);
|
|
186
|
+
|
|
187
|
+
engine.executor.runGroup(tBuildLevel);
|
|
188
|
+
|
|
189
|
+
tBuildLevel.promise().then(() => {
|
|
190
|
+
console.log('Generation took ', tBuildLevel.getExecutedCpuTime(), 'ms');
|
|
191
|
+
|
|
192
|
+
const camera = ecd.getAnyComponent(Camera);
|
|
193
|
+
|
|
194
|
+
EngineHarness.buildOrbitalCameraController({
|
|
195
|
+
cameraEntity: camera.entity,
|
|
196
|
+
engine
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// tweak camera for prototyping
|
|
200
|
+
const ctrl = ecd.getComponent(camera.entity, TopDownCameraController);
|
|
201
|
+
if (ctrl !== undefined) {
|
|
202
|
+
ctrl.distanceMax = 200;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Resume audio context
|
|
208
|
+
engine.devices.pointer.on.down.addOne(engine.sound.resumeContext, engine.sound);
|
|
209
|
+
engine.devices.pointer.on.wheel.addOne(engine.sound.resumeContext, engine.sound);
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const engineHarness = new EngineHarness();
|
|
214
|
+
|
|
215
|
+
init(engineHarness);
|
|
@@ -46,6 +46,8 @@ import { SoundEmitter } from "../../../engine/sound/ecs/emitter/SoundEmitter.js"
|
|
|
46
46
|
import { SampleGroundMoistureFilter } from "../filters/SampleGroundMoistureFilter.js";
|
|
47
47
|
import GeneratedArmy from "../../../../model/game/ecs/component/generator/army/GeneratedArmy.js";
|
|
48
48
|
import { MirMarkerTypes } from "../../../../generator/MirMarkerTypes.js";
|
|
49
|
+
import { TerrainLayerDescription } from "../../theme/TerrainLayerDescription.js";
|
|
50
|
+
import Vector2 from "../../../core/geom/Vector2.js";
|
|
49
51
|
|
|
50
52
|
export const SampleTheme0 = new Theme();
|
|
51
53
|
|
|
@@ -123,10 +125,6 @@ const filterSand = CellFilterMultiply.from(
|
|
|
123
125
|
filterNotRockAndNotRoad
|
|
124
126
|
);
|
|
125
127
|
|
|
126
|
-
const TERRAIN_LAYER_GRASS = 0;
|
|
127
|
-
const TERRAIN_LAYER_ROCK = 1;
|
|
128
|
-
const TERRAIN_LAYER_SAND = 3;
|
|
129
|
-
|
|
130
128
|
terrainTheme.rules.push(TerrainLayerRule.from(
|
|
131
129
|
CellFilterMultiply.from(
|
|
132
130
|
CellFilterMultiply.from(
|
|
@@ -135,22 +133,34 @@ terrainTheme.rules.push(TerrainLayerRule.from(
|
|
|
135
133
|
),
|
|
136
134
|
filterNotRockAndNotRoad
|
|
137
135
|
),
|
|
138
|
-
|
|
136
|
+
TerrainLayerDescription.from({
|
|
137
|
+
diffuse:'data/textures/materials/Sci-Fi Planet/Grass_02.png',
|
|
138
|
+
size:new Vector2(7,7)
|
|
139
|
+
})
|
|
139
140
|
));
|
|
140
141
|
|
|
141
142
|
terrainTheme.rules.push(TerrainLayerRule.from(
|
|
142
143
|
filterRock,
|
|
143
|
-
|
|
144
|
+
TerrainLayerDescription.from({
|
|
145
|
+
diffuse:'data/textures/Materials_Stylized/4k JPEG/Stylized_04_Rocks/Stylized_04_Rocks_basecolor.jpg',
|
|
146
|
+
size:new Vector2(7,7)
|
|
147
|
+
})
|
|
144
148
|
));
|
|
145
149
|
|
|
146
150
|
terrainTheme.rules.push(TerrainLayerRule.from(
|
|
147
151
|
filterSand,
|
|
148
|
-
|
|
152
|
+
TerrainLayerDescription.from({
|
|
153
|
+
diffuse:'data/textures/Materials_Stylized/4k JPEG/Stylized_06_Sand/Stylized_06_Sand_basecolor.jpg',
|
|
154
|
+
size:new Vector2(7,7)
|
|
155
|
+
})
|
|
149
156
|
));
|
|
150
157
|
|
|
151
158
|
terrainTheme.rules.push(TerrainLayerRule.from(
|
|
152
159
|
filterRoad,
|
|
153
|
-
|
|
160
|
+
TerrainLayerDescription.from({
|
|
161
|
+
diffuse:'data/textures/Materials_Stylized/4k JPEG/Stylized_02_Stone_Ground/Stylized_02_Stone_Ground_basecolor.jpg',
|
|
162
|
+
size:new Vector2(7,7)
|
|
163
|
+
})
|
|
154
164
|
));
|
|
155
165
|
|
|
156
166
|
terrainTheme.rules.push(TerrainLayerRule.from(
|
|
@@ -158,7 +168,10 @@ terrainTheme.rules.push(TerrainLayerRule.from(
|
|
|
158
168
|
ROAD_FILTER,
|
|
159
169
|
CellFilterLerp.from(CellFilterLiteralFloat.from(1), CellFilterLiteralFloat.from(0.3), NOISE_10_a)
|
|
160
170
|
),
|
|
161
|
-
|
|
171
|
+
TerrainLayerDescription.from({
|
|
172
|
+
diffuse:'data/textures/materials/Sci-Fi Planet/Grass_02.png',
|
|
173
|
+
size:new Vector2(7,7)
|
|
174
|
+
}),
|
|
162
175
|
));
|
|
163
176
|
|
|
164
177
|
SampleTheme0.terrain = terrainTheme;
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { CellFilter } from "../../CellFilter.js";
|
|
2
2
|
import { gaussian } from "../../../../core/math/gaussian.js";
|
|
3
|
-
|
|
3
|
+
import { max2 } from "../../../../core/math/max2.js";
|
|
4
|
+
import { assert } from "../../../../core/assert.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {number[]} result
|
|
9
|
+
* @param {number} samplesX
|
|
10
|
+
* @param {number} samplesY
|
|
11
|
+
* @param {number} sigma_x
|
|
12
|
+
* @param {number} sigma_y
|
|
13
|
+
* @return {number}
|
|
14
|
+
*/
|
|
4
15
|
function buildKernel(result, samplesX, samplesY, sigma_x, sigma_y) {
|
|
5
|
-
|
|
6
|
-
|
|
16
|
+
assert.isNonNegativeInteger(samplesX, 'samplesX');
|
|
17
|
+
assert.isNonNegativeInteger(samplesY, 'samplesY');
|
|
18
|
+
|
|
19
|
+
const half_samples_x = samplesX * 0.5;
|
|
20
|
+
const half_samples_y = samplesY * 0.5;
|
|
7
21
|
|
|
8
22
|
let powerTotal = 0;
|
|
9
23
|
let ix, iy;
|
|
@@ -70,6 +84,8 @@ export class CellFilterGaussianBlur extends CellFilter {
|
|
|
70
84
|
if (!this.source.initialized) {
|
|
71
85
|
this.source.initialize(grid, seed);
|
|
72
86
|
|
|
87
|
+
this.__kernel = new Float32Array(this.samples_x * this.samples_y);
|
|
88
|
+
|
|
73
89
|
// initialize kernel
|
|
74
90
|
this.__kernel_total_power = buildKernel(this.__kernel, this.samples_x, this.samples_y, this.sigma_x, this.sigma_y);
|
|
75
91
|
}
|
|
@@ -84,13 +100,13 @@ export class CellFilterGaussianBlur extends CellFilter {
|
|
|
84
100
|
* @param {number} quality
|
|
85
101
|
* @returns {CellFilterGaussianBlur}
|
|
86
102
|
*/
|
|
87
|
-
static from(source, x, y, quality =
|
|
103
|
+
static from(source, x, y, quality = 3) {
|
|
88
104
|
const r = new CellFilterGaussianBlur();
|
|
89
105
|
|
|
90
106
|
r.source = source;
|
|
91
107
|
|
|
92
|
-
r.samples_x = quality * x;
|
|
93
|
-
r.samples_y = quality * y;
|
|
108
|
+
r.samples_x = max2(2, Math.round(quality * x));
|
|
109
|
+
r.samples_y = max2(2, Math.round(quality * y));
|
|
94
110
|
|
|
95
111
|
r.size_x = x;
|
|
96
112
|
r.size_y = y;
|
|
@@ -102,24 +118,24 @@ export class CellFilterGaussianBlur extends CellFilter {
|
|
|
102
118
|
const samplesX = this.samples_x;
|
|
103
119
|
const samplesY = this.samples_y;
|
|
104
120
|
|
|
105
|
-
const half_samples_x = (samplesX
|
|
106
|
-
const half_samples_y = (samplesY
|
|
121
|
+
const half_samples_x = (samplesX - 1) * 0.5;
|
|
122
|
+
const half_samples_y = (samplesY - 1) * 0.5;
|
|
107
123
|
|
|
108
124
|
const sizeX = this.size_x;
|
|
109
125
|
const sizeY = this.size_y;
|
|
110
126
|
|
|
111
|
-
const local_u_scale = 1 / samplesX;
|
|
112
|
-
const local_v_scale = 1 / samplesY;
|
|
127
|
+
const local_u_scale = 1 / (samplesX - 1);
|
|
128
|
+
const local_v_scale = 1 / (samplesY - 1);
|
|
113
129
|
|
|
114
130
|
let sum = 0;
|
|
115
|
-
let ix, iy;
|
|
131
|
+
let ix, iy = 0;
|
|
116
132
|
|
|
117
133
|
const source = this.source;
|
|
118
134
|
const kernel = this.__kernel;
|
|
119
135
|
|
|
120
|
-
const i_samples_x = samplesX|0;
|
|
136
|
+
const i_samples_x = samplesX | 0;
|
|
121
137
|
|
|
122
|
-
for (
|
|
138
|
+
for (; iy < samplesY; iy++) {
|
|
123
139
|
const local_y = iy - half_samples_y;
|
|
124
140
|
|
|
125
141
|
const ny = local_y * local_v_scale;
|
|
@@ -2,6 +2,7 @@ import { assert } from "../../core/assert.js";
|
|
|
2
2
|
import { QuadTreeNode } from "../../core/geom/2d/quad-tree/QuadTreeNode.js";
|
|
3
3
|
import { OffsetScaleTransform2D } from "../../engine/ecs/terrain/ecs/OffsetScaleTransform2D.js";
|
|
4
4
|
import { MarkerMatchCounter } from "./MarkerMatchCounter.js";
|
|
5
|
+
import { max2 } from "../../core/math/max2.js";
|
|
5
6
|
|
|
6
7
|
const scratch_match_counter = new MarkerMatchCounter();
|
|
7
8
|
|
|
@@ -167,8 +168,14 @@ export class GridData {
|
|
|
167
168
|
* @param {number} height
|
|
168
169
|
*/
|
|
169
170
|
resize(width, height) {
|
|
170
|
-
assert.
|
|
171
|
-
assert.
|
|
171
|
+
assert.isNumber(width, 'width');
|
|
172
|
+
assert.isNumber(height, 'height');
|
|
173
|
+
|
|
174
|
+
assert.isNonNegativeInteger(width,'width');
|
|
175
|
+
assert.isNonNegativeInteger(height,'height');
|
|
176
|
+
|
|
177
|
+
assert.isFiniteNumber(width, 'width');
|
|
178
|
+
assert.isFiniteNumber(height, 'width');
|
|
172
179
|
|
|
173
180
|
if (width === this.width && height === this.height) {
|
|
174
181
|
//no need, already the right size
|
|
@@ -187,6 +194,14 @@ export class GridData {
|
|
|
187
194
|
|
|
188
195
|
layer.resize(width, height);
|
|
189
196
|
}
|
|
197
|
+
|
|
198
|
+
// resize the quad tree pre-emptively, to avoid expensive re-balancing operations later on
|
|
199
|
+
this.markers.resize(
|
|
200
|
+
-max2(1, width * 0.5),
|
|
201
|
+
-max2(1, height * 0.5),
|
|
202
|
+
max2(width + 1, width * 1.5),
|
|
203
|
+
max2(height + 1, height * 1.5)
|
|
204
|
+
);
|
|
190
205
|
}
|
|
191
206
|
|
|
192
207
|
/**
|
|
@@ -44,7 +44,7 @@ export class GridCellPlacementRule {
|
|
|
44
44
|
* @param {Vector2} [offset]
|
|
45
45
|
* @returns {GridCellPlacementRule}
|
|
46
46
|
*/
|
|
47
|
-
static from({ matcher, actions, probability, offset = Vector2.zero }) {
|
|
47
|
+
static from({ matcher, actions, probability = CellFilterLiteralFloat.from(1), offset = Vector2.zero }) {
|
|
48
48
|
|
|
49
49
|
assert.defined(matcher);
|
|
50
50
|
assert.defined(actions);
|
|
@@ -56,10 +56,8 @@ export class GridCellPlacementRule {
|
|
|
56
56
|
r.pattern = matcher;
|
|
57
57
|
r.actions = actions;
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
r.probability = probability;
|
|
62
|
-
}
|
|
59
|
+
assert.equal(probability.isCellFilter, true, 'probability.isCellFilter !== true');
|
|
60
|
+
r.probability = probability;
|
|
63
61
|
|
|
64
62
|
r.positionOffset.copy(offset);
|
|
65
63
|
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.33.
|
|
8
|
+
"version": "2.33.70",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|