UNPKG

fbx-parser

Version:

This parser will parse FBX text files and convert them into a JavaScript-Object structure.

137 lines (136 loc) 5.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseText = void 0; /** * Returns a list of FBXNodes * @param ascii the FBX ascii file content */ function parseText(ascii) { var lines = ascii.split('\n'); var rootNode = { name: '', props: [], nodes: [], }; var currentNode = rootNode; var path = [currentNode]; var state = 0 /* expectingNodeOrClose */; for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) { var line = lines_1[_i]; line = line.trim(); // Empty Line if (line.length === 0) continue; // Comment Line if (line[0] === ';') continue; // Depending on State (expecting sub-node or node close, expecting property list continuation-if line ends with a comma) if (state === 0 /* expectingNodeOrClose */) { // Node Close if (line[0] === '}') { // Can't close when in root node if (path.length === 1) throw 'FBX syntax error'; path.pop(); currentNode = path[path.length - 1]; } else { // find colon after the the node name var firstCol = line.indexOf(':'); var nodeName = line.substring(0, firstCol); nodeName = nodeName.trim(); // check end of line var expectingSubnodes = line[line.length - 1] === '{'; var propertyString = line.substring(firstCol + 1, line.length - (expectingSubnodes ? 1 : 0)); var propertyStringList = propertyString.split(','); var properties = []; for (var _a = 0, propertyStringList_1 = propertyStringList; _a < propertyStringList_1.length; _a++) { var propertyString_1 = propertyStringList_1[_a]; var trimmed = propertyString_1.trim(); if (trimmed === '') continue; var value = convertProperty(trimmed); if (typeof value === 'undefined') continue; properties.push(value); } if (propertyStringList[propertyStringList.length - 1] === '') state = 1 /* expectingPropertyListContinuation */; var newNode = { name: nodeName, props: properties, nodes: [], }; currentNode.nodes.push(newNode); if (expectingSubnodes || state === 1 /* expectingPropertyListContinuation */) { path.push(newNode); currentNode = newNode; } } } else if (state === 1 /* expectingPropertyListContinuation */) { // check end of line var expectingSubnodes = line[line.length - 1] === '{'; var propertyString = line.substring(0, line.length - (expectingSubnodes ? 1 : 0)); var propertyStringList = propertyString.split(','); var properties = []; for (var _b = 0, propertyStringList_2 = propertyStringList; _b < propertyStringList_2.length; _b++) { var propertyString_2 = propertyStringList_2[_b]; var trimmed = propertyString_2.trim(); if (trimmed === '' || trimmed === '}') continue; var value = convertProperty(trimmed); if (typeof value === 'undefined') continue; properties.push(value); } currentNode.props = currentNode.props.concat(properties); if (propertyStringList[propertyStringList.length - 1] !== '') state = 0 /* expectingNodeOrClose */; if (!expectingSubnodes && state === 0 /* expectingNodeOrClose */) { path.pop(); currentNode = path[path.length - 1]; } } } // nodes with name a seem to actually just be an array prop and handled like a prop in binary function correctArrays(node) { if (node.nodes.length === 1 && node.props.length === 0 && node.nodes[0].name === 'a') { node.props = [node.nodes[0].props]; node.nodes = []; } else { for (var _i = 0, _a = node.nodes; _i < _a.length; _i++) { var childNode = _a[_i]; correctArrays(childNode); } } } correctArrays(rootNode); return rootNode.nodes; } exports.parseText = parseText; /** * Auto detects and converts the property type * @param prop */ function convertProperty(prop) { if (prop[0] == '*') return undefined; // e.g. array size if (prop[0] == '"') return prop.substr(1, prop.length - 2); if (prop == 'T') return true; if (prop == 'F') return false; if (prop == 'Y') return true; if (prop == 'N') return false; if (prop.indexOf('.') != -1) return parseFloat(prop); var n = BigInt(prop); if (n < Number.MIN_SAFE_INTEGER || n > Number.MAX_SAFE_INTEGER) return n; return Number(n); }