UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

126 lines (85 loc) 3.23 kB
import { PointFitnessFunction } from "../PointFitnessFunction.js"; import { assert } from "../../../../core/assert.js"; import { gaussian } from "../../../../core/math/gaussian.js"; export class PointFitnessGaussianBlur extends PointFitnessFunction { constructor() { super(); this.samples_x = 5; this.samples_y = 5; this.samples_z = 5; this.sigma_x = 10; this.sigma_y = 10; this.sigma_z = 10; this.size_x = 1; this.size_y = 1; this.size_z = 1; /** * * @type {PointFitnessFunction} */ this.source = null; } /** * * @param {PointFitnessFunction} source * @param {number} x * @param {number} y * @param {number} z * @param {number} [quality] * @returns {PointFitnessGaussianBlur} */ static from(source, x, y, z, quality = 5) { assert.isNumber(x, 'x'); assert.isNumber(y, 'y'); assert.isNumber(z, 'z'); assert.isNumber(quality, 'quality'); assert.equal(source.isPointFitnessFunction, true, 'source.isPointFitnessFunction !== true'); const r = new PointFitnessGaussianBlur(); r.source = source; r.samples_x = x * quality; r.samples_y = y * quality; r.samples_z = z * quality; r.size_x = x; r.size_y = y; r.size_z = z; return r; } evaluate(ecd, x, y, z) { const samplesX = this.samples_x; const samplesY = this.samples_y; const samplesZ = this.samples_z; const half_samples_x = (samplesX / 2); const half_samples_y = (samplesY / 2); const half_samples_z = (samplesZ / 2); const sizeX = this.size_x; const sizeY = this.size_y; const sizeZ = this.size_z; let sum = 0; let powerTotal = 0; for (let iz = 0; iz < samplesZ; iz++) { const local_z = iz - half_samples_z; const fz = gaussian(this.sigma_z, local_z); const nz = local_z / samplesZ; const offset_z = sizeZ * nz; for (let iy = 0; iy < samplesY; iy++) { const local_y = iy - half_samples_y; const fy = gaussian(this.sigma_y, local_y); const ny = local_y / samplesY; const offset_y = sizeY * ny; for (let ix = 0; ix < samplesX; ix++) { const local_x = ix - half_samples_x; const fx = gaussian(this.sigma_x, local_x); const nx = local_x / samplesX; const offset_x = sizeX * nx; const power = fx * fy * fz; powerTotal += power; const sourceValue = this.source.evaluate(ecd, x + offset_x, y + offset_y, z + offset_z); sum += sourceValue * power; } } } const result = sum / powerTotal; return result; } } PointFitnessGaussianBlur.prototype.type = "PointFitnessGaussianBlur";