diff --git a/aframe/collada/collada-model.js b/aframe/collada/collada-model.js index d3d5761..c749be9 100644 --- a/aframe/collada/collada-model.js +++ b/aframe/collada/collada-model.js @@ -1,4 +1,4 @@ -import "./lib/ColladaLoader.js"; +import { ColladaLoader } from 'three/examples/jsm/loaders/ColladaLoader.js'; export const Component = AFRAME.registerComponent('collada-model', { schema: { @@ -8,8 +8,7 @@ export const Component = AFRAME.registerComponent('collada-model', { init: function () { this.model = null; - this.loader = new THREE.ColladaLoader(); - this.loader.options.convertUpAxis = true; + this.loader = new ColladaLoader(); }, update: function () { diff --git a/aframe/collada/dist/collada-model.js b/aframe/collada/dist/collada-model.js index c1c494b..7dd515f 100644 --- a/aframe/collada/dist/collada-model.js +++ b/aframe/collada/dist/collada-model.js @@ -1,3018 +1 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 0) tracks.push(new THREE.VectorKeyframeTrack(name + '.position', times, positionData)); - if (quaternionData.length > 0) tracks.push(new THREE.QuaternionKeyframeTrack(name + '.quaternion', times, quaternionData)); - if (scaleData.length > 0) tracks.push(new THREE.VectorKeyframeTrack(name + '.scale', times, scaleData)); - return tracks; - } - - function transformAnimationData(keyframes, property, defaultValue) { - var keyframe; - var empty = true; - var i, l; // check, if values of a property are missing in our keyframes - - for (i = 0, l = keyframes.length; i < l; i++) { - keyframe = keyframes[i]; - - if (keyframe.value[property] === undefined) { - keyframe.value[property] = null; // mark as missing - } else { - empty = false; - } - } - - if (empty === true) { - // no values at all, so we set a default value - for (i = 0, l = keyframes.length; i < l; i++) { - keyframe = keyframes[i]; - keyframe.value[property] = defaultValue; - } - } else { - // filling gaps - createMissingKeyframes(keyframes, property); - } - } - - function createMissingKeyframes(keyframes, property) { - var prev, next; - - for (var i = 0, l = keyframes.length; i < l; i++) { - var keyframe = keyframes[i]; - - if (keyframe.value[property] === null) { - prev = getPrev(keyframes, i, property); - next = getNext(keyframes, i, property); - - if (prev === null) { - keyframe.value[property] = next.value[property]; - continue; - } - - if (next === null) { - keyframe.value[property] = prev.value[property]; - continue; - } - - interpolate(keyframe, prev, next, property); - } - } - } - - function getPrev(keyframes, i, property) { - while (i >= 0) { - var keyframe = keyframes[i]; - if (keyframe.value[property] !== null) return keyframe; - i--; - } - - return null; - } - - function getNext(keyframes, i, property) { - while (i < keyframes.length) { - var keyframe = keyframes[i]; - if (keyframe.value[property] !== null) return keyframe; - i++; - } - - return null; - } - - function interpolate(key, prev, next, property) { - if (next.time - prev.time === 0) { - key.value[property] = prev.value[property]; - return; - } - - key.value[property] = (key.time - prev.time) * (next.value[property] - prev.value[property]) / (next.time - prev.time) + prev.value[property]; - } // animation clips - - - function parseAnimationClip(xml) { - var data = { - name: xml.getAttribute('id') || 'default', - start: parseFloat(xml.getAttribute('start') || 0), - end: parseFloat(xml.getAttribute('end') || 0), - animations: [] - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'instance_animation': - data.animations.push(parseId(child.getAttribute('url'))); - break; - } - } - - library.clips[xml.getAttribute('id')] = data; - } - - function buildAnimationClip(data) { - var tracks = []; - var name = data.name; - var duration = data.end - data.start || -1; - var animations = data.animations; - - for (var i = 0, il = animations.length; i < il; i++) { - var animationTracks = getAnimation(animations[i]); - - for (var j = 0, jl = animationTracks.length; j < jl; j++) { - tracks.push(animationTracks[j]); - } - } - - return new THREE.AnimationClip(name, duration, tracks); - } - - function getAnimationClip(id) { - return getBuild(library.clips[id], buildAnimationClip); - } // controller - - - function parseController(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'skin': - // there is exactly one skin per controller - data.id = parseId(child.getAttribute('source')); - data.skin = parseSkin(child); - break; - - case 'morph': - data.id = parseId(child.getAttribute('source')); - console.warn('THREE.ColladaLoader: Morph target animation not supported yet.'); - break; - } - } - - library.controllers[xml.getAttribute('id')] = data; - } - - function parseSkin(xml) { - var data = { - sources: {} - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'bind_shape_matrix': - data.bindShapeMatrix = parseFloats(child.textContent); - break; - - case 'source': - var id = child.getAttribute('id'); - data.sources[id] = parseSource(child); - break; - - case 'joints': - data.joints = parseJoints(child); - break; - - case 'vertex_weights': - data.vertexWeights = parseVertexWeights(child); - break; - } - } - - return data; - } - - function parseJoints(xml) { - var data = { - inputs: {} - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'input': - var semantic = child.getAttribute('semantic'); - var id = parseId(child.getAttribute('source')); - data.inputs[semantic] = id; - break; - } - } - - return data; - } - - function parseVertexWeights(xml) { - var data = { - inputs: {} - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'input': - var semantic = child.getAttribute('semantic'); - var id = parseId(child.getAttribute('source')); - var offset = parseInt(child.getAttribute('offset')); - data.inputs[semantic] = { - id: id, - offset: offset - }; - break; - - case 'vcount': - data.vcount = parseInts(child.textContent); - break; - - case 'v': - data.v = parseInts(child.textContent); - break; - } - } - - return data; - } - - function buildController(data) { - var build = { - id: data.id - }; - var geometry = library.geometries[build.id]; - - if (data.skin !== undefined) { - build.skin = buildSkin(data.skin); // we enhance the 'sources' property of the corresponding geometry with our skin data - - geometry.sources.skinIndices = build.skin.indices; - geometry.sources.skinWeights = build.skin.weights; - } - - return build; - } - - function buildSkin(data) { - var BONE_LIMIT = 4; - var build = { - joints: [], - // this must be an array to preserve the joint order - indices: { - array: [], - stride: BONE_LIMIT - }, - weights: { - array: [], - stride: BONE_LIMIT - } - }; - var sources = data.sources; - var vertexWeights = data.vertexWeights; - var vcount = vertexWeights.vcount; - var v = vertexWeights.v; - var jointOffset = vertexWeights.inputs.JOINT.offset; - var weightOffset = vertexWeights.inputs.WEIGHT.offset; - var jointSource = data.sources[data.joints.inputs.JOINT]; - var inverseSource = data.sources[data.joints.inputs.INV_BIND_MATRIX]; - var weights = sources[vertexWeights.inputs.WEIGHT.id].array; - var stride = 0; - var i, j, l; // procces skin data for each vertex - - for (i = 0, l = vcount.length; i < l; i++) { - var jointCount = vcount[i]; // this is the amount of joints that affect a single vertex - - var vertexSkinData = []; - - for (j = 0; j < jointCount; j++) { - var skinIndex = v[stride + jointOffset]; - var weightId = v[stride + weightOffset]; - var skinWeight = weights[weightId]; - vertexSkinData.push({ - index: skinIndex, - weight: skinWeight - }); - stride += 2; - } // we sort the joints in descending order based on the weights. - // this ensures, we only procced the most important joints of the vertex - - - vertexSkinData.sort(descending); // now we provide for each vertex a set of four index and weight values. - // the order of the skin data matches the order of vertices - - for (j = 0; j < BONE_LIMIT; j++) { - var d = vertexSkinData[j]; - - if (d !== undefined) { - build.indices.array.push(d.index); - build.weights.array.push(d.weight); - } else { - build.indices.array.push(0); - build.weights.array.push(0); - } - } - } // setup bind matrix - - - if (data.bindShapeMatrix) { - build.bindMatrix = new THREE.Matrix4().fromArray(data.bindShapeMatrix).transpose(); - } else { - build.bindMatrix = new THREE.Matrix4().identity(); - } // process bones and inverse bind matrix data - - - for (i = 0, l = jointSource.array.length; i < l; i++) { - var name = jointSource.array[i]; - var boneInverse = new THREE.Matrix4().fromArray(inverseSource.array, i * inverseSource.stride).transpose(); - build.joints.push({ - name: name, - boneInverse: boneInverse - }); - } - - return build; // array sort function - - function descending(a, b) { - return b.weight - a.weight; - } - } - - function getController(id) { - return getBuild(library.controllers[id], buildController); - } // image - - - function parseImage(xml) { - var data = { - init_from: getElementsByTagName(xml, 'init_from')[0].textContent - }; - library.images[xml.getAttribute('id')] = data; - } - - function buildImage(data) { - if (data.build !== undefined) return data.build; - return data.init_from; - } - - function getImage(id) { - var data = library.images[id]; - - if (data !== undefined) { - return getBuild(data, buildImage); - } - - console.warn('THREE.ColladaLoader: Couldn\'t find image with ID:', id); - return null; - } // effect - - - function parseEffect(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'profile_COMMON': - data.profile = parseEffectProfileCOMMON(child); - break; - } - } - - library.effects[xml.getAttribute('id')] = data; - } - - function parseEffectProfileCOMMON(xml) { - var data = { - surfaces: {}, - samplers: {} - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'newparam': - parseEffectNewparam(child, data); - break; - - case 'technique': - data.technique = parseEffectTechnique(child); - break; - - case 'extra': - data.extra = parseEffectExtra(child); - break; - } - } - - return data; - } - - function parseEffectNewparam(xml, data) { - var sid = xml.getAttribute('sid'); - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'surface': - data.surfaces[sid] = parseEffectSurface(child); - break; - - case 'sampler2D': - data.samplers[sid] = parseEffectSampler(child); - break; - } - } - } - - function parseEffectSurface(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'init_from': - data.init_from = child.textContent; - break; - } - } - - return data; - } - - function parseEffectSampler(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'source': - data.source = child.textContent; - break; - } - } - - return data; - } - - function parseEffectTechnique(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'constant': - case 'lambert': - case 'blinn': - case 'phong': - data.type = child.nodeName; - data.parameters = parseEffectParameters(child); - break; - } - } - - return data; - } - - function parseEffectParameters(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'emission': - case 'diffuse': - case 'specular': - case 'bump': - case 'ambient': - case 'shininess': - case 'transparency': - data[child.nodeName] = parseEffectParameter(child); - break; - - case 'transparent': - data[child.nodeName] = { - opaque: child.getAttribute('opaque'), - data: parseEffectParameter(child) - }; - break; - } - } - - return data; - } - - function parseEffectParameter(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'color': - data[child.nodeName] = parseFloats(child.textContent); - break; - - case 'float': - data[child.nodeName] = parseFloat(child.textContent); - break; - - case 'texture': - data[child.nodeName] = { - id: child.getAttribute('texture'), - extra: parseEffectParameterTexture(child) - }; - break; - } - } - - return data; - } - - function parseEffectParameterTexture(xml) { - var data = { - technique: {} - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'extra': - parseEffectParameterTextureExtra(child, data); - break; - } - } - - return data; - } - - function parseEffectParameterTextureExtra(xml, data) { - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'technique': - parseEffectParameterTextureExtraTechnique(child, data); - break; - } - } - } - - function parseEffectParameterTextureExtraTechnique(xml, data) { - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'repeatU': - case 'repeatV': - case 'offsetU': - case 'offsetV': - data.technique[child.nodeName] = parseFloat(child.textContent); - break; - - case 'wrapU': - case 'wrapV': - // some files have values for wrapU/wrapV which become NaN via parseInt - if (child.textContent.toUpperCase() === 'TRUE') { - data.technique[child.nodeName] = 1; - } else if (child.textContent.toUpperCase() === 'FALSE') { - data.technique[child.nodeName] = 0; - } else { - data.technique[child.nodeName] = parseInt(child.textContent); - } - - break; - } - } - } - - function parseEffectExtra(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'technique': - data.technique = parseEffectExtraTechnique(child); - break; - } - } - - return data; - } - - function parseEffectExtraTechnique(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'double_sided': - data[child.nodeName] = parseInt(child.textContent); - break; - } - } - - return data; - } - - function buildEffect(data) { - return data; - } - - function getEffect(id) { - return getBuild(library.effects[id], buildEffect); - } // material - - - function parseMaterial(xml) { - var data = { - name: xml.getAttribute('name') - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'instance_effect': - data.url = parseId(child.getAttribute('url')); - break; - } - } - - library.materials[xml.getAttribute('id')] = data; - } - - function getTextureLoader(image) { - var loader; - var extension = image.slice((image.lastIndexOf('.') - 1 >>> 0) + 2); // http://www.jstips.co/en/javascript/get-file-extension/ - - extension = extension.toLowerCase(); - - switch (extension) { - case 'tga': - loader = tgaLoader; - break; - - default: - loader = textureLoader; - } - - return loader; - } - - function buildMaterial(data) { - var effect = getEffect(data.url); - var technique = effect.profile.technique; - var extra = effect.profile.extra; - var material; - - switch (technique.type) { - case 'phong': - case 'blinn': - material = new THREE.MeshPhongMaterial(); - break; - - case 'lambert': - material = new THREE.MeshLambertMaterial(); - break; - - default: - material = new THREE.MeshBasicMaterial(); - break; - } - - material.name = data.name || ''; - - function getTexture(textureObject) { - var sampler = effect.profile.samplers[textureObject.id]; - var image = null; // get image - - if (sampler !== undefined) { - var surface = effect.profile.surfaces[sampler.source]; - image = getImage(surface.init_from); - } else { - console.warn('THREE.ColladaLoader: Undefined sampler. Access image directly (see #12530).'); - image = getImage(textureObject.id); - } // create texture if image is avaiable - - - if (image !== null) { - var loader = getTextureLoader(image); - - if (loader !== undefined) { - var texture = loader.load(image); - var extra = textureObject.extra; - - if (extra !== undefined && extra.technique !== undefined && isEmpty(extra.technique) === false) { - var technique = extra.technique; - texture.wrapS = technique.wrapU ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; - texture.wrapT = technique.wrapV ? THREE.RepeatWrapping : THREE.ClampToEdgeWrapping; - texture.offset.set(technique.offsetU || 0, technique.offsetV || 0); - texture.repeat.set(technique.repeatU || 1, technique.repeatV || 1); - } else { - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - } - - return texture; - } else { - console.warn('THREE.ColladaLoader: Loader for texture %s not found.', image); - return null; - } - } else { - console.warn('THREE.ColladaLoader: Couldn\'t create texture with ID:', textureObject.id); - return null; - } - } - - var parameters = technique.parameters; - - for (var key in parameters) { - var parameter = parameters[key]; - - switch (key) { - case 'diffuse': - if (parameter.color) material.color.fromArray(parameter.color); - if (parameter.texture) material.map = getTexture(parameter.texture); - break; - - case 'specular': - if (parameter.color && material.specular) material.specular.fromArray(parameter.color); - if (parameter.texture) material.specularMap = getTexture(parameter.texture); - break; - - case 'bump': - if (parameter.texture) material.normalMap = getTexture(parameter.texture); - break; - - case 'ambient': - if (parameter.texture) material.lightMap = getTexture(parameter.texture); - break; - - case 'shininess': - if (parameter.float && material.shininess) material.shininess = parameter.float; - break; - - case 'emission': - if (parameter.color && material.emissive) material.emissive.fromArray(parameter.color); - if (parameter.texture) material.emissiveMap = getTexture(parameter.texture); - break; - } - } // - - - var transparent = parameters['transparent']; - var transparency = parameters['transparency']; // does not exist but - - if (transparency === undefined && transparent) { - transparency = { - float: 1 - }; - } // does not exist but - - - if (transparent === undefined && transparency) { - transparent = { - opaque: 'A_ONE', - data: { - color: [1, 1, 1, 1] - } - }; - } - - if (transparent && transparency) { - // handle case if a texture exists but no color - if (transparent.data.texture) { - // we do not set an alpha map (see #13792) - material.transparent = true; - } else { - var color = transparent.data.color; - - switch (transparent.opaque) { - case 'A_ONE': - material.opacity = color[3] * transparency.float; - break; - - case 'RGB_ZERO': - material.opacity = 1 - color[0] * transparency.float; - break; - - case 'A_ZERO': - material.opacity = 1 - color[3] * transparency.float; - break; - - case 'RGB_ONE': - material.opacity = color[0] * transparency.float; - break; - - default: - console.warn('THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.', transparent.opaque); - } - - if (material.opacity < 1) material.transparent = true; - } - } // - - - if (extra !== undefined && extra.technique !== undefined && extra.technique.double_sided === 1) { - material.side = THREE.DoubleSide; - } - - return material; - } - - function getMaterial(id) { - return getBuild(library.materials[id], buildMaterial); - } // camera - - - function parseCamera(xml) { - var data = { - name: xml.getAttribute('name') - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'optics': - data.optics = parseCameraOptics(child); - break; - } - } - - library.cameras[xml.getAttribute('id')] = data; - } - - function parseCameraOptics(xml) { - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - - switch (child.nodeName) { - case 'technique_common': - return parseCameraTechnique(child); - } - } - - return {}; - } - - function parseCameraTechnique(xml) { - var data = {}; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - - switch (child.nodeName) { - case 'perspective': - case 'orthographic': - data.technique = child.nodeName; - data.parameters = parseCameraParameters(child); - break; - } - } - - return data; - } - - function parseCameraParameters(xml) { - var data = {}; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - - switch (child.nodeName) { - case 'xfov': - case 'yfov': - case 'xmag': - case 'ymag': - case 'znear': - case 'zfar': - case 'aspect_ratio': - data[child.nodeName] = parseFloat(child.textContent); - break; - } - } - - return data; - } - - function buildCamera(data) { - var camera; - - switch (data.optics.technique) { - case 'perspective': - camera = new THREE.PerspectiveCamera(data.optics.parameters.yfov, data.optics.parameters.aspect_ratio, data.optics.parameters.znear, data.optics.parameters.zfar); - break; - - case 'orthographic': - var ymag = data.optics.parameters.ymag; - var xmag = data.optics.parameters.xmag; - var aspectRatio = data.optics.parameters.aspect_ratio; - xmag = xmag === undefined ? ymag * aspectRatio : xmag; - ymag = ymag === undefined ? xmag / aspectRatio : ymag; - xmag *= 0.5; - ymag *= 0.5; - camera = new THREE.OrthographicCamera(-xmag, xmag, ymag, -ymag, // left, right, top, bottom - data.optics.parameters.znear, data.optics.parameters.zfar); - break; - - default: - camera = new THREE.PerspectiveCamera(); - break; - } - - camera.name = data.name || ''; - return camera; - } - - function getCamera(id) { - var data = library.cameras[id]; - - if (data !== undefined) { - return getBuild(data, buildCamera); - } - - console.warn('THREE.ColladaLoader: Couldn\'t find camera with ID:', id); - return null; - } // light - - - function parseLight(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'technique_common': - data = parseLightTechnique(child); - break; - } - } - - library.lights[xml.getAttribute('id')] = data; - } - - function parseLightTechnique(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'directional': - case 'point': - case 'spot': - case 'ambient': - data.technique = child.nodeName; - data.parameters = parseLightParameters(child); - } - } - - return data; - } - - function parseLightParameters(xml) { - var data = {}; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'color': - var array = parseFloats(child.textContent); - data.color = new THREE.Color().fromArray(array); - break; - - case 'falloff_angle': - data.falloffAngle = parseFloat(child.textContent); - break; - - case 'quadratic_attenuation': - var f = parseFloat(child.textContent); - data.distance = f ? Math.sqrt(1 / f) : 0; - break; - } - } - - return data; - } - - function buildLight(data) { - var light; - - switch (data.technique) { - case 'directional': - light = new THREE.DirectionalLight(); - break; - - case 'point': - light = new THREE.PointLight(); - break; - - case 'spot': - light = new THREE.SpotLight(); - break; - - case 'ambient': - light = new THREE.AmbientLight(); - break; - } - - if (data.parameters.color) light.color.copy(data.parameters.color); - if (data.parameters.distance) light.distance = data.parameters.distance; - return light; - } - - function getLight(id) { - var data = library.lights[id]; - - if (data !== undefined) { - return getBuild(data, buildLight); - } - - console.warn('THREE.ColladaLoader: Couldn\'t find light with ID:', id); - return null; - } // geometry - - - function parseGeometry(xml) { - var data = { - name: xml.getAttribute('name'), - sources: {}, - vertices: {}, - primitives: [] - }; - var mesh = getElementsByTagName(xml, 'mesh')[0]; // the following tags inside geometry are not supported yet (see https://github.com/mrdoob/three.js/pull/12606): convex_mesh, spline, brep - - if (mesh === undefined) return; - - for (var i = 0; i < mesh.childNodes.length; i++) { - var child = mesh.childNodes[i]; - if (child.nodeType !== 1) continue; - var id = child.getAttribute('id'); - - switch (child.nodeName) { - case 'source': - data.sources[id] = parseSource(child); - break; - - case 'vertices': - // data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ]; - data.vertices = parseGeometryVertices(child); - break; - - case 'polygons': - console.warn('THREE.ColladaLoader: Unsupported primitive type: ', child.nodeName); - break; - - case 'lines': - case 'linestrips': - case 'polylist': - case 'triangles': - data.primitives.push(parseGeometryPrimitive(child)); - break; - - default: - console.log(child); - } - } - - library.geometries[xml.getAttribute('id')] = data; - } - - function parseSource(xml) { - var data = { - array: [], - stride: 3 - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'float_array': - data.array = parseFloats(child.textContent); - break; - - case 'Name_array': - data.array = parseStrings(child.textContent); - break; - - case 'technique_common': - var accessor = getElementsByTagName(child, 'accessor')[0]; - - if (accessor !== undefined) { - data.stride = parseInt(accessor.getAttribute('stride')); - } - - break; - } - } - - return data; - } - - function parseGeometryVertices(xml) { - var data = {}; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - data[child.getAttribute('semantic')] = parseId(child.getAttribute('source')); - } - - return data; - } - - function parseGeometryPrimitive(xml) { - var primitive = { - type: xml.nodeName, - material: xml.getAttribute('material'), - count: parseInt(xml.getAttribute('count')), - inputs: {}, - stride: 0, - hasUV: false - }; - - for (var i = 0, l = xml.childNodes.length; i < l; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'input': - var id = parseId(child.getAttribute('source')); - var semantic = child.getAttribute('semantic'); - var offset = parseInt(child.getAttribute('offset')); - var set = parseInt(child.getAttribute('set')); - var inputname = set > 0 ? semantic + set : semantic; - primitive.inputs[inputname] = { - id: id, - offset: offset - }; - primitive.stride = Math.max(primitive.stride, offset + 1); - if (semantic === 'TEXCOORD') primitive.hasUV = true; - break; - - case 'vcount': - primitive.vcount = parseInts(child.textContent); - break; - - case 'p': - primitive.p = parseInts(child.textContent); - break; - } - } - - return primitive; - } - - function groupPrimitives(primitives) { - var build = {}; - - for (var i = 0; i < primitives.length; i++) { - var primitive = primitives[i]; - if (build[primitive.type] === undefined) build[primitive.type] = []; - build[primitive.type].push(primitive); - } - - return build; - } - - function checkUVCoordinates(primitives) { - var count = 0; - - for (var i = 0, l = primitives.length; i < l; i++) { - var primitive = primitives[i]; - - if (primitive.hasUV === true) { - count++; - } - } - - if (count > 0 && count < primitives.length) { - primitives.uvsNeedsFix = true; - } - } - - function buildGeometry(data) { - var build = {}; - var sources = data.sources; - var vertices = data.vertices; - var primitives = data.primitives; - if (primitives.length === 0) return {}; // our goal is to create one buffer geometry for a single type of primitives - // first, we group all primitives by their type - - var groupedPrimitives = groupPrimitives(primitives); - - for (var type in groupedPrimitives) { - var primitiveType = groupedPrimitives[type]; // second, ensure consistent uv coordinates for each type of primitives (polylist,triangles or lines) - - checkUVCoordinates(primitiveType); // third, create a buffer geometry for each type of primitives - - build[type] = buildGeometryType(primitiveType, sources, vertices); - } - - return build; - } - - function buildGeometryType(primitives, sources, vertices) { - var build = {}; - var position = { - array: [], - stride: 0 - }; - var normal = { - array: [], - stride: 0 - }; - var uv = { - array: [], - stride: 0 - }; - var uv2 = { - array: [], - stride: 0 - }; - var color = { - array: [], - stride: 0 - }; - var skinIndex = { - array: [], - stride: 4 - }; - var skinWeight = { - array: [], - stride: 4 - }; - var geometry = new THREE.BufferGeometry(); - var materialKeys = []; - var start = 0; - - for (var p = 0; p < primitives.length; p++) { - var primitive = primitives[p]; - var inputs = primitive.inputs; // groups - - var count = 0; - - switch (primitive.type) { - case 'lines': - case 'linestrips': - count = primitive.count * 2; - break; - - case 'triangles': - count = primitive.count * 3; - break; - - case 'polylist': - for (var g = 0; g < primitive.count; g++) { - var vc = primitive.vcount[g]; - - switch (vc) { - case 3: - count += 3; // single triangle - - break; - - case 4: - count += 6; // quad, subdivided into two triangles - - break; - - default: - count += (vc - 2) * 3; // polylist with more than four vertices - - break; - } - } - - break; - - default: - console.warn('THREE.ColladaLoader: Unknow primitive type:', primitive.type); - } - - geometry.addGroup(start, count, p); - start += count; // material - - if (primitive.material) { - materialKeys.push(primitive.material); - } // geometry data - - - for (var name in inputs) { - var input = inputs[name]; - - switch (name) { - case 'VERTEX': - for (var key in vertices) { - var id = vertices[key]; - - switch (key) { - case 'POSITION': - var prevLength = position.array.length; - buildGeometryData(primitive, sources[id], input.offset, position.array); - position.stride = sources[id].stride; - - if (sources.skinWeights && sources.skinIndices) { - buildGeometryData(primitive, sources.skinIndices, input.offset, skinIndex.array); - buildGeometryData(primitive, sources.skinWeights, input.offset, skinWeight.array); - } // see #3803 - - - if (primitive.hasUV === false && primitives.uvsNeedsFix === true) { - var count = (position.array.length - prevLength) / position.stride; - - for (var i = 0; i < count; i++) { - // fill missing uv coordinates - uv.array.push(0, 0); - } - } - - break; - - case 'NORMAL': - buildGeometryData(primitive, sources[id], input.offset, normal.array); - normal.stride = sources[id].stride; - break; - - case 'COLOR': - buildGeometryData(primitive, sources[id], input.offset, color.array); - color.stride = sources[id].stride; - break; - - case 'TEXCOORD': - buildGeometryData(primitive, sources[id], input.offset, uv.array); - uv.stride = sources[id].stride; - break; - - case 'TEXCOORD1': - buildGeometryData(primitive, sources[id], input.offset, uv2.array); - uv.stride = sources[id].stride; - break; - - default: - console.warn('THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key); - } - } - - break; - - case 'NORMAL': - buildGeometryData(primitive, sources[input.id], input.offset, normal.array); - normal.stride = sources[input.id].stride; - break; - - case 'COLOR': - buildGeometryData(primitive, sources[input.id], input.offset, color.array); - color.stride = sources[input.id].stride; - break; - - case 'TEXCOORD': - buildGeometryData(primitive, sources[input.id], input.offset, uv.array); - uv.stride = sources[input.id].stride; - break; - - case 'TEXCOORD1': - buildGeometryData(primitive, sources[input.id], input.offset, uv2.array); - uv2.stride = sources[input.id].stride; - break; - } - } - } // build geometry - - - if (position.array.length > 0) geometry.setAttribute('position', new THREE.Float32BufferAttribute(position.array, position.stride)); - if (normal.array.length > 0) geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normal.array, normal.stride)); - if (color.array.length > 0) geometry.setAttribute('color', new THREE.Float32BufferAttribute(color.array, color.stride)); - if (uv.array.length > 0) geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uv.array, uv.stride)); - if (uv2.array.length > 0) geometry.setAttribute('uv2', new THREE.Float32BufferAttribute(uv2.array, uv2.stride)); - if (skinIndex.array.length > 0) geometry.setAttribute('skinIndex', new THREE.Float32BufferAttribute(skinIndex.array, skinIndex.stride)); - if (skinWeight.array.length > 0) geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeight.array, skinWeight.stride)); - build.data = geometry; - build.type = primitives[0].type; - build.materialKeys = materialKeys; - return build; - } - - function buildGeometryData(primitive, source, offset, array) { - var indices = primitive.p; - var stride = primitive.stride; - var vcount = primitive.vcount; - - function pushVector(i) { - var index = indices[i + offset] * sourceStride; - var length = index + sourceStride; - - for (; index < length; index++) { - array.push(sourceArray[index]); - } - } - - var sourceArray = source.array; - var sourceStride = source.stride; - - if (primitive.vcount !== undefined) { - var index = 0; - - for (var i = 0, l = vcount.length; i < l; i++) { - var count = vcount[i]; - - if (count === 4) { - var a = index + stride * 0; - var b = index + stride * 1; - var c = index + stride * 2; - var d = index + stride * 3; - pushVector(a); - pushVector(b); - pushVector(d); - pushVector(b); - pushVector(c); - pushVector(d); - } else if (count === 3) { - var a = index + stride * 0; - var b = index + stride * 1; - var c = index + stride * 2; - pushVector(a); - pushVector(b); - pushVector(c); - } else if (count > 4) { - for (var k = 1, kl = count - 2; k <= kl; k++) { - var a = index + stride * 0; - var b = index + stride * k; - var c = index + stride * (k + 1); - pushVector(a); - pushVector(b); - pushVector(c); - } - } - - index += stride * count; - } - } else { - for (var i = 0, l = indices.length; i < l; i += stride) { - pushVector(i); - } - } - } - - function getGeometry(id) { - return getBuild(library.geometries[id], buildGeometry); - } // kinematics - - - function parseKinematicsModel(xml) { - var data = { - name: xml.getAttribute('name') || '', - joints: {}, - links: [] - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'technique_common': - parseKinematicsTechniqueCommon(child, data); - break; - } - } - - library.kinematicsModels[xml.getAttribute('id')] = data; - } - - function buildKinematicsModel(data) { - if (data.build !== undefined) return data.build; - return data; - } - - function getKinematicsModel(id) { - return getBuild(library.kinematicsModels[id], buildKinematicsModel); - } - - function parseKinematicsTechniqueCommon(xml, data) { - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'joint': - data.joints[child.getAttribute('sid')] = parseKinematicsJoint(child); - break; - - case 'link': - data.links.push(parseKinematicsLink(child)); - break; - } - } - } - - function parseKinematicsJoint(xml) { - var data; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'prismatic': - case 'revolute': - data = parseKinematicsJointParameter(child); - break; - } - } - - return data; - } - - function parseKinematicsJointParameter(xml, data) { - var data = { - sid: xml.getAttribute('sid'), - name: xml.getAttribute('name') || '', - axis: new THREE.Vector3(), - limits: { - min: 0, - max: 0 - }, - type: xml.nodeName, - static: false, - zeroPosition: 0, - middlePosition: 0 - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'axis': - var array = parseFloats(child.textContent); - data.axis.fromArray(array); - break; - - case 'limits': - var max = child.getElementsByTagName('max')[0]; - var min = child.getElementsByTagName('min')[0]; - data.limits.max = parseFloat(max.textContent); - data.limits.min = parseFloat(min.textContent); - break; - } - } // if min is equal to or greater than max, consider the joint static - - - if (data.limits.min >= data.limits.max) { - data.static = true; - } // calculate middle position - - - data.middlePosition = (data.limits.min + data.limits.max) / 2.0; - return data; - } - - function parseKinematicsLink(xml) { - var data = { - sid: xml.getAttribute('sid'), - name: xml.getAttribute('name') || '', - attachments: [], - transforms: [] - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'attachment_full': - data.attachments.push(parseKinematicsAttachment(child)); - break; - - case 'matrix': - case 'translate': - case 'rotate': - data.transforms.push(parseKinematicsTransform(child)); - break; - } - } - - return data; - } - - function parseKinematicsAttachment(xml) { - var data = { - joint: xml.getAttribute('joint').split('/').pop(), - transforms: [], - links: [] - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'link': - data.links.push(parseKinematicsLink(child)); - break; - - case 'matrix': - case 'translate': - case 'rotate': - data.transforms.push(parseKinematicsTransform(child)); - break; - } - } - - return data; - } - - function parseKinematicsTransform(xml) { - var data = { - type: xml.nodeName - }; - var array = parseFloats(xml.textContent); - - switch (data.type) { - case 'matrix': - data.obj = new THREE.Matrix4(); - data.obj.fromArray(array).transpose(); - break; - - case 'translate': - data.obj = new THREE.Vector3(); - data.obj.fromArray(array); - break; - - case 'rotate': - data.obj = new THREE.Vector3(); - data.obj.fromArray(array); - data.angle = THREE.MathUtils.degToRad(array[3]); - break; - } - - return data; - } // physics - - - function parsePhysicsModel(xml) { - var data = { - name: xml.getAttribute('name') || '', - rigidBodies: {} - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'rigid_body': - data.rigidBodies[child.getAttribute('name')] = {}; - parsePhysicsRigidBody(child, data.rigidBodies[child.getAttribute('name')]); - break; - } - } - - library.physicsModels[xml.getAttribute('id')] = data; - } - - function parsePhysicsRigidBody(xml, data) { - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'technique_common': - parsePhysicsTechniqueCommon(child, data); - break; - } - } - } - - function parsePhysicsTechniqueCommon(xml, data) { - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'inertia': - data.inertia = parseFloats(child.textContent); - break; - - case 'mass': - data.mass = parseFloats(child.textContent)[0]; - break; - } - } - } // scene - - - function parseKinematicsScene(xml) { - var data = { - bindJointAxis: [] - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'bind_joint_axis': - data.bindJointAxis.push(parseKinematicsBindJointAxis(child)); - break; - } - } - - library.kinematicsScenes[parseId(xml.getAttribute('url'))] = data; - } - - function parseKinematicsBindJointAxis(xml) { - var data = { - target: xml.getAttribute('target').split('/').pop() - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'axis': - var param = child.getElementsByTagName('param')[0]; - data.axis = param.textContent; - var tmpJointIndex = data.axis.split('inst_').pop().split('axis')[0]; - data.jointIndex = tmpJointIndex.substr(0, tmpJointIndex.length - 1); - break; - } - } - - return data; - } - - function buildKinematicsScene(data) { - if (data.build !== undefined) return data.build; - return data; - } - - function getKinematicsScene(id) { - return getBuild(library.kinematicsScenes[id], buildKinematicsScene); - } - - function setupKinematics() { - var kinematicsModelId = Object.keys(library.kinematicsModels)[0]; - var kinematicsSceneId = Object.keys(library.kinematicsScenes)[0]; - var visualSceneId = Object.keys(library.visualScenes)[0]; - if (kinematicsModelId === undefined || kinematicsSceneId === undefined) return; - var kinematicsModel = getKinematicsModel(kinematicsModelId); - var kinematicsScene = getKinematicsScene(kinematicsSceneId); - var visualScene = getVisualScene(visualSceneId); - var bindJointAxis = kinematicsScene.bindJointAxis; - var jointMap = {}; - - for (var i = 0, l = bindJointAxis.length; i < l; i++) { - var axis = bindJointAxis[i]; // the result of the following query is an element of type 'translate', 'rotate','scale' or 'matrix' - - var targetElement = collada.querySelector('[sid="' + axis.target + '"]'); - - if (targetElement) { - // get the parent of the transform element - var parentVisualElement = targetElement.parentElement; // connect the joint of the kinematics model with the element in the visual scene - - connect(axis.jointIndex, parentVisualElement); - } - } - - function connect(jointIndex, visualElement) { - var visualElementName = visualElement.getAttribute('name'); - var joint = kinematicsModel.joints[jointIndex]; - visualScene.traverse(function (object) { - if (object.name === visualElementName) { - jointMap[jointIndex] = { - object: object, - transforms: buildTransformList(visualElement), - joint: joint, - position: joint.zeroPosition - }; - } - }); - } - - var m0 = new THREE.Matrix4(); - kinematics = { - joints: kinematicsModel && kinematicsModel.joints, - getJointValue: function (jointIndex) { - var jointData = jointMap[jointIndex]; - - if (jointData) { - return jointData.position; - } else { - console.warn('THREE.ColladaLoader: Joint ' + jointIndex + ' doesn\'t exist.'); - } - }, - setJointValue: function (jointIndex, value) { - var jointData = jointMap[jointIndex]; - - if (jointData) { - var joint = jointData.joint; - - if (value > joint.limits.max || value < joint.limits.min) { - console.warn('THREE.ColladaLoader: Joint ' + jointIndex + ' value ' + value + ' outside of limits (min: ' + joint.limits.min + ', max: ' + joint.limits.max + ').'); - } else if (joint.static) { - console.warn('THREE.ColladaLoader: Joint ' + jointIndex + ' is static.'); - } else { - var object = jointData.object; - var axis = joint.axis; - var transforms = jointData.transforms; - matrix.identity(); // each update, we have to apply all transforms in the correct order - - for (var i = 0; i < transforms.length; i++) { - var transform = transforms[i]; // if there is a connection of the transform node with a joint, apply the joint value - - if (transform.sid && transform.sid.indexOf(jointIndex) !== -1) { - switch (joint.type) { - case 'revolute': - matrix.multiply(m0.makeRotationAxis(axis, THREE.MathUtils.degToRad(value))); - break; - - case 'prismatic': - matrix.multiply(m0.makeTranslation(axis.x * value, axis.y * value, axis.z * value)); - break; - - default: - console.warn('THREE.ColladaLoader: Unknown joint type: ' + joint.type); - break; - } - } else { - switch (transform.type) { - case 'matrix': - matrix.multiply(transform.obj); - break; - - case 'translate': - matrix.multiply(m0.makeTranslation(transform.obj.x, transform.obj.y, transform.obj.z)); - break; - - case 'scale': - matrix.scale(transform.obj); - break; - - case 'rotate': - matrix.multiply(m0.makeRotationAxis(transform.obj, transform.angle)); - break; - } - } - } - - object.matrix.copy(matrix); - object.matrix.decompose(object.position, object.quaternion, object.scale); - jointMap[jointIndex].position = value; - } - } else { - console.log('THREE.ColladaLoader: ' + jointIndex + ' does not exist.'); - } - } - }; - } - - function buildTransformList(node) { - var transforms = []; - var xml = collada.querySelector('[id="' + node.id + '"]'); - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'matrix': - var array = parseFloats(child.textContent); - var matrix = new THREE.Matrix4().fromArray(array).transpose(); - transforms.push({ - sid: child.getAttribute('sid'), - type: child.nodeName, - obj: matrix - }); - break; - - case 'translate': - case 'scale': - var array = parseFloats(child.textContent); - var vector = new THREE.Vector3().fromArray(array); - transforms.push({ - sid: child.getAttribute('sid'), - type: child.nodeName, - obj: vector - }); - break; - - case 'rotate': - var array = parseFloats(child.textContent); - var vector = new THREE.Vector3().fromArray(array); - var angle = THREE.MathUtils.degToRad(array[3]); - transforms.push({ - sid: child.getAttribute('sid'), - type: child.nodeName, - obj: vector, - angle: angle - }); - break; - } - } - - return transforms; - } // nodes - - - function prepareNodes(xml) { - var elements = xml.getElementsByTagName('node'); // ensure all node elements have id attributes - - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - - if (element.hasAttribute('id') === false) { - element.setAttribute('id', generateId()); - } - } - } - - var matrix = new THREE.Matrix4(); - var vector = new THREE.Vector3(); - - function parseNode(xml) { - var data = { - name: xml.getAttribute('name') || '', - type: xml.getAttribute('type'), - id: xml.getAttribute('id'), - sid: xml.getAttribute('sid'), - matrix: new THREE.Matrix4(), - nodes: [], - instanceCameras: [], - instanceControllers: [], - instanceLights: [], - instanceGeometries: [], - instanceNodes: [], - transforms: {} - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - if (child.nodeType !== 1) continue; - - switch (child.nodeName) { - case 'node': - data.nodes.push(child.getAttribute('id')); - parseNode(child); - break; - - case 'instance_camera': - data.instanceCameras.push(parseId(child.getAttribute('url'))); - break; - - case 'instance_controller': - data.instanceControllers.push(parseNodeInstance(child)); - break; - - case 'instance_light': - data.instanceLights.push(parseId(child.getAttribute('url'))); - break; - - case 'instance_geometry': - data.instanceGeometries.push(parseNodeInstance(child)); - break; - - case 'instance_node': - data.instanceNodes.push(parseId(child.getAttribute('url'))); - break; - - case 'matrix': - var array = parseFloats(child.textContent); - data.matrix.multiply(matrix.fromArray(array).transpose()); - data.transforms[child.getAttribute('sid')] = child.nodeName; - break; - - case 'translate': - var array = parseFloats(child.textContent); - vector.fromArray(array); - data.matrix.multiply(matrix.makeTranslation(vector.x, vector.y, vector.z)); - data.transforms[child.getAttribute('sid')] = child.nodeName; - break; - - case 'rotate': - var array = parseFloats(child.textContent); - var angle = THREE.MathUtils.degToRad(array[3]); - data.matrix.multiply(matrix.makeRotationAxis(vector.fromArray(array), angle)); - data.transforms[child.getAttribute('sid')] = child.nodeName; - break; - - case 'scale': - var array = parseFloats(child.textContent); - data.matrix.scale(vector.fromArray(array)); - data.transforms[child.getAttribute('sid')] = child.nodeName; - break; - - case 'extra': - break; - - default: - console.log(child); - } - } - - if (hasNode(data.id)) { - console.warn('THREE.ColladaLoader: There is already a node with ID %s. Exclude current node from further processing.', data.id); - } else { - library.nodes[data.id] = data; - } - - return data; - } - - function parseNodeInstance(xml) { - var data = { - id: parseId(xml.getAttribute('url')), - materials: {}, - skeletons: [] - }; - - for (var i = 0; i < xml.childNodes.length; i++) { - var child = xml.childNodes[i]; - - switch (child.nodeName) { - case 'bind_material': - var instances = child.getElementsByTagName('instance_material'); - - for (var j = 0; j < instances.length; j++) { - var instance = instances[j]; - var symbol = instance.getAttribute('symbol'); - var target = instance.getAttribute('target'); - data.materials[symbol] = parseId(target); - } - - break; - - case 'skeleton': - data.skeletons.push(parseId(child.textContent)); - break; - - default: - break; - } - } - - return data; - } - - function buildSkeleton(skeletons, joints) { - var boneData = []; - var sortedBoneData = []; - var i, j, data; // a skeleton can have multiple root bones. collada expresses this - // situtation with multiple "skeleton" tags per controller instance - - for (i = 0; i < skeletons.length; i++) { - var skeleton = skeletons[i]; - var root; - - if (hasNode(skeleton)) { - root = getNode(skeleton); - buildBoneHierarchy(root, joints, boneData); - } else if (hasVisualScene(skeleton)) { - // handle case where the skeleton refers to the visual scene (#13335) - var visualScene = library.visualScenes[skeleton]; - var children = visualScene.children; - - for (var j = 0; j < children.length; j++) { - var child = children[j]; - - if (child.type === 'JOINT') { - var root = getNode(child.id); - buildBoneHierarchy(root, joints, boneData); - } - } - } else { - console.error('THREE.ColladaLoader: Unable to find root bone of skeleton with ID:', skeleton); - } - } // sort bone data (the order is defined in the corresponding controller) - - - for (i = 0; i < joints.length; i++) { - for (j = 0; j < boneData.length; j++) { - data = boneData[j]; - - if (data.bone.name === joints[i].name) { - sortedBoneData[i] = data; - data.processed = true; - break; - } - } - } // add unprocessed bone data at the end of the list - - - for (i = 0; i < boneData.length; i++) { - data = boneData[i]; - - if (data.processed === false) { - sortedBoneData.push(data); - data.processed = true; - } - } // setup arrays for skeleton creation - - - var bones = []; - var boneInverses = []; - - for (i = 0; i < sortedBoneData.length; i++) { - data = sortedBoneData[i]; - bones.push(data.bone); - boneInverses.push(data.boneInverse); - } - - return new THREE.Skeleton(bones, boneInverses); - } - - function buildBoneHierarchy(root, joints, boneData) { - // setup bone data from visual scene - root.traverse(function (object) { - if (object.isBone === true) { - var boneInverse; // retrieve the boneInverse from the controller data - - for (var i = 0; i < joints.length; i++) { - var joint = joints[i]; - - if (joint.name === object.name) { - boneInverse = joint.boneInverse; - break; - } - } - - if (boneInverse === undefined) { - // Unfortunately, there can be joints in the visual scene that are not part of the - // corresponding controller. In this case, we have to create a dummy boneInverse matrix - // for the respective bone. This bone won't affect any vertices, because there are no skin indices - // and weights defined for it. But we still have to add the bone to the sorted bone list in order to - // ensure a correct animation of the model. - boneInverse = new THREE.Matrix4(); - } - - boneData.push({ - bone: object, - boneInverse: boneInverse, - processed: false - }); - } - }); - } - - function buildNode(data) { - var objects = []; - var matrix = data.matrix; - var nodes = data.nodes; - var type = data.type; - var instanceCameras = data.instanceCameras; - var instanceControllers = data.instanceControllers; - var instanceLights = data.instanceLights; - var instanceGeometries = data.instanceGeometries; - var instanceNodes = data.instanceNodes; // nodes - - for (var i = 0, l = nodes.length; i < l; i++) { - objects.push(getNode(nodes[i])); - } // instance cameras - - - for (var i = 0, l = instanceCameras.length; i < l; i++) { - var instanceCamera = getCamera(instanceCameras[i]); - - if (instanceCamera !== null) { - objects.push(instanceCamera.clone()); - } - } // instance controllers - - - for (var i = 0, l = instanceControllers.length; i < l; i++) { - var instance = instanceControllers[i]; - var controller = getController(instance.id); - var geometries = getGeometry(controller.id); - var newObjects = buildObjects(geometries, instance.materials); - var skeletons = instance.skeletons; - var joints = controller.skin.joints; - var skeleton = buildSkeleton(skeletons, joints); - - for (var j = 0, jl = newObjects.length; j < jl; j++) { - var object = newObjects[j]; - - if (object.isSkinnedMesh) { - object.bind(skeleton, controller.skin.bindMatrix); - object.normalizeSkinWeights(); - } - - objects.push(object); - } - } // instance lights - - - for (var i = 0, l = instanceLights.length; i < l; i++) { - var instanceLight = getLight(instanceLights[i]); - - if (instanceLight !== null) { - objects.push(instanceLight.clone()); - } - } // instance geometries - - - for (var i = 0, l = instanceGeometries.length; i < l; i++) { - var instance = instanceGeometries[i]; // a single geometry instance in collada can lead to multiple object3Ds. - // this is the case when primitives are combined like triangles and lines - - var geometries = getGeometry(instance.id); - var newObjects = buildObjects(geometries, instance.materials); - - for (var j = 0, jl = newObjects.length; j < jl; j++) { - objects.push(newObjects[j]); - } - } // instance nodes - - - for (var i = 0, l = instanceNodes.length; i < l; i++) { - objects.push(getNode(instanceNodes[i]).clone()); - } - - var object; - - if (nodes.length === 0 && objects.length === 1) { - object = objects[0]; - } else { - object = type === 'JOINT' ? new THREE.Bone() : new THREE.Group(); - - for (var i = 0; i < objects.length; i++) { - object.add(objects[i]); - } - } - - object.name = type === 'JOINT' ? data.sid : data.name; - object.matrix.copy(matrix); - object.matrix.decompose(object.position, object.quaternion, object.scale); - return object; - } - - var fallbackMaterial = new THREE.MeshBasicMaterial({ - color: 0xff00ff - }); - - function resolveMaterialBinding(keys, instanceMaterials) { - var materials = []; - - for (var i = 0, l = keys.length; i < l; i++) { - var id = instanceMaterials[keys[i]]; - - if (id === undefined) { - console.warn('THREE.ColladaLoader: Material with key %s not found. Apply fallback material.', keys[i]); - materials.push(fallbackMaterial); - } else { - materials.push(getMaterial(id)); - } - } - - return materials; - } - - function buildObjects(geometries, instanceMaterials) { - var objects = []; - - for (var type in geometries) { - var geometry = geometries[type]; - var materials = resolveMaterialBinding(geometry.materialKeys, instanceMaterials); // handle case if no materials are defined - - if (materials.length === 0) { - if (type === 'lines' || type === 'linestrips') { - materials.push(new THREE.LineBasicMaterial()); - } else { - materials.push(new THREE.MeshPhongMaterial()); - } - } // regard skinning - - - var skinning = geometry.data.attributes.skinIndex !== undefined; - - if (skinning) { - for (var i = 0, l = materials.length; i < l; i++) { - materials[i].skinning = true; - } - } // choose between a single or multi materials (material array) - - - var material = materials.length === 1 ? materials[0] : materials; // now create a specific 3D object - - var object; - - switch (type) { - case 'lines': - object = new THREE.LineSegments(geometry.data, material); - break; - - case 'linestrips': - object = new THREE.Line(geometry.data, material); - break; - - case 'triangles': - case 'polylist': - if (skinning) { - object = new THREE.SkinnedMesh(geometry.data, material); - } else { - object = new THREE.Mesh(geometry.data, material); - } - - break; - } - - objects.push(object); - } - - return objects; - } - - function hasNode(id) { - return library.nodes[id] !== undefined; - } - - function getNode(id) { - return getBuild(library.nodes[id], buildNode); - } // visual scenes - - - function parseVisualScene(xml) { - var data = { - name: xml.getAttribute('name'), - children: [] - }; - prepareNodes(xml); - var elements = getElementsByTagName(xml, 'node'); - - for (var i = 0; i < elements.length; i++) { - data.children.push(parseNode(elements[i])); - } - - library.visualScenes[xml.getAttribute('id')] = data; - } - - function buildVisualScene(data) { - var group = new THREE.Group(); - group.name = data.name; - var children = data.children; - - for (var i = 0; i < children.length; i++) { - var child = children[i]; - group.add(getNode(child.id)); - } - - return group; - } - - function hasVisualScene(id) { - return library.visualScenes[id] !== undefined; - } - - function getVisualScene(id) { - return getBuild(library.visualScenes[id], buildVisualScene); - } // scenes - - - function parseScene(xml) { - var instance = getElementsByTagName(xml, 'instance_visual_scene')[0]; - return getVisualScene(parseId(instance.getAttribute('url'))); - } - - function setupAnimations() { - var clips = library.clips; - - if (isEmpty(clips) === true) { - if (isEmpty(library.animations) === false) { - // if there are animations but no clips, we create a default clip for playback - var tracks = []; - - for (var id in library.animations) { - var animationTracks = getAnimation(id); - - for (var i = 0, l = animationTracks.length; i < l; i++) { - tracks.push(animationTracks[i]); - } - } - - animations.push(new THREE.AnimationClip('default', -1, tracks)); - } - } else { - for (var id in clips) { - animations.push(getAnimationClip(id)); - } - } - } // convert the parser error element into text with each child elements text - // separated by new lines. - - - function parserErrorToText(parserError) { - var result = ''; - var stack = [parserError]; - - while (stack.length) { - var node = stack.shift(); - - if (node.nodeType === Node.TEXT_NODE) { - result += node.textContent; - } else { - result += '\n'; - stack.push.apply(stack, node.childNodes); - } - } - - return result.trim(); - } - - if (text.length === 0) { - return { - scene: new THREE.Scene() - }; - } - - var xml = new DOMParser().parseFromString(text, 'application/xml'); - var collada = getElementsByTagName(xml, 'COLLADA')[0]; - var parserError = xml.getElementsByTagName('parsererror')[0]; - - if (parserError !== undefined) { - // Chrome will return parser error with a div in it - var errorElement = getElementsByTagName(parserError, 'div')[0]; - var errorText; - - if (errorElement) { - errorText = errorElement.textContent; - } else { - errorText = parserErrorToText(parserError); - } - - console.error('THREE.ColladaLoader: Failed to parse collada file.\n', errorText); - return null; - } // metadata - - - var version = collada.getAttribute('version'); - console.log('THREE.ColladaLoader: File version', version); - var asset = parseAsset(getElementsByTagName(collada, 'asset')[0]); - var textureLoader = new THREE.TextureLoader(this.manager); - textureLoader.setPath(this.resourcePath || path).setCrossOrigin(this.crossOrigin); - var tgaLoader; - - if (THREE.TGALoader) { - tgaLoader = new THREE.TGALoader(this.manager); - tgaLoader.setPath(this.resourcePath || path); - } // - - - var animations = []; - var kinematics = {}; - var count = 0; // - - var library = { - animations: {}, - clips: {}, - controllers: {}, - images: {}, - effects: {}, - materials: {}, - cameras: {}, - lights: {}, - geometries: {}, - nodes: {}, - visualScenes: {}, - kinematicsModels: {}, - physicsModels: {}, - kinematicsScenes: {} - }; - parseLibrary(collada, 'library_animations', 'animation', parseAnimation); - parseLibrary(collada, 'library_animation_clips', 'animation_clip', parseAnimationClip); - parseLibrary(collada, 'library_controllers', 'controller', parseController); - parseLibrary(collada, 'library_images', 'image', parseImage); - parseLibrary(collada, 'library_effects', 'effect', parseEffect); - parseLibrary(collada, 'library_materials', 'material', parseMaterial); - parseLibrary(collada, 'library_cameras', 'camera', parseCamera); - parseLibrary(collada, 'library_lights', 'light', parseLight); - parseLibrary(collada, 'library_geometries', 'geometry', parseGeometry); - parseLibrary(collada, 'library_nodes', 'node', parseNode); - parseLibrary(collada, 'library_visual_scenes', 'visual_scene', parseVisualScene); - parseLibrary(collada, 'library_kinematics_models', 'kinematics_model', parseKinematicsModel); - parseLibrary(collada, 'library_physics_models', 'physics_model', parsePhysicsModel); - parseLibrary(collada, 'scene', 'instance_kinematics_scene', parseKinematicsScene); - buildLibrary(library.animations, buildAnimation); - buildLibrary(library.clips, buildAnimationClip); - buildLibrary(library.controllers, buildController); - buildLibrary(library.images, buildImage); - buildLibrary(library.effects, buildEffect); - buildLibrary(library.materials, buildMaterial); - buildLibrary(library.cameras, buildCamera); - buildLibrary(library.lights, buildLight); - buildLibrary(library.geometries, buildGeometry); - buildLibrary(library.visualScenes, buildVisualScene); - setupAnimations(); - setupKinematics(); - var scene = parseScene(getElementsByTagName(collada, 'scene')[0]); - scene.animations = animations; - - if (asset.upAxis === 'Z_UP') { - scene.quaternion.setFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0)); - } - - scene.scale.multiplyScalar(asset.unit); - return { - get animations() { - console.warn('THREE.ColladaLoader: Please access animations over scene.animations now.'); - return animations; - }, - - kinematics: kinematics, - library: library, - scene: scene - }; - } -}); -var _default = THREE.ColladaLoader; -exports.default = _default; - -},{}]},{},[1]); +(()=>{"use strict";const e=THREE;class t extends e.DataTextureLoader{constructor(e){super(e)}parse(t){t.length<19&&console.error("THREE.TGALoader: Not enough data to contain header.");let n=0;const o=new Uint8Array(t),s={id_length:o[n++],colormap_type:o[n++],image_type:o[n++],colormap_index:o[n++]|o[n++]<<8,colormap_length:o[n++]|o[n++]<<8,colormap_size:o[n++],origin:[o[n++]|o[n++]<<8,o[n++]|o[n++]<<8],width:o[n++]|o[n++]<<8,height:o[n++]|o[n++]<<8,pixel_size:o[n++],flags:o[n++]};!function(e){switch(e.image_type){case 1:case 9:(e.colormap_length>256||24!==e.colormap_size||1!==e.colormap_type)&&console.error("THREE.TGALoader: Invalid type colormap data for indexed type.");break;case 2:case 3:case 10:case 11:e.colormap_type&&console.error("THREE.TGALoader: Invalid type colormap data for colormap type.");break;case 0:console.error("THREE.TGALoader: No data.");default:console.error('THREE.TGALoader: Invalid type "%s".',e.image_type)}(e.width<=0||e.height<=0)&&console.error("THREE.TGALoader: Invalid image size."),8!==e.pixel_size&&16!==e.pixel_size&&24!==e.pixel_size&&32!==e.pixel_size&&console.error('THREE.TGALoader: Invalid pixel size "%s".',e.pixel_size)}(s),s.id_length+n>t.length&&console.error("THREE.TGALoader: No data."),n+=s.id_length;let r=!1,i=!1,a=!1;switch(s.image_type){case 9:r=!0,i=!0;break;case 1:i=!0;break;case 10:r=!0;break;case 2:break;case 11:r=!0,a=!0;break;case 3:a=!0}const c=new Uint8Array(s.width*s.height*4),l=function(e,t,n,o,s){let r,i;const a=n.pixel_size>>3,c=n.width*n.height*a;if(t&&(i=s.subarray(o,o+=n.colormap_length*(n.colormap_size>>3))),e){let e,t,n;r=new Uint8Array(c);let i=0;const l=new Uint8Array(a);for(;i>4){default:case 2:i=0,l=1,u=t,c=0,d=1,f=n;break;case 0:i=0,l=1,u=t,c=n-1,d=-1,f=-1;break;case 3:i=t-1,l=-1,u=-1,c=0,d=1,f=n;break;case 1:i=t-1,l=-1,u=-1,c=n-1,d=-1,f=-1}if(a)switch(s.pixel_size){case 8:!function(e,t,n,o,r,i,a,c){let l,d,u,f=0;const h=s.width;for(u=t;u!==o;u+=n)for(d=r;d!==a;d+=i,f++)l=c[f],e[4*(d+h*u)+0]=l,e[4*(d+h*u)+1]=l,e[4*(d+h*u)+2]=l,e[4*(d+h*u)+3]=255}(e,c,d,f,i,l,u,o);break;case 16:!function(e,t,n,o,r,i,a,c){let l,d,u=0;const f=s.width;for(d=t;d!==o;d+=n)for(l=r;l!==a;l+=i,u+=2)e[4*(l+f*d)+0]=c[u+0],e[4*(l+f*d)+1]=c[u+0],e[4*(l+f*d)+2]=c[u+0],e[4*(l+f*d)+3]=c[u+1]}(e,c,d,f,i,l,u,o);break;default:console.error("THREE.TGALoader: Format not supported.")}else switch(s.pixel_size){case 8:!function(e,t,n,o,r,i,a,c,l){const d=l;let u,f,h,m=0;const p=s.width;for(h=t;h!==o;h+=n)for(f=r;f!==a;f+=i,m++)u=c[m],e[4*(f+p*h)+3]=255,e[4*(f+p*h)+2]=d[3*u+0],e[4*(f+p*h)+1]=d[3*u+1],e[4*(f+p*h)+0]=d[3*u+2]}(e,c,d,f,i,l,u,o,r);break;case 16:!function(e,t,n,o,r,i,a,c){let l,d,u,f=0;const h=s.width;for(u=t;u!==o;u+=n)for(d=r;d!==a;d+=i,f+=2)l=c[f+0]+(c[f+1]<<8),e[4*(d+h*u)+0]=(31744&l)>>7,e[4*(d+h*u)+1]=(992&l)>>2,e[4*(d+h*u)+2]=(31&l)<<3,e[4*(d+h*u)+3]=32768&l?0:255}(e,c,d,f,i,l,u,o);break;case 24:!function(e,t,n,o,r,i,a,c){let l,d,u=0;const f=s.width;for(d=t;d!==o;d+=n)for(l=r;l!==a;l+=i,u+=3)e[4*(l+f*d)+3]=255,e[4*(l+f*d)+2]=c[u+0],e[4*(l+f*d)+1]=c[u+1],e[4*(l+f*d)+0]=c[u+2]}(e,c,d,f,i,l,u,o);break;case 32:!function(e,t,n,o,r,i,a,c){let l,d,u=0;const f=s.width;for(d=t;d!==o;d+=n)for(l=r;l!==a;l+=i,u+=4)e[4*(l+f*d)+2]=c[u+0],e[4*(l+f*d)+1]=c[u+1],e[4*(l+f*d)+0]=c[u+2],e[4*(l+f*d)+3]=c[u+3]}(e,c,d,f,i,l,u,o);break;default:console.error("THREE.TGALoader: Format not supported.")}}(c,s.width,s.height,l.pixel_data,l.palettes),{data:c,width:s.width,height:s.height,flipY:!0,generateMipmaps:!0,minFilter:e.LinearMipmapLinearFilter}}}class n extends e.Loader{constructor(e){super(e)}load(t,n,o,s){const r=this,i=""===r.path?e.LoaderUtils.extractUrlBase(t):r.path,a=new e.FileLoader(r.manager);a.setPath(r.path),a.setRequestHeader(r.requestHeader),a.setWithCredentials(r.withCredentials),a.load(t,(function(e){try{n(r.parse(e,i))}catch(e){s?s(e):console.error(e),r.manager.itemError(t)}}),o,s)}parse(n,o){function s(e,t){const n=[],o=e.childNodes;for(let e=0,s=o.length;e0&&n.push(new e.VectorKeyframeTrack(s+".position",r,i)),a.length>0&&n.push(new e.QuaternionKeyframeTrack(s+".quaternion",r,a)),c.length>0&&n.push(new e.VectorKeyframeTrack(s+".scale",r,c)),n}function v(e,t,n){let o,s,r,i=!0;for(s=0,r=e.length;s=0;){const o=e[t];if(null!==o.value[n])return o;t--}return null}function C(e,t,n){for(;t>>0));return n=n.toLowerCase(),t="tga"===n?Je:We,t}(r);if(void 0!==n){const s=n.load(r),i=t.extra;if(void 0!==i&&void 0!==i.technique&&!1===l(i.technique)){const t=i.technique;s.wrapS=t.wrapU?e.RepeatWrapping:e.ClampToEdgeWrapping,s.wrapT=t.wrapV?e.RepeatWrapping:e.ClampToEdgeWrapping,s.offset.set(t.offsetU||0,t.offsetV||0),s.repeat.set(t.repeatU||1,t.repeatV||1)}else s.wrapS=e.RepeatWrapping,s.wrapT=e.RepeatWrapping;return null!==o&&(s.encoding=o),s}return console.warn("THREE.ColladaLoader: Loader for texture %s not found.",r),null}return console.warn("THREE.ColladaLoader: Couldn't create texture with ID:",t.id),null}r.name=t.name||"";const a=s.parameters;for(const t in a){const n=a[t];switch(t){case"diffuse":n.color&&r.color.fromArray(n.color),n.texture&&(r.map=i(n.texture,e.sRGBEncoding));break;case"specular":n.color&&r.specular&&r.specular.fromArray(n.color),n.texture&&(r.specularMap=i(n.texture));break;case"bump":n.texture&&(r.normalMap=i(n.texture));break;case"ambient":n.texture&&(r.lightMap=i(n.texture,e.sRGBEncoding));break;case"shininess":n.float&&r.shininess&&(r.shininess=n.float);break;case"emission":n.color&&r.emissive&&r.emissive.fromArray(n.color),n.texture&&(r.emissiveMap=i(n.texture,e.sRGBEncoding))}}r.color.convertSRGBToLinear(),r.specular&&r.specular.convertSRGBToLinear(),r.emissive&&r.emissive.convertSRGBToLinear();let c=a.transparent,d=a.transparency;if(void 0===d&&c&&(d={float:1}),void 0===c&&d&&(c={opaque:"A_ONE",data:{color:[1,1,1,1]}}),c&&d)if(c.data.texture)r.transparent=!0;else{const e=c.data.color;switch(c.opaque){case"A_ONE":r.opacity=e[3]*d.float;break;case"RGB_ZERO":r.opacity=1-e[0]*d.float;break;case"A_ZERO":r.opacity=1-e[3]*d.float;break;case"RGB_ONE":r.opacity=e[0]*d.float;break;default:console.warn('THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.',c.opaque)}r.opacity<1&&(r.transparent=!0)}if(void 0!==s.extra&&void 0!==s.extra.technique){const t=s.extra.technique;for(const n in t){const o=t[n];switch(n){case"double_sided":r.side=1===o?e.DoubleSide:e.FrontSide;break;case"bump":r.normalMap=i(o.texture),r.normalScale=new e.Vector2(1,1)}}}return r}function Z(e){return m(Qe.materials[e],Y)}function Q(e){for(let t=0;t0?n+r:n;t.inputs[i]={id:e,offset:s},t.stride=Math.max(t.stride,s+1),"TEXCOORD"===n&&(t.hasUV=!0);break;case"vcount":t.vcount=a(o.textContent);break;case"p":t.p=a(o.textContent)}}return t}function de(e){let t=0;for(let n=0,o=e.length;n0&&t0&&f.setAttribute("position",new e.Float32BufferAttribute(r.array,r.stride)),i.array.length>0&&f.setAttribute("normal",new e.Float32BufferAttribute(i.array,i.stride)),l.array.length>0&&f.setAttribute("color",new e.Float32BufferAttribute(l.array,l.stride)),a.array.length>0&&f.setAttribute("uv",new e.Float32BufferAttribute(a.array,a.stride)),c.array.length>0&&f.setAttribute("uv2",new e.Float32BufferAttribute(c.array,c.stride)),d.length>0&&f.setAttribute("skinIndex",new e.Float32BufferAttribute(d,4)),u.length>0&&f.setAttribute("skinWeight",new e.Float32BufferAttribute(u,4)),s.data=f,s.type=t[0].type,s.materialKeys=h,s}function he(e,t,n,o,s=!1){const r=e.p,i=e.stride,a=e.vcount;function c(e){let t=r[e+n]*d;const i=t+d;for(;t4)for(let t=1,o=n-2;t<=o;t++){const n=e+i*t,o=e+i*(t+1);c(e+0*i),c(n),c(o)}e+=i*n}}else for(let e=0,t=r.length;e=n.limits.max&&(n.static=!0),n.middlePosition=(n.limits.min+n.limits.max)/2,n}function Ne(e){const t={sid:e.getAttribute("sid"),name:e.getAttribute("name")||"",attachments:[],transforms:[]};for(let n=0;ns.limits.max||n