@woosh/meep-engine 2.39.2 → 2.39.5
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/bvh2/{traversal/__detailed_box_volume_intersection.js → aabb3/aabb3_detailed_volume_intersection.js} +47 -27
- package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +13 -0
- package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +5 -3
- package/core/bvh2/traversal/__process_point_if_within_planes.js +1 -0
- package/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +60 -0
- package/core/geom/3d/plane/is_point_within_planes.js +46 -0
- package/core/geom/3d/topology/bounds/{computeTraingleClusterNormalBoundingCone.js → computeTriangleClusterNormalBoundingCone.js} +8 -1
- package/core/geom/Vector3.d.ts +8 -0
- package/editor/actions/concrete/ActionUpdateTexture.js +21 -0
- package/editor/actions/concrete/ArrayCopyAction.js +39 -0
- package/editor/actions/concrete/ModifyPatchTextureArray2DAction.js +182 -0
- package/editor/enableEditor.js +30 -2
- package/editor/tools/paint/TerrainPaintTool.js +19 -3
- package/editor/tools/paint/TerrainTexturePaintTool.js +19 -57
- package/editor/tools/paint/prototypeTerrainEditor.js +67 -0
- package/editor/view/ecs/ComponentControlView.js +105 -10
- package/editor/view/ecs/EntityEditor.js +1 -1
- package/engine/ecs/fow/FogOfWarSystem.js +6 -3
- package/engine/ecs/terrain/ecs/Terrain.js +57 -47
- package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +16 -2
- package/engine/ecs/terrain/ecs/layers/TerrainLayers.js +17 -0
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +24 -78
- package/engine/ecs/terrain/ecs/splat/loadLegacyTerrainSplats.js +73 -0
- package/engine/graphics/camera/camera_compute_distance_to_fit_length.d.ts +1 -0
- package/engine/graphics/camera/camera_compute_distance_to_fit_length.js +16 -0
- package/engine/graphics/camera/testClippingPlaneComputation.js +7 -4
- package/engine/graphics/ecs/camera/Camera.js +2 -2
- package/engine/graphics/ecs/camera/CameraClippingPlaneComputer.js +5 -8
- package/engine/graphics/ecs/camera/CameraSystem.js +18 -184
- package/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +32 -0
- package/engine/graphics/ecs/camera/build_three_camera_object.js +29 -0
- package/engine/graphics/ecs/camera/compute_perspective_camera_focal_position.js +27 -0
- package/engine/graphics/ecs/camera/frustum_from_camera.js +20 -0
- package/engine/graphics/ecs/camera/is_valid_distance_value.js +11 -0
- package/engine/graphics/ecs/camera/set_camera_aspect_ratio.js +46 -0
- package/engine/graphics/ecs/camera/update_camera_transform.js +17 -0
- package/engine/graphics/ecs/path/testPathDisplaySystem.js +19 -15
- package/engine/graphics/ecs/path/tube/TubePathStyle.js +1 -0
- package/engine/graphics/{Utils.js → makeModelView.js} +1 -10
- package/engine/graphics/micron/build/PatchRepresentation.js +3 -3
- package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +2 -2
- package/engine/graphics/render/forward_plus/LightManager.js +2 -2
- package/engine/graphics/render/view/CameraView.js +2 -2
- package/engine/graphics/texture/sampler/Sampler2D.js +1293 -1267
- package/engine/graphics/texture/texture_array_2d_copy.js +45 -0
- package/engine/graphics/util/makeMeshPreviewScene.js +2 -2
- package/package.json +1 -1
- package/view/renderModel.js +1 -1
- package/view/string_tag_to_css_class_name.js +12 -0
- package/engine/graphics/util/computeMeshPreviewCameraDistance.js +0 -10
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { clamp } from "../../../core/math/clamp.js";
|
|
2
|
-
import { inverseLerp } from "../../../core/math/inverseLerp.js";
|
|
3
1
|
import { TerrainPaintTool } from "./TerrainPaintTool.js";
|
|
4
2
|
import { convertSampler2D2DataURL } from "../../../engine/graphics/texture/sampler/convertSampler2D2DataURL.js";
|
|
5
3
|
import { obtainTerrain } from "../../../engine/ecs/terrain/util/obtainTerrain.js";
|
|
6
|
-
import {
|
|
4
|
+
import { ModifyPatchTextureArray2DAction } from "../../actions/concrete/ModifyPatchTextureArray2DAction.js";
|
|
5
|
+
import { ArrayCopyAction } from "../../actions/concrete/ArrayCopyAction.js";
|
|
6
|
+
import { ActionUpdateTexture } from "../../actions/concrete/ActionUpdateTexture.js";
|
|
7
7
|
|
|
8
8
|
export class TerrainTexturePaintTool extends TerrainPaintTool {
|
|
9
9
|
constructor() {
|
|
@@ -68,6 +68,9 @@ export class TerrainTexturePaintTool extends TerrainPaintTool {
|
|
|
68
68
|
*/
|
|
69
69
|
const layer = terrain.layers.get(this.settings.splatIndex);
|
|
70
70
|
|
|
71
|
+
if (layer === undefined) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
71
74
|
|
|
72
75
|
const url = convertSampler2D2DataURL(layer.diffuse);
|
|
73
76
|
|
|
@@ -82,7 +85,7 @@ export class TerrainTexturePaintTool extends TerrainPaintTool {
|
|
|
82
85
|
super.shutdown();
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
paint(timeDelta) {
|
|
88
|
+
async paint(timeDelta) {
|
|
86
89
|
|
|
87
90
|
const power = this.settings.brushStrength * timeDelta;
|
|
88
91
|
|
|
@@ -133,7 +136,6 @@ export class TerrainTexturePaintTool extends TerrainPaintTool {
|
|
|
133
136
|
const splatWidth = splat.size.x;
|
|
134
137
|
const splatHeight = splat.size.y;
|
|
135
138
|
|
|
136
|
-
const splatLayerSize = splatWidth * splatHeight;
|
|
137
139
|
|
|
138
140
|
const h_x0 = uv_x0 * splatWidth;
|
|
139
141
|
const h_x1 = uv_x1 * splatWidth;
|
|
@@ -150,61 +152,21 @@ export class TerrainTexturePaintTool extends TerrainPaintTool {
|
|
|
150
152
|
const splatIndex = this.settings.splatIndex;
|
|
151
153
|
|
|
152
154
|
//create action
|
|
153
|
-
const patchWidth = x1 - x0;
|
|
154
|
-
|
|
155
|
-
const targetSplatLayerAddress = splatIndex * splatLayerSize;
|
|
156
|
-
|
|
157
|
-
const splat_layer_sampler = splat.getLayerWeightSampler(splatIndex);
|
|
158
|
-
|
|
159
|
-
const m_action = new ModifyPatchSampler2DAction(splat_layer_sampler, [x0, y0, x1, y1]);
|
|
160
|
-
|
|
161
|
-
const patchMaterialData = m_action.patch.data;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
for (let y = y0; y < y1; y++) {
|
|
165
|
-
|
|
166
|
-
const v = inverseLerp(h_y0, h_y1, y);
|
|
167
|
-
|
|
168
|
-
for (let x = x0; x < x1; x++) {
|
|
169
|
-
|
|
170
|
-
const u = inverseLerp(h_x0, h_x1, x);
|
|
171
|
-
|
|
172
|
-
const markerValue = marker.sampleChannelBilinearUV(u, v, 3);
|
|
173
|
-
|
|
174
|
-
if (Number.isNaN(markerValue)) {
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
155
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const baseValue = weightData[targetSplatLayerAddress + splatTexelIndex];
|
|
182
|
-
|
|
183
|
-
const delta = markerValue * speed;
|
|
184
|
-
|
|
185
|
-
const value = baseValue + delta;
|
|
186
|
-
|
|
187
|
-
const clampedValue = clamp(value, 0, 255);
|
|
188
|
-
|
|
189
|
-
if (Number.isNaN(clampedValue)) {
|
|
190
|
-
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
//write new weight for the material
|
|
196
|
-
weightData[targetSplatLayerAddress + splatTexelIndex] = clampedValue;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const patchIndex = ((y - y0) * patchWidth + (x - x0));
|
|
200
|
-
|
|
201
|
-
patchMaterialData[patchIndex] = clampedValue;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
}
|
|
156
|
+
// const m_action = new ModifyPatchSampler2DAction(splat_layer_sampler, [x0, y0, x1, y1]);
|
|
157
|
+
const m_action = new ModifyPatchTextureArray2DAction(weightData, [splat.size.x, splat.size.y, splat.depth], [x0, y0, x1, y1]);
|
|
205
158
|
|
|
159
|
+
m_action.applyWeightStampToLayer(
|
|
160
|
+
uv_x * splat.size.x, uv_y * splat.size.y,
|
|
161
|
+
marker, splatIndex, speed,
|
|
162
|
+
0, 255
|
|
163
|
+
);
|
|
206
164
|
|
|
207
|
-
this.editor.actions.
|
|
165
|
+
await this.editor.actions.doMany([
|
|
166
|
+
m_action,
|
|
167
|
+
new ArrayCopyAction(weightData, splat.weightData),
|
|
168
|
+
new ActionUpdateTexture(splat.weightTexture)
|
|
169
|
+
]);
|
|
208
170
|
}
|
|
209
171
|
|
|
210
172
|
start() {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { EngineHarness } from "../../../engine/EngineHarness.js";
|
|
2
|
+
import { GizmoRenderingPlugin } from "../../../engine/graphics/render/gizmo/GizmoRenderingPlugin.js";
|
|
3
|
+
import { GameAssetType } from "../../../engine/asset/GameAssetType.js";
|
|
4
|
+
import { TextureAssetLoader } from "../../../engine/asset/loaders/texture/TextureAssetLoader.js";
|
|
5
|
+
import Vector2 from "../../../core/geom/Vector2.js";
|
|
6
|
+
import { enableEditor } from "../../enableEditor.js";
|
|
7
|
+
import { initializeEditor } from "../../../../model/game/initializeEditor.js";
|
|
8
|
+
|
|
9
|
+
import '../../../../../../css/game.scss';
|
|
10
|
+
import '../../../../../../css/editor/EntityEditorView.scss';
|
|
11
|
+
import '../../../../../../css/editor/EditorView.scss';
|
|
12
|
+
import { TerrainLayer } from "../../../engine/ecs/terrain/ecs/layers/TerrainLayer.js";
|
|
13
|
+
import Terrain from "../../../engine/ecs/terrain/ecs/Terrain.js";
|
|
14
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
15
|
+
|
|
16
|
+
new EngineHarness()
|
|
17
|
+
.initialize({
|
|
18
|
+
configuration(config, engine) {
|
|
19
|
+
|
|
20
|
+
config.addPlugin(GizmoRenderingPlugin);
|
|
21
|
+
|
|
22
|
+
config.addLoader(GameAssetType.Texture, new TextureAssetLoader());
|
|
23
|
+
}
|
|
24
|
+
}).then(main);
|
|
25
|
+
|
|
26
|
+
async function main(engine) {
|
|
27
|
+
await EngineHarness.buildBasics({
|
|
28
|
+
engine,
|
|
29
|
+
focus:new Vector3(128,0,128),
|
|
30
|
+
distance:30,
|
|
31
|
+
terrainResolution: 1,
|
|
32
|
+
terrainSize: new Vector2(128, 128),
|
|
33
|
+
enableWater: false
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const terrain_entity = engine.entityManager.dataset.getAnyComponent(Terrain);
|
|
37
|
+
const terrain = terrain_entity.component;
|
|
38
|
+
|
|
39
|
+
terrain.samplerHeight.resize(256, 256);
|
|
40
|
+
await terrain.updateHeights();
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
terrain.layers.addLayer(TerrainLayer.from("data/textures/materials/terrain_township_set/512/Grass_1.png", 20, 20));
|
|
44
|
+
terrain.layers.addLayer(TerrainLayer.from("data/textures/materials/terrain_township_set/512/Ground_1.png", 20, 20));
|
|
45
|
+
terrain.layers.addLayer(TerrainLayer.from("data/textures/materials/RAYGEAS/Stylized Ground Textures/Sand_2/Sand_2_AlbedoSmoothness.png", 20, 20));
|
|
46
|
+
terrain.layers.buildTexture();
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
terrain.splat.resize(256, 256, terrain.layers.count())
|
|
50
|
+
|
|
51
|
+
await terrain.layers.loadTextureData(engine.assetManager);
|
|
52
|
+
|
|
53
|
+
terrain.splat.fillLayerWeights(0, 50);
|
|
54
|
+
|
|
55
|
+
terrain.splat.weightTexture.needsUpdate = true;
|
|
56
|
+
terrain.updateMaterial();
|
|
57
|
+
|
|
58
|
+
const editor_controls = enableEditor(engine, initializeEditor);
|
|
59
|
+
|
|
60
|
+
editor_controls.enable();
|
|
61
|
+
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
editor_controls.editor.selection.add(terrain_entity.entity);
|
|
64
|
+
}, 100);
|
|
65
|
+
|
|
66
|
+
console.warn(terrain);
|
|
67
|
+
}
|
|
@@ -5,6 +5,100 @@ import ObservedBoolean from "../../../core/model/ObservedBoolean.js";
|
|
|
5
5
|
import LabelView from "../../../view/common/LabelView.js";
|
|
6
6
|
import ButtonView from "../../../view/elements/button/ButtonView.js";
|
|
7
7
|
import EmptyView from "../../../view/elements/EmptyView.js";
|
|
8
|
+
import { downloadAsFile } from "../../../core/binary/ByteArrayTools.js";
|
|
9
|
+
|
|
10
|
+
export async function obtainClipBoard() {
|
|
11
|
+
if (navigator.clipboard === undefined) {
|
|
12
|
+
const queries = [{
|
|
13
|
+
name: "clipboard-read"
|
|
14
|
+
}, {
|
|
15
|
+
name: "clipboard-write"
|
|
16
|
+
}];
|
|
17
|
+
|
|
18
|
+
const permission_queries = queries.map(q => navigator.permissions.query(q));
|
|
19
|
+
|
|
20
|
+
const statuses = await Promise.all(permission_queries);
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < statuses.length; i++) {
|
|
23
|
+
const permissionStatus = statuses[i];
|
|
24
|
+
|
|
25
|
+
if (permissionStatus.state !== "granted") {
|
|
26
|
+
throw new Error(`Permission for query not granted (actual state = ${permissionStatus.state}). Query:${JSON.stringify(queries[i])}`)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return navigator.clipboard;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param {string} text
|
|
37
|
+
* @param {string} [data_name]
|
|
38
|
+
* @returns {Promise<void>}
|
|
39
|
+
*/
|
|
40
|
+
export async function safeClipboardWriteText(text, data_name = "data") {
|
|
41
|
+
|
|
42
|
+
return obtainClipBoard().then(
|
|
43
|
+
() => {
|
|
44
|
+
return navigator.clipboard.writeText(text);
|
|
45
|
+
},
|
|
46
|
+
() => {
|
|
47
|
+
// no clipboard available
|
|
48
|
+
console.log(`No clipboard available, downloading instead`);
|
|
49
|
+
downloadAsFile(text, `${data_name}.json`);
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function safeClipboardReadText() {
|
|
55
|
+
|
|
56
|
+
return obtainClipBoard().then(() => {
|
|
57
|
+
|
|
58
|
+
return navigator.clipboard.readText();
|
|
59
|
+
}, () => {
|
|
60
|
+
// clipboard not available
|
|
61
|
+
console.log(`No clipboard available, using a prompt instead`);
|
|
62
|
+
|
|
63
|
+
function clickElem(elem) {
|
|
64
|
+
// Thx user1601638 on Stack Overflow (6/6/2018 - https://stackoverflow.com/questions/13405129/javascript-create-and-save-file )
|
|
65
|
+
var eventMouse = document.createEvent("MouseEvents")
|
|
66
|
+
eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
|
|
67
|
+
elem.dispatchEvent(eventMouse)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function openFile(func) {
|
|
71
|
+
const fileInput = document.createElement("input");
|
|
72
|
+
|
|
73
|
+
const readFile = function (e) {
|
|
74
|
+
var file = e.target.files[0];
|
|
75
|
+
if (!file) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
var reader = new FileReader();
|
|
79
|
+
reader.onload = function (e) {
|
|
80
|
+
var contents = e.target.result;
|
|
81
|
+
fileInput.func(contents)
|
|
82
|
+
document.body.removeChild(fileInput)
|
|
83
|
+
}
|
|
84
|
+
reader.readAsText(file)
|
|
85
|
+
}
|
|
86
|
+
fileInput.type = 'file'
|
|
87
|
+
fileInput.style.display = 'none'
|
|
88
|
+
fileInput.onchange = readFile
|
|
89
|
+
fileInput.func = func
|
|
90
|
+
document.body.appendChild(fileInput)
|
|
91
|
+
clickElem(fileInput)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
openFile(resolve);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
}
|
|
8
102
|
|
|
9
103
|
/**
|
|
10
104
|
* @template T
|
|
@@ -16,9 +110,10 @@ export class ComponentControlView extends View {
|
|
|
16
110
|
* @param {T} component
|
|
17
111
|
* @param {EntityManager} entityManager
|
|
18
112
|
* @param {View} vController
|
|
113
|
+
* @param engine
|
|
19
114
|
* @constructor
|
|
20
115
|
*/
|
|
21
|
-
constructor(entity, component, entityManager, vController ) {
|
|
116
|
+
constructor(entity, component, entityManager, vController, engine) {
|
|
22
117
|
super();
|
|
23
118
|
|
|
24
119
|
this.signal = {
|
|
@@ -54,7 +149,7 @@ export class ComponentControlView extends View {
|
|
|
54
149
|
|
|
55
150
|
const bCopy = new ButtonView({
|
|
56
151
|
classList: ['copy'],
|
|
57
|
-
action() {
|
|
152
|
+
async action() {
|
|
58
153
|
const json = component.toJSON();
|
|
59
154
|
|
|
60
155
|
const data = JSON.stringify({
|
|
@@ -62,9 +157,9 @@ export class ComponentControlView extends View {
|
|
|
62
157
|
data: json
|
|
63
158
|
}, 3, 3);
|
|
64
159
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
);
|
|
160
|
+
safeClipboardWriteText(data, typeName).then(() => {
|
|
161
|
+
console.log(`${entity}:${typeName} dumped`);
|
|
162
|
+
});
|
|
68
163
|
}
|
|
69
164
|
});
|
|
70
165
|
|
|
@@ -72,8 +167,9 @@ export class ComponentControlView extends View {
|
|
|
72
167
|
|
|
73
168
|
const bPaste = new ButtonView({
|
|
74
169
|
classList: ['paste'],
|
|
75
|
-
action() {
|
|
76
|
-
|
|
170
|
+
async action() {
|
|
171
|
+
|
|
172
|
+
safeClipboardReadText().then(text => {
|
|
77
173
|
const json = JSON.parse(text);
|
|
78
174
|
|
|
79
175
|
if (json.type !== typeName) {
|
|
@@ -81,12 +177,11 @@ export class ComponentControlView extends View {
|
|
|
81
177
|
}
|
|
82
178
|
|
|
83
179
|
//get system
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
component.fromJSON(json.data, system);
|
|
180
|
+
component.fromJSON(json.data, engine);
|
|
87
181
|
|
|
88
182
|
console.log(`${entity}:${typeName} pasted from clip`);
|
|
89
183
|
});
|
|
184
|
+
|
|
90
185
|
}
|
|
91
186
|
});
|
|
92
187
|
|
|
@@ -182,7 +182,7 @@ class EntityEditor extends View {
|
|
|
182
182
|
});
|
|
183
183
|
vBody.addChild(view);
|
|
184
184
|
|
|
185
|
-
const controlView = new ComponentControlView(entityId, component, entityManager, vBody);
|
|
185
|
+
const controlView = new ComponentControlView(entityId, component, entityManager, vBody, editor.engine);
|
|
186
186
|
|
|
187
187
|
const Klass = component.constructor;
|
|
188
188
|
|
|
@@ -5,7 +5,6 @@ import { Frustum } from "three";
|
|
|
5
5
|
import { VisibilityFilter } from "../../graphics/render/visibility/VisibilityFilter.js";
|
|
6
6
|
import Vector4 from "../../../core/geom/Vector4.js";
|
|
7
7
|
import { Camera } from "../../graphics/ecs/camera/Camera.js";
|
|
8
|
-
import { computePerspectiveCameraFocalPosition, frustumFromCamera } from "../../graphics/ecs/camera/CameraSystem.js";
|
|
9
8
|
import WaterSystem from "../../graphics/ecs/water/WaterSystem.js";
|
|
10
9
|
import Vector3 from "../../../core/geom/Vector3.js";
|
|
11
10
|
import { BlendingType } from "../../graphics/texture/sampler/BlendingType.js";
|
|
@@ -13,6 +12,10 @@ import { FogOfWarRenderer } from "./shader/FogOfWarRenderer.js";
|
|
|
13
12
|
import { StandardFrameBuffers } from "../../graphics/StandardFrameBuffers.js";
|
|
14
13
|
import { CompositLayer } from "../../graphics/composit/CompositLayer.js";
|
|
15
14
|
import { CompositingStages } from "../../graphics/composit/CompositingStages.js";
|
|
15
|
+
import {
|
|
16
|
+
compute_perspective_camera_focal_position
|
|
17
|
+
} from "../../graphics/ecs/camera/compute_perspective_camera_focal_position.js";
|
|
18
|
+
import { frustum_from_camera } from "../../graphics/ecs/camera/frustum_from_camera.js";
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
const frustum = new Frustum();
|
|
@@ -70,7 +73,7 @@ export class FogOfWarSystem extends System {
|
|
|
70
73
|
|
|
71
74
|
objectPredicateInitialize: (camera) => {
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
compute_perspective_camera_focal_position(camera, cameraFocalPoint);
|
|
74
77
|
|
|
75
78
|
fog = null;
|
|
76
79
|
|
|
@@ -89,7 +92,7 @@ export class FogOfWarSystem extends System {
|
|
|
89
92
|
dataset.traverseComponents(Camera, c => {
|
|
90
93
|
if (c.active) {
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
frustum_from_camera(c.object, frustum);
|
|
93
96
|
|
|
94
97
|
const nearPlane = frustum.planes[4];
|
|
95
98
|
|
|
@@ -26,7 +26,7 @@ import { assert } from "../../../../core/assert.js";
|
|
|
26
26
|
import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
27
27
|
import { TerrainLayers } from "./layers/TerrainLayers.js";
|
|
28
28
|
import { SplatMaterial } from "../../../graphics/material/SplatMaterial.js";
|
|
29
|
-
import {
|
|
29
|
+
import { SplatMapping } from "./splat/SplatMapping.js";
|
|
30
30
|
import { OffsetScaleTransform2D } from "./OffsetScaleTransform2D.js";
|
|
31
31
|
import { GridTransformKind } from "./GridTransformKind.js";
|
|
32
32
|
import { makeTerrainWorkerProxy } from "./makeTerrainWorkerProxy.js";
|
|
@@ -36,6 +36,7 @@ import { TerrainFlags } from "./TerrainFlags.js";
|
|
|
36
36
|
import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalStateException.js";
|
|
37
37
|
import { buildLightTexture } from "./BuildLightTexture.js";
|
|
38
38
|
import { promiseSamplerHeight } from "./PromiseSamplerHeight.js";
|
|
39
|
+
import { loadLegacyTerrainSplats } from "./splat/loadLegacyTerrainSplats.js";
|
|
39
40
|
|
|
40
41
|
let idCounter = 0;
|
|
41
42
|
|
|
@@ -592,48 +593,6 @@ class Terrain {
|
|
|
592
593
|
result.set(x, y);
|
|
593
594
|
}
|
|
594
595
|
|
|
595
|
-
/**
|
|
596
|
-
*
|
|
597
|
-
* @param opt
|
|
598
|
-
* @param {TerrainSystem} terrainSystem
|
|
599
|
-
*/
|
|
600
|
-
fromJSON(opt, terrainSystem) {
|
|
601
|
-
// mark as needing rebuilding
|
|
602
|
-
this.clearFlag(TerrainFlags.Built);
|
|
603
|
-
|
|
604
|
-
if (opt === undefined) {
|
|
605
|
-
opt = {};
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
if (opt.preview !== undefined) {
|
|
609
|
-
this.preview.fromJSON(opt.preview);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/**
|
|
613
|
-
* Assumes lowest and highest points to be at the distance equal to half the range from 0
|
|
614
|
-
* @type {number}
|
|
615
|
-
*/
|
|
616
|
-
this.heightRange = opt.heightMapRange;
|
|
617
|
-
|
|
618
|
-
this.resolution = opt.resolution !== undefined ? opt.resolution : 4;
|
|
619
|
-
|
|
620
|
-
const size = this.size;
|
|
621
|
-
|
|
622
|
-
if (opt.size !== undefined) {
|
|
623
|
-
size.fromJSON(opt.size);
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
this.gridScale = opt.scale !== undefined ? opt.scale : 2;
|
|
627
|
-
//
|
|
628
|
-
|
|
629
|
-
this.heightMapURL = opt.heightMap;
|
|
630
|
-
this.materialDesc = opt.material;
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
// debugSamplers(this);
|
|
634
|
-
this.build(terrainSystem.assetManager);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
596
|
/**
|
|
638
597
|
*
|
|
639
598
|
* @return {Promise}
|
|
@@ -690,6 +649,15 @@ class Terrain {
|
|
|
690
649
|
this.layers.updateLayerScales(this.size.x * this.gridScale, this.size.y * this.gridScale);
|
|
691
650
|
}
|
|
692
651
|
|
|
652
|
+
/**
|
|
653
|
+
* Should be called after modifying heights to actualize changes
|
|
654
|
+
* @returns {Promise<void>}
|
|
655
|
+
*/
|
|
656
|
+
async updateHeights() {
|
|
657
|
+
this.updateHeightTexture();
|
|
658
|
+
await this.updateWorkerHeights();
|
|
659
|
+
}
|
|
660
|
+
|
|
693
661
|
updateHeightTexture() {
|
|
694
662
|
const sampler = this.samplerHeight;
|
|
695
663
|
const texture = this.heightTexture;
|
|
@@ -925,16 +893,58 @@ class Terrain {
|
|
|
925
893
|
return result;
|
|
926
894
|
}
|
|
927
895
|
|
|
896
|
+
/**
|
|
897
|
+
*
|
|
898
|
+
* @param opt
|
|
899
|
+
* @param {Engine} engine
|
|
900
|
+
*/
|
|
901
|
+
fromJSON(opt, engine) {
|
|
902
|
+
// mark as needing rebuilding
|
|
903
|
+
this.clearFlag(TerrainFlags.Built);
|
|
904
|
+
|
|
905
|
+
if (opt === undefined) {
|
|
906
|
+
opt = {};
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (opt.preview !== undefined) {
|
|
910
|
+
this.preview.fromJSON(opt.preview);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
this.resolution = opt.resolution !== undefined ? opt.resolution : 4;
|
|
914
|
+
|
|
915
|
+
const size = this.size;
|
|
916
|
+
|
|
917
|
+
if (opt.size !== undefined) {
|
|
918
|
+
size.fromJSON(opt.size);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
this.gridScale = opt.scale !== undefined ? opt.scale : 2;
|
|
922
|
+
//
|
|
923
|
+
|
|
924
|
+
this.materialDesc = opt.material;
|
|
925
|
+
|
|
926
|
+
this.samplerHeight.fromJSON(opt.heights);
|
|
927
|
+
this.layers.fromJSON(opt.layers);
|
|
928
|
+
this.splat.fromJSON(opt.splat);
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
// debugSamplers(this);
|
|
932
|
+
this.build(engine.assetManager);
|
|
933
|
+
}
|
|
934
|
+
|
|
928
935
|
toJSON() {
|
|
929
|
-
|
|
936
|
+
const result = {
|
|
930
937
|
size: this.size.toJSON(),
|
|
931
|
-
heightMapRange: this.heightRange,
|
|
932
938
|
scale: this.gridScale,
|
|
933
939
|
resolution: this.resolution,
|
|
934
|
-
heightMap: this.heightMapURL,
|
|
935
940
|
material: this.materialDesc,
|
|
936
|
-
preview: this.preview.toJSON()
|
|
941
|
+
preview: this.preview.toJSON(),
|
|
942
|
+
heights: this.samplerHeight.toJSON(),
|
|
943
|
+
layers: this.layers.toJSON(),
|
|
944
|
+
splat: this.splat.toJSON()
|
|
937
945
|
};
|
|
946
|
+
|
|
947
|
+
return result;
|
|
938
948
|
}
|
|
939
949
|
}
|
|
940
950
|
|
|
@@ -58,6 +58,20 @@ export class TerrainLayer {
|
|
|
58
58
|
this.onChanged = new Signal();
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
toJSON() {
|
|
62
|
+
return {
|
|
63
|
+
textureDiffuseURL: this.textureDiffuseURL,
|
|
64
|
+
size: this.size.toJSON(),
|
|
65
|
+
extra: this.extra
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fromJSON({ textureDiffuseURL, size, extra = {} }) {
|
|
70
|
+
this.textureDiffuseURL = textureDiffuseURL;
|
|
71
|
+
this.size.fromJSON(size);
|
|
72
|
+
this.extra = extra;
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
/**
|
|
62
76
|
*
|
|
63
77
|
* @param {string} url
|
|
@@ -120,9 +134,9 @@ export class TerrainLayer {
|
|
|
120
134
|
this.diffuse = Sampler2D.uint8(destination_item_size, image.width, image.height);
|
|
121
135
|
}
|
|
122
136
|
|
|
123
|
-
const source = new Sampler2D(source_data,source_item_size,image.width, image.height);
|
|
137
|
+
const source = new Sampler2D(source_data, source_item_size, image.width, image.height);
|
|
124
138
|
|
|
125
|
-
copy_Sampler2D_channel_data(source,this.diffuse);
|
|
139
|
+
copy_Sampler2D_channel_data(source, this.diffuse);
|
|
126
140
|
|
|
127
141
|
this.onChanged.send0();
|
|
128
142
|
|
|
@@ -158,6 +158,18 @@ export class TerrainLayers {
|
|
|
158
158
|
this.scalesTexture.generateMipmaps = false;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
toJSON() {
|
|
162
|
+
return {
|
|
163
|
+
resolution: this.resolution.toJSON(),
|
|
164
|
+
layers: this.layers.toJSON()
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
fromJSON({ resolution, layers }) {
|
|
169
|
+
this.resolution.fromJSON(resolution);
|
|
170
|
+
this.layers.fromJSON(layers, TerrainLayer);
|
|
171
|
+
}
|
|
172
|
+
|
|
161
173
|
/**
|
|
162
174
|
*
|
|
163
175
|
* @param {number} terrainWidth
|
|
@@ -330,10 +342,15 @@ export class TerrainLayers {
|
|
|
330
342
|
|
|
331
343
|
const arrayData = image.data;
|
|
332
344
|
|
|
345
|
+
|
|
333
346
|
const resolution = this.resolution;
|
|
334
347
|
|
|
335
348
|
const singleLayerByteSize = resolution.x * resolution.y * 3;
|
|
336
349
|
|
|
350
|
+
if (arrayData.length < singleLayerByteSize * index) {
|
|
351
|
+
throw new Error('Texture data is too small, make sure you rebuild texture data before attempting to write');
|
|
352
|
+
}
|
|
353
|
+
|
|
337
354
|
const address = singleLayerByteSize * index;
|
|
338
355
|
|
|
339
356
|
const sampler = this.__obtain_layer_data_at_resolution(layer, resolution);
|