UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

90 lines (65 loc) 2.44 kB
import { assert } from "../../../core/assert.js"; /** * Was originally written for TAA jitter sequence optimization in order to reduce maximum impulse * @template T * @param {T[]} sequence * @param {number} dimensions * @param {number} offset * @param {number} count * @param {function(address0:number, address1:number, sequence:T[]):number} cost_function * @param {*} [cost_function_ctx] */ export function optimize_cyclic_sequence_pairwise( sequence, dimensions, offset, count, cost_function, cost_function_ctx ) { assert.isNonNegativeInteger(dimensions, 'dimensions'); assert.isNonNegativeInteger(offset, 'offset'); assert.isNonNegativeInteger(count, 'count'); assert.isFunction(cost_function, 'cost_function'); let swaps = 0; let distance_max = (count - 1) >>> 1; function index_to_address(index) { const wrapped_index = (index + count) % count; return offset + wrapped_index * dimensions; } function move(from, to){ const i0 = index_to_address(from); const i1 = index_to_address(to); const clip = sequence.splice(i0, dimensions); sequence.splice(i1, 0, ...clip); } function pair_cost(i0, i1){ return cost_function.call(cost_function_ctx, index_to_address(i0), index_to_address(i1), sequence) } main: do { swaps = 0; for (let from = 0; from < count; from++) { for (let distance = -distance_max; distance <= distance_max; distance++) { if (distance === 0) { continue; } // estimate swap benefit const to = from+distance; const removal_gain = pair_cost(from-1, from+1) - ( pair_cost(from-1, from) + pair_cost(from, from+1) ); move(from, to); const insertion_gain = ( pair_cost(to-1, to) + pair_cost(to, to+1)) - pair_cost(to -1, to+1); const move_cost =insertion_gain + removal_gain; if (move_cost >= 0) { // bad swap, undo move(to, from); continue; } swaps++; continue main; } } } while (swaps > 0); }