@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
126 lines (85 loc) • 3.23 kB
JavaScript
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";