@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,118 @@
|
|
|
1
|
+
import { Action } from "../../../core/process/undo/Action.js";
|
|
2
|
+
import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
|
|
3
|
+
|
|
4
|
+
export class ModifyPatchSampler2DAction extends Action {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {Sampler2D} sampler
|
|
8
|
+
* @param {number[]} bounds
|
|
9
|
+
*/
|
|
10
|
+
constructor(sampler, bounds) {
|
|
11
|
+
super();
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @type {Sampler2D}
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
this.__sampler = sampler;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @type {number[]}
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
this.__bounds = bounds;
|
|
26
|
+
|
|
27
|
+
const width = this.__bounds[2] - this.__bounds[0];
|
|
28
|
+
const height = this.__bounds[3] - this.__bounds[1];
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @type {Sampler2D}
|
|
33
|
+
*/
|
|
34
|
+
this.__patch_new = Sampler2D.float32(sampler.itemSize, width, height);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @type {Sampler2D}
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
this.__patch_old = Sampler2D.float32(sampler.itemSize, width, height);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get patch() {
|
|
45
|
+
return this.__patch_new;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get x() {
|
|
49
|
+
return this.__bounds[0];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get y() {
|
|
53
|
+
return this.__bounds[1];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param {number} x coordinate in global space
|
|
59
|
+
* @param {number} y coordinate in global space
|
|
60
|
+
* @param {number} [channel]
|
|
61
|
+
* @returns {number} delta between original value and the new one after the change
|
|
62
|
+
*/
|
|
63
|
+
computeDelta(x, y, channel = 0) {
|
|
64
|
+
const _x = x - this.x;
|
|
65
|
+
|
|
66
|
+
if (_x < 0 || _x > this.__patch_new.width - 1) {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const _y = y - this.y;
|
|
71
|
+
|
|
72
|
+
if (_y < 0 || _y > this.__patch_new.height - 1) {
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const value_old = this.__patch_old.sampleChannelBilinear(_x, _y, channel);
|
|
77
|
+
const value_new = this.__patch_new.sampleChannelBilinear(_x, _y, channel);
|
|
78
|
+
|
|
79
|
+
return value_new - value_old;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
computeByteSize() {
|
|
83
|
+
return this.__patch_new.computeByteSize() + this.__patch_old.computeByteSize() + 280;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
async apply(context) {
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @type {Sampler2D}
|
|
92
|
+
*/
|
|
93
|
+
const source = this.__sampler;
|
|
94
|
+
|
|
95
|
+
//store old data from the patch
|
|
96
|
+
const patch_old = this.__patch_old;
|
|
97
|
+
|
|
98
|
+
patch_old.copy_sameItemSize(source, this.x, this.y, 0, 0, patch_old.width, patch_old.height);
|
|
99
|
+
|
|
100
|
+
const patch_new = this.__patch_new;
|
|
101
|
+
|
|
102
|
+
//apply the patch
|
|
103
|
+
source.copy_sameItemSize(patch_new, 0, 0, this.x, this.y, patch_new.width, patch_new.height);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async revert(context) {
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @type {Sampler2D}
|
|
110
|
+
*/
|
|
111
|
+
const source = this.__sampler;
|
|
112
|
+
|
|
113
|
+
const patch_old = this.__patch_old;
|
|
114
|
+
|
|
115
|
+
//apply the patch
|
|
116
|
+
source.copy_sameItemSize(patch_old, 0, 0, this.x, this.y, patch_old.width, patch_old.height);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ModifyPatchSampler2DAction } from "./ModifyPatchSampler2DAction.js";
|
|
2
|
+
import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
|
|
3
|
+
|
|
4
|
+
test("apply patch size 0", async () => {
|
|
5
|
+
const sampler = Sampler2D.uint8(1, 1, 1);
|
|
6
|
+
sampler.data[0] = 123;
|
|
7
|
+
|
|
8
|
+
const action = new ModifyPatchSampler2DAction(sampler, [0, 0, 0, 0]);
|
|
9
|
+
|
|
10
|
+
await action.apply();
|
|
11
|
+
|
|
12
|
+
expect([...sampler.data]).toEqual([123]);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("apply patch size 1, fill entire", async () => {
|
|
16
|
+
const sampler = Sampler2D.uint8(1, 1, 1);
|
|
17
|
+
sampler.data[0] = 123;
|
|
18
|
+
|
|
19
|
+
const action = new ModifyPatchSampler2DAction(sampler, [0, 0, 1, 1]);
|
|
20
|
+
|
|
21
|
+
action.patch.data[0] = 42;
|
|
22
|
+
|
|
23
|
+
await action.apply();
|
|
24
|
+
|
|
25
|
+
expect([...sampler.data]).toEqual([42]);
|
|
26
|
+
|
|
27
|
+
await action.revert();
|
|
28
|
+
|
|
29
|
+
expect([...sampler.data]).toEqual([123]);
|
|
30
|
+
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
|
|
1
|
+
import { ModifyPatchSampler2DAction } from "./ModifyPatchSampler2DAction.js";
|
|
3
2
|
|
|
4
|
-
export class PatchTerrainHeightAction extends
|
|
3
|
+
export class PatchTerrainHeightAction extends ModifyPatchSampler2DAction {
|
|
5
4
|
/**
|
|
6
5
|
*
|
|
7
6
|
* @param {Terrain} terrain
|
|
@@ -11,64 +10,25 @@ export class PatchTerrainHeightAction extends Action {
|
|
|
11
10
|
* @param {number} height
|
|
12
11
|
*/
|
|
13
12
|
constructor(terrain, x, y, width, height) {
|
|
14
|
-
super();
|
|
13
|
+
super(terrain.samplerHeight, [x, y, x + width, y + height]);
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
*
|
|
18
17
|
* @type {Terrain}
|
|
19
18
|
*/
|
|
20
19
|
this.terrain = terrain;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @type {Sampler2D}
|
|
25
|
-
*/
|
|
26
|
-
this.patch = Sampler2D.float32(1, width, height);
|
|
27
|
-
|
|
28
|
-
this.x = x;
|
|
29
|
-
this.y = y;
|
|
30
|
-
|
|
31
|
-
this.__oldPatch = Sampler2D.float32(1, width, height);
|
|
32
20
|
}
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* @param {number} x
|
|
37
|
-
* @param {number} y
|
|
38
|
-
* @returns {number}
|
|
39
|
-
*/
|
|
40
|
-
computeDelta(x, y) {
|
|
41
|
-
|
|
42
|
-
const _x = x - this.x;
|
|
43
|
-
|
|
44
|
-
if (_x < 0 || _x > this.patch.width - 1) {
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const _y = y - this.y;
|
|
49
|
-
|
|
50
|
-
if (_y < 0 || _y > this.patch.height - 1) {
|
|
51
|
-
return 0;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const sourceValue = this.__oldPatch.sampleChannelBilinear(_x, _y, 0);
|
|
55
|
-
const targetValue = this.patch.sampleChannelBilinear(_x, _y, 0);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return targetValue - sourceValue;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
computeByteSize() {
|
|
62
|
-
return this.patch.computeByteSize() + this.__oldPatch.computeByteSize() + 280;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
updateTerrain() {
|
|
22
|
+
async updateTerrain() {
|
|
66
23
|
/**
|
|
67
24
|
*
|
|
68
25
|
* @type {Terrain}
|
|
69
26
|
*/
|
|
70
27
|
const terrain = this.terrain;
|
|
71
28
|
|
|
29
|
+
terrain.updateHeightTexture();
|
|
30
|
+
terrain.updateWorkerHeights();
|
|
31
|
+
|
|
72
32
|
/**
|
|
73
33
|
*
|
|
74
34
|
* @type {Sampler2D}
|
|
@@ -81,10 +41,6 @@ export class PatchTerrainHeightAction extends Action {
|
|
|
81
41
|
*/
|
|
82
42
|
const tiles = terrain.__tiles;
|
|
83
43
|
|
|
84
|
-
tiles.buildWorker.setHeightSampler(heightMap.data, heightMap.itemSize, heightMap.width, heightMap.height);
|
|
85
|
-
|
|
86
|
-
const terrainSize = terrain.size;
|
|
87
|
-
|
|
88
44
|
const x = this.x;
|
|
89
45
|
const y = this.y;
|
|
90
46
|
|
|
@@ -94,66 +50,18 @@ export class PatchTerrainHeightAction extends Action {
|
|
|
94
50
|
const v0 = y / heightMap.height;
|
|
95
51
|
const v1 = (y + this.patch.height) / heightMap.height;
|
|
96
52
|
|
|
97
|
-
|
|
98
|
-
const tx1 = u1 * terrainSize.x;
|
|
99
|
-
|
|
100
|
-
const ty0 = v0 * terrainSize.y;
|
|
101
|
-
const ty1 = v1 * terrainSize.y;
|
|
102
|
-
|
|
103
|
-
const dirtyTiles = tiles.getRawTilesOverlappingRectangle(tx0 - 1, ty0 - 1, tx1 + 1, ty1 + 1);
|
|
104
|
-
|
|
105
|
-
dirtyTiles.forEach(tile => {
|
|
106
|
-
tile.isBuilt = false;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
terrain.heightTexture.needsUpdate = true;
|
|
53
|
+
tiles.rebuildTilesByUV(u0, v0, u1, v1);
|
|
110
54
|
}
|
|
111
55
|
|
|
112
56
|
async apply(context) {
|
|
57
|
+
await super.apply(context);
|
|
113
58
|
|
|
114
|
-
|
|
115
|
-
*
|
|
116
|
-
* @type {Terrain}
|
|
117
|
-
*/
|
|
118
|
-
const terrain = this.terrain;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
*
|
|
122
|
-
* @type {Sampler2D}
|
|
123
|
-
*/
|
|
124
|
-
const heightMap = terrain.heightMap;
|
|
125
|
-
|
|
126
|
-
//store old data from the patch
|
|
127
|
-
const oldPatch = this.__oldPatch;
|
|
128
|
-
|
|
129
|
-
oldPatch.copy_sameItemSize(heightMap, this.x, this.y, 0, 0, oldPatch.width, oldPatch.height);
|
|
130
|
-
|
|
131
|
-
const patch = this.patch;
|
|
132
|
-
//apply the patch
|
|
133
|
-
heightMap.copy_sameItemSize(patch, 0, 0, this.x, this.y, patch.width, patch.height);
|
|
134
|
-
|
|
135
|
-
this.updateTerrain();
|
|
59
|
+
await this.updateTerrain();
|
|
136
60
|
}
|
|
137
61
|
|
|
138
62
|
async revert(context) {
|
|
63
|
+
await super.revert(context);
|
|
139
64
|
|
|
140
|
-
|
|
141
|
-
*
|
|
142
|
-
* @type {Terrain}
|
|
143
|
-
*/
|
|
144
|
-
const terrain = this.terrain;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
*
|
|
148
|
-
* @type {Sampler2D}
|
|
149
|
-
*/
|
|
150
|
-
const heightMap = terrain.heightMap;
|
|
151
|
-
|
|
152
|
-
const patch = this.__oldPatch;
|
|
153
|
-
|
|
154
|
-
//apply the patch
|
|
155
|
-
heightMap.copy_sameItemSize(patch, 0, 0, this.x, this.y, patch.width, patch.height);
|
|
156
|
-
|
|
157
|
-
this.updateTerrain();
|
|
65
|
+
await this.updateTerrain();
|
|
158
66
|
}
|
|
159
67
|
}
|
|
@@ -67,6 +67,19 @@ function isReservedField(object, field_name) {
|
|
|
67
67
|
return false;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
*
|
|
72
|
+
* @type {string[]}
|
|
73
|
+
*/
|
|
74
|
+
const reserved_prototype_names = [
|
|
75
|
+
"constructor"
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const reserved_prototypes = [
|
|
79
|
+
Object,
|
|
80
|
+
Object.prototype
|
|
81
|
+
];
|
|
82
|
+
|
|
70
83
|
/**
|
|
71
84
|
*
|
|
72
85
|
* @param {Object} object
|
|
@@ -101,48 +114,58 @@ function extract_object_fields_reflection(object, result, object_proto) {
|
|
|
101
114
|
result.push(descriptor);
|
|
102
115
|
}
|
|
103
116
|
|
|
104
|
-
|
|
117
|
+
if (!reserved_prototypes.includes(object_proto)) {
|
|
105
118
|
|
|
106
|
-
|
|
107
|
-
const d = descriptors[d_name];
|
|
119
|
+
const descriptors = Object.getOwnPropertyDescriptors(object_proto);
|
|
108
120
|
|
|
109
|
-
|
|
121
|
+
for (let d_name in descriptors) {
|
|
110
122
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
123
|
+
if (reserved_prototype_names.includes(d_name)) {
|
|
124
|
+
// reserved name, skip
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
114
127
|
|
|
115
|
-
|
|
116
|
-
adapter.writable = false;
|
|
117
|
-
}
|
|
128
|
+
const d = descriptors[d_name];
|
|
118
129
|
|
|
119
|
-
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
130
|
+
const adapter = new FieldValueAdapter();
|
|
122
131
|
|
|
132
|
+
if (d.get === undefined && d.value === undefined) {
|
|
133
|
+
adapter.readable = false;
|
|
134
|
+
}
|
|
123
135
|
|
|
124
|
-
|
|
136
|
+
if (d.get !== undefined && d.set === undefined) {
|
|
137
|
+
adapter.writable = false;
|
|
138
|
+
}
|
|
125
139
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
console.warn(e);
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
140
|
+
if (!adapter.readable) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
132
143
|
|
|
133
|
-
const field_type = objectToClass(field_value);
|
|
134
144
|
|
|
135
|
-
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
145
|
+
let field_value;
|
|
138
146
|
|
|
139
|
-
|
|
147
|
+
try {
|
|
148
|
+
field_value = adapter.read(object, d_name);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
console.warn(e);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
140
153
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
const field_type = objectToClass(field_value);
|
|
155
|
+
|
|
156
|
+
if (field_type === undefined) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const descriptor = new FieldDescriptor();
|
|
161
|
+
|
|
162
|
+
descriptor.name = d_name;
|
|
163
|
+
descriptor.type = field_type;
|
|
164
|
+
descriptor.adapter = adapter;
|
|
165
|
+
|
|
166
|
+
result.push(descriptor);
|
|
167
|
+
}
|
|
144
168
|
|
|
145
|
-
result.push(descriptor);
|
|
146
169
|
}
|
|
147
170
|
}
|
|
148
171
|
|
|
@@ -153,6 +176,7 @@ function extract_object_fields_reflection(object, result, object_proto) {
|
|
|
153
176
|
* @returns {FieldDescriptor[]}
|
|
154
177
|
*/
|
|
155
178
|
function extractObjectFields(object, registry) {
|
|
179
|
+
|
|
156
180
|
const result = [];
|
|
157
181
|
|
|
158
182
|
const object_proto = Object.getPrototypeOf(object);
|
|
@@ -11,49 +11,96 @@ import { DataType } from "../../../../core/collection/table/DataType.js";
|
|
|
11
11
|
import { min2 } from "../../../../core/math/min2.js";
|
|
12
12
|
import { max2 } from "../../../../core/math/max2.js";
|
|
13
13
|
import { isTypedArray } from "../../../../core/collection/array/typed/isTypedArray.js";
|
|
14
|
+
import { FrameRunner } from "../../../../engine/graphics/FrameRunner.js";
|
|
15
|
+
|
|
16
|
+
const UPDATE_DELAY = 200;
|
|
14
17
|
|
|
15
18
|
export class Sampler2DEditor extends TypeEditor {
|
|
16
19
|
build(parent, field, context) {
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* @type {Sampler2D}
|
|
19
23
|
*/
|
|
20
24
|
const sampler = field.adapter.read(parent, field.name);
|
|
21
25
|
|
|
22
|
-
let
|
|
26
|
+
let last_version = -1;
|
|
27
|
+
let last_update_time = 0;
|
|
28
|
+
let last_update_duration = 0;
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
30
|
+
const view = new CanvasView();
|
|
31
|
+
view.css({
|
|
32
|
+
background: 'black'
|
|
33
|
+
});
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
function draw() {
|
|
36
|
+
const draw_start_time = performance.now();
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
const result_sampler = new Sampler2D(new TypedArrayConstructor(sampler.itemSize * res * res), sampler.itemSize, res, res);
|
|
38
|
+
let dataType;
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
if (isTypedArray(sampler.data)) {
|
|
41
|
+
dataType = typedArrayToDataType(sampler.data);
|
|
42
|
+
} else {
|
|
43
|
+
dataType = DataType.Float32;
|
|
44
|
+
}
|
|
36
45
|
|
|
37
|
-
|
|
46
|
+
let TypedArrayConstructor = typedArrayConstructorByInstance(sampler.data);
|
|
47
|
+
|
|
48
|
+
if (TypedArrayConstructor === Uint8Array) {
|
|
49
|
+
// use clamped array to avoid filtering artifacts
|
|
50
|
+
TypedArrayConstructor = Uint8ClampedArray;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const res = 32;
|
|
54
|
+
const result_sampler = new Sampler2D(new TypedArrayConstructor(sampler.itemSize * res * res), sampler.itemSize, res, res);
|
|
55
|
+
|
|
56
|
+
scaleSampler2D(sampler, result_sampler);
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
let min = 0, max = 0;
|
|
60
|
+
if (dataType === DataType.Float32) {
|
|
61
|
+
min = Infinity;
|
|
62
|
+
max = -Infinity;
|
|
63
|
+
for (let i = 0; i < result_sampler.itemSize; i++) {
|
|
64
|
+
|
|
65
|
+
min = min2(min, result_sampler.computeMin(i).value)
|
|
66
|
+
max = max2(min, result_sampler.computeMax(i).value)
|
|
67
|
+
}
|
|
68
|
+
} else if (dataType === DataType.Uint8) {
|
|
69
|
+
min = 0;
|
|
70
|
+
max = 255;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const scale = 255 / (max - min);
|
|
74
|
+
const offset = min;
|
|
75
|
+
|
|
76
|
+
sampler2D2Canvas(result_sampler, scale, offset, view.el);
|
|
77
|
+
|
|
78
|
+
last_version = sampler.version;
|
|
79
|
+
|
|
80
|
+
const draw_end_time = performance.now();
|
|
81
|
+
last_update_duration = draw_end_time - draw_start_time;
|
|
82
|
+
|
|
83
|
+
last_update_time = draw_end_time;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
view.on.linked.add(try_update);
|
|
88
|
+
|
|
89
|
+
function try_update() {
|
|
90
|
+
if (sampler.version !== last_version) {
|
|
38
91
|
|
|
39
|
-
|
|
40
|
-
if (dataType === DataType.Float32) {
|
|
41
|
-
min = Infinity;
|
|
42
|
-
max = -Infinity;
|
|
43
|
-
for (let i = 0; i < result_sampler.itemSize; i++) {
|
|
92
|
+
const time_now = performance.now();
|
|
44
93
|
|
|
45
|
-
|
|
46
|
-
|
|
94
|
+
if ((time_now - last_update_time) >= UPDATE_DELAY) {
|
|
95
|
+
draw();
|
|
96
|
+
}
|
|
47
97
|
}
|
|
48
|
-
} else if (dataType === DataType.Uint8) {
|
|
49
|
-
min = 0;
|
|
50
|
-
max = 255;
|
|
51
98
|
}
|
|
52
99
|
|
|
53
|
-
const
|
|
54
|
-
const offset = min;
|
|
100
|
+
const frameRunner = new FrameRunner(try_update);
|
|
55
101
|
|
|
56
|
-
|
|
102
|
+
view.on.linked.add(frameRunner.startup, frameRunner);
|
|
103
|
+
view.on.unlinked.add(frameRunner.shutdown, frameRunner);
|
|
57
104
|
|
|
58
105
|
return view;
|
|
59
106
|
}
|
|
@@ -4,8 +4,49 @@ import { TerrainFlags } from "../../../../../../engine/ecs/terrain/ecs/TerrainFl
|
|
|
4
4
|
import { ImagePathEditor } from "../../ImagePathEditor.js";
|
|
5
5
|
import { EnumEditor } from "../../common/EnumEditor.js";
|
|
6
6
|
import { GridTransformKind } from "../../../../../../engine/ecs/terrain/ecs/GridTransformKind.js";
|
|
7
|
+
import { Texture } from "three";
|
|
7
8
|
|
|
8
9
|
export class TerrainEditor extends ObjectEditor {
|
|
10
|
+
build(parent, field, registry) {
|
|
11
|
+
const view = super.build(parent, field, registry);
|
|
12
|
+
|
|
13
|
+
if (view) {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {Terrain}
|
|
17
|
+
*/
|
|
18
|
+
const terrain = field.adapter.read(parent, field.name);
|
|
19
|
+
|
|
20
|
+
function updateLayers() {
|
|
21
|
+
|
|
22
|
+
terrain.layers.buildTexture();
|
|
23
|
+
terrain.layers.writeAllLayersDataIntoTexture();
|
|
24
|
+
|
|
25
|
+
terrain.updateMaterial();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// splats
|
|
29
|
+
view.bindSignal(terrain.layers.layers.on.added, () => {
|
|
30
|
+
terrain.splat.addWeightLayer();
|
|
31
|
+
updateLayers();
|
|
32
|
+
});
|
|
33
|
+
view.bindSignal(terrain.layers.layers.on.removed, (a, index) => {
|
|
34
|
+
terrain.splat.removeWeightLayer(index);
|
|
35
|
+
|
|
36
|
+
updateLayers();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// mapping sizes
|
|
40
|
+
view.bindSignal(terrain.splat.size.onChanged, (x, y) => {
|
|
41
|
+
terrain.splat.resize(x, y, terrain.splat.depth);
|
|
42
|
+
|
|
43
|
+
terrain.updateMaterial();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return view;
|
|
48
|
+
}
|
|
49
|
+
|
|
9
50
|
get schema() {
|
|
10
51
|
return {
|
|
11
52
|
properties: {
|
|
@@ -35,6 +76,12 @@ export class TerrainEditor extends ObjectEditor {
|
|
|
35
76
|
},
|
|
36
77
|
heightTexture: {
|
|
37
78
|
transient: true
|
|
79
|
+
},
|
|
80
|
+
buildLightMap: {
|
|
81
|
+
type: Function
|
|
82
|
+
},
|
|
83
|
+
aoMap: {
|
|
84
|
+
type: Texture
|
|
38
85
|
}
|
|
39
86
|
}
|
|
40
87
|
};
|
|
@@ -3,6 +3,12 @@ import ButtonView from "../../../../../view/elements/button/ButtonView.js";
|
|
|
3
3
|
|
|
4
4
|
export class FunctionEditor extends TypeEditor {
|
|
5
5
|
build(parent, field, registry) {
|
|
6
|
+
|
|
7
|
+
if (field.schema === undefined) {
|
|
8
|
+
// no schema, function editors are only available for explicit schema
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
6
12
|
/**
|
|
7
13
|
* @type {Function}
|
|
8
14
|
*/
|
|
@@ -13,8 +19,6 @@ export class FunctionEditor extends TypeEditor {
|
|
|
13
19
|
return undefined;
|
|
14
20
|
}
|
|
15
21
|
|
|
16
|
-
// TODO check that function takes no parameters maybe?
|
|
17
|
-
|
|
18
22
|
return new ButtonView({
|
|
19
23
|
action: () => {
|
|
20
24
|
v.call(parent);
|
|
@@ -270,7 +270,7 @@ export function pickingEntitySelection(point, engine, camera) {
|
|
|
270
270
|
*/
|
|
271
271
|
const sgm = em.getSystem(ShadedGeometrySystem);
|
|
272
272
|
|
|
273
|
-
if (sgm !== undefined) {
|
|
273
|
+
if (sgm !== undefined && sgm !== null) {
|
|
274
274
|
const hits = sgm.raycast(
|
|
275
275
|
source.x, source.y, source.y,
|
|
276
276
|
rayDirection.x, rayDirection.y, rayDirection.z
|