war3-model-docs
Version:
Warcraft 3 model parser, generator, convertor and previewer
39 lines (31 loc) • 208 kB
JavaScript
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./docs/common/shim.ts":
/*!*****************************!*\
!*** ./docs/common/shim.ts ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\nif (!Float32Array.prototype.reverse) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n Float32Array.prototype.reverse = Array.prototype.reverse;\n}\n\n\n\n//# sourceURL=webpack://war3-model-docs/./docs/common/shim.ts?");
/***/ }),
/***/ "./docs/optframes/optframes.ts":
/*!*************************************!*\
!*** ./docs/optframes/optframes.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _mdl_parse__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../mdl/parse */ \"./mdl/parse.ts\");\n/* harmony import */ var _mdx_parse__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../mdx/parse */ \"./mdx/parse.ts\");\n/* harmony import */ var _mdl_generate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../mdl/generate */ \"./mdl/generate.ts\");\n/* harmony import */ var _mdx_generate__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../mdx/generate */ \"./mdx/generate.ts\");\n/* harmony import */ var _common_shim__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../common/shim */ \"./docs/common/shim.ts\");\n\n\n\n\n\n\ndocument.addEventListener('DOMContentLoaded', function init() {\n var container = document.querySelector('.container');\n var saveMDL = document.querySelector('.save[data-type=\"mdl\"]');\n var saveMDX = document.querySelector('.save[data-type=\"mdx\"]');\n var label = document.querySelector('.label');\n var log = document.querySelector('.log');\n var dropTarget;\n var model;\n var cleanedName;\n container.addEventListener('dragenter', function onDragEnter(event) {\n dropTarget = event.target;\n container.classList.add('container_drag');\n event.preventDefault();\n });\n container.addEventListener('dragleave', function onDragLeave(event) {\n if (event.target === dropTarget) {\n container.classList.remove('container_drag');\n }\n });\n container.addEventListener('dragover', function onDragLeave(event) {\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n });\n container.addEventListener('drop', function onDrop(event) {\n event.preventDefault();\n container.classList.remove('container_drag');\n var file = event.dataTransfer.files && event.dataTransfer.files[0];\n if (!file) {\n return;\n }\n var reader = new FileReader();\n var isMDX = file.name.indexOf('.mdx') > -1;\n cleanedName = file.name.replace(/\\.[^.]+$/, '');\n reader.onload = function () {\n try {\n if (isMDX) {\n model = (0,_mdx_parse__WEBPACK_IMPORTED_MODULE_1__.parse)(reader.result);\n }\n else {\n model = (0,_mdl_parse__WEBPACK_IMPORTED_MODULE_0__.parse)(reader.result);\n }\n }\n catch (err) {\n showError(err);\n return;\n }\n processModel();\n };\n if (isMDX) {\n reader.readAsArrayBuffer(file);\n }\n else {\n reader.readAsText(file);\n }\n });\n [saveMDL, saveMDX].forEach(function (button) {\n button.addEventListener('click', function save(event) {\n event.preventDefault();\n var res;\n var isMDL = button.getAttribute('data-type') === 'mdl';\n if (isMDL) {\n res = new Blob([(0,_mdl_generate__WEBPACK_IMPORTED_MODULE_2__.generate)(model)], { type: 'octet/stream' });\n }\n else {\n res = new Blob([(0,_mdx_generate__WEBPACK_IMPORTED_MODULE_3__.generate)(model)], { type: 'octet/stream' });\n }\n var link = document.createElement('a');\n link.style.display = 'none';\n document.body.appendChild(link);\n link.href = URL.createObjectURL(res);\n link.download = cleanedName + (isMDL ? '.mdl' : '.mdx');\n link.click();\n URL.revokeObjectURL(link.href);\n document.body.removeChild(link);\n });\n });\n function clearLog() {\n log.innerHTML = '';\n }\n function logStr(str) {\n var p = document.createElement('p');\n p.textContent = str;\n log.appendChild(p);\n }\n function processModel() {\n clearLog();\n logStr('Optimization is lossy, make sure to test result models');\n var totalKeys = 0, cleanedKeys = 0;\n var isSameKey = function (keyframe0, keyframe1) {\n for (var i = 0; i < keyframe0.Vector.length; ++i) {\n if (keyframe0.Vector[i] !== keyframe1.Vector[i]) {\n return false;\n }\n }\n if (keyframe0.InTan) {\n for (var i = 0; i < keyframe0.InTan.length; ++i) {\n if (keyframe0.InTan[i] !== keyframe1.InTan[i]) {\n return false;\n }\n }\n for (var i = 0; i < keyframe0.OutTan.length; ++i) {\n if (keyframe0.OutTan[i] !== keyframe1.OutTan[i]) {\n return false;\n }\n }\n }\n return true;\n };\n var processKeys = function (obj, key) {\n var animVector = obj[key];\n var sequences = model.Sequences;\n var globalSequences = model.GlobalSequences;\n if (!animVector || !animVector.Keys) {\n return;\n }\n totalKeys += animVector.Keys.length;\n var newKeys = [];\n var processAnim = function (from, to) {\n var keys = [];\n for (var _i = 0, _a = animVector.Keys; _i < _a.length; _i++) {\n var keyframe = _a[_i];\n if (keyframe.Frame >= from && keyframe.Frame <= to) {\n keys.push(keyframe);\n }\n }\n var prevKey = null;\n var filtered = [];\n for (var i = 0; i < keys.length; ++i) {\n if (!prevKey) {\n prevKey = keys[i];\n filtered.push(keys[i]);\n }\n else {\n if (!(isSameKey(keys[i], prevKey) &&\n (i + 1 === keys.length || isSameKey(keys[i], keys[i + 1])))) {\n filtered.push(keys[i]);\n }\n prevKey = keys[i];\n }\n }\n newKeys = newKeys.concat(filtered);\n };\n if (animVector.GlobalSeqId !== null) {\n processAnim(0, globalSequences[animVector.GlobalSeqId]);\n }\n else {\n for (var _i = 0, sequences_1 = sequences; _i < sequences_1.length; _i++) {\n var anim = sequences_1[_i];\n processAnim(anim.Interval[0], anim.Interval[1]);\n }\n }\n cleanedKeys += animVector.Keys.length - newKeys.length;\n animVector.Keys = newKeys;\n };\n for (var _i = 0, _a = model.Nodes; _i < _a.length; _i++) {\n var node = _a[_i];\n processKeys(node, 'Translation');\n processKeys(node, 'Rotation');\n processKeys(node, 'Scaling');\n processKeys(node, 'Visibility');\n processKeys(node, 'EmissionRate');\n processKeys(node, 'Gravity');\n processKeys(node, 'Latitude');\n processKeys(node, 'LifeSpan');\n processKeys(node, 'InitVelocity');\n processKeys(node, 'Speed');\n processKeys(node, 'Variation');\n processKeys(node, 'Width');\n processKeys(node, 'Length');\n processKeys(node, 'AttenuationStart');\n processKeys(node, 'AttenuationEnd');\n processKeys(node, 'Color');\n processKeys(node, 'Intensity');\n processKeys(node, 'AmbIntensity');\n processKeys(node, 'AmbColor');\n processKeys(node, 'HeightAbove');\n processKeys(node, 'HeightBelow');\n processKeys(node, 'Alpha');\n processKeys(node, 'TextureSlot');\n }\n for (var _b = 0, _c = model.Cameras; _b < _c.length; _b++) {\n var camera = _c[_b];\n processKeys(camera, 'TargetTranslation');\n processKeys(camera, 'Translation');\n processKeys(camera, 'Rotation');\n }\n for (var _d = 0, _e = model.TextureAnims; _d < _e.length; _d++) {\n var anim = _e[_d];\n processKeys(anim, 'Translation');\n processKeys(anim, 'Rotation');\n processKeys(anim, 'Scaling');\n }\n for (var _f = 0, _g = model.Materials; _f < _g.length; _f++) {\n var material = _g[_f];\n for (var _h = 0, _j = material.Layers; _h < _j.length; _h++) {\n var layer = _j[_h];\n processKeys(layer, 'TextureID');\n processKeys(layer, 'Alpha');\n }\n }\n logStr(cleanedKeys + '/' + totalKeys + ' frames removed');\n container.classList.add('container_with-data');\n }\n function showError(err) {\n container.classList.remove('container_with-data');\n label.textContent = err;\n }\n});\n\n\n//# sourceURL=webpack://war3-model-docs/./docs/optframes/optframes.ts?");
/***/ }),
/***/ "./mdl/generate.ts":
/*!*************************!*\
!*** ./mdl/generate.ts ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"generate\": () => (/* binding */ generate)\n/* harmony export */ });\n/* harmony import */ var _model__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../model */ \"./model.ts\");\n\nvar FLOAT_PRESICION = 6;\nvar EPSILON = 1e-6;\nfunction isNotEmptyVec3(vec, val) {\n if (val === void 0) { val = 0; }\n return Math.abs(vec[0] - val) > EPSILON ||\n Math.abs(vec[1] - val) > EPSILON ||\n Math.abs(vec[2] - val) > EPSILON;\n}\nfunction generateTab(tabSize) {\n if (tabSize === void 0) { tabSize = 1; }\n if (tabSize === 0) {\n return '';\n }\n var res = '\\t';\n for (var i = 1; i < tabSize; ++i) {\n res += '\\t';\n }\n return res;\n}\nfunction generateWrappedString(val) {\n return \"\\\"\" + val + \"\\\"\";\n}\nfunction generateWrappedStringOrNumber(val) {\n if (typeof val === 'number') {\n return String(val);\n }\n return generateWrappedString(val);\n}\nfunction generateBlockStart(blockName, subInfo, tabSize) {\n if (subInfo === void 0) { subInfo = null; }\n if (tabSize === void 0) { tabSize = 0; }\n return generateTab(tabSize) +\n blockName + ' ' +\n (subInfo !== null ? generateWrappedStringOrNumber(subInfo) + ' ' : '') +\n '{\\n';\n}\nfunction generateBlockEnd(tabSize) {\n if (tabSize === void 0) { tabSize = 0; }\n return generateTab(tabSize) + '}\\n';\n}\nvar trailingZeroRegExp = /(\\..+?)0+$/;\nvar trailingZeroRegExp2 = /\\.0+$/;\nvar negativeZeroRegExp = /^-0$/;\nfunction generateNumber(val) {\n return val.toFixed(FLOAT_PRESICION)\n .replace(trailingZeroRegExp, '$1')\n .replace(trailingZeroRegExp2, '')\n .replace(negativeZeroRegExp, '0');\n}\nfunction generateArray(arr, reverse) {\n if (reverse === void 0) { reverse = false; }\n var middle = '';\n if (reverse) {\n for (var i = arr.length - 1; i >= 0; --i) {\n if (i < arr.length - 1) {\n middle += ', ';\n }\n middle += generateNumber(arr[i]);\n }\n }\n else {\n for (var i = 0; i < arr.length; ++i) {\n if (i > 0) {\n middle += ', ';\n }\n middle += generateNumber(arr[i]);\n }\n }\n return '{ ' + middle + ' }';\n}\nfunction generateUIntArray(arr) {\n var middle = '';\n for (var i = 0; i < arr.length; ++i) {\n if (i > 0) {\n middle += ', ';\n }\n middle += String(arr[i]);\n }\n return '{ ' + middle + ' }';\n}\nfunction generateStatic(isStatic) {\n return isStatic ? 'static ' : '';\n}\nfunction generateProp(name, val, isStatic, tabSize) {\n if (tabSize === void 0) { tabSize = 1; }\n return generateTab(tabSize) + generateStatic(isStatic) + name + \" \" + val + \",\\n\";\n}\nfunction generateIntProp(name, val, isStatic, tabSize) {\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n return generateProp(name, String(val), isStatic, tabSize);\n}\nfunction generateFloatProp(name, val, isStatic, tabSize) {\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n return generateProp(name, generateNumber(val), isStatic, tabSize);\n}\nfunction generateStringProp(name, val, isStatic, tabSize) {\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n return generateProp(name, val, isStatic, tabSize);\n}\nfunction generateWrappedStringProp(name, val, isStatic, tabSize) {\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n return generateProp(name, generateWrappedString(val), isStatic, tabSize);\n}\nfunction generateFloatArrayProp(name, val, isStatic, tabSize) {\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n return generateProp(name, generateArray(val), isStatic, tabSize);\n}\nfunction generateUIntArrayProp(name, val, isStatic, tabSize) {\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n return generateProp(name, generateUIntArray(val), isStatic, tabSize);\n}\nfunction generateBooleanProp(name, tabSize) {\n if (tabSize === void 0) { tabSize = 1; }\n return generateTab(tabSize) + name + ',\\n';\n}\nfunction generateIntPropIfNotEmpty(name, val, defaultVal, isStatic, tabSize) {\n if (defaultVal === void 0) { defaultVal = 0; }\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n if (val !== defaultVal && val !== null && val !== undefined) {\n return generateIntProp(name, val, isStatic, tabSize);\n }\n return '';\n}\nfunction generateFloatPropIfNotEmpty(name, val, defaultVal, isStatic, tabSize) {\n if (defaultVal === void 0) { defaultVal = 0; }\n if (isStatic === void 0) { isStatic = null; }\n if (tabSize === void 0) { tabSize = 1; }\n if (Math.abs(val - defaultVal) > EPSILON) {\n return generateFloatProp(name, val, isStatic, tabSize);\n }\n return '';\n}\nfunction generateLineType(lineType) {\n switch (lineType) {\n case _model__WEBPACK_IMPORTED_MODULE_0__.LineType.DontInterp:\n return 'DontInterp';\n case _model__WEBPACK_IMPORTED_MODULE_0__.LineType.Linear:\n return 'Linear';\n case _model__WEBPACK_IMPORTED_MODULE_0__.LineType.Bezier:\n return 'Bezier';\n case _model__WEBPACK_IMPORTED_MODULE_0__.LineType.Hermite:\n return 'Hermite';\n }\n return '';\n}\nfunction generateAnimKeyFrame(key, tabSize, reverse) {\n if (tabSize === void 0) { tabSize = 2; }\n if (reverse === void 0) { reverse = false; }\n var res = generateTab(tabSize) + key.Frame + ': ' +\n (key.Vector.length === 1 ? generateNumber(key.Vector[0]) : generateArray(key.Vector, reverse)) + ',\\n';\n if (key.InTan /* or OutTan */) {\n res += generateTab(tabSize + 1) + 'InTan ' +\n (key.InTan.length === 1 ? generateNumber(key.InTan[0]) : generateArray(key.InTan, reverse)) + ',\\n';\n res += generateTab(tabSize + 1) + 'OutTan ' +\n (key.OutTan.length === 1 ? generateNumber(key.OutTan[0]) : generateArray(key.OutTan, reverse)) + ',\\n';\n }\n return res;\n}\nfunction generateAnimVectorProp(name, val, defaultVal, tabSize, reverse) {\n if (defaultVal === void 0) { defaultVal = 0; }\n if (tabSize === void 0) { tabSize = 1; }\n if (reverse === void 0) { reverse = false; }\n if (val === null || val === undefined) {\n return '';\n }\n if (typeof val === 'number') {\n if (typeof defaultVal === 'number' && Math.abs(val - defaultVal) < EPSILON) {\n return '';\n }\n else {\n return generateFloatProp(name, val, true, tabSize);\n }\n }\n else {\n return generateBlockStart(name, val.Keys.length, tabSize) +\n generateBooleanProp(generateLineType(val.LineType), tabSize + 1) +\n (val.GlobalSeqId !== null ? generateIntProp('GlobalSeqId', val.GlobalSeqId, null, tabSize + 1) : '') +\n val.Keys.map(function (key) { return generateAnimKeyFrame(key, tabSize + 1, reverse); }).join('') +\n generateBlockEnd(tabSize);\n }\n}\nfunction generateVersion(model) {\n return generateBlockStart('Version') +\n generateIntProp('FormatVersion', model.Version) +\n generateBlockEnd();\n}\nfunction generateModel(model) {\n return generateBlockStart('Model', model.Info.Name) +\n generateIntPropIfNotEmpty('NumGeosets', model.Geosets.length) +\n generateIntPropIfNotEmpty('NumGeosetAnims', model.GeosetAnims.length) +\n generateIntPropIfNotEmpty('NumHelpers', model.Helpers.length) +\n generateIntPropIfNotEmpty('NumBones', model.Bones.length) +\n (model.Lights.length ? generateIntPropIfNotEmpty('NumLights', model.Lights.length) : '') +\n generateIntPropIfNotEmpty('NumAttachments', model.Attachments.length) +\n generateIntPropIfNotEmpty('NumEvents', model.EventObjects.length) +\n generateIntPropIfNotEmpty('NumParticleEmitters', model.ParticleEmitters.length) +\n (model.ParticleEmitters2.length ?\n generateIntPropIfNotEmpty('NumParticleEmitters2', model.ParticleEmitters2.length) :\n '') +\n (model.RibbonEmitters.length ?\n generateIntPropIfNotEmpty('NumRibbonEmitters', model.RibbonEmitters.length) :\n '') +\n generateIntProp('BlendTime', model.Info.BlendTime) +\n generateFloatArrayProp('MinimumExtent', model.Info.MinimumExtent) +\n generateFloatArrayProp('MaximumExtent', model.Info.MaximumExtent) +\n generateFloatPropIfNotEmpty('BoundsRadius', model.Info.BoundsRadius) +\n generateBlockEnd();\n}\nfunction generateSequences(model) {\n return generateBlockStart('Sequences', model.Sequences.length) +\n model.Sequences.map(generateSequenceChunk).join('') +\n generateBlockEnd();\n}\nfunction generateSequenceChunk(sequence) {\n return generateBlockStart('Anim', sequence.Name, 1) +\n generateUIntArrayProp('Interval', sequence.Interval, null, 2) +\n generateFloatPropIfNotEmpty('Rarity', sequence.Rarity, 0, null, 2) +\n generateFloatPropIfNotEmpty('MoveSpeed', sequence.MoveSpeed, 0, null, 2) +\n (sequence.NonLooping ? generateBooleanProp('NonLooping', 2) : '') +\n generateFloatArrayProp('MinimumExtent', sequence.MinimumExtent, null, 2) +\n generateFloatArrayProp('MaximumExtent', sequence.MaximumExtent, null, 2) +\n generateFloatPropIfNotEmpty('BoundsRadius', sequence.BoundsRadius, 0, null, 2) +\n generateBlockEnd(1);\n}\nfunction generateGlobalSequences(model) {\n if (!model.GlobalSequences || !model.GlobalSequences.length) {\n return '';\n }\n return generateBlockStart('GlobalSequences', model.GlobalSequences.length) +\n model.GlobalSequences.map(function (duration) { return generateIntProp('Duration', duration); }).join('') +\n generateBlockEnd();\n}\nfunction generateTextures(model) {\n if (!model.Textures.length) {\n return '';\n }\n return generateBlockStart('Textures', model.Textures.length) +\n model.Textures.map(generateTextureChunk).join('') +\n generateBlockEnd();\n}\nfunction generateTextureChunk(texture) {\n return generateBlockStart('Bitmap', null, 1) +\n generateWrappedStringProp('Image', texture.Image, null, 2) +\n generateIntPropIfNotEmpty('ReplaceableId', texture.ReplaceableId, 0, null, 2) +\n (texture.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.TextureFlags.WrapWidth ? generateBooleanProp('WrapWidth', 2) : '') +\n (texture.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.TextureFlags.WrapHeight ? generateBooleanProp('WrapHeight', 2) : '') +\n generateBlockEnd(1);\n}\nfunction generateMaterials(model) {\n if (!model.Materials.length) {\n return '';\n }\n return generateBlockStart('Materials', model.Materials.length) +\n model.Materials.map(function (it) { return generateMaterialChunk(model, it); }).join('') +\n generateBlockEnd();\n}\nfunction generateMaterialChunk(model, material) {\n var shader = '';\n if (model.Version >= 900 && material.Shader) {\n shader = generateWrappedStringProp('Shader', material.Shader, false, 2);\n }\n return generateBlockStart('Material', null, 1) +\n (material.RenderMode & _model__WEBPACK_IMPORTED_MODULE_0__.MaterialRenderMode.ConstantColor ? generateBooleanProp('ConstantColor', 2) : '') +\n (material.RenderMode & _model__WEBPACK_IMPORTED_MODULE_0__.MaterialRenderMode.SortPrimsFarZ ? generateBooleanProp('SortPrimsFarZ', 2) : '') +\n (material.RenderMode & _model__WEBPACK_IMPORTED_MODULE_0__.MaterialRenderMode.FullResolution ? generateBooleanProp('FullResolution', 2) : '') +\n generateIntPropIfNotEmpty('PriorityPlane', material.PriorityPlane, 0, null, 2) +\n generateIntPropIfNotEmpty('RenderMode', material.RenderMode, 0, null, 2) +\n shader +\n material.Layers.map(function (it) { return generateLayerChunk(model, it); }).join('') +\n generateBlockEnd(1);\n}\nfunction generateFilterMode(filterMode) {\n switch (filterMode) {\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.None:\n return 'None';\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Transparent:\n return 'Transparent';\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Blend:\n return 'Blend';\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Additive:\n return 'Additive';\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.AddAlpha:\n return 'AddAlpha';\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Modulate:\n return 'Modulate';\n case _model__WEBPACK_IMPORTED_MODULE_0__.FilterMode.Modulate2x:\n return 'Modulate2x';\n }\n return '';\n}\nfunction generateLayerChunk(model, layer) {\n var middle = '';\n if (model.Version >= 900) {\n middle += (layer.EmissiveGain !== undefined ? generateAnimVectorProp('EmissiveGain', layer.EmissiveGain, 1, 3) : '');\n if (model.Version >= 1000) {\n middle += (layer.FresnelColor !== undefined ? generateColorProp('FresnelColor', layer.FresnelColor, true, 3) : '');\n middle += (layer.FresnelOpacity !== undefined ? generateAnimVectorProp('FresnelOpacity', layer.FresnelOpacity, 0, 3) : '');\n middle += (layer.FresnelTeamColor !== undefined ? generateAnimVectorProp('FresnelTeamColor', layer.FresnelTeamColor, 0, 3) : '');\n }\n }\n return generateBlockStart('Layer', null, 2) +\n generateStringProp('FilterMode', generateFilterMode(layer.FilterMode), null, 3) +\n (layer.Alpha !== undefined ? generateAnimVectorProp('Alpha', layer.Alpha, 1, 3) : '') +\n (layer.TextureID !== undefined ? generateAnimVectorProp('TextureID', layer.TextureID, null, 3) : '') +\n (layer.Shading & _model__WEBPACK_IMPORTED_MODULE_0__.LayerShading.TwoSided ? generateBooleanProp('TwoSided', 3) : '') +\n (layer.Shading & _model__WEBPACK_IMPORTED_MODULE_0__.LayerShading.Unshaded ? generateBooleanProp('Unshaded', 3) : '') +\n (layer.Shading & _model__WEBPACK_IMPORTED_MODULE_0__.LayerShading.Unfogged ? generateBooleanProp('Unfogged', 3) : '') +\n (layer.Shading & _model__WEBPACK_IMPORTED_MODULE_0__.LayerShading.SphereEnvMap ? generateBooleanProp('SphereEnvMap', 3) : '') +\n (layer.Shading & _model__WEBPACK_IMPORTED_MODULE_0__.LayerShading.NoDepthTest ? generateBooleanProp('NoDepthTest', 3) : '') +\n (layer.Shading & _model__WEBPACK_IMPORTED_MODULE_0__.LayerShading.NoDepthSet ? generateBooleanProp('NoDepthSet', 3) : '') +\n generateIntPropIfNotEmpty('CoordId', layer.CoordId, 0, null, 3) +\n generateIntPropIfNotEmpty('TVertexAnimId', layer.TVertexAnimId, null, null, 3) +\n middle +\n generateBlockEnd(2);\n}\nfunction generateTextureAnims(model) {\n if (!model.TextureAnims.length) {\n return '';\n }\n return generateBlockStart('TextureAnims', model.TextureAnims.length) +\n model.TextureAnims.map(generateTextureAnimChunk).join('') +\n generateBlockEnd();\n}\nfunction generateTextureAnimChunk(textureAnim) {\n return generateBlockStart('TVertexAnim', null, 1) +\n (textureAnim.Translation ? generateAnimVectorProp('Translation', textureAnim.Translation, null, 2) : '') +\n (textureAnim.Rotation ? generateAnimVectorProp('Rotation', textureAnim.Rotation, null, 2) : '') +\n (textureAnim.Scaling ? generateAnimVectorProp('Scaling', textureAnim.Scaling, null, 2) : '') +\n generateBlockEnd(1);\n}\nfunction generateGeosets(model) {\n if (!model.Geosets.length) {\n return '';\n }\n return model.Geosets.map(function (it) { return generateGeosetChunk(model, it); }).join('');\n}\nfunction generateGeosetChunk(model, geoset) {\n var middle = '';\n if (model.Version >= 900) {\n middle += (geoset.LevelOfDetail !== undefined ? generateIntProp('LevelOfDetail', geoset.LevelOfDetail) : '') +\n (geoset.Name ? generateWrappedStringProp('Name', geoset.Name) : '') +\n (geoset.Tangents ? generateGeosetArray('Tangents', geoset.Tangents, 4) : '') +\n (geoset.SkinWeights ? generrateGeosetSkinWeights(geoset.SkinWeights) : '');\n }\n return generateBlockStart('Geoset') +\n generateGeosetArray('Vertices', geoset.Vertices, 3) +\n generateGeosetArray('Normals', geoset.Normals, 3) +\n generateGeosetArray('TVertices', geoset.TVertices[0], 2) +\n generateGeosetVertexGroup(geoset.VertexGroup) +\n generateGeosetFaces(geoset.Faces) +\n generateGeosetGroups(geoset.Groups) +\n generateFloatArrayProp('MinimumExtent', geoset.MinimumExtent) +\n generateFloatArrayProp('MaximumExtent', geoset.MaximumExtent) +\n generateFloatPropIfNotEmpty('BoundsRadius', geoset.BoundsRadius) +\n generateGeosetAnimInfos(geoset.Anims) +\n generateIntProp('MaterialID', geoset.MaterialID) +\n generateIntProp('SelectionGroup', geoset.SelectionGroup) +\n (geoset.Unselectable ? generateBooleanProp('Unselectable') : '') +\n middle +\n generateBlockEnd();\n}\nfunction generateGeosetArray(name, arr, elemLength) {\n var middle = '';\n var elemCount = arr.length / elemLength;\n for (var i = 0; i < elemCount; ++i) {\n middle += generateTab(2) + generateArray(arr.slice(i * elemLength, (i + 1) * elemLength)) + ',\\n';\n }\n return generateBlockStart(name, elemCount, 1) +\n middle +\n generateBlockEnd(1);\n}\nfunction generateGeosetVertexGroup(arr) {\n if (!arr.length) {\n return '';\n }\n var middle = '';\n for (var i = 0; i < arr.length; ++i) {\n middle += generateTab(2) + arr[i] + ',\\n';\n }\n return generateBlockStart('VertexGroup', null, 1) +\n middle +\n generateBlockEnd(1);\n}\nfunction generateGeosetFaces(arr) {\n return generateBlockStart(\"Faces 1 \" + arr.length, null, 1) +\n generateBlockStart('Triangles', null, 2) +\n generateTab(3) + generateUIntArray(arr) + ',\\n' +\n generateBlockEnd(2) +\n generateBlockEnd(1);\n}\nfunction generateGeosetGroups(groups) {\n var totalMatrices = 0;\n var middle = '';\n for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {\n var group = groups_1[_i];\n totalMatrices += group.length;\n middle += generateTab(2) + 'Matrices ' + generateUIntArray(group) + ',\\n';\n }\n return generateBlockStart(\"Groups \" + groups.length + \" \" + totalMatrices, null, 1) +\n middle +\n generateBlockEnd(1);\n}\nfunction generrateGeosetSkinWeights(skinWeights) {\n var res = generateBlockStart('SkinWeights', skinWeights.length / 4, 1);\n for (var i = 0; i < skinWeights.length; ++i) {\n if (i % 8 === 0) {\n res += generateTab(2);\n }\n else {\n res += ' ';\n }\n res += skinWeights[i] + ',';\n if ((i + 1) % 8 === 0) {\n res += '\\n';\n }\n }\n res += generateBlockEnd(1);\n return res;\n}\nfunction generateGeosetAnimInfos(anims) {\n if (!anims) {\n return '';\n }\n return anims.map(generateGeosetAnimInfoChunk).join('');\n}\nfunction generateGeosetAnimInfoChunk(anim) {\n return generateBlockStart('Anim', null, 1) +\n generateFloatArrayProp('MinimumExtent', anim.MinimumExtent, null, 2) +\n generateFloatArrayProp('MaximumExtent', anim.MaximumExtent, null, 2) +\n generateFloatPropIfNotEmpty('BoundsRadius', anim.BoundsRadius, 0, null, 2) +\n generateBlockEnd(1);\n}\nfunction generateGeosetAnims(model) {\n if (!model.GeosetAnims.length) {\n return '';\n }\n return model.GeosetAnims.map(generateGeosetAnimChunk).join('');\n}\nfunction generateColorProp(name, color, isStatic, tabSize) {\n if (tabSize === void 0) { tabSize = 1; }\n if (color) {\n if (color instanceof Float32Array) {\n if (!isStatic || isNotEmptyVec3(color, 1)) {\n var middle = '';\n for (var i = 2; i >= 0; --i) {\n if (i < 2) {\n middle += ', ';\n }\n middle += generateNumber(color[i]);\n }\n return \"\" + generateTab(tabSize) + (isStatic ? 'static ' : '') + name + \" { \" + middle + \" },\\n\";\n }\n }\n else {\n return generateAnimVectorProp(name, color, null, tabSize, true);\n }\n }\n return '';\n}\nfunction generateGeosetAnimChunk(geosetAnim) {\n return generateBlockStart('GeosetAnim') +\n generateIntProp('GeosetId', geosetAnim.GeosetId) +\n generateAnimVectorProp('Alpha', geosetAnim.Alpha, 1) +\n generateColorProp('Color', geosetAnim.Color, true) +\n (geosetAnim.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.GeosetAnimFlags.DropShadow ? generateBooleanProp('DropShadow') : '') +\n generateBlockEnd();\n}\nfunction generateNodeProps(node) {\n return generateIntProp('ObjectId', node.ObjectId) +\n generateIntPropIfNotEmpty('Parent', node.Parent, null) +\n generateNodeDontInherit(node.Flags) +\n (node.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.Billboarded ? generateBooleanProp('Billboarded') : '') +\n (node.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.BillboardedLockX ? generateBooleanProp('BillboardedLockX') : '') +\n (node.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.BillboardedLockY ? generateBooleanProp('BillboardedLockY') : '') +\n (node.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.BillboardedLockZ ? generateBooleanProp('BillboardedLockZ') : '') +\n (node.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.CameraAnchored ? generateBooleanProp('CameraAnchored') : '') +\n (node.Translation !== undefined ? generateAnimVectorProp('Translation', node.Translation) : '') +\n (node.Rotation !== undefined ? generateAnimVectorProp('Rotation', node.Rotation) : '') +\n (node.Scaling !== undefined ? generateAnimVectorProp('Scaling', node.Scaling) : '');\n}\nfunction generateNodeDontInherit(flags) {\n var flagsStrs = [];\n if (flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.DontInheritTranslation) {\n flagsStrs.push('Translation');\n }\n if (flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.DontInheritRotation) {\n flagsStrs.push('Rotation');\n }\n if (flags & _model__WEBPACK_IMPORTED_MODULE_0__.NodeFlags.DontInheritScaling) {\n flagsStrs.push('Scaling');\n }\n if (!flagsStrs.length) {\n return '';\n }\n return generateTab(1) + 'DontInherit { ' + flagsStrs.join(', ') + ' },\\n';\n}\nfunction generateBones(model) {\n if (!model.Bones.length) {\n return '';\n }\n return model.Bones.map(generateBoneChunk).join('');\n}\nfunction generateBoneChunk(bone) {\n return generateBlockStart('Bone', bone.Name) +\n generateNodeProps(bone) +\n (bone.GeosetId !== null ?\n generateIntProp('GeosetId', bone.GeosetId) :\n generateStringProp('GeosetId', 'Multiple')) +\n (bone.GeosetAnimId !== null ?\n generateIntProp('GeosetAnimId', bone.GeosetAnimId) :\n generateStringProp('GeosetAnimId', 'None')) +\n generateBlockEnd();\n}\nfunction generateLights(model) {\n if (!model.Lights.length) {\n return '';\n }\n return model.Lights.map(generateLightChunk).join('');\n}\nfunction generateLightChunk(light) {\n return generateBlockStart('Light', light.Name) +\n generateNodeProps(light) +\n generateBooleanProp(generateLightType(light.LightType)) +\n generateAnimVectorProp('AttenuationStart', light.AttenuationStart) +\n generateAnimVectorProp('AttenuationEnd', light.AttenuationEnd) +\n generateColorProp('Color', light.Color, true) +\n generateAnimVectorProp('Intensity', light.Intensity, null) +\n generateColorProp('AmbColor', light.AmbColor, true) +\n generateAnimVectorProp('AmbIntensity', light.AmbIntensity, null) +\n generateAnimVectorProp('Visibility', light.Visibility, 1) +\n generateBlockEnd();\n}\nfunction generateLightType(lightType) {\n switch (lightType) {\n case _model__WEBPACK_IMPORTED_MODULE_0__.LightType.Omnidirectional:\n return 'Omnidirectional';\n case _model__WEBPACK_IMPORTED_MODULE_0__.LightType.Directional:\n return 'Directional';\n case _model__WEBPACK_IMPORTED_MODULE_0__.LightType.Ambient:\n return 'Ambient';\n }\n return '';\n}\nfunction generateHelpers(model) {\n return model.Helpers.map(generateHelperChunk).join('');\n}\nfunction generateHelperChunk(helper) {\n return generateBlockStart('Helper', helper.Name) +\n generateNodeProps(helper) +\n generateBlockEnd();\n}\nfunction generateAttachments(model) {\n return model.Attachments.map(generateAttachmentChunk).join('');\n}\nfunction generateAttachmentChunk(attachment) {\n return generateBlockStart('Attachment', attachment.Name) +\n generateNodeProps(attachment) +\n generateIntProp('AttachmentID', attachment.AttachmentID) +\n (attachment.Path ? generateWrappedStringProp('Path', attachment.Path) : '') +\n generateAnimVectorProp('Visibility', attachment.Visibility, 1) +\n generateBlockEnd();\n}\nfunction generatePivotPoints(model) {\n return generateBlockStart('PivotPoints', model.PivotPoints.length) +\n model.PivotPoints.map(function (point) { return \"\" + generateTab() + generateArray(point) + \",\\n\"; }).join('') +\n generateBlockEnd();\n}\nfunction generateParticleEmitters(model) {\n return model.ParticleEmitters.map(generateParticleEmitterChunk).join('');\n}\nfunction generateParticleEmitterChunk(emitter) {\n return generateBlockStart('ParticleEmitter', emitter.Name) +\n generateNodeProps(emitter) +\n (emitter.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitterFlags.EmitterUsesMDL ? generateBooleanProp('EmitterUsesMDL') : '') +\n (emitter.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitterFlags.EmitterUsesTGA ? generateBooleanProp('EmitterUsesTGA') : '') +\n generateAnimVectorProp('EmissionRate', emitter.EmissionRate) +\n generateAnimVectorProp('Gravity', emitter.Gravity) +\n generateAnimVectorProp('Longitude', emitter.Longitude) +\n generateAnimVectorProp('Latitude', emitter.Latitude) +\n generateAnimVectorProp('Visibility', emitter.Visibility) +\n generateBlockStart('Particle', null, 1) +\n generateAnimVectorProp('LifeSpan', emitter.LifeSpan, null, 2) +\n generateAnimVectorProp('InitVelocity', emitter.InitVelocity, null, 2) +\n generateWrappedStringProp('Path', emitter.Path, false, 2) +\n generateBlockEnd(1) +\n generateBlockEnd();\n}\nfunction generateParticleEmitters2(model) {\n return model.ParticleEmitters2.map(generateParticleEmitter2Chunk).join('');\n}\nfunction generateParticleEmitters2FilterMode(filterMode) {\n switch (filterMode) {\n case _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FilterMode.Blend:\n return 'Blend';\n case _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FilterMode.Additive:\n return 'Additive';\n case _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FilterMode.Modulate:\n return 'Modulate';\n case _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FilterMode.Modulate2x:\n return 'Modulate2x';\n case _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FilterMode.AlphaKey:\n return 'AlphaKey';\n }\n return '';\n}\nfunction generateSegmentColor(colors) {\n return generateBlockStart('SegmentColor', null, 1) +\n colors.map(function (color) { return generateColorProp('Color', color, false, 2); }).join('') +\n generateTab() + '},\\n';\n}\nfunction generateParticleEmitter2FrameFlags(frameFlags) {\n if (frameFlags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FramesFlags.Head && frameFlags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FramesFlags.Tail) {\n return 'Both';\n }\n else if (frameFlags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FramesFlags.Head) {\n return 'Head';\n }\n else if (frameFlags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2FramesFlags.Tail) {\n return 'Tail';\n }\n return '';\n}\nfunction generateParticleEmitter2Chunk(particleEmitter2) {\n return generateBlockStart('ParticleEmitter2', particleEmitter2.Name) +\n generateNodeProps(particleEmitter2) +\n generateBooleanProp(generateParticleEmitters2FilterMode(particleEmitter2.FilterMode)) +\n generateAnimVectorProp('Speed', particleEmitter2.Speed, null) +\n generateAnimVectorProp('Variation', particleEmitter2.Variation, null) +\n generateAnimVectorProp('Latitude', particleEmitter2.Latitude, null) +\n generateAnimVectorProp('Gravity', particleEmitter2.Gravity, null) +\n generateAnimVectorProp('EmissionRate', particleEmitter2.EmissionRate, null) +\n generateAnimVectorProp('Width', particleEmitter2.Width, null) +\n generateAnimVectorProp('Length', particleEmitter2.Length, null) +\n generateAnimVectorProp('Visibility', particleEmitter2.Visibility, 1) +\n generateSegmentColor(particleEmitter2.SegmentColor) +\n generateUIntArrayProp('Alpha', particleEmitter2.Alpha) +\n generateFloatArrayProp('ParticleScaling', particleEmitter2.ParticleScaling) +\n generateFloatArrayProp('LifeSpanUVAnim', particleEmitter2.LifeSpanUVAnim) +\n generateFloatArrayProp('DecayUVAnim', particleEmitter2.DecayUVAnim) +\n generateFloatArrayProp('TailUVAnim', particleEmitter2.TailUVAnim) +\n generateFloatArrayProp('TailDecayUVAnim', particleEmitter2.TailDecayUVAnim) +\n generateIntPropIfNotEmpty('Rows', particleEmitter2.Rows, 0) +\n generateIntPropIfNotEmpty('Columns', particleEmitter2.Columns, 0) +\n generateIntProp('TextureID', particleEmitter2.TextureID) +\n generateIntPropIfNotEmpty('Time', particleEmitter2.Time, 0) +\n generateIntPropIfNotEmpty('LifeSpan', particleEmitter2.LifeSpan, 0) +\n generateIntPropIfNotEmpty('TailLength', particleEmitter2.TailLength, 0) +\n (particleEmitter2.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2Flags.SortPrimsFarZ ? generateBooleanProp('SortPrimsFarZ') : '') +\n (particleEmitter2.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2Flags.LineEmitter ? generateBooleanProp('LineEmitter') : '') +\n (particleEmitter2.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2Flags.ModelSpace ? generateBooleanProp('ModelSpace') : '') +\n (particleEmitter2.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2Flags.Unshaded ? generateBooleanProp('Unshaded') : '') +\n (particleEmitter2.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2Flags.Unfogged ? generateBooleanProp('Unfogged') : '') +\n (particleEmitter2.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitter2Flags.XYQuad ? generateBooleanProp('XYQuad') : '') +\n (particleEmitter2.Squirt ? generateBooleanProp('Squirt') : '') +\n generateBooleanProp(generateParticleEmitter2FrameFlags(particleEmitter2.FrameFlags)) +\n generateBlockEnd();\n}\nfunction generateRibbonEmitters(model) {\n return model.RibbonEmitters.map(generateRibbonEmitterChunk).join('');\n}\nfunction generateRibbonEmitterChunk(ribbonEmitter) {\n return generateBlockStart('RibbonEmitter', ribbonEmitter.Name) +\n generateNodeProps(ribbonEmitter) +\n generateAnimVectorProp('HeightAbove', ribbonEmitter.HeightAbove, null) +\n generateAnimVectorProp('HeightBelow', ribbonEmitter.HeightBelow, null) +\n generateAnimVectorProp('Alpha', ribbonEmitter.Alpha, null) +\n generateColorProp('Color', ribbonEmitter.Color, true) +\n generateAnimVectorProp('TextureSlot', ribbonEmitter.TextureSlot, null) +\n generateAnimVectorProp('Visibility', ribbonEmitter.Visibility, 1) +\n generateIntProp('EmissionRate', ribbonEmitter.EmissionRate) +\n generateIntProp('LifeSpan', ribbonEmitter.LifeSpan) +\n generateIntPropIfNotEmpty('Gravity', ribbonEmitter.Gravity, 0) +\n generateIntProp('Rows', ribbonEmitter.Rows) +\n generateIntProp('Columns', ribbonEmitter.Columns) +\n generateIntPropIfNotEmpty('MaterialID', ribbonEmitter.MaterialID) +\n generateBlockEnd();\n}\nfunction generateEventObjects(model) {\n return model.EventObjects.map(generateEventObjectChunk).join('');\n}\nfunction generateEventTrack(eventTrack) {\n var middle = '';\n for (var i = 0; i < eventTrack.length; ++i) {\n middle += generateTab(2) + eventTrack[i] + ',\\n';\n }\n return generateBlockStart('EventTrack', eventTrack.length, 1) +\n middle +\n generateBlockEnd(1);\n}\nfunction generateEventObjectChunk(eventObject) {\n return generateBlockStart('EventObject', eventObject.Name) +\n generateNodeProps(eventObject) +\n generateEventTrack(eventObject.EventTrack) +\n generateBlockEnd();\n}\nfunction generateCameras(model) {\n return model.Cameras.map(generateCameraChunk).join('');\n}\nfunction generateCameraChunk(camera) {\n return generateBlockStart('Camera', camera.Name) +\n generateFloatProp('FieldOfView', camera.FieldOfView) +\n generateFloatProp('FarClip', camera.FarClip) +\n generateFloatProp('NearClip', camera.NearClip) +\n generateFloatArrayProp('Position', camera.Position) +\n generateAnimVectorProp('Translation', camera.Translation) +\n generateAnimVectorProp('Rotation', camera.Rotation) +\n generateBlockStart('Target', null, 1) +\n generateFloatArrayProp('Position', camera.TargetPosition, null, 2) +\n generateAnimVectorProp('Translation', camera.TargetTranslation, null, 2) +\n generateBlockEnd(1) +\n generateBlockEnd();\n}\nfunction generateCollisionShapes(model) {\n return model.CollisionShapes.map(generateCollisionShapeChunk).join('');\n}\nfunction generateCollisionShapeChunk(collisionShape) {\n var middle = '';\n if (collisionShape.Shape === _model__WEBPACK_IMPORTED_MODULE_0__.CollisionShapeType.Box) {\n middle = generateBooleanProp('Box');\n middle += generateBlockStart('Vertices', 2, 1) +\n generateTab(2) + generateArray(collisionShape.Vertices.slice(0, 3)) + ',\\n' +\n generateTab(2) + generateArray(collisionShape.Vertices.slice(3, 6)) + ',\\n' +\n generateBlockEnd(1);\n }\n else {\n middle = generateBooleanProp('Sphere');\n middle += generateBlockStart('Vertices', 1, 1) +\n generateTab(2) + generateArray(collisionShape.Vertices) + ',\\n' +\n generateBlockEnd(1) +\n generateFloatProp('BoundsRadius', collisionShape.BoundsRadius);\n }\n return generateBlockStart('CollisionShape', collisionShape.Name) +\n generateNodeProps(collisionShape) +\n middle +\n generateBlockEnd();\n}\nfunction generateFaceFX(model) {\n if (model.Version < 900 || !model.FaceFX) {\n return '';\n }\n return model.FaceFX.map(generateFaceFXChunk).join('');\n}\nfunction generateFaceFXChunk(faceFX) {\n return generateBlockStart('FaceFX', faceFX.Name) +\n generateWrappedStringProp('Path', faceFX.Path) +\n generateBlockEnd();\n}\nfunction generateBindPose(model) {\n if (model.Version < 900 || !model.BindPoses) {\n return '';\n }\n return model.BindPoses.map(generateBindPoseChunk).join('');\n}\nfunction generateBindPoseChunk(bindPose) {\n var middle = generateBlockStart('Matrices', bindPose.Matrices.length, 1) +\n bindPose.Matrices.map(function (item) {\n return generateTab(2) + generateArray(item);\n }).join('\\n') + '\\n' +\n generateBlockEnd(1);\n return generateBlockStart('BindPose') +\n middle +\n generateBlockEnd();\n}\nfunction generateParticleEmitterPopcorn(model) {\n if (model.Version < 900 || !model.ParticleEmitterPopcorns) {\n return '';\n }\n return model.ParticleEmitterPopcorns.map(generateParticleEmitterPopcornChunk).join('');\n}\nfunction generateParticleEmitterPopcornChunk(emitter) {\n return generateBlockStart('ParticleEmitterPopcorn', emitter.Name) +\n generateNodeProps(emitter) +\n (emitter.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitterPopcornFlags.Unshaded ? generateBooleanProp('Unshaded') : '') +\n (emitter.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitterPopcornFlags.SortPrimsFarZ ? generateBooleanProp('SortPrimsFarZ') : '') +\n (emitter.Flags & _model__WEBPACK_IMPORTED_MODULE_0__.ParticleEmitterPopcornFlags.Unfogged ? generateBooleanProp('Unfogged') : '') +\n generateAnimVectorProp('LifeSpan', emitter.LifeSpan, null) +\n generateAnimVectorProp('EmissionRate', emitter.EmissionRate, 0) +\n generateAnimVectorProp('Speed', emitter.Speed, 0) +\n generateColorProp('Color', emitter.Color, true) +\n generateAnimVectorProp('Alpha', emitter.Alpha, 1) +\n generateIntPropIfNotEmpty('ReplaceableId', emitter.ReplaceableId, 0, null) +\n generateWrappedStringProp('Path', emitter.Path, false) +\n generateWrappedStringProp('AnimVisibilityGuide', emitter.AnimVisibilityGuide, false) +\n generateAnimVectorProp('Visibility', emitter.Visibility) +\n generateBlockEnd();\n}\nvar generators = [\n generateVersion,\n generateModel,\n generateSequences,\n generateGlobalSequences,\n generateTextures,\n generateMaterials,\n generateTextureAnims,\n generateGeosets,\n generateGeosetAnims,\n generateBones,\n generateLights,\n generateHelpers,\n generateAttachments,\n generatePivotPoints,\n generateParticleEmitters,\n generateParticleEmitters2,\n generateRibbonEmitters,\n generateEventObjects,\n generateCameras,\n generateCollisionShapes,\n generateFaceFX,\n generateBindPose,\n generateParticleEmitterPopcorn\n];\nfunction generate(model) {\n var res = '';\n for (var _i = 0, generators_1 = generators; _i < gen