@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
219 lines (159 loc) • 7.59 kB
JavaScript
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);
}
}