UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

219 lines (159 loc) • 7.59 kB
import Signal from "../../../../src/core/events/signal/Signal.js"; import Vector2 from "../../../../src/core/geom/Vector2.js"; import ObservedValue from "../../../../src/core/model/ObservedValue.js"; import { TerrainLayer } from "../../../../src/engine/ecs/terrain/ecs/layers/TerrainLayer.js"; import CheckersTextureURI from "../../../../src/engine/graphics/texture/CheckersTextureURI.js"; import { sampler2d_scale } from "../../../../src/engine/graphics/texture/sampler/resize/sampler2d_scale.js"; import { Sampler2D } from "../../../../src/engine/graphics/texture/sampler/Sampler2D.js"; import sampler2d_to_html_canvas from "../../../../src/engine/graphics/texture/sampler/sampler2d_to_html_canvas.js"; import LabelView from "../../../../src/view/common/LabelView.js"; import { NativeListController } from "../../../../src/view/controller/controls/NativeListController.js"; import Vector2Control from "../../../../src/view/controller/controls/Vector2Control.js"; import { CanvasView } from "../../../../src/view/elements/CanvasView.js"; import EmptyView from "../../../../src/view/elements/EmptyView.js"; import GroupView from "../../../../src/view/elements/Group.js"; import View from "../../../../src/view/View.js"; import DatGuiController from "./DatGuiController.js"; class LayersController extends View { /** * * @param {Terrain} terrain * @param {TerrainLayers} layers * @param {AssetManager} assetManager */ constructor({ terrain, layers, assetManager }) { super(); this.el = document.createElement('div'); this.addClass('ui-terrain-layers-controller-view'); function updateLayers() { terrain.layers.buildTexture(); terrain.layers.writeAllLayersDataIntoTexture(); terrain.updateMaterial(); } const updateBus = new Signal(); this.bindSignal(layers.layers.on.added, () => { terrain.splat.addWeightLayer(); }); this.bindSignal(layers.layers.on.removed, (layer, index) => { terrain.splat.removeWeightLayer(index); updateLayers(); }); this.addChild( new NativeListController({ model: layers.layers, elementFactory() { const layer = new TerrainLayer(); layer.textureDiffuseURL = CheckersTextureURI; layer.size.set(1, 1); layer.loadTextureData(assetManager) .then(() => { updateLayers(); updateBus.send1(layer); }); return layer; }, /** * * @param {TerrainLayer} layer * @return {View} */ elementViewFactory(layer) { const v = new EmptyView(); v.bindSignal(updateBus, (l) => { if (l === layer) { update(); } }); v.addClass('ui-terrain-layer-controller-view'); const vCanvas = new CanvasView(); vCanvas.size.set(64, 64); const t = Sampler2D.uint8(layer.diffuse.itemSize, 64, 64); function update() { sampler2d_scale(layer.diffuse, t); sampler2d_to_html_canvas(t, 1, 0, vCanvas.el); } update(); v.addChild(vCanvas); const vURL = new EmptyView({ classList: ['url'], tag: 'input' }); const elValue = vURL.el; elValue.setAttribute('type', 'text'); elValue.value = layer.textureDiffuseURL; elValue.addEventListener('input', () => { const v = elValue.value; layer.textureDiffuseURL = v; layer.loadTextureData(assetManager).then(() => { update(); const index = layers.layers.indexOf(layer); layers.writeLayerDataIntoTexture(index); }); }); const vSize = new Vector2Control(); vSize.model.set(layer.size); v.bindSignal(layer.size.onChanged, terrain.updateMaterial, terrain); const groupView = new GroupView(); groupView.add(new LabelView('size')); groupView.add(vSize); v.addChild(groupView); v.addChild(vURL); return v; } }) ); } } export class TerrainController extends View { /** * * @param {AssetManager} assetManager */ constructor(assetManager) { super(); this.el = document.createElement('div'); this.model = new ObservedValue(null); const self = this; /** * * @param {Terrain} model */ function setModel(model) { self.removeAllChildren(); const controller = new DatGuiController(); self.addChild(controller); if (model !== null) { controller.addAction(() => { model.__tiles.rebuild(); }, 'Rebuild'); controller.add(model, 'size', { step: 1 }); controller.add(model, 'resolution').step(1); controller.add(model, 'gridScale').step(1).name('Gird Size'); const proxy = { heightResolution: new Vector2(model.samplerHeight.width, model.samplerHeight.height), weightResolution: new Vector2(model.splat.size.x, model.splat.size.y), layerResolution: new Vector2(model.layers.resolution.x, model.layers.resolution.y), }; proxy.heightResolution.onChanged.add((x, y) => { model.samplerHeight.resize(x, y); }); proxy.weightResolution.onChanged.add((x, y) => { model.splat.resize(x, y, model.splat.depth); }); proxy.layerResolution.onChanged.add((x, y) => { model.layers.resolution.set(x, y); model.layers.buildTexture(); model.layers.writeAllLayersDataIntoTexture(); }); controller.add(proxy, 'heightResolution', { step: 1 }); controller.add(proxy, 'weightResolution', { step: 1 }); controller.add(proxy, 'layerResolution', { step: 1 }); if (model.preview.url === null) { model.preview.url = ''; } controller.add(model.preview, 'url').name('preview url'); controller.add(model.preview, 'offset'); controller.add(model.preview, 'scale'); self.addChild(new LayersController({ terrain: model, layers: model.layers, assetManager })); } } this.model.onChanged.add(setModel); } }