securityos/node_modules/butterchurn/dist/butterchurn.js

10659 lines
447 KiB
JavaScript

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("butterchurn", [], factory);
else if(typeof exports === 'object')
exports["butterchurn"] = factory();
else
root["butterchurn"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./node_modules/@assemblyscript/loader/index.js":
/*!******************************************************!*\
!*** ./node_modules/@assemblyscript/loader/index.js ***!
\******************************************************/
/*! exports provided: instantiate, instantiateSync, instantiateStreaming, demangle, default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "instantiate", function() { return instantiate; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "instantiateSync", function() { return instantiateSync; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "instantiateStreaming", function() { return instantiateStreaming; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "demangle", function() { return demangle; });
// Runtime header offsets
const ID_OFFSET = -8;
const SIZE_OFFSET = -4;
// Runtime ids
const ARRAYBUFFER_ID = 0;
const STRING_ID = 1;
// const ARRAYBUFFERVIEW_ID = 2;
// Runtime type information
const ARRAYBUFFERVIEW = 1 << 0;
const ARRAY = 1 << 1;
const STATICARRAY = 1 << 2;
// const SET = 1 << 3;
// const MAP = 1 << 4;
const VAL_ALIGN_OFFSET = 6;
// const VAL_ALIGN = 1 << VAL_ALIGN_OFFSET;
const VAL_SIGNED = 1 << 11;
const VAL_FLOAT = 1 << 12;
// const VAL_NULLABLE = 1 << 13;
const VAL_MANAGED = 1 << 14;
// const KEY_ALIGN_OFFSET = 15;
// const KEY_ALIGN = 1 << KEY_ALIGN_OFFSET;
// const KEY_SIGNED = 1 << 20;
// const KEY_FLOAT = 1 << 21;
// const KEY_NULLABLE = 1 << 22;
// const KEY_MANAGED = 1 << 23;
// Array(BufferView) layout
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0;
const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4;
const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8;
const ARRAYBUFFERVIEW_SIZE = 12;
const ARRAY_LENGTH_OFFSET = 12;
const ARRAY_SIZE = 16;
const BIGINT = typeof BigUint64Array !== "undefined";
const THIS = Symbol();
const STRING_DECODE_THRESHOLD = 32;
const decoder = new TextDecoder("utf-16le");
/** Gets a string from an U32 and an U16 view on a memory. */
function getStringImpl(buffer, ptr) {
const len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1;
const arr = new Uint16Array(buffer, ptr, len);
if (len <= STRING_DECODE_THRESHOLD) {
return String.fromCharCode.apply(String, arr);
}
return decoder.decode(arr);
}
/** Prepares the base module prior to instantiation. */
function preInstantiate(imports) {
const extendedExports = {};
function getString(memory, ptr) {
if (!memory) return "<yet unknown>";
return getStringImpl(memory.buffer, ptr);
}
// add common imports used by stdlib for convenience
const env = (imports.env = imports.env || {});
env.abort = env.abort || function abort(msg, file, line, colm) {
const memory = extendedExports.memory || env.memory; // prefer exported, otherwise try imported
throw Error(`abort: ${getString(memory, msg)} at ${getString(memory, file)}:${line}:${colm}`);
};
env.trace = env.trace || function trace(msg, n, ...args) {
const memory = extendedExports.memory || env.memory;
console.log(`trace: ${getString(memory, msg)}${n ? " " : ""}${args.slice(0, n).join(", ")}`);
};
env.seed = env.seed || Date.now;
imports.Math = imports.Math || Math;
imports.Date = imports.Date || Date;
return extendedExports;
}
/** Prepares the final module once instantiation is complete. */
function postInstantiate(extendedExports, instance) {
const exports = instance.exports;
const memory = exports.memory;
const table = exports.table;
const __new = exports["__new"];
const __retain = exports["__retain"];
const __rtti_base = exports["__rtti_base"] || ~0; // oob if not present
/** Gets the runtime type info for the given id. */
function getInfo(id) {
const U32 = new Uint32Array(memory.buffer);
const count = U32[__rtti_base >>> 2];
if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`);
return U32[(__rtti_base + 4 >>> 2) + id * 2];
}
/** Gets and validate runtime type info for the given id for array like objects */
function getArrayInfo(id) {
const info = getInfo(id);
if (!(info & (ARRAYBUFFERVIEW | ARRAY | STATICARRAY))) throw Error(`not an array: ${id}, flags=${info}`);
return info;
}
/** Gets the runtime base id for the given id. */
function getBase(id) {
const U32 = new Uint32Array(memory.buffer);
const count = U32[__rtti_base >>> 2];
if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`);
return U32[(__rtti_base + 4 >>> 2) + id * 2 + 1];
}
/** Gets the runtime alignment of a collection's values. */
function getValueAlign(info) {
return 31 - Math.clz32((info >>> VAL_ALIGN_OFFSET) & 31); // -1 if none
}
/** Gets the runtime alignment of a collection's keys. */
// function getKeyAlign(info) {
// return 31 - Math.clz32((info >>> KEY_ALIGN_OFFSET) & 31); // -1 if none
// }
/** Allocates a new string in the module's memory and returns its retained pointer. */
function __newString(str) {
if (str == null) return 0;
const length = str.length;
const ptr = __new(length << 1, STRING_ID);
const U16 = new Uint16Array(memory.buffer);
for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i);
return ptr;
}
extendedExports.__newString = __newString;
/** Reads a string from the module's memory by its pointer. */
function __getString(ptr) {
if (!ptr) return null;
const buffer = memory.buffer;
const id = new Uint32Array(buffer)[ptr + ID_OFFSET >>> 2];
if (id !== STRING_ID) throw Error(`not a string: ${ptr}`);
return getStringImpl(buffer, ptr);
}
extendedExports.__getString = __getString;
/** Gets the view matching the specified alignment, signedness and floatness. */
function getView(alignLog2, signed, float) {
const buffer = memory.buffer;
if (float) {
switch (alignLog2) {
case 2: return new Float32Array(buffer);
case 3: return new Float64Array(buffer);
}
} else {
switch (alignLog2) {
case 0: return new (signed ? Int8Array : Uint8Array)(buffer);
case 1: return new (signed ? Int16Array : Uint16Array)(buffer);
case 2: return new (signed ? Int32Array : Uint32Array)(buffer);
case 3: return new (signed ? BigInt64Array : BigUint64Array)(buffer);
}
}
throw Error(`unsupported align: ${alignLog2}`);
}
/** Allocates a new array in the module's memory and returns its retained pointer. */
function __newArray(id, values) {
const info = getArrayInfo(id);
const align = getValueAlign(info);
const length = values.length;
const buf = __new(length << align, info & STATICARRAY ? id : ARRAYBUFFER_ID);
let result;
if (info & STATICARRAY) {
result = buf;
} else {
const arr = __new(info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE, id);
const U32 = new Uint32Array(memory.buffer);
U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = __retain(buf);
U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf;
U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align;
if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
result = arr;
}
const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
if (info & VAL_MANAGED) {
for (let i = 0; i < length; ++i) view[(buf >>> align) + i] = __retain(values[i]);
} else {
view.set(values, buf >>> align);
}
return result;
}
extendedExports.__newArray = __newArray;
/** Gets a live view on an array's values in the module's memory. Infers the array type from RTTI. */
function __getArrayView(arr) {
const U32 = new Uint32Array(memory.buffer);
const id = U32[arr + ID_OFFSET >>> 2];
const info = getArrayInfo(id);
const align = getValueAlign(info);
let buf = info & STATICARRAY
? arr
: U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
const length = info & ARRAY
? U32[arr + ARRAY_LENGTH_OFFSET >>> 2]
: U32[buf + SIZE_OFFSET >>> 2] >>> align;
return getView(align, info & VAL_SIGNED, info & VAL_FLOAT).subarray(buf >>>= align, buf + length);
}
extendedExports.__getArrayView = __getArrayView;
/** Copies an array's values from the module's memory. Infers the array type from RTTI. */
function __getArray(arr) {
const input = __getArrayView(arr);
const len = input.length;
const out = new Array(len);
for (let i = 0; i < len; i++) out[i] = input[i];
return out;
}
extendedExports.__getArray = __getArray;
/** Copies an ArrayBuffer's value from the module's memory. */
function __getArrayBuffer(ptr) {
const buffer = memory.buffer;
const length = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2];
return buffer.slice(ptr, ptr + length);
}
extendedExports.__getArrayBuffer = __getArrayBuffer;
/** Copies a typed array's values from the module's memory. */
function getTypedArray(Type, alignLog2, ptr) {
return new Type(getTypedArrayView(Type, alignLog2, ptr));
}
/** Gets a live view on a typed array's values in the module's memory. */
function getTypedArrayView(Type, alignLog2, ptr) {
const buffer = memory.buffer;
const U32 = new Uint32Array(buffer);
const bufPtr = U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2);
}
/** Attach a set of get TypedArray and View functions to the exports. */
function attachTypedArrayFunctions(ctor, name, align) {
extendedExports[`__get${name}`] = getTypedArray.bind(null, ctor, align);
extendedExports[`__get${name}View`] = getTypedArrayView.bind(null, ctor, align);
}
[
Int8Array,
Uint8Array,
Uint8ClampedArray,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Float32Array,
Float64Array
].forEach(ctor => {
attachTypedArrayFunctions(ctor, ctor.name, 31 - Math.clz32(ctor.BYTES_PER_ELEMENT));
});
if (BIGINT) {
[BigUint64Array, BigInt64Array].forEach(ctor => {
attachTypedArrayFunctions(ctor, ctor.name.slice(3), 3);
});
}
/** Tests whether an object is an instance of the class represented by the specified base id. */
function __instanceof(ptr, baseId) {
const U32 = new Uint32Array(memory.buffer);
let id = U32[ptr + ID_OFFSET >>> 2];
if (id <= U32[__rtti_base >>> 2]) {
do {
if (id == baseId) return true;
id = getBase(id);
} while (id);
}
return false;
}
extendedExports.__instanceof = __instanceof;
// Pull basic exports to extendedExports so code in preInstantiate can use them
extendedExports.memory = extendedExports.memory || memory;
extendedExports.table = extendedExports.table || table;
// Demangle exports and provide the usual utility on the prototype
return demangle(exports, extendedExports);
}
function isResponse(src) {
return typeof Response !== "undefined" && src instanceof Response;
}
function isModule(src) {
return src instanceof WebAssembly.Module;
}
/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */
async function instantiate(source, imports = {}) {
if (isResponse(source = await source)) return instantiateStreaming(source, imports);
const module = isModule(source) ? source : await WebAssembly.compile(source);
const extended = preInstantiate(imports);
const instance = await WebAssembly.instantiate(module, imports);
const exports = postInstantiate(extended, instance);
return { module, instance, exports };
}
/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */
function instantiateSync(source, imports = {}) {
const module = isModule(source) ? source : new WebAssembly.Module(source);
const extended = preInstantiate(imports);
const instance = new WebAssembly.Instance(module, imports);
const exports = postInstantiate(extended, instance);
return { module, instance, exports };
}
/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */
async function instantiateStreaming(source, imports = {}) {
if (!WebAssembly.instantiateStreaming) {
return instantiate(
isResponse(source = await source)
? source.arrayBuffer()
: source,
imports
);
}
const extended = preInstantiate(imports);
const result = await WebAssembly.instantiateStreaming(source, imports);
const exports = postInstantiate(extended, result.instance);
return { ...result, exports };
}
/** Demangles an AssemblyScript module's exports to a friendly object structure. */
function demangle(exports, extendedExports = {}) {
const setArgumentsLength = exports["__argumentsLength"]
? length => { exports["__argumentsLength"].value = length; }
: exports["__setArgumentsLength"] || exports["__setargc"] || (() => { /* nop */ });
for (let internalName in exports) {
if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue;
const elem = exports[internalName];
let parts = internalName.split(".");
let curr = extendedExports;
while (parts.length > 1) {
let part = parts.shift();
if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {};
curr = curr[part];
}
let name = parts[0];
let hash = name.indexOf("#");
if (hash >= 0) {
const className = name.substring(0, hash);
const classElem = curr[className];
if (typeof classElem === "undefined" || !classElem.prototype) {
const ctor = function(...args) {
return ctor.wrap(ctor.prototype.constructor(0, ...args));
};
ctor.prototype = {
valueOf() { return this[THIS]; }
};
ctor.wrap = function(thisValue) {
return Object.create(ctor.prototype, { [THIS]: { value: thisValue, writable: false } });
};
if (classElem) Object.getOwnPropertyNames(classElem).forEach(name =>
Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name))
);
curr[className] = ctor;
}
name = name.substring(hash + 1);
curr = curr[className].prototype;
if (/^(get|set):/.test(name)) {
if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
let getter = exports[internalName.replace("set:", "get:")];
let setter = exports[internalName.replace("get:", "set:")];
Object.defineProperty(curr, name, {
get() { return getter(this[THIS]); },
set(value) { setter(this[THIS], value); },
enumerable: true
});
}
} else {
if (name === 'constructor') {
(curr[name] = (...args) => {
setArgumentsLength(args.length);
return elem(...args);
}).original = elem;
} else { // instance method
(curr[name] = function(...args) { // !
setArgumentsLength(args.length);
return elem(this[THIS], ...args);
}).original = elem;
}
}
} else {
if (/^(get|set):/.test(name)) {
if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) {
Object.defineProperty(curr, name, {
get: exports[internalName.replace("set:", "get:")],
set: exports[internalName.replace("get:", "set:")],
enumerable: true
});
}
} else if (typeof elem === "function" && elem !== setArgumentsLength) {
(curr[name] = (...args) => {
setArgumentsLength(args.length);
return elem(...args);
}).original = elem;
} else {
curr[name] = elem;
}
}
}
return extendedExports;
}
/* harmony default export */ __webpack_exports__["default"] = ({
instantiate,
instantiateSync,
instantiateStreaming,
demangle
});
/***/ }),
/***/ "./node_modules/@babel/runtime/helpers/defineProperty.js":
/*!***************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/defineProperty.js ***!
\***************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
module.exports = _defineProperty;
/***/ }),
/***/ "./node_modules/ecma-proposal-math-extensions/reference-implementation/index.js":
/*!**************************************************************************************!*\
!*** ./node_modules/ecma-proposal-math-extensions/reference-implementation/index.js ***!
\**************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
{
const defineMath = (name, assignment) => {
var configurable = typeof assignment === "function" ? true : false;
var writable = typeof assignment === "function" ? true : false;
var enumerable = typeof assignment === "function" ? true : false;
Object.defineProperty(Math, name, {
configurable: configurable,
enumerable: enumerable,
writable: writable,
value: assignment
});
};
defineMath("DEG_PER_RAD", Math.PI / 180);
defineMath("RAD_PER_DEG", 180 / Math.PI);
const f32A = new Float32Array(1);
defineMath("scale", function scale(x, inLow, inHigh, outLow, outHigh) {
if (arguments.length === 0) {
return NaN;
}
if (Number.isNaN(x) ||
Number.isNaN(inLow) ||
Number.isNaN(inHigh) ||
Number.isNaN(outLow) ||
Number.isNaN(outHigh)) {
return NaN;
}
if (x === Infinity ||
x === -Infinity) {
return x;
}
return (x - inLow) * (outHigh - outLow) /
(inHigh - inLow) + outLow;
});
defineMath("fscale", function fscale(x, inLow, inHigh, outLow, outHigh) {
f32A[0] = Math.scale(x, inLow, inHigh, outLow, outHigh);
return f32A[0];
});
defineMath("clamp", function clamp(x, lower, upper) {
return Math.min(upper, Math.max(lower, x));
});
defineMath("radians", function radians(degrees) {
return degrees * Math.DEG_PER_RAD;
});
defineMath("degrees", function degrees(radians) {
return radians * Math.RAD_PER_DEG;
});
}
/***/ }),
/***/ "./node_modules/eel-wasm/dist/build/parser.js":
/*!****************************************************!*\
!*** ./node_modules/eel-wasm/dist/build/parser.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(module, process) {/* parser generated by jison 0.4.18 */
/*
Returns a Parser object of the following structure:
Parser: {
yy: {}
}
Parser.prototype: {
yy: {},
trace: function(),
symbols_: {associative list: name ==> number},
terminals_: {associative list: number ==> name},
productions_: [...],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
table: [...],
defaultActions: {...},
parseError: function(str, hash),
parse: function(input),
lexer: {
EOF: 1,
parseError: function(str, hash),
setInput: function(input),
input: function(),
unput: function(str),
more: function(),
less: function(n),
pastInput: function(),
upcomingInput: function(),
showPosition: function(),
test_match: function(regex_match_array, rule_index),
next: function(),
lex: function(),
begin: function(condition),
popState: function(),
_currentRules: function(),
topState: function(),
pushState: function(condition),
options: {
ranges: boolean (optional: true ==> token location info will include a .range[] member)
flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
},
performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
rules: [...],
conditions: {associative list: name ==> set},
}
}
token location info (@$, _$, etc.): {
first_line: n,
last_line: n,
first_column: n,
last_column: n,
range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
}
the parseError function receives a 'hash' object with these members for lexer and parser errors: {
text: (matched text)
token: (the produced terminal token, if any)
line: (yylineno)
}
while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
loc: (yylloc)
expected: (string describing the set of expected tokens)
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
}
*/
var parser = (function () {
var o = function (k, v, o, l) { for (o = o || {}, l = k.length; l--; o[k[l]] = v)
; return o; }, $V0 = [1, 18], $V1 = [1, 7], $V2 = [1, 19], $V3 = [1, 20], $V4 = [1, 14], $V5 = [1, 15], $V6 = [1, 16], $V7 = [1, 33], $V8 = [1, 31], $V9 = [1, 23], $Va = [1, 22], $Vb = [1, 24], $Vc = [1, 25], $Vd = [1, 26], $Ve = [1, 27], $Vf = [1, 28], $Vg = [1, 29], $Vh = [1, 30], $Vi = [5, 8, 15, 18, 20, 28, 29, 32, 33, 34, 35, 36, 37, 38], $Vj = [5, 15, 18], $Vk = [5, 12, 15, 17, 18, 24, 25, 28, 29, 30], $Vl = [1, 57], $Vm = [5, 8, 12, 15, 17, 18, 24, 25, 28, 29, 30], $Vn = [15, 18], $Vo = [5, 8, 15, 18, 28, 29, 38], $Vp = [5, 8, 15, 18, 28, 29, 32, 33, 38], $Vq = [5, 8, 15, 18, 28, 29, 32, 33, 34, 37, 38], $Vr = [5, 8, 15, 18, 28, 29, 32, 33, 34, 35, 36, 37, 38], $Vs = [5, 8, 15, 18], $Vt = [5, 8, 15, 18, 20, 22, 28, 29, 32, 33, 34, 35, 36, 37, 38];
var parser = { trace: function trace() { },
yy: {},
symbols_: { "error": 2, "SCRIPT": 3, "expression": 4, "EOF": 5, "expressionsOptionalTrailingSemi": 6, "separator": 7, ";": 8, "expressions": 9, "EXPRESSION_BLOCK": 10, "IDENTIFIER": 11, "IDENTIFIER_TOKEN": 12, "argument": 13, "arguments": 14, ",": 15, "FUNCTION_CALL": 16, "(": 17, ")": 18, "LOGICAL_EXPRESSION": 19, "LOGICAL_OPERATOR_TOKEN": 20, "ASSIGNMENT": 21, "ASSIGNMENT_OPERATOR_TOKEN": 22, "number": 23, "DIGITS_TOKEN": 24, ".": 25, "NUMBER_LITERAL": 26, "UNARY_EXPRESSION": 27, "-": 28, "+": 29, "!": 30, "BINARY_EXPRESSION": 31, "*": 32, "/": 33, "%": 34, "&": 35, "|": 36, "^": 37, "COMPARISON_TOKEN": 38, "$accept": 0, "$end": 1 },
terminals_: { 2: "error", 5: "EOF", 8: ";", 12: "IDENTIFIER_TOKEN", 15: ",", 17: "(", 18: ")", 20: "LOGICAL_OPERATOR_TOKEN", 22: "ASSIGNMENT_OPERATOR_TOKEN", 24: "DIGITS_TOKEN", 25: ".", 28: "-", 29: "+", 30: "!", 32: "*", 33: "/", 34: "%", 35: "&", 36: "|", 37: "^", 38: "COMPARISON_TOKEN" },
productions_: [0, [3, 2], [3, 2], [3, 1], [7, 1], [7, 2], [9, 2], [9, 3], [6, 1], [6, 2], [10, 1], [11, 1], [13, 1], [13, 1], [14, 1], [14, 3], [16, 3], [16, 4], [19, 3], [21, 3], [21, 3], [23, 1], [23, 2], [23, 3], [23, 2], [23, 1], [26, 1], [27, 2], [27, 2], [27, 2], [31, 3], [31, 3], [31, 3], [31, 3], [31, 3], [31, 3], [31, 3], [31, 3], [31, 3], [4, 1], [4, 1], [4, 3], [4, 1], [4, 1], [4, 1], [4, 1], [4, 1], [4, 3]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
return { type: 'SCRIPT', body: [$$[$0 - 1]], loc: this._$ };
break;
case 2:
return { type: 'SCRIPT', body: $$[$0 - 1], loc: this._$ };
break;
case 3:
return { type: 'SCRIPT', body: [], loc: this._$ };
break;
case 6:
this.$ = [$$[$0 - 1]];
break;
case 7:
this.$ = $$[$0 - 2].concat([$$[$0 - 1]]);
break;
case 8:
this.$ = $$[$0];
break;
case 9:
this.$ = $$[$0 - 1].concat([$$[$0]]);
break;
case 10:
this.$ = { type: 'EXPRESSION_BLOCK', body: $$[$0], loc: this._$ };
break;
case 11:
this.$ = { type: 'IDENTIFIER', value: $$[$0].toLowerCase(), loc: this._$ };
break;
case 14:
this.$ = [$$[$0]];
break;
case 15:
this.$ = $$[$0 - 2].concat([$$[$0]]);
break;
case 16:
this.$ = { type: 'CALL_EXPRESSION', callee: $$[$0 - 2], arguments: [], loc: this._$ };
break;
case 17:
this.$ = { type: 'CALL_EXPRESSION', callee: $$[$0 - 3], arguments: $$[$0 - 1], loc: this._$ };
break;
case 18:
this.$ = { type: 'LOGICAL_EXPRESSION', left: $$[$0 - 2], right: $$[$0], operator: $$[$0 - 1], loc: this._$ };
break;
case 19:
case 20:
this.$ = { type: 'ASSIGNMENT_EXPRESSION', left: $$[$0 - 2], operator: $$[$0 - 1], right: $$[$0], loc: this._$ };
break;
case 21:
this.$ = Number($$[$0]);
break;
case 22:
this.$ = Number($$[$0 - 1]);
break;
case 23:
this.$ = Number($$[$0 - 2] + $$[$0 - 1] + $$[$0]);
break;
case 24:
this.$ = Number('0' + $$[$0 - 1] + $$[$0]);
break;
case 25:
this.$ = 0;
break;
case 26:
this.$ = { type: 'NUMBER_LITERAL', value: $$[$0], loc: this._$ };
break;
case 27:
case 28:
case 29:
this.$ = { type: 'UNARY_EXPRESSION', value: $$[$0], operator: $$[$0 - 1], loc: this._$ };
break;
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
this.$ = { type: 'BINARY_EXPRESSION', left: $$[$0 - 2], right: $$[$0], operator: $$[$0 - 1], loc: this._$ };
break;
case 41:
case 47:
this.$ = $$[$0 - 1];
break;
}
},
table: [{ 3: 1, 4: 2, 5: [1, 4], 6: 3, 9: 13, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 1: [3] }, { 5: [1, 21], 7: 32, 8: $V7, 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }, { 5: [1, 34] }, { 1: [2, 3] }, o($Vi, [2, 39]), o($Vi, [2, 40]), { 4: 35, 6: 37, 9: 13, 10: 36, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, o($Vi, [2, 42]), o($Vi, [2, 43]), o($Vi, [2, 44], { 22: [1, 38] }), o($Vi, [2, 45], { 17: [1, 40], 22: [1, 39] }), o($Vi, [2, 46]), o($Vj, [2, 8], { 31: 5, 27: 6, 26: 8, 21: 9, 16: 10, 11: 11, 19: 12, 23: 17, 4: 41, 12: $V0, 17: $V1, 24: $V2, 25: $V3, 28: $V4, 29: $V5, 30: $V6 }), { 4: 42, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 43, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 44, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, o($Vi, [2, 26]), o([5, 8, 15, 17, 18, 20, 22, 28, 29, 32, 33, 34, 35, 36, 37, 38], [2, 11]), o($Vi, [2, 21], { 25: [1, 45] }), o($Vi, [2, 25], { 24: [1, 46] }), { 1: [2, 1] }, { 4: 47, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 48, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 49, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 50, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 51, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 52, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 53, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 54, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 55, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 56, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, o($Vk, [2, 6], { 8: $Vl }), o($Vm, [2, 4]), { 1: [2, 2] }, { 7: 32, 8: $V7, 18: [1, 58], 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }, { 18: [1, 59] }, o($Vn, [2, 10]), { 4: 60, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 61, 11: 11, 12: $V0, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, { 4: 65, 6: 37, 9: 13, 10: 66, 11: 11, 12: $V0, 13: 64, 14: 63, 16: 10, 17: $V1, 18: [1, 62], 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, o($Vj, [2, 9], { 7: 67, 8: $V7, 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }), o($Vo, [2, 27], { 20: $V8, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vo, [2, 28], { 20: $V8, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vo, [2, 29], { 20: $V8, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vi, [2, 22], { 24: [1, 68] }), o($Vi, [2, 24]), o($Vo, [2, 30], { 20: $V8, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vo, [2, 31], { 20: $V8, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vp, [2, 32], { 20: $V8, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vp, [2, 33], { 20: $V8, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg }), o($Vq, [2, 34], { 20: $V8, 35: $Ve, 36: $Vf }), o($Vr, [2, 35], { 20: $V8 }), o($Vr, [2, 36], { 20: $V8 }), o($Vq, [2, 37], { 20: $V8, 35: $Ve, 36: $Vf }), o($Vs, [2, 38], { 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }), o($Vi, [2, 18]), o($Vm, [2, 5]), o($Vi, [2, 41]), o($Vi, [2, 47]), o($Vs, [2, 20], { 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }), o($Vs, [2, 19], { 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }), o($Vt, [2, 16]), { 15: [1, 70], 18: [1, 69] }, o($Vn, [2, 14]), o($Vn, [2, 12], { 7: 32, 8: $V7, 20: $V8, 28: $V9, 29: $Va, 32: $Vb, 33: $Vc, 34: $Vd, 35: $Ve, 36: $Vf, 37: $Vg, 38: $Vh }), o($Vn, [2, 13]), o($Vk, [2, 7], { 8: $Vl }), o($Vi, [2, 23]), o($Vt, [2, 17]), { 4: 65, 6: 37, 9: 13, 10: 66, 11: 11, 12: $V0, 13: 71, 16: 10, 17: $V1, 19: 12, 21: 9, 23: 17, 24: $V2, 25: $V3, 26: 8, 27: 6, 28: $V4, 29: $V5, 30: $V6, 31: 5 }, o($Vn, [2, 15])],
defaultActions: { 4: [2, 3], 21: [2, 1], 34: [2, 2] },
parseError: function parseError(str, hash) {
if (hash.recoverable) {
this.trace(str);
}
else {
var error = new Error(str);
error.hash = hash;
throw error;
}
},
parse: function parse(input) {
var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
var args = lstack.slice.call(arguments, 1);
var lexer = Object.create(this.lexer);
var sharedState = { yy: {} };
for (var k in this.yy) {
if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
sharedState.yy[k] = this.yy[k];
}
}
lexer.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer;
sharedState.yy.parser = this;
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
var yyloc = lexer.yylloc;
lstack.push(yyloc);
var ranges = lexer.options && lexer.options.ranges;
if (typeof sharedState.yy.parseError === 'function') {
this.parseError = sharedState.yy.parseError;
}
else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
function popStack(n) {
stack.length = stack.length - 2 * n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
_token_stack: var lex = function () {
var token;
token = lexer.lex() || EOF;
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
};
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
while (true) {
state = stack[stack.length - 1];
if (this.defaultActions[state]) {
action = this.defaultActions[state];
}
else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
action = table[state] && table[state][symbol];
}
if (typeof action === 'undefined' || !action.length || !action[0]) {
var errStr = '';
expected = [];
for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) {
expected.push('\'' + this.terminals_[p] + '\'');
}
}
if (lexer.showPosition) {
errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
}
else {
errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
}
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yyloc,
expected: expected
});
}
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
}
switch (action[0]) {
case 1:
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]);
symbol = null;
if (!preErrorSymbol) {
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
if (recovering > 0) {
recovering--;
}
}
else {
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2:
len = this.productions_[action[1]][1];
yyval.$ = vstack[vstack.length - len];
yyval._$ = {
first_line: lstack[lstack.length - (len || 1)].first_line,
last_line: lstack[lstack.length - 1].last_line,
first_column: lstack[lstack.length - (len || 1)].first_column,
last_column: lstack[lstack.length - 1].last_column
};
if (ranges) {
yyval._$.range = [
lstack[lstack.length - (len || 1)].range[0],
lstack[lstack.length - 1].range[1]
];
}
r = this.performAction.apply(yyval, [
yytext,
yyleng,
yylineno,
sharedState.yy,
action[1],
vstack,
lstack
].concat(args));
if (typeof r !== 'undefined') {
return r;
}
if (len) {
stack = stack.slice(0, -1 * len * 2);
vstack = vstack.slice(0, -1 * len);
lstack = lstack.slice(0, -1 * len);
}
stack.push(this.productions_[action[1]][0]);
vstack.push(yyval.$);
lstack.push(yyval._$);
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
stack.push(newState);
break;
case 3:
return true;
}
}
return true;
} };
/* generated by jison-lex 0.3.4 */
var lexer = (function () {
var lexer = ({
EOF: 1,
parseError: function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
}
else {
throw new Error(str);
}
},
// resets the lexer, sets new input
setInput: function (input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = this._backtrack = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0, 0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input: function () {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
}
else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(1);
return ch;
},
// unshifts one char (or a string) into the input
unput: function (ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
var r = this.yylloc.range;
this.yylloc = {
first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ?
(lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ oldLines[oldLines.length - lines.length].length - lines[0].length :
this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
this.yyleng = this.yytext.length;
return this;
},
// When called from action, caches matched text and appends it on next action
more: function () {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject: function () {
if (this.options.backtrack_lexer) {
this._backtrack = true;
}
else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
return this;
},
// retain first n characters of the match
less: function (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput: function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
},
// displays upcoming input, i.e. for error messages
upcomingInput: function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20 - next.length);
}
return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
},
// displays the character position where the lexing error occurred, i.e. for error messages
showPosition: function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
// test the lexed token: return FALSE when not a match, otherwise return token
test_match: function (match, indexed_rule) {
var token, lines, backup;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ?
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
this.yylloc.last_column + match[0].length
};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
}
else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
return false; // rule action called reject() implying the next rule should be tested instead.
}
return false;
},
// return next match in input
next: function () {
if (this.done) {
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token, match, tempMatch, index;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rules[i]);
if (token !== false) {
return token;
}
else if (this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
}
else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
}
else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === "") {
return this.EOF;
}
else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
},
// return next match that has a token
lex: function lex() {
var r = this.next();
if (r) {
return r;
}
else {
return this.lex();
}
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin: function begin(condition) {
this.conditionStack.push(condition);
},
// pop the previously active lexer condition state off the condition stack
popState: function popState() {
var n = this.conditionStack.length - 1;
if (n > 0) {
return this.conditionStack.pop();
}
else {
return this.conditionStack[0];
}
},
// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules: function _currentRules() {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
}
else {
return this.conditions["INITIAL"].rules;
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState: function topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
}
else {
return "INITIAL";
}
},
// alias for begin(condition)
pushState: function pushState(condition) {
this.begin(condition);
},
// return the number of states currently on the stack
stateStackSize: function stateStackSize() {
return this.conditionStack.length;
},
options: {},
performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
var YYSTATE = YY_START;
switch ($avoiding_name_collisions) {
case 0: /* skip whitespace */
break;
case 1:
return 24;
break;
case 2:
return 38;
break;
case 3:
return 22;
break;
case 4:
return 20;
break;
case 5:
return 12;
break;
case 6:
return 5;
break;
case 7:
return yy_.yytext[0];
break;
}
},
rules: [/^(?:\s+)/, /^(?:[0-9]+)/, /^(?:(==|!=|<=|>=|<|>))/, /^(?:[+\-*/%]?=)/, /^(?:(\&\&)|\|\|)/, /^(?:[a-zA-Z_][a-zA-Z0-9._]*)/, /^(?:$)/, /^(?:.)/],
conditions: { "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7], "inclusive": true } }
});
return lexer;
})();
parser.lexer = lexer;
function Parser() {
this.yy = {};
}
Parser.prototype = parser;
parser.Parser = Parser;
return new Parser;
})();
if (true) {
exports.parser = parser;
exports.Parser = parser.Parser;
exports.parse = function () { return parser.parse.apply(parser, arguments); };
exports.main = () => { };
if ( true && __webpack_require__.c[__webpack_require__.s] === module) {
exports.main(process.argv.slice(1));
}
}
//# sourceMappingURL=parser.js.map
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/module.js */ "./node_modules/webpack/buildin/module.js")(module), __webpack_require__(/*! ./../../../process/browser.js */ "./node_modules/process/browser.js")))
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/astUtils.js":
/*!****************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/astUtils.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CHILDREN = {
ASSIGNMENT_EXPRESSION: [
{ type: "NODE", key: "right" },
],
SCRIPT: [{ type: "ARRAY", key: "body" }],
EXPRESSION_BLOCK: [{ type: "ARRAY", key: "body" }],
UNARY_EXPRESSION: [{ type: "NODE", key: "value" }],
NUMBER_LITERAL: [],
IDENTIFIER: [],
CALL_EXPRESSION: [
{ type: "ARRAY", key: "arguments" },
{ type: "NODE", key: "callee" },
],
BINARY_EXPRESSION: [
{ type: "NODE", key: "left" },
{ type: "NODE", key: "right" },
],
LOGICAL_EXPRESSION: [
{ type: "NODE", key: "left" },
{ type: "NODE", key: "right" },
],
};
function mapAst(ast, cb) {
const children = CHILDREN[ast.type];
let newAst = ast;
if (children == null) {
throw new Error(`Unknown children definition for ${ast.type}`);
}
children.forEach(child => {
if (child.type === "NODE") {
const orignalChild = ast[child.key];
const newChild = mapAst(orignalChild, cb);
if (newChild !== orignalChild) {
newAst = Object.assign(Object.assign({}, newAst), { [child.key]: newChild });
}
}
else if (child.type === "ARRAY") {
const orignalChildren = ast[child.key];
const newChildren = orignalChildren.map(originalChild => mapAst(originalChild, cb));
const childrenHaveChanged = orignalChildren.some((child, i) => child !== newChildren[i]);
if (childrenHaveChanged) {
newAst = Object.assign(Object.assign({}, newAst), { [child.key]: newChildren });
}
}
});
return cb(newAst);
}
exports.mapAst = mapAst;
//# sourceMappingURL=astUtils.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/compiler.js":
/*!****************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/compiler.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const parser_1 = __webpack_require__(/*! ./parser */ "./node_modules/eel-wasm/dist/src/parser.js");
const emitter_1 = __webpack_require__(/*! ./emitter */ "./node_modules/eel-wasm/dist/src/emitter.js");
const encoding_1 = __webpack_require__(/*! ./encoding */ "./node_modules/eel-wasm/dist/src/encoding.js");
const shims_1 = __importDefault(__webpack_require__(/*! ./shims */ "./node_modules/eel-wasm/dist/src/shims.js"));
const Utils = __importStar(__webpack_require__(/*! ./utils */ "./node_modules/eel-wasm/dist/src/utils.js"));
const wasmFunctions_1 = __webpack_require__(/*! ./wasmFunctions */ "./node_modules/eel-wasm/dist/src/wasmFunctions.js");
const constants_1 = __webpack_require__(/*! ./constants */ "./node_modules/eel-wasm/dist/src/constants.js");
function compileModule({ pools, functions: funcs, eelVersion = 2, preParsed = false, }) {
if (Object.keys(pools).includes("shims")) {
throw new Error('You may not name a pool "shims". "shims" is reserved for injected JavaScript functions.');
}
// Collect all the globals that we expect to get as imports.
const importedVars = [];
Object.entries(pools).forEach(([poolName, pool]) => {
pool.forEach(variableName => {
importedVars.push([poolName, variableName]);
});
});
// Ensure all the imported globals get the first ids.
const varResolver = new Utils.ScopedIdMap();
importedVars.forEach(([poolName, variableName]) => {
varResolver.get(poolName, variableName);
});
const functionImports = Object.entries(shims_1.default).map(([name, func]) => {
return {
args: new Array(func.length).fill(null).map(_ => encoding_1.VAL_TYPE.f64),
// Shims implicitly always return a number
returns: [encoding_1.VAL_TYPE.f64],
name,
};
});
const localFuncOrder = [];
const moduleFuncs = [];
Object.entries(funcs).forEach(([name, { pool, code }]) => {
if (pools[pool] == null) {
const poolsList = Object.keys(pools);
if (poolsList.length === 0) {
throw new Error(`The function "${name}" was declared as using a variable ` +
`pool named "${pool}" but no pools were defined.`);
}
throw new Error(`The function "${name}" was declared as using a variable ` +
`pool named "${pool}" which is not among the variable ` +
`pools defined. The defined variable pools are: ` +
`${Utils.formatList(poolsList)}.`);
}
const ast = preParsed ? code : parser_1.parse(code);
if (typeof ast === "string") {
// TODO: Change the API so this can be enforced by types
throw new Error("Got passed unparsed code without setting the preParsed flag");
}
if (ast.type !== "SCRIPT") {
throw new Error("Invalid AST");
}
if (ast.body.length === 0) {
return;
}
const localVariables = [];
const context = {
resolveVar: name => {
// The `reg00`-`reg99` variables are special in that they are shared between all pools.
if (/^reg\d\d$/.test(name)) {
return varResolver.get(null, name);
}
return varResolver.get(pool, name);
},
resolveLocal: type => {
// TODO: We could provide a way for the emitter to release a local
// variable so that we can reuse it, much in the same way a traditional
// compiler does in register allocation.
localVariables.push(type);
return localVariables.length - 1;
},
resolveFunc: name => {
// If this is a shim, return the shim index.
const shimdex = functionImports.findIndex(func => func.name === name);
if (shimdex !== -1) {
const call = encoding_1.op.call(shimdex);
if (name === "rand" && eelVersion === 1) {
return [...call, encoding_1.op.f64_floor];
}
return call;
}
// If it's not a shim and it's not a defined function, return null.
// The emitter will generate a nice error.
if (wasmFunctions_1.localFuncMap[name] == null) {
return null;
}
let index = localFuncOrder.indexOf(name);
if (index === -1) {
localFuncOrder.push(name);
index = localFuncOrder.length - 1;
}
return encoding_1.op.call(index + functionImports.length);
},
rawSource: code,
};
const binary = emitter_1.emit(ast, context);
moduleFuncs.push({
binary,
exportName: name,
args: [],
returns: [],
localVariables,
});
});
const localFuncs = localFuncOrder.map(name => {
const func = wasmFunctions_1.localFuncMap[name];
// This check is technicaly redundant since we check inside resolveLocalFunc
// in the compiler context. It's here just to catch potential compiler bugs.
if (func == null) {
throw new Error(`Undefined local function "${name}"`);
}
return func;
});
// Given a function definition, return a hashable string representation of its signature.
const getSignatureKey = (func) => {
return [...func.args, "|", ...func.returns].join("-");
};
// https://webassembly.github.io/spec/core/binary/modules.html#type-section
const types = [];
const typeIndexByKey = new Map();
[...functionImports, ...localFuncs, ...moduleFuncs].forEach(func => {
const key = getSignatureKey(func);
if (typeIndexByKey.has(key)) {
return;
}
types.push([
encoding_1.FUNCTION_TYPE,
...encoding_1.encodeFlatVector(func.args),
...encoding_1.encodeFlatVector(func.returns),
]);
typeIndexByKey.set(key, types.length - 1);
});
function getTypeIndex(func) {
const key = getSignatureKey(func);
const typeIndex = typeIndexByKey.get(key);
if (typeIndex == null) {
throw new Error(`Failed to get a type index for key ${key}`);
}
return typeIndex;
}
// https://webassembly.github.io/spec/core/binary/modules.html#import-section
const imports = [
...importedVars.map(([namespace, name]) => {
return [
...encoding_1.encodeString(namespace),
...encoding_1.encodeString(name),
...[encoding_1.GLOBAL_TYPE, encoding_1.VAL_TYPE.f64, encoding_1.MUTABILITY.var],
];
}),
...functionImports.map((func, i) => {
const typeIndex = getTypeIndex(func);
return [
...encoding_1.encodeString("shims"),
...encoding_1.encodeString(func.name),
...[encoding_1.TYPE_IDX, ...encoding_1.unsignedLEB128(typeIndex)],
];
}),
];
// https://webassembly.github.io/spec/core/binary/modules.html#function-section
//
// > Functions are referenced through function indices, starting with the smallest
// > index not referencing a function import.
const functions = [...localFuncs, ...moduleFuncs].map(func => {
const typeIndex = getTypeIndex(func);
return encoding_1.unsignedLEB128(typeIndex);
});
const memories = [
// Only one memory
[
0x01,
...encoding_1.unsignedLEB128(constants_1.WASM_MEMORY_SIZE),
...encoding_1.unsignedLEB128(constants_1.WASM_MEMORY_SIZE),
],
];
// https://webassembly.github.io/spec/core/binary/modules.html#global-section
const globalCount = varResolver.size() - importedVars.length;
const globals = Utils.times(globalCount, () => {
return [
encoding_1.VAL_TYPE.f64,
encoding_1.MUTABILITY.var,
...encoding_1.op.f64_const(0),
encoding_1.op.end,
];
});
// https://webassembly.github.io/spec/core/binary/modules.html#binary-exportsec
const xports = [...moduleFuncs].map((func, i) => {
const funcIndex = i + functionImports.length + localFuncs.length;
return [
...encoding_1.encodeString(func.exportName),
encoding_1.EXPORT_TYPE.FUNC,
...encoding_1.unsignedLEB128(funcIndex),
];
});
/* Uncomment this to expose memory
xports.push([
...encodeString("memory"),
EXPORT_TYPE.MEMORY,
...unsignedLEB128(0),
]);
*/
// https://webassembly.github.io/spec/core/binary/modules.html#code-section
const codes = [...localFuncs, ...moduleFuncs].map(func => {
var _a;
// TODO: We could collapose consecutive types here, or even move to a two
// pass approach where ids are resolved after the emitter is run.
const localTypes = ((_a = func.localVariables) !== null && _a !== void 0 ? _a : []).map(type => {
return [...encoding_1.unsignedLEB128(1), type];
});
// It's a bit odd that every other section is an array of arrays and this
// one is an array of vectors. The spec says this is so that when navigating
// the binary functions can be skipped efficiently.
return encoding_1.encodeFlatVector([
...encoding_1.encodeNestedVector(localTypes),
...func.binary,
encoding_1.op.end,
]);
});
return new Uint8Array([
// Magic module header
...encoding_1.MAGIC,
// Version number
...encoding_1.WASM_VERSION,
...encoding_1.encodeSection(encoding_1.SECTION.TYPE, types),
...encoding_1.encodeSection(encoding_1.SECTION.IMPORT, imports),
...encoding_1.encodeSection(encoding_1.SECTION.FUNC, functions),
...encoding_1.encodeSection(encoding_1.SECTION.MEMORY, memories),
...encoding_1.encodeSection(encoding_1.SECTION.GLOBAL, globals),
...encoding_1.encodeSection(encoding_1.SECTION.EXPORT, xports),
...encoding_1.encodeSection(encoding_1.SECTION.CODE, codes),
]);
}
exports.compileModule = compileModule;
//# sourceMappingURL=compiler.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/constants.js":
/*!*****************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/constants.js ***!
\*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// https://webassembly.github.io/spec/core/exec/runtime.html#page-size
const WASM_PAGE_SIZE = 65536;
const BYTES_PER_F64 = 8;
const BUFFER_COUNT = 2;
// https://github.com/WACUP/vis_milk2/blob/de9625a89e724afe23ed273b96b8e48496095b6c/ns-eel2/ns-eel.h#L136
exports.MAX_LOOP_COUNT = 1048576;
// The number of items allowed in each buffer (megabuf/gmegabuf).
// https://github.com/WACUP/vis_milk2/blob/de9625a89e724afe23ed273b96b8e48496095b6c/ns-eel2/ns-eel.h#L145
exports.BUFFER_SIZE = 65536 * 128;
exports.WASM_MEMORY_SIZE = Math.ceil((exports.BUFFER_SIZE * BYTES_PER_F64 * BUFFER_COUNT) / WASM_PAGE_SIZE);
//# sourceMappingURL=constants.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/emitter.js":
/*!***************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/emitter.js ***!
\***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const encoding_1 = __webpack_require__(/*! ./encoding */ "./node_modules/eel-wasm/dist/src/encoding.js");
const shims_1 = __importDefault(__webpack_require__(/*! ./shims */ "./node_modules/eel-wasm/dist/src/shims.js"));
const errorUtils_1 = __webpack_require__(/*! ./errorUtils */ "./node_modules/eel-wasm/dist/src/errorUtils.js");
const wasmFunctions_1 = __webpack_require__(/*! ./wasmFunctions */ "./node_modules/eel-wasm/dist/src/wasmFunctions.js");
const utils_1 = __webpack_require__(/*! ./utils */ "./node_modules/eel-wasm/dist/src/utils.js");
const constants_1 = __webpack_require__(/*! ./constants */ "./node_modules/eel-wasm/dist/src/constants.js");
function emit(ast, context) {
var _a, _b, _c;
switch (ast.type) {
case "SCRIPT": {
const body = ast.body.map((statement, i) => {
return [...emit(statement, context), encoding_1.op.drop];
});
return utils_1.flatten(body);
}
case "EXPRESSION_BLOCK": {
return emitExpressionBlock(ast.body, context);
}
case "BINARY_EXPRESSION": {
const left = emit(ast.left, context);
const right = emit(ast.right, context);
const operatorToOps = {
"+": [encoding_1.op.f64_add],
"-": [encoding_1.op.f64_sub],
"*": [encoding_1.op.f64_mul],
"/": context.resolveFunc("div"),
"%": context.resolveFunc("mod"),
"|": context.resolveFunc("bitwiseOr"),
"&": context.resolveFunc("bitwiseAnd"),
"^": context.resolveFunc("pow"),
// Comparison operators
"==": [encoding_1.op.f64_sub, ...encoding_1.IS_ZEROISH, encoding_1.op.f64_convert_i32_s],
"!=": [encoding_1.op.f64_sub, ...encoding_1.IS_NOT_ZEROISH, encoding_1.op.f64_convert_i32_s],
"<": [encoding_1.op.f64_lt, encoding_1.op.f64_convert_i32_s],
">": [encoding_1.op.f64_gt, encoding_1.op.f64_convert_i32_s],
"<=": [encoding_1.op.f64_le, encoding_1.op.f64_convert_i32_s],
">=": [encoding_1.op.f64_ge, encoding_1.op.f64_convert_i32_s],
};
const code = operatorToOps[ast.operator];
if (code == null) {
throw errorUtils_1.createCompilerError(`Unknown binary expression operator ${ast.operator}`, ast.loc, context.rawSource);
}
return [...left, ...right, ...code];
}
case "CALL_EXPRESSION": {
const functionName = ast.callee.value;
// Destructure this so that TypeScript knows it won't get mutated.
const argList = ast.arguments;
const assertArity = (arity) => {
if (argList.length < arity) {
throw errorUtils_1.createUserError(`Too few arguments passed to \`${functionName}()\`. Expected ${arity} but only got ${argList.length}.`, ast.loc, context.rawSource);
}
if (argList.length > arity) {
throw errorUtils_1.createUserError(`Too many arguments passed to \`${functionName}()\`. Expected ${arity} but got ${argList.length}.`, argList[arity].loc, context.rawSource);
}
};
// Some functions have special behavior
switch (functionName) {
case "exec2":
assertArity(2);
return emitExpressionBlock(ast.arguments, context);
case "exec3":
assertArity(3);
return emitExpressionBlock(ast.arguments, context);
case "if":
assertArity(3);
const [test, consiquent, alternate] = ast.arguments;
return emitConditional(test, consiquent, alternate, context);
case "while":
assertArity(1);
return emitWhile(ast.arguments[0], context);
case "loop":
assertArity(2);
return emitLoop(ast.arguments[0], ast.arguments[1], context);
case "megabuf":
case "gmegabuf":
assertArity(1);
const index = context.resolveLocal(encoding_1.VAL_TYPE.i32);
return [
...emit(ast.arguments[0], context),
...((_a = context.resolveFunc("_getBufferIndex")) !== null && _a !== void 0 ? _a : []),
...encoding_1.op.local_tee(index),
...encoding_1.op.i32_const(-1),
encoding_1.op.i32_ne,
// STACK: [in range]
...encoding_1.op.if(encoding_1.BLOCK.f64),
...encoding_1.op.local_get(index),
...encoding_1.op.f64_load(3, emitAddMemoryOffset(functionName)),
encoding_1.op.else,
...encoding_1.op.f64_const(0),
encoding_1.op.end,
];
case "assign":
assertArity(2);
const variableIdentifier = ast.arguments[0];
if (variableIdentifier.type != "IDENTIFIER") {
throw errorUtils_1.createUserError("Expected the first argument of `assign()` to be an identifier.", variableIdentifier.loc, context.rawSource);
}
const resolvedName = context.resolveVar(variableIdentifier.value);
return [
...emit(ast.arguments[1], context),
...encoding_1.op.global_set(resolvedName),
...encoding_1.op.global_get(resolvedName),
];
}
// Function calls which can be linlined
const args = utils_1.flatten(ast.arguments.map(node => emit(node, context)));
// This is just a continuation of the above switch statement, but it's for functions which all parse their args the same.
switch (functionName) {
case "abs":
assertArity(1);
return [...args, encoding_1.op.f64_abs];
case "sqrt":
assertArity(1);
return [...args, encoding_1.op.f64_abs, encoding_1.op.f64_sqrt];
case "int":
assertArity(1);
return [...args, encoding_1.op.f64_floor];
case "min":
assertArity(2);
return [...args, encoding_1.op.f64_min];
case "max":
assertArity(2);
return [...args, encoding_1.op.f64_max];
case "above":
assertArity(2);
return [...args, encoding_1.op.f64_gt, encoding_1.op.f64_convert_i32_s];
case "below":
assertArity(2);
return [...args, encoding_1.op.f64_lt, encoding_1.op.f64_convert_i32_s];
case "equal":
assertArity(2);
return [...args, encoding_1.op.f64_sub, ...encoding_1.IS_ZEROISH, encoding_1.op.f64_convert_i32_s];
case "bnot":
assertArity(1);
return [...args, ...encoding_1.IS_ZEROISH, encoding_1.op.f64_convert_i32_s];
case "floor":
assertArity(1);
return [...args, encoding_1.op.f64_floor];
case "ceil":
assertArity(1);
return [...args, encoding_1.op.f64_ceil];
}
const invocation = context.resolveFunc(functionName);
if (invocation == null ||
// Ensure this isn't a private function. This is a bit awkward becuase
// Eel does implement some _ functions but while they are _intended_ to be
// private, they accidentally expose them. We should find a cleaner way
// to defining user accessible functions vs utility functions used by
// the compiler.
functionName.startsWith("_")) {
throw errorUtils_1.createUserError(`"${functionName}" is not defined.`, ast.callee.loc, context.rawSource);
}
if (shims_1.default[functionName] != null) {
assertArity(shims_1.default[functionName].length);
}
else if (wasmFunctions_1.localFuncMap[functionName] != null) {
assertArity(wasmFunctions_1.localFuncMap[functionName].args.length);
}
else {
throw errorUtils_1.createCompilerError(`Missing arity information for the function \`${functionName}()\``, ast.callee.loc, context.rawSource);
}
return [...args, ...invocation];
}
case "ASSIGNMENT_EXPRESSION": {
const { left } = ast;
const rightCode = emit(ast.right, context);
const mutationCode = getAssignmentOperatorMutation(ast, context);
if (left.type === "IDENTIFIER") {
const resolvedName = context.resolveVar(left.value);
// TODO: In lots of cases we don't care about the return value. In those
// cases we should try to find a way to omit the `get/drop` combo.
// Peephole optimization seems to be the conventional way to do this.
// https://en.wikipedia.org/wiki/Peephole_optimization
const get = encoding_1.op.global_get(resolvedName);
const set = encoding_1.op.global_set(resolvedName);
// `=` is a special case in that it does not need the original value.
if (mutationCode === null) {
return [...rightCode, ...set, ...get];
}
return [...get, ...rightCode, ...mutationCode, ...set, ...get];
}
if (left.type !== "CALL_EXPRESSION") {
throw errorUtils_1.createCompilerError(
// @ts-ignore This is a guard in case the parser has an error
`Unexpected left hand side type for assignment: ${left.type}`, ast.loc, context.rawSource);
}
// Special assignment case for `megabuf(n) = e` and `gmegabuf(n) = e`.
const localIndex = context.resolveLocal(encoding_1.VAL_TYPE.i32);
if (left.arguments.length !== 1) {
throw errorUtils_1.createUserError(`Expected 1 argument when assinging to a buffer but got ${left.arguments.length}.`, left.arguments.length === 0 ? left.loc : left.arguments[1].loc, context.rawSource);
}
const bufferName = left.callee.value;
if (bufferName !== "gmegabuf" && bufferName !== "megabuf") {
throw errorUtils_1.createUserError("The only function calls which may be assigned to are `gmegabuf()` and `megabuf()`.", left.callee.loc, context.rawSource);
}
const addOffset = emitAddMemoryOffset(bufferName);
if (mutationCode === null) {
// TODO: Move this to wasmFunctions once we know how to call functions
// from within functions (need to get the offset).
const unnormalizedIndex = context.resolveLocal(encoding_1.VAL_TYPE.i32);
const rightValue = context.resolveLocal(encoding_1.VAL_TYPE.f64);
return [
// Emit the right hand side unconditionally to ensure it always runs.
...rightCode,
...encoding_1.op.local_set(rightValue),
...emit(left.arguments[0], context),
...((_b = context.resolveFunc("_getBufferIndex")) !== null && _b !== void 0 ? _b : []),
...encoding_1.op.local_tee(unnormalizedIndex),
...encoding_1.op.i32_const(0),
encoding_1.op.i32_lt_s,
// STACK: [is the index out of range?]
...encoding_1.op.if(encoding_1.BLOCK.f64),
...encoding_1.op.f64_const(0),
encoding_1.op.else,
...encoding_1.op.local_get(unnormalizedIndex),
...encoding_1.op.local_tee(localIndex),
// STACK: [buffer index]
...encoding_1.op.local_get(rightValue),
// STACK: [buffer index, right]
...encoding_1.op.f64_store(3, addOffset),
// STACK: []
...encoding_1.op.local_get(rightValue),
// STACK: [Right/Buffer value]
encoding_1.op.end,
];
}
// TODO: Move this to wasmFunctions once we know how to call functions
// from within functions (need to get the offset).
const index = context.resolveLocal(encoding_1.VAL_TYPE.i32);
const inBounds = context.resolveLocal(encoding_1.VAL_TYPE.i32);
const rightValue = context.resolveLocal(encoding_1.VAL_TYPE.f64);
const result = context.resolveLocal(encoding_1.VAL_TYPE.f64);
return [
...rightCode,
...encoding_1.op.local_set(rightValue),
...emit(left.arguments[0], context),
...((_c = context.resolveFunc("_getBufferIndex")) !== null && _c !== void 0 ? _c : []),
...encoding_1.op.local_tee(index),
// STACK: [index]
...encoding_1.op.i32_const(-1),
encoding_1.op.i32_ne,
...encoding_1.op.local_tee(inBounds),
...encoding_1.op.if(encoding_1.BLOCK.f64),
...encoding_1.op.local_get(index),
...encoding_1.op.f64_load(3, addOffset),
encoding_1.op.else,
...encoding_1.op.f64_const(0),
encoding_1.op.end,
// STACK: [current value from memory || 0]
// Apply the mutation
...encoding_1.op.local_get(rightValue),
...mutationCode,
...encoding_1.op.local_tee(result),
// STACK: [new value]
...encoding_1.op.local_get(inBounds),
...encoding_1.op.if(encoding_1.BLOCK.void),
...encoding_1.op.local_get(index),
...encoding_1.op.local_get(result),
...encoding_1.op.f64_store(3, addOffset),
encoding_1.op.end,
];
}
case "LOGICAL_EXPRESSION": {
const left = emit(ast.left, context);
const right = emit(ast.right, context);
const behaviorMap = {
"&&": {
comparison: encoding_1.IS_ZEROISH,
shortCircutValue: 0,
},
"||": {
comparison: encoding_1.IS_NOT_ZEROISH,
shortCircutValue: 1,
},
};
const behavior = behaviorMap[ast.operator];
if (behavior == null) {
throw errorUtils_1.createCompilerError(`Unknown logical expression operator ${ast.operator}`, ast.loc, context.rawSource);
}
const { comparison, shortCircutValue } = behavior;
return [
...left,
...comparison,
...encoding_1.op.if(encoding_1.BLOCK.f64),
...encoding_1.op.f64_const(shortCircutValue),
encoding_1.op.else,
...right,
...encoding_1.IS_NOT_ZEROISH,
encoding_1.op.f64_convert_i32_s,
encoding_1.op.end,
];
}
case "UNARY_EXPRESSION": {
const value = emit(ast.value, context);
const operatorToCode = {
"-": [encoding_1.op.f64_neg],
"+": [],
"!": [...encoding_1.IS_ZEROISH, encoding_1.op.f64_convert_i32_s],
};
const code = operatorToCode[ast.operator];
if (code == null) {
throw errorUtils_1.createCompilerError(`Unknown logical unary operator ${ast.operator}`, ast.loc, context.rawSource);
}
return [...value, ...code];
}
case "IDENTIFIER":
const variableName = ast.value;
// TODO: It's a bit odd that not every IDENTIFIER node gets emitted. In
// function calls and assignments we just peek at the name and never emit
// it.
return encoding_1.op.global_get(context.resolveVar(variableName));
case "NUMBER_LITERAL":
return encoding_1.op.f64_const(ast.value);
default:
throw errorUtils_1.createCompilerError(
// @ts-ignore This runtime check is here because the caller may not be type-checked
`Unknown AST node type ${ast.type}`,
// @ts-ignore This runtime check is here because the caller may not be type-checked
ast.loc, context.rawSource);
}
}
exports.emit = emit;
function emitExpressionBlock(body, context) {
const statements = body.map((statement, i) => {
return emit(statement, context);
});
return utils_1.flatten(utils_1.arrayJoin(statements, [encoding_1.op.drop]));
}
function emitWhile(expression, context) {
const body = emit(expression, context);
const iterationCount = context.resolveLocal(encoding_1.VAL_TYPE.i32);
return [
...encoding_1.op.i32_const(0),
...encoding_1.op.local_set(iterationCount),
...encoding_1.op.loop(encoding_1.BLOCK.void),
// Increment and check loop count
...encoding_1.op.local_get(iterationCount),
...encoding_1.op.i32_const(1),
encoding_1.op.i32_add,
...encoding_1.op.local_tee(iterationCount),
// STACK: [iteration count]
...encoding_1.op.i32_const(constants_1.MAX_LOOP_COUNT),
encoding_1.op.i32_lt_u,
// STACK: [loop in range]
...body,
...encoding_1.IS_NOT_ZEROISH,
// STACK: [loop in range, body is truthy]
encoding_1.op.i32_and,
// STACK: [can continue]
...encoding_1.op.br_if(0),
encoding_1.op.end,
...encoding_1.op.f64_const(0),
];
}
function emitLoop(count, expression, context) {
const body = emit(expression, context);
const localIndex = context.resolveLocal(encoding_1.VAL_TYPE.i32);
return [
...encoding_1.op.block(encoding_1.BLOCK.void),
// Assign the count to a variable
...emit(count, context),
encoding_1.op.i32_trunc_f64_s,
...encoding_1.op.local_tee(localIndex),
...encoding_1.op.i32_const(0),
encoding_1.op.i32_le_s,
...encoding_1.op.br_if(1),
...encoding_1.op.loop(encoding_1.BLOCK.void),
// Run the body
...body,
encoding_1.op.drop,
// Decrement the count
...encoding_1.op.local_get(localIndex),
...encoding_1.op.i32_const(1),
encoding_1.op.i32_sub,
...encoding_1.op.local_tee(localIndex),
...encoding_1.op.i32_const(0),
encoding_1.op.i32_ne,
...encoding_1.op.br_if(0),
encoding_1.op.end,
encoding_1.op.end,
...encoding_1.op.f64_const(0),
];
}
function emitConditional(test, consiquent, alternate, context) {
// TODO: In some cases https://webassembly.studio/ compiles these to use `select`.
// Is that an optimization that we might want as well?
return [
...emit(test, context),
...encoding_1.IS_NOT_ZEROISH,
...encoding_1.op.if(encoding_1.BLOCK.f64),
...emit(consiquent, context),
encoding_1.op.else,
...emit(alternate, context),
encoding_1.op.end,
];
}
// There are two sections of memory. This function emits code to add the correct
// offset to an i32 index already on the stack.
function emitAddMemoryOffset(name) {
switch (name) {
case "gmegabuf":
return constants_1.BUFFER_SIZE * 8;
case "megabuf":
return 0;
}
}
function getAssignmentOperatorMutation(ast, context) {
const operatorToCode = {
"+=": [encoding_1.op.f64_add],
"-=": [encoding_1.op.f64_sub],
"*=": [encoding_1.op.f64_mul],
"/=": [encoding_1.op.f64_div],
"%=": context.resolveFunc("mod"),
"=": null,
};
const operatorCode = operatorToCode[ast.operator];
if (operatorCode === undefined) {
throw errorUtils_1.createCompilerError(`Unknown assignment operator "${ast.operator}"`, ast.loc, context.rawSource);
}
return operatorCode;
}
//# sourceMappingURL=emitter.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/encoding.js":
/*!****************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/encoding.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const ieee754 = __importStar(__webpack_require__(/*! ./ieee754 */ "./node_modules/eel-wasm/dist/src/ieee754.js"));
const utils_1 = __webpack_require__(/*! ./utils */ "./node_modules/eel-wasm/dist/src/utils.js");
exports.MAGIC = [0x00, 0x61, 0x73, 0x6d];
exports.WASM_VERSION = [0x01, 0x00, 0x00, 0x00];
exports.EPSILON = 0.00001;
// An intial attempt to construct a Wasm binary by hand.
/*
0 custom section
1 type section
2 import section
3 function section
4 table section
5 memory section
6 global section
7 export section
8 start section
9 element section
10 code section
11 data section
*/
// https://webassembly.github.io/spec/core/binary/modules.html#sections
exports.SECTION = {
TYPE: 1,
IMPORT: 2,
FUNC: 3,
MEMORY: 5,
GLOBAL: 6,
EXPORT: 7,
CODE: 10,
};
exports.EXPORT_TYPE = {
FUNC: 0x00,
TABLE: 0x01,
MEMORY: 0x02,
GLOBAL: 0x03,
};
exports.op = {
/*
* Control Instructions
* https://webassembly.github.io/spec/core/binary/instructions.html#control-instructions
*/
// unreachable: 0x00,
// nop: 0x01,
block: (blockType) => [0x02, blockType],
loop: (blockType) => [0x03, blockType],
if: (retType) => [0x04, retType],
else: 0x05,
end: 0x0b,
// br: (i: number) => [0x0c, ...signedLEB128(i)],
br_if: (i) => [0x0d, ...unsignedLEB128(i)],
// br_table: 0x0d,
// return: 0x0f,
call: (i) => [0x10, ...unsignedLEB128(i)],
// call_indirect: 0x11,
/*
* Parametric Instructions
* https://webassembly.github.io/spec/core/binary/instructions.html#parametric-instructions
*/
drop: 0x1a,
select: 0x1b,
/*
* Variable Instructions
* https://webassembly.github.io/spec/core/binary/instructions.html#variable-instructions
*/
local_get: (i) => [0x20, ...unsignedLEB128(i)],
local_set: (i) => [0x21, ...unsignedLEB128(i)],
local_tee: (i) => [0x22, ...unsignedLEB128(i)],
global_get: (i) => [0x23, ...unsignedLEB128(i)],
global_set: (i) => [0x24, ...unsignedLEB128(i)],
/*
* Memory Instructions
* https://webassembly.github.io/spec/core/binary/instructions.html#memory-instructions
*/
f64_load: (align, offset) => [
0x2b,
...unsignedLEB128(align),
...unsignedLEB128(offset),
],
f64_store: (align, offset) => [
0x39,
...unsignedLEB128(align),
...unsignedLEB128(offset),
],
/*
* Numeric Instructions
* https://webassembly.github.io/spec/core/binary/instructions.html#numeric-instructions
*/
i32_const: (i) => [0x41, ...signedLEB128(i)],
// i64_const: 0x42,
// f32_const: 0x43,
f64_const: (i) => [0x44, ...encodef64(i)],
i32_eqz: 0x45,
// i32_eq: 0x46,
i32_ne: 0x47,
i32_lt_s: 0x48,
i32_lt_u: 0x49,
i32_gt_s: 0x4a,
// i32_gt_u: 0x4b,
i32_le_s: 0x4c,
i32_le_u: 0x4d,
i32_ge_s: 0x4e,
// i32_ge_u: 0x4f,
// [0x50...0x5a] i64
// [0x5b...0x60] f32
f64_eq: 0x61,
f64_ne: 0x62,
f64_lt: 0x63,
f64_gt: 0x64,
f64_le: 0x65,
f64_ge: 0x66,
// i32_clz: 0x67,
// i32_ctz: 0x68,
// i32_popcnt: 0x69,
i32_add: 0x6a,
i32_sub: 0x6b,
i32_mul: 0x6c,
// i32_div_s: 0x6d,
// i32_div_u: 0x6e,
i32_rem_s: 0x6f,
// i32_rem_u: 0x70,
i32_and: 0x71,
i32_or: 0x72,
// [0x73...0x78] More i32
// [0x79...0x8a] More i64
i64_rem_s: 0x81,
i64_and: 0x83,
i64_or: 0x84,
// [0x8b...0x98] More f32
f64_abs: 0x99,
f64_neg: 0x9a,
f64_ceil: 0x9b,
f64_floor: 0x9c,
// f64_trunc: 0x9d,
// f64_nearest: 0x9e,
f64_sqrt: 0x9f,
f64_add: 0xa0,
f64_sub: 0xa1,
f64_mul: 0xa2,
f64_div: 0xa3,
f64_min: 0xa4,
f64_max: 0xa5,
// f64_copysign: 0xa6,
i32_trunc_f64_s: 0xaa,
i32_trunc_f64_u: 0xab,
i64_trunc_s_f64: 0xb0,
f64_convert_i64_s: 0xb9,
f64_convert_i32_s: 0xb7,
};
// https://webassembly.github.io/spec/core/binary/instructions.html#binary-blocktype
exports.VAL_TYPE = {
i32: 0x7f,
i64: 0x7e,
f32: 0x7d,
f64: 0x7c,
};
exports.MUTABILITY = {
const: 0x00,
var: 0x01,
};
exports.BLOCK = {
void: 0x40,
i32: 0x7f,
i64: 0x7e,
f32: 0x7d,
f64: 0x7c,
};
// http://webassembly.github.io/spec/core/binary/types.html#function-types
exports.FUNCTION_TYPE = 0x60;
// I think these might actually be specific to importdesc
exports.MEMORY_IDX = 0x02;
exports.GLOBAL_TYPE = 0x03;
exports.TYPE_IDX = 0x00;
// Takes an f64 on the stack and leaves an int32 boolean representing if it's
// within epsilon of zero.
exports.IS_ZEROISH = [
exports.op.f64_abs,
...exports.op.f64_const(exports.EPSILON),
exports.op.f64_lt,
];
exports.IS_NOT_ZEROISH = [
exports.op.f64_abs,
...exports.op.f64_const(exports.EPSILON),
exports.op.f64_gt,
];
// f64
function encodef64(num) {
const arr = new Uint8Array(8);
ieee754.write(arr, num);
return arr;
}
exports.encodef64 = encodef64;
exports.encodeString = (str) => [str.length].concat(str.split("").map(s => s.charCodeAt(0)));
function unsignedLEB128(n) {
const buffer = [];
do {
let byte = n & 0x7f;
n >>>= 7;
if (n !== 0) {
byte |= 0x80;
}
buffer.push(byte);
} while (n !== 0);
return buffer;
}
exports.unsignedLEB128 = unsignedLEB128;
// https://github.com/shmishtopher/wasm-LEB128/blob/2f1039636e758293e571f996e8012c4d69f4b58f/lib/index.js#L6
function signedLEB128(value) {
let bytes = [];
let byte = 0x00;
let size = Math.ceil(Math.log2(Math.abs(value)));
let negative = value < 0;
let more = true;
while (more) {
byte = value & 127;
value = value >> 7;
if (negative) {
value = value | -(1 << (size - 7));
}
if ((value == 0 && (byte & 0x40) == 0) ||
(value == -1 && (byte & 0x40) == 0x40)) {
more = false;
}
else {
byte = byte | 128;
}
bytes.push(byte);
}
return bytes;
}
exports.signedLEB128 = signedLEB128;
// https://webassembly.github.io/spec/core/binary/conventions.html#binary-vec
// Vectors are encoded with their length followed by their element sequence
exports.encodeFlatVector = (data) => unsignedLEB128(data.length).concat(data);
exports.encodeNestedVector = (data) => unsignedLEB128(data.length).concat(utils_1.flatten(data));
// subSections is an array of arrays
function encodeSection(type, subSections) {
// Sections are all optional, so if we get an empty vector of subSections, we
// can omit the whole section.
if (subSections.length === 0) {
return [];
}
// The size of this vector is not needed for decoding, but can be
// used to skip sections when navigating through a binary.
// TODO: Remove this assertion once we are more confident in our output.
const vec = exports.encodeFlatVector(exports.encodeNestedVector(subSections));
vec.unshift(type);
return vec;
}
exports.encodeSection = encodeSection;
//# sourceMappingURL=encoding.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/envParser.js":
/*!*****************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/envParser.js ***!
\*****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
// This module is in charge of selecting either the pre-built module or the one
// that builds it a runtime with jison.
let parserImpl = __webpack_require__(/*! ../build/parser */ "./node_modules/eel-wasm/dist/build/parser.js");
/*
let parserImpl = null;
// Always use the dynamic one, while we figure out why the built one doens't work.
if (process.env.NODE_ENV === "production") {
parserImpl = require("../build/parser");
} else {
parserImpl = require("../tools/buildParser");
}
*/
module.exports = { parse: parserImpl.parse };
//# sourceMappingURL=envParser.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/errorUtils.js":
/*!******************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/errorUtils.js ***!
\******************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = __webpack_require__(/*! ./utils */ "./node_modules/eel-wasm/dist/src/utils.js");
/* Build up a string showing a formatted source location in context with line numbers.
*
* 2 | z = sqr(y, 10);
* > 3 | x = wat();
* | ^^^
* 4 | y = 100;
*/
function printLoc(loc, rawSource, contextLines = 1) {
const firstIndex = Math.max(loc.first_line - 1 - contextLines, 0);
const lastIndex = loc.last_line + contextLines;
const sourceLines = rawSource.split("\n").slice(firstIndex, lastIndex);
const annotatedLines = sourceLines.map((line, i) => {
const lineNumber = i + firstIndex + 1;
const inRange = lineNumber >= loc.first_line && lineNumber <= loc.last_line;
const gutter = inRange ? ">" : " ";
return `${gutter} ${lineNumber} | ${line}`;
});
if (loc.first_line === loc.last_line) {
const padding = utils_1.repeat(loc.first_column, " ");
const underline = utils_1.repeat(loc.last_column - loc.first_column, "^");
const insertIndex = loc.first_line - firstIndex;
annotatedLines.splice(insertIndex, 0, ` | ${padding}${underline}`);
}
return annotatedLines.join("\n");
}
exports.printLoc = printLoc;
class CompilerError extends Error {
constructor(message, loc, rawSource) {
super(message);
// TODO: Create an error message that encourages users to open an issue at
// https://github.com/captbaritone/eel-wasm/issues is they see this, and gives
// Them an easy way to attach the right context.
this.sourceContext = printLoc(loc, rawSource);
this.loc = loc;
}
}
class UserError extends CompilerError {
}
function createUserError(message, loc, rawSource) {
return new UserError(message, loc, rawSource);
}
exports.createUserError = createUserError;
function createCompilerError(message, loc, rawSource) {
return new CompilerError(message, loc, rawSource);
}
exports.createCompilerError = createCompilerError;
//# sourceMappingURL=errorUtils.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/ieee754.js":
/*!***************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/ieee754.js ***!
\***************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// Copied from https://github.com/feross/ieee754/blob/master/index.js
function write(buffer, value) {
// Originally these four were arguments, but we only ever use it like this.
const offset = 0;
const isLE = true;
let mLen = 52;
const nBytes = 8;
var e, m, c;
var eLen = nBytes * 8 - mLen - 1;
var eMax = (1 << eLen) - 1;
var eBias = eMax >> 1;
var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
var i = isLE ? 0 : nBytes - 1;
var d = isLE ? 1 : -1;
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
value = Math.abs(value);
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0;
e = eMax;
}
else {
e = Math.floor(Math.log(value) / Math.LN2);
if (value * (c = Math.pow(2, -e)) < 1) {
e--;
c *= 2;
}
if (e + eBias >= 1) {
value += rt / c;
}
else {
value += rt * Math.pow(2, 1 - eBias);
}
if (value * c >= 2) {
e++;
c /= 2;
}
if (e + eBias >= eMax) {
m = 0;
e = eMax;
}
else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen);
e = e + eBias;
}
else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
e = 0;
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) { }
e = (e << mLen) | m;
eLen += mLen;
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) { }
buffer[offset + i - d] |= s * 128;
}
exports.write = write;
//# sourceMappingURL=ieee754.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/index.js":
/*!*************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/index.js ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const parser_1 = __webpack_require__(/*! ./parser */ "./node_modules/eel-wasm/dist/src/parser.js");
exports.parse = parser_1.parse;
const compiler_1 = __webpack_require__(/*! ./compiler */ "./node_modules/eel-wasm/dist/src/compiler.js");
exports.compileModule = compiler_1.compileModule;
const shims_1 = __importDefault(__webpack_require__(/*! ./shims */ "./node_modules/eel-wasm/dist/src/shims.js"));
exports.shims = shims_1.default;
const loader_1 = __webpack_require__(/*! ./loader */ "./node_modules/eel-wasm/dist/src/loader.js");
exports.loadModule = loader_1.loadModule;
//# sourceMappingURL=index.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/loader.js":
/*!**************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/loader.js ***!
\**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const shims_1 = __importDefault(__webpack_require__(/*! ./shims */ "./node_modules/eel-wasm/dist/src/shims.js"));
const compiler_1 = __webpack_require__(/*! ./compiler */ "./node_modules/eel-wasm/dist/src/compiler.js");
async function loadModule({ pools, functions, eelVersion = 2, }) {
let compilerPools = {};
Object.entries(pools).forEach(([key, globals]) => {
compilerPools[key] = new Set(Object.keys(globals));
});
const buffer = compiler_1.compileModule({
pools: compilerPools,
functions,
eelVersion,
});
const mod = await WebAssembly.compile(buffer);
var importObject = Object.assign(Object.assign({}, pools), { shims: shims_1.default });
return await WebAssembly.instantiate(mod, importObject);
}
exports.loadModule = loadModule;
//# sourceMappingURL=loader.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/parser.js":
/*!**************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/parser.js ***!
\**************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const preProcessor_1 = __webpack_require__(/*! ./preProcessor */ "./node_modules/eel-wasm/dist/src/preProcessor.js");
const envParser_1 = __webpack_require__(/*! ./envParser */ "./node_modules/eel-wasm/dist/src/envParser.js");
const astUtils_1 = __webpack_require__(/*! ./astUtils */ "./node_modules/eel-wasm/dist/src/astUtils.js");
const errorUtils_1 = __webpack_require__(/*! ./errorUtils */ "./node_modules/eel-wasm/dist/src/errorUtils.js");
function mapLoc(loc, mapper) {
const first = preProcessor_1.getLoc(mapper, loc.first_column);
const last = preProcessor_1.getLoc(mapper, loc.last_column);
return {
first_column: first.column,
last_column: last.column,
first_line: first.line,
last_line: last.line,
};
}
function parse(code) {
const [processedCode, mapper] = preProcessor_1.preProcess(code);
try {
const ast = envParser_1.parse(processedCode);
return astUtils_1.mapAst(ast, (node) => {
if (node.loc.first_line !== 1 || node.loc.last_line != 1) {
throw errorUtils_1.createCompilerError("Unexpected multiline", node.loc, code);
}
return Object.assign(Object.assign({}, node), { loc: mapLoc(node.loc, mapper) });
});
}
catch (e) {
if (e.hash == null) {
throw e;
}
throw errorUtils_1.createUserError(`Parse Error: ${e.message.split("\n")[3]}`, mapLoc(e.hash.loc, mapper), code);
}
}
exports.parse = parse;
//# sourceMappingURL=parser.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/preProcessor.js":
/*!********************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/preProcessor.js ***!
\********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getLoc(mapper, destCol) {
let previousAnchor = { destCol: 1, srcCol: 1, srcLine: 1 };
// Find the last anchor with a destCol > destCol.
// Reversed: Find the first anchor with a destCol <= destCol
// TODO: Use binary search
mapper.forEach(anchor => {
if (anchor.destCol > destCol) {
return;
}
previousAnchor = anchor;
});
const remainingColumns = destCol - previousAnchor.destCol;
return {
column: previousAnchor.srcCol + remainingColumns,
line: previousAnchor.srcLine,
};
}
exports.getLoc = getLoc;
// Started with this function: https://github.com/WACUP/vis_milk2/blob/cc2e85aed44373d0b6b2115c0806ec035856860a/vis_milk2/state.cpp#L1532-L1557
function preProcess(src) {
const mapper = [];
let srcLine = 1;
let dest = "";
let lineStart = 0;
let inlineComment = false;
let blockComment = false;
let emitAnchor = false;
for (let i = 0; i < src.length; i++) {
const char = src[i];
if (emitAnchor) {
const destCol = dest.length + 1;
const srcCol = i - lineStart + 1;
mapper.push({ destCol, srcCol, srcLine });
emitAnchor = false;
}
if (char === "\n") {
inlineComment = false;
srcLine++;
lineStart = i + 1;
emitAnchor = true;
}
else if (char === "\r" && src[i + 1] === "\n") {
i++;
inlineComment = false;
srcLine++;
lineStart = i + 1;
emitAnchor = true;
}
else if (blockComment && char === "*" && src[i + 1] === "/") {
// TODO: What if we are not currently in a block comment?
blockComment = false;
i++;
emitAnchor = true;
}
else if ((char === "\\" && src[i + 1] === "\\") ||
(char === "/" && src[i + 1] === "/")) {
inlineComment = true;
i++;
}
else if (char === "/" && src[i + 1] === "*") {
blockComment = true;
i++;
}
else if (!inlineComment && !blockComment) {
dest += char;
}
}
return [dest, mapper];
}
exports.preProcess = preProcess;
//# sourceMappingURL=preProcessor.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/shims.js":
/*!*************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/shims.js ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const EPSILON = 0.00001;
const shims = {
// TODO: Reimplement some of these functions natively in Wasm?
sin: Math.sin,
cos: Math.cos,
tan: Math.tan,
asin: Math.asin,
acos: Math.acos,
atan: Math.atan,
atan2: Math.atan2,
rand: a => Math.random() * a,
pow: Math.pow,
log: Math.log,
log10: Math.log10,
exp: Math.exp,
sigmoid: function (x, y) {
const t = 1 + Math.exp(-x * y);
return Math.abs(t) > EPSILON ? 1.0 / t : 0;
},
};
exports.default = shims;
//# sourceMappingURL=shims.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/utils.js":
/*!*************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/utils.js ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function arrayJoin(arr, joiner) {
const newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i]);
const last = i === arr.length - 1;
if (!last) {
newArr.push(joiner);
}
}
return newArr;
}
exports.arrayJoin = arrayJoin;
function flatten(arr) {
return [].concat.apply([], arr);
}
exports.flatten = flatten;
function times(n, cb) {
return new Array(n).fill(null).map((_, i) => cb(i));
}
exports.times = times;
function repeat(n, char) {
return new Array(n).fill(char).join("");
}
exports.repeat = repeat;
// Maintain an ordered list of indexes for namespace/key pairs.
// In Wasm binary variables are referenced by their index. In our emitter we
// want to emit variables indexes as we encounter their names. This data
// structure lets us issue variable indexes on demmand and then iterate through
// them post facto.
//
// `null` may be passed for the namespace argument in order to get a global
// variable that exists in all namespaces.
class ScopedIdMap {
constructor() {
this._map = new Map();
}
// Get the index of a given namespace/key pair
get(namespace, key) {
const jointKey = namespace == null ? key : `${namespace}::${key}`;
if (!this._map.has(jointKey)) {
this._map.set(jointKey, this._map.size);
}
// @ts-ignore We know the key is here.
return this._map.get(jointKey);
}
size() {
return this._map.size;
}
}
exports.ScopedIdMap = ScopedIdMap;
function formatList(list) {
if (list.length === 0) {
throw new Error("Cannot format an empty list");
}
if (list.length === 1) {
return list[0];
}
const quoted = list.map(name => `"${name}"`);
const last = quoted.pop();
return quoted.join(", ") + ` and ${last}`;
}
exports.formatList = formatList;
//# sourceMappingURL=utils.js.map
/***/ }),
/***/ "./node_modules/eel-wasm/dist/src/wasmFunctions.js":
/*!*********************************************************!*\
!*** ./node_modules/eel-wasm/dist/src/wasmFunctions.js ***!
\*********************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const encoding_1 = __webpack_require__(/*! ./encoding */ "./node_modules/eel-wasm/dist/src/encoding.js");
const constants_1 = __webpack_require__(/*! ./constants */ "./node_modules/eel-wasm/dist/src/constants.js");
exports.localFuncMap = {
sqr: {
args: [encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
binary: [...encoding_1.op.local_get(0), ...encoding_1.op.local_get(0), encoding_1.op.f64_mul],
},
bor: {
args: [encoding_1.VAL_TYPE.f64, encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
binary: [
...encoding_1.op.local_get(0),
...encoding_1.IS_NOT_ZEROISH,
...encoding_1.op.local_get(1),
...encoding_1.IS_NOT_ZEROISH,
encoding_1.op.i32_or,
...encoding_1.op.i32_const(0),
encoding_1.op.i32_ne,
encoding_1.op.f64_convert_i32_s,
],
},
band: {
args: [encoding_1.VAL_TYPE.f64, encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
binary: [
...encoding_1.op.local_get(0),
...encoding_1.IS_NOT_ZEROISH,
...encoding_1.op.local_get(1),
...encoding_1.IS_NOT_ZEROISH,
encoding_1.op.i32_and,
...encoding_1.op.i32_const(0),
encoding_1.op.i32_ne,
encoding_1.op.f64_convert_i32_s,
],
},
sign: {
args: [encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
binary: [
...encoding_1.op.f64_const(0),
...encoding_1.op.local_get(0),
encoding_1.op.f64_lt,
...encoding_1.op.local_get(0),
...encoding_1.op.f64_const(0),
encoding_1.op.f64_lt,
encoding_1.op.i32_sub,
encoding_1.op.f64_convert_i32_s,
],
},
mod: {
args: [encoding_1.VAL_TYPE.f64, encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
localVariables: [encoding_1.VAL_TYPE.i32],
// TODO: Simplify all this type coersion
binary: [
...encoding_1.op.local_get(1),
encoding_1.op.i32_trunc_f64_s,
...encoding_1.op.local_tee(2),
...encoding_1.op.i32_const(0),
encoding_1.op.i32_ne,
...encoding_1.op.if(encoding_1.BLOCK.f64),
...encoding_1.op.local_get(0),
encoding_1.op.i32_trunc_f64_s,
...encoding_1.op.local_get(2),
encoding_1.op.i32_rem_s,
encoding_1.op.f64_convert_i32_s,
encoding_1.op.else,
...encoding_1.op.f64_const(0),
encoding_1.op.end,
],
},
bitwiseOr: {
args: [encoding_1.VAL_TYPE.f64, encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
binary: [
...encoding_1.op.local_get(0),
encoding_1.op.i64_trunc_s_f64,
...encoding_1.op.local_get(1),
encoding_1.op.i64_trunc_s_f64,
encoding_1.op.i64_or,
encoding_1.op.f64_convert_i64_s,
],
},
bitwiseAnd: {
args: [encoding_1.VAL_TYPE.f64, encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
binary: [
...encoding_1.op.local_get(0),
encoding_1.op.i64_trunc_s_f64,
...encoding_1.op.local_get(1),
encoding_1.op.i64_trunc_s_f64,
encoding_1.op.i64_and,
encoding_1.op.f64_convert_i64_s,
],
},
div: {
args: [encoding_1.VAL_TYPE.f64, encoding_1.VAL_TYPE.f64],
returns: [encoding_1.VAL_TYPE.f64],
localVariables: [encoding_1.VAL_TYPE.i32],
binary: [
...encoding_1.op.local_get(1),
...encoding_1.op.f64_const(0),
encoding_1.op.f64_ne,
...encoding_1.op.if(encoding_1.BLOCK.f64),
...encoding_1.op.local_get(0),
...encoding_1.op.local_get(1),
encoding_1.op.f64_div,
encoding_1.op.else,
...encoding_1.op.f64_const(0),
encoding_1.op.end,
],
},
// Takes a float buffer index and converts it to an int. Values out of range
// are returned as `-1`.
//
// NOTE: There's actually a subtle bug that exists in Milkdrop's Eel
// implementation, which we reproduce here.
//
// Wasm's `trunc()` rounds towards zero. This means that for index `-1` we
// will return zero, since: `roundTowardZero(-1 + EPSILON) == 0`
//
// A subsequent check handles negative indexes, so negative indexes > than
// `-1` are not affected.
_getBufferIndex: {
args: [encoding_1.VAL_TYPE.f64 /* 0: $index */],
returns: [encoding_1.VAL_TYPE.i32 /* $noramlizedIndex */],
localVariables: [
encoding_1.VAL_TYPE.f64,
encoding_1.VAL_TYPE.i32,
],
binary: [
...encoding_1.op.f64_const(encoding_1.EPSILON),
...encoding_1.op.local_get(0),
encoding_1.op.f64_add,
// STACK: [$i + EPSILON]
...encoding_1.op.local_tee(1),
encoding_1.op.i32_trunc_f64_s,
// TODO We could probably make this a tee and get rid of the next get if we swap the final condition
...encoding_1.op.local_set(2),
// STACK: []
...encoding_1.op.i32_const(-1),
...encoding_1.op.local_get(2),
// STACK: [-1, $truncated]
...encoding_1.op.i32_const(8),
encoding_1.op.i32_mul,
// STACK: [-1, $truncated * 8]
...encoding_1.op.local_get(2),
...encoding_1.op.i32_const(0),
// STACK: [-1, $truncated * 8, $truncated, 0]
encoding_1.op.i32_lt_s,
// STACK: [-1, $truncated * 8, <is index less than 0>]
...encoding_1.op.local_get(2),
...encoding_1.op.i32_const(constants_1.BUFFER_SIZE - 1),
encoding_1.op.i32_gt_s,
// STACK: [-1, $truncated * 8, <is index less than 0>, <is index more than MAX>]
encoding_1.op.i32_or,
// STACK: [-1, $truncated * 8, <is index out of range>]
encoding_1.op.select,
],
},
};
//# sourceMappingURL=wasmFunctions.js.map
/***/ }),
/***/ "./node_modules/process/browser.js":
/*!*****************************************!*\
!*** ./node_modules/process/browser.js ***!
\*****************************************/
/*! no static exports found */
/***/ (function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ }),
/***/ "./node_modules/webpack/buildin/module.js":
/*!***********************************!*\
!*** (webpack)/buildin/module.js ***!
\***********************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = function(module) {
if (!module.webpackPolyfill) {
module.deprecate = function() {};
module.paths = [];
// module.parent = undefined by default
if (!module.children) module.children = [];
Object.defineProperty(module, "loaded", {
enumerable: true,
get: function() {
return module.l;
}
});
Object.defineProperty(module, "id", {
enumerable: true,
get: function() {
return module.i;
}
});
module.webpackPolyfill = 1;
}
return module;
};
/***/ }),
/***/ "./src/assemblyscript/presetFunctions.ts":
/*!***********************************************!*\
!*** ./src/assemblyscript/presetFunctions.ts ***!
\***********************************************/
/*! no static exports found */
/***/ (function(module, exports) {
var data = "AGFzbQEAAAABPQpgAABgAXwBfGACfHwBfGACf38AYAR/f39/AGAJf39/f3x8fHx8AGADf399AGABfwF/YAJ/fwF/YAF+AX8CuBWMAQNlbnYFYWJvcnQABAhwaXhlbEVxcwtwZXJQaXhlbEVxcwAADHBpeGVsVmFyUG9vbAR3YXJwA3wBDHBpeGVsVmFyUG9vbAR6b29tA3wBDHBpeGVsVmFyUG9vbAd6b29tZXhwA3wBDHBpeGVsVmFyUG9vbAJjeAN8AQxwaXhlbFZhclBvb2wCY3kDfAEMcGl4ZWxWYXJQb29sAnN4A3wBDHBpeGVsVmFyUG9vbAJzeQN8AQxwaXhlbFZhclBvb2wCZHgDfAEMcGl4ZWxWYXJQb29sAmR5A3wBDHBpeGVsVmFyUG9vbANyb3QDfAEMcGl4ZWxWYXJQb29sA3JhZAN8AQxwaXhlbFZhclBvb2wDYW5nA3wBDHBpeGVsVmFyUG9vbAF4A3wBDHBpeGVsVmFyUG9vbAF5A3wBCHFWYXJQb29sAnExA3wBCHFWYXJQb29sAnEyA3wBCHFWYXJQb29sAnEzA3wBCHFWYXJQb29sAnE0A3wBCHFWYXJQb29sAnE1A3wBCHFWYXJQb29sAnE2A3wBCHFWYXJQb29sAnE3A3wBCHFWYXJQb29sAnE4A3wBCHFWYXJQb29sAnE5A3wBCHFWYXJQb29sA3ExMAN8AQhxVmFyUG9vbANxMTEDfAEIcVZhclBvb2wDcTEyA3wBCHFWYXJQb29sA3ExMwN8AQhxVmFyUG9vbANxMTQDfAEIcVZhclBvb2wDcTE1A3wBCHFWYXJQb29sA3ExNgN8AQhxVmFyUG9vbANxMTcDfAEIcVZhclBvb2wDcTE4A3wBCHFWYXJQb29sA3ExOQN8AQhxVmFyUG9vbANxMjADfAEIcVZhclBvb2wDcTIxA3wBCHFWYXJQb29sA3EyMgN8AQhxVmFyUG9vbANxMjMDfAEIcVZhclBvb2wDcTI0A3wBCHFWYXJQb29sA3EyNQN8AQhxVmFyUG9vbANxMjYDfAEIcVZhclBvb2wDcTI3A3wBCHFWYXJQb29sA3EyOAN8AQhxVmFyUG9vbANxMjkDfAEIcVZhclBvb2wDcTMwA3wBCHFWYXJQb29sA3EzMQN8AQhxVmFyUG9vbANxMzIDfAEIdFZhclBvb2wCdDEDfAEIdFZhclBvb2wCdDIDfAEIdFZhclBvb2wCdDMDfAEIdFZhclBvb2wCdDQDfAEIdFZhclBvb2wCdDUDfAEIdFZhclBvb2wCdDYDfAEIdFZhclBvb2wCdDcDfAEIdFZhclBvb2wCdDgDfAEKc2hhcGVQb29sMAN4XzADfAEKc2hhcGVQb29sMAN5XzADfAEKc2hhcGVQb29sMAVyYWRfMAN8AQpzaGFwZVBvb2wwBWFuZ18wA3wBCnNoYXBlUG9vbDADcl8wA3wBCnNoYXBlUG9vbDADZ18wA3wBCnNoYXBlUG9vbDADYl8wA3wBCnNoYXBlUG9vbDADYV8wA3wBCnNoYXBlUG9vbDAEcjJfMAN8AQpzaGFwZVBvb2wwBGcyXzADfAEKc2hhcGVQb29sMARiMl8wA3wBCnNoYXBlUG9vbDAEYTJfMAN8AQpzaGFwZVBvb2wwCmJvcmRlcl9yXzADfAEKc2hhcGVQb29sMApib3JkZXJfZ18wA3wBCnNoYXBlUG9vbDAKYm9yZGVyX2JfMAN8AQpzaGFwZVBvb2wwCmJvcmRlcl9hXzADfAEKc2hhcGVQb29sMA50aGlja291dGxpbmVfMAN8AQpzaGFwZVBvb2wwCnRleHR1cmVkXzADfAEKc2hhcGVQb29sMAp0ZXhfem9vbV8wA3wBCnNoYXBlUG9vbDAJdGV4X2FuZ18wA3wBCnNoYXBlUG9vbDAKYWRkaXRpdmVfMAN8AQpzaGFwZVBvb2wxA3hfMQN8AQpzaGFwZVBvb2wxA3lfMQN8AQpzaGFwZVBvb2wxBXJhZF8xA3wBCnNoYXBlUG9vbDEFYW5nXzEDfAEKc2hhcGVQb29sMQNyXzEDfAEKc2hhcGVQb29sMQNnXzEDfAEKc2hhcGVQb29sMQNiXzEDfAEKc2hhcGVQb29sMQNhXzEDfAEKc2hhcGVQb29sMQRyMl8xA3wBCnNoYXBlUG9vbDEEZzJfMQN8AQpzaGFwZVBvb2wxBGIyXzEDfAEKc2hhcGVQb29sMQRhMl8xA3wBCnNoYXBlUG9vbDEKYm9yZGVyX3JfMQN8AQpzaGFwZVBvb2wxCmJvcmRlcl9nXzEDfAEKc2hhcGVQb29sMQpib3JkZXJfYl8xA3wBCnNoYXBlUG9vbDEKYm9yZGVyX2FfMQN8AQpzaGFwZVBvb2wxDnRoaWNrb3V0bGluZV8xA3wBCnNoYXBlUG9vbDEKdGV4dHVyZWRfMQN8AQpzaGFwZVBvb2wxCnRleF96b29tXzEDfAEKc2hhcGVQb29sMQl0ZXhfYW5nXzEDfAEKc2hhcGVQb29sMQphZGRpdGl2ZV8xA3wBCnNoYXBlUG9vbDIDeF8yA3wBCnNoYXBlUG9vbDIDeV8yA3wBCnNoYXBlUG9vbDIFcmFkXzIDfAEKc2hhcGVQb29sMgVhbmdfMgN8AQpzaGFwZVBvb2wyA3JfMgN8AQpzaGFwZVBvb2wyA2dfMgN8AQpzaGFwZVBvb2wyA2JfMgN8AQpzaGFwZVBvb2wyA2FfMgN8AQpzaGFwZVBvb2wyBHIyXzIDfAEKc2hhcGVQb29sMgRnMl8yA3wBCnNoYXBlUG9vbDIEYjJfMgN8AQpzaGFwZVBvb2wyBGEyXzIDfAEKc2hhcGVQb29sMgpib3JkZXJfcl8yA3wBCnNoYXBlUG9vbDIKYm9yZGVyX2dfMgN8AQpzaGFwZVBvb2wyCmJvcmRlcl9iXzIDfAEKc2hhcGVQb29sMgpib3JkZXJfYV8yA3wBCnNoYXBlUG9vbDIOdGhpY2tvdXRsaW5lXzIDfAEKc2hhcGVQb29sMgp0ZXh0dXJlZF8yA3wBCnNoYXBlUG9vbDIKdGV4X3pvb21fMgN8AQpzaGFwZVBvb2wyCXRleF9hbmdfMgN8AQpzaGFwZVBvb2wyCmFkZGl0aXZlXzIDfAEKc2hhcGVQb29sMwN4XzMDfAEKc2hhcGVQb29sMwN5XzMDfAEKc2hhcGVQb29sMwVyYWRfMwN8AQpzaGFwZVBvb2wzBWFuZ18zA3wBCnNoYXBlUG9vbDMDcl8zA3wBCnNoYXBlUG9vbDMDZ18zA3wBCnNoYXBlUG9vbDMDYl8zA3wBCnNoYXBlUG9vbDMDYV8zA3wBCnNoYXBlUG9vbDMEcjJfMwN8AQpzaGFwZVBvb2wzBGcyXzMDfAEKc2hhcGVQb29sMwRiMl8zA3wBCnNoYXBlUG9vbDMEYTJfMwN8AQpzaGFwZVBvb2wzCmJvcmRlcl9yXzMDfAEKc2hhcGVQb29sMwpib3JkZXJfZ18zA3wBCnNoYXBlUG9vbDMKYm9yZGVyX2JfMwN8AQpzaGFwZVBvb2wzCmJvcmRlcl9hXzMDfAEKc2hhcGVQb29sMw50aGlja291dGxpbmVfMwN8AQpzaGFwZVBvb2wzCnRleHR1cmVkXzMDfAEKc2hhcGVQb29sMwp0ZXhfem9vbV8zA3wBCnNoYXBlUG9vbDMJdGV4X2FuZ18zA3wBCnNoYXBlUG9vbDMKYWRkaXRpdmVfMwN8AQMZGAgDBwkBAQICAQYFAAAAAAAAAAAAAAAAAAUDAQABBuwMigF8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt8AUQAAAAAAAAAAAt/AUEAC3wBRAAAAAAAAAAAC3wBRAAAAAAAAAAAC34BQgALB9kB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";
module.exports = () => data;
/***/ }),
/***/ "./src/audio/audioLevels.js":
/*!**********************************!*\
!*** ./src/audio/audioLevels.js ***!
\**********************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AudioLevels; });
class AudioLevels {
constructor(audio) {
this.audio = audio;
let sampleRate;
if (this.audio.audioContext) {
sampleRate = this.audio.audioContext.sampleRate;
} else {
sampleRate = 44100;
}
const bucketHz = sampleRate / this.audio.fftSize;
const bassLow = Math.clamp(Math.round(20 / bucketHz) - 1, 0, this.audio.numSamps - 1);
const bassHigh = Math.clamp(Math.round(320 / bucketHz) - 1, 0, this.audio.numSamps - 1);
const midHigh = Math.clamp(Math.round(2800 / bucketHz) - 1, 0, this.audio.numSamps - 1);
const trebHigh = Math.clamp(Math.round(11025 / bucketHz) - 1, 0, this.audio.numSamps - 1);
this.starts = [bassLow, bassHigh, midHigh];
this.stops = [bassHigh, midHigh, trebHigh];
this.val = new Float32Array(3);
this.imm = new Float32Array(3);
this.att = new Float32Array(3);
this.avg = new Float32Array(3);
this.longAvg = new Float32Array(3);
this.att.fill(1);
this.avg.fill(1);
this.longAvg.fill(1);
}
/* eslint-disable camelcase */
get bass() {
return this.val[0];
}
get bass_att() {
return this.att[0];
}
get mid() {
return this.val[1];
}
get mid_att() {
return this.att[1];
}
get treb() {
return this.val[2];
}
get treb_att() {
return this.att[2];
}
/* eslint-enable camelcase */
static isFiniteNumber(num) {
return Number.isFinite(num) && !Number.isNaN(num);
}
static adjustRateToFPS(rate, baseFPS, FPS) {
return rate ** (baseFPS / FPS);
}
updateAudioLevels(fps, frame) {
if (this.audio.freqArray.length > 0) {
let effectiveFPS = fps;
if (!AudioLevels.isFiniteNumber(effectiveFPS) || effectiveFPS < 15) {
effectiveFPS = 15;
} else if (effectiveFPS > 144) {
effectiveFPS = 144;
} // Clear for next loop
this.imm.fill(0);
for (let i = 0; i < 3; i++) {
for (let j = this.starts[i]; j < this.stops[i]; j++) {
this.imm[i] += this.audio.freqArray[j];
}
}
for (let i = 0; i < 3; i++) {
let rate;
if (this.imm[i] > this.avg[i]) {
rate = 0.2;
} else {
rate = 0.5;
}
rate = AudioLevels.adjustRateToFPS(rate, 30.0, effectiveFPS);
this.avg[i] = this.avg[i] * rate + this.imm[i] * (1 - rate);
if (frame < 50) {
rate = 0.9;
} else {
rate = 0.992;
}
rate = AudioLevels.adjustRateToFPS(rate, 30.0, effectiveFPS);
this.longAvg[i] = this.longAvg[i] * rate + this.imm[i] * (1 - rate);
if (this.longAvg[i] < 0.001) {
this.val[i] = 1.0;
this.att[i] = 1.0;
} else {
this.val[i] = this.imm[i] / this.longAvg[i];
this.att[i] = this.avg[i] / this.longAvg[i];
}
}
}
}
}
/***/ }),
/***/ "./src/audio/audioProcessor.js":
/*!*************************************!*\
!*** ./src/audio/audioProcessor.js ***!
\*************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return AudioProcessor; });
/* harmony import */ var _fft__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./fft */ "./src/audio/fft.js");
class AudioProcessor {
constructor(context) {
this.numSamps = 512;
this.fftSize = this.numSamps * 2;
this.fft = new _fft__WEBPACK_IMPORTED_MODULE_0__["default"](this.fftSize, 512, true);
if (context) {
this.audioContext = context;
this.audible = context.createDelay();
this.analyser = context.createAnalyser();
this.analyser.smoothingTimeConstant = 0.0;
this.analyser.fftSize = this.fftSize;
this.audible.connect(this.analyser); // Split channels
this.analyserL = context.createAnalyser();
this.analyserL.smoothingTimeConstant = 0.0;
this.analyserL.fftSize = this.fftSize;
this.analyserR = context.createAnalyser();
this.analyserR.smoothingTimeConstant = 0.0;
this.analyserR.fftSize = this.fftSize;
this.splitter = context.createChannelSplitter(2);
this.audible.connect(this.splitter);
this.splitter.connect(this.analyserL, 0);
this.splitter.connect(this.analyserR, 1);
} // Initialised once as typed arrays
// Used for webaudio API raw (time domain) samples. 0 -> 255
this.timeByteArray = new Uint8Array(this.fftSize);
this.timeByteArrayL = new Uint8Array(this.fftSize);
this.timeByteArrayR = new Uint8Array(this.fftSize); // Signed raw samples shifted to -128 -> 127
this.timeArray = new Int8Array(this.fftSize);
this.timeByteArraySignedL = new Int8Array(this.fftSize);
this.timeByteArraySignedR = new Int8Array(this.fftSize); // Temporary array for smoothing
this.tempTimeArrayL = new Int8Array(this.fftSize);
this.tempTimeArrayR = new Int8Array(this.fftSize); // Undersampled from this.fftSize to this.numSamps
this.timeArrayL = new Int8Array(this.numSamps);
this.timeArrayR = new Int8Array(this.numSamps);
}
sampleAudio() {
this.analyser.getByteTimeDomainData(this.timeByteArray);
this.analyserL.getByteTimeDomainData(this.timeByteArrayL);
this.analyserR.getByteTimeDomainData(this.timeByteArrayR);
this.processAudio();
}
updateAudio(timeByteArray, timeByteArrayL, timeByteArrayR) {
this.timeByteArray.set(timeByteArray);
this.timeByteArrayL.set(timeByteArrayL);
this.timeByteArrayR.set(timeByteArrayR);
this.processAudio();
}
/* eslint-disable no-bitwise */
processAudio() {
for (let i = 0, j = 0, lastIdx = 0; i < this.fftSize; i++) {
// Shift Unsigned to Signed about 0
this.timeArray[i] = this.timeByteArray[i] - 128;
this.timeByteArraySignedL[i] = this.timeByteArrayL[i] - 128;
this.timeByteArraySignedR[i] = this.timeByteArrayR[i] - 128;
this.tempTimeArrayL[i] = 0.5 * (this.timeByteArraySignedL[i] + this.timeByteArraySignedL[lastIdx]);
this.tempTimeArrayR[i] = 0.5 * (this.timeByteArraySignedR[i] + this.timeByteArraySignedR[lastIdx]); // Undersampled
if (i % 2 === 0) {
this.timeArrayL[j] = this.tempTimeArrayL[i];
this.timeArrayR[j] = this.tempTimeArrayR[i];
j += 1;
}
lastIdx = i;
} // Use full width samples for the FFT
this.freqArray = this.fft.timeToFrequencyDomain(this.timeArray);
this.freqArrayL = this.fft.timeToFrequencyDomain(this.timeByteArraySignedL);
this.freqArrayR = this.fft.timeToFrequencyDomain(this.timeByteArraySignedR);
}
connectAudio(audionode) {
audionode.connect(this.audible);
}
disconnectAudio(audionode) {
audionode.disconnect(this.audible);
}
/* eslint-enable no-bitwise */
}
/***/ }),
/***/ "./src/audio/fft.js":
/*!**************************!*\
!*** ./src/audio/fft.js ***!
\**************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return FFT; });
class FFT {
constructor(samplesIn, samplesOut, equalize = false) {
this.samplesIn = samplesIn;
this.samplesOut = samplesOut;
this.equalize = equalize;
this.NFREQ = samplesOut * 2;
if (this.equalize) {
this.initEqualizeTable();
}
this.initBitRevTable();
this.initCosSinTable();
}
initEqualizeTable() {
this.equalizeArr = new Float32Array(this.samplesOut);
const invHalfNFREQ = 1.0 / this.samplesOut;
for (let i = 0; i < this.samplesOut; i++) {
this.equalizeArr[i] = -0.02 * Math.log((this.samplesOut - i) * invHalfNFREQ);
}
}
/* eslint-disable no-bitwise */
initBitRevTable() {
this.bitrevtable = new Uint16Array(this.NFREQ);
for (let i = 0; i < this.NFREQ; i++) {
this.bitrevtable[i] = i;
}
let j = 0;
for (let i = 0; i < this.NFREQ; i++) {
if (j > i) {
const temp = this.bitrevtable[i];
this.bitrevtable[i] = this.bitrevtable[j];
this.bitrevtable[j] = temp;
}
let m = this.NFREQ >> 1;
while (m >= 1 && j >= m) {
j -= m;
m >>= 1;
}
j += m;
}
}
initCosSinTable() {
let dftsize = 2;
let tabsize = 0;
while (dftsize <= this.NFREQ) {
tabsize += 1;
dftsize <<= 1;
}
this.cossintable = [new Float32Array(tabsize), new Float32Array(tabsize)];
dftsize = 2;
let i = 0;
while (dftsize <= this.NFREQ) {
const theta = -2.0 * Math.PI / dftsize;
this.cossintable[0][i] = Math.cos(theta);
this.cossintable[1][i] = Math.sin(theta);
i += 1;
dftsize <<= 1;
}
}
timeToFrequencyDomain(waveDataIn) {
const real = new Float32Array(this.NFREQ);
const imag = new Float32Array(this.NFREQ);
for (let i = 0; i < this.NFREQ; i++) {
const idx = this.bitrevtable[i];
if (idx < this.samplesIn) {
real[i] = waveDataIn[idx];
} else {
real[i] = 0;
}
imag[i] = 0;
}
let dftsize = 2;
let t = 0;
while (dftsize <= this.NFREQ) {
const wpr = this.cossintable[0][t];
const wpi = this.cossintable[1][t];
let wr = 1.0;
let wi = 0.0;
const hdftsize = dftsize >> 1;
for (let m = 0; m < hdftsize; m++) {
for (let i = m; i < this.NFREQ; i += dftsize) {
const j = i + hdftsize;
const tempr = wr * real[j] - wi * imag[j];
const tempi = wr * imag[j] + wi * real[j];
real[j] = real[i] - tempr;
imag[j] = imag[i] - tempi;
real[i] += tempr;
imag[i] += tempi;
}
const wtemp = wr;
wr = wtemp * wpr - wi * wpi;
wi = wi * wpr + wtemp * wpi;
}
dftsize <<= 1;
t += 1;
}
const spectralDataOut = new Float32Array(this.samplesOut);
if (this.equalize) {
for (let i = 0; i < this.samplesOut; i++) {
spectralDataOut[i] = this.equalizeArr[i] * Math.sqrt(real[i] * real[i] + imag[i] * imag[i]);
}
} else {
for (let i = 0; i < this.samplesOut; i++) {
spectralDataOut[i] = Math.sqrt(real[i] * real[i] + imag[i] * imag[i]);
}
}
return spectralDataOut;
}
/* eslint-enable no-bitwise */
}
/***/ }),
/***/ "./src/blankPreset.js":
/*!****************************!*\
!*** ./src/blankPreset.js ***!
\****************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* eslint-disable */
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
"use strict;";
var pmap = {
baseVals: {
gammaadj: 1.25,
wave_g: 0.5,
mv_x: 12.0,
warpscale: 1.0,
brighten: 0.0,
mv_y: 9.0,
wave_scale: 1.0,
echo_alpha: 0.0,
additivewave: 0.0,
sx: 1.0,
sy: 1.0,
warp: 0.01,
red_blue: 0.0,
wave_mode: 0.0,
wave_brighten: 0.0,
wrap: 0.0,
zoomexp: 1.0,
fshader: 0.0,
wave_r: 0.5,
echo_zoom: 1.0,
wave_smoothing: 0.75,
warpanimspeed: 1.0,
wave_dots: 0.0,
wave_x: 0.5,
wave_y: 0.5,
zoom: 1.0,
solarize: 0.0,
modwavealphabyvolume: 0.0,
dx: 0.0,
cx: 0.5,
dy: 0.0,
darken_center: 0.0,
cy: 0.5,
invert: 0.0,
bmotionvectorson: 0.0,
rot: 0.0,
modwavealphaend: 0.95,
wave_mystery: -0.2,
decay: 0.9,
wave_a: 1.0,
wave_b: 0.5,
rating: 5.0,
modwavealphastart: 0.75,
darken: 0.0,
echo_orient: 0.0,
ib_r: 0.5,
ib_g: 0.5,
ib_b: 0.5,
ib_a: 0.0,
ib_size: 0.0,
ob_r: 0.5,
ob_g: 0.5,
ob_b: 0.5,
ob_a: 0.0,
ob_size: 0.0,
mv_dx: 0.0,
mv_dy: 0.0,
mv_a: 0.0,
mv_r: 0.5,
mv_g: 0.5,
mv_b: 0.5,
mv_l: 0.0
},
init_eqs: function () {
var m = {};
return m;
},
frame_eqs: function (m) {
m.rkeys = ["warp"];
m.zoom = 1.01 + 0.02 * m.treb_att;
m.warp = 0.15 + 0.25 * m.bass_att;
return m;
},
pixel_eqs: function (m) {
m.warp = m.warp + m.rad * 0.15;
return m;
},
waves: [{
baseVals: {
a: 1.0,
enabled: 0.0,
b: 1.0,
g: 1.0,
scaling: 1.0,
samples: 512.0,
additive: 0.0,
usedots: 0.0,
spectrum: 0.0,
r: 1.0,
smoothing: 0.5,
thick: 0.0,
sep: 0.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
},
point_eqs: ""
}, {
baseVals: {
a: 1.0,
enabled: 0.0,
b: 1.0,
g: 1.0,
scaling: 1.0,
samples: 512.0,
additive: 0.0,
usedots: 0.0,
spectrum: 0.0,
r: 1.0,
smoothing: 0.5,
thick: 0.0,
sep: 0.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
},
point_eqs: ""
}, {
baseVals: {
a: 1.0,
enabled: 0.0,
b: 1.0,
g: 1.0,
scaling: 1.0,
samples: 512.0,
additive: 0.0,
usedots: 0.0,
spectrum: 0.0,
r: 1.0,
smoothing: 0.5,
thick: 0.0,
sep: 0.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
},
point_eqs: ""
}, {
baseVals: {
a: 1.0,
enabled: 0.0,
b: 1.0,
g: 1.0,
scaling: 1.0,
samples: 512.0,
additive: 0.0,
usedots: 0.0,
spectrum: 0.0,
r: 1.0,
smoothing: 0.5,
thick: 0.0,
sep: 0.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
},
point_eqs: ""
}],
shapes: [{
baseVals: {
r2: 0.0,
a: 1.0,
enabled: 0.0,
b: 0.0,
tex_ang: 0.0,
thickoutline: 0.0,
g: 0.0,
textured: 0.0,
g2: 1.0,
tex_zoom: 1.0,
additive: 0.0,
border_a: 0.1,
border_b: 1.0,
b2: 0.0,
a2: 0.0,
r: 1.0,
border_g: 1.0,
rad: 0.1,
x: 0.5,
y: 0.5,
ang: 0.0,
sides: 4.0,
border_r: 1.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
}
}, {
baseVals: {
r2: 0.0,
a: 1.0,
enabled: 0.0,
b: 0.0,
tex_ang: 0.0,
thickoutline: 0.0,
g: 0.0,
textured: 0.0,
g2: 1.0,
tex_zoom: 1.0,
additive: 0.0,
border_a: 0.1,
border_b: 1.0,
b2: 0.0,
a2: 0.0,
r: 1.0,
border_g: 1.0,
rad: 0.1,
x: 0.5,
y: 0.5,
ang: 0.0,
sides: 4.0,
border_r: 1.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
}
}, {
baseVals: {
r2: 0.0,
a: 1.0,
enabled: 0.0,
b: 0.0,
tex_ang: 0.0,
thickoutline: 0.0,
g: 0.0,
textured: 0.0,
g2: 1.0,
tex_zoom: 1.0,
additive: 0.0,
border_a: 0.1,
border_b: 1.0,
b2: 0.0,
a2: 0.0,
r: 1.0,
border_g: 1.0,
rad: 0.1,
x: 0.5,
y: 0.5,
ang: 0.0,
sides: 4.0,
border_r: 1.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
}
}, {
baseVals: {
r2: 0.0,
a: 1.0,
enabled: 0.0,
b: 0.0,
tex_ang: 0.0,
thickoutline: 0.0,
g: 0.0,
textured: 0.0,
g2: 1.0,
tex_zoom: 1.0,
additive: 0.0,
border_a: 0.1,
border_b: 1.0,
b2: 0.0,
a2: 0.0,
r: 1.0,
border_g: 1.0,
rad: 0.1,
x: 0.5,
y: 0.5,
ang: 0.0,
sides: 4.0,
border_r: 1.0
},
init_eqs: function (m) {
m.rkeys = [];
return m;
},
frame_eqs: function (m) {
return m;
}
}],
warp: "shader_body {\nret = texture2D(sampler_main, uv).rgb;\nret -= 0.004;\n}\n",
comp: "shader_body {\nret = texture2D(sampler_main, uv).rgb;\nret *= hue_shader;\n}\n"
};
return pmap;
}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
/* eslint-enable */
/***/ }),
/***/ "./src/equations/presetEquationRunner.js":
/*!***********************************************!*\
!*** ./src/equations/presetEquationRunner.js ***!
\***********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PresetEquationRunner; });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ "./src/utils.js");
class PresetEquationRunner {
constructor(preset, globalVars, opts) {
this.preset = preset;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.qs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(1, 33).map(x => `q${x}`);
this.ts = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(1, 9).map(x => `t${x}`);
this.regs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(100).map(x => {
if (x < 10) {
return `reg0${x}`;
}
return `reg${x}`;
});
this.initializeEquations(globalVars);
}
initializeEquations(globalVars) {
this.runVertEQs = this.preset.pixel_eqs !== "";
this.mdVSQInit = null;
this.mdVSRegs = null;
this.mdVSFrame = null;
this.mdVSUserKeys = null;
this.mdVSFrameMap = null;
this.mdVSShapes = null;
this.mdVSUserKeysShapes = null;
this.mdVSFrameMapShapes = null;
this.mdVSWaves = null;
this.mdVSUserKeysWaves = null;
this.mdVSFrameMapWaves = null;
this.mdVSQAfterFrame = null;
this.gmegabuf = new Array(1048576).fill(0);
const mdVSBase = {
frame: globalVars.frame,
time: globalVars.time,
fps: globalVars.fps,
bass: globalVars.bass,
bass_att: globalVars.bass_att,
mid: globalVars.mid,
mid_att: globalVars.mid_att,
treb: globalVars.treb,
treb_att: globalVars.treb_att,
meshx: this.mesh_width,
meshy: this.mesh_height,
aspectx: this.invAspectx,
aspecty: this.invAspecty,
pixelsx: this.texsizeX,
pixelsy: this.texsizeY,
gmegabuf: this.gmegabuf
};
this.mdVS = Object.assign({}, this.preset.baseVals, mdVSBase);
this.mdVS.megabuf = new Array(1048576).fill(0);
this.mdVS.rand_start = new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]);
this.mdVS.rand_preset = new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]);
const nonUserKeys = this.qs.concat(this.regs, Object.keys(this.mdVS));
const mdVSAfterInit = this.preset.init_eqs(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].cloneVars(this.mdVS)); // qs need to be initialized to there init values every frame
this.mdVSQInit = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSAfterInit, this.qs);
this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSAfterInit, this.regs);
const initUserVars = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSAfterInit, Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(mdVSAfterInit, nonUserKeys)));
initUserVars.megabuf = mdVSAfterInit.megabuf;
initUserVars.gmegabuf = mdVSAfterInit.gmegabuf;
this.mdVSFrame = this.preset.frame_eqs(Object.assign({}, this.mdVS, this.mdVSQInit, this.mdVSRegs, initUserVars)); // user vars need to be copied between frames
this.mdVSUserKeys = Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(this.mdVSFrame, nonUserKeys)); // Determine vars to carry over between frames
this.mdVSFrameMap = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.mdVSUserKeys); // qs for shapes
this.mdVSQAfterFrame = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.qs);
this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.regs);
this.mdVSWaves = [];
this.mdVSTWaveInits = [];
this.mdVSUserKeysWaves = [];
this.mdVSFrameMapWaves = [];
if (this.preset.waves && this.preset.waves.length > 0) {
for (let i = 0; i < this.preset.waves.length; i++) {
const wave = this.preset.waves[i];
const baseVals = wave.baseVals;
if (baseVals.enabled !== 0) {
let mdVSWave = Object.assign({}, baseVals, mdVSBase);
const nonUserWaveKeys = this.qs.concat(this.ts, this.regs, Object.keys(mdVSWave));
Object.assign(mdVSWave, this.mdVSQAfterFrame, this.mdVSRegs);
mdVSWave.megabuf = new Array(1048576).fill(0);
if (wave.init_eqs) {
mdVSWave = wave.init_eqs(mdVSWave);
this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWave, this.regs); // base vals need to be reset
Object.assign(mdVSWave, baseVals);
}
this.mdVSWaves.push(mdVSWave);
this.mdVSTWaveInits.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWave, this.ts));
this.mdVSUserKeysWaves.push(Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(mdVSWave, nonUserWaveKeys)));
this.mdVSFrameMapWaves.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWave, this.mdVSUserKeysWaves[i]));
} else {
this.mdVSWaves.push({});
this.mdVSTWaveInits.push({});
this.mdVSUserKeysWaves.push([]);
this.mdVSFrameMapWaves.push({});
}
}
}
this.mdVSShapes = [];
this.mdVSTShapeInits = [];
this.mdVSUserKeysShapes = [];
this.mdVSFrameMapShapes = [];
if (this.preset.shapes && this.preset.shapes.length > 0) {
for (let i = 0; i < this.preset.shapes.length; i++) {
const shape = this.preset.shapes[i];
const baseVals = shape.baseVals;
if (baseVals.enabled !== 0) {
let mdVSShape = Object.assign({}, baseVals, mdVSBase);
const nonUserShapeKeys = this.qs.concat(this.ts, this.regs, Object.keys(mdVSShape));
Object.assign(mdVSShape, this.mdVSQAfterFrame, this.mdVSRegs);
mdVSShape.megabuf = new Array(1048576).fill(0);
if (shape.init_eqs) {
mdVSShape = shape.init_eqs(mdVSShape);
this.mdVSRegs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSShape, this.regs); // base vals need to be reset
Object.assign(mdVSShape, baseVals);
}
this.mdVSShapes.push(mdVSShape);
this.mdVSTShapeInits.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSShape, this.ts));
this.mdVSUserKeysShapes.push(Object.keys(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].omit(mdVSShape, nonUserShapeKeys)));
this.mdVSFrameMapShapes.push(_utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSShape, this.mdVSUserKeysShapes[i]));
} else {
this.mdVSShapes.push({});
this.mdVSTShapeInits.push({});
this.mdVSUserKeysShapes.push([]);
this.mdVSFrameMapShapes.push({});
}
}
}
}
updatePreset(preset, globalVars) {
this.preset = preset;
this.initializeEquations(globalVars);
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
}
runFrameEquations(globalVars) {
this.mdVSFrame = Object.assign({}, this.mdVS, this.mdVSQInit, this.mdVSFrameMap, globalVars);
this.mdVSFrame = this.preset.frame_eqs(this.mdVSFrame);
this.mdVSFrameMap = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.mdVSUserKeys);
this.mdVSQAfterFrame = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSFrame, this.qs);
return this.mdVSFrame;
}
runPixelEquations(mdVSVertex) {
return this.preset.pixel_eqs(mdVSVertex);
}
runShapeFrameEquations(shapeIdx, mdVSShape) {
return this.preset.shapes[shapeIdx].frame_eqs(mdVSShape);
}
runWaveFrameEquations(waveIdx, mdVSWave) {
return this.preset.waves[waveIdx].frame_eqs(mdVSWave);
}
runWavePointEquations(waveIdx, mdVSWaveFrame) {
return this.preset.waves[waveIdx].point_eqs(mdVSWaveFrame);
}
}
/***/ }),
/***/ "./src/equations/presetEquationRunnerWASM.js":
/*!***************************************************!*\
!*** ./src/equations/presetEquationRunnerWASM.js ***!
\***************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PresetEquationRunnerWASM; });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ "./src/utils.js");
class PresetEquationRunnerWASM {
constructor(preset, globalVars, opts) {
this.preset = preset;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.qs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(1, 33).map(x => `q${x}`);
this.ts = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(1, 9).map(x => `t${x}`);
this.regs = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].range(100).map(x => {
if (x < 10) {
return `reg0${x}`;
}
return `reg${x}`;
});
this.globalKeys = ["frame", "time", "fps", "bass", "bass_att", "mid", "mid_att", "treb", "treb_att", "meshx", "meshy", "aspectx", "aspecty", "pixelsx", "pixelsy"];
this.frameKeys = ["decay", "wave_a", "wave_r", "wave_g", "wave_b", "wave_x", "wave_y", "wave_scale", "wave_smoothing", "wave_mode", "old_wave_mode", "wave_mystery", "ob_size", "ob_r", "ob_g", "ob_b", "ob_a", "ib_size", "ib_r", "ib_g", "ib_b", "ib_a", "mv_x", "mv_y", "mv_dx", "mv_dy", "mv_l", "mv_r", "mv_g", "mv_b", "mv_a", "echo_zoom", "echo_alpha", "echo_orient", "wave_dots", "wave_thick", "additivewave", "wave_brighten", "modwavealphabyvolume", "modwavealphastart", "modwavealphaend", "darken_center", "gammaadj", "warp", "warpanimspeed", "warpscale", "zoom", "zoomexp", "rot", "cx", "cy", "dx", "dy", "sx", "sy", "fshader", "wrap", "invert", "brighten", "darken", "solarize", "bmotionvectorson", "b1n", "b2n", "b3n", "b1x", "b2x", "b3x", "b1ed"];
this.waveFrameKeys = ["samples", "sep", "scaling", "spectrum", "smoothing", "r", "g", "b", "a"];
this.waveFrameInputKeys = ["samples", "r", "g", "b", "a"];
this.initializeEquations(globalVars);
}
getQVars(pool) {
return _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pickWasm(this.preset.globalPools[pool], this.qs);
}
getTVars(pool) {
return _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pickWasm(this.preset.globalPools[pool], this.ts);
}
initializeEquations(globalVars) {
this.runVertEQs = !!this.preset.pixel_eqs;
this.mdVSQInit = null;
this.mdVSQAfterFrame = null;
const mdVSBase = {
frame: globalVars.frame,
time: globalVars.time,
fps: globalVars.fps,
bass: globalVars.bass,
bass_att: globalVars.bass_att,
mid: globalVars.mid,
mid_att: globalVars.mid_att,
treb: globalVars.treb,
treb_att: globalVars.treb_att,
meshx: this.mesh_width,
meshy: this.mesh_height,
aspectx: this.invAspectx,
aspecty: this.invAspecty,
pixelsx: this.texsizeX,
pixelsy: this.texsizeY
};
this.mdVS = Object.assign({}, this.preset.baseVals, mdVSBase); // eslint-disable-next-line max-len
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools.perFrame, this.mdVS, Object.keys(this.mdVS));
this.rand_start = new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]);
this.rand_preset = new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]);
this.preset.init_eqs(); // qs need to be initialized to there init values every frame
this.mdVSQInit = this.getQVars("perFrame");
this.preset.frame_eqs();
this.mdVSQAfterFrame = this.getQVars("perFrame");
this.mdVSTWaveInits = [];
if (this.preset.waves && this.preset.waves.length > 0) {
for (let i = 0; i < this.preset.waves.length; i++) {
const wave = this.preset.waves[i];
const baseVals = wave.baseVals;
if (baseVals.enabled !== 0) {
// eslint-disable-next-line max-len
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`wavePerFrame${i}`], baseVals, Object.keys(baseVals));
if (wave.init_eqs) {
wave.init_eqs(); // base vals need to be reset
// eslint-disable-next-line max-len
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`wavePerFrame${i}`], baseVals, Object.keys(baseVals));
}
this.mdVSTWaveInits.push(this.getTVars(`wavePerFrame${i}`));
} else {
this.mdVSTWaveInits.push({});
}
}
}
this.mdVSTShapeInits = [];
if (this.preset.shapes && this.preset.shapes.length > 0) {
for (let i = 0; i < this.preset.shapes.length; i++) {
const shape = this.preset.shapes[i];
const baseVals = shape.baseVals;
if (baseVals.enabled !== 0) {
// eslint-disable-next-line max-len
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`shapePerFrame${i}`], baseVals, Object.keys(baseVals));
if (shape.init_eqs) {
shape.init_eqs(); // base vals need to be reset
// eslint-disable-next-line max-len
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`shapePerFrame${i}`], baseVals, Object.keys(baseVals));
}
this.mdVSTShapeInits.push(this.getTVars(`shapePerFrame${i}`));
} else {
this.mdVSTShapeInits.push({});
}
}
}
}
updatePreset(preset, globalVars) {
this.preset = preset;
this.initializeEquations(globalVars);
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
}
runFrameEquations(globalVars) {
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools.perFrame, this.mdVS, this.frameKeys);
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools.perFrame, this.mdVSQInit, this.qs);
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools.perFrame, globalVars, this.globalKeys);
this.preset.frame_eqs();
this.preset.save_qs();
this.mdVSQAfterFrame = this.getQVars("perFrame"); // eslint-disable-next-line max-len
const mdVSFrame = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pickWasm(this.preset.globalPools.perFrame, [...this.frameKeys, ...this.globalKeys]);
mdVSFrame.rand_preset = this.rand_preset;
mdVSFrame.rand_start = this.rand_start;
return mdVSFrame;
}
/* eslint-disable max-len */
runWaveFrameEquations(waveIdx, globalVars) {
const baseVals = this.preset.waves[waveIdx].baseVals;
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`wavePerFrame${waveIdx}`], baseVals, this.waveFrameInputKeys);
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`wavePerFrame${waveIdx}`], this.mdVSQAfterFrame, this.qs);
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`wavePerFrame${waveIdx}`], this.mdVSTWaveInits[waveIdx], this.ts);
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(this.preset.globalPools[`wavePerFrame${waveIdx}`], globalVars, this.globalKeys);
this.preset.waves[waveIdx].frame_eqs();
return _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pickWasm(this.preset.globalPools[`wavePerFrame${waveIdx}`], this.waveFrameKeys);
}
/* eslint-enable max-len */
}
/***/ }),
/***/ "./src/image/imageTextures.js":
/*!************************************!*\
!*** ./src/image/imageTextures.js ***!
\************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ImageTextures; });
class ImageTextures {
constructor(gl) {
this.gl = gl;
this.anisoExt = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic");
this.samplers = {};
/* eslint-disable max-len */
this.clouds2Image = new Image();
this.clouds2Image.onload = () => {
this.samplers.clouds2 = this.gl.createTexture();
this.bindTexture(this.samplers.clouds2, this.clouds2Image, 128, 128);
};
this.clouds2Image.src = "data:image/jpeg;base64,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";
this.emptyImage = new Image();
this.emptyImage.onload = () => {
this.samplers.empty = this.gl.createTexture();
this.bindTexture(this.samplers.empty, this.emptyImage, 1, 1);
};
this.emptyImage.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
/* eslint-enable max-len */
}
bindTexture(texture, data, width, height) {
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
if (this.anisoExt) {
const max = this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
this.gl.texParameterf(this.gl.TEXTURE_2D, this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, max);
}
}
loadExtraImages(imageData) {
Object.keys(imageData).forEach(imageName => {
const {
data,
width,
height
} = imageData[imageName];
if (!this.samplers[imageName]) {
const image = new Image();
image.onload = () => {
this.samplers[imageName] = this.gl.createTexture();
this.bindTexture(this.samplers[imageName], image, width, height);
};
image.src = data;
}
});
}
getTexture(sampler) {
const tex = this.samplers[sampler];
if (tex) {
return tex;
}
return this.samplers.clouds2;
}
}
/***/ }),
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Butterchurn; });
/* harmony import */ var ecma_proposal_math_extensions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ecma-proposal-math-extensions */ "./node_modules/ecma-proposal-math-extensions/reference-implementation/index.js");
/* harmony import */ var ecma_proposal_math_extensions__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ecma_proposal_math_extensions__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _presetBase__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./presetBase */ "./src/presetBase.js");
/* harmony import */ var _presetBase__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_presetBase__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _visualizer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./visualizer */ "./src/visualizer.js");
class Butterchurn {
static createVisualizer(context, canvas, opts) {
return new _visualizer__WEBPACK_IMPORTED_MODULE_2__["default"](context, canvas, opts);
}
}
/***/ }),
/***/ "./src/noise/noise.js":
/*!****************************!*\
!*** ./src/noise/noise.js ***!
\****************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Noise; });
class Noise {
constructor(gl) {
this.gl = gl;
this.anisoExt = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic");
this.noiseTexLQ = this.gl.createTexture();
this.noiseTexLQLite = this.gl.createTexture();
this.noiseTexMQ = this.gl.createTexture();
this.noiseTexHQ = this.gl.createTexture();
this.noiseTexVolLQ = this.gl.createTexture();
this.noiseTexVolHQ = this.gl.createTexture();
this.nTexArrLQ = Noise.createNoiseTex(256, 1);
this.nTexArrLQLite = Noise.createNoiseTex(32, 1);
this.nTexArrMQ = Noise.createNoiseTex(256, 4);
this.nTexArrHQ = Noise.createNoiseTex(256, 8);
this.nTexArrVolLQ = Noise.createNoiseVolTex(32, 1);
this.nTexArrVolHQ = Noise.createNoiseVolTex(32, 4);
this.bindTexture(this.noiseTexLQ, this.nTexArrLQ, 256, 256);
this.bindTexture(this.noiseTexLQLite, this.nTexArrLQLite, 32, 32);
this.bindTexture(this.noiseTexMQ, this.nTexArrMQ, 256, 256);
this.bindTexture(this.noiseTexHQ, this.nTexArrHQ, 256, 256);
this.bindTexture3D(this.noiseTexVolLQ, this.nTexArrVolLQ, 32, 32, 32);
this.bindTexture3D(this.noiseTexVolHQ, this.nTexArrVolHQ, 32, 32, 32);
this.noiseTexPointLQ = this.gl.createSampler();
gl.samplerParameteri(this.noiseTexPointLQ, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.samplerParameteri(this.noiseTexPointLQ, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.samplerParameteri(this.noiseTexPointLQ, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.noiseTexPointLQ, gl.TEXTURE_WRAP_T, gl.REPEAT);
}
bindTexture(texture, data, width, height) {
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
if (this.anisoExt) {
const max = this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
this.gl.texParameterf(this.gl.TEXTURE_2D, this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, max);
}
}
bindTexture3D(texture, data, width, height, depth) {
this.gl.bindTexture(this.gl.TEXTURE_3D, texture);
this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);
this.gl.texImage3D(this.gl.TEXTURE_3D, 0, this.gl.RGBA, width, height, depth, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data);
this.gl.generateMipmap(this.gl.TEXTURE_3D);
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_WRAP_T, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_WRAP_R, this.gl.REPEAT);
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
if (this.anisoExt) {
const max = this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
this.gl.texParameterf(this.gl.TEXTURE_3D, this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, max);
}
}
static fCubicInterpolate(y0, y1, y2, y3, t) {
const t2 = t * t;
const t3 = t * t2;
const a0 = y3 - y2 - y0 + y1;
const a1 = y0 - y1 - a0;
const a2 = y2 - y0;
const a3 = y1;
return a0 * t3 + a1 * t2 + a2 * t + a3;
}
static dwCubicInterpolate(y0, y1, y2, y3, t) {
const ret = [];
for (let i = 0; i < 4; i++) {
let f = Noise.fCubicInterpolate(y0[i] / 255.0, y1[i] / 255.0, y2[i] / 255.0, y3[i] / 255.0, t);
f = Math.clamp(f, 0, 1);
ret[i] = f * 255;
}
return ret;
}
static createNoiseVolTex(noiseSize, zoom) {
const nsize = noiseSize * noiseSize * noiseSize;
const texArr = new Uint8Array(nsize * 4);
const texRange = zoom > 1 ? 216 : 256;
const halfTexRange = texRange * 0.5;
for (let i = 0; i < nsize; i++) {
texArr[i * 4 + 0] = Math.floor(Math.random() * texRange + halfTexRange);
texArr[i * 4 + 1] = Math.floor(Math.random() * texRange + halfTexRange);
texArr[i * 4 + 2] = Math.floor(Math.random() * texRange + halfTexRange);
texArr[i * 4 + 3] = Math.floor(Math.random() * texRange + halfTexRange);
}
const wordsPerSlice = noiseSize * noiseSize;
const wordsPerLine = noiseSize;
if (zoom > 1) {
for (let z = 0; z < noiseSize; z += zoom) {
for (let y = 0; y < noiseSize; y += zoom) {
for (let x = 0; x < noiseSize; x++) {
if (x % zoom !== 0) {
const baseX = Math.floor(x / zoom) * zoom + noiseSize;
const baseY = z * wordsPerSlice + y * wordsPerLine;
const y0 = [];
const y1 = [];
const y2 = [];
const y3 = [];
for (let i = 0; i < 4; i++) {
y0[i] = texArr[baseY * 4 + (baseX - zoom) % noiseSize * 4 + i];
y1[i] = texArr[baseY * 4 + baseX % noiseSize * 4 + i];
y2[i] = texArr[baseY * 4 + (baseX + zoom) % noiseSize * 4 + i];
y3[i] = texArr[baseY * 4 + (baseX + zoom * 2) % noiseSize * 4 + i];
}
const t = x % zoom / zoom;
const result = Noise.dwCubicInterpolate(y0, y1, y2, y3, t);
for (let i = 0; i < 4; i++) {
const offset = x * 4 + i;
texArr[z * wordsPerSlice * 4 + y * wordsPerLine * 4 + offset] = result[i];
}
}
}
}
}
for (let z = 0; z < noiseSize; z += zoom) {
for (let x = 0; x < noiseSize; x++) {
for (let y = 0; y < noiseSize; y++) {
if (y % zoom !== 0) {
const baseY = Math.floor(y / zoom) * zoom + noiseSize;
const baseZ = z * wordsPerSlice;
const y0 = [];
const y1 = [];
const y2 = [];
const y3 = [];
for (let i = 0; i < 4; i++) {
const offset = x * 4 + baseZ * 4 + i;
y0[i] = texArr[(baseY - zoom) % noiseSize * wordsPerLine * 4 + offset];
y1[i] = texArr[baseY % noiseSize * wordsPerLine * 4 + offset];
y2[i] = texArr[(baseY + zoom) % noiseSize * wordsPerLine * 4 + offset];
y3[i] = texArr[(baseY + zoom * 2) % noiseSize * wordsPerLine * 4 + offset];
}
const t = y % zoom / zoom;
const result = Noise.dwCubicInterpolate(y0, y1, y2, y3, t);
for (let i = 0; i < 4; i++) {
const offset = x * 4 + baseZ * 4 + i;
texArr[y * wordsPerLine * 4 + offset] = result[i];
}
}
}
}
}
for (let x = 0; x < noiseSize; x++) {
for (let y = 0; y < noiseSize; y++) {
for (let z = 0; z < noiseSize; z++) {
if (z % zoom !== 0) {
const baseY = y * wordsPerLine;
const baseZ = Math.floor(z / zoom) * zoom + noiseSize;
const y0 = [];
const y1 = [];
const y2 = [];
const y3 = [];
for (let i = 0; i < 4; i++) {
const offset = x * 4 + baseY * 4 + i;
y0[i] = texArr[(baseZ - zoom) % noiseSize * wordsPerSlice * 4 + offset];
y1[i] = texArr[baseZ % noiseSize * wordsPerSlice * 4 + offset];
y2[i] = texArr[(baseZ + zoom) % noiseSize * wordsPerSlice * 4 + offset];
y3[i] = texArr[(baseZ + zoom * 2) % noiseSize * wordsPerSlice * 4 + offset];
}
const t = y % zoom / zoom;
const result = Noise.dwCubicInterpolate(y0, y1, y2, y3, t);
for (let i = 0; i < 4; i++) {
const offset = x * 4 + baseY * 4 + i;
texArr[z * wordsPerSlice * 4 + offset] = result[i];
}
}
}
}
}
}
return texArr;
}
static createNoiseTex(noiseSize, zoom) {
const nsize = noiseSize * noiseSize;
const texArr = new Uint8Array(nsize * 4);
const texRange = zoom > 1 ? 216 : 256;
const halfTexRange = texRange * 0.5;
for (let i = 0; i < nsize; i++) {
texArr[i * 4 + 0] = Math.floor(Math.random() * texRange + halfTexRange);
texArr[i * 4 + 1] = Math.floor(Math.random() * texRange + halfTexRange);
texArr[i * 4 + 2] = Math.floor(Math.random() * texRange + halfTexRange);
texArr[i * 4 + 3] = Math.floor(Math.random() * texRange + halfTexRange);
}
if (zoom > 1) {
for (let y = 0; y < noiseSize; y += zoom) {
for (let x = 0; x < noiseSize; x++) {
if (x % zoom !== 0) {
const baseX = Math.floor(x / zoom) * zoom + noiseSize;
const baseY = y * noiseSize;
const y0 = [];
const y1 = [];
const y2 = [];
const y3 = [];
for (let z = 0; z < 4; z++) {
y0[z] = texArr[baseY * 4 + (baseX - zoom) % noiseSize * 4 + z];
y1[z] = texArr[baseY * 4 + baseX % noiseSize * 4 + z];
y2[z] = texArr[baseY * 4 + (baseX + zoom) % noiseSize * 4 + z];
y3[z] = texArr[baseY * 4 + (baseX + zoom * 2) % noiseSize * 4 + z];
}
const t = x % zoom / zoom;
const result = Noise.dwCubicInterpolate(y0, y1, y2, y3, t);
for (let z = 0; z < 4; z++) {
texArr[y * noiseSize * 4 + x * 4 + z] = result[z];
}
}
}
}
for (let x = 0; x < noiseSize; x++) {
for (let y = 0; y < noiseSize; y++) {
if (y % zoom !== 0) {
const baseY = Math.floor(y / zoom) * zoom + noiseSize;
const y0 = [];
const y1 = [];
const y2 = [];
const y3 = [];
for (let z = 0; z < 4; z++) {
y0[z] = texArr[(baseY - zoom) % noiseSize * noiseSize * 4 + x * 4 + z];
y1[z] = texArr[baseY % noiseSize * noiseSize * 4 + x * 4 + z];
y2[z] = texArr[(baseY + zoom) % noiseSize * noiseSize * 4 + x * 4 + z];
y3[z] = texArr[(baseY + zoom * 2) % noiseSize * noiseSize * 4 + x * 4 + z];
}
const t = y % zoom / zoom;
const result = Noise.dwCubicInterpolate(y0, y1, y2, y3, t);
for (let z = 0; z < 4; z++) {
texArr[y * noiseSize * 4 + x * 4 + z] = result[z];
}
}
}
}
}
return texArr;
}
}
/***/ }),
/***/ "./src/presetBase.js":
/*!***************************!*\
!*** ./src/presetBase.js ***!
\***************************/
/*! no static exports found */
/***/ (function(module, exports) {
/* eslint-disable */
var EPSILON = 0.00001;
window.sqr = function sqr(x) {
return x * x;
};
window.sqrt = function sqrt(x) {
return Math.sqrt(Math.abs(x));
};
window.log10 = function log10(val) {
return Math.log(val) * Math.LOG10E;
};
window.sign = function sign(x) {
return x > 0 ? 1 : x < 0 ? -1 : 0;
};
window.rand = function rand(x) {
var xf = Math.floor(x);
if (xf < 1) {
return Math.random();
}
return Math.random() * xf;
};
window.randint = function randint(x) {
return Math.floor(rand(x));
};
window.bnot = function bnot(x) {
return Math.abs(x) < EPSILON ? 1 : 0;
};
function isFiniteNumber(num) {
return isFinite(num) && !isNaN(num);
}
window.pow = function pow(x, y) {
var z = Math.pow(x, y);
if (!isFiniteNumber(z)) {
// mostly from complex results
return 0;
}
return z;
};
window.div = function div(x, y) {
if (y === 0) {
return 0;
}
return x / y;
};
window.mod = function mod(x, y) {
if (y === 0) {
return 0;
}
var z = Math.floor(x) % Math.floor(y);
return z;
};
window.bitor = function bitor(x, y) {
var z = Math.floor(x) | Math.floor(y);
return z;
};
window.bitand = function bitand(x, y) {
var z = Math.floor(x) & Math.floor(y);
return z;
};
window.sigmoid = function sigmoid(x, y) {
var t = 1 + Math.exp(-x * y);
return Math.abs(t) > EPSILON ? 1.0 / t : 0;
};
window.bor = function bor(x, y) {
return Math.abs(x) > EPSILON || Math.abs(y) > EPSILON ? 1 : 0;
};
window.band = function band(x, y) {
return Math.abs(x) > EPSILON && Math.abs(y) > EPSILON ? 1 : 0;
};
window.equal = function equal(x, y) {
return Math.abs(x - y) < EPSILON ? 1 : 0;
};
window.above = function above(x, y) {
return x > y ? 1 : 0;
};
window.below = function below(x, y) {
return x < y ? 1 : 0;
};
window.ifcond = function ifcond(x, y, z) {
return Math.abs(x) > EPSILON ? y : z;
};
window.memcpy = function memcpy(megabuf, dst, src, len) {
let destOffset = dst;
let srcOffset = src;
let copyLen = len;
if (srcOffset < 0) {
copyLen += srcOffset;
destOffset -= srcOffset;
srcOffset = 0;
}
if (destOffset < 0) {
copyLen += destOffset;
srcOffset -= destOffset;
destOffset = 0;
}
if (copyLen > 0) {
megabuf.copyWithin(destOffset, srcOffset, copyLen);
}
return dst;
};
/* eslint-enable */
/***/ }),
/***/ "./src/rendering/blendPattern.js":
/*!***************************************!*\
!*** ./src/rendering/blendPattern.js ***!
\***************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlendPattern; });
class BlendPattern {
constructor(opts) {
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.vertInfoA = new Float32Array((this.mesh_width + 1) * (this.mesh_height + 1));
this.vertInfoC = new Float32Array((this.mesh_width + 1) * (this.mesh_height + 1));
this.createBlendPattern();
}
static resizeMatrixValues(oldMat, oldWidth, oldHeight, newWidth, newHeight) {
const newMat = new Float32Array((newWidth + 1) * (newHeight + 1));
let nVert = 0;
for (let j = 0; j < newHeight + 1; j++) {
for (let i = 0; i < newWidth + 1; i++) {
let x = i / newHeight;
let y = j / newWidth;
x *= oldWidth + 1;
y *= oldHeight + 1;
x = Math.clamp(x, 0, oldWidth - 1);
y = Math.clamp(y, 0, oldHeight - 1);
const nx = Math.floor(x);
const ny = Math.floor(y);
const dx = x - nx;
const dy = y - ny;
const val00 = oldMat[ny * (oldWidth + 1) + nx];
const val01 = oldMat[ny * (oldWidth + 1) + (nx + 1)];
const val10 = oldMat[(ny + 1) * (oldWidth + 1) + nx];
const val11 = oldMat[(ny + 1) * (oldWidth + 1) + (nx + 1)];
newMat[nVert] = val00 * (1 - dx) * (1 - dy) + val01 * dx * (1 - dy) + val10 * (1 - dx) * dy + val11 * dx * dy;
nVert += 1;
}
}
return newMat;
}
updateGlobals(opts) {
const oldMeshWidth = this.mesh_width;
const oldMeshHeight = this.mesh_height;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
if (this.mesh_width !== oldMeshWidth || this.mesh_height !== oldMeshHeight) {
this.vertInfoA = BlendPattern.resizeMatrixValues(this.vertInfoA, oldMeshWidth, oldMeshHeight, this.mesh_width, this.mesh_height);
this.vertInfoC = BlendPattern.resizeMatrixValues(this.vertInfoC, oldMeshWidth, oldMeshHeight, this.mesh_width, this.mesh_height);
}
}
genPlasma(x0, x1, y0, y1, dt) {
const midx = Math.floor((x0 + x1) / 2);
const midy = Math.floor((y0 + y1) / 2);
let t00 = this.vertInfoC[y0 * (this.mesh_width + 1) + x0];
let t01 = this.vertInfoC[y0 * (this.mesh_width + 1) + x1];
let t10 = this.vertInfoC[y1 * (this.mesh_width + 1) + x0];
let t11 = this.vertInfoC[y1 * (this.mesh_width + 1) + x1];
if (y1 - y0 >= 2) {
if (x0 === 0) {
this.vertInfoC[midy * (this.mesh_width + 1) + x0] = 0.5 * (t00 + t10) + (Math.random() * 2 - 1) * dt * this.aspecty;
}
this.vertInfoC[midy * (this.mesh_width + 1) + x1] = 0.5 * (t01 + t11) + (Math.random() * 2 - 1) * dt * this.aspecty;
}
if (x1 - x0 >= 2) {
if (y0 === 0) {
this.vertInfoC[y0 * (this.mesh_width + 1) + midx] = 0.5 * (t00 + t01) + (Math.random() * 2 - 1) * dt * this.aspectx;
}
this.vertInfoC[y1 * (this.mesh_width + 1) + midx] = 0.5 * (t10 + t11) + (Math.random() * 2 - 1) * dt * this.aspectx;
}
if (y1 - y0 >= 2 && x1 - x0 >= 2) {
t00 = this.vertInfoC[midy * (this.mesh_width + 1) + x0];
t01 = this.vertInfoC[midy * (this.mesh_width + 1) + x1];
t10 = this.vertInfoC[y0 * (this.mesh_width + 1) + midx];
t11 = this.vertInfoC[y1 * (this.mesh_width + 1) + midx];
this.vertInfoC[midy * (this.mesh_width + 1) + midx] = 0.25 * (t10 + t11 + t00 + t01) + (Math.random() * 2 - 1) * dt;
this.genPlasma(x0, midx, y0, midy, dt * 0.5);
this.genPlasma(midx, x1, y0, midy, dt * 0.5);
this.genPlasma(x0, midx, midy, y1, dt * 0.5);
this.genPlasma(midx, x1, midy, y1, dt * 0.5);
}
}
createBlendPattern() {
const mixType = 1 + Math.floor(Math.random() * 3);
if (mixType === 0) {
// not currently used
let nVert = 0;
for (let y = 0; y <= this.mesh_height; y++) {
for (let x = 0; x <= this.mesh_width; x++) {
this.vertInfoA[nVert] = 1;
this.vertInfoC[nVert] = 0;
nVert += 1;
}
}
} else if (mixType === 1) {
const ang = Math.random() * 6.28;
const vx = Math.cos(ang);
const vy = Math.sin(ang);
const band = 0.1 + 0.2 * Math.random();
const invBand = 1.0 / band;
let nVert = 0;
for (let y = 0; y <= this.mesh_height; y++) {
const fy = y / this.mesh_height * this.aspecty;
for (let x = 0; x <= this.mesh_width; x++) {
const fx = x / this.mesh_width * this.aspectx;
let t = (fx - 0.5) * vx + (fy - 0.5) * vy + 0.5;
t = (t - 0.5) / Math.sqrt(2) + 0.5;
this.vertInfoA[nVert] = invBand * (1 + band);
this.vertInfoC[nVert] = -invBand + invBand * t;
nVert += 1;
}
}
} else if (mixType === 2) {
const band = 0.12 + 0.13 * Math.random();
const invBand = 1.0 / band;
this.vertInfoC[0] = Math.random();
this.vertInfoC[this.mesh_width] = Math.random();
this.vertInfoC[this.mesh_height * (this.mesh_width + 1)] = Math.random();
this.vertInfoC[this.mesh_height * (this.mesh_width + 1) + this.mesh_width] = Math.random();
this.genPlasma(0, this.mesh_width, 0, this.mesh_height, 0.25);
let minc = this.vertInfoC[0];
let maxc = this.vertInfoC[0];
let nVert = 0;
for (let y = 0; y <= this.mesh_height; y++) {
for (let x = 0; x <= this.mesh_width; x++) {
if (minc > this.vertInfoC[nVert]) {
minc = this.vertInfoC[nVert];
}
if (maxc < this.vertInfoC[nVert]) {
maxc = this.vertInfoC[nVert];
}
nVert += 1;
}
}
const mult = 1.0 / (maxc - minc);
nVert = 0;
for (let y = 0; y <= this.mesh_height; y++) {
for (let x = 0; x <= this.mesh_width; x++) {
const t = (this.vertInfoC[nVert] - minc) * mult;
this.vertInfoA[nVert] = invBand * (1 + band);
this.vertInfoC[nVert] = -invBand + invBand * t;
nVert += 1;
}
}
} else if (mixType === 3) {
const band = 0.02 + 0.14 * Math.random() + 0.34 * Math.random();
const invBand = 1.0 / band;
const dir = Math.floor(Math.random() * 2) * 2 - 1;
let nVert = 0;
for (let y = 0; y <= this.mesh_height; y++) {
const dy = (y / this.mesh_height - 0.5) * this.aspecty;
for (let x = 0; x <= this.mesh_width; x++) {
const dx = (x / this.mesh_width - 0.5) * this.aspectx;
let t = Math.sqrt(dx * dx + dy * dy) * 1.41421;
if (dir === -1) {
t = 1 - t;
}
this.vertInfoA[nVert] = invBand * (1 + band);
this.vertInfoC[nVert] = -invBand + invBand * t;
nVert += 1;
}
}
}
}
}
/***/ }),
/***/ "./src/rendering/motionVectors/motionVectors.js":
/*!******************************************************!*\
!*** ./src/rendering/motionVectors/motionVectors.js ***!
\******************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return MotionVectors; });
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class MotionVectors {
constructor(gl, opts) {
this.gl = gl;
this.maxX = 64;
this.maxY = 48;
this.positions = new Float32Array(this.maxX * this.maxY * 2 * 3);
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.positionVertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
in vec3 aPos;
void main(void) {
gl_Position = vec4(aPos, 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
out vec4 fragColor;
uniform vec4 u_color;
void main(void) {
fragColor = u_color;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.aPosLoc = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.colorLoc = this.gl.getUniformLocation(this.shaderProgram, "u_color");
}
getMotionDir(warpUVs, fx, fy) {
const y0 = Math.floor(fy * this.mesh_height);
const dy = fy * this.mesh_height - y0;
const x0 = Math.floor(fx * this.mesh_width);
const dx = fx * this.mesh_width - x0;
const x1 = x0 + 1;
const y1 = y0 + 1;
const gridX1 = this.mesh_width + 1;
let fx2;
let fy2;
fx2 = warpUVs[(y0 * gridX1 + x0) * 2 + 0] * (1 - dx) * (1 - dy);
fy2 = warpUVs[(y0 * gridX1 + x0) * 2 + 1] * (1 - dx) * (1 - dy);
fx2 += warpUVs[(y0 * gridX1 + x1) * 2 + 0] * dx * (1 - dy);
fy2 += warpUVs[(y0 * gridX1 + x1) * 2 + 1] * dx * (1 - dy);
fx2 += warpUVs[(y1 * gridX1 + x0) * 2 + 0] * (1 - dx) * dy;
fy2 += warpUVs[(y1 * gridX1 + x0) * 2 + 1] * (1 - dx) * dy;
fx2 += warpUVs[(y1 * gridX1 + x1) * 2 + 0] * dx * dy;
fy2 += warpUVs[(y1 * gridX1 + x1) * 2 + 1] * dx * dy;
return [fx2, 1.0 - fy2];
}
generateMotionVectors(mdVSFrame, warpUVs) {
const mvOn = mdVSFrame.bmotionvectorson;
const mvA = mvOn === 0 ? 0 : mdVSFrame.mv_a;
let nX = Math.floor(mdVSFrame.mv_x);
let nY = Math.floor(mdVSFrame.mv_y);
if (mvA > 0.001 && nX > 0 && nY > 0) {
let dx = mdVSFrame.mv_x - nX;
let dy = mdVSFrame.mv_y - nY;
if (nX > this.maxX) {
nX = this.maxX;
dx = 0;
}
if (nY > this.maxY) {
nY = this.maxY;
dy = 0;
}
const dx2 = mdVSFrame.mv_dx;
const dy2 = mdVSFrame.mv_dy;
const lenMult = mdVSFrame.mv_l;
const minLen = 1.0 / this.texsizeX;
this.numVecVerts = 0;
for (let j = 0; j < nY; j++) {
let fy = (j + 0.25) / (nY + dy + 0.25 - 1.0);
fy -= dy2;
if (fy > 0.0001 && fy < 0.9999) {
for (let i = 0; i < nX; i++) {
let fx = (i + 0.25) / (nX + dx + 0.25 - 1.0);
fx += dx2;
if (fx > 0.0001 && fx < 0.9999) {
const fx2arr = this.getMotionDir(warpUVs, fx, fy);
let fx2 = fx2arr[0];
let fy2 = fx2arr[1];
let dxi = fx2 - fx;
let dyi = fy2 - fy;
dxi *= lenMult;
dyi *= lenMult;
let fdist = Math.sqrt(dxi * dxi + dyi * dyi);
if (fdist < minLen && fdist > 0.00000001) {
fdist = minLen / fdist;
dxi *= fdist;
dyi *= fdist;
} else {
dxi = minLen;
dxi = minLen;
}
fx2 = fx + dxi;
fy2 = fy + dyi;
const vx1 = 2.0 * fx - 1.0;
const vy1 = 2.0 * fy - 1.0;
const vx2 = 2.0 * fx2 - 1.0;
const vy2 = 2.0 * fy2 - 1.0;
this.positions[this.numVecVerts * 3 + 0] = vx1;
this.positions[this.numVecVerts * 3 + 1] = vy1;
this.positions[this.numVecVerts * 3 + 2] = 0;
this.positions[(this.numVecVerts + 1) * 3 + 0] = vx2;
this.positions[(this.numVecVerts + 1) * 3 + 1] = vy2;
this.positions[(this.numVecVerts + 1) * 3 + 2] = 0;
this.numVecVerts += 2;
}
}
}
}
if (this.numVecVerts > 0) {
this.color = [mdVSFrame.mv_r, mdVSFrame.mv_g, mdVSFrame.mv_b, mvA];
return true;
}
}
return false;
}
drawMotionVectors(mdVSFrame, warpUVs) {
if (this.generateMotionVectors(mdVSFrame, warpUVs)) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLoc, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLoc);
this.gl.uniform4fv(this.colorLoc, this.color);
this.gl.lineWidth(1);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.LINES, 0, this.numVecVerts);
}
}
}
/***/ }),
/***/ "./src/rendering/renderer.js":
/*!***********************************!*\
!*** ./src/rendering/renderer.js ***!
\***********************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Renderer; });
/* harmony import */ var _audio_audioLevels__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../audio/audioLevels */ "./src/audio/audioLevels.js");
/* harmony import */ var _blankPreset__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../blankPreset */ "./src/blankPreset.js");
/* harmony import */ var _blankPreset__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_blankPreset__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _equations_presetEquationRunner__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../equations/presetEquationRunner */ "./src/equations/presetEquationRunner.js");
/* harmony import */ var _equations_presetEquationRunnerWASM__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../equations/presetEquationRunnerWASM */ "./src/equations/presetEquationRunnerWASM.js");
/* harmony import */ var _waves_basicWaveform__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./waves/basicWaveform */ "./src/rendering/waves/basicWaveform.js");
/* harmony import */ var _waves_customWaveform__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./waves/customWaveform */ "./src/rendering/waves/customWaveform.js");
/* harmony import */ var _shapes_customShape__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./shapes/customShape */ "./src/rendering/shapes/customShape.js");
/* harmony import */ var _sprites_border__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sprites/border */ "./src/rendering/sprites/border.js");
/* harmony import */ var _sprites_darkenCenter__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sprites/darkenCenter */ "./src/rendering/sprites/darkenCenter.js");
/* harmony import */ var _motionVectors_motionVectors__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./motionVectors/motionVectors */ "./src/rendering/motionVectors/motionVectors.js");
/* harmony import */ var _shaders_warp__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./shaders/warp */ "./src/rendering/shaders/warp.js");
/* harmony import */ var _shaders_comp__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./shaders/comp */ "./src/rendering/shaders/comp.js");
/* harmony import */ var _shaders_output__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./shaders/output */ "./src/rendering/shaders/output.js");
/* harmony import */ var _shaders_resample__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./shaders/resample */ "./src/rendering/shaders/resample.js");
/* harmony import */ var _shaders_blur_blur__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./shaders/blur/blur */ "./src/rendering/shaders/blur/blur.js");
/* harmony import */ var _noise_noise__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../noise/noise */ "./src/noise/noise.js");
/* harmony import */ var _image_imageTextures__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../image/imageTextures */ "./src/image/imageTextures.js");
/* harmony import */ var _text_titleText__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./text/titleText */ "./src/rendering/text/titleText.js");
/* harmony import */ var _blendPattern__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./blendPattern */ "./src/rendering/blendPattern.js");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils */ "./src/utils.js");
class Renderer {
constructor(gl, audio, opts) {
this.gl = gl;
this.audio = audio;
this.frameNum = 0;
this.fps = 30;
this.time = 0;
this.presetTime = 0;
this.lastTime = performance.now();
this.timeHist = [0];
this.timeHistMax = 120;
this.blending = false;
this.blendStartTime = 0;
this.blendProgress = 0;
this.blendDuration = 0;
this.width = opts.width || 1200;
this.height = opts.height || 900;
this.mesh_width = opts.meshWidth || 48;
this.mesh_height = opts.meshHeight || 36;
this.pixelRatio = opts.pixelRatio || window.devicePixelRatio || 1;
this.textureRatio = opts.textureRatio || 1;
this.outputFXAA = opts.outputFXAA || false;
this.texsizeX = this.width * this.pixelRatio * this.textureRatio;
this.texsizeY = this.height * this.pixelRatio * this.textureRatio;
this.aspectx = this.texsizeY > this.texsizeX ? this.texsizeX / this.texsizeY : 1;
this.aspecty = this.texsizeX > this.texsizeY ? this.texsizeY / this.texsizeX : 1;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.qs = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(1, 33).map(x => `q${x}`);
this.ts = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(1, 9).map(x => `t${x}`);
this.regs = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(0, 100).map(x => {
if (x < 10) {
return `reg0${x}`;
}
return `reg${x}`;
});
this.blurRatios = [[0.5, 0.25], [0.125, 0.125], [0.0625, 0.0625]];
this.audioLevels = new _audio_audioLevels__WEBPACK_IMPORTED_MODULE_0__["default"](this.audio);
this.prevFrameBuffer = this.gl.createFramebuffer();
this.targetFrameBuffer = this.gl.createFramebuffer();
this.prevTexture = this.gl.createTexture();
this.targetTexture = this.gl.createTexture();
this.compFrameBuffer = this.gl.createFramebuffer();
this.compTexture = this.gl.createTexture();
this.anisoExt = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic");
this.bindFrameBufferTexture(this.prevFrameBuffer, this.prevTexture);
this.bindFrameBufferTexture(this.targetFrameBuffer, this.targetTexture);
this.bindFrameBufferTexture(this.compFrameBuffer, this.compTexture);
const params = {
pixelRatio: this.pixelRatio,
textureRatio: this.textureRatio,
texsizeX: this.texsizeX,
texsizeY: this.texsizeY,
mesh_width: this.mesh_width,
mesh_height: this.mesh_height,
aspectx: this.aspectx,
aspecty: this.aspecty
};
this.noise = new _noise_noise__WEBPACK_IMPORTED_MODULE_15__["default"](gl);
this.image = new _image_imageTextures__WEBPACK_IMPORTED_MODULE_16__["default"](gl);
this.warpShader = new _shaders_warp__WEBPACK_IMPORTED_MODULE_10__["default"](gl, this.noise, this.image, params);
this.compShader = new _shaders_comp__WEBPACK_IMPORTED_MODULE_11__["default"](gl, this.noise, this.image, params);
this.outputShader = new _shaders_output__WEBPACK_IMPORTED_MODULE_12__["default"](gl, params);
this.prevWarpShader = new _shaders_warp__WEBPACK_IMPORTED_MODULE_10__["default"](gl, this.noise, this.image, params);
this.prevCompShader = new _shaders_comp__WEBPACK_IMPORTED_MODULE_11__["default"](gl, this.noise, this.image, params);
this.numBlurPasses = 0;
this.blurShader1 = new _shaders_blur_blur__WEBPACK_IMPORTED_MODULE_14__["default"](0, this.blurRatios, gl, params);
this.blurShader2 = new _shaders_blur_blur__WEBPACK_IMPORTED_MODULE_14__["default"](1, this.blurRatios, gl, params);
this.blurShader3 = new _shaders_blur_blur__WEBPACK_IMPORTED_MODULE_14__["default"](2, this.blurRatios, gl, params);
this.blurTexture1 = this.blurShader1.blurVerticalTexture;
this.blurTexture2 = this.blurShader2.blurVerticalTexture;
this.blurTexture3 = this.blurShader3.blurVerticalTexture;
this.basicWaveform = new _waves_basicWaveform__WEBPACK_IMPORTED_MODULE_4__["default"](gl, params);
this.customWaveforms = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(4).map(i => new _waves_customWaveform__WEBPACK_IMPORTED_MODULE_5__["default"](i, gl, params));
this.customShapes = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(4).map(i => new _shapes_customShape__WEBPACK_IMPORTED_MODULE_6__["default"](i, gl, params));
this.prevCustomWaveforms = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(4).map(i => new _waves_customWaveform__WEBPACK_IMPORTED_MODULE_5__["default"](i, gl, params));
this.prevCustomShapes = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].range(4).map(i => new _shapes_customShape__WEBPACK_IMPORTED_MODULE_6__["default"](i, gl, params));
this.darkenCenter = new _sprites_darkenCenter__WEBPACK_IMPORTED_MODULE_8__["default"](gl, params);
this.innerBorder = new _sprites_border__WEBPACK_IMPORTED_MODULE_7__["default"](gl, params);
this.outerBorder = new _sprites_border__WEBPACK_IMPORTED_MODULE_7__["default"](gl, params);
this.motionVectors = new _motionVectors_motionVectors__WEBPACK_IMPORTED_MODULE_9__["default"](gl, params);
this.titleText = new _text_titleText__WEBPACK_IMPORTED_MODULE_17__["default"](gl, params);
this.blendPattern = new _blendPattern__WEBPACK_IMPORTED_MODULE_18__["default"](params);
this.resampleShader = new _shaders_resample__WEBPACK_IMPORTED_MODULE_13__["default"](gl);
this.supertext = {
startTime: -1
};
this.warpUVs = new Float32Array((this.mesh_width + 1) * (this.mesh_height + 1) * 2);
this.warpColor = new Float32Array((this.mesh_width + 1) * (this.mesh_height + 1) * 4);
this.gl.clearColor(0, 0, 0, 1);
this.blankPreset = _blankPreset__WEBPACK_IMPORTED_MODULE_1___default.a;
const globalVars = {
frame: 0,
time: 0,
fps: 45,
bass: 1,
bass_att: 1,
mid: 1,
mid_att: 1,
treb: 1,
treb_att: 1
};
this.preset = _blankPreset__WEBPACK_IMPORTED_MODULE_1___default.a;
this.prevPreset = this.preset;
this.presetEquationRunner = new _equations_presetEquationRunner__WEBPACK_IMPORTED_MODULE_2__["default"](this.preset, globalVars, params);
this.prevPresetEquationRunner = new _equations_presetEquationRunner__WEBPACK_IMPORTED_MODULE_2__["default"](this.prevPreset, globalVars, params);
if (!this.preset.useWASM) {
this.regVars = this.presetEquationRunner.mdVSRegs;
}
}
static getHighestBlur(t) {
if (/sampler_blur3/.test(t)) {
return 3;
} else if (/sampler_blur2/.test(t)) {
return 2;
} else if (/sampler_blur1/.test(t)) {
return 1;
}
return 0;
}
loadPreset(preset, blendTime) {
this.blendPattern.createBlendPattern();
this.blending = true;
this.blendStartTime = this.time;
this.blendDuration = blendTime;
this.blendProgress = 0;
this.prevPresetEquationRunner = this.presetEquationRunner;
this.prevPreset = this.preset;
this.preset = preset;
this.presetTime = this.time;
const globalVars = {
frame: this.frameNum,
time: this.time,
fps: this.fps,
bass: this.audioLevels.bass,
bass_att: this.audioLevels.bass_att,
mid: this.audioLevels.mid,
mid_att: this.audioLevels.mid_att,
treb: this.audioLevels.treb,
treb_att: this.audioLevels.treb_att
};
const params = {
pixelRatio: this.pixelRatio,
textureRatio: this.textureRatio,
texsizeX: this.texsizeX,
texsizeY: this.texsizeY,
mesh_width: this.mesh_width,
mesh_height: this.mesh_height,
aspectx: this.aspectx,
aspecty: this.aspecty
};
if (preset.useWASM) {
this.preset.globalPools.perFrame.old_wave_mode.value = this.prevPreset.baseVals.wave_mode;
this.preset.baseVals.old_wave_mode = this.prevPreset.baseVals.wave_mode;
this.presetEquationRunner = new _equations_presetEquationRunnerWASM__WEBPACK_IMPORTED_MODULE_3__["default"](this.preset, globalVars, params);
if (this.preset.pixel_eqs_initialize_array) {
this.preset.pixel_eqs_initialize_array(this.mesh_width, this.mesh_height);
}
} else {
this.preset.baseVals.old_wave_mode = this.prevPreset.baseVals.wave_mode;
this.presetEquationRunner = new _equations_presetEquationRunner__WEBPACK_IMPORTED_MODULE_2__["default"](this.preset, globalVars, params);
this.regVars = this.presetEquationRunner.mdVSRegs;
}
const tmpWarpShader = this.prevWarpShader;
this.prevWarpShader = this.warpShader;
this.warpShader = tmpWarpShader;
const tmpCompShader = this.prevCompShader;
this.prevCompShader = this.compShader;
this.compShader = tmpCompShader;
const warpText = this.preset.warp.trim();
const compText = this.preset.comp.trim();
this.warpShader.updateShader(warpText);
this.compShader.updateShader(compText);
if (warpText.length === 0) {
this.numBlurPasses = 0;
} else {
this.numBlurPasses = Renderer.getHighestBlur(warpText);
}
if (compText.length !== 0) {
this.numBlurPasses = Math.max(this.numBlurPasses, Renderer.getHighestBlur(compText));
}
}
loadExtraImages(imageData) {
this.image.loadExtraImages(imageData);
}
setRendererSize(width, height, opts) {
const oldTexsizeX = this.texsizeX;
const oldTexsizeY = this.texsizeY;
this.width = width;
this.height = height;
this.mesh_width = opts.meshWidth || this.mesh_width;
this.mesh_height = opts.meshHeight || this.mesh_height;
this.pixelRatio = opts.pixelRatio || this.pixelRatio;
this.textureRatio = opts.textureRatio || this.textureRatio;
this.texsizeX = width * this.pixelRatio * this.textureRatio;
this.texsizeY = height * this.pixelRatio * this.textureRatio;
this.aspectx = this.texsizeY > this.texsizeX ? this.texsizeX / this.texsizeY : 1;
this.aspecty = this.texsizeX > this.texsizeY ? this.texsizeY / this.texsizeX : 1;
if (this.texsizeX !== oldTexsizeX || this.texsizeY !== oldTexsizeY) {
// copy target texture, because we flip prev/target at start of render
const targetTextureNew = this.gl.createTexture();
this.bindFrameBufferTexture(this.targetFrameBuffer, targetTextureNew);
this.bindFrambufferAndSetViewport(this.targetFrameBuffer, this.texsizeX, this.texsizeY);
this.resampleShader.renderQuadTexture(this.targetTexture);
this.targetTexture = targetTextureNew;
this.bindFrameBufferTexture(this.prevFrameBuffer, this.prevTexture);
this.bindFrameBufferTexture(this.compFrameBuffer, this.compTexture);
}
this.updateGlobals(); // rerender current frame at new size
if (this.frameNum > 0) {
this.renderToScreen();
}
}
setInternalMeshSize(width, height) {
this.mesh_width = width;
this.mesh_height = height;
this.updateGlobals();
}
setOutputAA(useAA) {
this.outputFXAA = useAA;
}
updateGlobals() {
const params = {
pixelRatio: this.pixelRatio,
textureRatio: this.textureRatio,
texsizeX: this.texsizeX,
texsizeY: this.texsizeY,
mesh_width: this.mesh_width,
mesh_height: this.mesh_height,
aspectx: this.aspectx,
aspecty: this.aspecty
};
this.presetEquationRunner.updateGlobals(params);
this.prevPresetEquationRunner.updateGlobals(params);
this.warpShader.updateGlobals(params);
this.prevWarpShader.updateGlobals(params);
this.compShader.updateGlobals(params);
this.prevCompShader.updateGlobals(params);
this.outputShader.updateGlobals(params);
this.blurShader1.updateGlobals(params);
this.blurShader2.updateGlobals(params);
this.blurShader3.updateGlobals(params);
this.basicWaveform.updateGlobals(params);
this.customWaveforms.forEach(wave => wave.updateGlobals(params));
this.customShapes.forEach(shape => shape.updateGlobals(params));
this.prevCustomWaveforms.forEach(wave => wave.updateGlobals(params));
this.prevCustomShapes.forEach(shape => shape.updateGlobals(params));
this.darkenCenter.updateGlobals(params);
this.innerBorder.updateGlobals(params);
this.outerBorder.updateGlobals(params);
this.motionVectors.updateGlobals(params);
this.titleText.updateGlobals(params);
this.blendPattern.updateGlobals(params);
this.warpUVs = new Float32Array((this.mesh_width + 1) * (this.mesh_height + 1) * 2);
this.warpColor = new Float32Array((this.mesh_width + 1) * (this.mesh_height + 1) * 4);
if (this.preset.pixel_eqs_initialize_array) {
this.preset.pixel_eqs_initialize_array(this.mesh_width, this.mesh_height);
}
}
calcTimeAndFPS(elapsedTime) {
let elapsed;
if (elapsedTime) {
elapsed = elapsedTime;
} else {
const newTime = performance.now();
elapsed = (newTime - this.lastTime) / 1000.0;
if (elapsed > 1.0 || elapsed < 0.0 || this.frame < 2) {
elapsed = 1.0 / 30.0;
}
this.lastTime = newTime;
}
this.time += 1.0 / this.fps;
if (this.blending) {
this.blendProgress = (this.time - this.blendStartTime) / this.blendDuration;
if (this.blendProgress > 1.0) {
this.blending = false;
}
}
const newHistTime = this.timeHist[this.timeHist.length - 1] + elapsed;
this.timeHist.push(newHistTime);
if (this.timeHist.length > this.timeHistMax) {
this.timeHist.shift();
}
const newFPS = this.timeHist.length / (newHistTime - this.timeHist[0]);
if (Math.abs(newFPS - this.fps) > 3.0 && this.frame > this.timeHistMax) {
this.fps = newFPS;
} else {
const damping = 0.93;
this.fps = damping * this.fps + (1.0 - damping) * newFPS;
}
}
runPixelEquations(presetEquationRunner, mdVSFrame, globalVars, blending) {
const gridX = this.mesh_width;
const gridZ = this.mesh_height;
const gridX1 = gridX + 1;
const gridZ1 = gridZ + 1;
const warpTimeV = this.time * mdVSFrame.warpanimspeed;
const warpScaleInv = 1.0 / mdVSFrame.warpscale;
const warpf0 = 11.68 + 4.0 * Math.cos(warpTimeV * 1.413 + 10);
const warpf1 = 8.77 + 3.0 * Math.cos(warpTimeV * 1.113 + 7);
const warpf2 = 10.54 + 3.0 * Math.cos(warpTimeV * 1.233 + 3);
const warpf3 = 11.49 + 4.0 * Math.cos(warpTimeV * 0.933 + 5);
const texelOffsetX = 0.0 / this.texsizeX;
const texelOffsetY = 0.0 / this.texsizeY;
const aspectx = this.aspectx;
const aspecty = this.aspecty;
let offset = 0;
let offsetColor = 0;
if (!presetEquationRunner.preset.useWASM) {
let mdVSVertex = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].cloneVars(mdVSFrame);
let warp = mdVSVertex.warp;
let zoom = mdVSVertex.zoom;
let zoomExp = mdVSVertex.zoomexp;
let cx = mdVSVertex.cx;
let cy = mdVSVertex.cy;
let sx = mdVSVertex.sx;
let sy = mdVSVertex.sy;
let dx = mdVSVertex.dx;
let dy = mdVSVertex.dy;
let rot = mdVSVertex.rot;
for (let iz = 0; iz < gridZ1; iz++) {
for (let ix = 0; ix < gridX1; ix++) {
const x = ix / gridX * 2.0 - 1.0;
const y = iz / gridZ * 2.0 - 1.0;
const rad = Math.sqrt(x * x * aspectx * aspectx + y * y * aspecty * aspecty);
if (presetEquationRunner.runVertEQs) {
let ang;
if (iz === gridZ / 2 && ix === gridX / 2) {
ang = 0;
} else {
ang = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].atan2(y * aspecty, x * aspectx);
}
mdVSVertex.x = x * 0.5 * aspectx + 0.5;
mdVSVertex.y = y * -0.5 * aspecty + 0.5;
mdVSVertex.rad = rad;
mdVSVertex.ang = ang;
mdVSVertex.zoom = mdVSFrame.zoom;
mdVSVertex.zoomexp = mdVSFrame.zoomexp;
mdVSVertex.rot = mdVSFrame.rot;
mdVSVertex.warp = mdVSFrame.warp;
mdVSVertex.cx = mdVSFrame.cx;
mdVSVertex.cy = mdVSFrame.cy;
mdVSVertex.dx = mdVSFrame.dx;
mdVSVertex.dy = mdVSFrame.dy;
mdVSVertex.sx = mdVSFrame.sx;
mdVSVertex.sy = mdVSFrame.sy;
mdVSVertex = presetEquationRunner.runPixelEquations(mdVSVertex);
warp = mdVSVertex.warp;
zoom = mdVSVertex.zoom;
zoomExp = mdVSVertex.zoomexp;
cx = mdVSVertex.cx;
cy = mdVSVertex.cy;
sx = mdVSVertex.sx;
sy = mdVSVertex.sy;
dx = mdVSVertex.dx;
dy = mdVSVertex.dy;
rot = mdVSVertex.rot;
}
const zoom2V = zoom ** zoomExp ** (rad * 2.0 - 1.0);
const zoom2Inv = 1.0 / zoom2V;
let u = x * 0.5 * aspectx * zoom2Inv + 0.5;
let v = -y * 0.5 * aspecty * zoom2Inv + 0.5;
u = (u - cx) / sx + cx;
v = (v - cy) / sy + cy;
if (warp !== 0) {
u += warp * 0.0035 * Math.sin(warpTimeV * 0.333 + warpScaleInv * (x * warpf0 - y * warpf3));
v += warp * 0.0035 * Math.cos(warpTimeV * 0.375 - warpScaleInv * (x * warpf2 + y * warpf1));
u += warp * 0.0035 * Math.cos(warpTimeV * 0.753 - warpScaleInv * (x * warpf1 - y * warpf2));
v += warp * 0.0035 * Math.sin(warpTimeV * 0.825 + warpScaleInv * (x * warpf0 + y * warpf3));
}
const u2 = u - cx;
const v2 = v - cy;
const cosRot = Math.cos(rot);
const sinRot = Math.sin(rot);
u = u2 * cosRot - v2 * sinRot + cx;
v = u2 * sinRot + v2 * cosRot + cy;
u -= dx;
v -= dy;
u = (u - 0.5) / aspectx + 0.5;
v = (v - 0.5) / aspecty + 0.5;
u += texelOffsetX;
v += texelOffsetY;
if (!blending) {
this.warpUVs[offset] = u;
this.warpUVs[offset + 1] = v;
this.warpColor[offsetColor + 0] = 1;
this.warpColor[offsetColor + 1] = 1;
this.warpColor[offsetColor + 2] = 1;
this.warpColor[offsetColor + 3] = 1;
} else {
let mix2 = this.blendPattern.vertInfoA[offset / 2] * this.blendProgress + this.blendPattern.vertInfoC[offset / 2];
mix2 = Math.clamp(mix2, 0, 1);
this.warpUVs[offset] = this.warpUVs[offset] * mix2 + u * (1 - mix2);
this.warpUVs[offset + 1] = this.warpUVs[offset + 1] * mix2 + v * (1 - mix2);
this.warpColor[offsetColor + 0] = 1;
this.warpColor[offsetColor + 1] = 1;
this.warpColor[offsetColor + 2] = 1;
this.warpColor[offsetColor + 3] = mix2;
}
offset += 2;
offsetColor += 4;
}
}
this.mdVSVertex = mdVSVertex;
} else {
const varPool = presetEquationRunner.preset.globalPools.perVertex;
_utils__WEBPACK_IMPORTED_MODULE_19__["default"].setWasm(varPool, globalVars, presetEquationRunner.globalKeys);
_utils__WEBPACK_IMPORTED_MODULE_19__["default"].setWasm(varPool, presetEquationRunner.mdVSQAfterFrame, presetEquationRunner.qs);
varPool.zoom.value = mdVSFrame.zoom;
varPool.zoomexp.value = mdVSFrame.zoomexp;
varPool.rot.value = mdVSFrame.rot;
varPool.warp.value = mdVSFrame.warp;
varPool.cx.value = mdVSFrame.cx;
varPool.cy.value = mdVSFrame.cy;
varPool.dx.value = mdVSFrame.dx;
varPool.dy.value = mdVSFrame.dy;
varPool.sx.value = mdVSFrame.sx;
varPool.sy.value = mdVSFrame.sy;
presetEquationRunner.preset.pixel_eqs_wasm(presetEquationRunner.runVertEQs, this.mesh_width, this.mesh_height, this.time, mdVSFrame.warpanimspeed, mdVSFrame.warpscale, this.aspectx, this.aspecty);
if (!blending) {
this.warpUVs = presetEquationRunner.preset.pixel_eqs_get_array();
this.warpColor.fill(1);
} else {
const newWarpUVs = presetEquationRunner.preset.pixel_eqs_get_array();
let offset = 0;
let offsetColor = 0;
for (let iz = 0; iz < gridZ1; iz++) {
for (let ix = 0; ix < gridX1; ix++) {
const u = newWarpUVs[offset];
const v = newWarpUVs[offset + 1];
let mix2 = this.blendPattern.vertInfoA[offset / 2] * this.blendProgress + this.blendPattern.vertInfoC[offset / 2];
mix2 = Math.clamp(mix2, 0, 1);
this.warpUVs[offset] = this.warpUVs[offset] * mix2 + u * (1 - mix2);
this.warpUVs[offset + 1] = this.warpUVs[offset + 1] * mix2 + v * (1 - mix2);
this.warpColor[offsetColor + 0] = 1;
this.warpColor[offsetColor + 1] = 1;
this.warpColor[offsetColor + 2] = 1;
this.warpColor[offsetColor + 3] = mix2;
offset += 2;
offsetColor += 4;
}
}
}
}
}
static mixFrameEquations(blendProgress, mdVSFrame, mdVSFramePrev) {
const mix = 0.5 - 0.5 * Math.cos(blendProgress * Math.PI);
const mix2 = 1 - mix;
const snapPoint = 0.5;
const mixedFrame = _utils__WEBPACK_IMPORTED_MODULE_19__["default"].cloneVars(mdVSFrame);
mixedFrame.decay = mix * mdVSFrame.decay + mix2 * mdVSFramePrev.decay;
mixedFrame.wave_a = mix * mdVSFrame.wave_a + mix2 * mdVSFramePrev.wave_a;
mixedFrame.wave_r = mix * mdVSFrame.wave_r + mix2 * mdVSFramePrev.wave_r;
mixedFrame.wave_g = mix * mdVSFrame.wave_g + mix2 * mdVSFramePrev.wave_g;
mixedFrame.wave_b = mix * mdVSFrame.wave_b + mix2 * mdVSFramePrev.wave_b;
mixedFrame.wave_x = mix * mdVSFrame.wave_x + mix2 * mdVSFramePrev.wave_x;
mixedFrame.wave_y = mix * mdVSFrame.wave_y + mix2 * mdVSFramePrev.wave_y;
mixedFrame.wave_mystery = mix * mdVSFrame.wave_mystery + mix2 * mdVSFramePrev.wave_mystery;
mixedFrame.ob_size = mix * mdVSFrame.ob_size + mix2 * mdVSFramePrev.ob_size;
mixedFrame.ob_r = mix * mdVSFrame.ob_r + mix2 * mdVSFramePrev.ob_r;
mixedFrame.ob_g = mix * mdVSFrame.ob_g + mix2 * mdVSFramePrev.ob_g;
mixedFrame.ob_b = mix * mdVSFrame.ob_b + mix2 * mdVSFramePrev.ob_b;
mixedFrame.ob_a = mix * mdVSFrame.ob_a + mix2 * mdVSFramePrev.ob_a;
mixedFrame.ib_size = mix * mdVSFrame.ib_size + mix2 * mdVSFramePrev.ib_size;
mixedFrame.ib_r = mix * mdVSFrame.ib_r + mix2 * mdVSFramePrev.ib_r;
mixedFrame.ib_g = mix * mdVSFrame.ib_g + mix2 * mdVSFramePrev.ib_g;
mixedFrame.ib_b = mix * mdVSFrame.ib_b + mix2 * mdVSFramePrev.ib_b;
mixedFrame.ib_a = mix * mdVSFrame.ib_a + mix2 * mdVSFramePrev.ib_a;
mixedFrame.mv_x = mix * mdVSFrame.mv_x + mix2 * mdVSFramePrev.mv_x;
mixedFrame.mv_y = mix * mdVSFrame.mv_y + mix2 * mdVSFramePrev.mv_y;
mixedFrame.mv_dx = mix * mdVSFrame.mv_dx + mix2 * mdVSFramePrev.mv_dx;
mixedFrame.mv_dy = mix * mdVSFrame.mv_dy + mix2 * mdVSFramePrev.mv_dy;
mixedFrame.mv_l = mix * mdVSFrame.mv_l + mix2 * mdVSFramePrev.mv_l;
mixedFrame.mv_r = mix * mdVSFrame.mv_r + mix2 * mdVSFramePrev.mv_r;
mixedFrame.mv_g = mix * mdVSFrame.mv_g + mix2 * mdVSFramePrev.mv_g;
mixedFrame.mv_b = mix * mdVSFrame.mv_b + mix2 * mdVSFramePrev.mv_b;
mixedFrame.mv_a = mix * mdVSFrame.mv_a + mix2 * mdVSFramePrev.mv_a;
mixedFrame.echo_zoom = mix * mdVSFrame.echo_zoom + mix2 * mdVSFramePrev.echo_zoom;
mixedFrame.echo_alpha = mix * mdVSFrame.echo_alpha + mix2 * mdVSFramePrev.echo_alpha;
mixedFrame.echo_orient = mix * mdVSFrame.echo_orient + mix2 * mdVSFramePrev.echo_orient;
mixedFrame.wave_dots = mix < snapPoint ? mdVSFramePrev.wave_dots : mdVSFrame.wave_dots;
mixedFrame.wave_thick = mix < snapPoint ? mdVSFramePrev.wave_thick : mdVSFrame.wave_thick;
mixedFrame.additivewave = mix < snapPoint ? mdVSFramePrev.additivewave : mdVSFrame.additivewave;
mixedFrame.wave_brighten = mix < snapPoint ? mdVSFramePrev.wave_brighten : mdVSFrame.wave_brighten;
mixedFrame.darken_center = mix < snapPoint ? mdVSFramePrev.darken_center : mdVSFrame.darken_center;
mixedFrame.gammaadj = mix < snapPoint ? mdVSFramePrev.gammaadj : mdVSFrame.gammaadj;
mixedFrame.wrap = mix < snapPoint ? mdVSFramePrev.wrap : mdVSFrame.wrap;
mixedFrame.invert = mix < snapPoint ? mdVSFramePrev.invert : mdVSFrame.invert;
mixedFrame.brighten = mix < snapPoint ? mdVSFramePrev.brighten : mdVSFrame.brighten;
mixedFrame.darken = mix < snapPoint ? mdVSFramePrev.darken : mdVSFrame.darken;
mixedFrame.solarize = mix < snapPoint ? mdVSFramePrev.brighten : mdVSFrame.solarize;
mixedFrame.b1n = mix * mdVSFrame.b1n + mix2 * mdVSFramePrev.b1n;
mixedFrame.b2n = mix * mdVSFrame.b2n + mix2 * mdVSFramePrev.b2n;
mixedFrame.b3n = mix * mdVSFrame.b3n + mix2 * mdVSFramePrev.b3n;
mixedFrame.b1x = mix * mdVSFrame.b1x + mix2 * mdVSFramePrev.b1x;
mixedFrame.b2x = mix * mdVSFrame.b2x + mix2 * mdVSFramePrev.b2x;
mixedFrame.b3x = mix * mdVSFrame.b3x + mix2 * mdVSFramePrev.b3x;
mixedFrame.b1ed = mix * mdVSFrame.b1ed + mix2 * mdVSFramePrev.b1ed;
return mixedFrame;
}
static getBlurValues(mdVSFrame) {
let blurMin1 = mdVSFrame.b1n;
let blurMin2 = mdVSFrame.b2n;
let blurMin3 = mdVSFrame.b3n;
let blurMax1 = mdVSFrame.b1x;
let blurMax2 = mdVSFrame.b2x;
let blurMax3 = mdVSFrame.b3x;
const fMinDist = 0.1;
if (blurMax1 - blurMin1 < fMinDist) {
const avg = (blurMin1 + blurMax1) * 0.5;
blurMin1 = avg - fMinDist * 0.5;
blurMax1 = avg - fMinDist * 0.5;
}
blurMax2 = Math.min(blurMax1, blurMax2);
blurMin2 = Math.max(blurMin1, blurMin2);
if (blurMax2 - blurMin2 < fMinDist) {
const avg = (blurMin2 + blurMax2) * 0.5;
blurMin2 = avg - fMinDist * 0.5;
blurMax2 = avg - fMinDist * 0.5;
}
blurMax3 = Math.min(blurMax2, blurMax3);
blurMin3 = Math.max(blurMin2, blurMin3);
if (blurMax3 - blurMin3 < fMinDist) {
const avg = (blurMin3 + blurMax3) * 0.5;
blurMin3 = avg - fMinDist * 0.5;
blurMax3 = avg - fMinDist * 0.5;
}
return {
blurMins: [blurMin1, blurMin2, blurMin3],
blurMaxs: [blurMax1, blurMax2, blurMax3]
};
}
bindFrambufferAndSetViewport(fb, width, height) {
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, fb);
this.gl.viewport(0, 0, width, height);
}
bindFrameBufferTexture(targetFrameBuffer, targetTexture) {
this.gl.bindTexture(this.gl.TEXTURE_2D, targetTexture);
this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.texsizeX, this.texsizeY, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, new Uint8Array(this.texsizeX * this.texsizeY * 4));
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
if (this.anisoExt) {
const max = this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
this.gl.texParameterf(this.gl.TEXTURE_2D, this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, max);
}
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, targetFrameBuffer);
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, targetTexture, 0);
}
render({
audioLevels,
elapsedTime
} = {}) {
this.calcTimeAndFPS(elapsedTime);
this.frameNum += 1;
if (audioLevels) {
this.audio.updateAudio(audioLevels.timeByteArray, audioLevels.timeByteArrayL, audioLevels.timeByteArrayR);
} else {
this.audio.sampleAudio();
}
this.audioLevels.updateAudioLevels(this.fps, this.frameNum);
const globalVars = {
frame: this.frameNum,
time: this.time,
fps: this.fps,
bass: this.audioLevels.bass,
bass_att: this.audioLevels.bass_att,
mid: this.audioLevels.mid,
mid_att: this.audioLevels.mid_att,
treb: this.audioLevels.treb,
treb_att: this.audioLevels.treb_att,
meshx: this.mesh_width,
meshy: this.mesh_height,
aspectx: this.invAspectx,
aspecty: this.invAspecty,
pixelsx: this.texsizeX,
pixelsy: this.texsizeY
};
const prevGlobalVars = Object.assign({}, globalVars);
if (!this.prevPreset.useWASM) {
prevGlobalVars.gmegabuf = this.prevPresetEquationRunner.gmegabuf;
}
if (!this.preset.useWASM) {
globalVars.gmegabuf = this.presetEquationRunner.gmegabuf;
Object.assign(globalVars, this.regVars);
}
const mdVSFrame = this.presetEquationRunner.runFrameEquations(globalVars);
this.runPixelEquations(this.presetEquationRunner, mdVSFrame, globalVars, false);
if (!this.preset.useWASM) {
Object.assign(this.regVars, _utils__WEBPACK_IMPORTED_MODULE_19__["default"].pick(this.mdVSVertex, this.regs));
Object.assign(globalVars, this.regVars);
}
let mdVSFrameMixed;
if (this.blending) {
this.prevMDVSFrame = this.prevPresetEquationRunner.runFrameEquations(prevGlobalVars);
this.runPixelEquations(this.prevPresetEquationRunner, this.prevMDVSFrame, prevGlobalVars, true);
mdVSFrameMixed = Renderer.mixFrameEquations(this.blendProgress, mdVSFrame, this.prevMDVSFrame);
} else {
mdVSFrameMixed = mdVSFrame;
}
const swapTexture = this.targetTexture;
this.targetTexture = this.prevTexture;
this.prevTexture = swapTexture;
const swapFrameBuffer = this.targetFrameBuffer;
this.targetFrameBuffer = this.prevFrameBuffer;
this.prevFrameBuffer = swapFrameBuffer;
this.gl.bindTexture(this.gl.TEXTURE_2D, this.prevTexture);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.bindFrambufferAndSetViewport(this.targetFrameBuffer, this.texsizeX, this.texsizeY);
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
this.gl.enable(this.gl.BLEND);
this.gl.blendEquation(this.gl.FUNC_ADD);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
const {
blurMins,
blurMaxs
} = Renderer.getBlurValues(mdVSFrameMixed);
if (!this.blending) {
this.warpShader.renderQuadTexture(false, this.prevTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, mdVSFrame, this.presetEquationRunner.mdVSQAfterFrame, this.warpUVs, this.warpColor);
} else {
this.prevWarpShader.renderQuadTexture(false, this.prevTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, this.prevMDVSFrame, this.prevPresetEquationRunner.mdVSQAfterFrame, this.warpUVs, this.warpColor);
this.warpShader.renderQuadTexture(true, this.prevTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, mdVSFrameMixed, this.presetEquationRunner.mdVSQAfterFrame, this.warpUVs, this.warpColor);
}
if (this.numBlurPasses > 0) {
this.blurShader1.renderBlurTexture(this.targetTexture, mdVSFrame, blurMins, blurMaxs);
if (this.numBlurPasses > 1) {
this.blurShader2.renderBlurTexture(this.blurTexture1, mdVSFrame, blurMins, blurMaxs);
if (this.numBlurPasses > 2) {
this.blurShader3.renderBlurTexture(this.blurTexture2, mdVSFrame, blurMins, blurMaxs);
}
} // rebind target texture framebuffer
this.bindFrambufferAndSetViewport(this.targetFrameBuffer, this.texsizeX, this.texsizeY);
}
this.motionVectors.drawMotionVectors(mdVSFrameMixed, this.warpUVs);
if (this.preset.shapes && this.preset.shapes.length > 0) {
this.customShapes.forEach((shape, i) => {
shape.drawCustomShape(this.blending ? this.blendProgress : 1, globalVars, this.presetEquationRunner, this.preset.shapes[i], this.prevTexture);
});
}
if (this.preset.waves && this.preset.waves.length > 0) {
this.customWaveforms.forEach((waveform, i) => {
waveform.drawCustomWaveform(this.blending ? this.blendProgress : 1, this.audio.timeArrayL, this.audio.timeArrayR, this.audio.freqArrayL, this.audio.freqArrayR, globalVars, this.presetEquationRunner, this.preset.waves[i]);
});
}
if (this.blending) {
if (this.prevPreset.shapes && this.prevPreset.shapes.length > 0) {
this.prevCustomShapes.forEach((shape, i) => {
shape.drawCustomShape(1.0 - this.blendProgress, prevGlobalVars, this.prevPresetEquationRunner, this.prevPreset.shapes[i], this.prevTexture);
});
}
if (this.prevPreset.waves && this.prevPreset.waves.length > 0) {
this.prevCustomWaveforms.forEach((waveform, i) => {
waveform.drawCustomWaveform(1.0 - this.blendProgress, this.audio.timeArrayL, this.audio.timeArrayR, this.audio.freqArrayL, this.audio.freqArrayR, prevGlobalVars, this.prevPresetEquationRunner, this.prevPreset.waves[i]);
});
}
}
this.basicWaveform.drawBasicWaveform(this.blending, this.blendProgress, this.audio.timeArrayL, this.audio.timeArrayR, mdVSFrameMixed);
this.darkenCenter.drawDarkenCenter(mdVSFrameMixed);
const outerColor = [mdVSFrameMixed.ob_r, mdVSFrameMixed.ob_g, mdVSFrameMixed.ob_b, mdVSFrameMixed.ob_a];
this.outerBorder.drawBorder(outerColor, mdVSFrameMixed.ob_size, 0);
const innerColor = [mdVSFrameMixed.ib_r, mdVSFrameMixed.ib_g, mdVSFrameMixed.ib_b, mdVSFrameMixed.ib_a];
this.innerBorder.drawBorder(innerColor, mdVSFrameMixed.ib_size, mdVSFrameMixed.ob_size);
if (this.supertext.startTime >= 0) {
const progress = (this.time - this.supertext.startTime) / this.supertext.duration;
if (progress >= 1) {
this.titleText.renderTitle(progress, true, globalVars);
}
} // Store variables in case we need to rerender
this.globalVars = globalVars;
this.mdVSFrame = mdVSFrame;
this.mdVSFrameMixed = mdVSFrameMixed;
this.renderToScreen();
}
renderToScreen() {
if (this.outputFXAA) {
this.bindFrambufferAndSetViewport(this.compFrameBuffer, this.texsizeX, this.texsizeY);
} else {
this.bindFrambufferAndSetViewport(null, this.width, this.height);
}
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
this.gl.enable(this.gl.BLEND);
this.gl.blendEquation(this.gl.FUNC_ADD);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
const {
blurMins,
blurMaxs
} = Renderer.getBlurValues(this.mdVSFrameMixed);
if (!this.blending) {
this.compShader.renderQuadTexture(false, this.targetTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, this.mdVSFrame, this.presetEquationRunner.mdVSQAfterFrame, this.warpColor);
} else {
this.prevCompShader.renderQuadTexture(false, this.targetTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, this.prevMDVSFrame, this.prevPresetEquationRunner.mdVSQAfterFrame, this.warpColor);
this.compShader.renderQuadTexture(true, this.targetTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, this.mdVSFrameMixed, this.presetEquationRunner.mdVSQAfterFrame, this.warpColor);
}
if (this.supertext.startTime >= 0) {
const progress = (this.time - this.supertext.startTime) / this.supertext.duration;
this.titleText.renderTitle(progress, false, this.globalVars);
if (progress >= 1) {
this.supertext.startTime = -1;
}
}
if (this.outputFXAA) {
this.gl.bindTexture(this.gl.TEXTURE_2D, this.compTexture);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.bindFrambufferAndSetViewport(null, this.width, this.height);
this.outputShader.renderQuadTexture(this.compTexture);
}
}
launchSongTitleAnim(text) {
this.supertext = {
startTime: this.time,
duration: 1.7
};
this.titleText.generateTitleTexture(text);
}
toDataURL() {
const data = new Uint8Array(this.texsizeX * this.texsizeY * 4);
const compFrameBuffer = this.gl.createFramebuffer();
const compTexture = this.gl.createTexture();
this.bindFrameBufferTexture(compFrameBuffer, compTexture);
const {
blurMins,
blurMaxs
} = Renderer.getBlurValues(this.mdVSFrameMixed);
this.compShader.renderQuadTexture(false, this.targetTexture, this.blurTexture1, this.blurTexture2, this.blurTexture3, blurMins, blurMaxs, this.mdVSFrame, this.presetEquationRunner.mdVSQAfterFrame, this.warpColor);
this.gl.readPixels(0, 0, this.texsizeX, this.texsizeY, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data); // flip data
Array.from({
length: this.texsizeY
}, (val, i) => data.slice(i * this.texsizeX * 4, (i + 1) * this.texsizeX * 4)).forEach((val, i) => data.set(val, (this.texsizeY - i - 1) * this.texsizeX * 4));
const canvas = document.createElement("canvas");
canvas.width = this.texsizeX;
canvas.height = this.texsizeY;
const context = canvas.getContext("2d");
const imageData = context.createImageData(this.texsizeX, this.texsizeY);
imageData.data.set(data);
context.putImageData(imageData, 0, 0);
this.gl.deleteTexture(compTexture);
this.gl.deleteFramebuffer(compFrameBuffer);
return canvas.toDataURL();
}
warpBufferToDataURL() {
const data = new Uint8Array(this.texsizeX * this.texsizeY * 4);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.targetFrameBuffer);
this.gl.readPixels(0, 0, this.texsizeX, this.texsizeY, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data);
const canvas = document.createElement("canvas");
canvas.width = this.texsizeX;
canvas.height = this.texsizeY;
const context = canvas.getContext("2d");
const imageData = context.createImageData(this.texsizeX, this.texsizeY);
imageData.data.set(data);
context.putImageData(imageData, 0, 0);
return canvas.toDataURL();
}
}
/***/ }),
/***/ "./src/rendering/shaders/blur/blur.js":
/*!********************************************!*\
!*** ./src/rendering/shaders/blur/blur.js ***!
\********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlurShader; });
/* harmony import */ var _blurVertical__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./blurVertical */ "./src/rendering/shaders/blur/blurVertical.js");
/* harmony import */ var _blurHorizontal__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blurHorizontal */ "./src/rendering/shaders/blur/blurHorizontal.js");
class BlurShader {
constructor(blurLevel, blurRatios, gl, opts = {}) {
this.blurLevel = blurLevel;
this.blurRatios = blurRatios;
this.gl = gl;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.anisoExt = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic");
this.blurHorizontalFrameBuffer = this.gl.createFramebuffer();
this.blurVerticalFrameBuffer = this.gl.createFramebuffer();
this.blurHorizontalTexture = this.gl.createTexture();
this.blurVerticalTexture = this.gl.createTexture();
this.setupFrameBufferTextures();
this.blurHorizontal = new _blurHorizontal__WEBPACK_IMPORTED_MODULE_1__["default"](gl, this.blurLevel, opts);
this.blurVertical = new _blurVertical__WEBPACK_IMPORTED_MODULE_0__["default"](gl, this.blurLevel, opts);
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.setupFrameBufferTextures();
}
getTextureSize(sizeRatio) {
let sizeX = Math.max(this.texsizeX * sizeRatio, 16);
sizeX = Math.floor((sizeX + 3) / 16) * 16;
let sizeY = Math.max(this.texsizeY * sizeRatio, 16);
sizeY = Math.floor((sizeY + 3) / 4) * 4;
return [sizeX, sizeY];
}
setupFrameBufferTextures() {
const srcBlurRatios = this.blurLevel > 0 ? this.blurRatios[this.blurLevel - 1] : [1, 1];
const dstBlurRatios = this.blurRatios[this.blurLevel];
const srcTexsizeHorizontal = this.getTextureSize(srcBlurRatios[1]);
const dstTexsizeHorizontal = this.getTextureSize(dstBlurRatios[0]);
this.bindFrameBufferTexture(this.blurHorizontalFrameBuffer, this.blurHorizontalTexture, dstTexsizeHorizontal);
const srcTexsizeVertical = dstTexsizeHorizontal;
const dstTexsizeVertical = this.getTextureSize(dstBlurRatios[1]);
this.bindFrameBufferTexture(this.blurVerticalFrameBuffer, this.blurVerticalTexture, dstTexsizeVertical);
this.horizontalTexsizes = [srcTexsizeHorizontal, dstTexsizeHorizontal];
this.verticalTexsizes = [srcTexsizeVertical, dstTexsizeVertical];
}
bindFrambufferAndSetViewport(fb, texsize) {
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, fb);
this.gl.viewport(0, 0, texsize[0], texsize[1]);
}
bindFrameBufferTexture(targetFrameBuffer, targetTexture, texsize) {
this.gl.bindTexture(this.gl.TEXTURE_2D, targetTexture);
this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT, 1);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, texsize[0], texsize[1], 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, new Uint8Array(texsize[0] * texsize[1] * 4));
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
if (this.anisoExt) {
const max = this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
this.gl.texParameterf(this.gl.TEXTURE_2D, this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, max);
}
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, targetFrameBuffer);
this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, targetTexture, 0);
}
renderBlurTexture(prevTexture, mdVSFrame, blurMins, blurMaxs) {
this.bindFrambufferAndSetViewport(this.blurHorizontalFrameBuffer, this.horizontalTexsizes[1]);
this.blurHorizontal.renderQuadTexture(prevTexture, mdVSFrame, blurMins, blurMaxs, this.horizontalTexsizes[0]);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.blurHorizontalTexture);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.bindFrambufferAndSetViewport(this.blurVerticalFrameBuffer, this.verticalTexsizes[1]);
this.blurVertical.renderQuadTexture(this.blurHorizontalTexture, mdVSFrame, this.verticalTexsizes[0]);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.blurVerticalTexture);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
}
}
/***/ }),
/***/ "./src/rendering/shaders/blur/blurHorizontal.js":
/*!******************************************************!*\
!*** ./src/rendering/shaders/blur/blurHorizontal.js ***!
\******************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlurHorizontal; });
/* harmony import */ var _shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class BlurHorizontal {
constructor(gl, blurLevel) {
this.gl = gl;
this.blurLevel = blurLevel;
const w = [4.0, 3.8, 3.5, 2.9, 1.9, 1.2, 0.7, 0.3];
const w1H = w[0] + w[1];
const w2H = w[2] + w[3];
const w3H = w[4] + w[5];
const w4H = w[6] + w[7];
const d1H = 0 + 2 * w[1] / w1H;
const d2H = 2 + 2 * w[3] / w2H;
const d3H = 4 + 2 * w[5] / w3H;
const d4H = 6 + 2 * w[7] / w4H;
this.ws = new Float32Array([w1H, w2H, w3H, w4H]);
this.ds = new Float32Array([d1H, d2H, d3H, d4H]);
this.wDiv = 0.5 / (w1H + w2H + w3H + w4H);
this.positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
this.vertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
out vec2 uv;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
uv = aPos * halfmad + halfmad;
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec2 uv;
out vec4 fragColor;
uniform sampler2D uTexture;
uniform vec4 texsize;
uniform float scale;
uniform float bias;
uniform vec4 ws;
uniform vec4 ds;
uniform float wdiv;
void main(void) {
float w1 = ws[0];
float w2 = ws[1];
float w3 = ws[2];
float w4 = ws[3];
float d1 = ds[0];
float d2 = ds[1];
float d3 = ds[2];
float d4 = ds[3];
vec2 uv2 = uv.xy;
vec3 blur =
( texture(uTexture, uv2 + vec2( d1 * texsize.z,0.0) ).xyz
+ texture(uTexture, uv2 + vec2(-d1 * texsize.z,0.0) ).xyz) * w1 +
( texture(uTexture, uv2 + vec2( d2 * texsize.z,0.0) ).xyz
+ texture(uTexture, uv2 + vec2(-d2 * texsize.z,0.0) ).xyz) * w2 +
( texture(uTexture, uv2 + vec2( d3 * texsize.z,0.0) ).xyz
+ texture(uTexture, uv2 + vec2(-d3 * texsize.z,0.0) ).xyz) * w3 +
( texture(uTexture, uv2 + vec2( d4 * texsize.z,0.0) ).xyz
+ texture(uTexture, uv2 + vec2(-d4 * texsize.z,0.0) ).xyz) * w4;
blur.xyz *= wdiv;
blur.xyz = blur.xyz * scale + bias;
fragColor = vec4(blur, 1.0);
}`);
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
this.texsizeLocation = this.gl.getUniformLocation(this.shaderProgram, "texsize");
this.scaleLoc = this.gl.getUniformLocation(this.shaderProgram, "scale");
this.biasLoc = this.gl.getUniformLocation(this.shaderProgram, "bias");
this.wsLoc = this.gl.getUniformLocation(this.shaderProgram, "ws");
this.dsLocation = this.gl.getUniformLocation(this.shaderProgram, "ds");
this.wdivLoc = this.gl.getUniformLocation(this.shaderProgram, "wdiv");
}
getScaleAndBias(blurMins, blurMaxs) {
const scale = [1, 1, 1];
const bias = [0, 0, 0];
let tempMin;
let tempMax;
scale[0] = 1.0 / (blurMaxs[0] - blurMins[0]);
bias[0] = -blurMins[0] * scale[0];
tempMin = (blurMins[1] - blurMins[0]) / (blurMaxs[0] - blurMins[0]);
tempMax = (blurMaxs[1] - blurMins[0]) / (blurMaxs[0] - blurMins[0]);
scale[1] = 1.0 / (tempMax - tempMin);
bias[1] = -tempMin * scale[1];
tempMin = (blurMins[2] - blurMins[1]) / (blurMaxs[1] - blurMins[1]);
tempMax = (blurMaxs[2] - blurMins[1]) / (blurMaxs[1] - blurMins[1]);
scale[2] = 1.0 / (tempMax - tempMin);
bias[2] = -tempMin * scale[2];
return {
scale: scale[this.blurLevel],
bias: bias[this.blurLevel]
};
}
renderQuadTexture(texture, mdVSFrame, blurMins, blurMaxs, srcTexsize) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.uniform1i(this.textureLoc, 0);
const {
scale,
bias
} = this.getScaleAndBias(blurMins, blurMaxs);
this.gl.uniform4fv(this.texsizeLocation, [srcTexsize[0], srcTexsize[1], 1.0 / srcTexsize[0], 1.0 / srcTexsize[1]]);
this.gl.uniform1f(this.scaleLoc, scale);
this.gl.uniform1f(this.biasLoc, bias);
this.gl.uniform4fv(this.wsLoc, this.ws);
this.gl.uniform4fv(this.dsLocation, this.ds);
this.gl.uniform1f(this.wdivLoc, this.wDiv);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
}
}
/***/ }),
/***/ "./src/rendering/shaders/blur/blurVertical.js":
/*!****************************************************!*\
!*** ./src/rendering/shaders/blur/blurVertical.js ***!
\****************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BlurVertical; });
/* harmony import */ var _shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class BlurVertical {
constructor(gl, blurLevel) {
this.gl = gl;
this.blurLevel = blurLevel;
const w = [4.0, 3.8, 3.5, 2.9, 1.9, 1.2, 0.7, 0.3];
const w1V = w[0] + w[1] + w[2] + w[3];
const w2V = w[4] + w[5] + w[6] + w[7];
const d1V = 0 + 2 * ((w[2] + w[3]) / w1V);
const d2V = 2 + 2 * ((w[6] + w[7]) / w2V);
this.wds = new Float32Array([w1V, w2V, d1V, d2V]);
this.wDiv = 1.0 / ((w1V + w2V) * 2);
this.positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
this.vertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
out vec2 uv;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
uv = aPos * halfmad + halfmad;
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec2 uv;
out vec4 fragColor;
uniform sampler2D uTexture;
uniform vec4 texsize;
uniform float ed1;
uniform float ed2;
uniform float ed3;
uniform vec4 wds;
uniform float wdiv;
void main(void) {
float w1 = wds[0];
float w2 = wds[1];
float d1 = wds[2];
float d2 = wds[3];
vec2 uv2 = uv.xy;
vec3 blur =
( texture(uTexture, uv2 + vec2(0.0, d1 * texsize.w) ).xyz
+ texture(uTexture, uv2 + vec2(0.0,-d1 * texsize.w) ).xyz) * w1 +
( texture(uTexture, uv2 + vec2(0.0, d2 * texsize.w) ).xyz
+ texture(uTexture, uv2 + vec2(0.0,-d2 * texsize.w) ).xyz) * w2;
blur.xyz *= wdiv;
float t = min(min(uv.x, uv.y), 1.0 - max(uv.x, uv.y));
t = sqrt(t);
t = ed1 + ed2 * clamp(t * ed3, 0.0, 1.0);
blur.xyz *= t;
fragColor = vec4(blur, 1.0);
}`);
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
this.texsizeLocation = this.gl.getUniformLocation(this.shaderProgram, "texsize");
this.ed1Loc = this.gl.getUniformLocation(this.shaderProgram, "ed1");
this.ed2Loc = this.gl.getUniformLocation(this.shaderProgram, "ed2");
this.ed3Loc = this.gl.getUniformLocation(this.shaderProgram, "ed3");
this.wdsLocation = this.gl.getUniformLocation(this.shaderProgram, "wds");
this.wdivLoc = this.gl.getUniformLocation(this.shaderProgram, "wdiv");
}
renderQuadTexture(texture, mdVSFrame, srcTexsize) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.uniform1i(this.textureLoc, 0);
const b1ed = this.blurLevel === 0 ? mdVSFrame.b1ed : 0.0;
this.gl.uniform4fv(this.texsizeLocation, [srcTexsize[0], srcTexsize[1], 1.0 / srcTexsize[0], 1.0 / srcTexsize[1]]);
this.gl.uniform1f(this.ed1Loc, 1.0 - b1ed);
this.gl.uniform1f(this.ed2Loc, b1ed);
this.gl.uniform1f(this.ed3Loc, 5.0);
this.gl.uniform4fv(this.wdsLocation, this.wds);
this.gl.uniform1f(this.wdivLoc, this.wDiv);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
}
}
/***/ }),
/***/ "./src/rendering/shaders/comp.js":
/*!***************************************!*\
!*** ./src/rendering/shaders/comp.js ***!
\***************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CompShader; });
/* harmony import */ var _shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class CompShader {
constructor(gl, noise, image, opts = {}) {
this.gl = gl;
this.noise = noise;
this.image = image;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.compWidth = 32;
this.compHeight = 24;
this.buildPositions();
this.indexBuf = gl.createBuffer();
this.positionVertexBuf = this.gl.createBuffer();
this.compColorVertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
this.mainSampler = this.gl.createSampler();
this.mainSamplerFW = this.gl.createSampler();
this.mainSamplerFC = this.gl.createSampler();
this.mainSamplerPW = this.gl.createSampler();
this.mainSamplerPC = this.gl.createSampler();
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
} // based on https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js
buildPositions() {
const width = 2;
const height = 2;
const widthHalf = width / 2;
const heightHalf = height / 2;
const gridX = this.compWidth;
const gridY = this.compHeight;
const gridX1 = gridX + 1;
const gridY1 = gridY + 1;
const segmentWidth = width / gridX;
const segmentHeight = height / gridY;
const vertices = [];
for (let iy = 0; iy < gridY1; iy++) {
const y = iy * segmentHeight - heightHalf;
for (let ix = 0; ix < gridX1; ix++) {
const x = ix * segmentWidth - widthHalf;
vertices.push(x, -y, 0);
}
}
const indices = [];
for (let iy = 0; iy < gridY; iy++) {
for (let ix = 0; ix < gridX; ix++) {
const a = ix + gridX1 * iy;
const b = ix + gridX1 * (iy + 1);
const c = ix + 1 + gridX1 * (iy + 1);
const d = ix + 1 + gridX1 * iy;
indices.push(a, b, d);
indices.push(b, c, d);
}
}
this.vertices = new Float32Array(vertices);
this.indices = new Uint16Array(indices);
}
updateGlobals(opts) {
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.buildPositions();
}
createShader(shaderText = "") {
let fragShaderText;
let fragShaderHeaderText;
if (shaderText.length === 0) {
fragShaderText = `float orient_horiz = mod(echo_orientation, 2.0);
float orient_x = (orient_horiz != 0.0) ? -1.0 : 1.0;
float orient_y = (echo_orientation >= 2.0) ? -1.0 : 1.0;
vec2 uv_echo = ((uv - 0.5) *
(1.0 / echo_zoom) *
vec2(orient_x, orient_y)) + 0.5;
ret = mix(texture(sampler_main, uv).rgb,
texture(sampler_main, uv_echo).rgb,
echo_alpha);
ret *= gammaAdj;
if(fShader >= 1.0) {
ret *= hue_shader;
} else if(fShader > 0.001) {
ret *= (1.0 - fShader) + (fShader * hue_shader);
}
if(brighten != 0) ret = sqrt(ret);
if(darken != 0) ret = ret*ret;
if(solarize != 0) ret = ret * (1.0 - ret) * 4.0;
if(invert != 0) ret = 1.0 - ret;`;
fragShaderHeaderText = "";
} else {
const shaderParts = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getShaderParts(shaderText);
fragShaderHeaderText = shaderParts[0];
fragShaderText = shaderParts[1];
}
fragShaderText = fragShaderText.replace(/texture2D/g, "texture");
fragShaderText = fragShaderText.replace(/texture3D/g, "texture");
this.userTextures = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getUserSamplers(fragShaderHeaderText);
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
in vec4 aCompColor;
out vec2 vUv;
out vec4 vColor;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
vUv = aPos * halfmad + halfmad;
vColor = aCompColor;
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
precision mediump sampler3D;
vec3 lum(vec3 v){
return vec3(dot(v, vec3(0.32,0.49,0.29)));
}
in vec2 vUv;
in vec4 vColor;
out vec4 fragColor;
uniform sampler2D sampler_main;
uniform sampler2D sampler_fw_main;
uniform sampler2D sampler_fc_main;
uniform sampler2D sampler_pw_main;
uniform sampler2D sampler_pc_main;
uniform sampler2D sampler_blur1;
uniform sampler2D sampler_blur2;
uniform sampler2D sampler_blur3;
uniform sampler2D sampler_noise_lq;
uniform sampler2D sampler_noise_lq_lite;
uniform sampler2D sampler_noise_mq;
uniform sampler2D sampler_noise_hq;
uniform sampler2D sampler_pw_noise_lq;
uniform sampler3D sampler_noisevol_lq;
uniform sampler3D sampler_noisevol_hq;
uniform float time;
uniform float gammaAdj;
uniform float echo_zoom;
uniform float echo_alpha;
uniform float echo_orientation;
uniform int invert;
uniform int brighten;
uniform int darken;
uniform int solarize;
uniform vec2 resolution;
uniform vec4 aspect;
uniform vec4 texsize;
uniform vec4 texsize_noise_lq;
uniform vec4 texsize_noise_mq;
uniform vec4 texsize_noise_hq;
uniform vec4 texsize_noise_lq_lite;
uniform vec4 texsize_noisevol_lq;
uniform vec4 texsize_noisevol_hq;
uniform float bass;
uniform float mid;
uniform float treb;
uniform float vol;
uniform float bass_att;
uniform float mid_att;
uniform float treb_att;
uniform float vol_att;
uniform float frame;
uniform float fps;
uniform vec4 _qa;
uniform vec4 _qb;
uniform vec4 _qc;
uniform vec4 _qd;
uniform vec4 _qe;
uniform vec4 _qf;
uniform vec4 _qg;
uniform vec4 _qh;
#define q1 _qa.x
#define q2 _qa.y
#define q3 _qa.z
#define q4 _qa.w
#define q5 _qb.x
#define q6 _qb.y
#define q7 _qb.z
#define q8 _qb.w
#define q9 _qc.x
#define q10 _qc.y
#define q11 _qc.z
#define q12 _qc.w
#define q13 _qd.x
#define q14 _qd.y
#define q15 _qd.z
#define q16 _qd.w
#define q17 _qe.x
#define q18 _qe.y
#define q19 _qe.z
#define q20 _qe.w
#define q21 _qf.x
#define q22 _qf.y
#define q23 _qf.z
#define q24 _qf.w
#define q25 _qg.x
#define q26 _qg.y
#define q27 _qg.z
#define q28 _qg.w
#define q29 _qh.x
#define q30 _qh.y
#define q31 _qh.z
#define q32 _qh.w
uniform vec4 slow_roam_cos;
uniform vec4 roam_cos;
uniform vec4 slow_roam_sin;
uniform vec4 roam_sin;
uniform float blur1_min;
uniform float blur1_max;
uniform float blur2_min;
uniform float blur2_max;
uniform float blur3_min;
uniform float blur3_max;
uniform float scale1;
uniform float scale2;
uniform float scale3;
uniform float bias1;
uniform float bias2;
uniform float bias3;
uniform vec4 rand_frame;
uniform vec4 rand_preset;
uniform float fShader;
float PI = ${Math.PI};
${fragShaderHeaderText}
void main(void) {
vec3 ret;
vec2 uv = vUv;
vec2 uv_orig = vUv;
uv.y = 1.0 - uv.y;
uv_orig.y = 1.0 - uv_orig.y;
float rad = length(uv - 0.5);
float ang = atan(uv.x - 0.5, uv.y - 0.5);
vec3 hue_shader = vColor.rgb;
${fragShaderText}
fragColor = vec4(ret, vColor.a);
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.compColorLocation = this.gl.getAttribLocation(this.shaderProgram, "aCompColor");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_main");
this.textureFWLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_fw_main");
this.textureFCLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_fc_main");
this.texturePWLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_pw_main");
this.texturePCLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_pc_main");
this.blurTexture1Loc = this.gl.getUniformLocation(this.shaderProgram, "sampler_blur1");
this.blurTexture2Loc = this.gl.getUniformLocation(this.shaderProgram, "sampler_blur2");
this.blurTexture3Loc = this.gl.getUniformLocation(this.shaderProgram, "sampler_blur3");
this.noiseLQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_lq");
this.noiseMQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_mq");
this.noiseHQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_hq");
this.noiseLQLiteLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_lq_lite");
this.noisePointLQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_pw_noise_lq");
this.noiseVolLQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noisevol_lq");
this.noiseVolHQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noisevol_hq");
this.timeLoc = this.gl.getUniformLocation(this.shaderProgram, "time");
this.gammaAdjLoc = this.gl.getUniformLocation(this.shaderProgram, "gammaAdj");
this.echoZoomLoc = this.gl.getUniformLocation(this.shaderProgram, "echo_zoom");
this.echoAlphaLoc = this.gl.getUniformLocation(this.shaderProgram, "echo_alpha");
this.echoOrientationLoc = this.gl.getUniformLocation(this.shaderProgram, "echo_orientation");
this.invertLoc = this.gl.getUniformLocation(this.shaderProgram, "invert");
this.brightenLoc = this.gl.getUniformLocation(this.shaderProgram, "brighten");
this.darkenLoc = this.gl.getUniformLocation(this.shaderProgram, "darken");
this.solarizeLoc = this.gl.getUniformLocation(this.shaderProgram, "solarize");
this.texsizeLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize");
this.texsizeNoiseLQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_lq");
this.texsizeNoiseMQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_mq");
this.texsizeNoiseHQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_hq");
this.texsizeNoiseLQLiteLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_lq_lite");
this.texsizeNoiseVolLQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noisevol_lq");
this.texsizeNoiseVolHQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noisevol_hq");
this.resolutionLoc = this.gl.getUniformLocation(this.shaderProgram, "resolution");
this.aspectLoc = this.gl.getUniformLocation(this.shaderProgram, "aspect");
this.bassLoc = this.gl.getUniformLocation(this.shaderProgram, "bass");
this.midLoc = this.gl.getUniformLocation(this.shaderProgram, "mid");
this.trebLoc = this.gl.getUniformLocation(this.shaderProgram, "treb");
this.volLoc = this.gl.getUniformLocation(this.shaderProgram, "vol");
this.bassAttLoc = this.gl.getUniformLocation(this.shaderProgram, "bass_att");
this.midAttLoc = this.gl.getUniformLocation(this.shaderProgram, "mid_att");
this.trebAttLoc = this.gl.getUniformLocation(this.shaderProgram, "treb_att");
this.volAttLoc = this.gl.getUniformLocation(this.shaderProgram, "vol_att");
this.frameLoc = this.gl.getUniformLocation(this.shaderProgram, "frame");
this.fpsLoc = this.gl.getUniformLocation(this.shaderProgram, "fps");
this.blur1MinLoc = this.gl.getUniformLocation(this.shaderProgram, "blur1_min");
this.blur1MaxLoc = this.gl.getUniformLocation(this.shaderProgram, "blur1_max");
this.blur2MinLoc = this.gl.getUniformLocation(this.shaderProgram, "blur2_min");
this.blur2MaxLoc = this.gl.getUniformLocation(this.shaderProgram, "blur2_max");
this.blur3MinLoc = this.gl.getUniformLocation(this.shaderProgram, "blur3_min");
this.blur3MaxLoc = this.gl.getUniformLocation(this.shaderProgram, "blur3_max");
this.scale1Loc = this.gl.getUniformLocation(this.shaderProgram, "scale1");
this.scale2Loc = this.gl.getUniformLocation(this.shaderProgram, "scale2");
this.scale3Loc = this.gl.getUniformLocation(this.shaderProgram, "scale3");
this.bias1Loc = this.gl.getUniformLocation(this.shaderProgram, "bias1");
this.bias2Loc = this.gl.getUniformLocation(this.shaderProgram, "bias2");
this.bias3Loc = this.gl.getUniformLocation(this.shaderProgram, "bias3");
this.randPresetLoc = this.gl.getUniformLocation(this.shaderProgram, "rand_preset");
this.randFrameLoc = this.gl.getUniformLocation(this.shaderProgram, "rand_frame");
this.fShaderLoc = this.gl.getUniformLocation(this.shaderProgram, "fShader");
this.qaLoc = this.gl.getUniformLocation(this.shaderProgram, "_qa");
this.qbLoc = this.gl.getUniformLocation(this.shaderProgram, "_qb");
this.qcLoc = this.gl.getUniformLocation(this.shaderProgram, "_qc");
this.qdLoc = this.gl.getUniformLocation(this.shaderProgram, "_qd");
this.qeLoc = this.gl.getUniformLocation(this.shaderProgram, "_qe");
this.qfLoc = this.gl.getUniformLocation(this.shaderProgram, "_qf");
this.qgLoc = this.gl.getUniformLocation(this.shaderProgram, "_qg");
this.qhLoc = this.gl.getUniformLocation(this.shaderProgram, "_qh");
this.slowRoamCosLoc = this.gl.getUniformLocation(this.shaderProgram, "slow_roam_cos");
this.roamCosLoc = this.gl.getUniformLocation(this.shaderProgram, "roam_cos");
this.slowRoamSinLoc = this.gl.getUniformLocation(this.shaderProgram, "slow_roam_sin");
this.roamSinLoc = this.gl.getUniformLocation(this.shaderProgram, "roam_sin");
for (let i = 0; i < this.userTextures.length; i++) {
const userTexture = this.userTextures[i];
userTexture.textureLoc = this.gl.getUniformLocation(this.shaderProgram, `sampler_${userTexture.sampler}`);
}
}
updateShader(shaderText) {
this.createShader(shaderText);
}
bindBlurVals(blurMins, blurMaxs) {
const blurMin1 = blurMins[0];
const blurMin2 = blurMins[1];
const blurMin3 = blurMins[2];
const blurMax1 = blurMaxs[0];
const blurMax2 = blurMaxs[1];
const blurMax3 = blurMaxs[2];
const scale1 = blurMax1 - blurMin1;
const bias1 = blurMin1;
const scale2 = blurMax2 - blurMin2;
const bias2 = blurMin2;
const scale3 = blurMax3 - blurMin3;
const bias3 = blurMin3;
this.gl.uniform1f(this.blur1MinLoc, blurMin1);
this.gl.uniform1f(this.blur1MaxLoc, blurMax1);
this.gl.uniform1f(this.blur2MinLoc, blurMin2);
this.gl.uniform1f(this.blur2MaxLoc, blurMax2);
this.gl.uniform1f(this.blur3MinLoc, blurMin3);
this.gl.uniform1f(this.blur3MaxLoc, blurMax3);
this.gl.uniform1f(this.scale1Loc, scale1);
this.gl.uniform1f(this.scale2Loc, scale2);
this.gl.uniform1f(this.scale3Loc, scale3);
this.gl.uniform1f(this.bias1Loc, bias1);
this.gl.uniform1f(this.bias2Loc, bias2);
this.gl.uniform1f(this.bias3Loc, bias3);
}
static generateHueBase(mdVSFrame) {
const hueBase = new Float32Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
/* eslint-disable max-len */
for (let i = 0; i < 4; i++) {
hueBase[i * 3 + 0] = 0.6 + 0.3 * Math.sin(mdVSFrame.time * 30.0 * 0.0143 + 3 + i * 21 + mdVSFrame.rand_start[3]);
hueBase[i * 3 + 1] = 0.6 + 0.3 * Math.sin(mdVSFrame.time * 30.0 * 0.0107 + 1 + i * 13 + mdVSFrame.rand_start[1]);
hueBase[i * 3 + 2] = 0.6 + 0.3 * Math.sin(mdVSFrame.time * 30.0 * 0.0129 + 6 + i * 9 + mdVSFrame.rand_start[2]);
const maxshade = Math.max(hueBase[i * 3], hueBase[i * 3 + 1], hueBase[i * 3 + 2]);
for (let k = 0; k < 3; k++) {
hueBase[i * 3 + k] = hueBase[i * 3 + k] / maxshade;
hueBase[i * 3 + k] = 0.5 + 0.5 * hueBase[i * 3 + k];
}
}
/* eslint-enable max-len */
return hueBase;
}
generateCompColors(blending, mdVSFrame, warpColor) {
const hueBase = CompShader.generateHueBase(mdVSFrame);
const gridX1 = this.compWidth + 1;
const gridY1 = this.compHeight + 1;
const compColor = new Float32Array(gridX1 * gridY1 * 4);
let offsetColor = 0;
for (let j = 0; j < gridY1; j++) {
for (let i = 0; i < gridX1; i++) {
let x = i / this.compWidth;
let y = j / this.compHeight;
const col = [1, 1, 1];
for (let c = 0; c < 3; c++) {
col[c] = hueBase[0 + c] * x * y + hueBase[3 + c] * (1 - x) * y + hueBase[6 + c] * x * (1 - y) + hueBase[9 + c] * (1 - x) * (1 - y);
}
let alpha = 1;
if (blending) {
x *= this.mesh_width + 1;
y *= this.mesh_height + 1;
x = Math.clamp(x, 0, this.mesh_width - 1);
y = Math.clamp(y, 0, this.mesh_height - 1);
const nx = Math.floor(x);
const ny = Math.floor(y);
const dx = x - nx;
const dy = y - ny;
const alpha00 = warpColor[(ny * (this.mesh_width + 1) + nx) * 4 + 3];
const alpha01 = warpColor[(ny * (this.mesh_width + 1) + (nx + 1)) * 4 + 3];
const alpha10 = warpColor[((ny + 1) * (this.mesh_width + 1) + nx) * 4 + 3];
const alpha11 = warpColor[((ny + 1) * (this.mesh_width + 1) + (nx + 1)) * 4 + 3];
alpha = alpha00 * (1 - dx) * (1 - dy) + alpha01 * dx * (1 - dy) + alpha10 * (1 - dx) * dy + alpha11 * dx * dy;
}
compColor[offsetColor + 0] = col[0];
compColor[offsetColor + 1] = col[1];
compColor[offsetColor + 2] = col[2];
compColor[offsetColor + 3] = alpha;
offsetColor += 4;
}
}
return compColor;
}
renderQuadTexture(blending, texture, blurTexture1, blurTexture2, blurTexture3, blurMins, blurMaxs, mdVSFrame, mdVSQs, warpColor) {
const compColors = this.generateCompColors(blending, mdVSFrame, warpColor);
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuf);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.indices, this.gl.STATIC_DRAW);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertices, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.compColorVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, compColors, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.compColorLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.compColorLocation);
const wrapping = mdVSFrame.wrap !== 0 ? this.gl.REPEAT : this.gl.CLAMP_TO_EDGE;
this.gl.samplerParameteri(this.mainSampler, this.gl.TEXTURE_WRAP_S, wrapping);
this.gl.samplerParameteri(this.mainSampler, this.gl.TEXTURE_WRAP_T, wrapping);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(0, this.mainSampler);
this.gl.uniform1i(this.textureLoc, 0);
this.gl.activeTexture(this.gl.TEXTURE1);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(1, this.mainSamplerFW);
this.gl.uniform1i(this.textureFWLoc, 1);
this.gl.activeTexture(this.gl.TEXTURE2);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(2, this.mainSamplerFC);
this.gl.uniform1i(this.textureFCLoc, 2);
this.gl.activeTexture(this.gl.TEXTURE3);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(3, this.mainSamplerPW);
this.gl.uniform1i(this.texturePWLoc, 3);
this.gl.activeTexture(this.gl.TEXTURE4);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(4, this.mainSamplerPC);
this.gl.uniform1i(this.texturePCLoc, 4);
this.gl.activeTexture(this.gl.TEXTURE5);
this.gl.bindTexture(this.gl.TEXTURE_2D, blurTexture1);
this.gl.uniform1i(this.blurTexture1Loc, 5);
this.gl.activeTexture(this.gl.TEXTURE6);
this.gl.bindTexture(this.gl.TEXTURE_2D, blurTexture2);
this.gl.uniform1i(this.blurTexture2Loc, 6);
this.gl.activeTexture(this.gl.TEXTURE7);
this.gl.bindTexture(this.gl.TEXTURE_2D, blurTexture3);
this.gl.uniform1i(this.blurTexture3Loc, 7);
this.gl.activeTexture(this.gl.TEXTURE8);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexLQ);
this.gl.uniform1i(this.noiseLQLoc, 8);
this.gl.activeTexture(this.gl.TEXTURE9);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexMQ);
this.gl.uniform1i(this.noiseMQLoc, 9);
this.gl.activeTexture(this.gl.TEXTURE10);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexHQ);
this.gl.uniform1i(this.noiseHQLoc, 10);
this.gl.activeTexture(this.gl.TEXTURE11);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexLQLite);
this.gl.uniform1i(this.noiseLQLiteLoc, 11);
this.gl.activeTexture(this.gl.TEXTURE12);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexLQ);
this.gl.bindSampler(12, this.noise.noiseTexPointLQ);
this.gl.uniform1i(this.noisePointLQLoc, 12);
this.gl.activeTexture(this.gl.TEXTURE13);
this.gl.bindTexture(this.gl.TEXTURE_3D, this.noise.noiseTexVolLQ);
this.gl.uniform1i(this.noiseVolLQLoc, 13);
this.gl.activeTexture(this.gl.TEXTURE14);
this.gl.bindTexture(this.gl.TEXTURE_3D, this.noise.noiseTexVolHQ);
this.gl.uniform1i(this.noiseVolHQLoc, 14);
for (let i = 0; i < this.userTextures.length; i++) {
const userTexture = this.userTextures[i];
this.gl.activeTexture(this.gl.TEXTURE15 + i);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.image.getTexture(userTexture.sampler));
this.gl.uniform1i(userTexture.textureLoc, 15 + i);
}
this.gl.uniform1f(this.timeLoc, mdVSFrame.time);
this.gl.uniform1f(this.gammaAdjLoc, mdVSFrame.gammaadj);
this.gl.uniform1f(this.echoZoomLoc, mdVSFrame.echo_zoom);
this.gl.uniform1f(this.echoAlphaLoc, mdVSFrame.echo_alpha);
this.gl.uniform1f(this.echoOrientationLoc, mdVSFrame.echo_orient);
this.gl.uniform1i(this.invertLoc, mdVSFrame.invert);
this.gl.uniform1i(this.brightenLoc, mdVSFrame.brighten);
this.gl.uniform1i(this.darkenLoc, mdVSFrame.darken);
this.gl.uniform1i(this.solarizeLoc, mdVSFrame.solarize);
this.gl.uniform2fv(this.resolutionLoc, [this.texsizeX, this.texsizeY]);
this.gl.uniform4fv(this.aspectLoc, [this.aspectx, this.aspecty, this.invAspectx, this.invAspecty]);
this.gl.uniform4fv(this.texsizeLoc, new Float32Array([this.texsizeX, this.texsizeY, 1.0 / this.texsizeX, 1.0 / this.texsizeY]));
this.gl.uniform4fv(this.texsizeNoiseLQLoc, [256, 256, 1 / 256, 1 / 256]);
this.gl.uniform4fv(this.texsizeNoiseMQLoc, [256, 256, 1 / 256, 1 / 256]);
this.gl.uniform4fv(this.texsizeNoiseHQLoc, [256, 256, 1 / 256, 1 / 256]);
this.gl.uniform4fv(this.texsizeNoiseLQLiteLoc, [32, 32, 1 / 32, 1 / 32]);
this.gl.uniform4fv(this.texsizeNoiseVolLQLoc, [32, 32, 1 / 32, 1 / 32]);
this.gl.uniform4fv(this.texsizeNoiseVolHQLoc, [32, 32, 1 / 32, 1 / 32]);
this.gl.uniform1f(this.bassLoc, mdVSFrame.bass);
this.gl.uniform1f(this.midLoc, mdVSFrame.mid);
this.gl.uniform1f(this.trebLoc, mdVSFrame.treb);
this.gl.uniform1f(this.volLoc, (mdVSFrame.bass + mdVSFrame.mid + mdVSFrame.treb) / 3);
this.gl.uniform1f(this.bassAttLoc, mdVSFrame.bass_att);
this.gl.uniform1f(this.midAttLoc, mdVSFrame.mid_att);
this.gl.uniform1f(this.trebAttLoc, mdVSFrame.treb_att);
this.gl.uniform1f(this.volAttLoc, (mdVSFrame.bass_att + mdVSFrame.mid_att + mdVSFrame.treb_att) / 3);
this.gl.uniform1f(this.frameLoc, mdVSFrame.frame);
this.gl.uniform1f(this.fpsLoc, mdVSFrame.fps);
this.gl.uniform4fv(this.randPresetLoc, mdVSFrame.rand_preset);
this.gl.uniform4fv(this.randFrameLoc, new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]));
this.gl.uniform1f(this.fShaderLoc, mdVSFrame.fshader);
this.gl.uniform4fv(this.qaLoc, new Float32Array([mdVSQs.q1 || 0, mdVSQs.q2 || 0, mdVSQs.q3 || 0, mdVSQs.q4 || 0]));
this.gl.uniform4fv(this.qbLoc, new Float32Array([mdVSQs.q5 || 0, mdVSQs.q6 || 0, mdVSQs.q7 || 0, mdVSQs.q8 || 0]));
this.gl.uniform4fv(this.qcLoc, new Float32Array([mdVSQs.q9 || 0, mdVSQs.q10 || 0, mdVSQs.q11 || 0, mdVSQs.q12 || 0]));
this.gl.uniform4fv(this.qdLoc, new Float32Array([mdVSQs.q13 || 0, mdVSQs.q14 || 0, mdVSQs.q15 || 0, mdVSQs.q16 || 0]));
this.gl.uniform4fv(this.qeLoc, new Float32Array([mdVSQs.q17 || 0, mdVSQs.q18 || 0, mdVSQs.q19 || 0, mdVSQs.q20 || 0]));
this.gl.uniform4fv(this.qfLoc, new Float32Array([mdVSQs.q21 || 0, mdVSQs.q22 || 0, mdVSQs.q23 || 0, mdVSQs.q24 || 0]));
this.gl.uniform4fv(this.qgLoc, new Float32Array([mdVSQs.q25 || 0, mdVSQs.q26 || 0, mdVSQs.q27 || 0, mdVSQs.q28 || 0]));
this.gl.uniform4fv(this.qhLoc, new Float32Array([mdVSQs.q29 || 0, mdVSQs.q30 || 0, mdVSQs.q31 || 0, mdVSQs.q32 || 0]));
this.gl.uniform4fv(this.slowRoamCosLoc, [0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.005), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.008), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.013), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.022)]);
this.gl.uniform4fv(this.roamCosLoc, [0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.3), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 1.3), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 5.0), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 20.0)]);
this.gl.uniform4fv(this.slowRoamSinLoc, [0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.005), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.008), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.013), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.022)]);
this.gl.uniform4fv(this.roamSinLoc, [0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.3), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 1.3), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 5.0), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 20.0)]);
this.bindBlurVals(blurMins, blurMaxs);
if (blending) {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
} else {
this.gl.disable(this.gl.BLEND);
}
this.gl.drawElements(this.gl.TRIANGLES, this.indices.length, this.gl.UNSIGNED_SHORT, 0);
if (!blending) {
this.gl.enable(this.gl.BLEND);
}
}
}
/***/ }),
/***/ "./src/rendering/shaders/output.js":
/*!*****************************************!*\
!*** ./src/rendering/shaders/output.js ***!
\*****************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return OutputShader; });
/* harmony import */ var _shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class OutputShader {
constructor(gl, opts) {
this.gl = gl;
this.textureRatio = opts.textureRatio;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
this.vertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
if (this.useFXAA()) {
this.createFXAAShader();
} else {
this.createShader();
}
}
useFXAA() {
return this.textureRatio <= 1;
}
updateGlobals(opts) {
this.textureRatio = opts.textureRatio;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.gl.deleteProgram(this.shaderProgram);
if (this.useFXAA()) {
this.createFXAAShader();
} else {
this.createShader();
}
} // based on https://github.com/mattdesl/glsl-fxaa
createFXAAShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
out vec2 v_rgbM;
out vec2 v_rgbNW;
out vec2 v_rgbNE;
out vec2 v_rgbSW;
out vec2 v_rgbSE;
uniform vec4 texsize;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
v_rgbM = aPos * halfmad + halfmad;
v_rgbNW = v_rgbM + (vec2(-1.0, -1.0) * texsize.zx);
v_rgbNE = v_rgbM + (vec2(1.0, -1.0) * texsize.zx);
v_rgbSW = v_rgbM + (vec2(-1.0, 1.0) * texsize.zx);
v_rgbSE = v_rgbM + (vec2(1.0, 1.0) * texsize.zx);
}`);
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec2 v_rgbM;
in vec2 v_rgbNW;
in vec2 v_rgbNE;
in vec2 v_rgbSW;
in vec2 v_rgbSE;
out vec4 fragColor;
uniform vec4 texsize;
uniform sampler2D uTexture;
#ifndef FXAA_REDUCE_MIN
#define FXAA_REDUCE_MIN (1.0/ 128.0)
#endif
#ifndef FXAA_REDUCE_MUL
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#endif
#ifndef FXAA_SPAN_MAX
#define FXAA_SPAN_MAX 8.0
#endif
void main(void) {
vec4 color;
vec3 rgbNW = textureLod(uTexture, v_rgbNW, 0.0).xyz;
vec3 rgbNE = textureLod(uTexture, v_rgbNE, 0.0).xyz;
vec3 rgbSW = textureLod(uTexture, v_rgbSW, 0.0).xyz;
vec3 rgbSE = textureLod(uTexture, v_rgbSE, 0.0).xyz;
vec3 rgbM = textureLod(uTexture, v_rgbM, 0.0).xyz;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM = dot(rgbM, luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
mediump vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir * rcpDirMin)) * texsize.zw;
vec3 rgbA = 0.5 * (
textureLod(uTexture, v_rgbM + dir * (1.0 / 3.0 - 0.5), 0.0).xyz +
textureLod(uTexture, v_rgbM + dir * (2.0 / 3.0 - 0.5), 0.0).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * (
textureLod(uTexture, v_rgbM + dir * -0.5, 0.0).xyz +
textureLod(uTexture, v_rgbM + dir * 0.5, 0.0).xyz);
float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax))
color = vec4(rgbA, 1.0);
else
color = vec4(rgbB, 1.0);
fragColor = color;
}`);
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
this.texsizeLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize");
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
out vec2 uv;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
uv = aPos * halfmad + halfmad;
}`);
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec2 uv;
out vec4 fragColor;
uniform sampler2D uTexture;
void main(void) {
fragColor = vec4(texture(uTexture, uv).rgb, 1.0);
}`);
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
}
renderQuadTexture(texture) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.uniform1i(this.textureLoc, 0);
if (this.useFXAA()) {
this.gl.uniform4fv(this.texsizeLoc, new Float32Array([this.texsizeX, this.texsizeY, 1.0 / this.texsizeX, 1.0 / this.texsizeY]));
}
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
}
}
/***/ }),
/***/ "./src/rendering/shaders/resample.js":
/*!*******************************************!*\
!*** ./src/rendering/shaders/resample.js ***!
\*******************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ResampleShader; });
/* harmony import */ var _shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class ResampleShader {
constructor(gl) {
this.gl = gl;
this.positions = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
this.vertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
out vec2 uv;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
uv = aPos * halfmad + halfmad;
}`);
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec2 uv;
out vec4 fragColor;
uniform sampler2D uTexture;
void main(void) {
fragColor = vec4(texture(uTexture, uv).rgb, 1.0);
}`);
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
}
renderQuadTexture(texture) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.uniform1i(this.textureLoc, 0);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
}
}
/***/ }),
/***/ "./src/rendering/shaders/shaderUtils.js":
/*!**********************************************!*\
!*** ./src/rendering/shaders/shaderUtils.js ***!
\**********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ShaderUtils; });
const lineMatcher = /uniform sampler2D sampler_(?:.+?);/g;
const samplerMatcher = /uniform sampler2D sampler_(.+?);/;
class ShaderUtils {
static getShaderParts(t) {
const sbIndex = t.indexOf("shader_body");
if (t && sbIndex > -1) {
const beforeShaderBody = t.substring(0, sbIndex);
const afterShaderBody = t.substring(sbIndex);
const firstCurly = afterShaderBody.indexOf("{");
const lastCurly = afterShaderBody.lastIndexOf("}");
const shaderBody = afterShaderBody.substring(firstCurly + 1, lastCurly);
return [beforeShaderBody, shaderBody];
}
return ["", t];
}
static getFragmentFloatPrecision(gl) {
if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {
return "highp";
} else if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {
return "mediump";
}
return "lowp";
}
static getUserSamplers(text) {
const samplers = [];
const lineMatches = text.match(lineMatcher);
if (lineMatches && lineMatches.length > 0) {
for (let i = 0; i < lineMatches.length; i++) {
const samplerMatches = lineMatches[i].match(samplerMatcher);
if (samplerMatches && samplerMatches.length > 0) {
const sampler = samplerMatches[1];
samplers.push({
sampler
});
}
}
}
return samplers;
}
}
/***/ }),
/***/ "./src/rendering/shaders/warp.js":
/*!***************************************!*\
!*** ./src/rendering/shaders/warp.js ***!
\***************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return WarpShader; });
/* harmony import */ var _shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class WarpShader {
constructor(gl, noise, image, opts = {}) {
this.gl = gl;
this.noise = noise;
this.image = image;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.buildPositions();
this.indexBuf = gl.createBuffer();
this.positionVertexBuf = this.gl.createBuffer();
this.warpUvVertexBuf = this.gl.createBuffer();
this.warpColorVertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
this.mainSampler = this.gl.createSampler();
this.mainSamplerFW = this.gl.createSampler();
this.mainSamplerFC = this.gl.createSampler();
this.mainSamplerPW = this.gl.createSampler();
this.mainSamplerPC = this.gl.createSampler();
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerFW, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(this.mainSamplerFC, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerPW, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(this.mainSamplerPC, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
} // based on https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js
buildPositions() {
const width = 2;
const height = 2;
const widthHalf = width / 2;
const heightHalf = height / 2;
const gridX = this.mesh_width;
const gridY = this.mesh_height;
const gridX1 = gridX + 1;
const gridY1 = gridY + 1;
const segmentWidth = width / gridX;
const segmentHeight = height / gridY;
const vertices = [];
for (let iy = 0; iy < gridY1; iy++) {
const y = iy * segmentHeight - heightHalf;
for (let ix = 0; ix < gridX1; ix++) {
const x = ix * segmentWidth - widthHalf;
vertices.push(x, -y, 0);
}
}
const indices = [];
for (let iy = 0; iy < gridY; iy++) {
for (let ix = 0; ix < gridX; ix++) {
const a = ix + gridX1 * iy;
const b = ix + gridX1 * (iy + 1);
const c = ix + 1 + gridX1 * (iy + 1);
const d = ix + 1 + gridX1 * iy;
indices.push(a, b, d);
indices.push(b, c, d);
}
}
this.vertices = new Float32Array(vertices);
this.indices = new Uint16Array(indices);
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.buildPositions();
}
createShader(shaderText = "") {
let fragShaderText;
let fragShaderHeaderText;
if (shaderText.length === 0) {
fragShaderText = "ret = texture(sampler_main, uv).rgb * decay;";
fragShaderHeaderText = "";
} else {
const shaderParts = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getShaderParts(shaderText);
fragShaderHeaderText = shaderParts[0];
fragShaderText = shaderParts[1];
}
fragShaderText = fragShaderText.replace(/texture2D/g, "texture");
fragShaderText = fragShaderText.replace(/texture3D/g, "texture");
this.userTextures = _shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getUserSamplers(fragShaderHeaderText);
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
precision ${this.floatPrecision} float;
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
in vec2 aWarpUv;
in vec4 aWarpColor;
out vec2 uv;
out vec2 uv_orig;
out vec4 vColor;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
uv_orig = aPos * halfmad + halfmad;
uv = aWarpUv;
vColor = aWarpColor;
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
precision mediump sampler3D;
in vec2 uv;
in vec2 uv_orig;
in vec4 vColor;
out vec4 fragColor;
uniform sampler2D sampler_main;
uniform sampler2D sampler_fw_main;
uniform sampler2D sampler_fc_main;
uniform sampler2D sampler_pw_main;
uniform sampler2D sampler_pc_main;
uniform sampler2D sampler_blur1;
uniform sampler2D sampler_blur2;
uniform sampler2D sampler_blur3;
uniform sampler2D sampler_noise_lq;
uniform sampler2D sampler_noise_lq_lite;
uniform sampler2D sampler_noise_mq;
uniform sampler2D sampler_noise_hq;
uniform sampler2D sampler_pw_noise_lq;
uniform sampler3D sampler_noisevol_lq;
uniform sampler3D sampler_noisevol_hq;
uniform float time;
uniform float decay;
uniform vec2 resolution;
uniform vec4 aspect;
uniform vec4 texsize;
uniform vec4 texsize_noise_lq;
uniform vec4 texsize_noise_mq;
uniform vec4 texsize_noise_hq;
uniform vec4 texsize_noise_lq_lite;
uniform vec4 texsize_noisevol_lq;
uniform vec4 texsize_noisevol_hq;
uniform float bass;
uniform float mid;
uniform float treb;
uniform float vol;
uniform float bass_att;
uniform float mid_att;
uniform float treb_att;
uniform float vol_att;
uniform float frame;
uniform float fps;
uniform vec4 _qa;
uniform vec4 _qb;
uniform vec4 _qc;
uniform vec4 _qd;
uniform vec4 _qe;
uniform vec4 _qf;
uniform vec4 _qg;
uniform vec4 _qh;
#define q1 _qa.x
#define q2 _qa.y
#define q3 _qa.z
#define q4 _qa.w
#define q5 _qb.x
#define q6 _qb.y
#define q7 _qb.z
#define q8 _qb.w
#define q9 _qc.x
#define q10 _qc.y
#define q11 _qc.z
#define q12 _qc.w
#define q13 _qd.x
#define q14 _qd.y
#define q15 _qd.z
#define q16 _qd.w
#define q17 _qe.x
#define q18 _qe.y
#define q19 _qe.z
#define q20 _qe.w
#define q21 _qf.x
#define q22 _qf.y
#define q23 _qf.z
#define q24 _qf.w
#define q25 _qg.x
#define q26 _qg.y
#define q27 _qg.z
#define q28 _qg.w
#define q29 _qh.x
#define q30 _qh.y
#define q31 _qh.z
#define q32 _qh.w
uniform vec4 slow_roam_cos;
uniform vec4 roam_cos;
uniform vec4 slow_roam_sin;
uniform vec4 roam_sin;
uniform float blur1_min;
uniform float blur1_max;
uniform float blur2_min;
uniform float blur2_max;
uniform float blur3_min;
uniform float blur3_max;
uniform float scale1;
uniform float scale2;
uniform float scale3;
uniform float bias1;
uniform float bias2;
uniform float bias3;
uniform vec4 rand_frame;
uniform vec4 rand_preset;
float PI = ${Math.PI};
${fragShaderHeaderText}
void main(void) {
vec3 ret;
float rad = length(uv_orig - 0.5);
float ang = atan(uv_orig.x - 0.5, uv_orig.y - 0.5);
${fragShaderText}
fragColor = vec4(ret, 1.0) * vColor;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.warpUvLocation = this.gl.getAttribLocation(this.shaderProgram, "aWarpUv");
this.warpColorLocation = this.gl.getAttribLocation(this.shaderProgram, "aWarpColor");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_main");
this.textureFWLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_fw_main");
this.textureFCLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_fc_main");
this.texturePWLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_pw_main");
this.texturePCLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_pc_main");
this.blurTexture1Loc = this.gl.getUniformLocation(this.shaderProgram, "sampler_blur1");
this.blurTexture2Loc = this.gl.getUniformLocation(this.shaderProgram, "sampler_blur2");
this.blurTexture3Loc = this.gl.getUniformLocation(this.shaderProgram, "sampler_blur3");
this.noiseLQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_lq");
this.noiseMQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_mq");
this.noiseHQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_hq");
this.noiseLQLiteLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noise_lq_lite");
this.noisePointLQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_pw_noise_lq");
this.noiseVolLQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noisevol_lq");
this.noiseVolHQLoc = this.gl.getUniformLocation(this.shaderProgram, "sampler_noisevol_hq");
this.decayLoc = this.gl.getUniformLocation(this.shaderProgram, "decay");
this.texsizeLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize");
this.texsizeNoiseLQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_lq");
this.texsizeNoiseMQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_mq");
this.texsizeNoiseHQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_hq");
this.texsizeNoiseLQLiteLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noise_lq_lite");
this.texsizeNoiseVolLQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noisevol_lq");
this.texsizeNoiseVolHQLoc = this.gl.getUniformLocation(this.shaderProgram, "texsize_noisevol_hq");
this.resolutionLoc = this.gl.getUniformLocation(this.shaderProgram, "resolution");
this.aspectLoc = this.gl.getUniformLocation(this.shaderProgram, "aspect");
this.bassLoc = this.gl.getUniformLocation(this.shaderProgram, "bass");
this.midLoc = this.gl.getUniformLocation(this.shaderProgram, "mid");
this.trebLoc = this.gl.getUniformLocation(this.shaderProgram, "treb");
this.volLoc = this.gl.getUniformLocation(this.shaderProgram, "vol");
this.bassAttLoc = this.gl.getUniformLocation(this.shaderProgram, "bass_att");
this.midAttLoc = this.gl.getUniformLocation(this.shaderProgram, "mid_att");
this.trebAttLoc = this.gl.getUniformLocation(this.shaderProgram, "treb_att");
this.volAttLoc = this.gl.getUniformLocation(this.shaderProgram, "vol_att");
this.timeLoc = this.gl.getUniformLocation(this.shaderProgram, "time");
this.frameLoc = this.gl.getUniformLocation(this.shaderProgram, "frame");
this.fpsLoc = this.gl.getUniformLocation(this.shaderProgram, "fps");
this.blur1MinLoc = this.gl.getUniformLocation(this.shaderProgram, "blur1_min");
this.blur1MaxLoc = this.gl.getUniformLocation(this.shaderProgram, "blur1_max");
this.blur2MinLoc = this.gl.getUniformLocation(this.shaderProgram, "blur2_min");
this.blur2MaxLoc = this.gl.getUniformLocation(this.shaderProgram, "blur2_max");
this.blur3MinLoc = this.gl.getUniformLocation(this.shaderProgram, "blur3_min");
this.blur3MaxLoc = this.gl.getUniformLocation(this.shaderProgram, "blur3_max");
this.scale1Loc = this.gl.getUniformLocation(this.shaderProgram, "scale1");
this.scale2Loc = this.gl.getUniformLocation(this.shaderProgram, "scale2");
this.scale3Loc = this.gl.getUniformLocation(this.shaderProgram, "scale3");
this.bias1Loc = this.gl.getUniformLocation(this.shaderProgram, "bias1");
this.bias2Loc = this.gl.getUniformLocation(this.shaderProgram, "bias2");
this.bias3Loc = this.gl.getUniformLocation(this.shaderProgram, "bias3");
this.randPresetLoc = this.gl.getUniformLocation(this.shaderProgram, "rand_preset");
this.randFrameLoc = this.gl.getUniformLocation(this.shaderProgram, "rand_frame");
this.qaLoc = this.gl.getUniformLocation(this.shaderProgram, "_qa");
this.qbLoc = this.gl.getUniformLocation(this.shaderProgram, "_qb");
this.qcLoc = this.gl.getUniformLocation(this.shaderProgram, "_qc");
this.qdLoc = this.gl.getUniformLocation(this.shaderProgram, "_qd");
this.qeLoc = this.gl.getUniformLocation(this.shaderProgram, "_qe");
this.qfLoc = this.gl.getUniformLocation(this.shaderProgram, "_qf");
this.qgLoc = this.gl.getUniformLocation(this.shaderProgram, "_qg");
this.qhLoc = this.gl.getUniformLocation(this.shaderProgram, "_qh");
this.slowRoamCosLoc = this.gl.getUniformLocation(this.shaderProgram, "slow_roam_cos");
this.roamCosLoc = this.gl.getUniformLocation(this.shaderProgram, "roam_cos");
this.slowRoamSinLoc = this.gl.getUniformLocation(this.shaderProgram, "slow_roam_sin");
this.roamSinLoc = this.gl.getUniformLocation(this.shaderProgram, "roam_sin");
for (let i = 0; i < this.userTextures.length; i++) {
const userTexture = this.userTextures[i];
userTexture.textureLoc = this.gl.getUniformLocation(this.shaderProgram, `sampler_${userTexture.sampler}`);
}
}
updateShader(shaderText) {
this.createShader(shaderText);
}
bindBlurVals(blurMins, blurMaxs) {
const blurMin1 = blurMins[0];
const blurMin2 = blurMins[1];
const blurMin3 = blurMins[2];
const blurMax1 = blurMaxs[0];
const blurMax2 = blurMaxs[1];
const blurMax3 = blurMaxs[2];
const scale1 = blurMax1 - blurMin1;
const bias1 = blurMin1;
const scale2 = blurMax2 - blurMin2;
const bias2 = blurMin2;
const scale3 = blurMax3 - blurMin3;
const bias3 = blurMin3;
this.gl.uniform1f(this.blur1MinLoc, blurMin1);
this.gl.uniform1f(this.blur1MaxLoc, blurMax1);
this.gl.uniform1f(this.blur2MinLoc, blurMin2);
this.gl.uniform1f(this.blur2MaxLoc, blurMax2);
this.gl.uniform1f(this.blur3MinLoc, blurMin3);
this.gl.uniform1f(this.blur3MaxLoc, blurMax3);
this.gl.uniform1f(this.scale1Loc, scale1);
this.gl.uniform1f(this.scale2Loc, scale2);
this.gl.uniform1f(this.scale3Loc, scale3);
this.gl.uniform1f(this.bias1Loc, bias1);
this.gl.uniform1f(this.bias2Loc, bias2);
this.gl.uniform1f(this.bias3Loc, bias3);
}
renderQuadTexture(blending, texture, blurTexture1, blurTexture2, blurTexture3, blurMins, blurMaxs, mdVSFrame, mdVSQs, warpUVs, warpColor) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuf);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.indices, this.gl.STATIC_DRAW);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertices, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.warpUvVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, warpUVs, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.warpUvLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.warpUvLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.warpColorVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, warpColor, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.warpColorLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.warpColorLocation);
const wrapping = mdVSFrame.wrap !== 0 ? this.gl.REPEAT : this.gl.CLAMP_TO_EDGE;
this.gl.samplerParameteri(this.mainSampler, this.gl.TEXTURE_WRAP_S, wrapping);
this.gl.samplerParameteri(this.mainSampler, this.gl.TEXTURE_WRAP_T, wrapping);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(0, this.mainSampler);
this.gl.uniform1i(this.textureLoc, 0);
this.gl.activeTexture(this.gl.TEXTURE1);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(1, this.mainSamplerFW);
this.gl.uniform1i(this.textureFWLoc, 1);
this.gl.activeTexture(this.gl.TEXTURE2);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(2, this.mainSamplerFC);
this.gl.uniform1i(this.textureFCLoc, 2);
this.gl.activeTexture(this.gl.TEXTURE3);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(3, this.mainSamplerPW);
this.gl.uniform1i(this.texturePWLoc, 3);
this.gl.activeTexture(this.gl.TEXTURE4);
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
this.gl.bindSampler(4, this.mainSamplerPC);
this.gl.uniform1i(this.texturePCLoc, 4);
this.gl.activeTexture(this.gl.TEXTURE5);
this.gl.bindTexture(this.gl.TEXTURE_2D, blurTexture1);
this.gl.uniform1i(this.blurTexture1Loc, 5);
this.gl.activeTexture(this.gl.TEXTURE6);
this.gl.bindTexture(this.gl.TEXTURE_2D, blurTexture2);
this.gl.uniform1i(this.blurTexture2Loc, 6);
this.gl.activeTexture(this.gl.TEXTURE7);
this.gl.bindTexture(this.gl.TEXTURE_2D, blurTexture3);
this.gl.uniform1i(this.blurTexture3Loc, 7);
this.gl.activeTexture(this.gl.TEXTURE8);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexLQ);
this.gl.uniform1i(this.noiseLQLoc, 8);
this.gl.activeTexture(this.gl.TEXTURE9);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexMQ);
this.gl.uniform1i(this.noiseMQLoc, 9);
this.gl.activeTexture(this.gl.TEXTURE10);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexHQ);
this.gl.uniform1i(this.noiseHQLoc, 10);
this.gl.activeTexture(this.gl.TEXTURE11);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexLQLite);
this.gl.uniform1i(this.noiseLQLiteLoc, 11);
this.gl.activeTexture(this.gl.TEXTURE12);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.noise.noiseTexLQ);
this.gl.bindSampler(12, this.noise.noiseTexPointLQ);
this.gl.uniform1i(this.noisePointLQLoc, 12);
this.gl.activeTexture(this.gl.TEXTURE13);
this.gl.bindTexture(this.gl.TEXTURE_3D, this.noise.noiseTexVolLQ);
this.gl.uniform1i(this.noiseVolLQLoc, 13);
this.gl.activeTexture(this.gl.TEXTURE14);
this.gl.bindTexture(this.gl.TEXTURE_3D, this.noise.noiseTexVolHQ);
this.gl.uniform1i(this.noiseVolHQLoc, 14);
for (let i = 0; i < this.userTextures.length; i++) {
const userTexture = this.userTextures[i];
this.gl.activeTexture(this.gl.TEXTURE15 + i);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.image.getTexture(userTexture.sampler));
this.gl.uniform1i(userTexture.textureLoc, 15 + i);
}
this.gl.uniform1f(this.decayLoc, mdVSFrame.decay);
this.gl.uniform2fv(this.resolutionLoc, [this.texsizeX, this.texsizeY]);
this.gl.uniform4fv(this.aspectLoc, [this.aspectx, this.aspecty, this.invAspectx, this.invAspecty]);
this.gl.uniform4fv(this.texsizeLoc, [this.texsizeX, this.texsizeY, 1.0 / this.texsizeX, 1.0 / this.texsizeY]);
this.gl.uniform4fv(this.texsizeNoiseLQLoc, [256, 256, 1 / 256, 1 / 256]);
this.gl.uniform4fv(this.texsizeNoiseMQLoc, [256, 256, 1 / 256, 1 / 256]);
this.gl.uniform4fv(this.texsizeNoiseHQLoc, [256, 256, 1 / 256, 1 / 256]);
this.gl.uniform4fv(this.texsizeNoiseLQLiteLoc, [32, 32, 1 / 32, 1 / 32]);
this.gl.uniform4fv(this.texsizeNoiseVolLQLoc, [32, 32, 1 / 32, 1 / 32]);
this.gl.uniform4fv(this.texsizeNoiseVolHQLoc, [32, 32, 1 / 32, 1 / 32]);
this.gl.uniform1f(this.bassLoc, mdVSFrame.bass);
this.gl.uniform1f(this.midLoc, mdVSFrame.mid);
this.gl.uniform1f(this.trebLoc, mdVSFrame.treb);
this.gl.uniform1f(this.volLoc, (mdVSFrame.bass + mdVSFrame.mid + mdVSFrame.treb) / 3);
this.gl.uniform1f(this.bassAttLoc, mdVSFrame.bass_att);
this.gl.uniform1f(this.midAttLoc, mdVSFrame.mid_att);
this.gl.uniform1f(this.trebAttLoc, mdVSFrame.treb_att);
this.gl.uniform1f(this.volAttLoc, (mdVSFrame.bass_att + mdVSFrame.mid_att + mdVSFrame.treb_att) / 3);
this.gl.uniform1f(this.timeLoc, mdVSFrame.time);
this.gl.uniform1f(this.frameLoc, mdVSFrame.frame);
this.gl.uniform1f(this.fpsLoc, mdVSFrame.fps);
this.gl.uniform4fv(this.randPresetLoc, mdVSFrame.rand_preset);
this.gl.uniform4fv(this.randFrameLoc, new Float32Array([Math.random(), Math.random(), Math.random(), Math.random()]));
this.gl.uniform4fv(this.qaLoc, new Float32Array([mdVSQs.q1 || 0, mdVSQs.q2 || 0, mdVSQs.q3 || 0, mdVSQs.q4 || 0]));
this.gl.uniform4fv(this.qbLoc, new Float32Array([mdVSQs.q5 || 0, mdVSQs.q6 || 0, mdVSQs.q7 || 0, mdVSQs.q8 || 0]));
this.gl.uniform4fv(this.qcLoc, new Float32Array([mdVSQs.q9 || 0, mdVSQs.q10 || 0, mdVSQs.q11 || 0, mdVSQs.q12 || 0]));
this.gl.uniform4fv(this.qdLoc, new Float32Array([mdVSQs.q13 || 0, mdVSQs.q14 || 0, mdVSQs.q15 || 0, mdVSQs.q16 || 0]));
this.gl.uniform4fv(this.qeLoc, new Float32Array([mdVSQs.q17 || 0, mdVSQs.q18 || 0, mdVSQs.q19 || 0, mdVSQs.q20 || 0]));
this.gl.uniform4fv(this.qfLoc, new Float32Array([mdVSQs.q21 || 0, mdVSQs.q22 || 0, mdVSQs.q23 || 0, mdVSQs.q24 || 0]));
this.gl.uniform4fv(this.qgLoc, new Float32Array([mdVSQs.q25 || 0, mdVSQs.q26 || 0, mdVSQs.q27 || 0, mdVSQs.q28 || 0]));
this.gl.uniform4fv(this.qhLoc, new Float32Array([mdVSQs.q29 || 0, mdVSQs.q30 || 0, mdVSQs.q31 || 0, mdVSQs.q32 || 0]));
this.gl.uniform4fv(this.slowRoamCosLoc, [0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.005), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.008), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.013), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.022)]);
this.gl.uniform4fv(this.roamCosLoc, [0.5 + 0.5 * Math.cos(mdVSFrame.time * 0.3), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 1.3), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 5.0), 0.5 + 0.5 * Math.cos(mdVSFrame.time * 20.0)]);
this.gl.uniform4fv(this.slowRoamSinLoc, [0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.005), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.008), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.013), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.022)]);
this.gl.uniform4fv(this.roamSinLoc, [0.5 + 0.5 * Math.sin(mdVSFrame.time * 0.3), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 1.3), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 5.0), 0.5 + 0.5 * Math.sin(mdVSFrame.time * 20.0)]);
this.bindBlurVals(blurMins, blurMaxs);
if (blending) {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
} else {
this.gl.disable(this.gl.BLEND);
}
this.gl.drawElements(this.gl.TRIANGLES, this.indices.length, this.gl.UNSIGNED_SHORT, 0);
if (!blending) {
this.gl.enable(this.gl.BLEND);
}
}
}
/***/ }),
/***/ "./src/rendering/shapes/customShape.js":
/*!*********************************************!*\
!*** ./src/rendering/shapes/customShape.js ***!
\*********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CustomShape; });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils */ "./src/utils.js");
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class CustomShape {
constructor(index, gl, opts) {
this.index = index;
this.gl = gl;
const maxSides = 101;
this.positions = new Float32Array((maxSides + 2) * 3);
this.colors = new Float32Array((maxSides + 2) * 4);
this.uvs = new Float32Array((maxSides + 2) * 2);
this.borderPositions = new Float32Array((maxSides + 1) * 3);
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.positionVertexBuf = this.gl.createBuffer();
this.colorVertexBuf = this.gl.createBuffer();
this.uvVertexBuf = this.gl.createBuffer();
this.borderPositionVertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_1__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
this.createBorderShader();
this.mainSampler = this.gl.createSampler();
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.samplerParameteri(this.mainSampler, gl.TEXTURE_WRAP_T, gl.REPEAT);
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
in vec3 aPos;
in vec4 aColor;
in vec2 aUv;
out vec4 vColor;
out vec2 vUv;
void main(void) {
vColor = aColor;
vUv = aUv;
gl_Position = vec4(aPos, 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
uniform sampler2D uTexture;
uniform float uTextured;
in vec4 vColor;
in vec2 vUv;
out vec4 fragColor;
void main(void) {
if (uTextured != 0.0) {
fragColor = texture(uTexture, vUv) * vColor;
} else {
fragColor = vColor;
}
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.aPosLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.aColorLocation = this.gl.getAttribLocation(this.shaderProgram, "aColor");
this.aUvLocation = this.gl.getAttribLocation(this.shaderProgram, "aUv");
this.texturedLoc = this.gl.getUniformLocation(this.shaderProgram, "uTextured");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
}
createBorderShader() {
this.borderShaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
in vec3 aBorderPos;
uniform vec2 thickOffset;
void main(void) {
gl_Position = vec4(aBorderPos +
vec3(thickOffset, 0.0), 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
out vec4 fragColor;
uniform vec4 uBorderColor;
void main(void) {
fragColor = uBorderColor;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.borderShaderProgram, vertShader);
this.gl.attachShader(this.borderShaderProgram, fragShader);
this.gl.linkProgram(this.borderShaderProgram);
this.aBorderPosLoc = this.gl.getAttribLocation(this.borderShaderProgram, "aBorderPos");
this.uBorderColorLoc = this.gl.getUniformLocation(this.borderShaderProgram, "uBorderColor");
this.thickOffsetLoc = this.gl.getUniformLocation(this.shaderProgram, "thickOffset");
}
drawCustomShape(blendProgress, globalVars, presetEquationRunner, shapeEqs, prevTexture) {
if (shapeEqs.baseVals.enabled !== 0) {
if (!presetEquationRunner.preset.useWASM) {
this.setupShapeBuffers(presetEquationRunner.mdVSFrame.wrap);
let mdVSShape = Object.assign({}, presetEquationRunner.mdVSShapes[this.index], presetEquationRunner.mdVSFrameMapShapes[this.index], globalVars); // If we aren't setting these every instance, set them initially
if (presetEquationRunner.preset.shapes[this.index].frame_eqs_str === "") {
mdVSShape = Object.assign(mdVSShape, presetEquationRunner.mdVSQAfterFrame, presetEquationRunner.mdVSTShapeInits[this.index]);
}
const baseVals = presetEquationRunner.preset.shapes[this.index].baseVals;
const numInst = Math.clamp(baseVals.num_inst, 1, 1024);
for (let j = 0; j < numInst; j++) {
mdVSShape.instance = j;
mdVSShape.x = baseVals.x;
mdVSShape.y = baseVals.y;
mdVSShape.rad = baseVals.rad;
mdVSShape.ang = baseVals.ang;
mdVSShape.r = baseVals.r;
mdVSShape.g = baseVals.g;
mdVSShape.b = baseVals.b;
mdVSShape.a = baseVals.a;
mdVSShape.r2 = baseVals.r2;
mdVSShape.g2 = baseVals.g2;
mdVSShape.b2 = baseVals.b2;
mdVSShape.a2 = baseVals.a2;
mdVSShape.border_r = baseVals.border_r;
mdVSShape.border_g = baseVals.border_g;
mdVSShape.border_b = baseVals.border_b;
mdVSShape.border_a = baseVals.border_a;
mdVSShape.thickoutline = baseVals.thickoutline;
mdVSShape.textured = baseVals.textured;
mdVSShape.tex_zoom = baseVals.tex_zoom;
mdVSShape.tex_ang = baseVals.tex_ang;
mdVSShape.additive = baseVals.additive;
let mdVSShapeFrame;
if (presetEquationRunner.preset.shapes[this.index].frame_eqs_str !== "") {
mdVSShape = Object.assign(mdVSShape, presetEquationRunner.mdVSQAfterFrame, presetEquationRunner.mdVSTShapeInits[this.index]);
mdVSShapeFrame = presetEquationRunner.runShapeFrameEquations(this.index, mdVSShape);
} else {
mdVSShapeFrame = mdVSShape;
}
let sides = mdVSShapeFrame.sides;
sides = Math.clamp(sides, 3, 100);
sides = Math.floor(sides);
const rad = mdVSShapeFrame.rad;
const ang = mdVSShapeFrame.ang;
const x = mdVSShapeFrame.x * 2 - 1;
const y = mdVSShapeFrame.y * -2 + 1;
const r = mdVSShapeFrame.r;
const g = mdVSShapeFrame.g;
const b = mdVSShapeFrame.b;
const a = mdVSShapeFrame.a;
const r2 = mdVSShapeFrame.r2;
const g2 = mdVSShapeFrame.g2;
const b2 = mdVSShapeFrame.b2;
const a2 = mdVSShapeFrame.a2;
const borderR = mdVSShapeFrame.border_r;
const borderG = mdVSShapeFrame.border_g;
const borderB = mdVSShapeFrame.border_b;
const borderA = mdVSShapeFrame.border_a;
this.borderColor = [borderR, borderG, borderB, borderA * blendProgress];
const thickoutline = mdVSShapeFrame.thickoutline;
const textured = mdVSShapeFrame.textured;
const texZoom = mdVSShapeFrame.tex_zoom;
const texAng = mdVSShapeFrame.tex_ang;
const additive = mdVSShapeFrame.additive;
const hasBorder = this.borderColor[3] > 0;
const isTextured = Math.abs(textured) >= 1;
const isBorderThick = Math.abs(thickoutline) >= 1;
const isAdditive = Math.abs(additive) >= 1;
this.positions[0] = x;
this.positions[1] = y;
this.positions[2] = 0;
this.colors[0] = r;
this.colors[1] = g;
this.colors[2] = b;
this.colors[3] = a * blendProgress;
if (isTextured) {
this.uvs[0] = 0.5;
this.uvs[1] = 0.5;
}
const quarterPi = Math.PI * 0.25;
for (let k = 1; k <= sides + 1; k++) {
const p = (k - 1) / sides;
const pTwoPi = p * 2 * Math.PI;
const angSum = pTwoPi + ang + quarterPi;
this.positions[k * 3 + 0] = x + rad * Math.cos(angSum) * this.aspecty;
this.positions[k * 3 + 1] = y + rad * Math.sin(angSum);
this.positions[k * 3 + 2] = 0;
this.colors[k * 4 + 0] = r2;
this.colors[k * 4 + 1] = g2;
this.colors[k * 4 + 2] = b2;
this.colors[k * 4 + 3] = a2 * blendProgress;
if (isTextured) {
const texAngSum = pTwoPi + texAng + quarterPi;
this.uvs[k * 2 + 0] = 0.5 + 0.5 * Math.cos(texAngSum) / texZoom * this.aspecty;
this.uvs[k * 2 + 1] = 0.5 + 0.5 * Math.sin(texAngSum) / texZoom;
}
if (hasBorder) {
this.borderPositions[(k - 1) * 3 + 0] = this.positions[k * 3 + 0];
this.borderPositions[(k - 1) * 3 + 1] = this.positions[k * 3 + 1];
this.borderPositions[(k - 1) * 3 + 2] = this.positions[k * 3 + 2];
}
}
this.mdVSShapeFrame = mdVSShapeFrame;
this.drawCustomShapeInstance(prevTexture, sides, isTextured, hasBorder, isBorderThick, isAdditive);
}
const mdVSUserKeysShape = presetEquationRunner.mdVSUserKeysShapes[this.index];
const mdVSNewFrameMapShape = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(this.mdVSShapeFrame, mdVSUserKeysShape); // eslint-disable-next-line no-param-reassign
presetEquationRunner.mdVSFrameMapShapes[this.index] = mdVSNewFrameMapShape;
} else {
// eslint-disable-next-line max-len
this.setupShapeBuffers(presetEquationRunner.preset.globalPools.perFrame.wrap.value);
const baseVals = presetEquationRunner.preset.shapes[this.index].baseVals;
const varPool = presetEquationRunner.preset.globalPools[`shapePerFrame${this.index}`];
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(varPool, globalVars, presetEquationRunner.globalKeys); // If we aren't setting these every instance, set them initially
if (!presetEquationRunner.preset.shapes[this.index].frame_eqs) {
presetEquationRunner.preset.restore_qs();
}
_utils__WEBPACK_IMPORTED_MODULE_0__["default"].setWasm(varPool, presetEquationRunner.mdVSTShapeInits[this.index], presetEquationRunner.ts);
presetEquationRunner.preset.save_ts();
varPool.x.value = baseVals.x;
varPool.y.value = baseVals.y;
varPool.rad.value = baseVals.rad;
varPool.ang.value = baseVals.ang;
varPool.r.value = baseVals.r;
varPool.g.value = baseVals.g;
varPool.b.value = baseVals.b;
varPool.a.value = baseVals.a;
varPool.r2.value = baseVals.r2;
varPool.g2.value = baseVals.g2;
varPool.b2.value = baseVals.b2;
varPool.a2.value = baseVals.a2;
varPool.border_r.value = baseVals.border_r;
varPool.border_g.value = baseVals.border_g;
varPool.border_b.value = baseVals.border_b;
varPool.border_a.value = baseVals.border_a;
varPool.thickoutline.value = baseVals.thickoutline;
varPool.textured.value = baseVals.textured;
varPool.tex_zoom.value = baseVals.tex_zoom;
varPool.tex_ang.value = baseVals.tex_ang;
varPool.additive.value = baseVals.additive;
presetEquationRunner.preset.shapes[this.index].frame_eqs_save();
const numInst = Math.clamp(baseVals.num_inst, 1, 1024);
for (let j = 0; j < numInst; j++) {
varPool.instance.value = j; // this condition should check the JS equations because of comments
if (presetEquationRunner.preset.shapes[this.index].frame_eqs) {
presetEquationRunner.preset.shapes[this.index].frame_eqs_restore();
presetEquationRunner.preset.restore_qs();
presetEquationRunner.preset.restore_ts();
presetEquationRunner.preset.shapes[this.index].frame_eqs();
}
let sides = varPool.sides.value;
sides = Math.clamp(sides, 3, 100);
sides = Math.floor(sides);
const rad = varPool.rad.value;
const ang = varPool.ang.value;
const x = varPool.x.value * 2 - 1;
const y = varPool.y.value * -2 + 1;
const r = varPool.r.value;
const g = varPool.g.value;
const b = varPool.b.value;
const a = varPool.a.value;
const r2 = varPool.r2.value;
const g2 = varPool.g2.value;
const b2 = varPool.b2.value;
const a2 = varPool.a2.value;
const borderR = varPool.border_r.value;
const borderG = varPool.border_g.value;
const borderB = varPool.border_b.value;
const borderA = varPool.border_a.value;
this.borderColor = [borderR, borderG, borderB, borderA * blendProgress];
const thickoutline = varPool.thickoutline.value;
const textured = varPool.textured.value;
const texZoom = varPool.tex_zoom.value;
const texAng = varPool.tex_ang.value;
const additive = varPool.additive.value;
const hasBorder = this.borderColor[3] > 0;
const isTextured = Math.abs(textured) >= 1;
const isBorderThick = Math.abs(thickoutline) >= 1;
const isAdditive = Math.abs(additive) >= 1;
this.positions[0] = x;
this.positions[1] = y;
this.positions[2] = 0;
this.colors[0] = r;
this.colors[1] = g;
this.colors[2] = b;
this.colors[3] = a * blendProgress;
if (isTextured) {
this.uvs[0] = 0.5;
this.uvs[1] = 0.5;
}
const quarterPi = Math.PI * 0.25;
for (let k = 1; k <= sides + 1; k++) {
const p = (k - 1) / sides;
const pTwoPi = p * 2 * Math.PI;
const angSum = pTwoPi + ang + quarterPi;
this.positions[k * 3 + 0] = x + rad * Math.cos(angSum) * this.aspecty;
this.positions[k * 3 + 1] = y + rad * Math.sin(angSum);
this.positions[k * 3 + 2] = 0;
this.colors[k * 4 + 0] = r2;
this.colors[k * 4 + 1] = g2;
this.colors[k * 4 + 2] = b2;
this.colors[k * 4 + 3] = a2 * blendProgress;
if (isTextured) {
const texAngSum = pTwoPi + texAng + quarterPi;
this.uvs[k * 2 + 0] = 0.5 + 0.5 * Math.cos(texAngSum) / texZoom * this.aspecty;
this.uvs[k * 2 + 1] = 0.5 + 0.5 * Math.sin(texAngSum) / texZoom;
}
if (hasBorder) {
this.borderPositions[(k - 1) * 3 + 0] = this.positions[k * 3 + 0];
this.borderPositions[(k - 1) * 3 + 1] = this.positions[k * 3 + 1];
this.borderPositions[(k - 1) * 3 + 2] = this.positions[k * 3 + 2];
}
}
this.drawCustomShapeInstance(prevTexture, sides, isTextured, hasBorder, isBorderThick, isAdditive);
}
}
}
}
setupShapeBuffers(wrap) {
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.DYNAMIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.colorVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.colors, this.gl.DYNAMIC_DRAW);
this.gl.vertexAttribPointer(this.aColorLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aColorLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.uvVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.uvs, this.gl.DYNAMIC_DRAW);
this.gl.vertexAttribPointer(this.aUvLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aUvLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.borderPositionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.borderPositions, this.gl.DYNAMIC_DRAW);
this.gl.vertexAttribPointer(this.aBorderPosLoc, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aBorderPosLoc);
const wrapping = wrap !== 0 ? this.gl.REPEAT : this.gl.CLAMP_TO_EDGE;
this.gl.samplerParameteri(this.mainSampler, this.gl.TEXTURE_WRAP_S, wrapping);
this.gl.samplerParameteri(this.mainSampler, this.gl.TEXTURE_WRAP_T, wrapping);
}
drawCustomShapeInstance(prevTexture, sides, isTextured, hasBorder, isBorderThick, isAdditive) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferSubData(this.gl.ARRAY_BUFFER, 0, this.positions, 0, (sides + 2) * 3);
this.gl.vertexAttribPointer(this.aPosLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.colorVertexBuf);
this.gl.bufferSubData(this.gl.ARRAY_BUFFER, 0, this.colors, 0, (sides + 2) * 4);
this.gl.vertexAttribPointer(this.aColorLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aColorLocation);
if (isTextured) {
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.uvVertexBuf);
this.gl.bufferSubData(this.gl.ARRAY_BUFFER, 0, this.uvs, 0, (sides + 2) * 2);
this.gl.vertexAttribPointer(this.aUvLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aUvLocation);
}
this.gl.uniform1f(this.texturedLoc, isTextured ? 1 : 0);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, prevTexture);
this.gl.bindSampler(0, this.mainSampler);
this.gl.uniform1i(this.textureLoc, 0);
if (isAdditive) {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
} else {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
}
this.gl.drawArrays(this.gl.TRIANGLE_FAN, 0, sides + 2);
if (hasBorder) {
this.gl.useProgram(this.borderShaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.borderPositionVertexBuf);
this.gl.bufferSubData(this.gl.ARRAY_BUFFER, 0, this.borderPositions, 0, (sides + 1) * 3);
this.gl.vertexAttribPointer(this.aBorderPosLoc, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aBorderPosLoc);
this.gl.uniform4fv(this.uBorderColorLoc, this.borderColor); // TODO: use drawArraysInstanced
const instances = isBorderThick ? 4 : 1;
for (let i = 0; i < instances; i++) {
const offset = 2;
if (i === 0) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, 0]);
} else if (i === 1) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, 0]);
} else if (i === 2) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, offset / this.texsizeY]);
} else if (i === 3) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, offset / this.texsizeY]);
}
this.gl.drawArrays(this.gl.LINE_STRIP, 0, sides + 1);
}
}
}
}
/***/ }),
/***/ "./src/rendering/sprites/border.js":
/*!*****************************************!*\
!*** ./src/rendering/sprites/border.js ***!
\*****************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Border; });
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class Border {
constructor(gl, opts = {}) {
this.gl = gl;
this.positions = new Float32Array(72);
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
this.vertexBuf = this.gl.createBuffer();
}
updateGlobals(opts) {
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
in vec3 aPos;
void main(void) {
gl_Position = vec4(aPos, 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
out vec4 fragColor;
uniform vec4 u_color;
void main(void) {
fragColor = u_color;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.aPosLoc = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.colorLoc = this.gl.getUniformLocation(this.shaderProgram, "u_color");
}
addTriangle(offset, point1, point2, point3) {
this.positions[offset + 0] = point1[0];
this.positions[offset + 1] = point1[1];
this.positions[offset + 2] = point1[2];
this.positions[offset + 3] = point2[0];
this.positions[offset + 4] = point2[1];
this.positions[offset + 5] = point2[2];
this.positions[offset + 6] = point3[0];
this.positions[offset + 7] = point3[1];
this.positions[offset + 8] = point3[2];
} // based on https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js
generateBorder(borderColor, borderSize, prevBorderSize) {
if (borderSize > 0 && borderColor[3] > 0) {
const width = 2;
const height = 2;
const widthHalf = width / 2;
const heightHalf = height / 2;
const prevBorderWidth = prevBorderSize / 2;
const borderWidth = borderSize / 2 + prevBorderWidth;
const prevBorderWidthWidth = prevBorderWidth * width;
const prevBorderWidthHeight = prevBorderWidth * height;
const borderWidthWidth = borderWidth * width;
const borderWidthHeight = borderWidth * height; // 1st side
let point1 = [-widthHalf + prevBorderWidthWidth, -heightHalf + borderWidthHeight, 0];
let point2 = [-widthHalf + prevBorderWidthWidth, heightHalf - borderWidthHeight, 0];
let point3 = [-widthHalf + borderWidthWidth, heightHalf - borderWidthHeight, 0];
let point4 = [-widthHalf + borderWidthWidth, -heightHalf + borderWidthHeight, 0];
this.addTriangle(0, point4, point2, point1);
this.addTriangle(9, point4, point3, point2); // 2nd side
point1 = [widthHalf - prevBorderWidthWidth, -heightHalf + borderWidthHeight, 0];
point2 = [widthHalf - prevBorderWidthWidth, heightHalf - borderWidthHeight, 0];
point3 = [widthHalf - borderWidthWidth, heightHalf - borderWidthHeight, 0];
point4 = [widthHalf - borderWidthWidth, -heightHalf + borderWidthHeight, 0];
this.addTriangle(18, point1, point2, point4);
this.addTriangle(27, point2, point3, point4); // Top
point1 = [-widthHalf + prevBorderWidthWidth, -heightHalf + prevBorderWidthHeight, 0];
point2 = [-widthHalf + prevBorderWidthWidth, borderWidthHeight - heightHalf, 0];
point3 = [widthHalf - prevBorderWidthWidth, borderWidthHeight - heightHalf, 0];
point4 = [widthHalf - prevBorderWidthWidth, -heightHalf + prevBorderWidthHeight, 0];
this.addTriangle(36, point4, point2, point1);
this.addTriangle(45, point4, point3, point2); // Bottom
point1 = [-widthHalf + prevBorderWidthWidth, heightHalf - prevBorderWidthHeight, 0];
point2 = [-widthHalf + prevBorderWidthWidth, heightHalf - borderWidthHeight, 0];
point3 = [widthHalf - prevBorderWidthWidth, heightHalf - borderWidthHeight, 0];
point4 = [widthHalf - prevBorderWidthWidth, heightHalf - prevBorderWidthHeight, 0];
this.addTriangle(54, point1, point2, point4);
this.addTriangle(63, point2, point3, point4);
return true;
}
return false;
}
drawBorder(borderColor, borderSize, prevBorderSize) {
if (this.generateBorder(borderColor, borderSize, prevBorderSize)) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLoc, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLoc);
this.gl.uniform4fv(this.colorLoc, borderColor);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.TRIANGLES, 0, this.positions.length / 3);
}
}
}
/***/ }),
/***/ "./src/rendering/sprites/darkenCenter.js":
/*!***********************************************!*\
!*** ./src/rendering/sprites/darkenCenter.js ***!
\***********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CustomShape; });
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class CustomShape {
constructor(gl, opts) {
this.gl = gl;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.generatePositions();
this.colors = new Float32Array([0, 0, 0, 3 / 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
this.positionVertexBuf = this.gl.createBuffer();
this.colorVertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
updateGlobals(opts) {
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.generatePositions();
}
generatePositions() {
const halfSize = 0.05;
this.positions = new Float32Array([0, 0, 0, -halfSize * this.aspecty, 0, 0, 0, -halfSize, 0, halfSize * this.aspecty, 0, 0, 0, halfSize, 0, -halfSize * this.aspecty, 0, 0]);
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
in vec3 aPos;
in vec4 aColor;
out vec4 vColor;
void main(void) {
vColor = aColor;
gl_Position = vec4(aPos, 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec4 vColor;
out vec4 fragColor;
void main(void) {
fragColor = vColor;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.aPosLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.aColorLocation = this.gl.getAttribLocation(this.shaderProgram, "aColor");
}
drawDarkenCenter(mdVSFrame) {
if (mdVSFrame.darken_center !== 0) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.colorVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.colors, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aColorLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aColorLocation);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawArrays(this.gl.TRIANGLE_FAN, 0, this.positions.length / 3);
}
}
}
/***/ }),
/***/ "./src/rendering/text/titleText.js":
/*!*****************************************!*\
!*** ./src/rendering/text/titleText.js ***!
\*****************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TitleText; });
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
class TitleText {
constructor(gl, opts = {}) {
this.gl = gl;
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.buildPositions();
this.textTexture = this.gl.createTexture();
this.indexBuf = gl.createBuffer();
this.positionVertexBuf = this.gl.createBuffer();
this.vertexBuf = this.gl.createBuffer();
this.canvas = document.createElement("canvas");
this.canvas.width = this.texsizeX;
this.canvas.height = this.texsizeY;
this.context2D = this.canvas.getContext("2d");
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
generateTitleTexture(text) {
this.context2D.clearRect(0, 0, this.texsizeX, this.texsizeY);
this.fontSize = Math.floor(16 * (this.texsizeX / 256));
this.fontSize = Math.max(this.fontSize, 6);
this.context2D.font = `italic ${this.fontSize}px Times New Roman`;
let titleText = text;
let textLength = this.context2D.measureText(titleText).width;
if (textLength > this.texsizeX) {
const percentToKeep = 0.91 * (this.texsizeX / textLength);
titleText = `${titleText.substring(0, Math.floor(titleText.length * percentToKeep))}...`;
textLength = this.context2D.measureText(titleText).width;
}
this.context2D.fillStyle = "#FFFFFF";
this.context2D.fillText(titleText, (this.texsizeX - textLength) / 2, this.texsizeY / 2);
const imageData = new Uint8Array(this.context2D.getImageData(0, 0, this.texsizeX, this.texsizeY).data.buffer);
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.textTexture);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.texsizeX, this.texsizeY, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, imageData);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.canvas.width = this.texsizeX;
this.canvas.height = this.texsizeY;
} // based on https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js
buildPositions() {
const width = 2;
const height = 2;
const widthHalf = width / 2;
const heightHalf = height / 2;
const gridX = 15;
const gridY = 7;
const gridX1 = gridX + 1;
const gridY1 = gridY + 1;
const segmentWidth = width / gridX;
const segmentHeight = height / gridY;
const vertices = [];
for (let iy = 0; iy < gridY1; iy++) {
const y = iy * segmentHeight - heightHalf;
for (let ix = 0; ix < gridX1; ix++) {
const x = ix * segmentWidth - widthHalf;
vertices.push(x, -y, 0);
}
}
const indices = [];
for (let iy = 0; iy < gridY; iy++) {
for (let ix = 0; ix < gridX; ix++) {
const a = ix + gridX1 * iy;
const b = ix + gridX1 * (iy + 1);
const c = ix + 1 + gridX1 * (iy + 1);
const d = ix + 1 + gridX1 * iy;
indices.push(a, b, d);
indices.push(b, c, d);
}
}
this.vertices = new Float32Array(vertices);
this.indices = new Uint16Array(indices);
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `#version 300 es
const vec2 halfmad = vec2(0.5);
in vec2 aPos;
in vec2 aUv;
out vec2 uv_orig;
out vec2 uv;
void main(void) {
gl_Position = vec4(aPos, 0.0, 1.0);
uv_orig = aPos * halfmad + halfmad;
uv = aUv;
}`);
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec2 uv_orig;
in vec2 uv;
out vec4 fragColor;
uniform sampler2D uTexture;
uniform float textColor;
void main(void) {
fragColor = texture(uTexture, uv) * vec4(textColor);
}`);
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.positionLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.uvLocation = this.gl.getAttribLocation(this.shaderProgram, "aUv");
this.textureLoc = this.gl.getUniformLocation(this.shaderProgram, "uTexture");
this.textColorLoc = this.gl.getUniformLocation(this.shaderProgram, "textColor");
}
generateUvs(progress, flip, globalVars) {
const gridX = 15;
const gridY = 7;
const gridX1 = gridX + 1;
const gridY1 = gridY + 1;
const uvs = [];
const vertClip = 0.75;
for (let j = 0; j < gridY1; j++) {
for (let i = 0; i < gridX1; i++) {
const u = i / gridX;
const v = (j / gridY - 0.5) * vertClip + 0.5;
const x = u * 2.0 - 1.0;
let y = v * 2.0 - 1.0;
if (progress >= 1) {
y += 1.0 / this.texsizeY;
}
uvs.push(x, flip ? y : -y);
}
}
const rampedProgress = Math.max(0, 1 - progress * 1.5);
const t2 = rampedProgress ** 1.8 * 1.3;
for (let j = 0; j < gridY1; j++) {
for (let i = 0; i < gridX1; i++) {
const idx = j * gridX1 + i;
uvs[idx] += t2 * 0.07 * Math.sin(globalVars.time * 0.31 + uvs[idx] * 0.39 - uvs[idx + 1] * 1.94);
uvs[idx] += t2 * 0.044 * Math.sin(globalVars.time * 0.81 - uvs[idx] * 1.91 + uvs[idx + 1] * 0.27);
uvs[idx] += t2 * 0.061 * Math.sin(globalVars.time * 1.31 + uvs[idx] * 0.61 + uvs[idx + 1] * 0.74);
uvs[idx + 1] += t2 * 0.061 * Math.sin(globalVars.time * 0.37 + uvs[idx] * 1.83 + uvs[idx + 1] * 0.69);
uvs[idx + 1] += t2 * 0.07 * Math.sin(globalVars.time * 0.67 + uvs[idx] * 0.42 - uvs[idx + 1] * 1.39);
uvs[idx + 1] += t2 * 0.087 * Math.sin(globalVars.time * 1.07 + uvs[idx] * 3.55 + uvs[idx + 1] * 0.89);
}
}
const scale = 1.01 / (progress ** 0.21 + 0.01);
for (let i = 0; i < uvs.length / 2; i++) {
uvs[i * 2] *= scale;
uvs[i * 2 + 1] *= scale * this.invAspecty; // get back UVs
uvs[i * 2] = (uvs[i * 2] + 1) / 2.0;
uvs[i * 2 + 1] = (uvs[i * 2 + 1] + 1) / 2.0;
}
return new Float32Array(uvs);
}
renderTitle(progress, flip, globalVars) {
this.gl.useProgram(this.shaderProgram);
const progressUvs = this.generateUvs(progress, flip, globalVars);
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuf);
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.indices, this.gl.STATIC_DRAW);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertices, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.positionLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.positionLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, progressUvs, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.uvLocation, 2, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.uvLocation);
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.textTexture);
this.gl.uniform1i(this.textureLoc, 0);
this.gl.uniform1f(this.textColorLoc, progress ** 0.3);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
this.gl.drawElements(this.gl.TRIANGLES, this.indices.length, this.gl.UNSIGNED_SHORT, 0);
}
}
/***/ }),
/***/ "./src/rendering/waves/basicWaveform.js":
/*!**********************************************!*\
!*** ./src/rendering/waves/basicWaveform.js ***!
\**********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return BasicWaveform; });
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
/* harmony import */ var _waveUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./waveUtils */ "./src/rendering/waves/waveUtils.js");
class BasicWaveform {
constructor(gl, opts = {}) {
this.gl = gl;
const numAudioSamples = 512;
this.positions = new Float32Array(numAudioSamples * 3);
this.positions2 = new Float32Array(numAudioSamples * 3);
this.oldPositions = new Float32Array(numAudioSamples * 3);
this.oldPositions2 = new Float32Array(numAudioSamples * 3);
this.smoothedPositions = new Float32Array((numAudioSamples * 2 - 1) * 3);
this.smoothedPositions2 = new Float32Array((numAudioSamples * 2 - 1) * 3);
this.color = [0, 0, 0, 1];
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_0__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
this.vertexBuf = this.gl.createBuffer();
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
in vec3 aPos;
uniform vec2 thickOffset;
void main(void) {
gl_Position = vec4(aPos + vec3(thickOffset, 0.0), 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
out vec4 fragColor;
uniform vec4 u_color;
void main(void) {
fragColor = u_color;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.aPosLoc = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.colorLoc = this.gl.getUniformLocation(this.shaderProgram, "u_color");
this.thickOffsetLoc = this.gl.getUniformLocation(this.shaderProgram, "thickOffset");
}
static processWaveform(timeArray, mdVSFrame) {
const waveform = [];
const scale = mdVSFrame.wave_scale / 128.0;
const smooth = mdVSFrame.wave_smoothing;
const smooth2 = scale * (1.0 - smooth);
waveform.push(timeArray[0] * scale);
for (let i = 1; i < timeArray.length; i++) {
waveform.push(timeArray[i] * smooth2 + waveform[i - 1] * smooth);
}
return waveform;
}
generateWaveform(blending, blendProgress, timeArrayL, timeArrayR, mdVSFrame) {
let alpha = mdVSFrame.wave_a;
const vol = (mdVSFrame.bass + mdVSFrame.mid + mdVSFrame.treb) / 3.0;
if (vol > -0.01 && alpha > 0.001 && timeArrayL.length > 0) {
const waveL = BasicWaveform.processWaveform(timeArrayL, mdVSFrame);
const waveR = BasicWaveform.processWaveform(timeArrayR, mdVSFrame);
const newWaveMode = Math.floor(mdVSFrame.wave_mode) % 8;
const oldWaveMode = Math.floor(mdVSFrame.old_wave_mode) % 8;
const wavePosX = mdVSFrame.wave_x * 2.0 - 1.0;
const wavePosY = mdVSFrame.wave_y * 2.0 - 1.0;
this.numVert = 0;
this.oldNumVert = 0;
const its = blending && newWaveMode !== oldWaveMode ? 2 : 1;
for (let it = 0; it < its; it++) {
const waveMode = it === 0 ? newWaveMode : oldWaveMode;
let fWaveParam2 = mdVSFrame.wave_mystery;
if ((waveMode === 0 || waveMode === 1 || waveMode === 4) && (fWaveParam2 < -1 || fWaveParam2 > 1)) {
fWaveParam2 = fWaveParam2 * 0.5 + 0.5;
fWaveParam2 -= Math.floor(fWaveParam2);
fWaveParam2 = Math.abs(fWaveParam2);
fWaveParam2 = fWaveParam2 * 2 - 1;
}
let numVert;
let positions;
let positions2;
if (it === 0) {
positions = this.positions;
positions2 = this.positions2;
} else {
positions = this.oldPositions;
positions2 = this.oldPositions2;
}
alpha = mdVSFrame.wave_a;
if (waveMode === 0) {
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
numVert = Math.floor(waveL.length / 2) + 1;
const numVertInv = 1.0 / (numVert - 1);
const sampleOffset = Math.floor((waveL.length - numVert) / 2);
for (let i = 0; i < numVert - 1; i++) {
let rad = 0.5 + 0.4 * waveR[i + sampleOffset] + fWaveParam2;
const ang = i * numVertInv * 2 * Math.PI + mdVSFrame.time * 0.2;
if (i < numVert / 10) {
let mix = i / (numVert * 0.1);
mix = 0.5 - 0.5 * Math.cos(mix * Math.PI);
const rad2 = 0.5 + 0.4 * waveR[i + numVert + sampleOffset] + fWaveParam2;
rad = (1.0 - mix) * rad2 + rad * mix;
}
positions[i * 3 + 0] = rad * Math.cos(ang) * this.aspecty + wavePosX;
positions[i * 3 + 1] = rad * Math.sin(ang) * this.aspectx + wavePosY;
positions[i * 3 + 2] = 0;
} // connect the loop
positions[(numVert - 1) * 3 + 0] = positions[0];
positions[(numVert - 1) * 3 + 1] = positions[1];
positions[(numVert - 1) * 3 + 2] = 0;
} else if (waveMode === 1) {
alpha *= 1.25;
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
numVert = Math.floor(waveL.length / 2);
for (let i = 0; i < numVert; i++) {
const rad = 0.53 + 0.43 * waveR[i] + fWaveParam2;
const ang = waveL[i + 32] * 0.5 * Math.PI + mdVSFrame.time * 2.3;
positions[i * 3 + 0] = rad * Math.cos(ang) * this.aspecty + wavePosX;
positions[i * 3 + 1] = rad * Math.sin(ang) * this.aspectx + wavePosY;
positions[i * 3 + 2] = 0;
}
} else if (waveMode === 2) {
if (this.texsizeX < 1024) {
alpha *= 0.09;
} else if (this.texsizeX >= 1024 && this.texsizeX < 2048) {
alpha *= 0.11;
} else {
alpha *= 0.13;
}
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
numVert = waveL.length;
for (let i = 0; i < waveL.length; i++) {
positions[i * 3 + 0] = waveR[i] * this.aspecty + wavePosX;
positions[i * 3 + 1] = waveL[(i + 32) % waveL.length] * this.aspectx + wavePosY;
positions[i * 3 + 2] = 0;
}
} else if (waveMode === 3) {
if (this.texsizeX < 1024) {
alpha *= 0.15;
} else if (this.texsizeX >= 1024 && this.texsizeX < 2048) {
alpha *= 0.22;
} else {
alpha *= 0.33;
}
alpha *= 1.3;
alpha *= mdVSFrame.treb * mdVSFrame.treb; // should be treb_imm
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
numVert = waveL.length;
for (let i = 0; i < waveL.length; i++) {
positions[i * 3 + 0] = waveR[i] * this.aspecty + wavePosX;
positions[i * 3 + 1] = waveL[(i + 32) % waveL.length] * this.aspectx + wavePosY;
positions[i * 3 + 2] = 0;
}
} else if (waveMode === 4) {
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
numVert = waveL.length;
if (numVert > this.texsizeX / 3) {
numVert = Math.floor(this.texsizeX / 3);
}
const numVertInv = 1.0 / numVert;
const sampleOffset = Math.floor((waveL.length - numVert) / 2);
const w1 = 0.45 + 0.5 * (fWaveParam2 * 0.5 + 0.5);
const w2 = 1.0 - w1;
for (let i = 0; i < numVert; i++) {
let x = 2.0 * i * numVertInv + (wavePosX - 1) + waveR[(i + 25 + sampleOffset) % waveL.length] * 0.44;
let y = waveL[i + sampleOffset] * 0.47 + wavePosY; // momentum
if (i > 1) {
x = x * w2 + w1 * (positions[(i - 1) * 3 + 0] * 2.0 - positions[(i - 2) * 3 + 0]);
y = y * w2 + w1 * (positions[(i - 1) * 3 + 1] * 2.0 - positions[(i - 2) * 3 + 1]);
}
positions[i * 3 + 0] = x;
positions[i * 3 + 1] = y;
positions[i * 3 + 2] = 0;
}
} else if (waveMode === 5) {
if (this.texsizeX < 1024) {
alpha *= 0.09;
} else if (this.texsizeX >= 1024 && this.texsizeX < 2048) {
alpha *= 0.11;
} else {
alpha *= 0.13;
}
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
const cosRot = Math.cos(mdVSFrame.time * 0.3);
const sinRot = Math.sin(mdVSFrame.time * 0.3);
numVert = waveL.length;
for (let i = 0; i < waveL.length; i++) {
const ioff = (i + 32) % waveL.length;
const x0 = waveR[i] * waveL[ioff] + waveL[i] * waveR[ioff];
const y0 = waveR[i] * waveR[i] - waveL[ioff] * waveL[ioff];
positions[i * 3 + 0] = (x0 * cosRot - y0 * sinRot) * (this.aspecty + wavePosX);
positions[i * 3 + 1] = (x0 * sinRot + y0 * cosRot) * (this.aspectx + wavePosY);
positions[i * 3 + 2] = 0;
}
} else if (waveMode === 6 || waveMode === 7) {
if (mdVSFrame.modwavealphabyvolume > 0) {
const alphaDiff = mdVSFrame.modwavealphaend - mdVSFrame.modwavealphastart;
alpha *= (vol - mdVSFrame.modwavealphastart) / alphaDiff;
}
alpha = Math.clamp(alpha, 0, 1);
numVert = Math.floor(waveL.length / 2);
if (numVert > this.texsizeX / 3) {
numVert = Math.floor(this.texsizeX / 3);
}
const sampleOffset = Math.floor((waveL.length - numVert) / 2);
const ang = Math.PI * 0.5 * fWaveParam2;
let dx = Math.cos(ang);
let dy = Math.sin(ang);
const edgex = [wavePosX * Math.cos(ang + Math.PI * 0.5) - dx * 3.0, wavePosX * Math.cos(ang + Math.PI * 0.5) + dx * 3.0];
const edgey = [wavePosX * Math.sin(ang + Math.PI * 0.5) - dy * 3.0, wavePosX * Math.sin(ang + Math.PI * 0.5) + dy * 3.0];
for (let i = 0; i < 2; i++) {
for (let j = 0; j < 4; j++) {
let t;
let bClip = false;
switch (j) {
case 0:
if (edgex[i] > 1.1) {
t = (1.1 - edgex[1 - i]) / (edgex[i] - edgex[1 - i]);
bClip = true;
}
break;
case 1:
if (edgex[i] < -1.1) {
t = (-1.1 - edgex[1 - i]) / (edgex[i] - edgex[1 - i]);
bClip = true;
}
break;
case 2:
if (edgey[i] > 1.1) {
t = (1.1 - edgey[1 - i]) / (edgey[i] - edgey[1 - i]);
bClip = true;
}
break;
case 3:
if (edgey[i] < -1.1) {
t = (-1.1 - edgey[1 - i]) / (edgey[i] - edgey[1 - i]);
bClip = true;
}
break;
default:
}
if (bClip) {
const dxi = edgex[i] - edgex[1 - i];
const dyi = edgey[i] - edgey[1 - i];
edgex[i] = edgex[1 - i] + dxi * t;
edgey[i] = edgey[1 - i] + dyi * t;
}
}
}
dx = (edgex[1] - edgex[0]) / numVert;
dy = (edgey[1] - edgey[0]) / numVert;
const ang2 = Math.atan2(dy, dx);
const perpDx = Math.cos(ang2 + Math.PI * 0.5);
const perpDy = Math.sin(ang2 + Math.PI * 0.5);
if (waveMode === 6) {
for (let i = 0; i < numVert; i++) {
const sample = waveL[i + sampleOffset];
positions[i * 3 + 0] = edgex[0] + dx * i + perpDx * 0.25 * sample;
positions[i * 3 + 1] = edgey[0] + dy * i + perpDy * 0.25 * sample;
positions[i * 3 + 2] = 0;
}
} else if (waveMode === 7) {
const sep = (wavePosY * 0.5 + 0.5) ** 2;
for (let i = 0; i < numVert; i++) {
const sample = waveL[i + sampleOffset];
positions[i * 3 + 0] = edgex[0] + dx * i + perpDx * (0.25 * sample + sep);
positions[i * 3 + 1] = edgey[0] + dy * i + perpDy * (0.25 * sample + sep);
positions[i * 3 + 2] = 0;
}
for (let i = 0; i < numVert; i++) {
const sample = waveR[i + sampleOffset];
positions2[i * 3 + 0] = edgex[0] + dx * i + perpDx * (0.25 * sample - sep);
positions2[i * 3 + 1] = edgey[0] + dy * i + perpDy * (0.25 * sample - sep);
positions2[i * 3 + 2] = 0;
}
}
}
if (it === 0) {
this.positions = positions;
this.positions2 = positions2;
this.numVert = numVert;
this.alpha = alpha;
} else {
this.oldPositions = positions;
this.oldPositions2 = positions2;
this.oldNumVert = numVert;
this.oldAlpha = alpha;
}
}
const mix = 0.5 - 0.5 * Math.cos(blendProgress * Math.PI);
const mix2 = 1 - mix;
if (this.oldNumVert > 0) {
alpha = mix * this.alpha + mix2 * this.oldAlpha;
}
let r = Math.clamp(mdVSFrame.wave_r, 0, 1);
let g = Math.clamp(mdVSFrame.wave_g, 0, 1);
let b = Math.clamp(mdVSFrame.wave_b, 0, 1);
if (mdVSFrame.wave_brighten !== 0) {
const maxc = Math.max(r, g, b);
if (maxc > 0.01) {
r /= maxc;
g /= maxc;
b /= maxc;
}
}
this.color = [r, g, b, alpha];
if (this.oldNumVert > 0) {
if (newWaveMode === 7) {
const m = (this.oldNumVert - 1) / (this.numVert * 2);
for (let i = 0; i < this.numVert; i++) {
const fIdx = i * m;
const nIdx = Math.floor(fIdx);
const t = fIdx - nIdx;
const x = this.oldPositions[nIdx * 3 + 0] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 0] * t;
const y = this.oldPositions[nIdx * 3 + 1] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 1] * t;
this.positions[i * 3 + 0] = this.positions[i * 3 + 0] * mix + x * mix2;
this.positions[i * 3 + 1] = this.positions[i * 3 + 1] * mix + y * mix2;
this.positions[i * 3 + 2] = 0;
}
for (let i = 0; i < this.numVert; i++) {
const fIdx = (i + this.numVert) * m;
const nIdx = Math.floor(fIdx);
const t = fIdx - nIdx;
const x = this.oldPositions[nIdx * 3 + 0] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 0] * t;
const y = this.oldPositions[nIdx * 3 + 1] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 1] * t;
this.positions2[i * 3 + 0] = this.positions2[i * 3 + 0] * mix + x * mix2;
this.positions2[i * 3 + 1] = this.positions2[i * 3 + 1] * mix + y * mix2;
this.positions2[i * 3 + 2] = 0;
}
} else if (oldWaveMode === 7) {
const halfNumVert = this.numVert / 2;
const m = (this.oldNumVert - 1) / halfNumVert;
for (let i = 0; i < halfNumVert; i++) {
const fIdx = i * m;
const nIdx = Math.floor(fIdx);
const t = fIdx - nIdx;
const x = this.oldPositions[nIdx * 3 + 0] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 0] * t;
const y = this.oldPositions[nIdx * 3 + 1] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 1] * t;
this.positions[i * 3 + 0] = this.positions[i * 3 + 0] * mix + x * mix2;
this.positions[i * 3 + 1] = this.positions[i * 3 + 1] * mix + y * mix2;
this.positions[i * 3 + 2] = 0;
}
for (let i = 0; i < halfNumVert; i++) {
const fIdx = i * m;
const nIdx = Math.floor(fIdx);
const t = fIdx - nIdx;
const x = this.oldPositions2[nIdx * 3 + 0] * (1 - t) + this.oldPositions2[(nIdx + 1) * 3 + 0] * t;
const y = this.oldPositions2[nIdx * 3 + 1] * (1 - t) + this.oldPositions2[(nIdx + 1) * 3 + 1] * t;
this.positions2[i * 3 + 0] = this.positions[(i + halfNumVert) * 3 + 0] * mix + x * mix2;
this.positions2[i * 3 + 1] = this.positions[(i + halfNumVert) * 3 + 1] * mix + y * mix2;
this.positions2[i * 3 + 2] = 0;
}
} else {
const m = (this.oldNumVert - 1) / this.numVert;
for (let i = 0; i < this.numVert; i++) {
const fIdx = i * m;
const nIdx = Math.floor(fIdx);
const t = fIdx - nIdx;
const x = this.oldPositions[nIdx * 3 + 0] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 0] * t;
const y = this.oldPositions[nIdx * 3 + 1] * (1 - t) + this.oldPositions[(nIdx + 1) * 3 + 1] * t;
this.positions[i * 3 + 0] = this.positions[i * 3 + 0] * mix + x * mix2;
this.positions[i * 3 + 1] = this.positions[i * 3 + 1] * mix + y * mix2;
this.positions[i * 3 + 2] = 0;
}
}
}
for (let i = 0; i < this.numVert; i++) {
this.positions[i * 3 + 1] = -this.positions[i * 3 + 1];
}
this.smoothedNumVert = this.numVert * 2 - 1;
_waveUtils__WEBPACK_IMPORTED_MODULE_1__["default"].smoothWave(this.positions, this.smoothedPositions, this.numVert);
if (newWaveMode === 7 || oldWaveMode === 7) {
for (let i = 0; i < this.numVert; i++) {
this.positions2[i * 3 + 1] = -this.positions2[i * 3 + 1];
}
_waveUtils__WEBPACK_IMPORTED_MODULE_1__["default"].smoothWave(this.positions2, this.smoothedPositions2, this.numVert);
}
return true;
}
return false;
}
drawBasicWaveform(blending, blendProgress, timeArrayL, timeArrayR, mdVSFrame) {
if (this.generateWaveform(blending, blendProgress, timeArrayL, timeArrayR, mdVSFrame)) {
this.gl.useProgram(this.shaderProgram);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.smoothedPositions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLoc, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLoc);
this.gl.uniform4fv(this.colorLoc, this.color);
let instances = 1;
if (mdVSFrame.wave_thick !== 0 || mdVSFrame.wave_dots !== 0) {
instances = 4;
}
if (mdVSFrame.additivewave !== 0) {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
} else {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
}
const drawMode = mdVSFrame.wave_dots !== 0 ? this.gl.POINTS : this.gl.LINE_STRIP; // TODO: use drawArraysInstanced
for (let i = 0; i < instances; i++) {
const offset = 2;
if (i === 0) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, 0]);
} else if (i === 1) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, 0]);
} else if (i === 2) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, offset / this.texsizeY]);
} else if (i === 3) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, offset / this.texsizeY]);
}
this.gl.drawArrays(drawMode, 0, this.smoothedNumVert);
}
const waveMode = Math.floor(mdVSFrame.wave_mode) % 8;
if (waveMode === 7) {
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.smoothedPositions2, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLoc, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLoc);
for (let i = 0; i < instances; i++) {
const offset = 2;
if (i === 0) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, 0]);
} else if (i === 1) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, 0]);
} else if (i === 2) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, offset / this.texsizeY]);
} else if (i === 3) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, offset / this.texsizeY]);
}
this.gl.drawArrays(drawMode, 0, this.smoothedNumVert);
}
}
}
}
}
/***/ }),
/***/ "./src/rendering/waves/customWaveform.js":
/*!***********************************************!*\
!*** ./src/rendering/waves/customWaveform.js ***!
\***********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CustomWaveform; });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils */ "./src/utils.js");
/* harmony import */ var _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shaders/shaderUtils */ "./src/rendering/shaders/shaderUtils.js");
/* harmony import */ var _waveUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./waveUtils */ "./src/rendering/waves/waveUtils.js");
class CustomWaveform {
constructor(index, gl, opts) {
this.index = index;
this.gl = gl;
const maxSamples = 512;
this.pointsData = [new Float32Array(maxSamples), new Float32Array(maxSamples)];
this.positions = new Float32Array(maxSamples * 3);
this.colors = new Float32Array(maxSamples * 4);
this.smoothedPositions = new Float32Array((maxSamples * 2 - 1) * 3);
this.smoothedColors = new Float32Array((maxSamples * 2 - 1) * 4);
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
this.positionVertexBuf = this.gl.createBuffer();
this.colorVertexBuf = this.gl.createBuffer();
this.floatPrecision = _shaders_shaderUtils__WEBPACK_IMPORTED_MODULE_1__["default"].getFragmentFloatPrecision(this.gl);
this.createShader();
}
updateGlobals(opts) {
this.texsizeX = opts.texsizeX;
this.texsizeY = opts.texsizeY;
this.mesh_width = opts.mesh_width;
this.mesh_height = opts.mesh_height;
this.aspectx = opts.aspectx;
this.aspecty = opts.aspecty;
this.invAspectx = 1.0 / this.aspectx;
this.invAspecty = 1.0 / this.aspecty;
}
createShader() {
this.shaderProgram = this.gl.createProgram();
const vertShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertShader, `
#version 300 es
uniform float uSize;
uniform vec2 thickOffset;
in vec3 aPos;
in vec4 aColor;
out vec4 vColor;
void main(void) {
vColor = aColor;
gl_PointSize = uSize;
gl_Position = vec4(aPos + vec3(thickOffset, 0.0), 1.0);
}
`.trim());
this.gl.compileShader(vertShader);
const fragShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragShader, `
#version 300 es
precision ${this.floatPrecision} float;
precision highp int;
precision mediump sampler2D;
in vec4 vColor;
out vec4 fragColor;
void main(void) {
fragColor = vColor;
}
`.trim());
this.gl.compileShader(fragShader);
this.gl.attachShader(this.shaderProgram, vertShader);
this.gl.attachShader(this.shaderProgram, fragShader);
this.gl.linkProgram(this.shaderProgram);
this.aPosLocation = this.gl.getAttribLocation(this.shaderProgram, "aPos");
this.aColorLocation = this.gl.getAttribLocation(this.shaderProgram, "aColor");
this.sizeLoc = this.gl.getUniformLocation(this.shaderProgram, "uSize");
this.thickOffsetLoc = this.gl.getUniformLocation(this.shaderProgram, "thickOffset");
}
generateWaveform(timeArrayL, timeArrayR, freqArrayL, freqArrayR, globalVars, presetEquationRunner, waveEqs, alphaMult) {
if (waveEqs.baseVals.enabled !== 0 && timeArrayL.length > 0) {
let mdVSWaveFrame;
if (presetEquationRunner.preset.useWASM) {
mdVSWaveFrame = presetEquationRunner.runWaveFrameEquations(this.index, globalVars);
} else {
const mdVSWave = Object.assign({}, presetEquationRunner.mdVSWaves[this.index], presetEquationRunner.mdVSFrameMapWaves[this.index], presetEquationRunner.mdVSQAfterFrame, presetEquationRunner.mdVSTWaveInits[this.index], globalVars);
mdVSWaveFrame = presetEquationRunner.runWaveFrameEquations(this.index, mdVSWave);
}
const maxSamples = 512;
if (Object.prototype.hasOwnProperty.call(mdVSWaveFrame, "samples")) {
this.samples = mdVSWaveFrame.samples;
} else {
this.samples = maxSamples;
}
if (this.samples > maxSamples) {
this.samples = maxSamples;
}
this.samples = Math.floor(this.samples);
const baseVals = presetEquationRunner.preset.waves[this.index].baseVals;
const sep = Math.floor(mdVSWaveFrame.sep);
const scaling = mdVSWaveFrame.scaling;
const spectrum = mdVSWaveFrame.spectrum;
const smoothing = mdVSWaveFrame.smoothing;
const usedots = baseVals.usedots;
const frameR = mdVSWaveFrame.r;
const frameG = mdVSWaveFrame.g;
const frameB = mdVSWaveFrame.b;
const frameA = mdVSWaveFrame.a;
const waveScale = presetEquationRunner.preset.baseVals.wave_scale;
this.samples -= sep;
if (this.samples >= 2 || usedots !== 0 && this.samples >= 1) {
const useSpectrum = spectrum !== 0;
const scale = (useSpectrum ? 0.15 : 0.004) * scaling * waveScale;
const pointsLeft = useSpectrum ? freqArrayL : timeArrayL;
const pointsRight = useSpectrum ? freqArrayR : timeArrayR;
const j0 = useSpectrum ? 0 : Math.floor((maxSamples - this.samples) / 2 - sep / 2);
const j1 = useSpectrum ? 0 : Math.floor((maxSamples - this.samples) / 2 + sep / 2);
const t = useSpectrum ? (maxSamples - sep) / this.samples : 1;
const mix1 = (smoothing * 0.98) ** 0.5;
const mix2 = 1 - mix1; // Milkdrop smooths waveform forward, backward and then scales
this.pointsData[0][0] = pointsLeft[j0];
this.pointsData[1][0] = pointsRight[j1];
for (let j = 1; j < this.samples; j++) {
const left = pointsLeft[Math.floor(j * t + j0)];
const right = pointsRight[Math.floor(j * t + j1)];
this.pointsData[0][j] = left * mix2 + this.pointsData[0][j - 1] * mix1;
this.pointsData[1][j] = right * mix2 + this.pointsData[1][j - 1] * mix1;
}
for (let j = this.samples - 2; j >= 0; j--) {
this.pointsData[0][j] = this.pointsData[0][j] * mix2 + this.pointsData[0][j + 1] * mix1;
this.pointsData[1][j] = this.pointsData[1][j] * mix2 + this.pointsData[1][j + 1] * mix1;
}
for (let j = 0; j < this.samples; j++) {
this.pointsData[0][j] *= scale;
this.pointsData[1][j] *= scale;
}
if (!presetEquationRunner.preset.useWASM) {
for (let j = 0; j < this.samples; j++) {
const value1 = this.pointsData[0][j];
const value2 = this.pointsData[1][j];
mdVSWaveFrame.sample = j / (this.samples - 1);
mdVSWaveFrame.value1 = value1;
mdVSWaveFrame.value2 = value2;
mdVSWaveFrame.x = 0.5 + value1;
mdVSWaveFrame.y = 0.5 + value2;
mdVSWaveFrame.r = frameR;
mdVSWaveFrame.g = frameG;
mdVSWaveFrame.b = frameB;
mdVSWaveFrame.a = frameA;
if (waveEqs.point_eqs !== "") {
mdVSWaveFrame = presetEquationRunner.runWavePointEquations(this.index, mdVSWaveFrame);
}
const x = (mdVSWaveFrame.x * 2 - 1) * this.invAspectx;
const y = (mdVSWaveFrame.y * -2 + 1) * this.invAspecty;
const r = mdVSWaveFrame.r;
const g = mdVSWaveFrame.g;
const b = mdVSWaveFrame.b;
const a = mdVSWaveFrame.a;
this.positions[j * 3 + 0] = x;
this.positions[j * 3 + 1] = y;
this.positions[j * 3 + 2] = 0;
this.colors[j * 4 + 0] = r;
this.colors[j * 4 + 1] = g;
this.colors[j * 4 + 2] = b;
this.colors[j * 4 + 3] = a * alphaMult;
}
} else {
const varPool = presetEquationRunner.preset.globalPools[`wavePerFrame${this.index}`];
for (let j = 0; j < this.samples; j++) {
const value1 = this.pointsData[0][j];
const value2 = this.pointsData[1][j];
varPool.sample.value = j / (this.samples - 1);
varPool.value1.value = value1;
varPool.value2.value = value2;
varPool.x.value = 0.5 + value1;
varPool.y.value = 0.5 + value2;
varPool.r.value = frameR;
varPool.g.value = frameG;
varPool.b.value = frameB;
varPool.a.value = frameA;
if (waveEqs.point_eqs) {
presetEquationRunner.preset.waves[this.index].point_eqs();
}
const x = (varPool.x.value * 2 - 1) * this.invAspectx;
const y = (varPool.y.value * -2 + 1) * this.invAspecty;
const r = varPool.r.value;
const g = varPool.g.value;
const b = varPool.b.value;
const a = varPool.a.value;
this.positions[j * 3 + 0] = x;
this.positions[j * 3 + 1] = y;
this.positions[j * 3 + 2] = 0;
this.colors[j * 4 + 0] = r;
this.colors[j * 4 + 1] = g;
this.colors[j * 4 + 2] = b;
this.colors[j * 4 + 3] = a * alphaMult;
}
} // this needs to be after per point (check fishbrain - witchcraft)
if (!presetEquationRunner.preset.useWASM) {
const mdvsUserKeysWave = presetEquationRunner.mdVSUserKeysWaves[this.index];
const mdVSNewFrameMapWave = _utils__WEBPACK_IMPORTED_MODULE_0__["default"].pick(mdVSWaveFrame, mdvsUserKeysWave); // eslint-disable-next-line no-param-reassign
presetEquationRunner.mdVSFrameMapWaves[this.index] = mdVSNewFrameMapWave;
} else {
mdVSWaveFrame.usedots = usedots;
mdVSWaveFrame.thick = baseVals.thick;
mdVSWaveFrame.additive = baseVals.additive;
}
this.mdVSWaveFrame = mdVSWaveFrame;
if (usedots === 0) {
_waveUtils__WEBPACK_IMPORTED_MODULE_2__["default"].smoothWaveAndColor(this.positions, this.colors, this.smoothedPositions, this.smoothedColors, this.samples);
}
return true;
}
}
return false;
}
drawCustomWaveform(blendProgress, timeArrayL, timeArrayR, freqArrayL, freqArrayR, globalVars, presetEquationRunner, waveEqs) {
if (waveEqs && this.generateWaveform(timeArrayL, timeArrayR, freqArrayL, freqArrayR, globalVars, presetEquationRunner, waveEqs, blendProgress)) {
this.gl.useProgram(this.shaderProgram);
const waveUseDots = this.mdVSWaveFrame.usedots !== 0;
const waveThick = this.mdVSWaveFrame.thick !== 0;
const waveAdditive = this.mdVSWaveFrame.additive !== 0;
let positions;
let colors;
let numVerts;
if (!waveUseDots) {
positions = this.smoothedPositions;
colors = this.smoothedColors;
numVerts = this.samples * 2 - 1;
} else {
positions = this.positions;
colors = this.colors;
numVerts = this.samples;
}
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aPosLocation, 3, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aPosLocation);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.colorVertexBuf);
this.gl.bufferData(this.gl.ARRAY_BUFFER, colors, this.gl.STATIC_DRAW);
this.gl.vertexAttribPointer(this.aColorLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.aColorLocation);
let instances = 1;
if (waveUseDots) {
if (waveThick) {
this.gl.uniform1f(this.sizeLoc, 2 + (this.texsizeX >= 1024 ? 1 : 0));
} else {
this.gl.uniform1f(this.sizeLoc, 1 + (this.texsizeX >= 1024 ? 1 : 0));
}
} else {
this.gl.uniform1f(this.sizeLoc, 1);
if (waveThick) {
instances = 4;
}
}
if (waveAdditive) {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
} else {
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
}
const drawMode = waveUseDots ? this.gl.POINTS : this.gl.LINE_STRIP; // TODO: use drawArraysInstanced
for (let i = 0; i < instances; i++) {
const offset = 2;
if (i === 0) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, 0]);
} else if (i === 1) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, 0]);
} else if (i === 2) {
this.gl.uniform2fv(this.thickOffsetLoc, [0, offset / this.texsizeY]);
} else if (i === 3) {
this.gl.uniform2fv(this.thickOffsetLoc, [offset / this.texsizeX, offset / this.texsizeY]);
}
this.gl.drawArrays(drawMode, 0, numVerts);
}
}
}
}
/***/ }),
/***/ "./src/rendering/waves/waveUtils.js":
/*!******************************************!*\
!*** ./src/rendering/waves/waveUtils.js ***!
\******************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return WaveUtils; });
class WaveUtils {
/* eslint-disable no-param-reassign */
static smoothWave(positions, positionsSmoothed, nVertsIn, zCoord = false) {
const c1 = -0.15;
const c2 = 1.15;
const c3 = 1.15;
const c4 = -0.15;
const invSum = 1.0 / (c1 + c2 + c3 + c4);
let j = 0;
let iBelow = 0;
let iAbove;
let iAbove2 = 1;
for (let i = 0; i < nVertsIn - 1; i++) {
iAbove = iAbove2;
iAbove2 = Math.min(nVertsIn - 1, i + 2);
for (let k = 0; k < 3; k++) {
positionsSmoothed[j * 3 + k] = positions[i * 3 + k];
}
if (zCoord) {
for (let k = 0; k < 3; k++) {
positionsSmoothed[(j + 1) * 3 + k] = (c1 * positions[iBelow * 3 + k] + c2 * positions[i * 3 + k] + c3 * positions[iAbove * 3 + k] + c4 * positions[iAbove2 * 3 + k]) * invSum;
}
} else {
for (let k = 0; k < 2; k++) {
positionsSmoothed[(j + 1) * 3 + k] = (c1 * positions[iBelow * 3 + k] + c2 * positions[i * 3 + k] + c3 * positions[iAbove * 3 + k] + c4 * positions[iAbove2 * 3 + k]) * invSum;
}
positionsSmoothed[(j + 1) * 3 + 2] = 0;
}
iBelow = i;
j += 2;
}
for (let k = 0; k < 3; k++) {
positionsSmoothed[j * 3 + k] = positions[(nVertsIn - 1) * 3 + k];
}
}
static smoothWaveAndColor(positions, colors, positionsSmoothed, colorsSmoothed, nVertsIn, zCoord = false) {
const c1 = -0.15;
const c2 = 1.15;
const c3 = 1.15;
const c4 = -0.15;
const invSum = 1.0 / (c1 + c2 + c3 + c4);
let j = 0;
let iBelow = 0;
let iAbove;
let iAbove2 = 1;
for (let i = 0; i < nVertsIn - 1; i++) {
iAbove = iAbove2;
iAbove2 = Math.min(nVertsIn - 1, i + 2);
for (let k = 0; k < 3; k++) {
positionsSmoothed[j * 3 + k] = positions[i * 3 + k];
}
if (zCoord) {
for (let k = 0; k < 3; k++) {
positionsSmoothed[(j + 1) * 3 + k] = (c1 * positions[iBelow * 3 + k] + c2 * positions[i * 3 + k] + c3 * positions[iAbove * 3 + k] + c4 * positions[iAbove2 * 3 + k]) * invSum;
}
} else {
for (let k = 0; k < 2; k++) {
positionsSmoothed[(j + 1) * 3 + k] = (c1 * positions[iBelow * 3 + k] + c2 * positions[i * 3 + k] + c3 * positions[iAbove * 3 + k] + c4 * positions[iAbove2 * 3 + k]) * invSum;
}
positionsSmoothed[(j + 1) * 3 + 2] = 0;
}
for (let k = 0; k < 4; k++) {
colorsSmoothed[j * 4 + k] = colors[i * 4 + k];
colorsSmoothed[(j + 1) * 4 + k] = colors[i * 4 + k];
}
iBelow = i;
j += 2;
}
for (let k = 0; k < 3; k++) {
positionsSmoothed[j * 3 + k] = positions[(nVertsIn - 1) * 3 + k];
}
for (let k = 0; k < 4; k++) {
colorsSmoothed[j * 4 + k] = colors[(nVertsIn - 1) * 4 + k];
}
}
/* eslint-enable no-param-reassign */
}
/***/ }),
/***/ "./src/utils.js":
/*!**********************!*\
!*** ./src/utils.js ***!
\**********************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Utils; });
class Utils {
static atan2(x, y) {
let a = Math.atan2(x, y);
if (a < 0) {
a += 2 * Math.PI;
}
return a;
}
static cloneVars(vars) {
return Object.assign({}, vars);
}
static range(start, end) {
if (end === undefined) {
return [...Array(start).keys()];
}
return Array.from({
length: end - start
}, (_, i) => i + start);
}
static pick(obj, keys) {
const newObj = {};
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
newObj[key] = obj[key] || 0;
}
return newObj;
}
static omit(obj, keys) {
const newObj = Object.assign({}, obj);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
delete newObj[key];
}
return newObj;
}
static setWasm(wasmGlobals, obj, keys) {
for (let i = 0; i < keys.length; i++) {
const key = keys[i]; // eslint-disable-next-line no-param-reassign
wasmGlobals[key].value = obj[key];
}
}
static pickWasm(wasmGlobals, keys) {
const newObj = {};
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
newObj[key] = wasmGlobals[key].value;
}
return newObj;
}
}
/***/ }),
/***/ "./src/visualizer.js":
/*!***************************!*\
!*** ./src/visualizer.js ***!
\***************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Visualizer; });
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js");
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var eel_wasm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! eel-wasm */ "./node_modules/eel-wasm/dist/src/index.js");
/* harmony import */ var eel_wasm__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(eel_wasm__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _assemblyscript_loader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @assemblyscript/loader */ "./node_modules/@assemblyscript/loader/index.js");
/* harmony import */ var _audio_audioProcessor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./audio/audioProcessor */ "./src/audio/audioProcessor.js");
/* harmony import */ var _rendering_renderer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./rendering/renderer */ "./src/rendering/renderer.js");
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils */ "./src/utils.js");
/* harmony import */ var _assemblyscript_presetFunctions_ts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./assemblyscript/presetFunctions.ts */ "./src/assemblyscript/presetFunctions.ts");
/* harmony import */ var _assemblyscript_presetFunctions_ts__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_assemblyscript_presetFunctions_ts__WEBPACK_IMPORTED_MODULE_6__);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
class Visualizer {
constructor(audioContext, canvas, opts) {
this.opts = opts;
this.audio = new _audio_audioProcessor__WEBPACK_IMPORTED_MODULE_3__["default"](audioContext);
const vizWidth = opts.width || 1200;
const vizHeight = opts.height || 900;
this.internalCanvas = document.createElement("canvas");
this.internalCanvas.width = vizWidth;
this.internalCanvas.height = vizHeight;
this.gl = this.internalCanvas.getContext("webgl2", {
alpha: false,
antialias: false,
depth: false,
stencil: false,
premultipliedAlpha: false
});
this.outputGl = canvas.getContext('2d');
this.baseValsDefaults = {
decay: 0.98,
gammaadj: 2,
echo_zoom: 2,
echo_alpha: 0,
echo_orient: 0,
red_blue: 0,
brighten: 0,
darken: 0,
wrap: 1,
darken_center: 0,
solarize: 0,
invert: 0,
bmotionvectorson: 1,
fshader: 0,
b1n: 0,
b2n: 0,
b3n: 0,
b1x: 1,
b2x: 1,
b3x: 1,
b1ed: 0.25,
wave_mode: 0,
additivewave: 0,
wave_dots: 0,
wave_thick: 0,
wave_a: 0.8,
wave_scale: 1,
wave_smoothing: 0.75,
wave_mystery: 0,
modwavealphabyvolume: 0,
modwavealphastart: 0.75,
modwavealphaend: 0.95,
wave_r: 1,
wave_g: 1,
wave_b: 1,
wave_x: 0.5,
wave_y: 0.5,
wave_brighten: 1,
mv_x: 12,
mv_y: 9,
mv_dx: 0,
mv_dy: 0,
mv_l: 0.9,
mv_r: 1,
mv_g: 1,
mv_b: 1,
mv_a: 1,
warpanimspeed: 1,
warpscale: 1,
zoomexp: 1,
zoom: 1,
rot: 0,
cx: 0.5,
cy: 0.5,
dx: 0,
dy: 0,
warp: 1,
sx: 1,
sy: 1,
ob_size: 0.01,
ob_r: 0,
ob_g: 0,
ob_b: 0,
ob_a: 0,
ib_size: 0.01,
ib_r: 0.25,
ib_g: 0.25,
ib_b: 0.25,
ib_a: 0
};
this.shapeBaseValsDefaults = {
enabled: 0,
sides: 4,
additive: 0,
thickoutline: 0,
textured: 0,
num_inst: 1,
tex_zoom: 1,
tex_ang: 0,
x: 0.5,
y: 0.5,
rad: 0.1,
ang: 0,
r: 1,
g: 0,
b: 0,
a: 1,
r2: 0,
g2: 1,
b2: 0,
a2: 0,
border_r: 1,
border_g: 1,
border_b: 1,
border_a: 0.1
};
this.waveBaseValsDefaults = {
enabled: 0,
samples: 512,
sep: 0,
scaling: 1,
smoothing: 0.5,
r: 1,
g: 1,
b: 1,
a: 1,
spectrum: 0,
usedots: 0,
thick: 0,
additive: 0
};
this.qs = _utils__WEBPACK_IMPORTED_MODULE_5__["default"].range(1, 33).map(x => `q${x}`);
this.ts = _utils__WEBPACK_IMPORTED_MODULE_5__["default"].range(1, 9).map(x => `t${x}`);
this.globalPerFrameVars = ["old_wave_mode", // globals
"frame", "time", "fps", "bass", "bass_att", "mid", "mid_att", "treb", "treb_att", "meshx", "meshy", "aspectx", "aspecty", "pixelsx", "pixelsy", "rand_start", "rand_preset"];
this.globalPerPixelVars = [// globals
"frame", "time", "fps", "bass", "bass_att", "mid", "mid_att", "treb", "treb_att", "meshx", "meshy", "aspectx", "aspecty", "pixelsx", "pixelsy", "rand_start", "rand_preset", // for pixel eqs
"x", "y", "rad", "ang"];
this.globalShapeVars = [// globals
"frame", "time", "fps", "bass", "bass_att", "mid", "mid_att", "treb", "treb_att", "meshx", "meshy", "aspectx", "aspecty", "pixelsx", "pixelsy", "rand_start", "rand_preset", // for shape eqs
"instance"];
this.shapeBaseVars = ["x", "y", "rad", "ang", "r", "g", "b", "a", "r2", "g2", "b2", "a2", "border_r", "border_g", "border_b", "border_a", "thickoutline", "textured", "tex_zoom", "tex_ang", "additive"];
this.globalWaveVars = [// globals
"frame", "time", "fps", "bass", "bass_att", "mid", "mid_att", "treb", "treb_att", "meshx", "meshy", "aspectx", "aspecty", "pixelsx", "pixelsy", "rand_start", "rand_preset", // for wave eqs
"x", "y", "sample", "value1", "value2"];
this.renderer = new _rendering_renderer__WEBPACK_IMPORTED_MODULE_4__["default"](this.gl, this.audio, opts);
}
loseGLContext() {
this.gl.getExtension("WEBGL_lose_context").loseContext();
this.outputGl = null;
}
connectAudio(audioNode) {
this.audioNode = audioNode;
this.audio.connectAudio(audioNode);
}
disconnectAudio(audioNode) {
this.audio.disconnectAudio(audioNode);
} // Override defaults, but only include variables in default map
static overrideDefaultVars(baseValsDefaults, baseVals) {
const combinedVals = {};
Object.keys(baseValsDefaults).forEach(key => {
if (Object.prototype.hasOwnProperty.call(baseVals, key)) {
combinedVals[key] = baseVals[key];
} else {
combinedVals[key] = baseValsDefaults[key];
}
});
return combinedVals;
}
createQVars() {
const wasmVars = {};
this.qs.forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, 0);
});
return wasmVars;
}
createTVars() {
const wasmVars = {};
this.ts.forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, 0);
});
return wasmVars;
}
createPerFramePool(baseVals) {
const wasmVars = {};
Object.keys(this.baseValsDefaults).forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, baseVals[key]);
});
this.globalPerFrameVars.forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, 0);
});
return wasmVars;
}
createPerPixelPool(baseVals) {
const wasmVars = {};
Object.keys(this.baseValsDefaults).forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, baseVals[key]);
});
this.globalPerPixelVars.forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, 0);
});
return wasmVars;
}
createCustomShapePerFramePool(baseVals) {
const wasmVars = {};
Object.keys(this.shapeBaseValsDefaults).forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, baseVals[key]);
});
this.globalShapeVars.forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, 0);
});
return wasmVars;
}
createCustomWavePerFramePool(baseVals) {
const wasmVars = {};
Object.keys(this.waveBaseValsDefaults).forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, baseVals[key]);
});
this.globalWaveVars.forEach(key => {
wasmVars[key] = new WebAssembly.Global({
value: "f64",
mutable: true
}, 0);
});
return wasmVars;
}
static makeShapeResetPool(pool, variables, idx) {
return variables.reduce((acc, variable) => {
return _objectSpread(_objectSpread({}, acc), {}, {
[`${variable}_${idx}`]: pool[variable]
});
}, {});
}
static base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var len = binaryString.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
async loadPreset(presetMap, blendTime = 0) {
const preset = JSON.parse(JSON.stringify(presetMap));
preset.baseVals = Visualizer.overrideDefaultVars(this.baseValsDefaults, preset.baseVals);
for (let i = 0; i < preset.shapes.length; i++) {
preset.shapes[i].baseVals = Visualizer.overrideDefaultVars(this.shapeBaseValsDefaults, preset.shapes[i].baseVals);
}
for (let i = 0; i < preset.waves.length; i++) {
preset.waves[i].baseVals = Visualizer.overrideDefaultVars(this.waveBaseValsDefaults, preset.waves[i].baseVals);
}
const forceJS = preset.useJS && !this.opts.onlyUseWASM;
if (Object.prototype.hasOwnProperty.call(preset, "init_eqs_eel") && !forceJS) {
preset.useWASM = true;
await this.loadWASMPreset(preset, blendTime);
} else if (!this.opts.onlyUseWASM) {
if (Object.prototype.hasOwnProperty.call(preset, "init_eqs_str")) {
this.loadJSPreset(preset, blendTime);
} else {
console.warn("Tried to load a JS preset that doesn't have converted strings");
}
} else {
console.warn("Tried to load a preset that doesn't support WASM with onlyUseWASM on");
}
}
async loadWASMPreset(preset, blendTime) {
const qWasmVars = this.createQVars();
const tWasmVars = this.createTVars();
const wasmVarPools = {
perFrame: _objectSpread(_objectSpread({}, qWasmVars), this.createPerFramePool(preset.baseVals)),
perVertex: _objectSpread(_objectSpread({}, qWasmVars), this.createPerPixelPool(preset.baseVals))
};
const wasmFunctions = {
presetInit: {
pool: "perFrame",
code: preset.init_eqs_eel
},
perFrame: {
pool: "perFrame",
code: preset.frame_eqs_eel
}
};
if (preset.pixel_eqs_eel !== "") {
wasmFunctions.perPixel = {
pool: "perVertex",
code: preset.pixel_eqs_eel
};
}
for (let i = 0; i < preset.shapes.length; i++) {
wasmVarPools[`shapePerFrame${i}`] = _objectSpread(_objectSpread(_objectSpread({}, qWasmVars), tWasmVars), this.createCustomShapePerFramePool(preset.shapes[i].baseVals));
if (preset.shapes[i].baseVals.enabled !== 0) {
wasmFunctions[`shapes_${i}_init_eqs`] = {
pool: `shapePerFrame${i}`,
code: preset.shapes[i].init_eqs_eel
};
wasmFunctions[`shapes_${i}_frame_eqs`] = {
pool: `shapePerFrame${i}`,
code: preset.shapes[i].frame_eqs_eel
};
}
}
for (let i = 0; i < preset.waves.length; i++) {
if (preset.waves[i].baseVals.enabled !== 0) {
wasmVarPools[`wavePerFrame${i}`] = _objectSpread(_objectSpread(_objectSpread({}, qWasmVars), tWasmVars), this.createCustomWavePerFramePool(preset.waves[i].baseVals));
wasmFunctions[`waves_${i}_init_eqs`] = {
pool: `wavePerFrame${i}`,
code: preset.waves[i].init_eqs_eel
};
wasmFunctions[`waves_${i}_frame_eqs`] = {
pool: `wavePerFrame${i}`,
code: preset.waves[i].frame_eqs_eel
};
if (preset.waves[i].point_eqs_eel && preset.waves[i].point_eqs_eel !== "") {
wasmFunctions[`waves_${i}_point_eqs`] = {
pool: `wavePerFrame${i}`,
code: preset.waves[i].point_eqs_eel
};
}
}
}
const mod = await Object(eel_wasm__WEBPACK_IMPORTED_MODULE_1__["loadModule"])({
pools: wasmVarPools,
functions: wasmFunctions,
eelVersion: preset.version || 2
}); // eel-wasm returns null if the function was empty
const handleEmptyFunction = f => {
return f ? f : () => {};
};
const presetFunctionsMod = await _assemblyscript_loader__WEBPACK_IMPORTED_MODULE_2__["default"].instantiate(Visualizer.base64ToArrayBuffer(_assemblyscript_presetFunctions_ts__WEBPACK_IMPORTED_MODULE_6___default()()), {
pixelEqs: {
perPixelEqs: handleEmptyFunction(mod.exports.perPixel)
},
// For resetting pixel eq vars
pixelVarPool: {
warp: wasmVarPools.perVertex.warp,
zoom: wasmVarPools.perVertex.zoom,
zoomexp: wasmVarPools.perVertex.zoomexp,
cx: wasmVarPools.perVertex.cx,
cy: wasmVarPools.perVertex.cy,
sx: wasmVarPools.perVertex.sx,
sy: wasmVarPools.perVertex.sy,
dx: wasmVarPools.perVertex.dx,
dy: wasmVarPools.perVertex.dy,
rot: wasmVarPools.perVertex.rot,
x: wasmVarPools.perVertex.x,
y: wasmVarPools.perVertex.y,
ang: wasmVarPools.perVertex.ang,
rad: wasmVarPools.perVertex.rad
},
// For resetting qs/ts
qVarPool: qWasmVars,
tVarPool: tWasmVars,
// For resetting shape vars
shapePool0: Visualizer.makeShapeResetPool(wasmVarPools["shapePerFrame0"], this.shapeBaseVars, 0),
shapePool1: Visualizer.makeShapeResetPool(wasmVarPools["shapePerFrame1"], this.shapeBaseVars, 1),
shapePool2: Visualizer.makeShapeResetPool(wasmVarPools["shapePerFrame2"], this.shapeBaseVars, 2),
shapePool3: Visualizer.makeShapeResetPool(wasmVarPools["shapePerFrame3"], this.shapeBaseVars, 3),
console: {
logi: value => {
// eslint-disable-next-line no-console
console.log("logi: " + value);
},
logf: value => {
// eslint-disable-next-line no-console
console.log("logf: " + value);
}
},
env: {
abort: () => {// No idea why we need this.
}
}
});
preset.globalPools = wasmVarPools;
preset.init_eqs = handleEmptyFunction(mod.exports.presetInit);
preset.frame_eqs = handleEmptyFunction(mod.exports.perFrame);
preset.save_qs = presetFunctionsMod.exports.saveQs;
preset.restore_qs = presetFunctionsMod.exports.restoreQs;
preset.save_ts = presetFunctionsMod.exports.saveTs;
preset.restore_ts = presetFunctionsMod.exports.restoreTs;
if (mod.exports.perPixel) {
preset.pixel_eqs = mod.exports.perPixel;
}
preset.pixel_eqs_initialize_array = (meshWidth, meshHeight) => {
const arrPtr = presetFunctionsMod.exports.createFloat32Array((meshWidth + 1) * (meshHeight + 1) * 2);
preset.pixel_eqs_array = arrPtr;
};
preset.pixel_eqs_get_array = () => {
return presetFunctionsMod.exports.__getFloat32ArrayView(preset.pixel_eqs_array);
};
preset.pixel_eqs_wasm = (...args) => presetFunctionsMod.exports.runPixelEquations(preset.pixel_eqs_array, ...args);
for (let i = 0; i < preset.shapes.length; i++) {
if (preset.shapes[i].baseVals.enabled !== 0) {
preset.shapes[i].init_eqs = handleEmptyFunction(mod.exports[`shapes_${i}_init_eqs`]); // Not wrapped because we check if null in customShapes
preset.shapes[i].frame_eqs = mod.exports[`shapes_${i}_frame_eqs`];
preset.shapes[i].frame_eqs_save = () => presetFunctionsMod.exports[`shape${i}_save`]();
preset.shapes[i].frame_eqs_restore = () => presetFunctionsMod.exports[`shape${i}_restore`]();
}
}
for (let i = 0; i < preset.waves.length; i++) {
if (preset.waves[i].baseVals.enabled !== 0) {
const wave = {
init_eqs: handleEmptyFunction(mod.exports[`waves_${i}_init_eqs`]),
frame_eqs: handleEmptyFunction(mod.exports[`waves_${i}_frame_eqs`])
};
if (preset.waves[i].point_eqs_eel && preset.waves[i].point_eqs_eel !== "") {
// Not wrapped because we check if null in customWaves
wave.point_eqs = mod.exports[`waves_${i}_point_eqs`];
} else {
wave.point_eqs = "";
}
preset.waves[i] = Object.assign({}, preset.waves[i], wave);
}
}
this.renderer.loadPreset(preset, blendTime);
}
loadJSPreset(preset, blendTime) {
// If init_eqs is already a function, it means we've already prepared the preset to run
if (typeof preset.init_eqs !== "function") {
/* eslint-disable no-param-reassign, no-new-func */
preset.init_eqs = new Function("a", `${preset.init_eqs_str} return a;`);
preset.frame_eqs = new Function("a", `${preset.frame_eqs_str} return a;`);
if (preset.pixel_eqs_str && preset.pixel_eqs_str !== "") {
preset.pixel_eqs = new Function("a", `${preset.pixel_eqs_str} return a;`);
} else {
preset.pixel_eqs = "";
}
for (let i = 0; i < preset.shapes.length; i++) {
if (preset.shapes[i].baseVals.enabled !== 0) {
preset.shapes[i] = Object.assign({}, preset.shapes[i], {
init_eqs: new Function("a", `${preset.shapes[i].init_eqs_str} return a;`),
frame_eqs: new Function("a", `${preset.shapes[i].frame_eqs_str} return a;`)
});
}
}
for (let i = 0; i < preset.waves.length; i++) {
if (preset.waves[i].baseVals.enabled !== 0) {
const wave = {
init_eqs: new Function("a", `${preset.waves[i].init_eqs_str} return a;`),
frame_eqs: new Function("a", `${preset.waves[i].frame_eqs_str} return a;`)
};
if (preset.waves[i].point_eqs_str && preset.waves[i].point_eqs_str !== "") {
wave.point_eqs = new Function("a", `${preset.waves[i].point_eqs_str} return a;`);
} else {
wave.point_eqs = "";
}
preset.waves[i] = Object.assign({}, preset.waves[i], wave);
}
}
/* eslint-enable no-param-reassign, no-new-func */
}
this.renderer.loadPreset(preset, blendTime);
}
loadExtraImages(imageData) {
this.renderer.loadExtraImages(imageData);
}
setRendererSize(width, height, opts = {}) {
this.internalCanvas.width = width;
this.internalCanvas.height = height;
this.renderer.setRendererSize(width, height, opts);
}
setInternalMeshSize(width, height) {
this.renderer.setInternalMeshSize(width, height);
}
setOutputAA(useAA) {
this.renderer.setOutputAA(useAA);
}
setCanvas(canvas) {
this.outputGl = canvas.getContext('2d');
}
render(opts) {
const renderOutput = this.renderer.render(opts);
if (this.outputGl) {
this.outputGl.drawImage(this.internalCanvas, 0, 0);
}
return renderOutput;
}
launchSongTitleAnim(text) {
this.renderer.launchSongTitleAnim(text);
}
toDataURL() {
return this.renderer.toDataURL();
}
warpBufferToDataURL() {
return this.renderer.warpBufferToDataURL();
}
}
/***/ })
/******/ });
});
//# sourceMappingURL=butterchurn.js.map