@woosh/meep-engine 2.37.19 → 2.37.20
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/binary/float2uint8.js +8 -0
- package/core/binary/uint82float.js +8 -0
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +6 -4
- package/core/collection/list/List.d.ts +1 -1
- package/core/color/Color.js +69 -1
- package/core/color/YCbCr_to_rgb_uint24.js +3 -4
- package/core/color/hsv2rgb.js +4 -3
- package/core/color/linear_to_sRGB.js +4 -5
- package/core/color/rgb2uint24.js +6 -4
- package/core/color/rgb_to_YCbCr_uint24.js +11 -13
- package/core/events/signal/Signal.d.ts +11 -9
- package/core/geom/2d/quad-tree/qt_collect_by_circle.js +67 -0
- package/core/geom/Quaternion.d.ts +16 -1
- package/core/geom/Quaternion.js +129 -65
- package/core/geom/Quaternion.spec.js +24 -0
- package/core/geom/Vector2.js +3 -3
- package/core/geom/Vector3.d.ts +2 -0
- package/core/geom/Vector3.js +31 -7
- package/core/geom/Vector4.js +16 -0
- package/core/math/bell_membership_function.js +19 -0
- package/core/math/exp2.js +8 -0
- package/core/math/interval/NumericInterval.js +17 -0
- package/core/math/physics/brdf/brdf_burley.js +25 -0
- package/core/math/physics/bsdf/bsdf_schlick.js +22 -0
- package/core/math/physics/irradiance/interpolate_irradiance_linear.js +18 -0
- package/{engine/sound/ecs/emitter/attenuate/attenuateSoundLogarithmic.js → core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js} +2 -2
- package/{engine/sound/ecs/emitter/attenuate/attenuateSoundSmith.js → core/math/physics/irradiance/interpolate_irradiance_smith.js} +1 -1
- package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
- package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
- package/editor/actions/concrete/PatchTerrainHeightAction.js +12 -104
- package/editor/ecs/component/createObjectEditor.js +53 -29
- package/editor/ecs/component/editors/Sampler2DEditor.js +71 -24
- package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +47 -0
- package/editor/ecs/component/editors/primitive/FunctionEditor.js +6 -2
- package/editor/tools/SelectionTool.js +1 -1
- package/editor/tools/paint/TerrainHeightPaintTool.js +88 -68
- package/editor/tools/paint/TerrainPaintTool.js +2 -1
- package/editor/tools/paint/TerrainTexturePaintTool.js +8 -73
- package/engine/asset/AssetManager.d.ts +1 -1
- package/engine/asset/AssetManager.js +390 -388
- package/engine/asset/loaders/gltf/extensions/MSFT_texture_dds.js +14 -2
- package/engine/ecs/fow/FogOfWarEditor.js +13 -0
- package/engine/ecs/terrain/ecs/OffsetScaleTransform2D.d.ts +6 -0
- package/engine/ecs/terrain/ecs/Terrain.js +21 -1
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +26 -28
- package/engine/ecs/terrain/overlay/TerrainOverlay.js +71 -66
- package/engine/ecs/terrain/tiles/TerrainTileManager.js +23 -0
- package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +13 -7
- package/engine/ecs/transform/Transform.d.ts +2 -0
- package/engine/ecs/transform/Transform.js +3 -0
- package/engine/graphics/ecs/light/Light.js +0 -47
- package/engine/graphics/ecs/light/LightSerializationAdapter.js +50 -0
- package/engine/graphics/ecs/mesh-v2/DrawMode.js +2 -1
- package/engine/graphics/ecs/mesh-v2/build_three_object.js +3 -1
- package/engine/graphics/ecs/sprite/Sprite.js +11 -0
- package/engine/graphics/ecs/sprite/SpriteSystemPE.js +133 -0
- package/engine/graphics/ecs/sprite/prototypeSpriteSystem.js +1566 -0
- package/engine/graphics/micron/prototypeVirtualGeometry.js +2 -2
- package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +17 -9
- package/engine/graphics/particles/particular/engine/renderers/ParticleRenderer.js +12 -10
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +7 -2
- package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticlePool.js +27 -0
- package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticleRenderer.js +80 -0
- package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +16 -4
- package/engine/graphics/shaders/TerrainShader.js +8 -8
- package/engine/graphics/texture/atlas/TextureAtlasDebugger.js +2 -1
- package/engine/graphics/texture/sampler/Sampler2D.js +190 -201
- package/engine/graphics/texture/sampler/Sampler2D.spec.js +34 -35
- package/engine/graphics/texture/sampler/bicubic.js +59 -0
- package/engine/graphics/texture/sampler/downsampleSample2D.spec.js +2 -2
- package/engine/graphics/texture/sampler/genericResampleSampler2D.js +0 -2
- package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +146 -0
- package/engine/graphics/texture/sampler/{downsampleSampler2D.js → sampler2D_scale_down_linear.js} +8 -4
- package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +140 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -3
- package/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.js +1 -1
- package/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -2
- package/engine/navigation/ecs/components/computeNonuniformCatmullRomSplineSample.js +117 -0
- package/engine/platform/GetURLHash.js +27 -0
- package/engine/platform/WebEnginePlatform.js +1 -22
- package/engine/sound/ecs/emitter/SoundEmitter.js +10 -6
- package/generation/GridGenerator.js +7 -6
- package/generation/example/SampleGenerator0.js +6 -6
- package/generation/example/filters/SampleGroundMoistureFilter.js +58 -17
- package/generation/example/themes/SampleTheme0.js +11 -7
- package/generation/filtering/numeric/CellFilterLiteralFloat.js +5 -0
- package/generation/filtering/numeric/complex/CellFilterDilate.js +36 -0
- package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +15 -5
- package/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +53 -1
- package/generation/filtering/numeric/math/CellFilterMax2.js +3 -0
- package/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +55 -0
- package/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +42 -0
- package/generation/filtering/numeric/sampling/CellFilterSampleLayerCubic.js +36 -0
- package/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +41 -0
- package/generation/grid/GridData.d.ts +5 -1
- package/generation/grid/GridData.js +35 -36
- package/generation/grid/MarkerMatchCounter.js +5 -3
- package/generation/markers/GridActionRuleSet.js +15 -32
- package/generation/markers/GridCellActionPlaceMarker.js +8 -10
- package/generation/markers/debug/visualizeMarkers.js +56 -36
- package/generation/markers/emitter/MarkerNodeEmitterFromAction.js +8 -8
- package/generation/markers/prototypeGridCellActionPlaceMarker.js +209 -0
- package/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -5
- package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +2 -2
- package/generation/placement/GridCellPlacementRule.js +10 -3
- package/package.json +1 -1
- package/samples/terrain/from_image.js +7 -3
- package/engine/graphics/particles/particular/engine/renderers/SoftBillboardParticleRenderer.js +0 -7
- package/engine/sound/ecs/emitter/attenuate/attenuateSoundLinear.js +0 -11
- package/generation/filtering/numeric/CellFilterReadGridLayer.js +0 -73
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CellFilterUnaryOperation } from "../../core/CellFilterUnaryOperation.js";
|
|
2
|
+
import { assert } from "../../../../core/assert.js";
|
|
3
|
+
import { bell_membership_function } from "../../../../core/math/bell_membership_function.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @see "dbellmf" function from Matlab
|
|
7
|
+
* @see https://codecrucks.com/what-is-fuzzy-membership-function-complete-guide/
|
|
8
|
+
* @see https://researchhubs.com/post/maths/fundamentals/bell-shaped-function.html
|
|
9
|
+
*/
|
|
10
|
+
export class CellFilterMembershipGeneralizedBell extends CellFilterUnaryOperation {
|
|
11
|
+
constructor() {
|
|
12
|
+
super();
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Controls window, larger value = larger window. Function will return exactly 0.5 at this distance away from center
|
|
17
|
+
* @type {number}
|
|
18
|
+
*/
|
|
19
|
+
this.a = 0;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Slope, larger slope makes function's tails sharper, meaning that values fall off faster away from center
|
|
23
|
+
* @type {number}
|
|
24
|
+
*/
|
|
25
|
+
this.b = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Controls center of the bell
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
this.c = 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static from(source, a = 1, b = 1, c = 0) {
|
|
34
|
+
assert.equal(source.isCellFilter, true, 'source.isCellFilter !== true');
|
|
35
|
+
|
|
36
|
+
assert.isNumber(a, 'a');
|
|
37
|
+
assert.isNumber(b, 'b');
|
|
38
|
+
assert.isNumber(c, 'c');
|
|
39
|
+
|
|
40
|
+
const r = new CellFilterMembershipGeneralizedBell();
|
|
41
|
+
|
|
42
|
+
r.a = a;
|
|
43
|
+
r.b = b;
|
|
44
|
+
r.c = c;
|
|
45
|
+
|
|
46
|
+
r.source = source;
|
|
47
|
+
|
|
48
|
+
return r;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
operation(v) {
|
|
52
|
+
return bell_membership_function(v, this.a, this.b, this.c);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CellFilter } from "../../CellFilter.js";
|
|
2
|
+
|
|
3
|
+
export class AbstractCellFilterSampleGridLayer extends CellFilter {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @type {string}
|
|
10
|
+
*/
|
|
11
|
+
this.layerId = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @type {GridDataLayer}
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
this.__layer = null;
|
|
19
|
+
|
|
20
|
+
this.__u_scale = 0;
|
|
21
|
+
this.__v_scale = 0;
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @type {Sampler2D}
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
this.__sampler = null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
initialize(grid, seed) {
|
|
31
|
+
super.initialize(grid, seed);
|
|
32
|
+
|
|
33
|
+
this.__layer = grid.getLayerById(this.layerId);
|
|
34
|
+
|
|
35
|
+
// cache required values
|
|
36
|
+
this.__sampler = this.__layer.sampler;
|
|
37
|
+
|
|
38
|
+
this.__u_scale = this.__sampler.width / grid.width;
|
|
39
|
+
this.__v_scale = this.__sampler.height / grid.height;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AbstractCellFilterSampleGridLayer } from "./AbstractCellFilterSampleGridLayer.js";
|
|
2
|
+
import { assert } from "../../../../core/assert.js";
|
|
3
|
+
|
|
4
|
+
export class CellFilterSampleLayerCubic extends AbstractCellFilterSampleGridLayer {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {string} layer
|
|
9
|
+
* @returns {CellFilterSampleLayerCubic}
|
|
10
|
+
*/
|
|
11
|
+
static from(layer) {
|
|
12
|
+
assert.typeOf(layer, 'string', 'layer');
|
|
13
|
+
|
|
14
|
+
const r = new CellFilterSampleLayerCubic();
|
|
15
|
+
|
|
16
|
+
r.layerId = layer;
|
|
17
|
+
|
|
18
|
+
return r;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
execute(grid, x, y, rotation) {
|
|
22
|
+
|
|
23
|
+
//convert to UV
|
|
24
|
+
const sampler_x = x * this.__u_scale;
|
|
25
|
+
const sampler_y = y * this.__v_scale;
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @type {Sampler2D}
|
|
31
|
+
*/
|
|
32
|
+
const sampler = this.__sampler;
|
|
33
|
+
|
|
34
|
+
return sampler.sampleChannelBicubic(sampler_x, sampler_y, 0);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { AbstractCellFilterSampleGridLayer } from "./AbstractCellFilterSampleGridLayer.js";
|
|
3
|
+
|
|
4
|
+
export class CellFilterSampleLayerLinear extends AbstractCellFilterSampleGridLayer {
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {string} layer
|
|
9
|
+
* @returns {CellFilterSampleLayerLinear}
|
|
10
|
+
*/
|
|
11
|
+
static from(layer) {
|
|
12
|
+
assert.typeOf(layer, 'string', 'layer');
|
|
13
|
+
|
|
14
|
+
const r = new CellFilterSampleLayerLinear();
|
|
15
|
+
|
|
16
|
+
r.layerId = layer;
|
|
17
|
+
|
|
18
|
+
return r;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
execute(grid, x, y, rotation) {
|
|
22
|
+
|
|
23
|
+
//convert to UV
|
|
24
|
+
const sampler_x = x * this.__u_scale;
|
|
25
|
+
const sampler_y = y * this.__v_scale;
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @type {Sampler2D}
|
|
31
|
+
*/
|
|
32
|
+
const sampler = this.__sampler;
|
|
33
|
+
|
|
34
|
+
const channel_value = sampler.sampleChannelBilinear(sampler_x, sampler_y, 0);
|
|
35
|
+
|
|
36
|
+
assert.notNaN(channel_value, 'channel_value');
|
|
37
|
+
|
|
38
|
+
return channel_value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
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
|
-
import { MarkerMatchCounter } from "./MarkerMatchCounter.js";
|
|
5
4
|
import { max2 } from "../../core/math/max2.js";
|
|
5
|
+
import { qt_collect_by_circle } from "../../core/geom/2d/quad-tree/qt_collect_by_circle.js";
|
|
6
|
+
import { v2_length_sqr } from "../../core/geom/Vector2.js";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @type {QuadTreeDatum<MarkerNode>[]}
|
|
11
|
+
*/
|
|
12
|
+
const marker_collection = [];
|
|
8
13
|
|
|
9
14
|
export class GridData {
|
|
10
15
|
constructor() {
|
|
@@ -78,34 +83,6 @@ export class GridData {
|
|
|
78
83
|
return undefined;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
/**
|
|
82
|
-
*
|
|
83
|
-
* @param {MarkerNode[]} result
|
|
84
|
-
* @param {number} x
|
|
85
|
-
* @param {number} y
|
|
86
|
-
* @param {number} radius
|
|
87
|
-
* @param {MarkerNodeMatcher} matcher
|
|
88
|
-
* @returns {number} match count
|
|
89
|
-
*/
|
|
90
|
-
queryMarkersInCircle(result, x, y, radius, matcher) {
|
|
91
|
-
let count = 0;
|
|
92
|
-
this.markers.traverseCircleIntersections(x, y, this.radius, leaf => {
|
|
93
|
-
/**
|
|
94
|
-
*
|
|
95
|
-
* @type {MarkerNode}
|
|
96
|
-
*/
|
|
97
|
-
const marker = leaf.data;
|
|
98
|
-
|
|
99
|
-
if (matcher.match(marker)) {
|
|
100
|
-
result.push(marker);
|
|
101
|
-
|
|
102
|
-
count++;
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
return count;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
86
|
/**
|
|
110
87
|
*
|
|
111
88
|
* @param {number} x
|
|
@@ -127,12 +104,34 @@ export class GridData {
|
|
|
127
104
|
* @returns {number}
|
|
128
105
|
*/
|
|
129
106
|
countMarkerInCircle(x, y, radius, matcher) {
|
|
130
|
-
|
|
131
|
-
|
|
107
|
+
const match_count = qt_collect_by_circle(marker_collection, 0, this.markers, x, y, radius);
|
|
108
|
+
|
|
109
|
+
let result = 0;
|
|
110
|
+
|
|
111
|
+
for (let i = 0; i < match_count; i++) {
|
|
112
|
+
const marker_datum = marker_collection[i];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
* @type {MarkerNode|null}
|
|
117
|
+
*/
|
|
118
|
+
const marker = marker_datum.data;
|
|
119
|
+
|
|
120
|
+
const distance_limit = radius + marker.size;
|
|
121
|
+
|
|
122
|
+
const distance_limit_sqr = distance_limit * distance_limit;
|
|
123
|
+
|
|
124
|
+
// check refined containment
|
|
125
|
+
if (v2_length_sqr(x - marker.position.x, y - marker.position.y) > distance_limit_sqr) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
132
128
|
|
|
133
|
-
|
|
129
|
+
if (matcher.match(marker)) {
|
|
130
|
+
result++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
134
133
|
|
|
135
|
-
return
|
|
134
|
+
return result;
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
/**
|
|
@@ -171,8 +170,8 @@ export class GridData {
|
|
|
171
170
|
assert.isNumber(width, 'width');
|
|
172
171
|
assert.isNumber(height, 'height');
|
|
173
172
|
|
|
174
|
-
assert.isNonNegativeInteger(width,'width');
|
|
175
|
-
assert.isNonNegativeInteger(height,'height');
|
|
173
|
+
assert.isNonNegativeInteger(width, 'width');
|
|
174
|
+
assert.isNonNegativeInteger(height, 'height');
|
|
176
175
|
|
|
177
176
|
assert.isFiniteNumber(width, 'width');
|
|
178
177
|
assert.isFiniteNumber(height, 'width');
|
|
@@ -5,7 +5,7 @@ export class MarkerMatchCounter {
|
|
|
5
5
|
constructor() {
|
|
6
6
|
/**
|
|
7
7
|
* Predicate
|
|
8
|
-
* @type {
|
|
8
|
+
* @type {MarkerNodeMatcher|null}
|
|
9
9
|
*/
|
|
10
10
|
this.matcher = null;
|
|
11
11
|
this.count = 0;
|
|
@@ -13,10 +13,12 @@ export class MarkerMatchCounter {
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
*
|
|
16
|
-
* @param {QuadTreeDatum<
|
|
16
|
+
* @param {QuadTreeDatum<MarkerNode>} node
|
|
17
17
|
*/
|
|
18
18
|
exec(node) {
|
|
19
|
-
|
|
19
|
+
const marker = node.data;
|
|
20
|
+
|
|
21
|
+
if (this.matcher.match(marker)) {
|
|
20
22
|
this.count++;
|
|
21
23
|
}
|
|
22
24
|
}
|
|
@@ -43,11 +43,6 @@ export class GridActionRuleSet {
|
|
|
43
43
|
*/
|
|
44
44
|
this.matchOrigin = true;
|
|
45
45
|
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @type {boolean}
|
|
49
|
-
*/
|
|
50
|
-
this.allowEveryRotation = false;
|
|
51
46
|
}
|
|
52
47
|
|
|
53
48
|
/**
|
|
@@ -58,16 +53,20 @@ export class GridActionRuleSet {
|
|
|
58
53
|
* @param {boolean} [allowEveryRotation]
|
|
59
54
|
* @returns {GridActionRuleSet}
|
|
60
55
|
*/
|
|
61
|
-
static from({ rules, policy = RuleSelectionPolicyType.Sequential, pattern = [0, 0], allowEveryRotation
|
|
56
|
+
static from({ rules, policy = RuleSelectionPolicyType.Sequential, pattern = [0, 0], allowEveryRotation }) {
|
|
62
57
|
assert.enum(policy, RuleSelectionPolicyType, 'policy');
|
|
63
|
-
assert.
|
|
58
|
+
assert.isArray(rules, 'rules');
|
|
59
|
+
assert.isArray(pattern, 'pattern');
|
|
64
60
|
|
|
65
61
|
const r = new GridActionRuleSet();
|
|
66
62
|
|
|
67
63
|
rules.forEach(r.add, r);
|
|
68
64
|
r.policy = policy;
|
|
69
65
|
r.pattern = pattern;
|
|
70
|
-
|
|
66
|
+
|
|
67
|
+
if (allowEveryRotation !== undefined) {
|
|
68
|
+
console.warn('.allowEveryRotation is deprecated');
|
|
69
|
+
}
|
|
71
70
|
|
|
72
71
|
return r;
|
|
73
72
|
}
|
|
@@ -122,7 +121,6 @@ export class GridActionRuleSet {
|
|
|
122
121
|
const patternSize = pattern.length;
|
|
123
122
|
|
|
124
123
|
const matchOrigin = this.matchOrigin;
|
|
125
|
-
const allowEveryRotation = this.allowEveryRotation;
|
|
126
124
|
|
|
127
125
|
const sampleCountX = width * resolution;
|
|
128
126
|
const sampleCountY = height * resolution;
|
|
@@ -160,30 +158,17 @@ export class GridActionRuleSet {
|
|
|
160
158
|
const sampleOffsetX = pattern[sampleIndex++];
|
|
161
159
|
const sampleOffsetY = pattern[sampleIndex++];
|
|
162
160
|
|
|
161
|
+
const ROTATION_COUNT = element.allowRotation ? 4 : 1;
|
|
163
162
|
|
|
164
|
-
let
|
|
165
|
-
let final_sample_offset_y = sampleOffsetY;
|
|
166
|
-
|
|
167
|
-
rotation_loop: for (let j = 0; j < 4; j++) {
|
|
168
|
-
|
|
163
|
+
for (let j = 0; j < ROTATION_COUNT; j++) {
|
|
169
164
|
|
|
170
165
|
const rotation = j * PI_HALF;
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
break rotation_loop;
|
|
175
|
-
} else {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const sin = Math.sin(rotation);
|
|
179
|
-
const cos = Math.cos(rotation);
|
|
167
|
+
const sin = Math.sin(rotation);
|
|
168
|
+
const cos = Math.cos(rotation);
|
|
180
169
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
}
|
|
170
|
+
const final_sample_offset_x = sampleOffsetX * cos - sampleOffsetY * sin;
|
|
171
|
+
const final_sample_offset_y = sampleOffsetX * sin + sampleOffsetY * cos;
|
|
187
172
|
|
|
188
173
|
const p_x = final_sample_offset_x + x;
|
|
189
174
|
const p_y = final_sample_offset_y + y;
|
|
@@ -198,7 +183,7 @@ export class GridActionRuleSet {
|
|
|
198
183
|
}
|
|
199
184
|
|
|
200
185
|
if (!match) {
|
|
201
|
-
continue
|
|
186
|
+
continue;
|
|
202
187
|
}
|
|
203
188
|
|
|
204
189
|
const roll = random();
|
|
@@ -209,9 +194,7 @@ export class GridActionRuleSet {
|
|
|
209
194
|
|
|
210
195
|
element.execute(grid, p_x, p_y, rotation);
|
|
211
196
|
|
|
212
|
-
|
|
213
|
-
break sampling_loop;
|
|
214
|
-
}
|
|
197
|
+
break sampling_loop;
|
|
215
198
|
}
|
|
216
199
|
|
|
217
200
|
}
|
|
@@ -3,6 +3,7 @@ import { MarkerNode } from "./MarkerNode.js";
|
|
|
3
3
|
import { Transform } from "../../engine/ecs/transform/Transform.js";
|
|
4
4
|
import Vector2 from "../../core/geom/Vector2.js";
|
|
5
5
|
import { assert } from "../../core/assert.js";
|
|
6
|
+
import Vector3 from "../../core/geom/Vector3.js";
|
|
6
7
|
|
|
7
8
|
export class GridCellActionPlaceMarker extends GridCellAction {
|
|
8
9
|
constructor() {
|
|
@@ -180,16 +181,17 @@ export class GridCellActionPlaceMarker extends GridCellAction {
|
|
|
180
181
|
target_y * transform.scale_y + transform.offset_y
|
|
181
182
|
);
|
|
182
183
|
|
|
183
|
-
node.transform.rotation.
|
|
184
|
+
node.transform.rotation.fromAxisAngle(Vector3.down, rotation);
|
|
184
185
|
|
|
185
186
|
node.transform.multiplyTransforms(node.transform, this.transform);
|
|
186
187
|
|
|
187
188
|
//add tags
|
|
188
189
|
const tags = this.tags;
|
|
189
|
-
const
|
|
190
|
-
|
|
190
|
+
const tag_count = tags.length;
|
|
191
|
+
const node_tags = node.tags;
|
|
192
|
+
for (let i = 0; i < tag_count; i++) {
|
|
191
193
|
const tag = tags[i];
|
|
192
|
-
|
|
194
|
+
node_tags.push(tag);
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
//write properties
|
|
@@ -199,13 +201,9 @@ export class GridCellActionPlaceMarker extends GridCellAction {
|
|
|
199
201
|
|
|
200
202
|
//apply transformations
|
|
201
203
|
const transformers = this.transformers;
|
|
202
|
-
const
|
|
204
|
+
const transformer_count = transformers.length;
|
|
203
205
|
|
|
204
|
-
|
|
205
|
-
debugger;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
for (let i = 0; i < transformerCount; i++) {
|
|
206
|
+
for (let i = 0; i < transformer_count; i++) {
|
|
209
207
|
const transformer = transformers[i];
|
|
210
208
|
node = transformer.transform(node, data);
|
|
211
209
|
}
|
|
@@ -51,8 +51,14 @@ function CircleGeometry(radius, arc) {
|
|
|
51
51
|
* @param {GridData} grid
|
|
52
52
|
* @param {EntityComponentDataset} ecd
|
|
53
53
|
* @param {MarkerNodeMatcher} marker_filter
|
|
54
|
+
* @param {boolean} [display_data]
|
|
54
55
|
*/
|
|
55
|
-
export function visualizeMarkers({
|
|
56
|
+
export function visualizeMarkers({
|
|
57
|
+
grid,
|
|
58
|
+
ecd,
|
|
59
|
+
marker_filter = MarkerNodeMatcherAny.INSTANCE,
|
|
60
|
+
display_data = true
|
|
61
|
+
}) {
|
|
56
62
|
|
|
57
63
|
/**
|
|
58
64
|
*
|
|
@@ -85,7 +91,8 @@ export function visualizeMarkers({ grid, ecd, marker_filter = MarkerNodeMatcherA
|
|
|
85
91
|
*/
|
|
86
92
|
const terrain = obtainTerrain(ecd);
|
|
87
93
|
|
|
88
|
-
const
|
|
94
|
+
const marker_radius = 0.05;
|
|
95
|
+
const geometry_0 = new TetrahedronBufferGeometry(marker_radius, 2);
|
|
89
96
|
|
|
90
97
|
const geometry_cylinder = CircleGeometry(1, 1);
|
|
91
98
|
|
|
@@ -110,63 +117,76 @@ export function visualizeMarkers({ grid, ecd, marker_filter = MarkerNodeMatcherA
|
|
|
110
117
|
mark_1.position.copy(markerNode.transform.position);
|
|
111
118
|
mark_1.position.sub(v3);
|
|
112
119
|
|
|
113
|
-
const line_geometry = new BufferGeometry();
|
|
114
|
-
line_geometry.setFromPoints([
|
|
115
|
-
mark_0.position,
|
|
116
|
-
mark_1.position
|
|
117
|
-
]);
|
|
118
|
-
|
|
119
|
-
const mark_line = new Line(line_geometry, m_line);
|
|
120
|
-
|
|
121
|
-
|
|
122
120
|
const mark_size = new Line(geometry_cylinder, m3);
|
|
123
121
|
mark_size.scale.set(markerNode.size, markerNode.size, markerNode.size);
|
|
124
122
|
|
|
125
123
|
|
|
126
124
|
g.add(mark_0);
|
|
127
|
-
|
|
125
|
+
|
|
126
|
+
if (mark_1.position.distanceToSquared(mark_0.position) > marker_radius * marker_radius * 0.2) {
|
|
127
|
+
// only draw second marker if they are sufficiently far apart
|
|
128
|
+
|
|
129
|
+
const line_geometry = new BufferGeometry();
|
|
130
|
+
line_geometry.setFromPoints([
|
|
131
|
+
mark_0.position,
|
|
132
|
+
mark_1.position
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
const mark_line = new Line(line_geometry, m_line);
|
|
136
|
+
|
|
137
|
+
g.add(mark_1);
|
|
138
|
+
g.add(mark_line);
|
|
139
|
+
}
|
|
140
|
+
|
|
128
141
|
g.add(mark_size);
|
|
129
|
-
|
|
142
|
+
|
|
143
|
+
const entityBuilder = new EntityBuilder();
|
|
130
144
|
|
|
131
145
|
const renderable = new Renderable(g);
|
|
132
146
|
renderable.computeBoundsFromObject();
|
|
133
147
|
|
|
134
|
-
|
|
148
|
+
if (display_data) {
|
|
149
|
+
const props = [];
|
|
135
150
|
|
|
136
|
-
|
|
151
|
+
props.push(`TYPE: ${markerNode.type}`);
|
|
137
152
|
|
|
138
|
-
|
|
139
|
-
|
|
153
|
+
for (const propertyKey in markerNode.properties) {
|
|
154
|
+
let propValue = formatValue(markerNode.properties[propertyKey]);
|
|
140
155
|
|
|
141
|
-
|
|
142
|
-
|
|
156
|
+
props.push(`${propertyKey}:${propValue}`);
|
|
157
|
+
}
|
|
143
158
|
|
|
144
|
-
|
|
145
|
-
|
|
159
|
+
props.push(`# [x: ${formatValue(markerNode.position.x)}, y: ${formatValue(markerNode.position.y)}]`);
|
|
160
|
+
props.push(`# [size: ${formatValue(markerNode.size)}]`);
|
|
146
161
|
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
for (let j = 0; j < markerNode.tags.length; j++) {
|
|
163
|
+
const tag = markerNode.tags[j];
|
|
149
164
|
|
|
150
|
-
|
|
151
|
-
|
|
165
|
+
props.push(`# T: ${tag}`);
|
|
166
|
+
}
|
|
152
167
|
|
|
153
168
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
const v = new LabelView(props.join('\n'), { classList: ['__debug-plaque'] });
|
|
170
|
+
v.css({
|
|
171
|
+
position: 'absolute',
|
|
172
|
+
whiteSpace: 'pre',
|
|
173
|
+
left: 0,
|
|
174
|
+
top: 0
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
entityBuilder
|
|
178
|
+
.add(new HeadsUpDisplay())
|
|
179
|
+
.add(new ViewportPosition())
|
|
180
|
+
.add(GUIElement.fromView(v))
|
|
181
|
+
;
|
|
182
|
+
}
|
|
161
183
|
|
|
162
184
|
const t = new Transform();
|
|
163
185
|
|
|
164
186
|
t.position.copy(v3);
|
|
165
187
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
.add(new ViewportPosition())
|
|
169
|
-
.add(GUIElement.fromView(v))
|
|
188
|
+
|
|
189
|
+
entityBuilder
|
|
170
190
|
.add(renderable)
|
|
171
191
|
.add(t)
|
|
172
192
|
.build(ecd);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MarkerNodeEmitter } from "./MarkerNodeEmitter.js";
|
|
2
2
|
import { assert } from "../../../core/assert.js";
|
|
3
3
|
|
|
4
|
-
export class MarkerNodeEmitterFromAction extends MarkerNodeEmitter{
|
|
4
|
+
export class MarkerNodeEmitterFromAction extends MarkerNodeEmitter {
|
|
5
5
|
constructor() {
|
|
6
6
|
super();
|
|
7
7
|
|
|
@@ -18,8 +18,8 @@ export class MarkerNodeEmitterFromAction extends MarkerNodeEmitter{
|
|
|
18
18
|
* @param {GridCellActionPlaceMarker[]} actions
|
|
19
19
|
* @return {MarkerNodeEmitterFromAction}
|
|
20
20
|
*/
|
|
21
|
-
static from(actions){
|
|
22
|
-
assert.isArray(actions,'actions');
|
|
21
|
+
static from(actions) {
|
|
22
|
+
assert.isArray(actions, 'actions');
|
|
23
23
|
|
|
24
24
|
for (let i = 0; i < actions.length; i++) {
|
|
25
25
|
|
|
@@ -27,11 +27,11 @@ assert.isArray(actions,'actions');
|
|
|
27
27
|
assert.equal(action.isGridCellActionPlaceMarker, true, 'action.isGridCellActionPlaceMarker !== true');
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
const r = new MarkerNodeEmitterFromAction();
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
r.actions = actions;
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
return r;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
initialize(data, seed) {
|
|
@@ -41,7 +41,7 @@ assert.isArray(actions,'actions');
|
|
|
41
41
|
for (let i = 0; i < n; i++) {
|
|
42
42
|
const action = actions[i];
|
|
43
43
|
|
|
44
|
-
action.initialize(data,seed);
|
|
44
|
+
action.initialize(data, seed);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -54,7 +54,7 @@ assert.isArray(actions,'actions');
|
|
|
54
54
|
|
|
55
55
|
const action = actions[i];
|
|
56
56
|
|
|
57
|
-
const node = action.buildNode(data,x,y,rotation);
|
|
57
|
+
const node = action.buildNode(data, x, y, rotation);
|
|
58
58
|
|
|
59
59
|
consumer.consume(node);
|
|
60
60
|
|