@woosh/meep-engine 2.39.13 → 2.39.16
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/int32_to_binary_string.js +18 -0
- package/core/cache/Cache.js +1 -1
- package/core/geom/3d/decompose_matrix_4_array.js +3 -1
- package/core/geom/3d/ray/ray3_array_apply_matrix4.js +15 -1
- package/core/geom/3d/topology/bounds/computeTopoMeshBoundingSphere.js +2 -1
- package/editor/tools/v2/TransformControls.js +1782 -0
- package/editor/tools/v2/prototypeTransformControls.js +79 -0
- package/engine/asset/AssetManager.js +82 -23
- package/engine/ecs/parent/EntityNode.js +41 -13
- package/engine/ecs/terrain/ecs/Terrain.js +49 -39
- package/engine/ecs/terrain/ecs/layers/TerrainLayers.js +12 -5
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +5 -1
- package/engine/ecs/transform/Transform.d.ts +2 -0
- package/engine/ecs/transform/Transform.js +6 -0
- package/engine/ecs/transform-attachment/TransformAttachment.js +13 -0
- package/engine/ecs/transform-attachment/TransformAttachmentSystem.js +138 -16
- package/engine/graphics/FrameRunner.js +8 -2
- package/engine/graphics/ecs/mesh-v2/DrawMode.js +4 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +77 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +10 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -30
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +11 -0
- package/engine/graphics/ecs/mesh-v2/render/adapters/InstancedRendererAdapter.js +8 -32
- package/engine/graphics/ecs/mesh-v2/render/optimization/RuntimeDrawMethodOptimizer.js +6 -0
- package/engine/graphics/geometry/buffered/makeGeometryIndexed.js +23 -0
- package/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +16 -4
- package/engine/graphics/geometry/buffered/query/GeometryVisitor.js +8 -1
- package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +14 -5
- package/engine/graphics/geometry/bvh/buffered/BinaryBVHFromBufferGeometry.js +56 -0
- package/engine/graphics/micron/build/hierarchy/build_merge_graph.js +1 -0
- package/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +18 -4
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +15 -5
- package/package.json +1 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { EngineHarness } from "../../../engine/EngineHarness.js";
|
|
2
|
+
import EntityBuilder from "../../../engine/ecs/EntityBuilder.js";
|
|
3
|
+
import { ShadedGeometry } from "../../../engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
|
|
4
|
+
import { BoxBufferGeometry, MeshStandardMaterial } from "three";
|
|
5
|
+
import { Transform } from "../../../engine/ecs/transform/Transform.js";
|
|
6
|
+
import { ShadedGeometrySystem } from "../../../engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
|
|
7
|
+
import { TransformControls } from "./TransformControls.js";
|
|
8
|
+
import { Camera } from "../../../engine/graphics/ecs/camera/Camera.js";
|
|
9
|
+
import { TransformAttachmentSystem } from "../../../engine/ecs/transform-attachment/TransformAttachmentSystem.js";
|
|
10
|
+
import InputController from "../../../engine/input/ecs/components/InputController.js";
|
|
11
|
+
import InputControllerSystem from "../../../engine/input/ecs/systems/InputControllerSystem.js";
|
|
12
|
+
|
|
13
|
+
const harness = new EngineHarness();
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param {Engine} engine
|
|
18
|
+
*/
|
|
19
|
+
async function main(engine) {
|
|
20
|
+
EngineHarness.buildBasics({
|
|
21
|
+
engine,
|
|
22
|
+
cameraController: false
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
// create something to drag
|
|
27
|
+
const ecd = engine.entityManager.dataset;
|
|
28
|
+
const cube = new EntityBuilder()
|
|
29
|
+
.add(ShadedGeometry.from(new BoxBufferGeometry(1, 1, 1), new MeshStandardMaterial({
|
|
30
|
+
color: 0xFFAAAA
|
|
31
|
+
})))
|
|
32
|
+
.add(Transform.fromJSON({
|
|
33
|
+
position: {
|
|
34
|
+
x: 10,
|
|
35
|
+
y: 0,
|
|
36
|
+
z: 10
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
const cube_entity = cube
|
|
41
|
+
.build(ecd);
|
|
42
|
+
|
|
43
|
+
const camera = ecd.getAnyComponent(Camera);
|
|
44
|
+
|
|
45
|
+
const controls = new TransformControls(camera.component.object, engine.gameView.el);
|
|
46
|
+
|
|
47
|
+
controls.build(ecd);
|
|
48
|
+
controls.attach(cube_entity);
|
|
49
|
+
|
|
50
|
+
// cube.getComponentSafe(Transform).position.onChanged.add(console.log);
|
|
51
|
+
// cube.getComponentSafe(Transform).scale.onChanged.add(console.warn);
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
new EntityBuilder().add(new InputController([{
|
|
55
|
+
path: 'keyboard/keys/w/down',
|
|
56
|
+
listener() {
|
|
57
|
+
controls.mode = "translate"
|
|
58
|
+
}
|
|
59
|
+
}, {
|
|
60
|
+
path: 'keyboard/keys/e/down',
|
|
61
|
+
listener() {
|
|
62
|
+
controls.mode = "scale"
|
|
63
|
+
}
|
|
64
|
+
}, {
|
|
65
|
+
path: 'keyboard/keys/r/down',
|
|
66
|
+
listener() {
|
|
67
|
+
controls.mode = "rotate"
|
|
68
|
+
}
|
|
69
|
+
}])).build(ecd);
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
harness.initialize({
|
|
74
|
+
configuration(config, engine) {
|
|
75
|
+
config.addSystem(new ShadedGeometrySystem(engine));
|
|
76
|
+
config.addSystem(new TransformAttachmentSystem(engine));
|
|
77
|
+
config.addSystem(new InputControllerSystem(engine.devices));
|
|
78
|
+
}
|
|
79
|
+
}).then(main);
|
|
@@ -14,29 +14,58 @@ import { array_remove_element } from "../../core/collection/array/array_remove_e
|
|
|
14
14
|
import { AssetDescription } from "./AssetDescription.js";
|
|
15
15
|
import { noop } from "../../core/function/Functions.js";
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
class AssetRequest {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {function(asset:Asset)} successCallback
|
|
21
|
+
* @param {function(error:*)} failureCallback
|
|
22
|
+
* @param {function(loaded:number, total:number):void} progressCallback
|
|
23
|
+
* @constructor
|
|
24
|
+
*/
|
|
25
|
+
constructor(successCallback, failureCallback, progressCallback) {
|
|
26
|
+
this.successCallback = successCallback;
|
|
27
|
+
this.failureCallback = failureCallback;
|
|
28
|
+
this.pogressCallback = progressCallback;
|
|
29
|
+
}
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
-
* @param {AssetDescription} description
|
|
34
|
-
* @constructor
|
|
33
|
+
* @enum {number}
|
|
35
34
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
const AssetLoadState = {
|
|
36
|
+
Initial: 0,
|
|
37
|
+
Queued: 1,
|
|
38
|
+
Loading: 2,
|
|
39
|
+
Succeeded: 3,
|
|
40
|
+
Failed: 4
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class PendingAsset {
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param {AssetDescription} description
|
|
48
|
+
* @constructor
|
|
49
|
+
*/
|
|
50
|
+
constructor(description) {
|
|
51
|
+
this.description = description;
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* @type {AssetRequest[]}
|
|
55
|
+
*/
|
|
56
|
+
this.requests = [];
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @type {BoundedValue}
|
|
60
|
+
*/
|
|
61
|
+
this.progress = new BoundedValue(0, 0);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @type {AssetLoadState|number}
|
|
66
|
+
*/
|
|
67
|
+
this.state = AssetLoadState.Initial;
|
|
68
|
+
}
|
|
40
69
|
}
|
|
41
70
|
|
|
42
71
|
|
|
@@ -232,6 +261,19 @@ export class AssetManager {
|
|
|
232
261
|
* @param {Asset} loaded_asset
|
|
233
262
|
*/
|
|
234
263
|
const success = async (loaded_asset) => {
|
|
264
|
+
if (pendingAsset.state === AssetLoadState.Succeeded) {
|
|
265
|
+
// incorrect state
|
|
266
|
+
console.warn(`Asset already resolved, duplicate success invocation. Ignored. AD:${assetDescription}`);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (pendingAsset.state === AssetLoadState.Failed) {
|
|
271
|
+
// incorrect state
|
|
272
|
+
console.error(`Asset already failed. Unexpected resolution signal. AD:${assetDescription}`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
pendingAsset.state = AssetLoadState.Succeeded;
|
|
276
|
+
|
|
235
277
|
let asset = loaded_asset;
|
|
236
278
|
|
|
237
279
|
// apply transform chain
|
|
@@ -256,25 +298,42 @@ export class AssetManager {
|
|
|
256
298
|
|
|
257
299
|
//register asset
|
|
258
300
|
assets.set(assetDescription, asset);
|
|
259
|
-
|
|
301
|
+
|
|
302
|
+
// process callbacks
|
|
303
|
+
for (let i = 0; i < requests.length; i++) {
|
|
304
|
+
const request = requests[i];
|
|
260
305
|
try {
|
|
261
306
|
request.successCallback(asset);
|
|
262
307
|
} catch (e) {
|
|
263
308
|
console.error("Failed to execute asset success callback", e);
|
|
264
309
|
}
|
|
265
|
-
}
|
|
310
|
+
}
|
|
311
|
+
|
|
266
312
|
//clear callbacks
|
|
267
313
|
requestMap.delete(assetDescription);
|
|
268
314
|
}
|
|
269
315
|
|
|
270
316
|
function failure(error) {
|
|
271
|
-
|
|
317
|
+
if (pendingAsset.state === AssetLoadState.Failed) {
|
|
318
|
+
console.warn(`Asset already failed, this is a redundant invocation. AD: ${assetDescription}`);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (pendingAsset.state === AssetLoadState.Succeeded) {
|
|
323
|
+
// incorrect state
|
|
324
|
+
console.error(`Asset already resolved. Unexpected failure signal. AD:${assetDescription}`);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
pendingAsset.state = AssetLoadState.Failed;
|
|
328
|
+
|
|
329
|
+
for (let i = 0; i < requests.length; i++) {
|
|
330
|
+
const request = requests[i];
|
|
272
331
|
try {
|
|
273
332
|
request.failureCallback(error);
|
|
274
333
|
} catch (e) {
|
|
275
334
|
console.error("Failed to execute asset failure callback", e);
|
|
276
335
|
}
|
|
277
|
-
}
|
|
336
|
+
}
|
|
278
337
|
//clear callbacks
|
|
279
338
|
requestMap.delete(assetDescription);
|
|
280
339
|
|
|
@@ -219,16 +219,24 @@ export class EntityNode {
|
|
|
219
219
|
addChild(node) {
|
|
220
220
|
const added = array_push_if_unique(this.__children, node);
|
|
221
221
|
|
|
222
|
-
if (added) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
222
|
+
if (!added) {
|
|
223
|
+
// already contain this child
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (node.parent !== null) {
|
|
228
|
+
// has a parent already, detach
|
|
229
|
+
node.parent.removeChild(node);
|
|
230
|
+
}
|
|
227
231
|
|
|
228
|
-
|
|
232
|
+
node.parent = this;
|
|
233
|
+
|
|
234
|
+
// live mode
|
|
235
|
+
if (this.__entity.isBuilt) {
|
|
236
|
+
// TODO attach node live
|
|
229
237
|
}
|
|
230
238
|
|
|
231
|
-
return
|
|
239
|
+
return true;
|
|
232
240
|
}
|
|
233
241
|
|
|
234
242
|
/**
|
|
@@ -239,13 +247,21 @@ export class EntityNode {
|
|
|
239
247
|
removeChild(node) {
|
|
240
248
|
const removed = array_remove_first(this.__children, node);
|
|
241
249
|
|
|
242
|
-
if (removed) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
node.parent = null;
|
|
250
|
+
if (!removed) {
|
|
251
|
+
// not present
|
|
252
|
+
return false;
|
|
246
253
|
}
|
|
247
254
|
|
|
248
|
-
|
|
255
|
+
assert.equal(node.parent, this, 'node is a child, but parent property points to something else instead of this node');
|
|
256
|
+
|
|
257
|
+
node.parent = null;
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
get isBuilt() {
|
|
264
|
+
return this.__entity.isBuilt;
|
|
249
265
|
}
|
|
250
266
|
|
|
251
267
|
/**
|
|
@@ -278,6 +294,7 @@ export class EntityNode {
|
|
|
278
294
|
const parent_entity_id = parent_entity_builder.entity;
|
|
279
295
|
parent_entity.entity = parent_entity_id;
|
|
280
296
|
|
|
297
|
+
assert.ok(parent.entity.hasComponent(Transform), "parent node must have a transform but doesn't. Transform is required for attachment transform hierarchy to work correctly");
|
|
281
298
|
|
|
282
299
|
const attachment = this.__safe_get_attachment();
|
|
283
300
|
|
|
@@ -306,7 +323,12 @@ export class EntityNode {
|
|
|
306
323
|
}
|
|
307
324
|
|
|
308
325
|
destroy() {
|
|
309
|
-
|
|
326
|
+
if (!this.__entity.isBuilt) {
|
|
327
|
+
// not built
|
|
328
|
+
|
|
329
|
+
//TODO check for dangling listeners
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
310
332
|
|
|
311
333
|
// remove listeners
|
|
312
334
|
this.__transform.position.onChanged.remove(this.__transform_sync_down, this);
|
|
@@ -328,3 +350,9 @@ export class EntityNode {
|
|
|
328
350
|
this.on.destroyed.send0();
|
|
329
351
|
}
|
|
330
352
|
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @readonly
|
|
356
|
+
* @type {boolean}
|
|
357
|
+
*/
|
|
358
|
+
EntityNode.prototype.isEntityNode = true;
|
|
@@ -36,6 +36,7 @@ import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalSt
|
|
|
36
36
|
import { buildLightTexture } from "./BuildLightTexture.js";
|
|
37
37
|
import { promiseSamplerHeight } from "./PromiseSamplerHeight.js";
|
|
38
38
|
import { loadLegacyTerrainSplats } from "./splat/loadLegacyTerrainSplats.js";
|
|
39
|
+
import { WHITE_PIXEL_DATA_URL } from "../../../graphics/WHITE_PIXEL_DATA_URL.js";
|
|
39
40
|
|
|
40
41
|
let idCounter = 0;
|
|
41
42
|
|
|
@@ -350,7 +351,7 @@ class Terrain {
|
|
|
350
351
|
overlay.tileImage.onChanged.add(this.updateTileImage, this);
|
|
351
352
|
}
|
|
352
353
|
|
|
353
|
-
updateTileImage() {
|
|
354
|
+
async updateTileImage() {
|
|
354
355
|
const tileImageURL = this.overlay.tileImage.getValue();
|
|
355
356
|
|
|
356
357
|
const assetManager = this.__assetManager;
|
|
@@ -359,27 +360,25 @@ class Terrain {
|
|
|
359
360
|
return;
|
|
360
361
|
}
|
|
361
362
|
|
|
362
|
-
assetManager.promise(tileImageURL, GameAssetType.Texture)
|
|
363
|
-
.then((asset) => {
|
|
363
|
+
const asset = await assetManager.promise(tileImageURL, GameAssetType.Texture);
|
|
364
364
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
365
|
+
if (tileImageURL !== this.overlay.tileImage.getValue()) {
|
|
366
|
+
//url has changed, abort
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
369
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
370
|
+
/**
|
|
371
|
+
*
|
|
372
|
+
* @type {Texture}
|
|
373
|
+
*/
|
|
374
|
+
const texture = asset.create();
|
|
375
375
|
|
|
376
|
-
|
|
377
|
-
|
|
376
|
+
texture.minFilter = LinearFilter;
|
|
377
|
+
texture.magFilter = LinearFilter;
|
|
378
378
|
|
|
379
|
-
|
|
379
|
+
texture.generateMipmaps = false;
|
|
380
380
|
|
|
381
|
-
|
|
382
|
-
});
|
|
381
|
+
this.material.uniforms.diffuseGridOverlaySprite.value = texture;
|
|
383
382
|
}
|
|
384
383
|
|
|
385
384
|
update(timeDelta) {
|
|
@@ -710,7 +709,7 @@ class Terrain {
|
|
|
710
709
|
}
|
|
711
710
|
|
|
712
711
|
/**
|
|
713
|
-
*
|
|
712
|
+
* @deprecated
|
|
714
713
|
* @param {AssetManager} assetManager
|
|
715
714
|
*/
|
|
716
715
|
buildFromLegacy(assetManager) {
|
|
@@ -928,39 +927,50 @@ class Terrain {
|
|
|
928
927
|
* @param opt
|
|
929
928
|
* @param {Engine} engine
|
|
930
929
|
*/
|
|
931
|
-
fromJSON(
|
|
930
|
+
fromJSON({
|
|
931
|
+
resolution = 4,
|
|
932
|
+
preview,
|
|
933
|
+
size = 1,
|
|
934
|
+
scale = 1,
|
|
935
|
+
material,
|
|
936
|
+
heights,
|
|
937
|
+
layers,
|
|
938
|
+
splat,
|
|
939
|
+
overlayTileImage
|
|
940
|
+
} = {}, engine) {
|
|
932
941
|
// mark as needing rebuilding
|
|
933
942
|
this.clearFlag(TerrainFlags.Built);
|
|
934
943
|
|
|
935
|
-
if (
|
|
936
|
-
|
|
944
|
+
if (preview !== undefined) {
|
|
945
|
+
this.preview.fromJSON(preview);
|
|
937
946
|
}
|
|
938
947
|
|
|
939
|
-
|
|
940
|
-
this.preview.fromJSON(opt.preview);
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
this.resolution = opt.resolution !== undefined ? opt.resolution : 4;
|
|
948
|
+
this.resolution = resolution;
|
|
944
949
|
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
if (opt.size !== undefined) {
|
|
948
|
-
size.fromJSON(opt.size);
|
|
949
|
-
}
|
|
950
|
+
this.size.fromJSON(size);
|
|
950
951
|
|
|
951
|
-
this.gridScale =
|
|
952
|
+
this.gridScale = scale;
|
|
952
953
|
//
|
|
953
954
|
|
|
954
|
-
this.materialDesc =
|
|
955
|
+
this.materialDesc = material;
|
|
955
956
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
957
|
+
if (heights !== undefined) {
|
|
958
|
+
this.samplerHeight.fromJSON(heights);
|
|
959
|
+
} else {
|
|
960
|
+
this.samplerHeight.data = new Float32Array(1);
|
|
961
|
+
this.samplerHeight.width = 1;
|
|
962
|
+
this.samplerHeight.height = 1;
|
|
963
|
+
this.samplerHeight.itemSize = 1;
|
|
964
|
+
this.samplerHeight.version++;
|
|
965
|
+
}
|
|
961
966
|
|
|
962
|
-
|
|
967
|
+
this.layers.fromJSON(layers);
|
|
968
|
+
this.splat.fromJSON(splat);
|
|
963
969
|
|
|
970
|
+
if (overlayTileImage !== undefined) {
|
|
971
|
+
this.overlay.baseTileImage = overlayTileImage;
|
|
972
|
+
} else {
|
|
973
|
+
this.overlay.baseTileImage = WHITE_PIXEL_DATA_URL;
|
|
964
974
|
}
|
|
965
975
|
|
|
966
976
|
|
|
@@ -111,6 +111,8 @@ const scaled_texture_cache = new Cache({
|
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
const DEFAULT_RESOLUTION = 512;
|
|
115
|
+
|
|
114
116
|
export class TerrainLayers {
|
|
115
117
|
constructor() {
|
|
116
118
|
|
|
@@ -124,7 +126,7 @@ export class TerrainLayers {
|
|
|
124
126
|
*
|
|
125
127
|
* @type {Vector2}
|
|
126
128
|
*/
|
|
127
|
-
this.resolution = new Vector2(
|
|
129
|
+
this.resolution = new Vector2(DEFAULT_RESOLUTION, DEFAULT_RESOLUTION);
|
|
128
130
|
|
|
129
131
|
/**
|
|
130
132
|
*
|
|
@@ -166,7 +168,7 @@ export class TerrainLayers {
|
|
|
166
168
|
};
|
|
167
169
|
}
|
|
168
170
|
|
|
169
|
-
fromJSON({ resolution, layers }) {
|
|
171
|
+
fromJSON({ resolution = DEFAULT_RESOLUTION, layers = [] } = {}) {
|
|
170
172
|
this.resolution.fromJSON(resolution);
|
|
171
173
|
this.layers.fromJSON(layers, TerrainLayer);
|
|
172
174
|
}
|
|
@@ -232,9 +234,14 @@ export class TerrainLayers {
|
|
|
232
234
|
|
|
233
235
|
const layerIndex = i;
|
|
234
236
|
|
|
235
|
-
promise.then(
|
|
236
|
-
|
|
237
|
-
|
|
237
|
+
promise.then(
|
|
238
|
+
() => {
|
|
239
|
+
this.writeLayerDataIntoTexture(layerIndex);
|
|
240
|
+
},
|
|
241
|
+
(reason) => {
|
|
242
|
+
console.error(`Failed to load layer [${layerIndex}]"${layer.textureDiffuseURL}". Reason: ${reason}`);
|
|
243
|
+
}
|
|
244
|
+
);
|
|
238
245
|
|
|
239
246
|
promises.push(promise);
|
|
240
247
|
}
|
|
@@ -59,7 +59,11 @@ export class SplatMapping {
|
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
fromJSON({
|
|
62
|
+
fromJSON({
|
|
63
|
+
size = { x: 1, y: 1 },
|
|
64
|
+
depth = 0,
|
|
65
|
+
data = []
|
|
66
|
+
} = {}) {
|
|
63
67
|
this.resize(size.x, size.y, depth);
|
|
64
68
|
array_copy(data, 0, this.weightData, 0, data.length);
|
|
65
69
|
|
|
@@ -285,6 +285,12 @@ export class Transform {
|
|
|
285
285
|
toMatrix4(result) {
|
|
286
286
|
compose_matrix4_array(result, this.position, this.rotation, this.scale);
|
|
287
287
|
}
|
|
288
|
+
|
|
289
|
+
makeIdentity() {
|
|
290
|
+
this.position.copy(Vector3.zero);
|
|
291
|
+
this.rotation.copy(Quaternion.identity);
|
|
292
|
+
this.scale.copy(Vector3.one);
|
|
293
|
+
}
|
|
288
294
|
}
|
|
289
295
|
|
|
290
296
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Transform } from "../transform/Transform.js";
|
|
2
|
+
import { int32_to_binary_string } from "../../../core/binary/int32_to_binary_string.js";
|
|
2
3
|
|
|
3
4
|
export const TransformAttachmentFlags = {
|
|
4
5
|
/**
|
|
@@ -31,6 +32,18 @@ export class TransformAttachment {
|
|
|
31
32
|
this.flags = DEFAULT_FLAGS;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
toString() {
|
|
36
|
+
return JSON.stringify(this.toJSON());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
toJSON() {
|
|
40
|
+
return {
|
|
41
|
+
transform: this.transform.toJSON(),
|
|
42
|
+
parent: this.parent,
|
|
43
|
+
flags: int32_to_binary_string(this.flags)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
34
47
|
get immediate() {
|
|
35
48
|
return this.getFlag(TransformAttachmentFlags.Immediate);
|
|
36
49
|
}
|