2018-08-01 21:34:58 +08:00

1594 lines
28 KiB
JavaScript

/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.ColladaLoader = function (manager) {
this.manager = (manager !== undefined) ? manager : THREE.DefaultLoadingManager;
};
THREE.ColladaLoader.prototype = {
constructor: THREE.ColladaLoader,
load: function (url, onLoad, onProgress, onError) {
var scope = this;
var loader = new THREE.FileLoader(scope.manager);
loader.load(url, function (text) {
onLoad(scope.parse(text));
}, onProgress, onError);
},
options: {
set convertUpAxis(value) {
console.log('ColladaLoder.options.convertUpAxis: TODO');
}
},
setCrossOrigin: function (value) {
this.crossOrigin = value;
},
parse: function (text) {
function getElementsByTagName(xml, name) {
// Non recursive xml.getElementsByTagName() ...
var array = [];
var childNodes = xml.childNodes;
for (var i = 0, l = childNodes.length; i < l; i++) {
var child = childNodes[i];
if (child.nodeName === name) {
array.push(child);
}
}
return array;
}
function parseFloats(text) {
if (text.length === 0) return [];
var parts = text.trim().split(/\s+/);
var array = new Array(parts.length);
for (var i = 0, l = parts.length; i < l; i++) {
array[i] = parseFloat(parts[i]);
}
return array;
}
function parseInts(text) {
if (text.length === 0) return [];
var parts = text.trim().split(/\s+/);
var array = new Array(parts.length);
for (var i = 0, l = parts.length; i < l; i++) {
array[i] = parseInt(parts[i]);
}
return array;
}
function parseId(text) {
return text.substring(1);
}
// asset
function parseAsset(xml) {
return {
unit: parseAssetUnit(getElementsByTagName(xml, 'unit')[0]),
upAxis: parseAssetUpAxis(getElementsByTagName(xml, 'up_axis')[0])
};
}
function parseAssetUnit(xml) {
return xml !== undefined ? parseFloat(xml.getAttribute('meter')) : 1;
}
function parseAssetUpAxis(xml) {
return xml !== undefined ? xml.textContent : 'Y_UP';
}
// library
function parseLibrary(xml, libraryName, nodeName, parser) {
var library = getElementsByTagName(xml, libraryName)[0];
if (library !== undefined) {
var elements = getElementsByTagName(library, nodeName);
for (var i = 0; i < elements.length; i++) {
parser(elements[i]);
}
}
}
function buildLibrary(data, builder) {
for (var name in data) {
var object = data[name];
object.build = builder(data[name]);
}
}
// get
function getBuild(data, builder) {
if (data.build !== undefined) return data.build;
data.build = builder(data);
return data.build;
}
// 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 new Image();
}
function getImage(id) {
return getBuild(library.images[id], buildImage);
}
// 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;
}
}
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 'shininess':
case 'transparent':
case 'transparency':
data[child.nodeName] = 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 = {};
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':
data = parseEffectParameterTextureExtra(child);
break;
}
}
return data;
}
function parseEffectParameterTextureExtra(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[child.nodeName] = parseEffectParameterTextureExtraTechnique(child);
break;
}
}
return data;
}
function parseEffectParameterTextureExtraTechnique(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 'repeatU':
case 'repeatV':
case 'offsetU':
case 'offsetV':
data[child.nodeName] = parseFloat(child.textContent);
break;
case 'wrapU':
case 'wrapV':
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 buildMaterial(data) {
var effect = getEffect(data.url);
var technique = effect.profile.technique;
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];
if (sampler !== undefined) {
var surface = effect.profile.surfaces[sampler.source];
var texture = new THREE.Texture(getImage(surface.init_from));
var extra = textureObject.extra;
if (extra !== undefined && extra.technique !== undefined) {
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, technique.offsetV);
texture.repeat.set(technique.repeatU, technique.repeatV);
} else {
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
}
texture.needsUpdate = true;
return texture;
}
console.error('ColladaLoder: Undefined sampler', 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);
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);
break;
case 'transparent':
// if ( parameter.texture ) material.alphaMap = getTexture( parameter.texture );
material.transparent = true;
break;
case 'transparency':
if (parameter.float !== undefined) material.opacity = parameter.float;
material.transparent = true;
break;
}
}
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':
camera = new THREE.OrthographicCamera( /* TODO */);
break;
default:
camera = new THREE.PerspectiveCamera();
break;
}
camera.name = data.name;
return camera;
}
function getCamera(id) {
return getBuild(library.cameras[id], buildCamera);
}
// 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) {
return getBuild(library.lights[id], buildLight);
}
// geometry
function parseGeometry(xml) {
var data = {
name: xml.getAttribute('name'),
sources: {},
vertices: {},
primitives: []
};
var mesh = getElementsByTagName(xml, 'mesh')[0];
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] = parseGeometrySource(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('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 parseGeometrySource(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 'technique_common':
var accessor = getElementsByTagName(child, 'accessor')[0];
if (accessor !== undefined) {
data.stride = parseInt(accessor.getAttribute('stride'));
}
break;
default:
console.log(child);
}
}
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'),
inputs: {},
stride: 0
};
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'));
primitive.inputs[semantic] = { id: id, offset: offset };
primitive.stride = Math.max(primitive.stride, offset + 1);
break;
case 'vcount':
primitive.vcount = parseInts(child.textContent);
break;
case 'p':
primitive.p = parseInts(child.textContent);
break;
}
}
return primitive;
}
var DEFAULT_LINEMATERIAL = new THREE.LineBasicMaterial();
var DEFAULT_MESHMATERIAL = new THREE.MeshPhongMaterial();
function buildGeometry(data) {
var group = {};
var sources = data.sources;
var vertices = data.vertices;
var primitives = data.primitives;
if (primitives.length === 0) return group;
for (var p = 0; p < primitives.length; p++) {
var primitive = primitives[p];
var inputs = primitive.inputs;
var geometry = new THREE.BufferGeometry();
if (data.name) geometry.name = data.name;
for (var name in inputs) {
var input = inputs[name];
switch (name) {
case 'VERTEX':
for (var key in vertices) {
geometry.addAttribute(key.toLowerCase(), buildGeometryAttribute(primitive, sources[vertices[key]], input.offset));
}
break;
case 'NORMAL':
geometry.addAttribute('normal', buildGeometryAttribute(primitive, sources[input.id], input.offset));
break;
case 'COLOR':
geometry.addAttribute('color', buildGeometryAttribute(primitive, sources[input.id], input.offset));
break;
case 'TEXCOORD':
geometry.addAttribute('uv', buildGeometryAttribute(primitive, sources[input.id], input.offset));
break;
}
}
var object;
switch (primitive.type) {
case 'lines':
object = new THREE.LineSegments(geometry, DEFAULT_LINEMATERIAL);
break;
case 'linestrips':
object = new THREE.Line(geometry, DEFAULT_LINEMATERIAL);
break;
case 'triangles':
case 'polylist':
object = new THREE.Mesh(geometry, DEFAULT_MESHMATERIAL);
break;
}
group[primitive.material] = object;
}
return group;
}
function buildGeometryAttribute(primitive, source, offset) {
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 maxcount = 0;
var sourceArray = source.array;
var sourceStride = source.stride;
var array = [];
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 {
maxcount = Math.max(maxcount, count);
}
index += stride * count;
}
if (maxcount > 0) {
console.log('ColladaLoader: Geometry has faces with more than 4 vertices.');
}
} else {
for (var i = 0, l = indices.length; i < l; i += stride) {
pushVector(i);
}
}
return new THREE.Float32BufferAttribute(array, sourceStride);
}
function getGeometry(id) {
return getBuild(library.geometries[id], buildGeometry);
}
// nodes
var matrix = new THREE.Matrix4();
var vector = new THREE.Vector3();
function parseNode(xml) {
var data = {
name: xml.getAttribute('name'),
matrix: new THREE.Matrix4(),
nodes: [],
instanceCameras: [],
instanceLights: [],
instanceGeometries: [],
instanceNodes: []
};
for (var i = 0; i < xml.childNodes.length; i++) {
var child = xml.childNodes[i];
if (child.nodeType !== 1) continue;
switch (child.nodeName) {
case 'node':
if (child.hasAttribute('id')) {
data.nodes.push(child.getAttribute('id'));
parseNode(child);
}
break;
case 'instance_camera':
data.instanceCameras.push(parseId(child.getAttribute('url')));
break;
case 'instance_light':
data.instanceLights.push(parseId(child.getAttribute('url')));
break;
case 'instance_geometry':
data.instanceGeometries.push(parseNodeInstanceGeometry(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()); // .transpose() when Z_UP?
break;
case 'translate':
var array = parseFloats(child.textContent);
vector.fromArray(array);
data.matrix.multiply(matrix.makeTranslation(vector.x, vector.y, vector.z));
break;
case 'rotate':
var array = parseFloats(child.textContent);
var angle = THREE.Math.degToRad(array[3]);
data.matrix.multiply(matrix.makeRotationAxis(vector.fromArray(array), angle));
break;
case 'scale':
var array = parseFloats(child.textContent);
data.matrix.scale(vector.fromArray(array));
break;
case 'extra':
break;
default:
console.log(child);
}
}
if (xml.hasAttribute('id')) {
library.nodes[xml.getAttribute('id')] = data;
}
return data;
}
function parseNodeInstanceGeometry(xml) {
var data = {
id: parseId(xml.getAttribute('url')),
materials: {}
};
for (var i = 0; i < xml.childNodes.length; i++) {
var child = xml.childNodes[i];
if (child.nodeName === '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;
}
}
return data;
}
function buildNode(data) {
var objects = [];
var matrix = data.matrix;
var nodes = data.nodes;
var instanceCameras = data.instanceCameras;
var instanceLights = data.instanceLights;
var instanceGeometries = data.instanceGeometries;
var instanceNodes = data.instanceNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
objects.push(getNode(nodes[i]).clone());
}
for (var i = 0, l = instanceCameras.length; i < l; i++) {
objects.push(getCamera(instanceCameras[i]).clone());
}
for (var i = 0, l = instanceLights.length; i < l; i++) {
objects.push(getLight(instanceLights[i]).clone());
}
for (var i = 0, l = instanceGeometries.length; i < l; i++) {
var instance = instanceGeometries[i];
var geometries = getGeometry(instance.id);
for (var key in geometries) {
var object = geometries[key].clone();
if (instance.materials[key] !== undefined) {
object.material = getMaterial(instance.materials[key]);
}
objects.push(object);
}
}
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 = new THREE.Group();
for (var i = 0; i < objects.length; i++) {
object.add(objects[i]);
}
}
object.name = data.name;
matrix.decompose(object.position, object.quaternion, object.scale);
return object;
}
function getNode(id) {
return getBuild(library.nodes[id], buildNode);
}
// visual scenes
function parseVisualScene(xml) {
var data = {
name: xml.getAttribute('name'),
children: []
};
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++) {
group.add(buildNode(children[i]));
}
return group;
}
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')));
}
console.time('ColladaLoader');
if (text.length === 0) {
return { scene: new THREE.Scene() };
}
console.time('ColladaLoader: DOMParser');
var xml = new DOMParser().parseFromString(text, 'application/xml');
console.timeEnd('ColladaLoader: DOMParser');
var collada = getElementsByTagName(xml, 'COLLADA')[0];
// metadata
var version = collada.getAttribute('version');
console.log('ColladaLoader: File version', version);
var asset = parseAsset(getElementsByTagName(collada, 'asset')[0]);
//
var library = {
images: {},
effects: {},
materials: {},
cameras: {},
lights: {},
geometries: {},
nodes: {},
visualScenes: {}
};
console.time('ColladaLoader: Parse');
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);
console.timeEnd('ColladaLoader: Parse');
console.time('ColladaLoader: Build');
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.nodes, buildNode );
buildLibrary(library.visualScenes, buildVisualScene);
console.timeEnd('ColladaLoader: Build');
// console.log( library );
var scene = parseScene(getElementsByTagName(collada, 'scene')[0]);
if (asset.upAxis === 'Z_UP') {
scene.rotation.x = - Math.PI / 2;
}
scene.scale.multiplyScalar(asset.unit);
console.timeEnd('ColladaLoader');
// console.log( scene );
return {
animations: [],
kinematics: { joints: [] },
library: library,
scene: scene
};
}
};