@woosh/meep-engine 2.43.23 → 2.43.25
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/3d/topology/struct/prototypeBinaryTopology.js +1 -1
- package/editor/Editor.js +3 -2
- package/engine/EngineHarness.js +25 -1
- package/engine/graphics/camera/camera_compute_distance_to_fit_length.js +7 -1
- package/engine/graphics/ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js +33 -0
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.d.ts +4 -1
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +16 -0
- package/engine/graphics/render/visibility/hiz/buffer/HierarchicalZBuffer.js +5 -1
- package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +6 -5
- package/engine/graphics/render/visibility/hiz/prototypeHiZ.js +9 -3
- package/engine/network/RemoteController.js +46 -6
- package/engine/network/remoteEditor.js +3 -0
- package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +1 -1
- package/package.json +1 -1
|
@@ -29,12 +29,12 @@ async function main() {
|
|
|
29
29
|
const index_array = lucy_geom.getIndex().array;
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
|
|
32
33
|
console.time('topo build - bin');
|
|
33
34
|
// console.profile('topo build - bin');
|
|
34
35
|
bt_index_geometry_to_topology(mesh, index_array, positions_array);
|
|
35
36
|
// console.profileEnd('topo build - bin');
|
|
36
37
|
console.timeEnd('topo build - bin');
|
|
37
|
-
|
|
38
38
|
//
|
|
39
39
|
// console.time('topo build - obj');
|
|
40
40
|
// topoMesh.build(positions_array, index_array);
|
package/editor/Editor.js
CHANGED
|
@@ -71,8 +71,8 @@ import { ObservedIntegerEditor } from "./ecs/component/editors/ObservedIntegerEd
|
|
|
71
71
|
|
|
72
72
|
import '../../../../css/editor/EntityEditorView.scss';
|
|
73
73
|
import '../../../../css/editor/EditorView.scss';
|
|
74
|
-
import {ParameterTrackSet} from "../engine/graphics/particles/particular/engine/parameter/ParameterTrackSet.js";
|
|
75
|
-
import {ParameterTrackSetEditor} from "./ecs/component/editors/ecs/ParameterTrackSetEditor.js";
|
|
74
|
+
import { ParameterTrackSet } from "../engine/graphics/particles/particular/engine/parameter/ParameterTrackSet.js";
|
|
75
|
+
import { ParameterTrackSetEditor } from "./ecs/component/editors/ecs/ParameterTrackSetEditor.js";
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* @template T
|
|
@@ -485,6 +485,7 @@ function Editor() {
|
|
|
485
485
|
resetSoundEmitterTracks(dataset);
|
|
486
486
|
|
|
487
487
|
const serializer = new BinaryBufferSerializer();
|
|
488
|
+
serializer.engine = self.engine;
|
|
488
489
|
serializer.registry = engine.binarySerializationRegistry;
|
|
489
490
|
|
|
490
491
|
const state = new EncodingBinaryBuffer();
|
package/engine/EngineHarness.js
CHANGED
|
@@ -29,6 +29,8 @@ import { noop } from "../core/function/Functions.js";
|
|
|
29
29
|
import SoundListenerSystem from "./sound/ecs/SoundListenerSystem.js";
|
|
30
30
|
import SoundListener from "./sound/ecs/SoundListener.js";
|
|
31
31
|
import { getURLHash } from "./platform/GetURLHash.js";
|
|
32
|
+
import Stats from "three/examples/jsm/libs/stats.module.js";
|
|
33
|
+
import EmptyView from "../view/elements/EmptyView.js";
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
*
|
|
@@ -68,6 +70,22 @@ export class EngineHarness {
|
|
|
68
70
|
this.p = null;
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @param {Engine} engine
|
|
76
|
+
*/
|
|
77
|
+
static addFpsCounter(engine) {
|
|
78
|
+
const stats = new Stats();
|
|
79
|
+
|
|
80
|
+
engine.graphics.on.postRender.add(stats.update, stats);
|
|
81
|
+
|
|
82
|
+
const view = new EmptyView({
|
|
83
|
+
el: stats.domElement
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
engine.viewStack.addChild(view);
|
|
87
|
+
}
|
|
88
|
+
|
|
71
89
|
/**
|
|
72
90
|
* @param {(config:EngineConfiguration,engine:Engine)=>*} configuration
|
|
73
91
|
* @param {boolean} [enable_localization] Whether or not to load localization data
|
|
@@ -228,6 +246,7 @@ export class EngineHarness {
|
|
|
228
246
|
* @param {boolean} [cameraController=true]
|
|
229
247
|
* @param {boolean} [cameraAutoClip]
|
|
230
248
|
* @param shadowmapResolution
|
|
249
|
+
* @param showFps
|
|
231
250
|
*/
|
|
232
251
|
static async buildBasics({
|
|
233
252
|
engine,
|
|
@@ -246,9 +265,14 @@ export class EngineHarness {
|
|
|
246
265
|
cameraFarDistance,
|
|
247
266
|
cameraController = true,
|
|
248
267
|
cameraAutoClip = false,
|
|
249
|
-
shadowmapResolution
|
|
268
|
+
shadowmapResolution,
|
|
269
|
+
showFps = true
|
|
250
270
|
}) {
|
|
251
271
|
|
|
272
|
+
if (showFps) {
|
|
273
|
+
EngineHarness.addFpsCounter(engine);
|
|
274
|
+
}
|
|
275
|
+
|
|
252
276
|
if (enableLights) {
|
|
253
277
|
await EngineHarness.buildLights({ engine: engine, shadowmapResolution });
|
|
254
278
|
}
|
|
@@ -7,10 +7,16 @@ import { assert } from "../../../core/assert.js";
|
|
|
7
7
|
* @returns {number}
|
|
8
8
|
*/
|
|
9
9
|
export function camera_compute_distance_to_fit_length(length, fov) {
|
|
10
|
+
// @see https://docs.unity3d.com/Manual/FrustumSizeAtDistance.html
|
|
11
|
+
|
|
10
12
|
assert.isNumber(length, 'length');
|
|
13
|
+
assert.greaterThanOrEqual(length, 0, 'length < 0');
|
|
14
|
+
|
|
11
15
|
assert.isNumber(fov, 'fov');
|
|
12
16
|
assert.greaterThan(fov, 0, 'fov <= 0');
|
|
13
17
|
assert.lessThan(fov, Math.PI, 'fov >= pi');
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
const signed_distance = (length * 0.5) / Math.tan(fov * 0.5);
|
|
20
|
+
|
|
21
|
+
return Math.abs(signed_distance);
|
|
16
22
|
}
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
import { array_quick_sort_by_comparator } from "../../../../../../core/collection/array/arrayQuickSort.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {THREE.Object3D} a
|
|
6
|
+
* @param {THREE.Object3D} b
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
function compare_by_material(a, b) {
|
|
10
|
+
|
|
11
|
+
const a_mat = a.material;
|
|
12
|
+
const b_mat = b.material;
|
|
13
|
+
|
|
14
|
+
if (a_mat === b_mat) {
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (a_mat === undefined) {
|
|
19
|
+
return 1;
|
|
20
|
+
} else if (b_mat === undefined) {
|
|
21
|
+
return -1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return a_mat.id - b_mat.id;
|
|
25
|
+
}
|
|
26
|
+
|
|
1
27
|
export class AbstractRenderAdapter {
|
|
2
28
|
constructor() {
|
|
3
29
|
|
|
@@ -16,6 +42,13 @@ export class AbstractRenderAdapter {
|
|
|
16
42
|
this.__objects = [];
|
|
17
43
|
}
|
|
18
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Sorting objects by material will help reduce context switching and number of graphics API calls
|
|
47
|
+
*/
|
|
48
|
+
sort_by_material() {
|
|
49
|
+
array_quick_sort_by_comparator(this.__objects, compare_by_material, null, 0, this.__object_count - 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
19
52
|
/**
|
|
20
53
|
*
|
|
21
54
|
* @param {THREE.BufferGeometry} geometry
|
|
@@ -114,6 +114,22 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
114
114
|
this.__blur = new DepthLimitedBlur({ format: RedFormat, clear_color: 0xFFFFFF });
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Higher value will make AO appear darker, lower values will make it lighter
|
|
119
|
+
* @param {number} v
|
|
120
|
+
*/
|
|
121
|
+
set intensity(v) {
|
|
122
|
+
this.__material.uniforms.intensity.value = v;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* @return {number}
|
|
128
|
+
*/
|
|
129
|
+
get intensity() {
|
|
130
|
+
return this.__material.uniforms.intensity.value;
|
|
131
|
+
}
|
|
132
|
+
|
|
117
133
|
/**
|
|
118
134
|
*
|
|
119
135
|
* @param {Camera} camera
|
|
@@ -91,7 +91,7 @@ export class HierarchicalZBuffer {
|
|
|
91
91
|
|
|
92
92
|
for (let i = existing_mip_depth; i < mip_depth; i++) {
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
const renderTarget = new WebGLRenderTarget(1, 1, {
|
|
95
95
|
minFilter: NearestFilter,
|
|
96
96
|
magFilter: NearestFilter,
|
|
97
97
|
format: RedFormat,
|
|
@@ -104,6 +104,10 @@ export class HierarchicalZBuffer {
|
|
|
104
104
|
generateMipmaps: false
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
+
renderTarget.texture.name = `Hierarchical Z buffer MIP ${i}`;
|
|
108
|
+
|
|
109
|
+
mips[i] = renderTarget;
|
|
110
|
+
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
}
|
|
@@ -58,7 +58,7 @@ function makeShader({ texture, alpha_override, swizzle }) {
|
|
|
58
58
|
|
|
59
59
|
if (texture_channel_count < 4) {
|
|
60
60
|
// no override specified, and alpha would be 0, force it to one to make image visible
|
|
61
|
-
_swizzle[
|
|
61
|
+
_swizzle[3] = 1;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
return new ShaderMaterial({
|
|
@@ -83,7 +83,7 @@ function makeShader({ texture, alpha_override, swizzle }) {
|
|
|
83
83
|
void main() {
|
|
84
84
|
|
|
85
85
|
vec4 texel = ${sampleTexel(texture, 'tDiffuse', 'vUv')};
|
|
86
|
-
gl_FragColor = ${glsl_gen_swizzled_read('texel',
|
|
86
|
+
gl_FragColor = ${glsl_gen_swizzled_read('texel', _swizzle)};
|
|
87
87
|
}`,
|
|
88
88
|
uniforms: {
|
|
89
89
|
|
|
@@ -163,7 +163,6 @@ export function renderSamplerFromTexture({
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
const render = () => {
|
|
166
|
-
|
|
167
166
|
const shader = getShader();
|
|
168
167
|
|
|
169
168
|
shader.uniforms.tDiffuse.value = texture;
|
|
@@ -186,10 +185,12 @@ export function renderSamplerFromTexture({
|
|
|
186
185
|
destination,
|
|
187
186
|
render,
|
|
188
187
|
set texture(v) {
|
|
188
|
+
if (v !== texture) {
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
texture = v;
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
getShader().uniforms.tDiffuse.value = v;
|
|
193
|
+
}
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
}
|
|
@@ -203,13 +203,17 @@ function print_perf_stats() {
|
|
|
203
203
|
function prepare_query_test(hiz, graphics, ecd) {
|
|
204
204
|
|
|
205
205
|
const query = new BatchOcclusionQuery();
|
|
206
|
-
query.setSize(
|
|
206
|
+
query.setSize(100);
|
|
207
207
|
|
|
208
208
|
|
|
209
209
|
const random = seededRandom(42);
|
|
210
210
|
|
|
211
211
|
const row_count = 8;
|
|
212
212
|
|
|
213
|
+
/**
|
|
214
|
+
*
|
|
215
|
+
* @type {EntityBuilder[]}
|
|
216
|
+
*/
|
|
213
217
|
const entities = [];
|
|
214
218
|
const labels = [];
|
|
215
219
|
|
|
@@ -224,8 +228,11 @@ function prepare_query_test(hiz, graphics, ecd) {
|
|
|
224
228
|
|
|
225
229
|
mat4.copy(projection, world_inverse);
|
|
226
230
|
mat4.multiply(projection, camera_projection, projection);
|
|
231
|
+
const aabb = new Float32Array(6);
|
|
232
|
+
|
|
233
|
+
const query_size = query.getSize();
|
|
227
234
|
|
|
228
|
-
for (let i = 0; i <
|
|
235
|
+
for (let i = 0; i < query_size; i++) {
|
|
229
236
|
const entity = entities[i];
|
|
230
237
|
|
|
231
238
|
if (entity === undefined) {
|
|
@@ -236,7 +243,6 @@ function prepare_query_test(hiz, graphics, ecd) {
|
|
|
236
243
|
* @type {Mesh}
|
|
237
244
|
*/
|
|
238
245
|
const mesh = entity.getComponent(Mesh);
|
|
239
|
-
const aabb = new Float32Array(6);
|
|
240
246
|
|
|
241
247
|
mesh.bvh.writeToArray(aabb, 0);
|
|
242
248
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BinaryBuffer } from "../../core/binary/BinaryBuffer.js";
|
|
2
2
|
import BinaryBufferDeSerializer from "../ecs/storage/BinaryBufferDeSerializer.js";
|
|
3
|
-
|
|
4
|
-
const scratch_buffer = new BinaryBuffer();
|
|
3
|
+
import { BinaryObjectSerializationAdapter } from "../ecs/storage/binary/object/BinaryObjectSerializationAdapter.js";
|
|
5
4
|
|
|
6
5
|
class LocalAPI {
|
|
7
6
|
/**
|
|
@@ -10,8 +9,23 @@ class LocalAPI {
|
|
|
10
9
|
*/
|
|
11
10
|
engine = null;
|
|
12
11
|
|
|
12
|
+
_object_serde = new BinaryObjectSerializationAdapter();
|
|
13
|
+
|
|
14
|
+
get _registry() {
|
|
15
|
+
return this.engine.binarySerializationRegistry;
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
*
|
|
20
|
+
* @return {EntityComponentDataset}
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
get _current_dataset() {
|
|
24
|
+
return this.engine.entityManager.dataset;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Server sent us a new world state
|
|
15
29
|
* @param {BinaryBuffer} buffer
|
|
16
30
|
*/
|
|
17
31
|
async writeCurrentSceneDataset(buffer) {
|
|
@@ -19,7 +33,9 @@ class LocalAPI {
|
|
|
19
33
|
|
|
20
34
|
const engine = this.engine;
|
|
21
35
|
|
|
22
|
-
|
|
36
|
+
deSerializer.registry = this._registry;
|
|
37
|
+
|
|
38
|
+
const ecd = this._current_dataset;
|
|
23
39
|
|
|
24
40
|
ecd.clear();
|
|
25
41
|
|
|
@@ -31,6 +47,30 @@ class LocalAPI {
|
|
|
31
47
|
|
|
32
48
|
await p;
|
|
33
49
|
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param {BinaryBuffer} buffer
|
|
54
|
+
* @return {Promise<void>}
|
|
55
|
+
*/
|
|
56
|
+
async createEntity(buffer) {
|
|
57
|
+
// create entity on the current scene with a given ID
|
|
58
|
+
|
|
59
|
+
const entity_id = buffer.readUintVar();
|
|
60
|
+
|
|
61
|
+
this._current_dataset.createEntitySpecific(entity_id);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async addComponentToEntity(buffer) {
|
|
65
|
+
const entity_id = buffer.readUintVar();
|
|
66
|
+
|
|
67
|
+
this._object_serde.registry = this._registry;
|
|
68
|
+
const component_instance = this._object_serde.deserialize(buffer);
|
|
69
|
+
|
|
70
|
+
this._current_dataset.addComponentToEntity(entity_id, component_instance);
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
34
74
|
}
|
|
35
75
|
|
|
36
76
|
export class RemoteController {
|
|
@@ -59,10 +99,10 @@ export class RemoteController {
|
|
|
59
99
|
async __handle_message(data) {
|
|
60
100
|
// console.log(`received message `, data);
|
|
61
101
|
|
|
62
|
-
|
|
102
|
+
const buffer = BinaryBuffer.fromArrayBuffer(data);
|
|
63
103
|
|
|
64
104
|
// read packet ID
|
|
65
|
-
const packet_id =
|
|
105
|
+
const packet_id = buffer.readUTF8String();
|
|
66
106
|
|
|
67
107
|
console.log(`packet ID: ${packet_id}`);
|
|
68
108
|
|
|
@@ -72,7 +112,7 @@ export class RemoteController {
|
|
|
72
112
|
}
|
|
73
113
|
|
|
74
114
|
try {
|
|
75
|
-
await this.localAPI[packet_id](
|
|
115
|
+
await this.localAPI[packet_id](buffer);
|
|
76
116
|
} catch (e) {
|
|
77
117
|
//
|
|
78
118
|
console.error(`Failed to process remote call to '${packet_id}':`, e);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EngineHarness } from "../EngineHarness.js";
|
|
2
2
|
import { RemoteController } from "./RemoteController.js";
|
|
3
3
|
import { ShadedGeometrySystem } from "../graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
|
|
4
|
+
import { initializeGameBinarySerializationRegistry } from "../../../model/game/GameBinarySerializationRegistry.js";
|
|
4
5
|
|
|
5
6
|
const harness = new EngineHarness();
|
|
6
7
|
|
|
@@ -15,6 +16,8 @@ async function main(engine) {
|
|
|
15
16
|
engine
|
|
16
17
|
});
|
|
17
18
|
|
|
19
|
+
initializeGameBinarySerializationRegistry(engine.binarySerializationRegistry);
|
|
20
|
+
|
|
18
21
|
const remote = new RemoteController();
|
|
19
22
|
|
|
20
23
|
remote.attach(engine);
|
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.43.
|
|
8
|
+
"version": "2.43.25",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|