war3-model
Version:
Warcraft 3 model parser, generator, convertor and previewer
1,449 lines • 487 kB
JavaScript
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.war3model = {}));
})(this, function(exports2) {
"use strict";
var TextureFlags = /* @__PURE__ */ ((TextureFlags2) => {
TextureFlags2[TextureFlags2["WrapWidth"] = 1] = "WrapWidth";
TextureFlags2[TextureFlags2["WrapHeight"] = 2] = "WrapHeight";
return TextureFlags2;
})(TextureFlags || {});
var FilterMode = /* @__PURE__ */ ((FilterMode2) => {
FilterMode2[FilterMode2["None"] = 0] = "None";
FilterMode2[FilterMode2["Transparent"] = 1] = "Transparent";
FilterMode2[FilterMode2["Blend"] = 2] = "Blend";
FilterMode2[FilterMode2["Additive"] = 3] = "Additive";
FilterMode2[FilterMode2["AddAlpha"] = 4] = "AddAlpha";
FilterMode2[FilterMode2["Modulate"] = 5] = "Modulate";
FilterMode2[FilterMode2["Modulate2x"] = 6] = "Modulate2x";
return FilterMode2;
})(FilterMode || {});
var LineType = /* @__PURE__ */ ((LineType2) => {
LineType2[LineType2["DontInterp"] = 0] = "DontInterp";
LineType2[LineType2["Linear"] = 1] = "Linear";
LineType2[LineType2["Hermite"] = 2] = "Hermite";
LineType2[LineType2["Bezier"] = 3] = "Bezier";
return LineType2;
})(LineType || {});
var LayerShading = /* @__PURE__ */ ((LayerShading2) => {
LayerShading2[LayerShading2["Unshaded"] = 1] = "Unshaded";
LayerShading2[LayerShading2["SphereEnvMap"] = 2] = "SphereEnvMap";
LayerShading2[LayerShading2["TwoSided"] = 16] = "TwoSided";
LayerShading2[LayerShading2["Unfogged"] = 32] = "Unfogged";
LayerShading2[LayerShading2["NoDepthTest"] = 64] = "NoDepthTest";
LayerShading2[LayerShading2["NoDepthSet"] = 128] = "NoDepthSet";
return LayerShading2;
})(LayerShading || {});
var MaterialRenderMode = /* @__PURE__ */ ((MaterialRenderMode2) => {
MaterialRenderMode2[MaterialRenderMode2["ConstantColor"] = 1] = "ConstantColor";
MaterialRenderMode2[MaterialRenderMode2["SortPrimsFarZ"] = 16] = "SortPrimsFarZ";
MaterialRenderMode2[MaterialRenderMode2["FullResolution"] = 32] = "FullResolution";
return MaterialRenderMode2;
})(MaterialRenderMode || {});
var GeosetAnimFlags = /* @__PURE__ */ ((GeosetAnimFlags2) => {
GeosetAnimFlags2[GeosetAnimFlags2["DropShadow"] = 1] = "DropShadow";
GeosetAnimFlags2[GeosetAnimFlags2["Color"] = 2] = "Color";
return GeosetAnimFlags2;
})(GeosetAnimFlags || {});
var NodeFlags = /* @__PURE__ */ ((NodeFlags2) => {
NodeFlags2[NodeFlags2["DontInheritTranslation"] = 1] = "DontInheritTranslation";
NodeFlags2[NodeFlags2["DontInheritRotation"] = 2] = "DontInheritRotation";
NodeFlags2[NodeFlags2["DontInheritScaling"] = 4] = "DontInheritScaling";
NodeFlags2[NodeFlags2["Billboarded"] = 8] = "Billboarded";
NodeFlags2[NodeFlags2["BillboardedLockX"] = 16] = "BillboardedLockX";
NodeFlags2[NodeFlags2["BillboardedLockY"] = 32] = "BillboardedLockY";
NodeFlags2[NodeFlags2["BillboardedLockZ"] = 64] = "BillboardedLockZ";
NodeFlags2[NodeFlags2["CameraAnchored"] = 128] = "CameraAnchored";
return NodeFlags2;
})(NodeFlags || {});
var NodeType = /* @__PURE__ */ ((NodeType2) => {
NodeType2[NodeType2["Helper"] = 0] = "Helper";
NodeType2[NodeType2["Bone"] = 256] = "Bone";
NodeType2[NodeType2["Light"] = 512] = "Light";
NodeType2[NodeType2["EventObject"] = 1024] = "EventObject";
NodeType2[NodeType2["Attachment"] = 2048] = "Attachment";
NodeType2[NodeType2["ParticleEmitter"] = 4096] = "ParticleEmitter";
NodeType2[NodeType2["CollisionShape"] = 8192] = "CollisionShape";
NodeType2[NodeType2["RibbonEmitter"] = 16384] = "RibbonEmitter";
return NodeType2;
})(NodeType || {});
var CollisionShapeType = /* @__PURE__ */ ((CollisionShapeType2) => {
CollisionShapeType2[CollisionShapeType2["Box"] = 0] = "Box";
CollisionShapeType2[CollisionShapeType2["Sphere"] = 2] = "Sphere";
return CollisionShapeType2;
})(CollisionShapeType || {});
var ParticleEmitterFlags = /* @__PURE__ */ ((ParticleEmitterFlags2) => {
ParticleEmitterFlags2[ParticleEmitterFlags2["EmitterUsesMDL"] = 32768] = "EmitterUsesMDL";
ParticleEmitterFlags2[ParticleEmitterFlags2["EmitterUsesTGA"] = 65536] = "EmitterUsesTGA";
return ParticleEmitterFlags2;
})(ParticleEmitterFlags || {});
var ParticleEmitter2Flags = /* @__PURE__ */ ((ParticleEmitter2Flags2) => {
ParticleEmitter2Flags2[ParticleEmitter2Flags2["Unshaded"] = 32768] = "Unshaded";
ParticleEmitter2Flags2[ParticleEmitter2Flags2["SortPrimsFarZ"] = 65536] = "SortPrimsFarZ";
ParticleEmitter2Flags2[ParticleEmitter2Flags2["LineEmitter"] = 131072] = "LineEmitter";
ParticleEmitter2Flags2[ParticleEmitter2Flags2["Unfogged"] = 262144] = "Unfogged";
ParticleEmitter2Flags2[ParticleEmitter2Flags2["ModelSpace"] = 524288] = "ModelSpace";
ParticleEmitter2Flags2[ParticleEmitter2Flags2["XYQuad"] = 1048576] = "XYQuad";
return ParticleEmitter2Flags2;
})(ParticleEmitter2Flags || {});
var ParticleEmitter2FilterMode = /* @__PURE__ */ ((ParticleEmitter2FilterMode2) => {
ParticleEmitter2FilterMode2[ParticleEmitter2FilterMode2["Blend"] = 0] = "Blend";
ParticleEmitter2FilterMode2[ParticleEmitter2FilterMode2["Additive"] = 1] = "Additive";
ParticleEmitter2FilterMode2[ParticleEmitter2FilterMode2["Modulate"] = 2] = "Modulate";
ParticleEmitter2FilterMode2[ParticleEmitter2FilterMode2["Modulate2x"] = 3] = "Modulate2x";
ParticleEmitter2FilterMode2[ParticleEmitter2FilterMode2["AlphaKey"] = 4] = "AlphaKey";
return ParticleEmitter2FilterMode2;
})(ParticleEmitter2FilterMode || {});
var ParticleEmitter2FramesFlags = /* @__PURE__ */ ((ParticleEmitter2FramesFlags2) => {
ParticleEmitter2FramesFlags2[ParticleEmitter2FramesFlags2["Head"] = 1] = "Head";
ParticleEmitter2FramesFlags2[ParticleEmitter2FramesFlags2["Tail"] = 2] = "Tail";
return ParticleEmitter2FramesFlags2;
})(ParticleEmitter2FramesFlags || {});
var LightType = /* @__PURE__ */ ((LightType2) => {
LightType2[LightType2["Omnidirectional"] = 0] = "Omnidirectional";
LightType2[LightType2["Directional"] = 1] = "Directional";
LightType2[LightType2["Ambient"] = 2] = "Ambient";
return LightType2;
})(LightType || {});
var ParticleEmitterPopcornFlags = /* @__PURE__ */ ((ParticleEmitterPopcornFlags2) => {
ParticleEmitterPopcornFlags2[ParticleEmitterPopcornFlags2["Unshaded"] = 32768] = "Unshaded";
ParticleEmitterPopcornFlags2[ParticleEmitterPopcornFlags2["SortPrimsFarZ"] = 65536] = "SortPrimsFarZ";
ParticleEmitterPopcornFlags2[ParticleEmitterPopcornFlags2["Unfogged"] = 262144] = "Unfogged";
return ParticleEmitterPopcornFlags2;
})(ParticleEmitterPopcornFlags || {});
const model = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
CollisionShapeType,
FilterMode,
GeosetAnimFlags,
LayerShading,
LightType,
LineType,
MaterialRenderMode,
NodeFlags,
NodeType,
ParticleEmitter2FilterMode,
ParticleEmitter2Flags,
ParticleEmitter2FramesFlags,
ParticleEmitterFlags,
ParticleEmitterPopcornFlags,
TextureFlags
}, Symbol.toStringTag, { value: "Module" }));
function mat4fromRotationOrigin(out, rotation2, origin) {
const x = rotation2[0], y = rotation2[1], z = rotation2[2], w = rotation2[3], x2 = x + x, y2 = y + y, z2 = z + z, xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2, ox = origin[0], oy = origin[1], oz = origin[2];
out[0] = 1 - (yy + zz);
out[1] = xy + wz;
out[2] = xz - wy;
out[3] = 0;
out[4] = xy - wz;
out[5] = 1 - (xx + zz);
out[6] = yz + wx;
out[7] = 0;
out[8] = xz + wy;
out[9] = yz - wx;
out[10] = 1 - (xx + yy);
out[11] = 0;
out[12] = ox - (out[0] * ox + out[4] * oy + out[8] * oz);
out[13] = oy - (out[1] * ox + out[5] * oy + out[9] * oz);
out[14] = oz - (out[2] * ox + out[6] * oy + out[10] * oz);
out[15] = 1;
return out;
}
function rand(from, to) {
return from + Math.random() * (to - from);
}
function degToRad(angle) {
return angle * Math.PI / 180;
}
function getShader(gl, source, type) {
const shader2 = gl.createShader(type);
gl.shaderSource(shader2, source);
gl.compileShader(shader2);
if (!gl.getShaderParameter(shader2, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader2));
return null;
}
return shader2;
}
function isWebGL2(gl) {
return gl instanceof WebGL2RenderingContext;
}
const LAYER_TEXTURE_NAME_MAP = {
"TextureID": 0,
"NormalTextureID": 1,
"ORMTextureID": 2,
"EmissiveTextureID": 3,
"TeamColorTextureID": 4,
"ReflectionsTextureID": 5
};
const LAYER_TEXTURE_ID_MAP = [
"TextureID",
"NormalTextureID",
"ORMTextureID",
"EmissiveTextureID",
"TeamColorTextureID",
"ReflectionsTextureID"
];
let State$1 = class State {
constructor(str) {
this.str = str;
this.pos = 0;
}
char() {
if (this.pos >= this.str.length) {
throwError(this, "incorrect model data");
}
return this.str[this.pos];
}
};
function throwError(state, str = "") {
throw new Error(`SyntaxError, near ${state.pos}` + (str ? ", " + str : ""));
}
function parseComment(state) {
if (state.char() === "/" && state.str[state.pos + 1] === "/") {
state.pos += 2;
while (state.pos < state.str.length && state.str[++state.pos] !== "\n") ;
++state.pos;
return true;
}
return false;
}
const spaceRE = /\s/i;
function parseSpace(state) {
while (state.pos < state.str.length && spaceRE.test(state.char())) {
++state.pos;
}
}
const keywordFirstCharRE = /[a-z]/i;
const keywordOtherCharRE = /[a-z0-9]/i;
function parseKeyword(state) {
if (!keywordFirstCharRE.test(state.char())) {
return null;
}
let keyword2 = state.char();
++state.pos;
while (keywordOtherCharRE.test(state.char())) {
keyword2 += state.str[state.pos++];
}
parseSpace(state);
return keyword2;
}
function parseSymbol(state, symbol) {
if (state.char() === symbol) {
++state.pos;
parseSpace(state);
}
}
function strictParseSymbol(state, symbol) {
if (state.char() !== symbol) {
throwError(state, `extected ${symbol}`);
}
++state.pos;
parseSpace(state);
}
function parseString(state) {
if (state.char() === '"') {
const start = ++state.pos;
while (state.char() !== '"') {
++state.pos;
}
++state.pos;
const res = state.str.substring(start, state.pos - 1);
parseSpace(state);
return res;
}
return null;
}
const numberFirstCharRE = /[-0-9]/;
const numberOtherCharRE = /[-+.0-9e]/i;
function parseNumber(state) {
if (numberFirstCharRE.test(state.char())) {
const start = state.pos;
++state.pos;
while (numberOtherCharRE.test(state.char())) {
++state.pos;
}
const res = parseFloat(state.str.substring(start, state.pos));
parseSpace(state);
return res;
}
return null;
}
function parseArray(state, arr, pos) {
if (state.char() !== "{") {
return null;
}
if (!arr) {
arr = [];
pos = 0;
}
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const num = parseNumber(state);
if (num === null) {
throwError(state, "expected number");
}
arr[pos++] = num;
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
return arr;
}
function parseArrayCounted(state, arr, pos) {
if (state.char() !== "{") {
return 0;
}
const start = pos;
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const num = parseNumber(state);
if (num === null) {
throwError(state, "expected number");
}
arr[pos++] = num;
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
return pos - start;
}
function parseArrayOrSingleItem(state, arr) {
if (state.char() !== "{") {
arr[0] = parseNumber(state);
return arr;
}
let pos = 0;
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const num = parseNumber(state);
if (num === null) {
throwError(state, "expected number");
}
arr[pos++] = num;
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
return arr;
}
function parseObject(state) {
let prefix = null;
const obj = {};
if (state.char() !== "{") {
prefix = parseString(state);
if (prefix === null) {
prefix = parseNumber(state);
}
if (prefix === null) {
throwError(state, "expected string or number");
}
}
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Interval") {
const array = new Uint32Array(2);
obj[keyword2] = parseArray(state, array, 0);
} else if (keyword2 === "MinimumExtent" || keyword2 === "MaximumExtent") {
const array = new Float32Array(3);
obj[keyword2] = parseArray(state, array, 0);
} else {
obj[keyword2] = parseArray(state) || parseString(state);
if (obj[keyword2] === null) {
obj[keyword2] = parseNumber(state);
}
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
return [prefix, obj];
}
function parseVersion$1(state, model2) {
const [_unused, obj] = parseObject(state);
if (obj.FormatVersion) {
model2.Version = obj.FormatVersion;
}
}
function parseModelInfo$1(state, model2) {
const [name, obj] = parseObject(state);
model2.Info = obj;
model2.Info.Name = name;
}
function parseSequences$1(state, model2) {
parseNumber(state);
strictParseSymbol(state, "{");
const res = [];
while (state.char() !== "}") {
parseKeyword(state);
const [name, obj] = parseObject(state);
obj.Name = name;
obj.NonLooping = "NonLooping" in obj;
obj.MoveSpeed = obj.MoveSpeed || 0;
obj.Rarity = obj.Rarity || 0;
res.push(obj);
}
strictParseSymbol(state, "}");
model2.Sequences = res;
}
function parseTextures$1(state, model2) {
const res = [];
parseNumber(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
parseKeyword(state);
const [_unused, obj] = parseObject(state);
obj.Flags = 0;
if ("WrapWidth" in obj) {
obj.Flags += TextureFlags.WrapWidth;
delete obj.WrapWidth;
}
if ("WrapHeight" in obj) {
obj.Flags += TextureFlags.WrapHeight;
delete obj.WrapHeight;
}
res.push(obj);
}
strictParseSymbol(state, "}");
model2.Textures = res;
}
const animVectorSize$2 = {
[
0
/* INT1 */
]: 1,
[
1
/* FLOAT1 */
]: 1,
[
2
/* FLOAT3 */
]: 3,
[
3
/* FLOAT4 */
]: 4
};
function parseAnimKeyframe(state, frame, type, lineType) {
const res = {
Frame: frame,
Vector: null
};
const Vector = type === 0 ? Int32Array : Float32Array;
const itemCount = animVectorSize$2[type];
res.Vector = parseArrayOrSingleItem(state, new Vector(itemCount));
strictParseSymbol(state, ",");
if (lineType === LineType.Hermite || lineType === LineType.Bezier) {
parseKeyword(state);
res.InTan = parseArrayOrSingleItem(state, new Vector(itemCount));
strictParseSymbol(state, ",");
parseKeyword(state);
res.OutTan = parseArrayOrSingleItem(state, new Vector(itemCount));
strictParseSymbol(state, ",");
}
return res;
}
function parseAnimVector(state, type) {
const animVector = {
LineType: LineType.DontInterp,
GlobalSeqId: null,
Keys: []
};
parseNumber(state);
strictParseSymbol(state, "{");
const lineType = parseKeyword(state);
if (lineType === "DontInterp" || lineType === "Linear" || lineType === "Hermite" || lineType === "Bezier") {
animVector.LineType = LineType[lineType];
}
strictParseSymbol(state, ",");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (keyword2 === "GlobalSeqId") {
animVector[keyword2] = parseNumber(state);
strictParseSymbol(state, ",");
} else {
const frame = parseNumber(state);
if (frame === null) {
throwError(state, "expected frame number or GlobalSeqId");
}
strictParseSymbol(state, ":");
animVector.Keys.push(parseAnimKeyframe(state, frame, type, animVector.LineType));
}
}
strictParseSymbol(state, "}");
return animVector;
}
function parseLayer(state, model2) {
const res = {
Alpha: null,
TVertexAnimId: null,
Shading: 0,
CoordId: 0
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (!isStatic && (keyword2 === "TextureID" || model2.Version >= 1100 && keyword2 in LAYER_TEXTURE_NAME_MAP)) {
res[keyword2] = parseAnimVector(
state,
0
/* INT1 */
);
} else if (!isStatic && keyword2 === "Alpha") {
res[keyword2] = parseAnimVector(
state,
1
/* FLOAT1 */
);
} else if (keyword2 === "Unshaded" || keyword2 === "SphereEnvMap" || keyword2 === "TwoSided" || keyword2 === "Unfogged" || keyword2 === "NoDepthTest" || keyword2 === "NoDepthSet") {
res.Shading |= LayerShading[keyword2];
} else if (keyword2 === "FilterMode") {
const val = parseKeyword(state);
if (val === "None" || val === "Transparent" || val === "Blend" || val === "Additive" || val === "AddAlpha" || val === "Modulate" || val === "Modulate2x") {
res.FilterMode = FilterMode[val];
}
} else if (keyword2 === "TVertexAnimId") {
res.TVertexAnimId = parseNumber(state);
} else if (model2.Version >= 900 && keyword2 === "EmissiveGain") {
if (isStatic) {
res[keyword2] = parseNumber(state);
} else {
res[keyword2] = parseAnimVector(
state,
1
/* FLOAT1 */
);
}
} else if (model2.Version >= 1e3 && keyword2 === "FresnelColor") {
if (isStatic) {
const array = new Float32Array(3);
res[keyword2] = parseArray(state, array, 0);
} else {
res[keyword2] = parseAnimVector(
state,
2
/* FLOAT3 */
);
}
} else if (model2.Version >= 1e3 && (keyword2 === "FresnelOpacity" || keyword2 === "FresnelTeamColor")) {
if (isStatic) {
res[keyword2] = parseNumber(state);
} else {
res[keyword2] = parseAnimVector(
state,
1
/* FLOAT1 */
);
}
} else {
let val = parseNumber(state);
if (val === null) {
val = parseKeyword(state);
}
res[keyword2] = val;
}
parseSymbol(state, ",");
parseComment(state);
parseSpace(state);
}
strictParseSymbol(state, "}");
return res;
}
function parseMaterials$1(state, model2) {
const res = [];
parseNumber(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const obj = {
RenderMode: 0,
Layers: []
};
parseKeyword(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Layer") {
obj.Layers.push(parseLayer(state, model2));
} else if (keyword2 === "PriorityPlane" || keyword2 === "RenderMode") {
obj[keyword2] = parseNumber(state);
} else if (keyword2 === "ConstantColor" || keyword2 === "SortPrimsFarZ" || keyword2 === "FullResolution") {
obj.RenderMode |= MaterialRenderMode[keyword2];
} else if (model2.Version >= 900 && model2.Version <= 1100 && keyword2 === "Shader") {
obj[keyword2] = parseString(state);
} else {
throw new Error("Unknown material property " + keyword2);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
res.push(obj);
}
strictParseSymbol(state, "}");
model2.Materials = res;
}
function parseGeosetPart(state, countPerObj, type) {
const count = parseNumber(state);
const arr = new (type === 1 ? Float32Array : Uint8Array)(count * countPerObj);
strictParseSymbol(state, "{");
for (let index = 0; index < count; ++index) {
parseArray(state, arr, index * countPerObj);
strictParseSymbol(state, ",");
}
strictParseSymbol(state, "}");
return arr;
}
function parseGeoset(state, model2) {
const res = {
Vertices: null,
Normals: null,
TVertices: [],
VertexGroup: new Uint8Array(0),
Faces: null,
Groups: null,
TotalGroupsCount: null,
MinimumExtent: null,
MaximumExtent: null,
BoundsRadius: 0,
Anims: [],
MaterialID: null,
SelectionGroup: null,
Unselectable: false
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Vertices" || keyword2 === "Normals" || keyword2 === "TVertices") {
let countPerObj = 3;
if (keyword2 === "TVertices") {
countPerObj = 2;
}
const arr = parseGeosetPart(
state,
countPerObj,
1
/* FLOAT */
);
if (keyword2 === "TVertices") {
res.TVertices.push(arr);
} else {
res[keyword2] = arr;
}
} else if (keyword2 === "VertexGroup") {
res[keyword2] = new Uint8Array(res.Vertices.length / 3);
parseArray(state, res[keyword2], 0);
} else if (keyword2 === "Faces") {
const groupCount = parseNumber(state);
const indexCount = parseNumber(state);
let pos = 0;
res.Faces = new Uint16Array(indexCount);
strictParseSymbol(state, "{");
const keyword22 = parseKeyword(state);
if (keyword22 !== "Triangles") {
throwError(state, "unexpected faces type");
}
strictParseSymbol(state, "{");
for (let g = 0; g < groupCount; ++g) {
const count = parseArrayCounted(state, res.Faces, pos);
if (!count) {
throwError(state, "expected array");
}
pos += count;
parseSymbol(state, ",");
}
if (pos !== indexCount || indexCount % 3 !== 0) {
throwError(state, "mismatched faces array");
}
strictParseSymbol(state, "}");
strictParseSymbol(state, "}");
} else if (keyword2 === "Groups") {
const groups = [];
parseNumber(state);
res.TotalGroupsCount = parseNumber(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
parseKeyword(state);
groups.push(parseArray(state));
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
res.Groups = groups;
} else if (keyword2 === "MinimumExtent" || keyword2 === "MaximumExtent") {
const arr = new Float32Array(3);
res[keyword2] = parseArray(state, arr, 0);
strictParseSymbol(state, ",");
} else if (keyword2 === "BoundsRadius" || keyword2 === "MaterialID" || keyword2 === "SelectionGroup") {
res[keyword2] = parseNumber(state);
strictParseSymbol(state, ",");
} else if (keyword2 === "Anim") {
const [_unused, obj] = parseObject(state);
if (obj.Alpha === void 0) {
obj.Alpha = 1;
}
res.Anims.push(obj);
} else if (keyword2 === "Unselectable") {
res.Unselectable = true;
strictParseSymbol(state, ",");
} else if (model2.Version >= 900) {
if (keyword2 === "LevelOfDetail") {
res.LevelOfDetail = parseNumber(state);
strictParseSymbol(state, ",");
} else if (keyword2 === "Name") {
res.Name = parseString(state);
strictParseSymbol(state, ",");
} else if (keyword2 === "Tangents") {
res.Tangents = parseGeosetPart(
state,
4,
1
/* FLOAT */
);
} else if (keyword2 === "SkinWeights") {
res.SkinWeights = parseGeosetPart(
state,
8,
0
/* INT */
);
}
}
}
strictParseSymbol(state, "}");
model2.Geosets.push(res);
}
function parseGeosetAnim(state, model2) {
const res = {
GeosetId: -1,
Alpha: 1,
Color: null,
Flags: 0
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (keyword2 === "Alpha") {
if (isStatic) {
res.Alpha = parseNumber(state);
} else {
res.Alpha = parseAnimVector(
state,
1
/* FLOAT1 */
);
}
} else if (keyword2 === "Color") {
if (isStatic) {
const array = new Float32Array(3);
res.Color = parseArray(state, array, 0);
res.Color.reverse();
} else {
res.Color = parseAnimVector(
state,
2
/* FLOAT3 */
);
for (const key of res.Color.Keys) {
key.Vector.reverse();
if (key.InTan) {
key.InTan.reverse();
key.OutTan.reverse();
}
}
}
} else if (keyword2 === "DropShadow") {
res.Flags |= GeosetAnimFlags[keyword2];
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.GeosetAnims.push(res);
}
function parseNode$1(state, type, model2) {
const name = parseString(state);
const node = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
Flags: NodeType[type]
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling" || keyword2 === "Visibility") {
let vectorType = 2;
if (keyword2 === "Rotation") {
vectorType = 3;
} else if (keyword2 === "Visibility") {
vectorType = 1;
}
node[keyword2] = parseAnimVector(state, vectorType);
} else if (keyword2 === "BillboardedLockZ" || keyword2 === "BillboardedLockY" || keyword2 === "BillboardedLockX" || keyword2 === "Billboarded" || keyword2 === "CameraAnchored") {
node.Flags |= NodeFlags[keyword2];
} else if (keyword2 === "DontInherit") {
strictParseSymbol(state, "{");
const val = parseKeyword(state);
if (val === "Translation") {
node.Flags |= NodeFlags.DontInheritTranslation;
} else if (val === "Rotation") {
node.Flags |= NodeFlags.DontInheritRotation;
} else if (val === "Scaling") {
node.Flags |= NodeFlags.DontInheritScaling;
}
strictParseSymbol(state, "}");
} else if (keyword2 === "Path") {
node[keyword2] = parseString(state);
} else {
let val = parseKeyword(state) || parseNumber(state);
if (keyword2 === "GeosetId" && val === "Multiple" || keyword2 === "GeosetAnimId" && val === "None") {
val = null;
}
node[keyword2] = val;
}
parseSymbol(state, ",");
parseComment(state);
parseSpace(state);
}
strictParseSymbol(state, "}");
model2.Nodes[node.ObjectId] = node;
return node;
}
function parseBone(state, model2) {
const node = parseNode$1(state, "Bone", model2);
model2.Bones.push(node);
}
function parseHelper(state, model2) {
const node = parseNode$1(state, "Helper", model2);
model2.Helpers.push(node);
}
function parseAttachment(state, model2) {
const node = parseNode$1(state, "Attachment", model2);
model2.Attachments.push(node);
}
function parsePivotPoints$1(state, model2) {
const count = parseNumber(state);
const res = [];
strictParseSymbol(state, "{");
for (let i = 0; i < count; ++i) {
res.push(parseArray(state, new Float32Array(3), 0));
strictParseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.PivotPoints = res;
}
function parseEventObject(state, model2) {
const name = parseString(state);
const res = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
EventTrack: null,
Flags: NodeType.EventObject
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "EventTrack") {
const count = parseNumber(state);
res.EventTrack = parseArray(state, new Uint32Array(count), 0);
} else if (keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling") {
const type = keyword2 === "Rotation" ? 3 : 2;
res[keyword2] = parseAnimVector(state, type);
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.EventObjects.push(res);
model2.Nodes[res.ObjectId] = res;
}
function parseCollisionShape(state, model2) {
const name = parseString(state);
const res = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
Shape: CollisionShapeType.Box,
Vertices: null,
Flags: NodeType.CollisionShape
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Sphere") {
res.Shape = CollisionShapeType.Sphere;
} else if (keyword2 === "Box") {
res.Shape = CollisionShapeType.Box;
} else if (keyword2 === "Vertices") {
const count = parseNumber(state);
const vertices = new Float32Array(count * 3);
strictParseSymbol(state, "{");
for (let i = 0; i < count; ++i) {
parseArray(state, vertices, i * 3);
strictParseSymbol(state, ",");
}
strictParseSymbol(state, "}");
res.Vertices = vertices;
} else if (keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling") {
const type = keyword2 === "Rotation" ? 3 : 2;
res[keyword2] = parseAnimVector(state, type);
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.CollisionShapes.push(res);
model2.Nodes[res.ObjectId] = res;
}
function parseGlobalSequences$1(state, model2) {
const res = [];
const count = parseNumber(state);
strictParseSymbol(state, "{");
for (let i = 0; i < count; ++i) {
const keyword2 = parseKeyword(state);
if (keyword2 === "Duration") {
res.push(parseNumber(state));
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.GlobalSequences = res;
}
function parseUnknownBlock(state) {
let opened;
while (state.char() !== void 0 && state.char() !== "{") {
++state.pos;
}
opened = 1;
++state.pos;
while (state.char() !== void 0 && opened > 0) {
if (state.char() === "{") {
++opened;
} else if (state.char() === "}") {
--opened;
}
++state.pos;
}
parseSpace(state);
}
function parseParticleEmitter(state, model2) {
const res = {
ObjectId: null,
Parent: null,
Name: null,
Flags: 0
};
res.Name = parseString(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (keyword2 === "ObjectId" || keyword2 === "Parent") {
res[keyword2] = parseNumber(state);
} else if (keyword2 === "EmitterUsesMDL" || keyword2 === "EmitterUsesTGA") {
res.Flags |= ParticleEmitterFlags[keyword2];
} else if (!isStatic && (keyword2 === "Visibility" || keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling" || keyword2 === "EmissionRate" || keyword2 === "Gravity" || keyword2 === "Longitude" || keyword2 === "Latitude")) {
let type = 2;
if (keyword2 === "Visibility" || keyword2 === "EmissionRate" || keyword2 === "Gravity" || keyword2 === "Longitude" || keyword2 === "Latitude") {
type = 1;
} else if (keyword2 === "Rotation") {
type = 3;
}
res[keyword2] = parseAnimVector(state, type);
} else if (keyword2 === "Particle") {
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword22 = parseKeyword(state);
let isStatic2 = false;
if (keyword22 === "static") {
isStatic2 = true;
keyword22 = parseKeyword(state);
}
if (!isStatic2 && (keyword22 === "LifeSpan" || keyword22 === "InitVelocity")) {
res[keyword22] = parseAnimVector(
state,
1
/* FLOAT1 */
);
} else if (keyword22 === "LifeSpan" || keyword22 === "InitVelocity") {
res[keyword22] = parseNumber(state);
} else if (keyword22 === "Path") {
res.Path = parseString(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.ParticleEmitters.push(res);
}
function parseParticleEmitter2(state, model2) {
const name = parseString(state);
const res = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
Flags: NodeType.ParticleEmitter,
FrameFlags: 0
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (!isStatic && (keyword2 === "Speed" || keyword2 === "Latitude" || keyword2 === "Visibility" || keyword2 === "EmissionRate" || keyword2 === "Width" || keyword2 === "Length" || keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling" || keyword2 === "Gravity" || keyword2 === "Variation")) {
let type = 2;
switch (keyword2) {
case "Rotation":
type = 3;
break;
case "Speed":
case "Latitude":
case "Visibility":
case "EmissionRate":
case "Width":
case "Length":
case "Gravity":
case "Variation":
type = 1;
break;
}
res[keyword2] = parseAnimVector(state, type);
} else if (keyword2 === "Variation" || keyword2 === "Gravity" || keyword2 === "ReplaceableId" || keyword2 === "PriorityPlane") {
res[keyword2] = parseNumber(state);
} else if (keyword2 === "SortPrimsFarZ" || keyword2 === "Unshaded" || keyword2 === "LineEmitter" || keyword2 === "Unfogged" || keyword2 === "ModelSpace" || keyword2 === "XYQuad") {
res.Flags |= ParticleEmitter2Flags[keyword2];
} else if (keyword2 === "Both") {
res.FrameFlags |= ParticleEmitter2FramesFlags.Head | ParticleEmitter2FramesFlags.Tail;
} else if (keyword2 === "Head" || keyword2 === "Tail") {
res.FrameFlags |= ParticleEmitter2FramesFlags[keyword2];
} else if (keyword2 === "Squirt") {
res[keyword2] = true;
} else if (keyword2 === "DontInherit") {
strictParseSymbol(state, "{");
const val = parseKeyword(state);
if (val === "Translation") {
res.Flags |= NodeFlags.DontInheritTranslation;
} else if (val === "Rotation") {
res.Flags |= NodeFlags.DontInheritRotation;
} else if (val === "Scaling") {
res.Flags |= NodeFlags.DontInheritScaling;
}
strictParseSymbol(state, "}");
} else if (keyword2 === "SegmentColor") {
const colors = [];
strictParseSymbol(state, "{");
while (state.char() !== "}") {
parseKeyword(state);
const colorArr = new Float32Array(3);
parseArray(state, colorArr, 0);
const temp = colorArr[0];
colorArr[0] = colorArr[2];
colorArr[2] = temp;
colors.push(colorArr);
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
res.SegmentColor = colors;
} else if (keyword2 === "Alpha") {
res.Alpha = new Uint8Array(3);
parseArray(state, res.Alpha, 0);
} else if (keyword2 === "ParticleScaling") {
res[keyword2] = new Float32Array(3);
parseArray(state, res[keyword2], 0);
} else if (keyword2 === "LifeSpanUVAnim" || keyword2 === "DecayUVAnim" || keyword2 === "TailUVAnim" || keyword2 === "TailDecayUVAnim") {
res[keyword2] = new Uint32Array(3);
parseArray(state, res[keyword2], 0);
} else if (keyword2 === "Transparent" || keyword2 === "Blend" || keyword2 === "Additive" || keyword2 === "AlphaKey" || keyword2 === "Modulate" || keyword2 === "Modulate2x") {
res.FilterMode = ParticleEmitter2FilterMode[keyword2];
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.ParticleEmitters2.push(res);
model2.Nodes[res.ObjectId] = res;
}
function parseCamera(state, model2) {
const res = {
Name: null,
Position: null,
FieldOfView: 0,
NearClip: 0,
FarClip: 0,
TargetPosition: null
};
res.Name = parseString(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Position") {
res.Position = new Float32Array(3);
parseArray(state, res.Position, 0);
} else if (keyword2 === "FieldOfView" || keyword2 === "NearClip" || keyword2 === "FarClip") {
res[keyword2] = parseNumber(state);
} else if (keyword2 === "Target") {
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword22 = parseKeyword(state);
if (keyword22 === "Position") {
res.TargetPosition = new Float32Array(3);
parseArray(state, res.TargetPosition, 0);
} else if (keyword22 === "Translation") {
res.TargetTranslation = parseAnimVector(
state,
2
/* FLOAT3 */
);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
} else if (keyword2 === "Translation" || keyword2 === "Rotation") {
res[keyword2] = parseAnimVector(
state,
keyword2 === "Rotation" ? 1 : 2
/* FLOAT3 */
);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.Cameras.push(res);
}
function parseLight(state, model2) {
const name = parseString(state);
const res = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
Flags: NodeType.Light,
LightType: 0
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (!isStatic && (keyword2 === "Visibility" || keyword2 === "Color" || keyword2 === "Intensity" || keyword2 === "AmbIntensity" || keyword2 === "AmbColor" || keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling" || keyword2 === "AttenuationStart" || keyword2 === "AttenuationEnd")) {
let type = 2;
switch (keyword2) {
case "Rotation":
type = 3;
break;
case "Visibility":
case "Intensity":
case "AmbIntensity":
case "AttenuationStart":
case "AttenuationEnd":
type = 1;
break;
}
res[keyword2] = parseAnimVector(state, type);
if (keyword2 === "Color" || keyword2 === "AmbColor") {
for (const key of res[keyword2].Keys) {
key.Vector.reverse();
if (key.InTan) {
key.InTan.reverse();
key.OutTan.reverse();
}
}
}
} else if (keyword2 === "Omnidirectional" || keyword2 === "Directional" || keyword2 === "Ambient") {
res.LightType = LightType[keyword2];
} else if (keyword2 === "Color" || keyword2 === "AmbColor") {
const color2 = new Float32Array(3);
parseArray(state, color2, 0);
const temp = color2[0];
color2[0] = color2[2];
color2[2] = temp;
res[keyword2] = color2;
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.Lights.push(res);
model2.Nodes[res.ObjectId] = res;
}
function parseTextureAnims$1(state, model2) {
const res = [];
parseNumber(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const obj = {};
parseKeyword(state);
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling") {
const type = keyword2 === "Rotation" ? 3 : 2;
obj[keyword2] = parseAnimVector(state, type);
} else {
throw new Error("Unknown texture anim property " + keyword2);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
res.push(obj);
}
strictParseSymbol(state, "}");
model2.TextureAnims = res;
}
function parseRibbonEmitter(state, model2) {
const name = parseString(state);
const res = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
Flags: NodeType.RibbonEmitter,
HeightAbove: null,
HeightBelow: null,
Alpha: null,
Color: null,
LifeSpan: null,
TextureSlot: null,
EmissionRate: null,
Rows: null,
Columns: null,
MaterialID: 0,
Gravity: null,
Visibility: null
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (!isStatic && (keyword2 === "Visibility" || keyword2 === "HeightAbove" || keyword2 === "HeightBelow" || keyword2 === "Translation" || keyword2 === "Rotation" || keyword2 === "Scaling" || keyword2 === "Alpha" || keyword2 === "TextureSlot")) {
let type = 2;
switch (keyword2) {
case "Rotation":
type = 3;
break;
case "Visibility":
case "HeightAbove":
case "HeightBelow":
case "Alpha":
type = 1;
break;
case "TextureSlot":
type = 0;
break;
}
res[keyword2] = parseAnimVector(state, type);
} else if (keyword2 === "Color") {
const color2 = new Float32Array(3);
parseArray(state, color2, 0);
const temp = color2[0];
color2[0] = color2[2];
color2[2] = temp;
res[keyword2] = color2;
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.RibbonEmitters.push(res);
model2.Nodes[res.ObjectId] = res;
}
function parseFaceFX$1(state, model2) {
if (model2.Version < 900) {
throwError(state, "Unexpected model chunk FaceFX");
}
const name = parseString(state);
const res = {
Name: name,
Path: ""
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
const keyword2 = parseKeyword(state);
if (!keyword2) {
throwError(state);
}
if (keyword2 === "Path") {
res.Path = parseString(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.FaceFX = model2.FaceFX || [];
model2.FaceFX.push(res);
}
function parseBindPose$1(state, model2) {
if (model2.Version < 900) {
throwError(state, "Unexpected model chunk BindPose");
}
const res = {
Matrices: []
};
strictParseSymbol(state, "{");
parseKeyword(state);
const count = parseNumber(state);
strictParseSymbol(state, "{");
for (let i = 0; i < count; ++i) {
const matrix = new Float32Array(12);
parseArray(state, matrix, 0);
parseSymbol(state, ",");
res.Matrices.push(matrix);
}
strictParseSymbol(state, "}");
strictParseSymbol(state, "}");
model2.BindPoses = model2.BindPoses || [];
model2.BindPoses.push(res);
}
function parseParticleEmitterPopcorn$1(state, model2) {
if (model2.Version < 900) {
throwError(state, "Unexpected model chunk ParticleEmitterPopcorn");
}
const name = parseString(state);
const res = {
Name: name,
ObjectId: null,
Parent: null,
PivotPoint: null,
Flags: NodeType.ParticleEmitter
};
strictParseSymbol(state, "{");
while (state.char() !== "}") {
let keyword2 = parseKeyword(state);
let isStatic = false;
if (!keyword2) {
throwError(state);
}
if (keyword2 === "static") {
isStatic = true;
keyword2 = parseKeyword(state);
}
if (!isStatic && (keyword2 === "LifeSpan" || keyword2 === "EmissionRate" || keyword2 === "Speed" || keyword2 === "Color" || keyword2 === "Alpha" || keyword2 === "Visibility" || keyword2 === "Rotation" || keyword2 === "Scaling" || keyword2 === "Translation")) {
let type = 2;
switch (keyword2) {
case "LifeSpan":
case "EmissionRate":
case "Speed":
case "Alpha":
case "Visibility":
type = 1;
break;
}
res[keyword2] = parseAnimVector(state, type);
} else if (keyword2 === "LifeSpan" || keyword2 === "EmissionRate" || keyword2 === "Speed" || keyword2 === "Alpha") {
res[keyword2] = parseNumber(state);
} else if (keyword2 === "Color") {
const array = new Float32Array(3);
res[keyword2] = parseArray(state, array, 0);
} else if (keyword2 === "ReplaceableId") {
res[keyword2] = parseNumber(state);
} else if (keyword2 === "Path" || keyword2 === "AnimVisibilityGuide") {
res[keyword2] = parseString(state);
} else if (keyword2 === "Unshaded" || keyword2 === "SortPrimsFarZ" || keyword2 === "Unfogged") {
if (keyword2 === "Unshaded") {
res.Flags |= ParticleEmitterPopcornFlags.Unshaded;
} else if (keyword2 === "Unfogged") {
res.Flags |= ParticleEmitterPopcornFlags.Unfogged;
} else if (keyword2 === "SortPrimsFarZ") {
res.Flags |= ParticleEmitterPopcornFlags.SortPrimsFarZ;
}
} else {
res[keyword2] = parseNumber(state);
}
parseSymbol(state, ",");
}
strictParseSymbol(state, "}");
model2.ParticleEmitterPopcorns = model2.ParticleEmitterPopcorns || [];
model2.ParticleEmitterPopcorns.push(res);
model2.Nodes[res.ObjectId] = res;
}
const parsers$1 = {
Version: parseVersion$1,
Model: parseModelInfo$1,
Sequences: parseSequences$1,
Textures: parseTextures$1,
Materials: parseMaterials$1,
Geoset: parseGeoset,
GeosetAnim: parseGeosetAnim,
Bone: parseBone,
Helper: parseHelper,
Attachment: parseAttachment,
PivotPoints: parsePivotPoints$1,
EventObject: parseEventObject,
CollisionShape: parseCollisionShape,
GlobalSequences: parseGlobalSequences