@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
97 lines (66 loc) • 2.82 kB
JavaScript
import { assert } from "../../../core/assert.js";
import { lerp } from "../../../core/math/lerp.js";
import { min2 } from "../../../core/math/min2.js";
import { obtainTerrain } from "../../../engine/ecs/terrain/util/obtainTerrain.js";
import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
import { CellFilterLiteralFloat } from "../../filtering/numeric/CellFilterLiteralFloat.js";
import { ContinuousGridCellAction } from "./ContinuousGridCellAction.js";
export class ContinuousGridCellActionSetTerrainHeight extends ContinuousGridCellAction {
/**
*
* @type {Sampler2D}
*/
heightSampler = null;
/**
* Target height
* @type {CellFilter}
*/
target = CellFilterLiteralFloat.from(0);
initialize(seed, ecd, grid) {
super.initialize(seed, ecd, grid);
/**
*
* @type {Terrain}
*/
const terrain = obtainTerrain(ecd);
assert.notNull(terrain, 'terrain');
this.heightSampler = terrain.samplerHeight;
this.target.initialize(grid, seed);
}
execute(ecd, grid, x, y, rotation, strength) {
const g_width = grid.width;
const g_height = grid.height;
const sampler = this.heightSampler;
const h_width = sampler.width;
const h_height = sampler.height;
const scale_x = h_width / g_width;
const scale_y = h_height / g_height;
//convert coordinates from grid space to sampler space
const gs_x_1 = g_width - 1;
const gs_y_1 = g_height - 1;
const u = gs_x_1 > 0 ? x / gs_x_1 : 0;
const v = gs_y_1 > 0 ? y / gs_y_1 : 0;
const hs_x_1 = h_width - 1;
const hs_y_1 = h_height - 1;
const s_x = u * hs_x_1;
const s_y = v * hs_y_1;
//round down to nearest integer
const x0 = Math.floor(s_x);
const x1 = min2(hs_x_1, Math.ceil(s_x ));
const y0 = Math.floor(s_y);
const y1 = min2(hs_y_1, Math.ceil(s_y ));
for (let _y = y0; _y <= y1; _y++) {
//convert coordinates to grid space
const _gy = (_y / hs_y_1) * gs_y_1;
for (let _x = x0; _x <= x1; _x++) {
//convert coordinates to grid space
const _gx = (_x / hs_x_1) * gs_x_1;
const oldValue = sampler.readChannel(_x, _y, 0);
const strengthValue = strength.execute(grid, _gx, _gy, rotation);
const targetValue = this.target.execute(grid, _gx, _gy, rotation);
const newValue = lerp(oldValue, targetValue, strengthValue);
sampler.writeChannel(_x, _y, 0, newValue);
}
}
}
}