1 |
- {"ast":null,"code":"import \"core-js/modules/es.array.push.js\";\nimport \"core-js/modules/es.typed-array.to-reversed.js\";\nimport \"core-js/modules/es.typed-array.to-sorted.js\";\nimport \"core-js/modules/es.typed-array.with.js\";\nimport \"core-js/modules/web.url-search-params.delete.js\";\nimport \"core-js/modules/web.url-search-params.has.js\";\nimport \"core-js/modules/web.url-search-params.size.js\";\nimport { AmbientLight, AnimationClip, Bone, BufferGeometry, ClampToEdgeWrapping, Color, DirectionalLight, EquirectangularReflectionMapping, Euler, FileLoader, Float32BufferAttribute, Group, Line, LineBasicMaterial, Loader, LoaderUtils, MathUtils, Matrix3, Matrix4, Mesh, MeshLambertMaterial, MeshPhongMaterial, NumberKeyframeTrack, Object3D, OrthographicCamera, PerspectiveCamera, PointLight, PropertyBinding, Quaternion, QuaternionKeyframeTrack, RepeatWrapping, Skeleton, SkinnedMesh, SpotLight, Texture, TextureLoader, Uint16BufferAttribute, Vector3, Vector4, VectorKeyframeTrack, SRGBColorSpace } from \"three\";\nimport * as fflate from \"../public/libs/fflate.module\";\nimport { NURBSCurve } from \"../public/curves/NURBSCurve.js\";\n\n/**\n * Loader loads FBX file and generates Group representing FBX scene.\n * Requires FBX file to be >= 7.0 and in ASCII or >= 6400 in Binary format\n * Versions lower than this may load but will probably have errors\n *\n * Needs Support:\n * Morph normals / blend shape normals\n *\n * FBX format references:\n * \thttps://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_index_html (C++ SDK reference)\n *\n * Binary format specification:\n *\thttps://code.blender.org/2013/08/fbx-binary-file-format-specification/\n */\n\nlet fbxTree;\nlet connections;\nlet sceneGraph;\nclass FBXLoader extends Loader {\n constructor(manager) {\n super(manager);\n }\n load(url, onLoad, onProgress, onError) {\n const scope = this;\n const path = scope.path === \"\" ? LoaderUtils.extractUrlBase(url) : scope.path;\n const loader = new FileLoader(this.manager);\n loader.setPath(scope.path);\n loader.setResponseType(\"arraybuffer\");\n loader.setRequestHeader(scope.requestHeader);\n loader.setWithCredentials(scope.withCredentials);\n loader.load(url, function (buffer) {\n try {\n onLoad(scope.parse(buffer, path));\n } catch (e) {\n if (onError) {\n onError(e);\n } else {\n console.error(e);\n }\n scope.manager.itemError(url);\n }\n }, onProgress, onError);\n }\n parse(FBXBuffer, path) {\n if (isFbxFormatBinary(FBXBuffer)) {\n fbxTree = new BinaryParser().parse(FBXBuffer);\n } else {\n const FBXText = convertArrayBufferToString(FBXBuffer);\n if (!isFbxFormatASCII(FBXText)) {\n throw new Error(\"THREE.FBXLoader: Unknown format.\");\n }\n if (getFbxVersion(FBXText) < 7000) {\n throw new Error(\"THREE.FBXLoader: FBX version not supported, FileVersion: \" + getFbxVersion(FBXText));\n }\n fbxTree = new TextParser().parse(FBXText);\n }\n\n // console.log( fbxTree );\n\n const textureLoader = new TextureLoader(this.manager).setPath(this.resourcePath || path).setCrossOrigin(this.crossOrigin);\n return new FBXTreeParser(textureLoader, this.manager).parse(fbxTree);\n }\n}\n\n// Parse the FBXTree object returned by the BinaryParser or TextParser and return a Group\nclass FBXTreeParser {\n constructor(textureLoader, manager) {\n this.textureLoader = textureLoader;\n this.manager = manager;\n }\n parse() {\n connections = this.parseConnections();\n const images = this.parseImages();\n const textures = this.parseTextures(images);\n const materials = this.parseMaterials(textures);\n const deformers = this.parseDeformers();\n const geometryMap = new GeometryParser().parse(deformers);\n this.parseScene(deformers, geometryMap, materials);\n return sceneGraph;\n }\n\n // Parses FBXTree.Connections which holds parent-child connections between objects (e.g. material -> texture, model->geometry )\n // and details the connection type\n parseConnections() {\n const connectionMap = new Map();\n if (\"Connections\" in fbxTree) {\n const rawConnections = fbxTree.Connections.connections;\n rawConnections.forEach(function (rawConnection) {\n const fromID = rawConnection[0];\n const toID = rawConnection[1];\n const relationship = rawConnection[2];\n if (!connectionMap.has(fromID)) {\n connectionMap.set(fromID, {\n parents: [],\n children: []\n });\n }\n const parentRelationship = {\n ID: toID,\n relationship: relationship\n };\n connectionMap.get(fromID).parents.push(parentRelationship);\n if (!connectionMap.has(toID)) {\n connectionMap.set(toID, {\n parents: [],\n children: []\n });\n }\n const childRelationship = {\n ID: fromID,\n relationship: relationship\n };\n connectionMap.get(toID).children.push(childRelationship);\n });\n }\n return connectionMap;\n }\n\n // Parse FBXTree.Objects.Video for embedded image data\n // These images are connected to textures in FBXTree.Objects.Textures\n // via FBXTree.Connections.\n parseImages() {\n const images = {};\n const blobs = {};\n if (\"Video\" in fbxTree.Objects) {\n const videoNodes = fbxTree.Objects.Video;\n for (const nodeID in videoNodes) {\n const videoNode = videoNodes[nodeID];\n const id = parseInt(nodeID);\n images[id] = videoNode.RelativeFilename || videoNode.Filename;\n\n // raw image data is in videoNode.Content\n if (\"Content\" in videoNode) {\n const arrayBufferContent = videoNode.Content instanceof ArrayBuffer && videoNode.Content.byteLength > 0;\n const base64Content = typeof videoNode.Content === \"string\" && videoNode.Content !== \"\";\n if (arrayBufferContent || base64Content) {\n const image = this.parseImage(videoNodes[nodeID]);\n blobs[videoNode.RelativeFilename || videoNode.Filename] = image;\n }\n }\n }\n }\n for (const id in images) {\n const filename = images[id];\n if (blobs[filename] !== undefined) images[id] = blobs[filename];else images[id] = images[id].split(\"\\\\\").pop();\n }\n return images;\n }\n\n // Parse embedded image data in FBXTree.Video.Content\n parseImage(videoNode) {\n const content = videoNode.Content;\n const fileName = videoNode.RelativeFilename || videoNode.Filename;\n const extension = fileName.slice(fileName.lastIndexOf(\".\") + 1).toLowerCase();\n let type;\n switch (extension) {\n case \"bmp\":\n type = \"image/bmp\";\n break;\n case \"jpg\":\n case \"jpeg\":\n type = \"image/jpeg\";\n break;\n case \"png\":\n type = \"image/png\";\n break;\n case \"tif\":\n type = \"image/tiff\";\n break;\n case \"tga\":\n if (this.manager.getHandler(\".tga\") === null) {\n console.warn(\"FBXLoader: TGA loader not found, skipping \", fileName);\n }\n type = \"image/tga\";\n break;\n default:\n console.warn('FBXLoader: Image type \"' + extension + '\" is not supported.');\n return;\n }\n if (typeof content === \"string\") {\n // ASCII format\n\n return \"data:\" + type + \";base64,\" + content;\n } else {\n // Binary Format\n\n const array = new Uint8Array(content);\n return window.URL.createObjectURL(new Blob([array], {\n type: type\n }));\n }\n }\n\n // Parse nodes in FBXTree.Objects.Texture\n // These contain details such as UV scaling, cropping, rotation etc and are connected\n // to images in FBXTree.Objects.Video\n parseTextures(images) {\n const textureMap = new Map();\n if (\"Texture\" in fbxTree.Objects) {\n const textureNodes = fbxTree.Objects.Texture;\n for (const nodeID in textureNodes) {\n const texture = this.parseTexture(textureNodes[nodeID], images);\n textureMap.set(parseInt(nodeID), texture);\n }\n }\n return textureMap;\n }\n\n // Parse individual node in FBXTree.Objects.Texture\n parseTexture(textureNode, images) {\n const texture = this.loadTexture(textureNode, images);\n texture.ID = textureNode.id;\n texture.name = textureNode.attrName;\n const wrapModeU = textureNode.WrapModeU;\n const wrapModeV = textureNode.WrapModeV;\n const valueU = wrapModeU !== undefined ? wrapModeU.value : 0;\n const valueV = wrapModeV !== undefined ? wrapModeV.value : 0;\n\n // http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_texture.html#889640e63e2e681259ea81061b85143a\n // 0: repeat(default), 1: clamp\n\n texture.wrapS = valueU === 0 ? RepeatWrapping : ClampToEdgeWrapping;\n texture.wrapT = valueV === 0 ? RepeatWrapping : ClampToEdgeWrapping;\n if (\"Scaling\" in textureNode) {\n const values = textureNode.Scaling.value;\n texture.repeat.x = values[0];\n texture.repeat.y = values[1];\n }\n if (\"Translation\" in textureNode) {\n const values = textureNode.Translation.value;\n texture.offset.x = values[0];\n texture.offset.y = values[1];\n }\n return texture;\n }\n\n // load a texture specified as a blob or data URI, or via an external URL using TextureLoader\n loadTexture(textureNode, images) {\n let fileName;\n const currentPath = this.textureLoader.path;\n const children = connections.get(textureNode.id).children;\n if (children !== undefined && children.length > 0 && images[children[0].ID] !== undefined) {\n fileName = images[children[0].ID];\n if (fileName.indexOf(\"blob:\") === 0 || fileName.indexOf(\"data:\") === 0) {\n this.textureLoader.setPath(undefined);\n }\n }\n let texture;\n const extension = textureNode.FileName.slice(-3).toLowerCase();\n if (extension === \"tga\") {\n const loader = this.manager.getHandler(\".tga\");\n if (loader === null) {\n console.warn(\"FBXLoader: TGA loader not found, creating placeholder texture for\", textureNode.RelativeFilename);\n texture = new Texture();\n } else {\n loader.setPath(this.textureLoader.path);\n texture = loader.load(fileName);\n }\n } else if (extension === \"psd\") {\n console.warn(\"FBXLoader: PSD textures are not supported, creating placeholder texture for\", textureNode.RelativeFilename);\n texture = new Texture();\n } else {\n texture = this.textureLoader.load(fileName);\n }\n this.textureLoader.setPath(currentPath);\n return texture;\n }\n\n // Parse nodes in FBXTree.Objects.Material\n parseMaterials(textureMap) {\n const materialMap = new Map();\n if (\"Material\" in fbxTree.Objects) {\n const materialNodes = fbxTree.Objects.Material;\n for (const nodeID in materialNodes) {\n const material = this.parseMaterial(materialNodes[nodeID], textureMap);\n if (material !== null) materialMap.set(parseInt(nodeID), material);\n }\n }\n return materialMap;\n }\n\n // Parse single node in FBXTree.Objects.Material\n // Materials are connected to texture maps in FBXTree.Objects.Textures\n // FBX format currently only supports Lambert and Phong shading models\n parseMaterial(materialNode, textureMap) {\n const ID = materialNode.id;\n const name = materialNode.attrName;\n let type = materialNode.ShadingModel;\n\n // Case where FBX wraps shading model in property object.\n if (typeof type === \"object\") {\n type = type.value;\n }\n\n // Ignore unused materials which don't have any connections.\n if (!connections.has(ID)) return null;\n const parameters = this.parseParameters(materialNode, textureMap, ID);\n let material;\n switch (type.toLowerCase()) {\n case \"phong\":\n material = new MeshPhongMaterial();\n break;\n case \"lambert\":\n material = new MeshLambertMaterial();\n break;\n default:\n console.warn('THREE.FBXLoader: unknown material type \"%s\". Defaulting to MeshPhongMaterial.', type);\n material = new MeshPhongMaterial();\n break;\n }\n material.setValues(parameters);\n material.name = name;\n return material;\n }\n\n // Parse FBX material and return parameters suitable for a three.js material\n // Also parse the texture map and return any textures associated with the material\n parseParameters(materialNode, textureMap, ID) {\n const parameters = {};\n if (materialNode.BumpFactor) {\n parameters.bumpScale = materialNode.BumpFactor.value;\n }\n if (materialNode.Diffuse) {\n parameters.color = new Color().fromArray(materialNode.Diffuse.value).convertSRGBToLinear();\n } else if (materialNode.DiffuseColor && (materialNode.DiffuseColor.type === \"Color\" || materialNode.DiffuseColor.type === \"ColorRGB\")) {\n // The blender exporter exports diffuse here instead of in materialNode.Diffuse\n parameters.color = new Color().fromArray(materialNode.DiffuseColor.value).convertSRGBToLinear();\n }\n if (materialNode.DisplacementFactor) {\n parameters.displacementScale = materialNode.DisplacementFactor.value;\n }\n if (materialNode.Emissive) {\n parameters.emissive = new Color().fromArray(materialNode.Emissive.value).convertSRGBToLinear();\n } else if (materialNode.EmissiveColor && (materialNode.EmissiveColor.type === \"Color\" || materialNode.EmissiveColor.type === \"ColorRGB\")) {\n // The blender exporter exports emissive color here instead of in materialNode.Emissive\n parameters.emissive = new Color().fromArray(materialNode.EmissiveColor.value).convertSRGBToLinear();\n }\n if (materialNode.EmissiveFactor) {\n parameters.emissiveIntensity = parseFloat(materialNode.EmissiveFactor.value);\n }\n if (materialNode.Opacity) {\n parameters.opacity = parseFloat(materialNode.Opacity.value);\n }\n if (parameters.opacity < 1.0) {\n parameters.transparent = true;\n }\n if (materialNode.ReflectionFactor) {\n parameters.reflectivity = materialNode.ReflectionFactor.value;\n }\n if (materialNode.Shininess) {\n parameters.shininess = materialNode.Shininess.value;\n }\n if (materialNode.Specular) {\n parameters.specular = new Color().fromArray(materialNode.Specular.value).convertSRGBToLinear();\n } else if (materialNode.SpecularColor && materialNode.SpecularColor.type === \"Color\") {\n // The blender exporter exports specular color here instead of in materialNode.Specular\n parameters.specular = new Color().fromArray(materialNode.SpecularColor.value).convertSRGBToLinear();\n }\n const scope = this;\n connections.get(ID).children.forEach(function (child) {\n const type = child.relationship;\n switch (type) {\n case \"Bump\":\n parameters.bumpMap = scope.getTexture(textureMap, child.ID);\n break;\n case \"Maya|TEX_ao_map\":\n parameters.aoMap = scope.getTexture(textureMap, child.ID);\n break;\n case \"DiffuseColor\":\n case \"Maya|TEX_color_map\":\n parameters.map = scope.getTexture(textureMap, child.ID);\n if (parameters.map !== undefined) {\n parameters.map.colorSpace = SRGBColorSpace;\n }\n break;\n case \"DisplacementColor\":\n parameters.displacementMap = scope.getTexture(textureMap, child.ID);\n break;\n case \"EmissiveColor\":\n parameters.emissiveMap = scope.getTexture(textureMap, child.ID);\n if (parameters.emissiveMap !== undefined) {\n parameters.emissiveMap.colorSpace = SRGBColorSpace;\n }\n break;\n case \"NormalMap\":\n case \"Maya|TEX_normal_map\":\n parameters.normalMap = scope.getTexture(textureMap, child.ID);\n break;\n case \"ReflectionColor\":\n parameters.envMap = scope.getTexture(textureMap, child.ID);\n if (parameters.envMap !== undefined) {\n parameters.envMap.mapping = EquirectangularReflectionMapping;\n parameters.envMap.colorSpace = SRGBColorSpace;\n }\n break;\n case \"SpecularColor\":\n parameters.specularMap = scope.getTexture(textureMap, child.ID);\n if (parameters.specularMap !== undefined) {\n parameters.specularMap.colorSpace = SRGBColorSpace;\n }\n break;\n case \"TransparentColor\":\n case \"TransparencyFactor\":\n parameters.alphaMap = scope.getTexture(textureMap, child.ID);\n parameters.transparent = true;\n break;\n case \"AmbientColor\":\n case \"ShininessExponent\": // AKA glossiness map\n case \"SpecularFactor\": // AKA specularLevel\n case \"VectorDisplacementColor\": // NOTE: Seems to be a copy of DisplacementColor\n default:\n console.warn(\"THREE.FBXLoader: %s map is not supported in three.js, skipping texture.\", type);\n break;\n }\n });\n return parameters;\n }\n\n // get a texture from the textureMap for use by a material.\n getTexture(textureMap, id) {\n // if the texture is a layered texture, just use the first layer and issue a warning\n if (\"LayeredTexture\" in fbxTree.Objects && id in fbxTree.Objects.LayeredTexture) {\n console.warn(\"THREE.FBXLoader: layered textures are not supported in three.js. Discarding all but first layer.\");\n id = connections.get(id).children[0].ID;\n }\n return textureMap.get(id);\n }\n\n // Parse nodes in FBXTree.Objects.Deformer\n // Deformer node can contain skinning or Vertex Cache animation data, however only skinning is supported here\n // Generates map of Skeleton-like objects for use later when generating and binding skeletons.\n parseDeformers() {\n const skeletons = {};\n const morphTargets = {};\n if (\"Deformer\" in fbxTree.Objects) {\n const DeformerNodes = fbxTree.Objects.Deformer;\n for (const nodeID in DeformerNodes) {\n const deformerNode = DeformerNodes[nodeID];\n const relationships = connections.get(parseInt(nodeID));\n if (deformerNode.attrType === \"Skin\") {\n const skeleton = this.parseSkeleton(relationships, DeformerNodes);\n skeleton.ID = nodeID;\n if (relationships.parents.length > 1) console.warn(\"THREE.FBXLoader: skeleton attached to more than one geometry is not supported.\");\n skeleton.geometryID = relationships.parents[0].ID;\n skeletons[nodeID] = skeleton;\n } else if (deformerNode.attrType === \"BlendShape\") {\n const morphTarget = {\n id: nodeID\n };\n morphTarget.rawTargets = this.parseMorphTargets(relationships, DeformerNodes);\n morphTarget.id = nodeID;\n if (relationships.parents.length > 1) console.warn(\"THREE.FBXLoader: morph target attached to more than one geometry is not supported.\");\n morphTargets[nodeID] = morphTarget;\n }\n }\n }\n return {\n skeletons: skeletons,\n morphTargets: morphTargets\n };\n }\n\n // Parse single nodes in FBXTree.Objects.Deformer\n // The top level skeleton node has type 'Skin' and sub nodes have type 'Cluster'\n // Each skin node represents a skeleton and each cluster node represents a bone\n parseSkeleton(relationships, deformerNodes) {\n const rawBones = [];\n relationships.children.forEach(function (child) {\n const boneNode = deformerNodes[child.ID];\n if (boneNode.attrType !== \"Cluster\") return;\n const rawBone = {\n ID: child.ID,\n indices: [],\n weights: [],\n transformLink: new Matrix4().fromArray(boneNode.TransformLink.a)\n // transform: new Matrix4().fromArray( boneNode.Transform.a ),\n // linkMode: boneNode.Mode,\n };\n\n if (\"Indexes\" in boneNode) {\n rawBone.indices = boneNode.Indexes.a;\n rawBone.weights = boneNode.Weights.a;\n }\n rawBones.push(rawBone);\n });\n return {\n rawBones: rawBones,\n bones: []\n };\n }\n\n // The top level morph deformer node has type \"BlendShape\" and sub nodes have type \"BlendShapeChannel\"\n parseMorphTargets(relationships, deformerNodes) {\n const rawMorphTargets = [];\n for (let i = 0; i < relationships.children.length; i++) {\n const child = relationships.children[i];\n const morphTargetNode = deformerNodes[child.ID];\n const rawMorphTarget = {\n name: morphTargetNode.attrName,\n initialWeight: morphTargetNode.DeformPercent,\n id: morphTargetNode.id,\n fullWeights: morphTargetNode.FullWeights.a\n };\n if (morphTargetNode.attrType !== \"BlendShapeChannel\") return;\n rawMorphTarget.geoID = connections.get(parseInt(child.ID)).children.filter(function (child) {\n return child.relationship === undefined;\n })[0].ID;\n rawMorphTargets.push(rawMorphTarget);\n }\n return rawMorphTargets;\n }\n\n // create the main Group() to be returned by the loader\n parseScene(deformers, geometryMap, materialMap) {\n sceneGraph = new Group();\n const modelMap = this.parseModels(deformers.skeletons, geometryMap, materialMap);\n const modelNodes = fbxTree.Objects.Model;\n const scope = this;\n modelMap.forEach(function (model) {\n const modelNode = modelNodes[model.ID];\n scope.setLookAtProperties(model, modelNode);\n const parentConnections = connections.get(model.ID).parents;\n parentConnections.forEach(function (connection) {\n const parent = modelMap.get(connection.ID);\n if (parent !== undefined) parent.add(model);\n });\n if (model.parent === null) {\n sceneGraph.add(model);\n }\n });\n this.bindSkeleton(deformers.skeletons, geometryMap, modelMap);\n this.createAmbientLight();\n sceneGraph.traverse(function (node) {\n if (node.userData.transformData) {\n if (node.parent) {\n node.userData.transformData.parentMatrix = node.parent.matrix;\n node.userData.transformData.parentMatrixWorld = node.parent.matrixWorld;\n }\n const transform = generateTransform(node.userData.transformData);\n node.applyMatrix4(transform);\n node.updateWorldMatrix();\n }\n });\n const animations = new AnimationParser().parse();\n\n // if all the models where already combined in a single group, just return that\n if (sceneGraph.children.length === 1 && sceneGraph.children[0].isGroup) {\n sceneGraph.children[0].animations = animations;\n sceneGraph = sceneGraph.children[0];\n }\n sceneGraph.animations = animations;\n }\n\n // parse nodes in FBXTree.Objects.Model\n parseModels(skeletons, geometryMap, materialMap) {\n const modelMap = new Map();\n const modelNodes = fbxTree.Objects.Model;\n for (const nodeID in modelNodes) {\n const id = parseInt(nodeID);\n const node = modelNodes[nodeID];\n const relationships = connections.get(id);\n let model = this.buildSkeleton(relationships, skeletons, id, node.attrName);\n if (!model) {\n switch (node.attrType) {\n case \"Camera\":\n model = this.createCamera(relationships);\n break;\n case \"Light\":\n model = this.createLight(relationships);\n break;\n case \"Mesh\":\n model = this.createMesh(relationships, geometryMap, materialMap);\n break;\n case \"NurbsCurve\":\n model = this.createCurve(relationships, geometryMap);\n break;\n case \"LimbNode\":\n case \"Root\":\n model = new Bone();\n break;\n case \"Null\":\n default:\n model = new Group();\n break;\n }\n model.name = node.attrName ? PropertyBinding.sanitizeNodeName(node.attrName) : \"\";\n model.ID = id;\n }\n this.getTransformData(model, node);\n modelMap.set(id, model);\n }\n return modelMap;\n }\n buildSkeleton(relationships, skeletons, id, name) {\n let bone = null;\n relationships.parents.forEach(function (parent) {\n for (const ID in skeletons) {\n const skeleton = skeletons[ID];\n skeleton.rawBones.forEach(function (rawBone, i) {\n if (rawBone.ID === parent.ID) {\n const subBone = bone;\n bone = new Bone();\n bone.matrixWorld.copy(rawBone.transformLink);\n\n // set name and id here - otherwise in cases where \"subBone\" is created it will not have a name / id\n\n bone.name = name ? PropertyBinding.sanitizeNodeName(name) : \"\";\n bone.ID = id;\n skeleton.bones[i] = bone;\n\n // In cases where a bone is shared between multiple meshes\n // duplicate the bone here and and it as a child of the first bone\n if (subBone !== null) {\n bone.add(subBone);\n }\n }\n });\n }\n });\n return bone;\n }\n\n // create a PerspectiveCamera or OrthographicCamera\n createCamera(relationships) {\n let model;\n let cameraAttribute;\n relationships.children.forEach(function (child) {\n const attr = fbxTree.Objects.NodeAttribute[child.ID];\n if (attr !== undefined) {\n cameraAttribute = attr;\n }\n });\n if (cameraAttribute === undefined) {\n model = new Object3D();\n } else {\n let type = 0;\n if (cameraAttribute.CameraProjectionType !== undefined && cameraAttribute.CameraProjectionType.value === 1) {\n type = 1;\n }\n let nearClippingPlane = 1;\n if (cameraAttribute.NearPlane !== undefined) {\n nearClippingPlane = cameraAttribute.NearPlane.value / 1000;\n }\n let farClippingPlane = 1000;\n if (cameraAttribute.FarPlane !== undefined) {\n farClippingPlane = cameraAttribute.FarPlane.value / 1000;\n }\n let width = window.innerWidth;\n let height = window.innerHeight;\n if (cameraAttribute.AspectWidth !== undefined && cameraAttribute.AspectHeight !== undefined) {\n width = cameraAttribute.AspectWidth.value;\n height = cameraAttribute.AspectHeight.value;\n }\n const aspect = width / height;\n let fov = 45;\n if (cameraAttribute.FieldOfView !== undefined) {\n fov = cameraAttribute.FieldOfView.value;\n }\n const focalLength = cameraAttribute.FocalLength ? cameraAttribute.FocalLength.value : null;\n switch (type) {\n case 0:\n // Perspective\n model = new PerspectiveCamera(fov, aspect, nearClippingPlane, farClippingPlane);\n if (focalLength !== null) model.setFocalLength(focalLength);\n break;\n case 1:\n // Orthographic\n model = new OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, nearClippingPlane, farClippingPlane);\n break;\n default:\n console.warn(\"THREE.FBXLoader: Unknown camera type \" + type + \".\");\n model = new Object3D();\n break;\n }\n }\n return model;\n }\n\n // Create a DirectionalLight, PointLight or SpotLight\n createLight(relationships) {\n let model;\n let lightAttribute;\n relationships.children.forEach(function (child) {\n const attr = fbxTree.Objects.NodeAttribute[child.ID];\n if (attr !== undefined) {\n lightAttribute = attr;\n }\n });\n if (lightAttribute === undefined) {\n model = new Object3D();\n } else {\n let type;\n\n // LightType can be undefined for Point lights\n if (lightAttribute.LightType === undefined) {\n type = 0;\n } else {\n type = lightAttribute.LightType.value;\n }\n let color = 0xffffff;\n if (lightAttribute.Color !== undefined) {\n color = new Color().fromArray(lightAttribute.Color.value).convertSRGBToLinear();\n }\n let intensity = lightAttribute.Intensity === undefined ? 1 : lightAttribute.Intensity.value / 100;\n\n // light disabled\n if (lightAttribute.CastLightOnObject !== undefined && lightAttribute.CastLightOnObject.value === 0) {\n intensity = 0;\n }\n let distance = 0;\n if (lightAttribute.FarAttenuationEnd !== undefined) {\n if (lightAttribute.EnableFarAttenuation !== undefined && lightAttribute.EnableFarAttenuation.value === 0) {\n distance = 0;\n } else {\n distance = lightAttribute.FarAttenuationEnd.value;\n }\n }\n\n // TODO: could this be calculated linearly from FarAttenuationStart to FarAttenuationEnd?\n const decay = 1;\n switch (type) {\n case 0:\n // Point\n model = new PointLight(color, intensity, distance, decay);\n break;\n case 1:\n // Directional\n model = new DirectionalLight(color, intensity);\n break;\n case 2:\n // Spot\n let angle = Math.PI / 3;\n if (lightAttribute.InnerAngle !== undefined) {\n angle = MathUtils.degToRad(lightAttribute.InnerAngle.value);\n }\n let penumbra = 0;\n if (lightAttribute.OuterAngle !== undefined) {\n // TODO: this is not correct - FBX calculates outer and inner angle in degrees\n // with OuterAngle > InnerAngle && OuterAngle <= Math.PI\n // while three.js uses a penumbra between (0, 1) to attenuate the inner angle\n penumbra = MathUtils.degToRad(lightAttribute.OuterAngle.value);\n penumbra = Math.max(penumbra, 1);\n }\n model = new SpotLight(color, intensity, distance, angle, penumbra, decay);\n break;\n default:\n console.warn(\"THREE.FBXLoader: Unknown light type \" + lightAttribute.LightType.value + \", defaulting to a PointLight.\");\n model = new PointLight(color, intensity);\n break;\n }\n if (lightAttribute.CastShadows !== undefined && lightAttribute.CastShadows.value === 1) {\n model.castShadow = true;\n }\n }\n return model;\n }\n createMesh(relationships, geometryMap, materialMap) {\n let model;\n let geometry = null;\n let material = null;\n const materials = [];\n\n // get geometry and materials(s) from connections\n relationships.children.forEach(function (child) {\n if (geometryMap.has(child.ID)) {\n geometry = geometryMap.get(child.ID);\n }\n if (materialMap.has(child.ID)) {\n materials.push(materialMap.get(child.ID));\n }\n });\n if (materials.length > 1) {\n material = materials;\n } else if (materials.length > 0) {\n material = materials[0];\n } else {\n material = new MeshPhongMaterial({\n name: Loader.DEFAULT_MATERIAL_NAME,\n color: 0xcccccc\n });\n materials.push(material);\n }\n if (\"color\" in geometry.attributes) {\n materials.forEach(function (material) {\n material.vertexColors = true;\n });\n }\n if (geometry.FBX_Deformer) {\n model = new SkinnedMesh(geometry, material);\n model.normalizeSkinWeights();\n } else {\n model = new Mesh(geometry, material);\n }\n return model;\n }\n createCurve(relationships, geometryMap) {\n const geometry = relationships.children.reduce(function (geo, child) {\n if (geometryMap.has(child.ID)) geo = geometryMap.get(child.ID);\n return geo;\n }, null);\n\n // FBX does not list materials for Nurbs lines, so we'll just put our own in here.\n const material = new LineBasicMaterial({\n name: Loader.DEFAULT_MATERIAL_NAME,\n color: 0x3300ff,\n linewidth: 1\n });\n return new Line(geometry, material);\n }\n\n // parse the model node for transform data\n getTransformData(model, modelNode) {\n const transformData = {};\n if (\"InheritType\" in modelNode) transformData.inheritType = parseInt(modelNode.InheritType.value);\n if (\"RotationOrder\" in modelNode) transformData.eulerOrder = getEulerOrder(modelNode.RotationOrder.value);else transformData.eulerOrder = \"ZYX\";\n if (\"Lcl_Translation\" in modelNode) transformData.translation = modelNode.Lcl_Translation.value;\n if (\"PreRotation\" in modelNode) transformData.preRotation = modelNode.PreRotation.value;\n if (\"Lcl_Rotation\" in modelNode) transformData.rotation = modelNode.Lcl_Rotation.value;\n if (\"PostRotation\" in modelNode) transformData.postRotation = modelNode.PostRotation.value;\n if (\"Lcl_Scaling\" in modelNode) transformData.scale = modelNode.Lcl_Scaling.value;\n if (\"ScalingOffset\" in modelNode) transformData.scalingOffset = modelNode.ScalingOffset.value;\n if (\"ScalingPivot\" in modelNode) transformData.scalingPivot = modelNode.ScalingPivot.value;\n if (\"RotationOffset\" in modelNode) transformData.rotationOffset = modelNode.RotationOffset.value;\n if (\"RotationPivot\" in modelNode) transformData.rotationPivot = modelNode.RotationPivot.value;\n model.userData.transformData = transformData;\n }\n setLookAtProperties(model, modelNode) {\n if (\"LookAtProperty\" in modelNode) {\n const children = connections.get(model.ID).children;\n children.forEach(function (child) {\n if (child.relationship === \"LookAtProperty\") {\n const lookAtTarget = fbxTree.Objects.Model[child.ID];\n if (\"Lcl_Translation\" in lookAtTarget) {\n const pos = lookAtTarget.Lcl_Translation.value;\n\n // DirectionalLight, SpotLight\n if (model.target !== undefined) {\n model.target.position.fromArray(pos);\n sceneGraph.add(model.target);\n } else {\n // Cameras and other Object3Ds\n\n model.lookAt(new Vector3().fromArray(pos));\n }\n }\n }\n });\n }\n }\n bindSkeleton(skeletons, geometryMap, modelMap) {\n const bindMatrices = this.parsePoseNodes();\n for (const ID in skeletons) {\n const skeleton = skeletons[ID];\n const parents = connections.get(parseInt(skeleton.ID)).parents;\n parents.forEach(function (parent) {\n if (geometryMap.has(parent.ID)) {\n const geoID = parent.ID;\n const geoRelationships = connections.get(geoID);\n geoRelationships.parents.forEach(function (geoConnParent) {\n if (modelMap.has(geoConnParent.ID)) {\n const model = modelMap.get(geoConnParent.ID);\n model.bind(new Skeleton(skeleton.bones), bindMatrices[geoConnParent.ID]);\n }\n });\n }\n });\n }\n }\n parsePoseNodes() {\n const bindMatrices = {};\n if (\"Pose\" in fbxTree.Objects) {\n const BindPoseNode = fbxTree.Objects.Pose;\n for (const nodeID in BindPoseNode) {\n if (BindPoseNode[nodeID].attrType === \"BindPose\" && BindPoseNode[nodeID].NbPoseNodes > 0) {\n const poseNodes = BindPoseNode[nodeID].PoseNode;\n if (Array.isArray(poseNodes)) {\n poseNodes.forEach(function (poseNode) {\n bindMatrices[poseNode.Node] = new Matrix4().fromArray(poseNode.Matrix.a);\n });\n } else {\n bindMatrices[poseNodes.Node] = new Matrix4().fromArray(poseNodes.Matrix.a);\n }\n }\n }\n }\n return bindMatrices;\n }\n\n // Parse ambient color in FBXTree.GlobalSettings - if it's not set to black (default), create an ambient light\n createAmbientLight() {\n if (\"GlobalSettings\" in fbxTree && \"AmbientColor\" in fbxTree.GlobalSettings) {\n const ambientColor = fbxTree.GlobalSettings.AmbientColor.value;\n const r = ambientColor[0];\n const g = ambientColor[1];\n const b = ambientColor[2];\n if (r !== 0 || g !== 0 || b !== 0) {\n const color = new Color(r, g, b).convertSRGBToLinear();\n sceneGraph.add(new AmbientLight(color, 1));\n }\n }\n }\n}\n\n// parse Geometry data from FBXTree and return map of BufferGeometries\nclass GeometryParser {\n constructor() {\n this.negativeMaterialIndices = false;\n }\n\n // Parse nodes in FBXTree.Objects.Geometry\n parse(deformers) {\n const geometryMap = new Map();\n if (\"Geometry\" in fbxTree.Objects) {\n const geoNodes = fbxTree.Objects.Geometry;\n for (const nodeID in geoNodes) {\n const relationships = connections.get(parseInt(nodeID));\n const geo = this.parseGeometry(relationships, geoNodes[nodeID], deformers);\n geometryMap.set(parseInt(nodeID), geo);\n }\n }\n\n // report warnings\n\n if (this.negativeMaterialIndices === true) {\n console.warn(\"THREE.FBXLoader: The FBX file contains invalid (negative) material indices. The asset might not render as expected.\");\n }\n return geometryMap;\n }\n\n // Parse single node in FBXTree.Objects.Geometry\n parseGeometry(relationships, geoNode, deformers) {\n switch (geoNode.attrType) {\n case \"Mesh\":\n return this.parseMeshGeometry(relationships, geoNode, deformers);\n break;\n case \"NurbsCurve\":\n return this.parseNurbsGeometry(geoNode);\n break;\n }\n }\n\n // Parse single node mesh geometry in FBXTree.Objects.Geometry\n parseMeshGeometry(relationships, geoNode, deformers) {\n const skeletons = deformers.skeletons;\n const morphTargets = [];\n const modelNodes = relationships.parents.map(function (parent) {\n return fbxTree.Objects.Model[parent.ID];\n });\n\n // don't create geometry if it is not associated with any models\n if (modelNodes.length === 0) return;\n const skeleton = relationships.children.reduce(function (skeleton, child) {\n if (skeletons[child.ID] !== undefined) skeleton = skeletons[child.ID];\n return skeleton;\n }, null);\n relationships.children.forEach(function (child) {\n if (deformers.morphTargets[child.ID] !== undefined) {\n morphTargets.push(deformers.morphTargets[child.ID]);\n }\n });\n\n // Assume one model and get the preRotation from that\n // if there is more than one model associated with the geometry this may cause problems\n const modelNode = modelNodes[0];\n const transformData = {};\n if (\"RotationOrder\" in modelNode) transformData.eulerOrder = getEulerOrder(modelNode.RotationOrder.value);\n if (\"InheritType\" in modelNode) transformData.inheritType = parseInt(modelNode.InheritType.value);\n if (\"GeometricTranslation\" in modelNode) transformData.translation = modelNode.GeometricTranslation.value;\n if (\"GeometricRotation\" in modelNode) transformData.rotation = modelNode.GeometricRotation.value;\n if (\"GeometricScaling\" in modelNode) transformData.scale = modelNode.GeometricScaling.value;\n const transform = generateTransform(transformData);\n return this.genGeometry(geoNode, skeleton, morphTargets, transform);\n }\n\n // Generate a BufferGeometry from a node in FBXTree.Objects.Geometry\n genGeometry(geoNode, skeleton, morphTargets, preTransform) {\n const geo = new BufferGeometry();\n if (geoNode.attrName) geo.name = geoNode.attrName;\n const geoInfo = this.parseGeoNode(geoNode, skeleton);\n const buffers = this.genBuffers(geoInfo);\n const positionAttribute = new Float32BufferAttribute(buffers.vertex, 3);\n positionAttribute.applyMatrix4(preTransform);\n geo.setAttribute(\"position\", positionAttribute);\n if (buffers.colors.length > 0) {\n geo.setAttribute(\"color\", new Float32BufferAttribute(buffers.colors, 3));\n }\n if (skeleton) {\n geo.setAttribute(\"skinIndex\", new Uint16BufferAttribute(buffers.weightsIndices, 4));\n geo.setAttribute(\"skinWeight\", new Float32BufferAttribute(buffers.vertexWeights, 4));\n\n // used later to bind the skeleton to the model\n geo.FBX_Deformer = skeleton;\n }\n if (buffers.normal.length > 0) {\n const normalMatrix = new Matrix3().getNormalMatrix(preTransform);\n const normalAttribute = new Float32BufferAttribute(buffers.normal, 3);\n normalAttribute.applyNormalMatrix(normalMatrix);\n geo.setAttribute(\"normal\", normalAttribute);\n }\n buffers.uvs.forEach(function (uvBuffer, i) {\n const name = i === 0 ? \"uv\" : `uv${i}`;\n geo.setAttribute(name, new Float32BufferAttribute(buffers.uvs[i], 2));\n });\n if (geoInfo.material && geoInfo.material.mappingType !== \"AllSame\") {\n // Convert the material indices of each vertex into rendering groups on the geometry.\n let prevMaterialIndex = buffers.materialIndex[0];\n let startIndex = 0;\n buffers.materialIndex.forEach(function (currentIndex, i) {\n if (currentIndex !== prevMaterialIndex) {\n geo.addGroup(startIndex, i - startIndex, prevMaterialIndex);\n prevMaterialIndex = currentIndex;\n startIndex = i;\n }\n });\n\n // the loop above doesn't add the last group, do that here.\n if (geo.groups.length > 0) {\n const lastGroup = geo.groups[geo.groups.length - 1];\n const lastIndex = lastGroup.start + lastGroup.count;\n if (lastIndex !== buffers.materialIndex.length) {\n geo.addGroup(lastIndex, buffers.materialIndex.length - lastIndex, prevMaterialIndex);\n }\n }\n\n // case where there are multiple materials but the whole geometry is only\n // using one of them\n if (geo.groups.length === 0) {\n geo.addGroup(0, buffers.materialIndex.length, buffers.materialIndex[0]);\n }\n }\n this.addMorphTargets(geo, geoNode, morphTargets, preTransform);\n return geo;\n }\n parseGeoNode(geoNode, skeleton) {\n const geoInfo = {};\n geoInfo.vertexPositions = geoNode.Vertices !== undefined ? geoNode.Vertices.a : [];\n geoInfo.vertexIndices = geoNode.PolygonVertexIndex !== undefined ? geoNode.PolygonVertexIndex.a : [];\n if (geoNode.LayerElementColor) {\n geoInfo.color = this.parseVertexColors(geoNode.LayerElementColor[0]);\n }\n if (geoNode.LayerElementMaterial) {\n geoInfo.material = this.parseMaterialIndices(geoNode.LayerElementMaterial[0]);\n }\n if (geoNode.LayerElementNormal) {\n geoInfo.normal = this.parseNormals(geoNode.LayerElementNormal[0]);\n }\n if (geoNode.LayerElementUV) {\n geoInfo.uv = [];\n let i = 0;\n while (geoNode.LayerElementUV[i]) {\n if (geoNode.LayerElementUV[i].UV) {\n geoInfo.uv.push(this.parseUVs(geoNode.LayerElementUV[i]));\n }\n i++;\n }\n }\n geoInfo.weightTable = {};\n if (skeleton !== null) {\n geoInfo.skeleton = skeleton;\n skeleton.rawBones.forEach(function (rawBone, i) {\n // loop over the bone's vertex indices and weights\n rawBone.indices.forEach(function (index, j) {\n if (geoInfo.weightTable[index] === undefined) geoInfo.weightTable[index] = [];\n geoInfo.weightTable[index].push({\n id: i,\n weight: rawBone.weights[j]\n });\n });\n });\n }\n return geoInfo;\n }\n genBuffers(geoInfo) {\n const buffers = {\n vertex: [],\n normal: [],\n colors: [],\n uvs: [],\n materialIndex: [],\n vertexWeights: [],\n weightsIndices: []\n };\n let polygonIndex = 0;\n let faceLength = 0;\n let displayedWeightsWarning = false;\n\n // these will hold data for a single face\n let facePositionIndexes = [];\n let faceNormals = [];\n let faceColors = [];\n let faceUVs = [];\n let faceWeights = [];\n let faceWeightIndices = [];\n const scope = this;\n geoInfo.vertexIndices.forEach(function (vertexIndex, polygonVertexIndex) {\n let materialIndex;\n let endOfFace = false;\n\n // Face index and vertex index arrays are combined in a single array\n // A cube with quad faces looks like this:\n // PolygonVertexIndex: *24 {\n // a: 0, 1, 3, -3, 2, 3, 5, -5, 4, 5, 7, -7, 6, 7, 1, -1, 1, 7, 5, -4, 6, 0, 2, -5\n // }\n // Negative numbers mark the end of a face - first face here is 0, 1, 3, -3\n // to find index of last vertex bit shift the index: ^ - 1\n if (vertexIndex < 0) {\n vertexIndex = vertexIndex ^ -1; // equivalent to ( x * -1 ) - 1\n endOfFace = true;\n }\n let weightIndices = [];\n let weights = [];\n facePositionIndexes.push(vertexIndex * 3, vertexIndex * 3 + 1, vertexIndex * 3 + 2);\n if (geoInfo.color) {\n const data = getData(polygonVertexIndex, polygonIndex, vertexIndex, geoInfo.color);\n faceColors.push(data[0], data[1], data[2]);\n }\n if (geoInfo.skeleton) {\n if (geoInfo.weightTable[vertexIndex] !== undefined) {\n geoInfo.weightTable[vertexIndex].forEach(function (wt) {\n weights.push(wt.weight);\n weightIndices.push(wt.id);\n });\n }\n if (weights.length > 4) {\n if (!displayedWeightsWarning) {\n console.warn(\"THREE.FBXLoader: Vertex has more than 4 skinning weights assigned to vertex. Deleting additional weights.\");\n displayedWeightsWarning = true;\n }\n const wIndex = [0, 0, 0, 0];\n const Weight = [0, 0, 0, 0];\n weights.forEach(function (weight, weightIndex) {\n let currentWeight = weight;\n let currentIndex = weightIndices[weightIndex];\n Weight.forEach(function (comparedWeight, comparedWeightIndex, comparedWeightArray) {\n if (currentWeight > comparedWeight) {\n comparedWeightArray[comparedWeightIndex] = currentWeight;\n currentWeight = comparedWeight;\n const tmp = wIndex[comparedWeightIndex];\n wIndex[comparedWeightIndex] = currentIndex;\n currentIndex = tmp;\n }\n });\n });\n weightIndices = wIndex;\n weights = Weight;\n }\n\n // if the weight array is shorter than 4 pad with 0s\n while (weights.length < 4) {\n weights.push(0);\n weightIndices.push(0);\n }\n for (let i = 0; i < 4; ++i) {\n faceWeights.push(weights[i]);\n faceWeightIndices.push(weightIndices[i]);\n }\n }\n if (geoInfo.normal) {\n const data = getData(polygonVertexIndex, polygonIndex, vertexIndex, geoInfo.normal);\n faceNormals.push(data[0], data[1], data[2]);\n }\n if (geoInfo.material && geoInfo.material.mappingType !== \"AllSame\") {\n materialIndex = getData(polygonVertexIndex, polygonIndex, vertexIndex, geoInfo.material)[0];\n if (materialIndex < 0) {\n scope.negativeMaterialIndices = true;\n materialIndex = 0; // fallback\n }\n }\n\n if (geoInfo.uv) {\n geoInfo.uv.forEach(function (uv, i) {\n const data = getData(polygonVertexIndex, polygonIndex, vertexIndex, uv);\n if (faceUVs[i] === undefined) {\n faceUVs[i] = [];\n }\n faceUVs[i].push(data[0]);\n faceUVs[i].push(data[1]);\n });\n }\n faceLength++;\n if (endOfFace) {\n if (faceLength > 4) console.warn(\"THREE.FBXLoader: Polygons with more than four sides are not supported. Make sure to triangulate the geometry during export.\");\n scope.genFace(buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength);\n polygonIndex++;\n faceLength = 0;\n\n // reset arrays for the next face\n facePositionIndexes = [];\n faceNormals = [];\n faceColors = [];\n faceUVs = [];\n faceWeights = [];\n faceWeightIndices = [];\n }\n });\n return buffers;\n }\n\n // Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris\n genFace(buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength) {\n for (let i = 2; i < faceLength; i++) {\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[0]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[1]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[2]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[(i - 1) * 3]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[(i - 1) * 3 + 1]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[(i - 1) * 3 + 2]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[i * 3]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[i * 3 + 1]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[i * 3 + 2]]);\n if (geoInfo.skeleton) {\n buffers.vertexWeights.push(faceWeights[0]);\n buffers.vertexWeights.push(faceWeights[1]);\n buffers.vertexWeights.push(faceWeights[2]);\n buffers.vertexWeights.push(faceWeights[3]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4 + 1]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4 + 2]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4 + 3]);\n buffers.vertexWeights.push(faceWeights[i * 4]);\n buffers.vertexWeights.push(faceWeights[i * 4 + 1]);\n buffers.vertexWeights.push(faceWeights[i * 4 + 2]);\n buffers.vertexWeights.push(faceWeights[i * 4 + 3]);\n buffers.weightsIndices.push(faceWeightIndices[0]);\n buffers.weightsIndices.push(faceWeightIndices[1]);\n buffers.weightsIndices.push(faceWeightIndices[2]);\n buffers.weightsIndices.push(faceWeightIndices[3]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4 + 1]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4 + 2]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4 + 3]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4 + 1]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4 + 2]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4 + 3]);\n }\n if (geoInfo.color) {\n buffers.colors.push(faceColors[0]);\n buffers.colors.push(faceColors[1]);\n buffers.colors.push(faceColors[2]);\n buffers.colors.push(faceColors[(i - 1) * 3]);\n buffers.colors.push(faceColors[(i - 1) * 3 + 1]);\n buffers.colors.push(faceColors[(i - 1) * 3 + 2]);\n buffers.colors.push(faceColors[i * 3]);\n buffers.colors.push(faceColors[i * 3 + 1]);\n buffers.colors.push(faceColors[i * 3 + 2]);\n }\n if (geoInfo.material && geoInfo.material.mappingType !== \"AllSame\") {\n buffers.materialIndex.push(materialIndex);\n buffers.materialIndex.push(materialIndex);\n buffers.materialIndex.push(materialIndex);\n }\n if (geoInfo.normal) {\n buffers.normal.push(faceNormals[0]);\n buffers.normal.push(faceNormals[1]);\n buffers.normal.push(faceNormals[2]);\n buffers.normal.push(faceNormals[(i - 1) * 3]);\n buffers.normal.push(faceNormals[(i - 1) * 3 + 1]);\n buffers.normal.push(faceNormals[(i - 1) * 3 + 2]);\n buffers.normal.push(faceNormals[i * 3]);\n buffers.normal.push(faceNormals[i * 3 + 1]);\n buffers.normal.push(faceNormals[i * 3 + 2]);\n }\n if (geoInfo.uv) {\n geoInfo.uv.forEach(function (uv, j) {\n if (buffers.uvs[j] === undefined) buffers.uvs[j] = [];\n buffers.uvs[j].push(faceUVs[j][0]);\n buffers.uvs[j].push(faceUVs[j][1]);\n buffers.uvs[j].push(faceUVs[j][(i - 1) * 2]);\n buffers.uvs[j].push(faceUVs[j][(i - 1) * 2 + 1]);\n buffers.uvs[j].push(faceUVs[j][i * 2]);\n buffers.uvs[j].push(faceUVs[j][i * 2 + 1]);\n });\n }\n }\n }\n addMorphTargets(parentGeo, parentGeoNode, morphTargets, preTransform) {\n if (morphTargets.length === 0) return;\n parentGeo.morphTargetsRelative = true;\n parentGeo.morphAttributes.position = [];\n // parentGeo.morphAttributes.normal = []; // not implemented\n\n const scope = this;\n morphTargets.forEach(function (morphTarget) {\n morphTarget.rawTargets.forEach(function (rawTarget) {\n const morphGeoNode = fbxTree.Objects.Geometry[rawTarget.geoID];\n if (morphGeoNode !== undefined) {\n scope.genMorphGeometry(parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name);\n }\n });\n });\n }\n\n // a morph geometry node is similar to a standard node, and the node is also contained\n // in FBXTree.Objects.Geometry, however it can only have attributes for position, normal\n // and a special attribute Index defining which vertices of the original geometry are affected\n // Normal and position attributes only have data for the vertices that are affected by the morph\n genMorphGeometry(parentGeo, parentGeoNode, morphGeoNode, preTransform, name) {\n const vertexIndices = parentGeoNode.PolygonVertexIndex !== undefined ? parentGeoNode.PolygonVertexIndex.a : [];\n const morphPositionsSparse = morphGeoNode.Vertices !== undefined ? morphGeoNode.Vertices.a : [];\n const indices = morphGeoNode.Indexes !== undefined ? morphGeoNode.Indexes.a : [];\n const length = parentGeo.attributes.position.count * 3;\n const morphPositions = new Float32Array(length);\n for (let i = 0; i < indices.length; i++) {\n const morphIndex = indices[i] * 3;\n morphPositions[morphIndex] = morphPositionsSparse[i * 3];\n morphPositions[morphIndex + 1] = morphPositionsSparse[i * 3 + 1];\n morphPositions[morphIndex + 2] = morphPositionsSparse[i * 3 + 2];\n }\n\n // TODO: add morph normal support\n const morphGeoInfo = {\n vertexIndices: vertexIndices,\n vertexPositions: morphPositions\n };\n const morphBuffers = this.genBuffers(morphGeoInfo);\n const positionAttribute = new Float32BufferAttribute(morphBuffers.vertex, 3);\n positionAttribute.name = name || morphGeoNode.attrName;\n positionAttribute.applyMatrix4(preTransform);\n parentGeo.morphAttributes.position.push(positionAttribute);\n }\n\n // Parse normal from FBXTree.Objects.Geometry.LayerElementNormal if it exists\n parseNormals(NormalNode) {\n const mappingType = NormalNode.MappingInformationType;\n const referenceType = NormalNode.ReferenceInformationType;\n const buffer = NormalNode.Normals.a;\n let indexBuffer = [];\n if (referenceType === \"IndexToDirect\") {\n if (\"NormalIndex\" in NormalNode) {\n indexBuffer = NormalNode.NormalIndex.a;\n } else if (\"NormalsIndex\" in NormalNode) {\n indexBuffer = NormalNode.NormalsIndex.a;\n }\n }\n return {\n dataSize: 3,\n buffer: buffer,\n indices: indexBuffer,\n mappingType: mappingType,\n referenceType: referenceType\n };\n }\n\n // Parse UVs from FBXTree.Objects.Geometry.LayerElementUV if it exists\n parseUVs(UVNode) {\n const mappingType = UVNode.MappingInformationType;\n const referenceType = UVNode.ReferenceInformationType;\n const buffer = UVNode.UV.a;\n let indexBuffer = [];\n if (referenceType === \"IndexToDirect\") {\n indexBuffer = UVNode.UVIndex.a;\n }\n return {\n dataSize: 2,\n buffer: buffer,\n indices: indexBuffer,\n mappingType: mappingType,\n referenceType: referenceType\n };\n }\n\n // Parse Vertex Colors from FBXTree.Objects.Geometry.LayerElementColor if it exists\n parseVertexColors(ColorNode) {\n const mappingType = ColorNode.MappingInformationType;\n const referenceType = ColorNode.ReferenceInformationType;\n const buffer = ColorNode.Colors.a;\n let indexBuffer = [];\n if (referenceType === \"IndexToDirect\") {\n indexBuffer = ColorNode.ColorIndex.a;\n }\n for (let i = 0, c = new Color(); i < buffer.length; i += 4) {\n c.fromArray(buffer, i).convertSRGBToLinear().toArray(buffer, i);\n }\n return {\n dataSize: 4,\n buffer: buffer,\n indices: indexBuffer,\n mappingType: mappingType,\n referenceType: referenceType\n };\n }\n\n // Parse mapping and material data in FBXTree.Objects.Geometry.LayerElementMaterial if it exists\n parseMaterialIndices(MaterialNode) {\n const mappingType = MaterialNode.MappingInformationType;\n const referenceType = MaterialNode.ReferenceInformationType;\n if (mappingType === \"NoMappingInformation\") {\n return {\n dataSize: 1,\n buffer: [0],\n indices: [0],\n mappingType: \"AllSame\",\n referenceType: referenceType\n };\n }\n const materialIndexBuffer = MaterialNode.Materials.a;\n\n // Since materials are stored as indices, there's a bit of a mismatch between FBX and what\n // we expect.So we create an intermediate buffer that points to the index in the buffer,\n // for conforming with the other functions we've written for other data.\n const materialIndices = [];\n for (let i = 0; i < materialIndexBuffer.length; ++i) {\n materialIndices.push(i);\n }\n return {\n dataSize: 1,\n buffer: materialIndexBuffer,\n indices: materialIndices,\n mappingType: mappingType,\n referenceType: referenceType\n };\n }\n\n // Generate a NurbGeometry from a node in FBXTree.Objects.Geometry\n parseNurbsGeometry(geoNode) {\n const order = parseInt(geoNode.Order);\n if (isNaN(order)) {\n console.error(\"THREE.FBXLoader: Invalid Order %s given for geometry ID: %s\", geoNode.Order, geoNode.id);\n return new BufferGeometry();\n }\n const degree = order - 1;\n const knots = geoNode.KnotVector.a;\n const controlPoints = [];\n const pointsValues = geoNode.Points.a;\n for (let i = 0, l = pointsValues.length; i < l; i += 4) {\n controlPoints.push(new Vector4().fromArray(pointsValues, i));\n }\n let startKnot, endKnot;\n if (geoNode.Form === \"Closed\") {\n controlPoints.push(controlPoints[0]);\n } else if (geoNode.Form === \"Periodic\") {\n startKnot = degree;\n endKnot = knots.length - 1 - startKnot;\n for (let i = 0; i < degree; ++i) {\n controlPoints.push(controlPoints[i]);\n }\n }\n const curve = new NURBSCurve(degree, knots, controlPoints, startKnot, endKnot);\n const points = curve.getPoints(controlPoints.length * 12);\n return new BufferGeometry().setFromPoints(points);\n }\n}\n\n// parse animation data from FBXTree\nclass AnimationParser {\n // take raw animation clips and turn them into three.js animation clips\n parse() {\n const animationClips = [];\n const rawClips = this.parseClips();\n if (rawClips !== undefined) {\n for (const key in rawClips) {\n const rawClip = rawClips[key];\n const clip = this.addClip(rawClip);\n animationClips.push(clip);\n }\n }\n return animationClips;\n }\n parseClips() {\n // since the actual transformation data is stored in FBXTree.Objects.AnimationCurve,\n // if this is undefined we can safely assume there are no animations\n if (fbxTree.Objects.AnimationCurve === undefined) return undefined;\n const curveNodesMap = this.parseAnimationCurveNodes();\n this.parseAnimationCurves(curveNodesMap);\n const layersMap = this.parseAnimationLayers(curveNodesMap);\n const rawClips = this.parseAnimStacks(layersMap);\n return rawClips;\n }\n\n // parse nodes in FBXTree.Objects.AnimationCurveNode\n // each AnimationCurveNode holds data for an animation transform for a model (e.g. left arm rotation )\n // and is referenced by an AnimationLayer\n parseAnimationCurveNodes() {\n const rawCurveNodes = fbxTree.Objects.AnimationCurveNode;\n const curveNodesMap = new Map();\n for (const nodeID in rawCurveNodes) {\n const rawCurveNode = rawCurveNodes[nodeID];\n if (rawCurveNode.attrName.match(/S|R|T|DeformPercent/) !== null) {\n const curveNode = {\n id: rawCurveNode.id,\n attr: rawCurveNode.attrName,\n curves: {}\n };\n curveNodesMap.set(curveNode.id, curveNode);\n }\n }\n return curveNodesMap;\n }\n\n // parse nodes in FBXTree.Objects.AnimationCurve and connect them up to\n // previously parsed AnimationCurveNodes. Each AnimationCurve holds data for a single animated\n // axis ( e.g. times and values of x rotation)\n parseAnimationCurves(curveNodesMap) {\n const rawCurves = fbxTree.Objects.AnimationCurve;\n\n // TODO: Many values are identical up to roundoff error, but won't be optimised\n // e.g. position times: [0, 0.4, 0. 8]\n // position values: [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.235384487103147e-7, 93.67520904541016, -0.9982695579528809]\n // clearly, this should be optimised to\n // times: [0], positions [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809]\n // this shows up in nearly every FBX file, and generally time array is length > 100\n\n for (const nodeID in rawCurves) {\n const animationCurve = {\n id: rawCurves[nodeID].id,\n times: rawCurves[nodeID].KeyTime.a.map(convertFBXTimeToSeconds),\n values: rawCurves[nodeID].KeyValueFloat.a\n };\n const relationships = connections.get(animationCurve.id);\n if (relationships !== undefined) {\n const animationCurveID = relationships.parents[0].ID;\n const animationCurveRelationship = relationships.parents[0].relationship;\n if (animationCurveRelationship.match(/X/)) {\n curveNodesMap.get(animationCurveID).curves[\"x\"] = animationCurve;\n } else if (animationCurveRelationship.match(/Y/)) {\n curveNodesMap.get(animationCurveID).curves[\"y\"] = animationCurve;\n } else if (animationCurveRelationship.match(/Z/)) {\n curveNodesMap.get(animationCurveID).curves[\"z\"] = animationCurve;\n } else if (animationCurveRelationship.match(/DeformPercent/) && curveNodesMap.has(animationCurveID)) {\n curveNodesMap.get(animationCurveID).curves[\"morph\"] = animationCurve;\n }\n }\n }\n }\n\n // parse nodes in FBXTree.Objects.AnimationLayer. Each layers holds references\n // to various AnimationCurveNodes and is referenced by an AnimationStack node\n // note: theoretically a stack can have multiple layers, however in practice there always seems to be one per stack\n parseAnimationLayers(curveNodesMap) {\n const rawLayers = fbxTree.Objects.AnimationLayer;\n const layersMap = new Map();\n for (const nodeID in rawLayers) {\n const layerCurveNodes = [];\n const connection = connections.get(parseInt(nodeID));\n if (connection !== undefined) {\n // all the animationCurveNodes used in the layer\n const children = connection.children;\n children.forEach(function (child, i) {\n if (curveNodesMap.has(child.ID)) {\n const curveNode = curveNodesMap.get(child.ID);\n\n // check that the curves are defined for at least one axis, otherwise ignore the curveNode\n if (curveNode.curves.x !== undefined || curveNode.curves.y !== undefined || curveNode.curves.z !== undefined) {\n if (layerCurveNodes[i] === undefined) {\n const modelID = connections.get(child.ID).parents.filter(function (parent) {\n return parent.relationship !== undefined;\n })[0].ID;\n if (modelID !== undefined) {\n const rawModel = fbxTree.Objects.Model[modelID.toString()];\n if (rawModel === undefined) {\n console.warn(\"THREE.FBXLoader: Encountered a unused curve.\", child);\n return;\n }\n const node = {\n modelName: rawModel.attrName ? PropertyBinding.sanitizeNodeName(rawModel.attrName) : \"\",\n ID: rawModel.id,\n initialPosition: [0, 0, 0],\n initialRotation: [0, 0, 0],\n initialScale: [1, 1, 1]\n };\n sceneGraph.traverse(function (child) {\n if (child.ID === rawModel.id) {\n node.transform = child.matrix;\n if (child.userData.transformData) node.eulerOrder = child.userData.transformData.eulerOrder;\n }\n });\n if (!node.transform) node.transform = new Matrix4();\n\n // if the animated model is pre rotated, we'll have to apply the pre rotations to every\n // animation value as well\n if (\"PreRotation\" in rawModel) node.preRotation = rawModel.PreRotation.value;\n if (\"PostRotation\" in rawModel) node.postRotation = rawModel.PostRotation.value;\n layerCurveNodes[i] = node;\n }\n }\n if (layerCurveNodes[i]) layerCurveNodes[i][curveNode.attr] = curveNode;\n } else if (curveNode.curves.morph !== undefined) {\n if (layerCurveNodes[i] === undefined) {\n const deformerID = connections.get(child.ID).parents.filter(function (parent) {\n return parent.relationship !== undefined;\n })[0].ID;\n const morpherID = connections.get(deformerID).parents[0].ID;\n const geoID = connections.get(morpherID).parents[0].ID;\n\n // assuming geometry is not used in more than one model\n const modelID = connections.get(geoID).parents[0].ID;\n const rawModel = fbxTree.Objects.Model[modelID];\n const node = {\n modelName: rawModel.attrName ? PropertyBinding.sanitizeNodeName(rawModel.attrName) : \"\",\n morphName: fbxTree.Objects.Deformer[deformerID].attrName\n };\n layerCurveNodes[i] = node;\n }\n layerCurveNodes[i][curveNode.attr] = curveNode;\n }\n }\n });\n layersMap.set(parseInt(nodeID), layerCurveNodes);\n }\n }\n return layersMap;\n }\n\n // parse nodes in FBXTree.Objects.AnimationStack. These are the top level node in the animation\n // hierarchy. Each Stack node will be used to create a AnimationClip\n parseAnimStacks(layersMap) {\n const rawStacks = fbxTree.Objects.AnimationStack;\n\n // connect the stacks (clips) up to the layers\n const rawClips = {};\n for (const nodeID in rawStacks) {\n const children = connections.get(parseInt(nodeID)).children;\n if (children.length > 1) {\n // it seems like stacks will always be associated with a single layer. But just in case there are files\n // where there are multiple layers per stack, we'll display a warning\n console.warn(\"THREE.FBXLoader: Encountered an animation stack with multiple layers, this is currently not supported. Ignoring subsequent layers.\");\n }\n const layer = layersMap.get(children[0].ID);\n rawClips[nodeID] = {\n name: rawStacks[nodeID].attrName,\n layer: layer\n };\n }\n return rawClips;\n }\n addClip(rawClip) {\n let tracks = [];\n const scope = this;\n rawClip.layer.forEach(function (rawTracks) {\n tracks = tracks.concat(scope.generateTracks(rawTracks));\n });\n return new AnimationClip(rawClip.name, -1, tracks);\n }\n generateTracks(rawTracks) {\n const tracks = [];\n let initialPosition = new Vector3();\n let initialRotation = new Quaternion();\n let initialScale = new Vector3();\n if (rawTracks.transform) rawTracks.transform.decompose(initialPosition, initialRotation, initialScale);\n initialPosition = initialPosition.toArray();\n initialRotation = new Euler().setFromQuaternion(initialRotation, rawTracks.eulerOrder).toArray();\n initialScale = initialScale.toArray();\n if (rawTracks.T !== undefined && Object.keys(rawTracks.T.curves).length > 0) {\n const positionTrack = this.generateVectorTrack(rawTracks.modelName, rawTracks.T.curves, initialPosition, \"position\");\n if (positionTrack !== undefined) tracks.push(positionTrack);\n }\n if (rawTracks.R !== undefined && Object.keys(rawTracks.R.curves).length > 0) {\n const rotationTrack = this.generateRotationTrack(rawTracks.modelName, rawTracks.R.curves, initialRotation, rawTracks.preRotation, rawTracks.postRotation, rawTracks.eulerOrder);\n if (rotationTrack !== undefined) tracks.push(rotationTrack);\n }\n if (rawTracks.S !== undefined && Object.keys(rawTracks.S.curves).length > 0) {\n const scaleTrack = this.generateVectorTrack(rawTracks.modelName, rawTracks.S.curves, initialScale, \"scale\");\n if (scaleTrack !== undefined) tracks.push(scaleTrack);\n }\n if (rawTracks.DeformPercent !== undefined) {\n const morphTrack = this.generateMorphTrack(rawTracks);\n if (morphTrack !== undefined) tracks.push(morphTrack);\n }\n return tracks;\n }\n generateVectorTrack(modelName, curves, initialValue, type) {\n const times = this.getTimesForAllAxes(curves);\n const values = this.getKeyframeTrackValues(times, curves, initialValue);\n return new VectorKeyframeTrack(modelName + \".\" + type, times, values);\n }\n generateRotationTrack(modelName, curves, initialValue, preRotation, postRotation, eulerOrder) {\n if (curves.x !== undefined) {\n this.interpolateRotations(curves.x);\n curves.x.values = curves.x.values.map(MathUtils.degToRad);\n }\n if (curves.y !== undefined) {\n this.interpolateRotations(curves.y);\n curves.y.values = curves.y.values.map(MathUtils.degToRad);\n }\n if (curves.z !== undefined) {\n this.interpolateRotations(curves.z);\n curves.z.values = curves.z.values.map(MathUtils.degToRad);\n }\n const times = this.getTimesForAllAxes(curves);\n const values = this.getKeyframeTrackValues(times, curves, initialValue);\n if (preRotation !== undefined) {\n preRotation = preRotation.map(MathUtils.degToRad);\n preRotation.push(eulerOrder);\n preRotation = new Euler().fromArray(preRotation);\n preRotation = new Quaternion().setFromEuler(preRotation);\n }\n if (postRotation !== undefined) {\n postRotation = postRotation.map(MathUtils.degToRad);\n postRotation.push(eulerOrder);\n postRotation = new Euler().fromArray(postRotation);\n postRotation = new Quaternion().setFromEuler(postRotation).invert();\n }\n const quaternion = new Quaternion();\n const euler = new Euler();\n const quaternionValues = [];\n for (let i = 0; i < values.length; i += 3) {\n euler.set(values[i], values[i + 1], values[i + 2], eulerOrder);\n quaternion.setFromEuler(euler);\n if (preRotation !== undefined) quaternion.premultiply(preRotation);\n if (postRotation !== undefined) quaternion.multiply(postRotation);\n quaternion.toArray(quaternionValues, i / 3 * 4);\n }\n return new QuaternionKeyframeTrack(modelName + \".quaternion\", times, quaternionValues);\n }\n generateMorphTrack(rawTracks) {\n const curves = rawTracks.DeformPercent.curves.morph;\n const values = curves.values.map(function (val) {\n return val / 100;\n });\n const morphNum = sceneGraph.getObjectByName(rawTracks.modelName).morphTargetDictionary[rawTracks.morphName];\n return new NumberKeyframeTrack(rawTracks.modelName + \".morphTargetInfluences[\" + morphNum + \"]\", curves.times, values);\n }\n\n // For all animated objects, times are defined separately for each axis\n // Here we'll combine the times into one sorted array without duplicates\n getTimesForAllAxes(curves) {\n let times = [];\n\n // first join together the times for each axis, if defined\n if (curves.x !== undefined) times = times.concat(curves.x.times);\n if (curves.y !== undefined) times = times.concat(curves.y.times);\n if (curves.z !== undefined) times = times.concat(curves.z.times);\n\n // then sort them\n times = times.sort(function (a, b) {\n return a - b;\n });\n\n // and remove duplicates\n if (times.length > 1) {\n let targetIndex = 1;\n let lastValue = times[0];\n for (let i = 1; i < times.length; i++) {\n const currentValue = times[i];\n if (currentValue !== lastValue) {\n times[targetIndex] = currentValue;\n lastValue = currentValue;\n targetIndex++;\n }\n }\n times = times.slice(0, targetIndex);\n }\n return times;\n }\n getKeyframeTrackValues(times, curves, initialValue) {\n const prevValue = initialValue;\n const values = [];\n let xIndex = -1;\n let yIndex = -1;\n let zIndex = -1;\n times.forEach(function (time) {\n if (curves.x) xIndex = curves.x.times.indexOf(time);\n if (curves.y) yIndex = curves.y.times.indexOf(time);\n if (curves.z) zIndex = curves.z.times.indexOf(time);\n\n // if there is an x value defined for this frame, use that\n if (xIndex !== -1) {\n const xValue = curves.x.values[xIndex];\n values.push(xValue);\n prevValue[0] = xValue;\n } else {\n // otherwise use the x value from the previous frame\n values.push(prevValue[0]);\n }\n if (yIndex !== -1) {\n const yValue = curves.y.values[yIndex];\n values.push(yValue);\n prevValue[1] = yValue;\n } else {\n values.push(prevValue[1]);\n }\n if (zIndex !== -1) {\n const zValue = curves.z.values[zIndex];\n values.push(zValue);\n prevValue[2] = zValue;\n } else {\n values.push(prevValue[2]);\n }\n });\n return values;\n }\n\n // Rotations are defined as Euler angles which can have values of any size\n // These will be converted to quaternions which don't support values greater than\n // PI, so we'll interpolate large rotations\n interpolateRotations(curve) {\n for (let i = 1; i < curve.values.length; i++) {\n const initialValue = curve.values[i - 1];\n const valuesSpan = curve.values[i] - initialValue;\n const absoluteSpan = Math.abs(valuesSpan);\n if (absoluteSpan >= 180) {\n const numSubIntervals = absoluteSpan / 180;\n const step = valuesSpan / numSubIntervals;\n let nextValue = initialValue + step;\n const initialTime = curve.times[i - 1];\n const timeSpan = curve.times[i] - initialTime;\n const interval = timeSpan / numSubIntervals;\n let nextTime = initialTime + interval;\n const interpolatedTimes = [];\n const interpolatedValues = [];\n while (nextTime < curve.times[i]) {\n interpolatedTimes.push(nextTime);\n nextTime += interval;\n interpolatedValues.push(nextValue);\n nextValue += step;\n }\n curve.times = inject(curve.times, i, interpolatedTimes);\n curve.values = inject(curve.values, i, interpolatedValues);\n }\n }\n }\n}\n\n// parse an FBX file in ASCII format\nclass TextParser {\n getPrevNode() {\n return this.nodeStack[this.currentIndent - 2];\n }\n getCurrentNode() {\n return this.nodeStack[this.currentIndent - 1];\n }\n getCurrentProp() {\n return this.currentProp;\n }\n pushStack(node) {\n this.nodeStack.push(node);\n this.currentIndent += 1;\n }\n popStack() {\n this.nodeStack.pop();\n this.currentIndent -= 1;\n }\n setCurrentProp(val, name) {\n this.currentProp = val;\n this.currentPropName = name;\n }\n parse(text) {\n this.currentIndent = 0;\n this.allNodes = new FBXTree();\n this.nodeStack = [];\n this.currentProp = [];\n this.currentPropName = \"\";\n const scope = this;\n const split = text.split(/[\\r\\n]+/);\n split.forEach(function (line, i) {\n const matchComment = line.match(/^[\\s\\t]*;/);\n const matchEmpty = line.match(/^[\\s\\t]*$/);\n if (matchComment || matchEmpty) return;\n const matchBeginning = line.match(\"^\\\\t{\" + scope.currentIndent + \"}(\\\\w+):(.*){\", \"\");\n const matchProperty = line.match(\"^\\\\t{\" + scope.currentIndent + \"}(\\\\w+):[\\\\s\\\\t\\\\r\\\\n](.*)\");\n const matchEnd = line.match(\"^\\\\t{\" + (scope.currentIndent - 1) + \"}}\");\n if (matchBeginning) {\n scope.parseNodeBegin(line, matchBeginning);\n } else if (matchProperty) {\n scope.parseNodeProperty(line, matchProperty, split[++i]);\n } else if (matchEnd) {\n scope.popStack();\n } else if (line.match(/^[^\\s\\t}]/)) {\n // large arrays are split over multiple lines terminated with a ',' character\n // if this is encountered the line needs to be joined to the previous line\n scope.parseNodePropertyContinued(line);\n }\n });\n return this.allNodes;\n }\n parseNodeBegin(line, property) {\n const nodeName = property[1].trim().replace(/^\"/, \"\").replace(/\"$/, \"\");\n const nodeAttrs = property[2].split(\",\").map(function (attr) {\n return attr.trim().replace(/^\"/, \"\").replace(/\"$/, \"\");\n });\n const node = {\n name: nodeName\n };\n const attrs = this.parseNodeAttr(nodeAttrs);\n const currentNode = this.getCurrentNode();\n\n // a top node\n if (this.currentIndent === 0) {\n this.allNodes.add(nodeName, node);\n } else {\n // a subnode\n\n // if the subnode already exists, append it\n if (nodeName in currentNode) {\n // special case Pose needs PoseNodes as an array\n if (nodeName === \"PoseNode\") {\n currentNode.PoseNode.push(node);\n } else if (currentNode[nodeName].id !== undefined) {\n currentNode[nodeName] = {};\n currentNode[nodeName][currentNode[nodeName].id] = currentNode[nodeName];\n }\n if (attrs.id !== \"\") currentNode[nodeName][attrs.id] = node;\n } else if (typeof attrs.id === \"number\") {\n currentNode[nodeName] = {};\n currentNode[nodeName][attrs.id] = node;\n } else if (nodeName !== \"Properties70\") {\n if (nodeName === \"PoseNode\") currentNode[nodeName] = [node];else currentNode[nodeName] = node;\n }\n }\n if (typeof attrs.id === \"number\") node.id = attrs.id;\n if (attrs.name !== \"\") node.attrName = attrs.name;\n if (attrs.type !== \"\") node.attrType = attrs.type;\n this.pushStack(node);\n }\n parseNodeAttr(attrs) {\n let id = attrs[0];\n if (attrs[0] !== \"\") {\n id = parseInt(attrs[0]);\n if (isNaN(id)) {\n id = attrs[0];\n }\n }\n let name = \"\",\n type = \"\";\n if (attrs.length > 1) {\n name = attrs[1].replace(/^(\\w+)::/, \"\");\n type = attrs[2];\n }\n return {\n id: id,\n name: name,\n type: type\n };\n }\n parseNodeProperty(line, property, contentLine) {\n let propName = property[1].replace(/^\"/, \"\").replace(/\"$/, \"\").trim();\n let propValue = property[2].replace(/^\"/, \"\").replace(/\"$/, \"\").trim();\n\n // for special case: base64 image data follows \"Content: ,\" line\n //\tContent: ,\n //\t \"/9j/4RDaRXhpZgAATU0A...\"\n if (propName === \"Content\" && propValue === \",\") {\n propValue = contentLine.replace(/\"/g, \"\").replace(/,$/, \"\").trim();\n }\n const currentNode = this.getCurrentNode();\n const parentName = currentNode.name;\n if (parentName === \"Properties70\") {\n this.parseNodeSpecialProperty(line, propName, propValue);\n return;\n }\n\n // Connections\n if (propName === \"C\") {\n const connProps = propValue.split(\",\").slice(1);\n const from = parseInt(connProps[0]);\n const to = parseInt(connProps[1]);\n let rest = propValue.split(\",\").slice(3);\n rest = rest.map(function (elem) {\n return elem.trim().replace(/^\"/, \"\");\n });\n propName = \"connections\";\n propValue = [from, to];\n append(propValue, rest);\n if (currentNode[propName] === undefined) {\n currentNode[propName] = [];\n }\n }\n\n // Node\n if (propName === \"Node\") currentNode.id = propValue;\n\n // connections\n if (propName in currentNode && Array.isArray(currentNode[propName])) {\n currentNode[propName].push(propValue);\n } else {\n if (propName !== \"a\") currentNode[propName] = propValue;else currentNode.a = propValue;\n }\n this.setCurrentProp(currentNode, propName);\n\n // convert string to array, unless it ends in ',' in which case more will be added to it\n if (propName === \"a\" && propValue.slice(-1) !== \",\") {\n currentNode.a = parseNumberArray(propValue);\n }\n }\n parseNodePropertyContinued(line) {\n const currentNode = this.getCurrentNode();\n currentNode.a += line;\n\n // if the line doesn't end in ',' we have reached the end of the property value\n // so convert the string to an array\n if (line.slice(-1) !== \",\") {\n currentNode.a = parseNumberArray(currentNode.a);\n }\n }\n\n // parse \"Property70\"\n parseNodeSpecialProperty(line, propName, propValue) {\n // split this\n // P: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",1,1,1\n // into array like below\n // [\"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\", \"1,1,1\" ]\n const props = propValue.split('\",').map(function (prop) {\n return prop.trim().replace(/^\\\"/, \"\").replace(/\\s/, \"_\");\n });\n const innerPropName = props[0];\n const innerPropType1 = props[1];\n const innerPropType2 = props[2];\n const innerPropFlag = props[3];\n let innerPropValue = props[4];\n\n // cast values where needed, otherwise leave as strings\n switch (innerPropType1) {\n case \"int\":\n case \"enum\":\n case \"bool\":\n case \"ULongLong\":\n case \"double\":\n case \"Number\":\n case \"FieldOfView\":\n innerPropValue = parseFloat(innerPropValue);\n break;\n case \"Color\":\n case \"ColorRGB\":\n case \"Vector3D\":\n case \"Lcl_Translation\":\n case \"Lcl_Rotation\":\n case \"Lcl_Scaling\":\n innerPropValue = parseNumberArray(innerPropValue);\n break;\n }\n\n // CAUTION: these props must append to parent's parent\n this.getPrevNode()[innerPropName] = {\n type: innerPropType1,\n type2: innerPropType2,\n flag: innerPropFlag,\n value: innerPropValue\n };\n this.setCurrentProp(this.getPrevNode(), innerPropName);\n }\n}\n\n// Parse an FBX file in Binary format\nclass BinaryParser {\n parse(buffer) {\n const reader = new BinaryReader(buffer);\n reader.skip(23); // skip magic 23 bytes\n\n const version = reader.getUint32();\n if (version < 6400) {\n throw new Error(\"THREE.FBXLoader: FBX version not supported, FileVersion: \" + version);\n }\n const allNodes = new FBXTree();\n while (!this.endOfContent(reader)) {\n const node = this.parseNode(reader, version);\n if (node !== null) allNodes.add(node.name, node);\n }\n return allNodes;\n }\n\n // Check if reader has reached the end of content.\n endOfContent(reader) {\n // footer size: 160bytes + 16-byte alignment padding\n // - 16bytes: magic\n // - padding til 16-byte alignment (at least 1byte?)\n //\t(seems like some exporters embed fixed 15 or 16bytes?)\n // - 4bytes: magic\n // - 4bytes: version\n // - 120bytes: zero\n // - 16bytes: magic\n if (reader.size() % 16 === 0) {\n return (reader.getOffset() + 160 + 16 & ~0xf) >= reader.size();\n } else {\n return reader.getOffset() + 160 + 16 >= reader.size();\n }\n }\n\n // recursively parse nodes until the end of the file is reached\n parseNode(reader, version) {\n const node = {};\n\n // The first three data sizes depends on version.\n const endOffset = version >= 7500 ? reader.getUint64() : reader.getUint32();\n const numProperties = version >= 7500 ? reader.getUint64() : reader.getUint32();\n version >= 7500 ? reader.getUint64() : reader.getUint32(); // the returned propertyListLen is not used\n\n const nameLen = reader.getUint8();\n const name = reader.getString(nameLen);\n\n // Regards this node as NULL-record if endOffset is zero\n if (endOffset === 0) return null;\n const propertyList = [];\n for (let i = 0; i < numProperties; i++) {\n propertyList.push(this.parseProperty(reader));\n }\n\n // Regards the first three elements in propertyList as id, attrName, and attrType\n const id = propertyList.length > 0 ? propertyList[0] : \"\";\n const attrName = propertyList.length > 1 ? propertyList[1] : \"\";\n const attrType = propertyList.length > 2 ? propertyList[2] : \"\";\n\n // check if this node represents just a single property\n // like (name, 0) set or (name2, [0, 1, 2]) set of {name: 0, name2: [0, 1, 2]}\n node.singleProperty = numProperties === 1 && reader.getOffset() === endOffset ? true : false;\n while (endOffset > reader.getOffset()) {\n const subNode = this.parseNode(reader, version);\n if (subNode !== null) this.parseSubNode(name, node, subNode);\n }\n node.propertyList = propertyList; // raw property list used by parent\n\n if (typeof id === \"number\") node.id = id;\n if (attrName !== \"\") node.attrName = attrName;\n if (attrType !== \"\") node.attrType = attrType;\n if (name !== \"\") node.name = name;\n return node;\n }\n parseSubNode(name, node, subNode) {\n // special case: child node is single property\n if (subNode.singleProperty === true) {\n const value = subNode.propertyList[0];\n if (Array.isArray(value)) {\n node[subNode.name] = subNode;\n subNode.a = value;\n } else {\n node[subNode.name] = value;\n }\n } else if (name === \"Connections\" && subNode.name === \"C\") {\n const array = [];\n subNode.propertyList.forEach(function (property, i) {\n // first Connection is FBX type (OO, OP, etc.). We'll discard these\n if (i !== 0) array.push(property);\n });\n if (node.connections === undefined) {\n node.connections = [];\n }\n node.connections.push(array);\n } else if (subNode.name === \"Properties70\") {\n const keys = Object.keys(subNode);\n keys.forEach(function (key) {\n node[key] = subNode[key];\n });\n } else if (name === \"Properties70\" && subNode.name === \"P\") {\n let innerPropName = subNode.propertyList[0];\n let innerPropType1 = subNode.propertyList[1];\n const innerPropType2 = subNode.propertyList[2];\n const innerPropFlag = subNode.propertyList[3];\n let innerPropValue;\n if (innerPropName.indexOf(\"Lcl \") === 0) innerPropName = innerPropName.replace(\"Lcl \", \"Lcl_\");\n if (innerPropType1.indexOf(\"Lcl \") === 0) innerPropType1 = innerPropType1.replace(\"Lcl \", \"Lcl_\");\n if (innerPropType1 === \"Color\" || innerPropType1 === \"ColorRGB\" || innerPropType1 === \"Vector\" || innerPropType1 === \"Vector3D\" || innerPropType1.indexOf(\"Lcl_\") === 0) {\n innerPropValue = [subNode.propertyList[4], subNode.propertyList[5], subNode.propertyList[6]];\n } else {\n innerPropValue = subNode.propertyList[4];\n }\n\n // this will be copied to parent, see above\n node[innerPropName] = {\n type: innerPropType1,\n type2: innerPropType2,\n flag: innerPropFlag,\n value: innerPropValue\n };\n } else if (node[subNode.name] === undefined) {\n if (typeof subNode.id === \"number\") {\n node[subNode.name] = {};\n node[subNode.name][subNode.id] = subNode;\n } else {\n node[subNode.name] = subNode;\n }\n } else {\n if (subNode.name === \"PoseNode\") {\n if (!Array.isArray(node[subNode.name])) {\n node[subNode.name] = [node[subNode.name]];\n }\n node[subNode.name].push(subNode);\n } else if (node[subNode.name][subNode.id] === undefined) {\n node[subNode.name][subNode.id] = subNode;\n }\n }\n }\n parseProperty(reader) {\n const type = reader.getString(1);\n let length;\n switch (type) {\n case \"C\":\n return reader.getBoolean();\n case \"D\":\n return reader.getFloat64();\n case \"F\":\n return reader.getFloat32();\n case \"I\":\n return reader.getInt32();\n case \"L\":\n return reader.getInt64();\n case \"R\":\n length = reader.getUint32();\n return reader.getArrayBuffer(length);\n case \"S\":\n length = reader.getUint32();\n return reader.getString(length);\n case \"Y\":\n return reader.getInt16();\n case \"b\":\n case \"c\":\n case \"d\":\n case \"f\":\n case \"i\":\n case \"l\":\n const arrayLength = reader.getUint32();\n const encoding = reader.getUint32(); // 0: non-compressed, 1: compressed\n const compressedLength = reader.getUint32();\n if (encoding === 0) {\n switch (type) {\n case \"b\":\n case \"c\":\n return reader.getBooleanArray(arrayLength);\n case \"d\":\n return reader.getFloat64Array(arrayLength);\n case \"f\":\n return reader.getFloat32Array(arrayLength);\n case \"i\":\n return reader.getInt32Array(arrayLength);\n case \"l\":\n return reader.getInt64Array(arrayLength);\n }\n }\n const data = fflate.unzlibSync(new Uint8Array(reader.getArrayBuffer(compressedLength)));\n const reader2 = new BinaryReader(data.buffer);\n switch (type) {\n case \"b\":\n case \"c\":\n return reader2.getBooleanArray(arrayLength);\n case \"d\":\n return reader2.getFloat64Array(arrayLength);\n case \"f\":\n return reader2.getFloat32Array(arrayLength);\n case \"i\":\n return reader2.getInt32Array(arrayLength);\n case \"l\":\n return reader2.getInt64Array(arrayLength);\n }\n break;\n // cannot happen but is required by the DeepScan\n\n default:\n throw new Error(\"THREE.FBXLoader: Unknown property type \" + type);\n }\n }\n}\nclass BinaryReader {\n constructor(buffer, littleEndian) {\n this.dv = new DataView(buffer);\n this.offset = 0;\n this.littleEndian = littleEndian !== undefined ? littleEndian : true;\n this._textDecoder = new TextDecoder();\n }\n getOffset() {\n return this.offset;\n }\n size() {\n return this.dv.buffer.byteLength;\n }\n skip(length) {\n this.offset += length;\n }\n\n // seems like true/false representation depends on exporter.\n // true: 1 or 'Y'(=0x59), false: 0 or 'T'(=0x54)\n // then sees LSB.\n getBoolean() {\n return (this.getUint8() & 1) === 1;\n }\n getBooleanArray(size) {\n const a = [];\n for (let i = 0; i < size; i++) {\n a.push(this.getBoolean());\n }\n return a;\n }\n getUint8() {\n const value = this.dv.getUint8(this.offset);\n this.offset += 1;\n return value;\n }\n getInt16() {\n const value = this.dv.getInt16(this.offset, this.littleEndian);\n this.offset += 2;\n return value;\n }\n getInt32() {\n const value = this.dv.getInt32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n getInt32Array(size) {\n const a = [];\n for (let i = 0; i < size; i++) {\n a.push(this.getInt32());\n }\n return a;\n }\n getUint32() {\n const value = this.dv.getUint32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n // JavaScript doesn't support 64-bit integer so calculate this here\n // 1 << 32 will return 1 so using multiply operation instead here.\n // There's a possibility that this method returns wrong value if the value\n // is out of the range between Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER.\n // TODO: safely handle 64-bit integer\n getInt64() {\n let low, high;\n if (this.littleEndian) {\n low = this.getUint32();\n high = this.getUint32();\n } else {\n high = this.getUint32();\n low = this.getUint32();\n }\n\n // calculate negative value\n if (high & 0x80000000) {\n high = ~high & 0xffffffff;\n low = ~low & 0xffffffff;\n if (low === 0xffffffff) high = high + 1 & 0xffffffff;\n low = low + 1 & 0xffffffff;\n return -(high * 0x100000000 + low);\n }\n return high * 0x100000000 + low;\n }\n getInt64Array(size) {\n const a = [];\n for (let i = 0; i < size; i++) {\n a.push(this.getInt64());\n }\n return a;\n }\n\n // Note: see getInt64() comment\n getUint64() {\n let low, high;\n if (this.littleEndian) {\n low = this.getUint32();\n high = this.getUint32();\n } else {\n high = this.getUint32();\n low = this.getUint32();\n }\n return high * 0x100000000 + low;\n }\n getFloat32() {\n const value = this.dv.getFloat32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n getFloat32Array(size) {\n const a = [];\n for (let i = 0; i < size; i++) {\n a.push(this.getFloat32());\n }\n return a;\n }\n getFloat64() {\n const value = this.dv.getFloat64(this.offset, this.littleEndian);\n this.offset += 8;\n return value;\n }\n getFloat64Array(size) {\n const a = [];\n for (let i = 0; i < size; i++) {\n a.push(this.getFloat64());\n }\n return a;\n }\n getArrayBuffer(size) {\n const value = this.dv.buffer.slice(this.offset, this.offset + size);\n this.offset += size;\n return value;\n }\n getString(size) {\n const start = this.offset;\n let a = new Uint8Array(this.dv.buffer, start, size);\n this.skip(size);\n const nullByte = a.indexOf(0);\n if (nullByte >= 0) a = new Uint8Array(this.dv.buffer, start, nullByte);\n return this._textDecoder.decode(a);\n }\n}\n\n// FBXTree holds a representation of the FBX data, returned by the TextParser ( FBX ASCII format)\n// and BinaryParser( FBX Binary format)\nclass FBXTree {\n add(key, val) {\n this[key] = val;\n }\n}\n\n// ************** UTILITY FUNCTIONS **************\n\nfunction isFbxFormatBinary(buffer) {\n const CORRECT = \"Kaydara\\u0020FBX\\u0020Binary\\u0020\\u0020\\0\";\n return buffer.byteLength >= CORRECT.length && CORRECT === convertArrayBufferToString(buffer, 0, CORRECT.length);\n}\nfunction isFbxFormatASCII(text) {\n const CORRECT = [\"K\", \"a\", \"y\", \"d\", \"a\", \"r\", \"a\", \"\\\\\", \"F\", \"B\", \"X\", \"\\\\\", \"B\", \"i\", \"n\", \"a\", \"r\", \"y\", \"\\\\\", \"\\\\\"];\n let cursor = 0;\n function read(offset) {\n const result = text[offset - 1];\n text = text.slice(cursor + offset);\n cursor++;\n return result;\n }\n for (let i = 0; i < CORRECT.length; ++i) {\n const num = read(1);\n if (num === CORRECT[i]) {\n return false;\n }\n }\n return true;\n}\nfunction getFbxVersion(text) {\n const versionRegExp = /FBXVersion: (\\d+)/;\n const match = text.match(versionRegExp);\n if (match) {\n const version = parseInt(match[1]);\n return version;\n }\n throw new Error(\"THREE.FBXLoader: Cannot find the version number for the file given.\");\n}\n\n// Converts FBX ticks into real time seconds.\nfunction convertFBXTimeToSeconds(time) {\n return time / 46186158000;\n}\nconst dataArray = [];\n\n// extracts the data from the correct position in the FBX array based on indexing type\nfunction getData(polygonVertexIndex, polygonIndex, vertexIndex, infoObject) {\n let index;\n switch (infoObject.mappingType) {\n case \"ByPolygonVertex\":\n index = polygonVertexIndex;\n break;\n case \"ByPolygon\":\n index = polygonIndex;\n break;\n case \"ByVertice\":\n index = vertexIndex;\n break;\n case \"AllSame\":\n index = infoObject.indices[0];\n break;\n default:\n console.warn(\"THREE.FBXLoader: unknown attribute mapping type \" + infoObject.mappingType);\n }\n if (infoObject.referenceType === \"IndexToDirect\") index = infoObject.indices[index];\n const from = index * infoObject.dataSize;\n const to = from + infoObject.dataSize;\n return slice(dataArray, infoObject.buffer, from, to);\n}\nconst tempEuler = new Euler();\nconst tempVec = new Vector3();\n\n// generate transformation from FBX transform data\n// ref: https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_10CDD63C_79C1_4F2D_BB28_AD2BE65A02ED_htm\n// ref: http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=cpp_ref/_transformations_2main_8cxx-example.html,topicNumber=cpp_ref__transformations_2main_8cxx_example_htmlfc10a1e1-b18d-4e72-9dc0-70d0f1959f5e\nfunction generateTransform(transformData) {\n const lTranslationM = new Matrix4();\n const lPreRotationM = new Matrix4();\n const lRotationM = new Matrix4();\n const lPostRotationM = new Matrix4();\n const lScalingM = new Matrix4();\n const lScalingPivotM = new Matrix4();\n const lScalingOffsetM = new Matrix4();\n const lRotationOffsetM = new Matrix4();\n const lRotationPivotM = new Matrix4();\n const lParentGX = new Matrix4();\n const lParentLX = new Matrix4();\n const lGlobalT = new Matrix4();\n const inheritType = transformData.inheritType ? transformData.inheritType : 0;\n if (transformData.translation) lTranslationM.setPosition(tempVec.fromArray(transformData.translation));\n if (transformData.preRotation) {\n const array = transformData.preRotation.map(MathUtils.degToRad);\n array.push(transformData.eulerOrder || Euler.DEFAULT_ORDER);\n lPreRotationM.makeRotationFromEuler(tempEuler.fromArray(array));\n }\n if (transformData.rotation) {\n const array = transformData.rotation.map(MathUtils.degToRad);\n array.push(transformData.eulerOrder || Euler.DEFAULT_ORDER);\n lRotationM.makeRotationFromEuler(tempEuler.fromArray(array));\n }\n if (transformData.postRotation) {\n const array = transformData.postRotation.map(MathUtils.degToRad);\n array.push(transformData.eulerOrder || Euler.DEFAULT_ORDER);\n lPostRotationM.makeRotationFromEuler(tempEuler.fromArray(array));\n lPostRotationM.invert();\n }\n if (transformData.scale) lScalingM.scale(tempVec.fromArray(transformData.scale));\n\n // Pivots and offsets\n if (transformData.scalingOffset) lScalingOffsetM.setPosition(tempVec.fromArray(transformData.scalingOffset));\n if (transformData.scalingPivot) lScalingPivotM.setPosition(tempVec.fromArray(transformData.scalingPivot));\n if (transformData.rotationOffset) lRotationOffsetM.setPosition(tempVec.fromArray(transformData.rotationOffset));\n if (transformData.rotationPivot) lRotationPivotM.setPosition(tempVec.fromArray(transformData.rotationPivot));\n\n // parent transform\n if (transformData.parentMatrixWorld) {\n lParentLX.copy(transformData.parentMatrix);\n lParentGX.copy(transformData.parentMatrixWorld);\n }\n const lLRM = lPreRotationM.clone().multiply(lRotationM).multiply(lPostRotationM);\n // Global Rotation\n const lParentGRM = new Matrix4();\n lParentGRM.extractRotation(lParentGX);\n\n // Global Shear*Scaling\n const lParentTM = new Matrix4();\n lParentTM.copyPosition(lParentGX);\n const lParentGRSM = lParentTM.clone().invert().multiply(lParentGX);\n const lParentGSM = lParentGRM.clone().invert().multiply(lParentGRSM);\n const lLSM = lScalingM;\n const lGlobalRS = new Matrix4();\n if (inheritType === 0) {\n lGlobalRS.copy(lParentGRM).multiply(lLRM).multiply(lParentGSM).multiply(lLSM);\n } else if (inheritType === 1) {\n lGlobalRS.copy(lParentGRM).multiply(lParentGSM).multiply(lLRM).multiply(lLSM);\n } else {\n const lParentLSM = new Matrix4().scale(new Vector3().setFromMatrixScale(lParentLX));\n const lParentLSM_inv = lParentLSM.clone().invert();\n const lParentGSM_noLocal = lParentGSM.clone().multiply(lParentLSM_inv);\n lGlobalRS.copy(lParentGRM).multiply(lLRM).multiply(lParentGSM_noLocal).multiply(lLSM);\n }\n const lRotationPivotM_inv = lRotationPivotM.clone().invert();\n const lScalingPivotM_inv = lScalingPivotM.clone().invert();\n // Calculate the local transform matrix\n let lTransform = lTranslationM.clone().multiply(lRotationOffsetM).multiply(lRotationPivotM).multiply(lPreRotationM).multiply(lRotationM).multiply(lPostRotationM).multiply(lRotationPivotM_inv).multiply(lScalingOffsetM).multiply(lScalingPivotM).multiply(lScalingM).multiply(lScalingPivotM_inv);\n const lLocalTWithAllPivotAndOffsetInfo = new Matrix4().copyPosition(lTransform);\n const lGlobalTranslation = lParentGX.clone().multiply(lLocalTWithAllPivotAndOffsetInfo);\n lGlobalT.copyPosition(lGlobalTranslation);\n lTransform = lGlobalT.clone().multiply(lGlobalRS);\n\n // from global to local\n lTransform.premultiply(lParentGX.invert());\n return lTransform;\n}\n\n// Returns the three.js intrinsic Euler order corresponding to FBX extrinsic Euler order\n// ref: http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html\nfunction getEulerOrder(order) {\n order = order || 0;\n const enums = [\"ZYX\",\n // -> XYZ extrinsic\n \"YZX\",\n // -> XZY extrinsic\n \"XZY\",\n // -> YZX extrinsic\n \"ZXY\",\n // -> YXZ extrinsic\n \"YXZ\",\n // -> ZXY extrinsic\n \"XYZ\" // -> ZYX extrinsic\n //'SphericXYZ', // not possible to support\n ];\n\n if (order === 6) {\n console.warn(\"THREE.FBXLoader: unsupported Euler Order: Spherical XYZ. Animations and rotations may be incorrect.\");\n return enums[0];\n }\n return enums[order];\n}\n\n// Parses comma separated list of numbers and returns them an array.\n// Used internally by the TextParser\nfunction parseNumberArray(value) {\n const array = value.split(\",\").map(function (val) {\n return parseFloat(val);\n });\n return array;\n}\nfunction convertArrayBufferToString(buffer, from, to) {\n if (from === undefined) from = 0;\n if (to === undefined) to = buffer.byteLength;\n return new TextDecoder().decode(new Uint8Array(buffer, from, to));\n}\nfunction append(a, b) {\n for (let i = 0, j = a.length, l = b.length; i < l; i++, j++) {\n a[j] = b[i];\n }\n}\nfunction slice(a, b, from, to) {\n for (let i = from, j = 0; i < to; i++, j++) {\n a[j] = b[i];\n }\n return a;\n}\n\n// inject array a2 into array a1 at index\nfunction inject(a1, index, a2) {\n return a1.slice(0, index).concat(a2).concat(a1.slice(index));\n}\nexport { FBXLoader };","map":{"version":3,"names":["AmbientLight","AnimationClip","Bone","BufferGeometry","ClampToEdgeWrapping","Color","DirectionalLight","EquirectangularReflectionMapping","Euler","FileLoader","Float32BufferAttribute","Group","Line","LineBasicMaterial","Loader","LoaderUtils","MathUtils","Matrix3","Matrix4","Mesh","MeshLambertMaterial","MeshPhongMaterial","NumberKeyframeTrack","Object3D","OrthographicCamera","PerspectiveCamera","PointLight","PropertyBinding","Quaternion","QuaternionKeyframeTrack","RepeatWrapping","Skeleton","SkinnedMesh","SpotLight","Texture","TextureLoader","Uint16BufferAttribute","Vector3","Vector4","VectorKeyframeTrack","SRGBColorSpace","fflate","NURBSCurve","fbxTree","connections","sceneGraph","FBXLoader","constructor","manager","load","url","onLoad","onProgress","onError","scope","path","extractUrlBase","loader","setPath","setResponseType","setRequestHeader","requestHeader","setWithCredentials","withCredentials","buffer","parse","e","console","error","itemError","FBXBuffer","isFbxFormatBinary","BinaryParser","FBXText","convertArrayBufferToString","isFbxFormatASCII","Error","getFbxVersion","TextParser","textureLoader","resourcePath","setCrossOrigin","crossOrigin","FBXTreeParser","parseConnections","images","parseImages","textures","parseTextures","materials","parseMaterials","deformers","parseDeformers","geometryMap","GeometryParser","parseScene","connectionMap","Map","rawConnections","Connections","forEach","rawConnection","fromID","toID","relationship","has","set","parents","children","parentRelationship","ID","get","push","childRelationship","blobs","Objects","videoNodes","Video","nodeID","videoNode","id","parseInt","RelativeFilename","Filename","arrayBufferContent","Content","ArrayBuffer","byteLength","base64Content","image","parseImage","filename","undefined","split","pop","content","fileName","extension","slice","lastIndexOf","toLowerCase","type","getHandler","warn","array","Uint8Array","window","URL","createObjectURL","Blob","textureMap","textureNodes","texture","parseTexture","textureNode","loadTexture","name","attrName","wrapModeU","WrapModeU","wrapModeV","WrapModeV","valueU","value","valueV","wrapS","wrapT","values","Scaling","repeat","x","y","Translation","offset","currentPath","length","indexOf","FileName","materialMap","materialNodes","Material","material","parseMaterial","materialNode","ShadingModel","parameters","parseParameters","setValues","BumpFactor","bumpScale","Diffuse","color","fromArray","convertSRGBToLinear","DiffuseColor","DisplacementFactor","displacementScale","Emissive","emissive","EmissiveColor","EmissiveFactor","emissiveIntensity","parseFloat","Opacity","opacity","transparent","ReflectionFactor","reflectivity","Shininess","shininess","Specular","specular","SpecularColor","child","bumpMap","getTexture","aoMap","map","colorSpace","displacementMap","emissiveMap","normalMap","envMap","mapping","specularMap","alphaMap","LayeredTexture","skeletons","morphTargets","DeformerNodes","Deformer","deformerNode","relationships","attrType","skeleton","parseSkeleton","geometryID","morphTarget","rawTargets","parseMorphTargets","deformerNodes","rawBones","boneNode","rawBone","indices","weights","transformLink","TransformLink","a","Indexes","Weights","bones","rawMorphTargets","i","morphTargetNode","rawMorphTarget","initialWeight","DeformPercent","fullWeights","FullWeights","geoID","filter","modelMap","parseModels","modelNodes","Model","model","modelNode","setLookAtProperties","parentConnections","connection","parent","add","bindSkeleton","createAmbientLight","traverse","node","userData","transformData","parentMatrix","matrix","parentMatrixWorld","matrixWorld","transform","generateTransform","applyMatrix4","updateWorldMatrix","animations","AnimationParser","isGroup","buildSkeleton","createCamera","createLight","createMesh","createCurve","sanitizeNodeName","getTransformData","bone","subBone","copy","cameraAttribute","attr","NodeAttribute","CameraProjectionType","nearClippingPlane","NearPlane","farClippingPlane","FarPlane","width","innerWidth","height","innerHeight","AspectWidth","AspectHeight","aspect","fov","FieldOfView","focalLength","FocalLength","setFocalLength","lightAttribute","LightType","intensity","Intensity","CastLightOnObject","distance","FarAttenuationEnd","EnableFarAttenuation","decay","angle","Math","PI","InnerAngle","degToRad","penumbra","OuterAngle","max","CastShadows","castShadow","geometry","DEFAULT_MATERIAL_NAME","attributes","vertexColors","FBX_Deformer","normalizeSkinWeights","reduce","geo","linewidth","inheritType","InheritType","eulerOrder","getEulerOrder","RotationOrder","translation","Lcl_Translation","preRotation","PreRotation","rotation","Lcl_Rotation","postRotation","PostRotation","scale","Lcl_Scaling","scalingOffset","ScalingOffset","scalingPivot","ScalingPivot","rotationOffset","RotationOffset","rotationPivot","RotationPivot","lookAtTarget","pos","target","position","lookAt","bindMatrices","parsePoseNodes","geoRelationships","geoConnParent","bind","BindPoseNode","Pose","NbPoseNodes","poseNodes","PoseNode","Array","isArray","poseNode","Node","Matrix","GlobalSettings","ambientColor","AmbientColor","r","g","b","negativeMaterialIndices","geoNodes","Geometry","parseGeometry","geoNode","parseMeshGeometry","parseNurbsGeometry","GeometricTranslation","GeometricRotation","GeometricScaling","genGeometry","preTransform","geoInfo","parseGeoNode","buffers","genBuffers","positionAttribute","vertex","setAttribute","colors","weightsIndices","vertexWeights","normal","normalMatrix","getNormalMatrix","normalAttribute","applyNormalMatrix","uvs","uvBuffer","mappingType","prevMaterialIndex","materialIndex","startIndex","currentIndex","addGroup","groups","lastGroup","lastIndex","start","count","addMorphTargets","vertexPositions","Vertices","vertexIndices","PolygonVertexIndex","LayerElementColor","parseVertexColors","LayerElementMaterial","parseMaterialIndices","LayerElementNormal","parseNormals","LayerElementUV","uv","UV","parseUVs","weightTable","index","j","weight","polygonIndex","faceLength","displayedWeightsWarning","facePositionIndexes","faceNormals","faceColors","faceUVs","faceWeights","faceWeightIndices","vertexIndex","polygonVertexIndex","endOfFace","weightIndices","data","getData","wt","wIndex","Weight","weightIndex","currentWeight","comparedWeight","comparedWeightIndex","comparedWeightArray","tmp","genFace","parentGeo","parentGeoNode","morphTargetsRelative","morphAttributes","rawTarget","morphGeoNode","genMorphGeometry","morphPositionsSparse","morphPositions","Float32Array","morphIndex","morphGeoInfo","morphBuffers","NormalNode","MappingInformationType","referenceType","ReferenceInformationType","Normals","indexBuffer","NormalIndex","NormalsIndex","dataSize","UVNode","UVIndex","ColorNode","Colors","ColorIndex","c","toArray","MaterialNode","materialIndexBuffer","Materials","materialIndices","order","Order","isNaN","degree","knots","KnotVector","controlPoints","pointsValues","Points","l","startKnot","endKnot","Form","curve","points","getPoints","setFromPoints","animationClips","rawClips","parseClips","key","rawClip","clip","addClip","AnimationCurve","curveNodesMap","parseAnimationCurveNodes","parseAnimationCurves","layersMap","parseAnimationLayers","parseAnimStacks","rawCurveNodes","AnimationCurveNode","rawCurveNode","match","curveNode","curves","rawCurves","animationCurve","times","KeyTime","convertFBXTimeToSeconds","KeyValueFloat","animationCurveID","animationCurveRelationship","rawLayers","AnimationLayer","layerCurveNodes","z","modelID","rawModel","toString","modelName","initialPosition","initialRotation","initialScale","morph","deformerID","morpherID","morphName","rawStacks","AnimationStack","layer","tracks","rawTracks","concat","generateTracks","decompose","setFromQuaternion","T","Object","keys","positionTrack","generateVectorTrack","R","rotationTrack","generateRotationTrack","S","scaleTrack","morphTrack","generateMorphTrack","initialValue","getTimesForAllAxes","getKeyframeTrackValues","interpolateRotations","setFromEuler","invert","quaternion","euler","quaternionValues","premultiply","multiply","val","morphNum","getObjectByName","morphTargetDictionary","sort","targetIndex","lastValue","currentValue","prevValue","xIndex","yIndex","zIndex","time","xValue","yValue","zValue","valuesSpan","absoluteSpan","abs","numSubIntervals","step","nextValue","initialTime","timeSpan","interval","nextTime","interpolatedTimes","interpolatedValues","inject","getPrevNode","nodeStack","currentIndent","getCurrentNode","getCurrentProp","currentProp","pushStack","popStack","setCurrentProp","currentPropName","text","allNodes","FBXTree","line","matchComment","matchEmpty","matchBeginning","matchProperty","matchEnd","parseNodeBegin","parseNodeProperty","parseNodePropertyContinued","property","nodeName","trim","replace","nodeAttrs","attrs","parseNodeAttr","currentNode","contentLine","propName","propValue","parentName","parseNodeSpecialProperty","connProps","from","to","rest","elem","append","parseNumberArray","props","prop","innerPropName","innerPropType1","innerPropType2","innerPropFlag","innerPropValue","type2","flag","reader","BinaryReader","skip","version","getUint32","endOfContent","parseNode","size","getOffset","endOffset","getUint64","numProperties","nameLen","getUint8","getString","propertyList","parseProperty","singleProperty","subNode","parseSubNode","getBoolean","getFloat64","getFloat32","getInt32","getInt64","getArrayBuffer","getInt16","arrayLength","encoding","compressedLength","getBooleanArray","getFloat64Array","getFloat32Array","getInt32Array","getInt64Array","unzlibSync","reader2","littleEndian","dv","DataView","_textDecoder","TextDecoder","low","high","nullByte","decode","CORRECT","cursor","read","result","num","versionRegExp","dataArray","infoObject","tempEuler","tempVec","lTranslationM","lPreRotationM","lRotationM","lPostRotationM","lScalingM","lScalingPivotM","lScalingOffsetM","lRotationOffsetM","lRotationPivotM","lParentGX","lParentLX","lGlobalT","setPosition","DEFAULT_ORDER","makeRotationFromEuler","lLRM","clone","lParentGRM","extractRotation","lParentTM","copyPosition","lParentGRSM","lParentGSM","lLSM","lGlobalRS","lParentLSM","setFromMatrixScale","lParentLSM_inv","lParentGSM_noLocal","lRotationPivotM_inv","lScalingPivotM_inv","lTransform","lLocalTWithAllPivotAndOffsetInfo","lGlobalTranslation","enums","a1","a2"],"sources":["/Users/mac/projects/mime/mine/src/FBXLoader.js"],"sourcesContent":["import {\n AmbientLight,\n AnimationClip,\n Bone,\n BufferGeometry,\n ClampToEdgeWrapping,\n Color,\n DirectionalLight,\n EquirectangularReflectionMapping,\n Euler,\n FileLoader,\n Float32BufferAttribute,\n Group,\n Line,\n LineBasicMaterial,\n Loader,\n LoaderUtils,\n MathUtils,\n Matrix3,\n Matrix4,\n Mesh,\n MeshLambertMaterial,\n MeshPhongMaterial,\n NumberKeyframeTrack,\n Object3D,\n OrthographicCamera,\n PerspectiveCamera,\n PointLight,\n PropertyBinding,\n Quaternion,\n QuaternionKeyframeTrack,\n RepeatWrapping,\n Skeleton,\n SkinnedMesh,\n SpotLight,\n Texture,\n TextureLoader,\n Uint16BufferAttribute,\n Vector3,\n Vector4,\n VectorKeyframeTrack,\n SRGBColorSpace,\n} from \"three\";\nimport * as fflate from \"../public/libs/fflate.module\";\nimport { NURBSCurve } from \"../public/curves/NURBSCurve.js\";\n\n/**\n * Loader loads FBX file and generates Group representing FBX scene.\n * Requires FBX file to be >= 7.0 and in ASCII or >= 6400 in Binary format\n * Versions lower than this may load but will probably have errors\n *\n * Needs Support:\n * Morph normals / blend shape normals\n *\n * FBX format references:\n * \thttps://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_index_html (C++ SDK reference)\n *\n * Binary format specification:\n *\thttps://code.blender.org/2013/08/fbx-binary-file-format-specification/\n */\n\nlet fbxTree;\nlet connections;\nlet sceneGraph;\n\nclass FBXLoader extends Loader {\n constructor(manager) {\n super(manager);\n }\n\n load(url, onLoad, onProgress, onError) {\n const scope = this;\n\n const path =\n scope.path === \"\" ? LoaderUtils.extractUrlBase(url) : scope.path;\n\n const loader = new FileLoader(this.manager);\n loader.setPath(scope.path);\n loader.setResponseType(\"arraybuffer\");\n loader.setRequestHeader(scope.requestHeader);\n loader.setWithCredentials(scope.withCredentials);\n\n loader.load(\n url,\n function (buffer) {\n try {\n onLoad(scope.parse(buffer, path));\n } catch (e) {\n if (onError) {\n onError(e);\n } else {\n console.error(e);\n }\n\n scope.manager.itemError(url);\n }\n },\n onProgress,\n onError\n );\n }\n\n parse(FBXBuffer, path) {\n if (isFbxFormatBinary(FBXBuffer)) {\n fbxTree = new BinaryParser().parse(FBXBuffer);\n } else {\n const FBXText = convertArrayBufferToString(FBXBuffer);\n\n if (!isFbxFormatASCII(FBXText)) {\n throw new Error(\"THREE.FBXLoader: Unknown format.\");\n }\n\n if (getFbxVersion(FBXText) < 7000) {\n throw new Error(\n \"THREE.FBXLoader: FBX version not supported, FileVersion: \" +\n getFbxVersion(FBXText)\n );\n }\n\n fbxTree = new TextParser().parse(FBXText);\n }\n\n // console.log( fbxTree );\n\n const textureLoader = new TextureLoader(this.manager)\n .setPath(this.resourcePath || path)\n .setCrossOrigin(this.crossOrigin);\n\n return new FBXTreeParser(textureLoader, this.manager).parse(fbxTree);\n }\n}\n\n// Parse the FBXTree object returned by the BinaryParser or TextParser and return a Group\nclass FBXTreeParser {\n constructor(textureLoader, manager) {\n this.textureLoader = textureLoader;\n this.manager = manager;\n }\n\n parse() {\n connections = this.parseConnections();\n\n const images = this.parseImages();\n const textures = this.parseTextures(images);\n const materials = this.parseMaterials(textures);\n const deformers = this.parseDeformers();\n const geometryMap = new GeometryParser().parse(deformers);\n\n this.parseScene(deformers, geometryMap, materials);\n\n return sceneGraph;\n }\n\n // Parses FBXTree.Connections which holds parent-child connections between objects (e.g. material -> texture, model->geometry )\n // and details the connection type\n parseConnections() {\n const connectionMap = new Map();\n\n if (\"Connections\" in fbxTree) {\n const rawConnections = fbxTree.Connections.connections;\n\n rawConnections.forEach(function (rawConnection) {\n const fromID = rawConnection[0];\n const toID = rawConnection[1];\n const relationship = rawConnection[2];\n\n if (!connectionMap.has(fromID)) {\n connectionMap.set(fromID, {\n parents: [],\n children: [],\n });\n }\n\n const parentRelationship = { ID: toID, relationship: relationship };\n connectionMap.get(fromID).parents.push(parentRelationship);\n\n if (!connectionMap.has(toID)) {\n connectionMap.set(toID, {\n parents: [],\n children: [],\n });\n }\n\n const childRelationship = { ID: fromID, relationship: relationship };\n connectionMap.get(toID).children.push(childRelationship);\n });\n }\n\n return connectionMap;\n }\n\n // Parse FBXTree.Objects.Video for embedded image data\n // These images are connected to textures in FBXTree.Objects.Textures\n // via FBXTree.Connections.\n parseImages() {\n const images = {};\n const blobs = {};\n\n if (\"Video\" in fbxTree.Objects) {\n const videoNodes = fbxTree.Objects.Video;\n\n for (const nodeID in videoNodes) {\n const videoNode = videoNodes[nodeID];\n\n const id = parseInt(nodeID);\n\n images[id] = videoNode.RelativeFilename || videoNode.Filename;\n\n // raw image data is in videoNode.Content\n if (\"Content\" in videoNode) {\n const arrayBufferContent =\n videoNode.Content instanceof ArrayBuffer &&\n videoNode.Content.byteLength > 0;\n const base64Content =\n typeof videoNode.Content === \"string\" && videoNode.Content !== \"\";\n\n if (arrayBufferContent || base64Content) {\n const image = this.parseImage(videoNodes[nodeID]);\n\n blobs[videoNode.RelativeFilename || videoNode.Filename] = image;\n }\n }\n }\n }\n\n for (const id in images) {\n const filename = images[id];\n\n if (blobs[filename] !== undefined) images[id] = blobs[filename];\n else images[id] = images[id].split(\"\\\\\").pop();\n }\n\n return images;\n }\n\n // Parse embedded image data in FBXTree.Video.Content\n parseImage(videoNode) {\n const content = videoNode.Content;\n const fileName = videoNode.RelativeFilename || videoNode.Filename;\n const extension = fileName\n .slice(fileName.lastIndexOf(\".\") + 1)\n .toLowerCase();\n\n let type;\n\n switch (extension) {\n case \"bmp\":\n type = \"image/bmp\";\n break;\n\n case \"jpg\":\n case \"jpeg\":\n type = \"image/jpeg\";\n break;\n\n case \"png\":\n type = \"image/png\";\n break;\n\n case \"tif\":\n type = \"image/tiff\";\n break;\n\n case \"tga\":\n if (this.manager.getHandler(\".tga\") === null) {\n console.warn(\"FBXLoader: TGA loader not found, skipping \", fileName);\n }\n\n type = \"image/tga\";\n break;\n\n default:\n console.warn(\n 'FBXLoader: Image type \"' + extension + '\" is not supported.'\n );\n return;\n }\n\n if (typeof content === \"string\") {\n // ASCII format\n\n return \"data:\" + type + \";base64,\" + content;\n } else {\n // Binary Format\n\n const array = new Uint8Array(content);\n return window.URL.createObjectURL(new Blob([array], { type: type }));\n }\n }\n\n // Parse nodes in FBXTree.Objects.Texture\n // These contain details such as UV scaling, cropping, rotation etc and are connected\n // to images in FBXTree.Objects.Video\n parseTextures(images) {\n const textureMap = new Map();\n\n if (\"Texture\" in fbxTree.Objects) {\n const textureNodes = fbxTree.Objects.Texture;\n for (const nodeID in textureNodes) {\n const texture = this.parseTexture(textureNodes[nodeID], images);\n textureMap.set(parseInt(nodeID), texture);\n }\n }\n\n return textureMap;\n }\n\n // Parse individual node in FBXTree.Objects.Texture\n parseTexture(textureNode, images) {\n const texture = this.loadTexture(textureNode, images);\n\n texture.ID = textureNode.id;\n\n texture.name = textureNode.attrName;\n\n const wrapModeU = textureNode.WrapModeU;\n const wrapModeV = textureNode.WrapModeV;\n\n const valueU = wrapModeU !== undefined ? wrapModeU.value : 0;\n const valueV = wrapModeV !== undefined ? wrapModeV.value : 0;\n\n // http://download.autodesk.com/us/fbx/SDKdocs/FBX_SDK_Help/files/fbxsdkref/class_k_fbx_texture.html#889640e63e2e681259ea81061b85143a\n // 0: repeat(default), 1: clamp\n\n texture.wrapS = valueU === 0 ? RepeatWrapping : ClampToEdgeWrapping;\n texture.wrapT = valueV === 0 ? RepeatWrapping : ClampToEdgeWrapping;\n\n if (\"Scaling\" in textureNode) {\n const values = textureNode.Scaling.value;\n\n texture.repeat.x = values[0];\n texture.repeat.y = values[1];\n }\n\n if (\"Translation\" in textureNode) {\n const values = textureNode.Translation.value;\n\n texture.offset.x = values[0];\n texture.offset.y = values[1];\n }\n\n return texture;\n }\n\n // load a texture specified as a blob or data URI, or via an external URL using TextureLoader\n loadTexture(textureNode, images) {\n let fileName;\n\n const currentPath = this.textureLoader.path;\n\n const children = connections.get(textureNode.id).children;\n\n if (\n children !== undefined &&\n children.length > 0 &&\n images[children[0].ID] !== undefined\n ) {\n fileName = images[children[0].ID];\n\n if (fileName.indexOf(\"blob:\") === 0 || fileName.indexOf(\"data:\") === 0) {\n this.textureLoader.setPath(undefined);\n }\n }\n\n let texture;\n\n const extension = textureNode.FileName.slice(-3).toLowerCase();\n\n if (extension === \"tga\") {\n const loader = this.manager.getHandler(\".tga\");\n\n if (loader === null) {\n console.warn(\n \"FBXLoader: TGA loader not found, creating placeholder texture for\",\n textureNode.RelativeFilename\n );\n texture = new Texture();\n } else {\n loader.setPath(this.textureLoader.path);\n texture = loader.load(fileName);\n }\n } else if (extension === \"psd\") {\n console.warn(\n \"FBXLoader: PSD textures are not supported, creating placeholder texture for\",\n textureNode.RelativeFilename\n );\n texture = new Texture();\n } else {\n texture = this.textureLoader.load(fileName);\n }\n\n this.textureLoader.setPath(currentPath);\n\n return texture;\n }\n\n // Parse nodes in FBXTree.Objects.Material\n parseMaterials(textureMap) {\n const materialMap = new Map();\n\n if (\"Material\" in fbxTree.Objects) {\n const materialNodes = fbxTree.Objects.Material;\n\n for (const nodeID in materialNodes) {\n const material = this.parseMaterial(materialNodes[nodeID], textureMap);\n\n if (material !== null) materialMap.set(parseInt(nodeID), material);\n }\n }\n\n return materialMap;\n }\n\n // Parse single node in FBXTree.Objects.Material\n // Materials are connected to texture maps in FBXTree.Objects.Textures\n // FBX format currently only supports Lambert and Phong shading models\n parseMaterial(materialNode, textureMap) {\n const ID = materialNode.id;\n const name = materialNode.attrName;\n let type = materialNode.ShadingModel;\n\n // Case where FBX wraps shading model in property object.\n if (typeof type === \"object\") {\n type = type.value;\n }\n\n // Ignore unused materials which don't have any connections.\n if (!connections.has(ID)) return null;\n\n const parameters = this.parseParameters(materialNode, textureMap, ID);\n\n let material;\n\n switch (type.toLowerCase()) {\n case \"phong\":\n material = new MeshPhongMaterial();\n break;\n case \"lambert\":\n material = new MeshLambertMaterial();\n break;\n default:\n console.warn(\n 'THREE.FBXLoader: unknown material type \"%s\". Defaulting to MeshPhongMaterial.',\n type\n );\n material = new MeshPhongMaterial();\n break;\n }\n\n material.setValues(parameters);\n material.name = name;\n\n return material;\n }\n\n // Parse FBX material and return parameters suitable for a three.js material\n // Also parse the texture map and return any textures associated with the material\n parseParameters(materialNode, textureMap, ID) {\n const parameters = {};\n\n if (materialNode.BumpFactor) {\n parameters.bumpScale = materialNode.BumpFactor.value;\n }\n\n if (materialNode.Diffuse) {\n parameters.color = new Color()\n .fromArray(materialNode.Diffuse.value)\n .convertSRGBToLinear();\n } else if (\n materialNode.DiffuseColor &&\n (materialNode.DiffuseColor.type === \"Color\" ||\n materialNode.DiffuseColor.type === \"ColorRGB\")\n ) {\n // The blender exporter exports diffuse here instead of in materialNode.Diffuse\n parameters.color = new Color()\n .fromArray(materialNode.DiffuseColor.value)\n .convertSRGBToLinear();\n }\n\n if (materialNode.DisplacementFactor) {\n parameters.displacementScale = materialNode.DisplacementFactor.value;\n }\n\n if (materialNode.Emissive) {\n parameters.emissive = new Color()\n .fromArray(materialNode.Emissive.value)\n .convertSRGBToLinear();\n } else if (\n materialNode.EmissiveColor &&\n (materialNode.EmissiveColor.type === \"Color\" ||\n materialNode.EmissiveColor.type === \"ColorRGB\")\n ) {\n // The blender exporter exports emissive color here instead of in materialNode.Emissive\n parameters.emissive = new Color()\n .fromArray(materialNode.EmissiveColor.value)\n .convertSRGBToLinear();\n }\n\n if (materialNode.EmissiveFactor) {\n parameters.emissiveIntensity = parseFloat(\n materialNode.EmissiveFactor.value\n );\n }\n\n if (materialNode.Opacity) {\n parameters.opacity = parseFloat(materialNode.Opacity.value);\n }\n\n if (parameters.opacity < 1.0) {\n parameters.transparent = true;\n }\n\n if (materialNode.ReflectionFactor) {\n parameters.reflectivity = materialNode.ReflectionFactor.value;\n }\n\n if (materialNode.Shininess) {\n parameters.shininess = materialNode.Shininess.value;\n }\n\n if (materialNode.Specular) {\n parameters.specular = new Color()\n .fromArray(materialNode.Specular.value)\n .convertSRGBToLinear();\n } else if (\n materialNode.SpecularColor &&\n materialNode.SpecularColor.type === \"Color\"\n ) {\n // The blender exporter exports specular color here instead of in materialNode.Specular\n parameters.specular = new Color()\n .fromArray(materialNode.SpecularColor.value)\n .convertSRGBToLinear();\n }\n\n const scope = this;\n connections.get(ID).children.forEach(function (child) {\n const type = child.relationship;\n\n switch (type) {\n case \"Bump\":\n parameters.bumpMap = scope.getTexture(textureMap, child.ID);\n break;\n\n case \"Maya|TEX_ao_map\":\n parameters.aoMap = scope.getTexture(textureMap, child.ID);\n break;\n\n case \"DiffuseColor\":\n case \"Maya|TEX_color_map\":\n parameters.map = scope.getTexture(textureMap, child.ID);\n if (parameters.map !== undefined) {\n parameters.map.colorSpace = SRGBColorSpace;\n }\n\n break;\n\n case \"DisplacementColor\":\n parameters.displacementMap = scope.getTexture(textureMap, child.ID);\n break;\n\n case \"EmissiveColor\":\n parameters.emissiveMap = scope.getTexture(textureMap, child.ID);\n if (parameters.emissiveMap !== undefined) {\n parameters.emissiveMap.colorSpace = SRGBColorSpace;\n }\n\n break;\n\n case \"NormalMap\":\n case \"Maya|TEX_normal_map\":\n parameters.normalMap = scope.getTexture(textureMap, child.ID);\n break;\n\n case \"ReflectionColor\":\n parameters.envMap = scope.getTexture(textureMap, child.ID);\n if (parameters.envMap !== undefined) {\n parameters.envMap.mapping = EquirectangularReflectionMapping;\n parameters.envMap.colorSpace = SRGBColorSpace;\n }\n\n break;\n\n case \"SpecularColor\":\n parameters.specularMap = scope.getTexture(textureMap, child.ID);\n if (parameters.specularMap !== undefined) {\n parameters.specularMap.colorSpace = SRGBColorSpace;\n }\n\n break;\n\n case \"TransparentColor\":\n case \"TransparencyFactor\":\n parameters.alphaMap = scope.getTexture(textureMap, child.ID);\n parameters.transparent = true;\n break;\n\n case \"AmbientColor\":\n case \"ShininessExponent\": // AKA glossiness map\n case \"SpecularFactor\": // AKA specularLevel\n case \"VectorDisplacementColor\": // NOTE: Seems to be a copy of DisplacementColor\n default:\n console.warn(\n \"THREE.FBXLoader: %s map is not supported in three.js, skipping texture.\",\n type\n );\n break;\n }\n });\n\n return parameters;\n }\n\n // get a texture from the textureMap for use by a material.\n getTexture(textureMap, id) {\n // if the texture is a layered texture, just use the first layer and issue a warning\n if (\n \"LayeredTexture\" in fbxTree.Objects &&\n id in fbxTree.Objects.LayeredTexture\n ) {\n console.warn(\n \"THREE.FBXLoader: layered textures are not supported in three.js. Discarding all but first layer.\"\n );\n id = connections.get(id).children[0].ID;\n }\n\n return textureMap.get(id);\n }\n\n // Parse nodes in FBXTree.Objects.Deformer\n // Deformer node can contain skinning or Vertex Cache animation data, however only skinning is supported here\n // Generates map of Skeleton-like objects for use later when generating and binding skeletons.\n parseDeformers() {\n const skeletons = {};\n const morphTargets = {};\n\n if (\"Deformer\" in fbxTree.Objects) {\n const DeformerNodes = fbxTree.Objects.Deformer;\n\n for (const nodeID in DeformerNodes) {\n const deformerNode = DeformerNodes[nodeID];\n\n const relationships = connections.get(parseInt(nodeID));\n\n if (deformerNode.attrType === \"Skin\") {\n const skeleton = this.parseSkeleton(relationships, DeformerNodes);\n skeleton.ID = nodeID;\n\n if (relationships.parents.length > 1)\n console.warn(\n \"THREE.FBXLoader: skeleton attached to more than one geometry is not supported.\"\n );\n skeleton.geometryID = relationships.parents[0].ID;\n\n skeletons[nodeID] = skeleton;\n } else if (deformerNode.attrType === \"BlendShape\") {\n const morphTarget = {\n id: nodeID,\n };\n\n morphTarget.rawTargets = this.parseMorphTargets(\n relationships,\n DeformerNodes\n );\n morphTarget.id = nodeID;\n\n if (relationships.parents.length > 1)\n console.warn(\n \"THREE.FBXLoader: morph target attached to more than one geometry is not supported.\"\n );\n\n morphTargets[nodeID] = morphTarget;\n }\n }\n }\n\n return {\n skeletons: skeletons,\n morphTargets: morphTargets,\n };\n }\n\n // Parse single nodes in FBXTree.Objects.Deformer\n // The top level skeleton node has type 'Skin' and sub nodes have type 'Cluster'\n // Each skin node represents a skeleton and each cluster node represents a bone\n parseSkeleton(relationships, deformerNodes) {\n const rawBones = [];\n\n relationships.children.forEach(function (child) {\n const boneNode = deformerNodes[child.ID];\n\n if (boneNode.attrType !== \"Cluster\") return;\n\n const rawBone = {\n ID: child.ID,\n indices: [],\n weights: [],\n transformLink: new Matrix4().fromArray(boneNode.TransformLink.a),\n // transform: new Matrix4().fromArray( boneNode.Transform.a ),\n // linkMode: boneNode.Mode,\n };\n\n if (\"Indexes\" in boneNode) {\n rawBone.indices = boneNode.Indexes.a;\n rawBone.weights = boneNode.Weights.a;\n }\n\n rawBones.push(rawBone);\n });\n\n return {\n rawBones: rawBones,\n bones: [],\n };\n }\n\n // The top level morph deformer node has type \"BlendShape\" and sub nodes have type \"BlendShapeChannel\"\n parseMorphTargets(relationships, deformerNodes) {\n const rawMorphTargets = [];\n\n for (let i = 0; i < relationships.children.length; i++) {\n const child = relationships.children[i];\n\n const morphTargetNode = deformerNodes[child.ID];\n\n const rawMorphTarget = {\n name: morphTargetNode.attrName,\n initialWeight: morphTargetNode.DeformPercent,\n id: morphTargetNode.id,\n fullWeights: morphTargetNode.FullWeights.a,\n };\n\n if (morphTargetNode.attrType !== \"BlendShapeChannel\") return;\n\n rawMorphTarget.geoID = connections\n .get(parseInt(child.ID))\n .children.filter(function (child) {\n return child.relationship === undefined;\n })[0].ID;\n\n rawMorphTargets.push(rawMorphTarget);\n }\n\n return rawMorphTargets;\n }\n\n // create the main Group() to be returned by the loader\n parseScene(deformers, geometryMap, materialMap) {\n sceneGraph = new Group();\n\n const modelMap = this.parseModels(\n deformers.skeletons,\n geometryMap,\n materialMap\n );\n\n const modelNodes = fbxTree.Objects.Model;\n\n const scope = this;\n modelMap.forEach(function (model) {\n const modelNode = modelNodes[model.ID];\n scope.setLookAtProperties(model, modelNode);\n\n const parentConnections = connections.get(model.ID).parents;\n\n parentConnections.forEach(function (connection) {\n const parent = modelMap.get(connection.ID);\n if (parent !== undefined) parent.add(model);\n });\n\n if (model.parent === null) {\n sceneGraph.add(model);\n }\n });\n\n this.bindSkeleton(deformers.skeletons, geometryMap, modelMap);\n\n this.createAmbientLight();\n\n sceneGraph.traverse(function (node) {\n if (node.userData.transformData) {\n if (node.parent) {\n node.userData.transformData.parentMatrix = node.parent.matrix;\n node.userData.transformData.parentMatrixWorld =\n node.parent.matrixWorld;\n }\n\n const transform = generateTransform(node.userData.transformData);\n\n node.applyMatrix4(transform);\n node.updateWorldMatrix();\n }\n });\n\n const animations = new AnimationParser().parse();\n\n // if all the models where already combined in a single group, just return that\n if (sceneGraph.children.length === 1 && sceneGraph.children[0].isGroup) {\n sceneGraph.children[0].animations = animations;\n sceneGraph = sceneGraph.children[0];\n }\n\n sceneGraph.animations = animations;\n }\n\n // parse nodes in FBXTree.Objects.Model\n parseModels(skeletons, geometryMap, materialMap) {\n const modelMap = new Map();\n const modelNodes = fbxTree.Objects.Model;\n\n for (const nodeID in modelNodes) {\n const id = parseInt(nodeID);\n const node = modelNodes[nodeID];\n const relationships = connections.get(id);\n\n let model = this.buildSkeleton(\n relationships,\n skeletons,\n id,\n node.attrName\n );\n\n if (!model) {\n switch (node.attrType) {\n case \"Camera\":\n model = this.createCamera(relationships);\n break;\n case \"Light\":\n model = this.createLight(relationships);\n break;\n case \"Mesh\":\n model = this.createMesh(relationships, geometryMap, materialMap);\n break;\n case \"NurbsCurve\":\n model = this.createCurve(relationships, geometryMap);\n break;\n case \"LimbNode\":\n case \"Root\":\n model = new Bone();\n break;\n case \"Null\":\n default:\n model = new Group();\n break;\n }\n\n model.name = node.attrName\n ? PropertyBinding.sanitizeNodeName(node.attrName)\n : \"\";\n\n model.ID = id;\n }\n\n this.getTransformData(model, node);\n modelMap.set(id, model);\n }\n\n return modelMap;\n }\n\n buildSkeleton(relationships, skeletons, id, name) {\n let bone = null;\n\n relationships.parents.forEach(function (parent) {\n for (const ID in skeletons) {\n const skeleton = skeletons[ID];\n\n skeleton.rawBones.forEach(function (rawBone, i) {\n if (rawBone.ID === parent.ID) {\n const subBone = bone;\n bone = new Bone();\n\n bone.matrixWorld.copy(rawBone.transformLink);\n\n // set name and id here - otherwise in cases where \"subBone\" is created it will not have a name / id\n\n bone.name = name ? PropertyBinding.sanitizeNodeName(name) : \"\";\n bone.ID = id;\n\n skeleton.bones[i] = bone;\n\n // In cases where a bone is shared between multiple meshes\n // duplicate the bone here and and it as a child of the first bone\n if (subBone !== null) {\n bone.add(subBone);\n }\n }\n });\n }\n });\n\n return bone;\n }\n\n // create a PerspectiveCamera or OrthographicCamera\n createCamera(relationships) {\n let model;\n let cameraAttribute;\n\n relationships.children.forEach(function (child) {\n const attr = fbxTree.Objects.NodeAttribute[child.ID];\n\n if (attr !== undefined) {\n cameraAttribute = attr;\n }\n });\n\n if (cameraAttribute === undefined) {\n model = new Object3D();\n } else {\n let type = 0;\n if (\n cameraAttribute.CameraProjectionType !== undefined &&\n cameraAttribute.CameraProjectionType.value === 1\n ) {\n type = 1;\n }\n\n let nearClippingPlane = 1;\n if (cameraAttribute.NearPlane !== undefined) {\n nearClippingPlane = cameraAttribute.NearPlane.value / 1000;\n }\n\n let farClippingPlane = 1000;\n if (cameraAttribute.FarPlane !== undefined) {\n farClippingPlane = cameraAttribute.FarPlane.value / 1000;\n }\n\n let width = window.innerWidth;\n let height = window.innerHeight;\n\n if (\n cameraAttribute.AspectWidth !== undefined &&\n cameraAttribute.AspectHeight !== undefined\n ) {\n width = cameraAttribute.AspectWidth.value;\n height = cameraAttribute.AspectHeight.value;\n }\n\n const aspect = width / height;\n\n let fov = 45;\n if (cameraAttribute.FieldOfView !== undefined) {\n fov = cameraAttribute.FieldOfView.value;\n }\n\n const focalLength = cameraAttribute.FocalLength\n ? cameraAttribute.FocalLength.value\n : null;\n\n switch (type) {\n case 0: // Perspective\n model = new PerspectiveCamera(\n fov,\n aspect,\n nearClippingPlane,\n farClippingPlane\n );\n if (focalLength !== null) model.setFocalLength(focalLength);\n break;\n\n case 1: // Orthographic\n model = new OrthographicCamera(\n -width / 2,\n width / 2,\n height / 2,\n -height / 2,\n nearClippingPlane,\n farClippingPlane\n );\n break;\n\n default:\n console.warn(\"THREE.FBXLoader: Unknown camera type \" + type + \".\");\n model = new Object3D();\n break;\n }\n }\n\n return model;\n }\n\n // Create a DirectionalLight, PointLight or SpotLight\n createLight(relationships) {\n let model;\n let lightAttribute;\n\n relationships.children.forEach(function (child) {\n const attr = fbxTree.Objects.NodeAttribute[child.ID];\n\n if (attr !== undefined) {\n lightAttribute = attr;\n }\n });\n\n if (lightAttribute === undefined) {\n model = new Object3D();\n } else {\n let type;\n\n // LightType can be undefined for Point lights\n if (lightAttribute.LightType === undefined) {\n type = 0;\n } else {\n type = lightAttribute.LightType.value;\n }\n\n let color = 0xffffff;\n\n if (lightAttribute.Color !== undefined) {\n color = new Color()\n .fromArray(lightAttribute.Color.value)\n .convertSRGBToLinear();\n }\n\n let intensity =\n lightAttribute.Intensity === undefined\n ? 1\n : lightAttribute.Intensity.value / 100;\n\n // light disabled\n if (\n lightAttribute.CastLightOnObject !== undefined &&\n lightAttribute.CastLightOnObject.value === 0\n ) {\n intensity = 0;\n }\n\n let distance = 0;\n if (lightAttribute.FarAttenuationEnd !== undefined) {\n if (\n lightAttribute.EnableFarAttenuation !== undefined &&\n lightAttribute.EnableFarAttenuation.value === 0\n ) {\n distance = 0;\n } else {\n distance = lightAttribute.FarAttenuationEnd.value;\n }\n }\n\n // TODO: could this be calculated linearly from FarAttenuationStart to FarAttenuationEnd?\n const decay = 1;\n\n switch (type) {\n case 0: // Point\n model = new PointLight(color, intensity, distance, decay);\n break;\n\n case 1: // Directional\n model = new DirectionalLight(color, intensity);\n break;\n\n case 2: // Spot\n let angle = Math.PI / 3;\n\n if (lightAttribute.InnerAngle !== undefined) {\n angle = MathUtils.degToRad(lightAttribute.InnerAngle.value);\n }\n\n let penumbra = 0;\n if (lightAttribute.OuterAngle !== undefined) {\n // TODO: this is not correct - FBX calculates outer and inner angle in degrees\n // with OuterAngle > InnerAngle && OuterAngle <= Math.PI\n // while three.js uses a penumbra between (0, 1) to attenuate the inner angle\n penumbra = MathUtils.degToRad(lightAttribute.OuterAngle.value);\n penumbra = Math.max(penumbra, 1);\n }\n\n model = new SpotLight(\n color,\n intensity,\n distance,\n angle,\n penumbra,\n decay\n );\n break;\n\n default:\n console.warn(\n \"THREE.FBXLoader: Unknown light type \" +\n lightAttribute.LightType.value +\n \", defaulting to a PointLight.\"\n );\n model = new PointLight(color, intensity);\n break;\n }\n\n if (\n lightAttribute.CastShadows !== undefined &&\n lightAttribute.CastShadows.value === 1\n ) {\n model.castShadow = true;\n }\n }\n\n return model;\n }\n\n createMesh(relationships, geometryMap, materialMap) {\n let model;\n let geometry = null;\n let material = null;\n const materials = [];\n\n // get geometry and materials(s) from connections\n relationships.children.forEach(function (child) {\n if (geometryMap.has(child.ID)) {\n geometry = geometryMap.get(child.ID);\n }\n\n if (materialMap.has(child.ID)) {\n materials.push(materialMap.get(child.ID));\n }\n });\n\n if (materials.length > 1) {\n material = materials;\n } else if (materials.length > 0) {\n material = materials[0];\n } else {\n material = new MeshPhongMaterial({\n name: Loader.DEFAULT_MATERIAL_NAME,\n color: 0xcccccc,\n });\n materials.push(material);\n }\n\n if (\"color\" in geometry.attributes) {\n materials.forEach(function (material) {\n material.vertexColors = true;\n });\n }\n\n if (geometry.FBX_Deformer) {\n model = new SkinnedMesh(geometry, material);\n model.normalizeSkinWeights();\n } else {\n model = new Mesh(geometry, material);\n }\n\n return model;\n }\n\n createCurve(relationships, geometryMap) {\n const geometry = relationships.children.reduce(function (geo, child) {\n if (geometryMap.has(child.ID)) geo = geometryMap.get(child.ID);\n\n return geo;\n }, null);\n\n // FBX does not list materials for Nurbs lines, so we'll just put our own in here.\n const material = new LineBasicMaterial({\n name: Loader.DEFAULT_MATERIAL_NAME,\n color: 0x3300ff,\n linewidth: 1,\n });\n return new Line(geometry, material);\n }\n\n // parse the model node for transform data\n getTransformData(model, modelNode) {\n const transformData = {};\n\n if (\"InheritType\" in modelNode)\n transformData.inheritType = parseInt(modelNode.InheritType.value);\n\n if (\"RotationOrder\" in modelNode)\n transformData.eulerOrder = getEulerOrder(modelNode.RotationOrder.value);\n else transformData.eulerOrder = \"ZYX\";\n\n if (\"Lcl_Translation\" in modelNode)\n transformData.translation = modelNode.Lcl_Translation.value;\n\n if (\"PreRotation\" in modelNode)\n transformData.preRotation = modelNode.PreRotation.value;\n if (\"Lcl_Rotation\" in modelNode)\n transformData.rotation = modelNode.Lcl_Rotation.value;\n if (\"PostRotation\" in modelNode)\n transformData.postRotation = modelNode.PostRotation.value;\n\n if (\"Lcl_Scaling\" in modelNode)\n transformData.scale = modelNode.Lcl_Scaling.value;\n\n if (\"ScalingOffset\" in modelNode)\n transformData.scalingOffset = modelNode.ScalingOffset.value;\n if (\"ScalingPivot\" in modelNode)\n transformData.scalingPivot = modelNode.ScalingPivot.value;\n\n if (\"RotationOffset\" in modelNode)\n transformData.rotationOffset = modelNode.RotationOffset.value;\n if (\"RotationPivot\" in modelNode)\n transformData.rotationPivot = modelNode.RotationPivot.value;\n\n model.userData.transformData = transformData;\n }\n\n setLookAtProperties(model, modelNode) {\n if (\"LookAtProperty\" in modelNode) {\n const children = connections.get(model.ID).children;\n\n children.forEach(function (child) {\n if (child.relationship === \"LookAtProperty\") {\n const lookAtTarget = fbxTree.Objects.Model[child.ID];\n\n if (\"Lcl_Translation\" in lookAtTarget) {\n const pos = lookAtTarget.Lcl_Translation.value;\n\n // DirectionalLight, SpotLight\n if (model.target !== undefined) {\n model.target.position.fromArray(pos);\n sceneGraph.add(model.target);\n } else {\n // Cameras and other Object3Ds\n\n model.lookAt(new Vector3().fromArray(pos));\n }\n }\n }\n });\n }\n }\n\n bindSkeleton(skeletons, geometryMap, modelMap) {\n const bindMatrices = this.parsePoseNodes();\n\n for (const ID in skeletons) {\n const skeleton = skeletons[ID];\n\n const parents = connections.get(parseInt(skeleton.ID)).parents;\n\n parents.forEach(function (parent) {\n if (geometryMap.has(parent.ID)) {\n const geoID = parent.ID;\n const geoRelationships = connections.get(geoID);\n\n geoRelationships.parents.forEach(function (geoConnParent) {\n if (modelMap.has(geoConnParent.ID)) {\n const model = modelMap.get(geoConnParent.ID);\n\n model.bind(\n new Skeleton(skeleton.bones),\n bindMatrices[geoConnParent.ID]\n );\n }\n });\n }\n });\n }\n }\n\n parsePoseNodes() {\n const bindMatrices = {};\n\n if (\"Pose\" in fbxTree.Objects) {\n const BindPoseNode = fbxTree.Objects.Pose;\n\n for (const nodeID in BindPoseNode) {\n if (\n BindPoseNode[nodeID].attrType === \"BindPose\" &&\n BindPoseNode[nodeID].NbPoseNodes > 0\n ) {\n const poseNodes = BindPoseNode[nodeID].PoseNode;\n\n if (Array.isArray(poseNodes)) {\n poseNodes.forEach(function (poseNode) {\n bindMatrices[poseNode.Node] = new Matrix4().fromArray(\n poseNode.Matrix.a\n );\n });\n } else {\n bindMatrices[poseNodes.Node] = new Matrix4().fromArray(\n poseNodes.Matrix.a\n );\n }\n }\n }\n }\n\n return bindMatrices;\n }\n\n // Parse ambient color in FBXTree.GlobalSettings - if it's not set to black (default), create an ambient light\n createAmbientLight() {\n if (\n \"GlobalSettings\" in fbxTree &&\n \"AmbientColor\" in fbxTree.GlobalSettings\n ) {\n const ambientColor = fbxTree.GlobalSettings.AmbientColor.value;\n const r = ambientColor[0];\n const g = ambientColor[1];\n const b = ambientColor[2];\n\n if (r !== 0 || g !== 0 || b !== 0) {\n const color = new Color(r, g, b).convertSRGBToLinear();\n sceneGraph.add(new AmbientLight(color, 1));\n }\n }\n }\n}\n\n// parse Geometry data from FBXTree and return map of BufferGeometries\nclass GeometryParser {\n constructor() {\n this.negativeMaterialIndices = false;\n }\n\n // Parse nodes in FBXTree.Objects.Geometry\n parse(deformers) {\n const geometryMap = new Map();\n\n if (\"Geometry\" in fbxTree.Objects) {\n const geoNodes = fbxTree.Objects.Geometry;\n\n for (const nodeID in geoNodes) {\n const relationships = connections.get(parseInt(nodeID));\n const geo = this.parseGeometry(\n relationships,\n geoNodes[nodeID],\n deformers\n );\n\n geometryMap.set(parseInt(nodeID), geo);\n }\n }\n\n // report warnings\n\n if (this.negativeMaterialIndices === true) {\n console.warn(\n \"THREE.FBXLoader: The FBX file contains invalid (negative) material indices. The asset might not render as expected.\"\n );\n }\n\n return geometryMap;\n }\n\n // Parse single node in FBXTree.Objects.Geometry\n parseGeometry(relationships, geoNode, deformers) {\n switch (geoNode.attrType) {\n case \"Mesh\":\n return this.parseMeshGeometry(relationships, geoNode, deformers);\n break;\n\n case \"NurbsCurve\":\n return this.parseNurbsGeometry(geoNode);\n break;\n }\n }\n\n // Parse single node mesh geometry in FBXTree.Objects.Geometry\n parseMeshGeometry(relationships, geoNode, deformers) {\n const skeletons = deformers.skeletons;\n const morphTargets = [];\n\n const modelNodes = relationships.parents.map(function (parent) {\n return fbxTree.Objects.Model[parent.ID];\n });\n\n // don't create geometry if it is not associated with any models\n if (modelNodes.length === 0) return;\n\n const skeleton = relationships.children.reduce(function (skeleton, child) {\n if (skeletons[child.ID] !== undefined) skeleton = skeletons[child.ID];\n\n return skeleton;\n }, null);\n\n relationships.children.forEach(function (child) {\n if (deformers.morphTargets[child.ID] !== undefined) {\n morphTargets.push(deformers.morphTargets[child.ID]);\n }\n });\n\n // Assume one model and get the preRotation from that\n // if there is more than one model associated with the geometry this may cause problems\n const modelNode = modelNodes[0];\n\n const transformData = {};\n\n if (\"RotationOrder\" in modelNode)\n transformData.eulerOrder = getEulerOrder(modelNode.RotationOrder.value);\n if (\"InheritType\" in modelNode)\n transformData.inheritType = parseInt(modelNode.InheritType.value);\n\n if (\"GeometricTranslation\" in modelNode)\n transformData.translation = modelNode.GeometricTranslation.value;\n if (\"GeometricRotation\" in modelNode)\n transformData.rotation = modelNode.GeometricRotation.value;\n if (\"GeometricScaling\" in modelNode)\n transformData.scale = modelNode.GeometricScaling.value;\n\n const transform = generateTransform(transformData);\n\n return this.genGeometry(geoNode, skeleton, morphTargets, transform);\n }\n\n // Generate a BufferGeometry from a node in FBXTree.Objects.Geometry\n genGeometry(geoNode, skeleton, morphTargets, preTransform) {\n const geo = new BufferGeometry();\n if (geoNode.attrName) geo.name = geoNode.attrName;\n\n const geoInfo = this.parseGeoNode(geoNode, skeleton);\n const buffers = this.genBuffers(geoInfo);\n\n const positionAttribute = new Float32BufferAttribute(buffers.vertex, 3);\n\n positionAttribute.applyMatrix4(preTransform);\n\n geo.setAttribute(\"position\", positionAttribute);\n\n if (buffers.colors.length > 0) {\n geo.setAttribute(\"color\", new Float32BufferAttribute(buffers.colors, 3));\n }\n\n if (skeleton) {\n geo.setAttribute(\n \"skinIndex\",\n new Uint16BufferAttribute(buffers.weightsIndices, 4)\n );\n\n geo.setAttribute(\n \"skinWeight\",\n new Float32BufferAttribute(buffers.vertexWeights, 4)\n );\n\n // used later to bind the skeleton to the model\n geo.FBX_Deformer = skeleton;\n }\n\n if (buffers.normal.length > 0) {\n const normalMatrix = new Matrix3().getNormalMatrix(preTransform);\n\n const normalAttribute = new Float32BufferAttribute(buffers.normal, 3);\n normalAttribute.applyNormalMatrix(normalMatrix);\n\n geo.setAttribute(\"normal\", normalAttribute);\n }\n\n buffers.uvs.forEach(function (uvBuffer, i) {\n const name = i === 0 ? \"uv\" : `uv${i}`;\n\n geo.setAttribute(name, new Float32BufferAttribute(buffers.uvs[i], 2));\n });\n\n if (geoInfo.material && geoInfo.material.mappingType !== \"AllSame\") {\n // Convert the material indices of each vertex into rendering groups on the geometry.\n let prevMaterialIndex = buffers.materialIndex[0];\n let startIndex = 0;\n\n buffers.materialIndex.forEach(function (currentIndex, i) {\n if (currentIndex !== prevMaterialIndex) {\n geo.addGroup(startIndex, i - startIndex, prevMaterialIndex);\n\n prevMaterialIndex = currentIndex;\n startIndex = i;\n }\n });\n\n // the loop above doesn't add the last group, do that here.\n if (geo.groups.length > 0) {\n const lastGroup = geo.groups[geo.groups.length - 1];\n const lastIndex = lastGroup.start + lastGroup.count;\n\n if (lastIndex !== buffers.materialIndex.length) {\n geo.addGroup(\n lastIndex,\n buffers.materialIndex.length - lastIndex,\n prevMaterialIndex\n );\n }\n }\n\n // case where there are multiple materials but the whole geometry is only\n // using one of them\n if (geo.groups.length === 0) {\n geo.addGroup(0, buffers.materialIndex.length, buffers.materialIndex[0]);\n }\n }\n\n this.addMorphTargets(geo, geoNode, morphTargets, preTransform);\n\n return geo;\n }\n\n parseGeoNode(geoNode, skeleton) {\n const geoInfo = {};\n\n geoInfo.vertexPositions =\n geoNode.Vertices !== undefined ? geoNode.Vertices.a : [];\n geoInfo.vertexIndices =\n geoNode.PolygonVertexIndex !== undefined\n ? geoNode.PolygonVertexIndex.a\n : [];\n\n if (geoNode.LayerElementColor) {\n geoInfo.color = this.parseVertexColors(geoNode.LayerElementColor[0]);\n }\n\n if (geoNode.LayerElementMaterial) {\n geoInfo.material = this.parseMaterialIndices(\n geoNode.LayerElementMaterial[0]\n );\n }\n\n if (geoNode.LayerElementNormal) {\n geoInfo.normal = this.parseNormals(geoNode.LayerElementNormal[0]);\n }\n\n if (geoNode.LayerElementUV) {\n geoInfo.uv = [];\n\n let i = 0;\n while (geoNode.LayerElementUV[i]) {\n if (geoNode.LayerElementUV[i].UV) {\n geoInfo.uv.push(this.parseUVs(geoNode.LayerElementUV[i]));\n }\n\n i++;\n }\n }\n\n geoInfo.weightTable = {};\n\n if (skeleton !== null) {\n geoInfo.skeleton = skeleton;\n\n skeleton.rawBones.forEach(function (rawBone, i) {\n // loop over the bone's vertex indices and weights\n rawBone.indices.forEach(function (index, j) {\n if (geoInfo.weightTable[index] === undefined)\n geoInfo.weightTable[index] = [];\n\n geoInfo.weightTable[index].push({\n id: i,\n weight: rawBone.weights[j],\n });\n });\n });\n }\n\n return geoInfo;\n }\n\n genBuffers(geoInfo) {\n const buffers = {\n vertex: [],\n normal: [],\n colors: [],\n uvs: [],\n materialIndex: [],\n vertexWeights: [],\n weightsIndices: [],\n };\n\n let polygonIndex = 0;\n let faceLength = 0;\n let displayedWeightsWarning = false;\n\n // these will hold data for a single face\n let facePositionIndexes = [];\n let faceNormals = [];\n let faceColors = [];\n let faceUVs = [];\n let faceWeights = [];\n let faceWeightIndices = [];\n\n const scope = this;\n geoInfo.vertexIndices.forEach(function (vertexIndex, polygonVertexIndex) {\n let materialIndex;\n let endOfFace = false;\n\n // Face index and vertex index arrays are combined in a single array\n // A cube with quad faces looks like this:\n // PolygonVertexIndex: *24 {\n // a: 0, 1, 3, -3, 2, 3, 5, -5, 4, 5, 7, -7, 6, 7, 1, -1, 1, 7, 5, -4, 6, 0, 2, -5\n // }\n // Negative numbers mark the end of a face - first face here is 0, 1, 3, -3\n // to find index of last vertex bit shift the index: ^ - 1\n if (vertexIndex < 0) {\n vertexIndex = vertexIndex ^ -1; // equivalent to ( x * -1 ) - 1\n endOfFace = true;\n }\n\n let weightIndices = [];\n let weights = [];\n\n facePositionIndexes.push(\n vertexIndex * 3,\n vertexIndex * 3 + 1,\n vertexIndex * 3 + 2\n );\n\n if (geoInfo.color) {\n const data = getData(\n polygonVertexIndex,\n polygonIndex,\n vertexIndex,\n geoInfo.color\n );\n\n faceColors.push(data[0], data[1], data[2]);\n }\n\n if (geoInfo.skeleton) {\n if (geoInfo.weightTable[vertexIndex] !== undefined) {\n geoInfo.weightTable[vertexIndex].forEach(function (wt) {\n weights.push(wt.weight);\n weightIndices.push(wt.id);\n });\n }\n\n if (weights.length > 4) {\n if (!displayedWeightsWarning) {\n console.warn(\n \"THREE.FBXLoader: Vertex has more than 4 skinning weights assigned to vertex. Deleting additional weights.\"\n );\n displayedWeightsWarning = true;\n }\n\n const wIndex = [0, 0, 0, 0];\n const Weight = [0, 0, 0, 0];\n\n weights.forEach(function (weight, weightIndex) {\n let currentWeight = weight;\n let currentIndex = weightIndices[weightIndex];\n\n Weight.forEach(function (\n comparedWeight,\n comparedWeightIndex,\n comparedWeightArray\n ) {\n if (currentWeight > comparedWeight) {\n comparedWeightArray[comparedWeightIndex] = currentWeight;\n currentWeight = comparedWeight;\n\n const tmp = wIndex[comparedWeightIndex];\n wIndex[comparedWeightIndex] = currentIndex;\n currentIndex = tmp;\n }\n });\n });\n\n weightIndices = wIndex;\n weights = Weight;\n }\n\n // if the weight array is shorter than 4 pad with 0s\n while (weights.length < 4) {\n weights.push(0);\n weightIndices.push(0);\n }\n\n for (let i = 0; i < 4; ++i) {\n faceWeights.push(weights[i]);\n faceWeightIndices.push(weightIndices[i]);\n }\n }\n\n if (geoInfo.normal) {\n const data = getData(\n polygonVertexIndex,\n polygonIndex,\n vertexIndex,\n geoInfo.normal\n );\n\n faceNormals.push(data[0], data[1], data[2]);\n }\n\n if (geoInfo.material && geoInfo.material.mappingType !== \"AllSame\") {\n materialIndex = getData(\n polygonVertexIndex,\n polygonIndex,\n vertexIndex,\n geoInfo.material\n )[0];\n\n if (materialIndex < 0) {\n scope.negativeMaterialIndices = true;\n materialIndex = 0; // fallback\n }\n }\n\n if (geoInfo.uv) {\n geoInfo.uv.forEach(function (uv, i) {\n const data = getData(\n polygonVertexIndex,\n polygonIndex,\n vertexIndex,\n uv\n );\n\n if (faceUVs[i] === undefined) {\n faceUVs[i] = [];\n }\n\n faceUVs[i].push(data[0]);\n faceUVs[i].push(data[1]);\n });\n }\n\n faceLength++;\n\n if (endOfFace) {\n if (faceLength > 4)\n console.warn(\n \"THREE.FBXLoader: Polygons with more than four sides are not supported. Make sure to triangulate the geometry during export.\"\n );\n\n scope.genFace(\n buffers,\n geoInfo,\n facePositionIndexes,\n materialIndex,\n faceNormals,\n faceColors,\n faceUVs,\n faceWeights,\n faceWeightIndices,\n faceLength\n );\n\n polygonIndex++;\n faceLength = 0;\n\n // reset arrays for the next face\n facePositionIndexes = [];\n faceNormals = [];\n faceColors = [];\n faceUVs = [];\n faceWeights = [];\n faceWeightIndices = [];\n }\n });\n\n return buffers;\n }\n\n // Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris\n genFace(\n buffers,\n geoInfo,\n facePositionIndexes,\n materialIndex,\n faceNormals,\n faceColors,\n faceUVs,\n faceWeights,\n faceWeightIndices,\n faceLength\n ) {\n for (let i = 2; i < faceLength; i++) {\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[0]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[1]]);\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[2]]);\n\n buffers.vertex.push(\n geoInfo.vertexPositions[facePositionIndexes[(i - 1) * 3]]\n );\n buffers.vertex.push(\n geoInfo.vertexPositions[facePositionIndexes[(i - 1) * 3 + 1]]\n );\n buffers.vertex.push(\n geoInfo.vertexPositions[facePositionIndexes[(i - 1) * 3 + 2]]\n );\n\n buffers.vertex.push(geoInfo.vertexPositions[facePositionIndexes[i * 3]]);\n buffers.vertex.push(\n geoInfo.vertexPositions[facePositionIndexes[i * 3 + 1]]\n );\n buffers.vertex.push(\n geoInfo.vertexPositions[facePositionIndexes[i * 3 + 2]]\n );\n\n if (geoInfo.skeleton) {\n buffers.vertexWeights.push(faceWeights[0]);\n buffers.vertexWeights.push(faceWeights[1]);\n buffers.vertexWeights.push(faceWeights[2]);\n buffers.vertexWeights.push(faceWeights[3]);\n\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4 + 1]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4 + 2]);\n buffers.vertexWeights.push(faceWeights[(i - 1) * 4 + 3]);\n\n buffers.vertexWeights.push(faceWeights[i * 4]);\n buffers.vertexWeights.push(faceWeights[i * 4 + 1]);\n buffers.vertexWeights.push(faceWeights[i * 4 + 2]);\n buffers.vertexWeights.push(faceWeights[i * 4 + 3]);\n\n buffers.weightsIndices.push(faceWeightIndices[0]);\n buffers.weightsIndices.push(faceWeightIndices[1]);\n buffers.weightsIndices.push(faceWeightIndices[2]);\n buffers.weightsIndices.push(faceWeightIndices[3]);\n\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4 + 1]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4 + 2]);\n buffers.weightsIndices.push(faceWeightIndices[(i - 1) * 4 + 3]);\n\n buffers.weightsIndices.push(faceWeightIndices[i * 4]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4 + 1]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4 + 2]);\n buffers.weightsIndices.push(faceWeightIndices[i * 4 + 3]);\n }\n\n if (geoInfo.color) {\n buffers.colors.push(faceColors[0]);\n buffers.colors.push(faceColors[1]);\n buffers.colors.push(faceColors[2]);\n\n buffers.colors.push(faceColors[(i - 1) * 3]);\n buffers.colors.push(faceColors[(i - 1) * 3 + 1]);\n buffers.colors.push(faceColors[(i - 1) * 3 + 2]);\n\n buffers.colors.push(faceColors[i * 3]);\n buffers.colors.push(faceColors[i * 3 + 1]);\n buffers.colors.push(faceColors[i * 3 + 2]);\n }\n\n if (geoInfo.material && geoInfo.material.mappingType !== \"AllSame\") {\n buffers.materialIndex.push(materialIndex);\n buffers.materialIndex.push(materialIndex);\n buffers.materialIndex.push(materialIndex);\n }\n\n if (geoInfo.normal) {\n buffers.normal.push(faceNormals[0]);\n buffers.normal.push(faceNormals[1]);\n buffers.normal.push(faceNormals[2]);\n\n buffers.normal.push(faceNormals[(i - 1) * 3]);\n buffers.normal.push(faceNormals[(i - 1) * 3 + 1]);\n buffers.normal.push(faceNormals[(i - 1) * 3 + 2]);\n\n buffers.normal.push(faceNormals[i * 3]);\n buffers.normal.push(faceNormals[i * 3 + 1]);\n buffers.normal.push(faceNormals[i * 3 + 2]);\n }\n\n if (geoInfo.uv) {\n geoInfo.uv.forEach(function (uv, j) {\n if (buffers.uvs[j] === undefined) buffers.uvs[j] = [];\n\n buffers.uvs[j].push(faceUVs[j][0]);\n buffers.uvs[j].push(faceUVs[j][1]);\n\n buffers.uvs[j].push(faceUVs[j][(i - 1) * 2]);\n buffers.uvs[j].push(faceUVs[j][(i - 1) * 2 + 1]);\n\n buffers.uvs[j].push(faceUVs[j][i * 2]);\n buffers.uvs[j].push(faceUVs[j][i * 2 + 1]);\n });\n }\n }\n }\n\n addMorphTargets(parentGeo, parentGeoNode, morphTargets, preTransform) {\n if (morphTargets.length === 0) return;\n\n parentGeo.morphTargetsRelative = true;\n\n parentGeo.morphAttributes.position = [];\n // parentGeo.morphAttributes.normal = []; // not implemented\n\n const scope = this;\n morphTargets.forEach(function (morphTarget) {\n morphTarget.rawTargets.forEach(function (rawTarget) {\n const morphGeoNode = fbxTree.Objects.Geometry[rawTarget.geoID];\n\n if (morphGeoNode !== undefined) {\n scope.genMorphGeometry(\n parentGeo,\n parentGeoNode,\n morphGeoNode,\n preTransform,\n rawTarget.name\n );\n }\n });\n });\n }\n\n // a morph geometry node is similar to a standard node, and the node is also contained\n // in FBXTree.Objects.Geometry, however it can only have attributes for position, normal\n // and a special attribute Index defining which vertices of the original geometry are affected\n // Normal and position attributes only have data for the vertices that are affected by the morph\n genMorphGeometry(parentGeo, parentGeoNode, morphGeoNode, preTransform, name) {\n const vertexIndices =\n parentGeoNode.PolygonVertexIndex !== undefined\n ? parentGeoNode.PolygonVertexIndex.a\n : [];\n\n const morphPositionsSparse =\n morphGeoNode.Vertices !== undefined ? morphGeoNode.Vertices.a : [];\n const indices =\n morphGeoNode.Indexes !== undefined ? morphGeoNode.Indexes.a : [];\n\n const length = parentGeo.attributes.position.count * 3;\n const morphPositions = new Float32Array(length);\n\n for (let i = 0; i < indices.length; i++) {\n const morphIndex = indices[i] * 3;\n\n morphPositions[morphIndex] = morphPositionsSparse[i * 3];\n morphPositions[morphIndex + 1] = morphPositionsSparse[i * 3 + 1];\n morphPositions[morphIndex + 2] = morphPositionsSparse[i * 3 + 2];\n }\n\n // TODO: add morph normal support\n const morphGeoInfo = {\n vertexIndices: vertexIndices,\n vertexPositions: morphPositions,\n };\n\n const morphBuffers = this.genBuffers(morphGeoInfo);\n\n const positionAttribute = new Float32BufferAttribute(\n morphBuffers.vertex,\n 3\n );\n positionAttribute.name = name || morphGeoNode.attrName;\n\n positionAttribute.applyMatrix4(preTransform);\n\n parentGeo.morphAttributes.position.push(positionAttribute);\n }\n\n // Parse normal from FBXTree.Objects.Geometry.LayerElementNormal if it exists\n parseNormals(NormalNode) {\n const mappingType = NormalNode.MappingInformationType;\n const referenceType = NormalNode.ReferenceInformationType;\n const buffer = NormalNode.Normals.a;\n let indexBuffer = [];\n if (referenceType === \"IndexToDirect\") {\n if (\"NormalIndex\" in NormalNode) {\n indexBuffer = NormalNode.NormalIndex.a;\n } else if (\"NormalsIndex\" in NormalNode) {\n indexBuffer = NormalNode.NormalsIndex.a;\n }\n }\n\n return {\n dataSize: 3,\n buffer: buffer,\n indices: indexBuffer,\n mappingType: mappingType,\n referenceType: referenceType,\n };\n }\n\n // Parse UVs from FBXTree.Objects.Geometry.LayerElementUV if it exists\n parseUVs(UVNode) {\n const mappingType = UVNode.MappingInformationType;\n const referenceType = UVNode.ReferenceInformationType;\n const buffer = UVNode.UV.a;\n let indexBuffer = [];\n if (referenceType === \"IndexToDirect\") {\n indexBuffer = UVNode.UVIndex.a;\n }\n\n return {\n dataSize: 2,\n buffer: buffer,\n indices: indexBuffer,\n mappingType: mappingType,\n referenceType: referenceType,\n };\n }\n\n // Parse Vertex Colors from FBXTree.Objects.Geometry.LayerElementColor if it exists\n parseVertexColors(ColorNode) {\n const mappingType = ColorNode.MappingInformationType;\n const referenceType = ColorNode.ReferenceInformationType;\n const buffer = ColorNode.Colors.a;\n let indexBuffer = [];\n if (referenceType === \"IndexToDirect\") {\n indexBuffer = ColorNode.ColorIndex.a;\n }\n\n for (let i = 0, c = new Color(); i < buffer.length; i += 4) {\n c.fromArray(buffer, i).convertSRGBToLinear().toArray(buffer, i);\n }\n\n return {\n dataSize: 4,\n buffer: buffer,\n indices: indexBuffer,\n mappingType: mappingType,\n referenceType: referenceType,\n };\n }\n\n // Parse mapping and material data in FBXTree.Objects.Geometry.LayerElementMaterial if it exists\n parseMaterialIndices(MaterialNode) {\n const mappingType = MaterialNode.MappingInformationType;\n const referenceType = MaterialNode.ReferenceInformationType;\n\n if (mappingType === \"NoMappingInformation\") {\n return {\n dataSize: 1,\n buffer: [0],\n indices: [0],\n mappingType: \"AllSame\",\n referenceType: referenceType,\n };\n }\n\n const materialIndexBuffer = MaterialNode.Materials.a;\n\n // Since materials are stored as indices, there's a bit of a mismatch between FBX and what\n // we expect.So we create an intermediate buffer that points to the index in the buffer,\n // for conforming with the other functions we've written for other data.\n const materialIndices = [];\n\n for (let i = 0; i < materialIndexBuffer.length; ++i) {\n materialIndices.push(i);\n }\n\n return {\n dataSize: 1,\n buffer: materialIndexBuffer,\n indices: materialIndices,\n mappingType: mappingType,\n referenceType: referenceType,\n };\n }\n\n // Generate a NurbGeometry from a node in FBXTree.Objects.Geometry\n parseNurbsGeometry(geoNode) {\n const order = parseInt(geoNode.Order);\n\n if (isNaN(order)) {\n console.error(\n \"THREE.FBXLoader: Invalid Order %s given for geometry ID: %s\",\n geoNode.Order,\n geoNode.id\n );\n return new BufferGeometry();\n }\n\n const degree = order - 1;\n\n const knots = geoNode.KnotVector.a;\n const controlPoints = [];\n const pointsValues = geoNode.Points.a;\n\n for (let i = 0, l = pointsValues.length; i < l; i += 4) {\n controlPoints.push(new Vector4().fromArray(pointsValues, i));\n }\n\n let startKnot, endKnot;\n\n if (geoNode.Form === \"Closed\") {\n controlPoints.push(controlPoints[0]);\n } else if (geoNode.Form === \"Periodic\") {\n startKnot = degree;\n endKnot = knots.length - 1 - startKnot;\n\n for (let i = 0; i < degree; ++i) {\n controlPoints.push(controlPoints[i]);\n }\n }\n\n const curve = new NURBSCurve(\n degree,\n knots,\n controlPoints,\n startKnot,\n endKnot\n );\n const points = curve.getPoints(controlPoints.length * 12);\n\n return new BufferGeometry().setFromPoints(points);\n }\n}\n\n// parse animation data from FBXTree\nclass AnimationParser {\n // take raw animation clips and turn them into three.js animation clips\n parse() {\n const animationClips = [];\n\n const rawClips = this.parseClips();\n\n if (rawClips !== undefined) {\n for (const key in rawClips) {\n const rawClip = rawClips[key];\n\n const clip = this.addClip(rawClip);\n\n animationClips.push(clip);\n }\n }\n\n return animationClips;\n }\n\n parseClips() {\n // since the actual transformation data is stored in FBXTree.Objects.AnimationCurve,\n // if this is undefined we can safely assume there are no animations\n if (fbxTree.Objects.AnimationCurve === undefined) return undefined;\n\n const curveNodesMap = this.parseAnimationCurveNodes();\n\n this.parseAnimationCurves(curveNodesMap);\n\n const layersMap = this.parseAnimationLayers(curveNodesMap);\n const rawClips = this.parseAnimStacks(layersMap);\n\n return rawClips;\n }\n\n // parse nodes in FBXTree.Objects.AnimationCurveNode\n // each AnimationCurveNode holds data for an animation transform for a model (e.g. left arm rotation )\n // and is referenced by an AnimationLayer\n parseAnimationCurveNodes() {\n const rawCurveNodes = fbxTree.Objects.AnimationCurveNode;\n\n const curveNodesMap = new Map();\n\n for (const nodeID in rawCurveNodes) {\n const rawCurveNode = rawCurveNodes[nodeID];\n\n if (rawCurveNode.attrName.match(/S|R|T|DeformPercent/) !== null) {\n const curveNode = {\n id: rawCurveNode.id,\n attr: rawCurveNode.attrName,\n curves: {},\n };\n\n curveNodesMap.set(curveNode.id, curveNode);\n }\n }\n\n return curveNodesMap;\n }\n\n // parse nodes in FBXTree.Objects.AnimationCurve and connect them up to\n // previously parsed AnimationCurveNodes. Each AnimationCurve holds data for a single animated\n // axis ( e.g. times and values of x rotation)\n parseAnimationCurves(curveNodesMap) {\n const rawCurves = fbxTree.Objects.AnimationCurve;\n\n // TODO: Many values are identical up to roundoff error, but won't be optimised\n // e.g. position times: [0, 0.4, 0. 8]\n // position values: [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.23538335023477e-7, 93.67518615722656, -0.9982695579528809, 7.235384487103147e-7, 93.67520904541016, -0.9982695579528809]\n // clearly, this should be optimised to\n // times: [0], positions [7.23538335023477e-7, 93.67518615722656, -0.9982695579528809]\n // this shows up in nearly every FBX file, and generally time array is length > 100\n\n for (const nodeID in rawCurves) {\n const animationCurve = {\n id: rawCurves[nodeID].id,\n times: rawCurves[nodeID].KeyTime.a.map(convertFBXTimeToSeconds),\n values: rawCurves[nodeID].KeyValueFloat.a,\n };\n\n const relationships = connections.get(animationCurve.id);\n\n if (relationships !== undefined) {\n const animationCurveID = relationships.parents[0].ID;\n const animationCurveRelationship =\n relationships.parents[0].relationship;\n\n if (animationCurveRelationship.match(/X/)) {\n curveNodesMap.get(animationCurveID).curves[\"x\"] = animationCurve;\n } else if (animationCurveRelationship.match(/Y/)) {\n curveNodesMap.get(animationCurveID).curves[\"y\"] = animationCurve;\n } else if (animationCurveRelationship.match(/Z/)) {\n curveNodesMap.get(animationCurveID).curves[\"z\"] = animationCurve;\n } else if (\n animationCurveRelationship.match(/DeformPercent/) &&\n curveNodesMap.has(animationCurveID)\n ) {\n curveNodesMap.get(animationCurveID).curves[\"morph\"] = animationCurve;\n }\n }\n }\n }\n\n // parse nodes in FBXTree.Objects.AnimationLayer. Each layers holds references\n // to various AnimationCurveNodes and is referenced by an AnimationStack node\n // note: theoretically a stack can have multiple layers, however in practice there always seems to be one per stack\n parseAnimationLayers(curveNodesMap) {\n const rawLayers = fbxTree.Objects.AnimationLayer;\n\n const layersMap = new Map();\n\n for (const nodeID in rawLayers) {\n const layerCurveNodes = [];\n\n const connection = connections.get(parseInt(nodeID));\n\n if (connection !== undefined) {\n // all the animationCurveNodes used in the layer\n const children = connection.children;\n\n children.forEach(function (child, i) {\n if (curveNodesMap.has(child.ID)) {\n const curveNode = curveNodesMap.get(child.ID);\n\n // check that the curves are defined for at least one axis, otherwise ignore the curveNode\n if (\n curveNode.curves.x !== undefined ||\n curveNode.curves.y !== undefined ||\n curveNode.curves.z !== undefined\n ) {\n if (layerCurveNodes[i] === undefined) {\n const modelID = connections\n .get(child.ID)\n .parents.filter(function (parent) {\n return parent.relationship !== undefined;\n })[0].ID;\n\n if (modelID !== undefined) {\n const rawModel = fbxTree.Objects.Model[modelID.toString()];\n\n if (rawModel === undefined) {\n console.warn(\n \"THREE.FBXLoader: Encountered a unused curve.\",\n child\n );\n return;\n }\n\n const node = {\n modelName: rawModel.attrName\n ? PropertyBinding.sanitizeNodeName(rawModel.attrName)\n : \"\",\n ID: rawModel.id,\n initialPosition: [0, 0, 0],\n initialRotation: [0, 0, 0],\n initialScale: [1, 1, 1],\n };\n\n sceneGraph.traverse(function (child) {\n if (child.ID === rawModel.id) {\n node.transform = child.matrix;\n\n if (child.userData.transformData)\n node.eulerOrder =\n child.userData.transformData.eulerOrder;\n }\n });\n\n if (!node.transform) node.transform = new Matrix4();\n\n // if the animated model is pre rotated, we'll have to apply the pre rotations to every\n // animation value as well\n if (\"PreRotation\" in rawModel)\n node.preRotation = rawModel.PreRotation.value;\n if (\"PostRotation\" in rawModel)\n node.postRotation = rawModel.PostRotation.value;\n\n layerCurveNodes[i] = node;\n }\n }\n\n if (layerCurveNodes[i])\n layerCurveNodes[i][curveNode.attr] = curveNode;\n } else if (curveNode.curves.morph !== undefined) {\n if (layerCurveNodes[i] === undefined) {\n const deformerID = connections\n .get(child.ID)\n .parents.filter(function (parent) {\n return parent.relationship !== undefined;\n })[0].ID;\n\n const morpherID = connections.get(deformerID).parents[0].ID;\n const geoID = connections.get(morpherID).parents[0].ID;\n\n // assuming geometry is not used in more than one model\n const modelID = connections.get(geoID).parents[0].ID;\n\n const rawModel = fbxTree.Objects.Model[modelID];\n\n const node = {\n modelName: rawModel.attrName\n ? PropertyBinding.sanitizeNodeName(rawModel.attrName)\n : \"\",\n morphName: fbxTree.Objects.Deformer[deformerID].attrName,\n };\n\n layerCurveNodes[i] = node;\n }\n\n layerCurveNodes[i][curveNode.attr] = curveNode;\n }\n }\n });\n\n layersMap.set(parseInt(nodeID), layerCurveNodes);\n }\n }\n\n return layersMap;\n }\n\n // parse nodes in FBXTree.Objects.AnimationStack. These are the top level node in the animation\n // hierarchy. Each Stack node will be used to create a AnimationClip\n parseAnimStacks(layersMap) {\n const rawStacks = fbxTree.Objects.AnimationStack;\n\n // connect the stacks (clips) up to the layers\n const rawClips = {};\n\n for (const nodeID in rawStacks) {\n const children = connections.get(parseInt(nodeID)).children;\n\n if (children.length > 1) {\n // it seems like stacks will always be associated with a single layer. But just in case there are files\n // where there are multiple layers per stack, we'll display a warning\n console.warn(\n \"THREE.FBXLoader: Encountered an animation stack with multiple layers, this is currently not supported. Ignoring subsequent layers.\"\n );\n }\n\n const layer = layersMap.get(children[0].ID);\n\n rawClips[nodeID] = {\n name: rawStacks[nodeID].attrName,\n layer: layer,\n };\n }\n\n return rawClips;\n }\n\n addClip(rawClip) {\n let tracks = [];\n\n const scope = this;\n rawClip.layer.forEach(function (rawTracks) {\n tracks = tracks.concat(scope.generateTracks(rawTracks));\n });\n\n return new AnimationClip(rawClip.name, -1, tracks);\n }\n\n generateTracks(rawTracks) {\n const tracks = [];\n\n let initialPosition = new Vector3();\n let initialRotation = new Quaternion();\n let initialScale = new Vector3();\n\n if (rawTracks.transform)\n rawTracks.transform.decompose(\n initialPosition,\n initialRotation,\n initialScale\n );\n\n initialPosition = initialPosition.toArray();\n initialRotation = new Euler()\n .setFromQuaternion(initialRotation, rawTracks.eulerOrder)\n .toArray();\n initialScale = initialScale.toArray();\n\n if (\n rawTracks.T !== undefined &&\n Object.keys(rawTracks.T.curves).length > 0\n ) {\n const positionTrack = this.generateVectorTrack(\n rawTracks.modelName,\n rawTracks.T.curves,\n initialPosition,\n \"position\"\n );\n if (positionTrack !== undefined) tracks.push(positionTrack);\n }\n\n if (\n rawTracks.R !== undefined &&\n Object.keys(rawTracks.R.curves).length > 0\n ) {\n const rotationTrack = this.generateRotationTrack(\n rawTracks.modelName,\n rawTracks.R.curves,\n initialRotation,\n rawTracks.preRotation,\n rawTracks.postRotation,\n rawTracks.eulerOrder\n );\n if (rotationTrack !== undefined) tracks.push(rotationTrack);\n }\n\n if (\n rawTracks.S !== undefined &&\n Object.keys(rawTracks.S.curves).length > 0\n ) {\n const scaleTrack = this.generateVectorTrack(\n rawTracks.modelName,\n rawTracks.S.curves,\n initialScale,\n \"scale\"\n );\n if (scaleTrack !== undefined) tracks.push(scaleTrack);\n }\n\n if (rawTracks.DeformPercent !== undefined) {\n const morphTrack = this.generateMorphTrack(rawTracks);\n if (morphTrack !== undefined) tracks.push(morphTrack);\n }\n\n return tracks;\n }\n\n generateVectorTrack(modelName, curves, initialValue, type) {\n const times = this.getTimesForAllAxes(curves);\n const values = this.getKeyframeTrackValues(times, curves, initialValue);\n\n return new VectorKeyframeTrack(modelName + \".\" + type, times, values);\n }\n\n generateRotationTrack(\n modelName,\n curves,\n initialValue,\n preRotation,\n postRotation,\n eulerOrder\n ) {\n if (curves.x !== undefined) {\n this.interpolateRotations(curves.x);\n curves.x.values = curves.x.values.map(MathUtils.degToRad);\n }\n\n if (curves.y !== undefined) {\n this.interpolateRotations(curves.y);\n curves.y.values = curves.y.values.map(MathUtils.degToRad);\n }\n\n if (curves.z !== undefined) {\n this.interpolateRotations(curves.z);\n curves.z.values = curves.z.values.map(MathUtils.degToRad);\n }\n\n const times = this.getTimesForAllAxes(curves);\n const values = this.getKeyframeTrackValues(times, curves, initialValue);\n\n if (preRotation !== undefined) {\n preRotation = preRotation.map(MathUtils.degToRad);\n preRotation.push(eulerOrder);\n\n preRotation = new Euler().fromArray(preRotation);\n preRotation = new Quaternion().setFromEuler(preRotation);\n }\n\n if (postRotation !== undefined) {\n postRotation = postRotation.map(MathUtils.degToRad);\n postRotation.push(eulerOrder);\n\n postRotation = new Euler().fromArray(postRotation);\n postRotation = new Quaternion().setFromEuler(postRotation).invert();\n }\n\n const quaternion = new Quaternion();\n const euler = new Euler();\n\n const quaternionValues = [];\n\n for (let i = 0; i < values.length; i += 3) {\n euler.set(values[i], values[i + 1], values[i + 2], eulerOrder);\n\n quaternion.setFromEuler(euler);\n\n if (preRotation !== undefined) quaternion.premultiply(preRotation);\n if (postRotation !== undefined) quaternion.multiply(postRotation);\n\n quaternion.toArray(quaternionValues, (i / 3) * 4);\n }\n\n return new QuaternionKeyframeTrack(\n modelName + \".quaternion\",\n times,\n quaternionValues\n );\n }\n\n generateMorphTrack(rawTracks) {\n const curves = rawTracks.DeformPercent.curves.morph;\n const values = curves.values.map(function (val) {\n return val / 100;\n });\n\n const morphNum = sceneGraph.getObjectByName(rawTracks.modelName)\n .morphTargetDictionary[rawTracks.morphName];\n\n return new NumberKeyframeTrack(\n rawTracks.modelName + \".morphTargetInfluences[\" + morphNum + \"]\",\n curves.times,\n values\n );\n }\n\n // For all animated objects, times are defined separately for each axis\n // Here we'll combine the times into one sorted array without duplicates\n getTimesForAllAxes(curves) {\n let times = [];\n\n // first join together the times for each axis, if defined\n if (curves.x !== undefined) times = times.concat(curves.x.times);\n if (curves.y !== undefined) times = times.concat(curves.y.times);\n if (curves.z !== undefined) times = times.concat(curves.z.times);\n\n // then sort them\n times = times.sort(function (a, b) {\n return a - b;\n });\n\n // and remove duplicates\n if (times.length > 1) {\n let targetIndex = 1;\n let lastValue = times[0];\n for (let i = 1; i < times.length; i++) {\n const currentValue = times[i];\n if (currentValue !== lastValue) {\n times[targetIndex] = currentValue;\n lastValue = currentValue;\n targetIndex++;\n }\n }\n\n times = times.slice(0, targetIndex);\n }\n\n return times;\n }\n\n getKeyframeTrackValues(times, curves, initialValue) {\n const prevValue = initialValue;\n\n const values = [];\n\n let xIndex = -1;\n let yIndex = -1;\n let zIndex = -1;\n\n times.forEach(function (time) {\n if (curves.x) xIndex = curves.x.times.indexOf(time);\n if (curves.y) yIndex = curves.y.times.indexOf(time);\n if (curves.z) zIndex = curves.z.times.indexOf(time);\n\n // if there is an x value defined for this frame, use that\n if (xIndex !== -1) {\n const xValue = curves.x.values[xIndex];\n values.push(xValue);\n prevValue[0] = xValue;\n } else {\n // otherwise use the x value from the previous frame\n values.push(prevValue[0]);\n }\n\n if (yIndex !== -1) {\n const yValue = curves.y.values[yIndex];\n values.push(yValue);\n prevValue[1] = yValue;\n } else {\n values.push(prevValue[1]);\n }\n\n if (zIndex !== -1) {\n const zValue = curves.z.values[zIndex];\n values.push(zValue);\n prevValue[2] = zValue;\n } else {\n values.push(prevValue[2]);\n }\n });\n\n return values;\n }\n\n // Rotations are defined as Euler angles which can have values of any size\n // These will be converted to quaternions which don't support values greater than\n // PI, so we'll interpolate large rotations\n interpolateRotations(curve) {\n for (let i = 1; i < curve.values.length; i++) {\n const initialValue = curve.values[i - 1];\n const valuesSpan = curve.values[i] - initialValue;\n\n const absoluteSpan = Math.abs(valuesSpan);\n\n if (absoluteSpan >= 180) {\n const numSubIntervals = absoluteSpan / 180;\n\n const step = valuesSpan / numSubIntervals;\n let nextValue = initialValue + step;\n\n const initialTime = curve.times[i - 1];\n const timeSpan = curve.times[i] - initialTime;\n const interval = timeSpan / numSubIntervals;\n let nextTime = initialTime + interval;\n\n const interpolatedTimes = [];\n const interpolatedValues = [];\n\n while (nextTime < curve.times[i]) {\n interpolatedTimes.push(nextTime);\n nextTime += interval;\n\n interpolatedValues.push(nextValue);\n nextValue += step;\n }\n\n curve.times = inject(curve.times, i, interpolatedTimes);\n curve.values = inject(curve.values, i, interpolatedValues);\n }\n }\n }\n}\n\n// parse an FBX file in ASCII format\nclass TextParser {\n getPrevNode() {\n return this.nodeStack[this.currentIndent - 2];\n }\n\n getCurrentNode() {\n return this.nodeStack[this.currentIndent - 1];\n }\n\n getCurrentProp() {\n return this.currentProp;\n }\n\n pushStack(node) {\n this.nodeStack.push(node);\n this.currentIndent += 1;\n }\n\n popStack() {\n this.nodeStack.pop();\n this.currentIndent -= 1;\n }\n\n setCurrentProp(val, name) {\n this.currentProp = val;\n this.currentPropName = name;\n }\n\n parse(text) {\n this.currentIndent = 0;\n\n this.allNodes = new FBXTree();\n this.nodeStack = [];\n this.currentProp = [];\n this.currentPropName = \"\";\n\n const scope = this;\n\n const split = text.split(/[\\r\\n]+/);\n\n split.forEach(function (line, i) {\n const matchComment = line.match(/^[\\s\\t]*;/);\n const matchEmpty = line.match(/^[\\s\\t]*$/);\n\n if (matchComment || matchEmpty) return;\n\n const matchBeginning = line.match(\n \"^\\\\t{\" + scope.currentIndent + \"}(\\\\w+):(.*){\",\n \"\"\n );\n const matchProperty = line.match(\n \"^\\\\t{\" + scope.currentIndent + \"}(\\\\w+):[\\\\s\\\\t\\\\r\\\\n](.*)\"\n );\n const matchEnd = line.match(\"^\\\\t{\" + (scope.currentIndent - 1) + \"}}\");\n\n if (matchBeginning) {\n scope.parseNodeBegin(line, matchBeginning);\n } else if (matchProperty) {\n scope.parseNodeProperty(line, matchProperty, split[++i]);\n } else if (matchEnd) {\n scope.popStack();\n } else if (line.match(/^[^\\s\\t}]/)) {\n // large arrays are split over multiple lines terminated with a ',' character\n // if this is encountered the line needs to be joined to the previous line\n scope.parseNodePropertyContinued(line);\n }\n });\n\n return this.allNodes;\n }\n\n parseNodeBegin(line, property) {\n const nodeName = property[1].trim().replace(/^\"/, \"\").replace(/\"$/, \"\");\n\n const nodeAttrs = property[2].split(\",\").map(function (attr) {\n return attr.trim().replace(/^\"/, \"\").replace(/\"$/, \"\");\n });\n\n const node = { name: nodeName };\n const attrs = this.parseNodeAttr(nodeAttrs);\n\n const currentNode = this.getCurrentNode();\n\n // a top node\n if (this.currentIndent === 0) {\n this.allNodes.add(nodeName, node);\n } else {\n // a subnode\n\n // if the subnode already exists, append it\n if (nodeName in currentNode) {\n // special case Pose needs PoseNodes as an array\n if (nodeName === \"PoseNode\") {\n currentNode.PoseNode.push(node);\n } else if (currentNode[nodeName].id !== undefined) {\n currentNode[nodeName] = {};\n currentNode[nodeName][currentNode[nodeName].id] =\n currentNode[nodeName];\n }\n\n if (attrs.id !== \"\") currentNode[nodeName][attrs.id] = node;\n } else if (typeof attrs.id === \"number\") {\n currentNode[nodeName] = {};\n currentNode[nodeName][attrs.id] = node;\n } else if (nodeName !== \"Properties70\") {\n if (nodeName === \"PoseNode\") currentNode[nodeName] = [node];\n else currentNode[nodeName] = node;\n }\n }\n\n if (typeof attrs.id === \"number\") node.id = attrs.id;\n if (attrs.name !== \"\") node.attrName = attrs.name;\n if (attrs.type !== \"\") node.attrType = attrs.type;\n\n this.pushStack(node);\n }\n\n parseNodeAttr(attrs) {\n let id = attrs[0];\n\n if (attrs[0] !== \"\") {\n id = parseInt(attrs[0]);\n\n if (isNaN(id)) {\n id = attrs[0];\n }\n }\n\n let name = \"\",\n type = \"\";\n\n if (attrs.length > 1) {\n name = attrs[1].replace(/^(\\w+)::/, \"\");\n type = attrs[2];\n }\n\n return { id: id, name: name, type: type };\n }\n\n parseNodeProperty(line, property, contentLine) {\n let propName = property[1].replace(/^\"/, \"\").replace(/\"$/, \"\").trim();\n let propValue = property[2].replace(/^\"/, \"\").replace(/\"$/, \"\").trim();\n\n // for special case: base64 image data follows \"Content: ,\" line\n //\tContent: ,\n //\t \"/9j/4RDaRXhpZgAATU0A...\"\n if (propName === \"Content\" && propValue === \",\") {\n propValue = contentLine.replace(/\"/g, \"\").replace(/,$/, \"\").trim();\n }\n\n const currentNode = this.getCurrentNode();\n const parentName = currentNode.name;\n\n if (parentName === \"Properties70\") {\n this.parseNodeSpecialProperty(line, propName, propValue);\n return;\n }\n\n // Connections\n if (propName === \"C\") {\n const connProps = propValue.split(\",\").slice(1);\n const from = parseInt(connProps[0]);\n const to = parseInt(connProps[1]);\n\n let rest = propValue.split(\",\").slice(3);\n\n rest = rest.map(function (elem) {\n return elem.trim().replace(/^\"/, \"\");\n });\n\n propName = \"connections\";\n propValue = [from, to];\n append(propValue, rest);\n\n if (currentNode[propName] === undefined) {\n currentNode[propName] = [];\n }\n }\n\n // Node\n if (propName === \"Node\") currentNode.id = propValue;\n\n // connections\n if (propName in currentNode && Array.isArray(currentNode[propName])) {\n currentNode[propName].push(propValue);\n } else {\n if (propName !== \"a\") currentNode[propName] = propValue;\n else currentNode.a = propValue;\n }\n\n this.setCurrentProp(currentNode, propName);\n\n // convert string to array, unless it ends in ',' in which case more will be added to it\n if (propName === \"a\" && propValue.slice(-1) !== \",\") {\n currentNode.a = parseNumberArray(propValue);\n }\n }\n\n parseNodePropertyContinued(line) {\n const currentNode = this.getCurrentNode();\n\n currentNode.a += line;\n\n // if the line doesn't end in ',' we have reached the end of the property value\n // so convert the string to an array\n if (line.slice(-1) !== \",\") {\n currentNode.a = parseNumberArray(currentNode.a);\n }\n }\n\n // parse \"Property70\"\n parseNodeSpecialProperty(line, propName, propValue) {\n // split this\n // P: \"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\",1,1,1\n // into array like below\n // [\"Lcl Scaling\", \"Lcl Scaling\", \"\", \"A\", \"1,1,1\" ]\n const props = propValue.split('\",').map(function (prop) {\n return prop.trim().replace(/^\\\"/, \"\").replace(/\\s/, \"_\");\n });\n\n const innerPropName = props[0];\n const innerPropType1 = props[1];\n const innerPropType2 = props[2];\n const innerPropFlag = props[3];\n let innerPropValue = props[4];\n\n // cast values where needed, otherwise leave as strings\n switch (innerPropType1) {\n case \"int\":\n case \"enum\":\n case \"bool\":\n case \"ULongLong\":\n case \"double\":\n case \"Number\":\n case \"FieldOfView\":\n innerPropValue = parseFloat(innerPropValue);\n break;\n\n case \"Color\":\n case \"ColorRGB\":\n case \"Vector3D\":\n case \"Lcl_Translation\":\n case \"Lcl_Rotation\":\n case \"Lcl_Scaling\":\n innerPropValue = parseNumberArray(innerPropValue);\n break;\n }\n\n // CAUTION: these props must append to parent's parent\n this.getPrevNode()[innerPropName] = {\n type: innerPropType1,\n type2: innerPropType2,\n flag: innerPropFlag,\n value: innerPropValue,\n };\n\n this.setCurrentProp(this.getPrevNode(), innerPropName);\n }\n}\n\n// Parse an FBX file in Binary format\nclass BinaryParser {\n parse(buffer) {\n const reader = new BinaryReader(buffer);\n reader.skip(23); // skip magic 23 bytes\n\n const version = reader.getUint32();\n\n if (version < 6400) {\n throw new Error(\n \"THREE.FBXLoader: FBX version not supported, FileVersion: \" + version\n );\n }\n\n const allNodes = new FBXTree();\n\n while (!this.endOfContent(reader)) {\n const node = this.parseNode(reader, version);\n if (node !== null) allNodes.add(node.name, node);\n }\n\n return allNodes;\n }\n\n // Check if reader has reached the end of content.\n endOfContent(reader) {\n // footer size: 160bytes + 16-byte alignment padding\n // - 16bytes: magic\n // - padding til 16-byte alignment (at least 1byte?)\n //\t(seems like some exporters embed fixed 15 or 16bytes?)\n // - 4bytes: magic\n // - 4bytes: version\n // - 120bytes: zero\n // - 16bytes: magic\n if (reader.size() % 16 === 0) {\n return ((reader.getOffset() + 160 + 16) & ~0xf) >= reader.size();\n } else {\n return reader.getOffset() + 160 + 16 >= reader.size();\n }\n }\n\n // recursively parse nodes until the end of the file is reached\n parseNode(reader, version) {\n const node = {};\n\n // The first three data sizes depends on version.\n const endOffset = version >= 7500 ? reader.getUint64() : reader.getUint32();\n const numProperties =\n version >= 7500 ? reader.getUint64() : reader.getUint32();\n\n version >= 7500 ? reader.getUint64() : reader.getUint32(); // the returned propertyListLen is not used\n\n const nameLen = reader.getUint8();\n const name = reader.getString(nameLen);\n\n // Regards this node as NULL-record if endOffset is zero\n if (endOffset === 0) return null;\n\n const propertyList = [];\n\n for (let i = 0; i < numProperties; i++) {\n propertyList.push(this.parseProperty(reader));\n }\n\n // Regards the first three elements in propertyList as id, attrName, and attrType\n const id = propertyList.length > 0 ? propertyList[0] : \"\";\n const attrName = propertyList.length > 1 ? propertyList[1] : \"\";\n const attrType = propertyList.length > 2 ? propertyList[2] : \"\";\n\n // check if this node represents just a single property\n // like (name, 0) set or (name2, [0, 1, 2]) set of {name: 0, name2: [0, 1, 2]}\n node.singleProperty =\n numProperties === 1 && reader.getOffset() === endOffset ? true : false;\n\n while (endOffset > reader.getOffset()) {\n const subNode = this.parseNode(reader, version);\n\n if (subNode !== null) this.parseSubNode(name, node, subNode);\n }\n\n node.propertyList = propertyList; // raw property list used by parent\n\n if (typeof id === \"number\") node.id = id;\n if (attrName !== \"\") node.attrName = attrName;\n if (attrType !== \"\") node.attrType = attrType;\n if (name !== \"\") node.name = name;\n\n return node;\n }\n\n parseSubNode(name, node, subNode) {\n // special case: child node is single property\n if (subNode.singleProperty === true) {\n const value = subNode.propertyList[0];\n\n if (Array.isArray(value)) {\n node[subNode.name] = subNode;\n\n subNode.a = value;\n } else {\n node[subNode.name] = value;\n }\n } else if (name === \"Connections\" && subNode.name === \"C\") {\n const array = [];\n\n subNode.propertyList.forEach(function (property, i) {\n // first Connection is FBX type (OO, OP, etc.). We'll discard these\n if (i !== 0) array.push(property);\n });\n\n if (node.connections === undefined) {\n node.connections = [];\n }\n\n node.connections.push(array);\n } else if (subNode.name === \"Properties70\") {\n const keys = Object.keys(subNode);\n\n keys.forEach(function (key) {\n node[key] = subNode[key];\n });\n } else if (name === \"Properties70\" && subNode.name === \"P\") {\n let innerPropName = subNode.propertyList[0];\n let innerPropType1 = subNode.propertyList[1];\n const innerPropType2 = subNode.propertyList[2];\n const innerPropFlag = subNode.propertyList[3];\n let innerPropValue;\n\n if (innerPropName.indexOf(\"Lcl \") === 0)\n innerPropName = innerPropName.replace(\"Lcl \", \"Lcl_\");\n if (innerPropType1.indexOf(\"Lcl \") === 0)\n innerPropType1 = innerPropType1.replace(\"Lcl \", \"Lcl_\");\n\n if (\n innerPropType1 === \"Color\" ||\n innerPropType1 === \"ColorRGB\" ||\n innerPropType1 === \"Vector\" ||\n innerPropType1 === \"Vector3D\" ||\n innerPropType1.indexOf(\"Lcl_\") === 0\n ) {\n innerPropValue = [\n subNode.propertyList[4],\n subNode.propertyList[5],\n subNode.propertyList[6],\n ];\n } else {\n innerPropValue = subNode.propertyList[4];\n }\n\n // this will be copied to parent, see above\n node[innerPropName] = {\n type: innerPropType1,\n type2: innerPropType2,\n flag: innerPropFlag,\n value: innerPropValue,\n };\n } else if (node[subNode.name] === undefined) {\n if (typeof subNode.id === \"number\") {\n node[subNode.name] = {};\n node[subNode.name][subNode.id] = subNode;\n } else {\n node[subNode.name] = subNode;\n }\n } else {\n if (subNode.name === \"PoseNode\") {\n if (!Array.isArray(node[subNode.name])) {\n node[subNode.name] = [node[subNode.name]];\n }\n\n node[subNode.name].push(subNode);\n } else if (node[subNode.name][subNode.id] === undefined) {\n node[subNode.name][subNode.id] = subNode;\n }\n }\n }\n\n parseProperty(reader) {\n const type = reader.getString(1);\n let length;\n\n switch (type) {\n case \"C\":\n return reader.getBoolean();\n\n case \"D\":\n return reader.getFloat64();\n\n case \"F\":\n return reader.getFloat32();\n\n case \"I\":\n return reader.getInt32();\n\n case \"L\":\n return reader.getInt64();\n\n case \"R\":\n length = reader.getUint32();\n return reader.getArrayBuffer(length);\n\n case \"S\":\n length = reader.getUint32();\n return reader.getString(length);\n\n case \"Y\":\n return reader.getInt16();\n\n case \"b\":\n case \"c\":\n case \"d\":\n case \"f\":\n case \"i\":\n case \"l\":\n const arrayLength = reader.getUint32();\n const encoding = reader.getUint32(); // 0: non-compressed, 1: compressed\n const compressedLength = reader.getUint32();\n\n if (encoding === 0) {\n switch (type) {\n case \"b\":\n case \"c\":\n return reader.getBooleanArray(arrayLength);\n\n case \"d\":\n return reader.getFloat64Array(arrayLength);\n\n case \"f\":\n return reader.getFloat32Array(arrayLength);\n\n case \"i\":\n return reader.getInt32Array(arrayLength);\n\n case \"l\":\n return reader.getInt64Array(arrayLength);\n }\n }\n\n const data = fflate.unzlibSync(\n new Uint8Array(reader.getArrayBuffer(compressedLength))\n );\n const reader2 = new BinaryReader(data.buffer);\n\n switch (type) {\n case \"b\":\n case \"c\":\n return reader2.getBooleanArray(arrayLength);\n\n case \"d\":\n return reader2.getFloat64Array(arrayLength);\n\n case \"f\":\n return reader2.getFloat32Array(arrayLength);\n\n case \"i\":\n return reader2.getInt32Array(arrayLength);\n\n case \"l\":\n return reader2.getInt64Array(arrayLength);\n }\n\n break; // cannot happen but is required by the DeepScan\n\n default:\n throw new Error(\"THREE.FBXLoader: Unknown property type \" + type);\n }\n }\n}\n\nclass BinaryReader {\n constructor(buffer, littleEndian) {\n this.dv = new DataView(buffer);\n this.offset = 0;\n this.littleEndian = littleEndian !== undefined ? littleEndian : true;\n this._textDecoder = new TextDecoder();\n }\n\n getOffset() {\n return this.offset;\n }\n\n size() {\n return this.dv.buffer.byteLength;\n }\n\n skip(length) {\n this.offset += length;\n }\n\n // seems like true/false representation depends on exporter.\n // true: 1 or 'Y'(=0x59), false: 0 or 'T'(=0x54)\n // then sees LSB.\n getBoolean() {\n return (this.getUint8() & 1) === 1;\n }\n\n getBooleanArray(size) {\n const a = [];\n\n for (let i = 0; i < size; i++) {\n a.push(this.getBoolean());\n }\n\n return a;\n }\n\n getUint8() {\n const value = this.dv.getUint8(this.offset);\n this.offset += 1;\n return value;\n }\n\n getInt16() {\n const value = this.dv.getInt16(this.offset, this.littleEndian);\n this.offset += 2;\n return value;\n }\n\n getInt32() {\n const value = this.dv.getInt32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n getInt32Array(size) {\n const a = [];\n\n for (let i = 0; i < size; i++) {\n a.push(this.getInt32());\n }\n\n return a;\n }\n\n getUint32() {\n const value = this.dv.getUint32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n // JavaScript doesn't support 64-bit integer so calculate this here\n // 1 << 32 will return 1 so using multiply operation instead here.\n // There's a possibility that this method returns wrong value if the value\n // is out of the range between Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER.\n // TODO: safely handle 64-bit integer\n getInt64() {\n let low, high;\n\n if (this.littleEndian) {\n low = this.getUint32();\n high = this.getUint32();\n } else {\n high = this.getUint32();\n low = this.getUint32();\n }\n\n // calculate negative value\n if (high & 0x80000000) {\n high = ~high & 0xffffffff;\n low = ~low & 0xffffffff;\n\n if (low === 0xffffffff) high = (high + 1) & 0xffffffff;\n\n low = (low + 1) & 0xffffffff;\n\n return -(high * 0x100000000 + low);\n }\n\n return high * 0x100000000 + low;\n }\n\n getInt64Array(size) {\n const a = [];\n\n for (let i = 0; i < size; i++) {\n a.push(this.getInt64());\n }\n\n return a;\n }\n\n // Note: see getInt64() comment\n getUint64() {\n let low, high;\n\n if (this.littleEndian) {\n low = this.getUint32();\n high = this.getUint32();\n } else {\n high = this.getUint32();\n low = this.getUint32();\n }\n\n return high * 0x100000000 + low;\n }\n\n getFloat32() {\n const value = this.dv.getFloat32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n getFloat32Array(size) {\n const a = [];\n\n for (let i = 0; i < size; i++) {\n a.push(this.getFloat32());\n }\n\n return a;\n }\n\n getFloat64() {\n const value = this.dv.getFloat64(this.offset, this.littleEndian);\n this.offset += 8;\n return value;\n }\n\n getFloat64Array(size) {\n const a = [];\n\n for (let i = 0; i < size; i++) {\n a.push(this.getFloat64());\n }\n\n return a;\n }\n\n getArrayBuffer(size) {\n const value = this.dv.buffer.slice(this.offset, this.offset + size);\n this.offset += size;\n return value;\n }\n\n getString(size) {\n const start = this.offset;\n let a = new Uint8Array(this.dv.buffer, start, size);\n\n this.skip(size);\n\n const nullByte = a.indexOf(0);\n if (nullByte >= 0) a = new Uint8Array(this.dv.buffer, start, nullByte);\n\n return this._textDecoder.decode(a);\n }\n}\n\n// FBXTree holds a representation of the FBX data, returned by the TextParser ( FBX ASCII format)\n// and BinaryParser( FBX Binary format)\nclass FBXTree {\n add(key, val) {\n this[key] = val;\n }\n}\n\n// ************** UTILITY FUNCTIONS **************\n\nfunction isFbxFormatBinary(buffer) {\n const CORRECT = \"Kaydara\\u0020FBX\\u0020Binary\\u0020\\u0020\\0\";\n\n return (\n buffer.byteLength >= CORRECT.length &&\n CORRECT === convertArrayBufferToString(buffer, 0, CORRECT.length)\n );\n}\n\nfunction isFbxFormatASCII(text) {\n const CORRECT = [\n \"K\",\n \"a\",\n \"y\",\n \"d\",\n \"a\",\n \"r\",\n \"a\",\n \"\\\\\",\n \"F\",\n \"B\",\n \"X\",\n \"\\\\\",\n \"B\",\n \"i\",\n \"n\",\n \"a\",\n \"r\",\n \"y\",\n \"\\\\\",\n \"\\\\\",\n ];\n\n let cursor = 0;\n\n function read(offset) {\n const result = text[offset - 1];\n text = text.slice(cursor + offset);\n cursor++;\n return result;\n }\n\n for (let i = 0; i < CORRECT.length; ++i) {\n const num = read(1);\n if (num === CORRECT[i]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction getFbxVersion(text) {\n const versionRegExp = /FBXVersion: (\\d+)/;\n const match = text.match(versionRegExp);\n\n if (match) {\n const version = parseInt(match[1]);\n return version;\n }\n\n throw new Error(\n \"THREE.FBXLoader: Cannot find the version number for the file given.\"\n );\n}\n\n// Converts FBX ticks into real time seconds.\nfunction convertFBXTimeToSeconds(time) {\n return time / 46186158000;\n}\n\nconst dataArray = [];\n\n// extracts the data from the correct position in the FBX array based on indexing type\nfunction getData(polygonVertexIndex, polygonIndex, vertexIndex, infoObject) {\n let index;\n\n switch (infoObject.mappingType) {\n case \"ByPolygonVertex\":\n index = polygonVertexIndex;\n break;\n case \"ByPolygon\":\n index = polygonIndex;\n break;\n case \"ByVertice\":\n index = vertexIndex;\n break;\n case \"AllSame\":\n index = infoObject.indices[0];\n break;\n default:\n console.warn(\n \"THREE.FBXLoader: unknown attribute mapping type \" +\n infoObject.mappingType\n );\n }\n\n if (infoObject.referenceType === \"IndexToDirect\")\n index = infoObject.indices[index];\n\n const from = index * infoObject.dataSize;\n const to = from + infoObject.dataSize;\n\n return slice(dataArray, infoObject.buffer, from, to);\n}\n\nconst tempEuler = new Euler();\nconst tempVec = new Vector3();\n\n// generate transformation from FBX transform data\n// ref: https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_10CDD63C_79C1_4F2D_BB28_AD2BE65A02ED_htm\n// ref: http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=cpp_ref/_transformations_2main_8cxx-example.html,topicNumber=cpp_ref__transformations_2main_8cxx_example_htmlfc10a1e1-b18d-4e72-9dc0-70d0f1959f5e\nfunction generateTransform(transformData) {\n const lTranslationM = new Matrix4();\n const lPreRotationM = new Matrix4();\n const lRotationM = new Matrix4();\n const lPostRotationM = new Matrix4();\n\n const lScalingM = new Matrix4();\n const lScalingPivotM = new Matrix4();\n const lScalingOffsetM = new Matrix4();\n const lRotationOffsetM = new Matrix4();\n const lRotationPivotM = new Matrix4();\n\n const lParentGX = new Matrix4();\n const lParentLX = new Matrix4();\n const lGlobalT = new Matrix4();\n\n const inheritType = transformData.inheritType ? transformData.inheritType : 0;\n\n if (transformData.translation)\n lTranslationM.setPosition(tempVec.fromArray(transformData.translation));\n\n if (transformData.preRotation) {\n const array = transformData.preRotation.map(MathUtils.degToRad);\n array.push(transformData.eulerOrder || Euler.DEFAULT_ORDER);\n lPreRotationM.makeRotationFromEuler(tempEuler.fromArray(array));\n }\n\n if (transformData.rotation) {\n const array = transformData.rotation.map(MathUtils.degToRad);\n array.push(transformData.eulerOrder || Euler.DEFAULT_ORDER);\n lRotationM.makeRotationFromEuler(tempEuler.fromArray(array));\n }\n\n if (transformData.postRotation) {\n const array = transformData.postRotation.map(MathUtils.degToRad);\n array.push(transformData.eulerOrder || Euler.DEFAULT_ORDER);\n lPostRotationM.makeRotationFromEuler(tempEuler.fromArray(array));\n lPostRotationM.invert();\n }\n\n if (transformData.scale)\n lScalingM.scale(tempVec.fromArray(transformData.scale));\n\n // Pivots and offsets\n if (transformData.scalingOffset)\n lScalingOffsetM.setPosition(tempVec.fromArray(transformData.scalingOffset));\n if (transformData.scalingPivot)\n lScalingPivotM.setPosition(tempVec.fromArray(transformData.scalingPivot));\n if (transformData.rotationOffset)\n lRotationOffsetM.setPosition(\n tempVec.fromArray(transformData.rotationOffset)\n );\n if (transformData.rotationPivot)\n lRotationPivotM.setPosition(tempVec.fromArray(transformData.rotationPivot));\n\n // parent transform\n if (transformData.parentMatrixWorld) {\n lParentLX.copy(transformData.parentMatrix);\n lParentGX.copy(transformData.parentMatrixWorld);\n }\n\n const lLRM = lPreRotationM\n .clone()\n .multiply(lRotationM)\n .multiply(lPostRotationM);\n // Global Rotation\n const lParentGRM = new Matrix4();\n lParentGRM.extractRotation(lParentGX);\n\n // Global Shear*Scaling\n const lParentTM = new Matrix4();\n lParentTM.copyPosition(lParentGX);\n\n const lParentGRSM = lParentTM.clone().invert().multiply(lParentGX);\n const lParentGSM = lParentGRM.clone().invert().multiply(lParentGRSM);\n const lLSM = lScalingM;\n\n const lGlobalRS = new Matrix4();\n\n if (inheritType === 0) {\n lGlobalRS\n .copy(lParentGRM)\n .multiply(lLRM)\n .multiply(lParentGSM)\n .multiply(lLSM);\n } else if (inheritType === 1) {\n lGlobalRS\n .copy(lParentGRM)\n .multiply(lParentGSM)\n .multiply(lLRM)\n .multiply(lLSM);\n } else {\n const lParentLSM = new Matrix4().scale(\n new Vector3().setFromMatrixScale(lParentLX)\n );\n const lParentLSM_inv = lParentLSM.clone().invert();\n const lParentGSM_noLocal = lParentGSM.clone().multiply(lParentLSM_inv);\n\n lGlobalRS\n .copy(lParentGRM)\n .multiply(lLRM)\n .multiply(lParentGSM_noLocal)\n .multiply(lLSM);\n }\n\n const lRotationPivotM_inv = lRotationPivotM.clone().invert();\n const lScalingPivotM_inv = lScalingPivotM.clone().invert();\n // Calculate the local transform matrix\n let lTransform = lTranslationM\n .clone()\n .multiply(lRotationOffsetM)\n .multiply(lRotationPivotM)\n .multiply(lPreRotationM)\n .multiply(lRotationM)\n .multiply(lPostRotationM)\n .multiply(lRotationPivotM_inv)\n .multiply(lScalingOffsetM)\n .multiply(lScalingPivotM)\n .multiply(lScalingM)\n .multiply(lScalingPivotM_inv);\n\n const lLocalTWithAllPivotAndOffsetInfo = new Matrix4().copyPosition(\n lTransform\n );\n\n const lGlobalTranslation = lParentGX\n .clone()\n .multiply(lLocalTWithAllPivotAndOffsetInfo);\n lGlobalT.copyPosition(lGlobalTranslation);\n\n lTransform = lGlobalT.clone().multiply(lGlobalRS);\n\n // from global to local\n lTransform.premultiply(lParentGX.invert());\n\n return lTransform;\n}\n\n// Returns the three.js intrinsic Euler order corresponding to FBX extrinsic Euler order\n// ref: http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_euler_html\nfunction getEulerOrder(order) {\n order = order || 0;\n\n const enums = [\n \"ZYX\", // -> XYZ extrinsic\n \"YZX\", // -> XZY extrinsic\n \"XZY\", // -> YZX extrinsic\n \"ZXY\", // -> YXZ extrinsic\n \"YXZ\", // -> ZXY extrinsic\n \"XYZ\", // -> ZYX extrinsic\n //'SphericXYZ', // not possible to support\n ];\n\n if (order === 6) {\n console.warn(\n \"THREE.FBXLoader: unsupported Euler Order: Spherical XYZ. Animations and rotations may be incorrect.\"\n );\n return enums[0];\n }\n\n return enums[order];\n}\n\n// Parses comma separated list of numbers and returns them an array.\n// Used internally by the TextParser\nfunction parseNumberArray(value) {\n const array = value.split(\",\").map(function (val) {\n return parseFloat(val);\n });\n\n return array;\n}\n\nfunction convertArrayBufferToString(buffer, from, to) {\n if (from === undefined) from = 0;\n if (to === undefined) to = buffer.byteLength;\n\n return new TextDecoder().decode(new Uint8Array(buffer, from, to));\n}\n\nfunction append(a, b) {\n for (let i = 0, j = a.length, l = b.length; i < l; i++, j++) {\n a[j] = b[i];\n }\n}\n\nfunction slice(a, b, from, to) {\n for (let i = from, j = 0; i < to; i++, j++) {\n a[j] = b[i];\n }\n\n return a;\n}\n\n// inject array a2 into array a1 at index\nfunction inject(a1, index, a2) {\n return a1.slice(0, index).concat(a2).concat(a1.slice(index));\n}\n\nexport { FBXLoader };\n"],"mappings":"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"},"metadata":{},"sourceType":"module","externalDependencies":[]}
|