UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

122 lines (85 loc) 3.48 kB
import { assert } from "../../../../../core/assert.js"; import { vector_normalize } from "../../../../../core/geom/vec/vector_normalize.js"; import Vector2 from "../../../../../core/geom/Vector2.js"; import { deserializeSoundMaterialFromJSON } from "../../concrete/json/deserializeSoundMaterialFromJSON.js"; import { SilentSoundMaterial } from "../../concrete/SilentSoundMaterial.js"; import { SingleSoundMaterial } from "../../concrete/SingleSoundMaterial.js"; import { SoundMaterialComposition } from "../../concrete/SoundMaterialComposition.js"; import { SoundMaterialSurfaceDetector } from "../SoundMaterialSurfaceDetector.js"; const v2_temp = new Vector2(); export class TerrainSoundMaterialSurfaceDetector extends SoundMaterialSurfaceDetector { constructor() { super(); /** * * @type {AbstractSoundMaterialDefinition[]} */ this.materials = []; /** * * @type {Terrain} * @private */ this.__terrain = null; /** * * @type {SoundMaterialComposition} * @private */ this.__composite = new SoundMaterialComposition(); this.__composite.setVolumeThreshold(0.1); } loadMaterialsFromJSON(json) { assert.isArray(json, 'json'); for (let i = 0; i < json.length; i++) { const jEl = json[i]; const material = SingleSoundMaterial.fromJSON(jEl); this.materials[i] = material; } } /** * * @param {Terrain} terrain */ initialize(terrain) { this.__terrain = terrain; // initialize composite material const layer_count = terrain.layers.count(); for (let i = 0; i < layer_count; i++) { const terrainLayer = terrain.layers.get(i); // attempt to extract information from the layer const soundMaterial = terrainLayer.extra.soundMaterial; if (soundMaterial === undefined) { // no material set this.setLayerMaterial(i, SilentSoundMaterial.INSTANCE); } else { this.setLayerMaterial(i, deserializeSoundMaterialFromJSON(soundMaterial)); } } } /** * * @param {number} layer_index * @param {AbstractSoundMaterialDefinition} material */ setLayerMaterial(layer_index, material) { assert.isNumber(layer_index, 'layer_index'); assert.isNonNegativeInteger(layer_index, 'layer_index'); this.materials[layer_index] = material; this.__composite.setMaterial(layer_index, material, 1); } detect(thing, point, interaction) { this.__terrain.mapPointWorld2Grid(point, v2_temp); const u = v2_temp.x / this.__terrain.size.x; const v = v2_temp.y / this.__terrain.size.y; const layer_count = this.__terrain.layers.count(); const result = []; for (let i = 0; i < layer_count; i++) { const weight = this.__terrain.splat.sampleWeight(u, v, i); this.__composite.weights[i] = weight; } vector_normalize(this.__composite.weights, this.__composite.weights, layer_count); const additions = this.__composite.computeInteractionSounds(result, 0, interaction); return result; } }