提交 a9c17b52 编写于 作者: M Mr.doob

ColladaLoader2: Separated parse and build steps.

上级 12803ed6
......@@ -84,7 +84,7 @@ THREE.ColladaLoader.prototype = {
// library
function buildLibrary( data, libraryName, nodeName, parser ) {
function parseLibrary( data, libraryName, nodeName, parser ) {
var library = xml.getElementsByTagName( libraryName )[ 0 ];
......@@ -94,8 +94,7 @@ THREE.ColladaLoader.prototype = {
for ( var i = 0; i < elements.length; i ++ ) {
var element = elements[ i ];
data[ element.getAttribute( 'id' ) ] = parser( element );
parser( elements[ i ] );
}
......@@ -103,13 +102,48 @@ THREE.ColladaLoader.prototype = {
}
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
var imageLoader = new THREE.ImageLoader();
function parseImage( xml ) {
var url = xml.getElementsByTagName( 'init_from' )[ 0 ].textContent;
var data = {
url: xml.getElementsByTagName( 'init_from' )[ 0 ].textContent
};
library.images[ xml.getAttribute( 'id' ) ] = data;
}
function buildImage( data ) {
if ( data.build !== undefined ) return data.build;
var url = data.url;
if ( baseUrl !== undefined ) url = baseUrl + url;
......@@ -117,11 +151,25 @@ THREE.ColladaLoader.prototype = {
}
function getImage( id ) {
return getBuild( library.images[ id ], buildImage );
}
// effect
function parseEffect( xml ) {
// console.log( xml );
}
function buildEffect( data ) {
}
function getEffect( id ) {
return getBuild( library.effects[ id ], buildEffect );
}
......@@ -129,14 +177,29 @@ THREE.ColladaLoader.prototype = {
function parseCamera( xml ) {
console.log( 'ColladaLoader.parseCamera: TODO')
var data = {
name: xml.getAttribute( 'name' )
};
library.cameras[ xml.getAttribute( 'id' ) ] = {};
}
function buildCamera( data ) {
var camera = new THREE.PerspectiveCamera();
camera.name = xml.getAttribute( 'name' );
camera.name = data.name;
return camera;
}
function getCamera( id ) {
return getBuild( library.cameras[ id ], buildCamera );
}
// light
function parseLight( xml ) {
......@@ -159,34 +222,7 @@ THREE.ColladaLoader.prototype = {
}
//
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;
library.lights[ xml.getAttribute( 'id' ) ] = data;
}
......@@ -252,15 +288,48 @@ THREE.ColladaLoader.prototype = {
}
// geometry
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 lineMaterial = new THREE.LineBasicMaterial();
var meshMaterial = new THREE.MeshPhongMaterial();
return getBuild( library.lights[ id ], buildLight );
}
// geometry
function parseGeometry( xml ) {
var data = {
id: xml.getAttribute( 'id' ),
name: xml.getAttribute( 'name' ),
sources: {},
primitives: []
......@@ -302,7 +371,51 @@ THREE.ColladaLoader.prototype = {
}
//
library.geometries[ xml.getAttribute( 'id' ) ] = data;
}
function parseGeometryPrimitive( xml ) {
var primitive = {
type: xml.nodeName,
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;
}
function buildGeometry( data ) {
var group = new THREE.Group();
......@@ -412,16 +525,16 @@ THREE.ColladaLoader.prototype = {
switch ( primitive.type ) {
case 'lines':
group.add( new THREE.LineSegments( geometry, lineMaterial ) );
group.add( new THREE.LineSegments( geometry ) );
break;
case 'linestrips':
group.add( new THREE.Line( geometry, lineMaterial ) );
group.add( new THREE.Line( geometry ) );
break;
case 'triangles':
case 'polylist':
group.add( new THREE.Mesh( geometry, meshMaterial ) );
group.add( new THREE.Mesh( geometry ) );
break;
}
......@@ -440,43 +553,9 @@ THREE.ColladaLoader.prototype = {
}
function parseGeometryPrimitive( xml ) {
var primitive = {
type: xml.nodeName,
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;
}
}
function getGeometry( id ) {
return primitive;
return getBuild( library.geometries[ id ], buildGeometry );
}
......@@ -487,10 +566,10 @@ THREE.ColladaLoader.prototype = {
function parseNode( xml ) {
var node = {
var data = {
name: xml.getAttribute( 'name' ),
matrix: new THREE.Matrix4(),
children: []
nodes: []
};
for ( var i = 0; i < xml.childNodes.length; i ++ ) {
......@@ -502,45 +581,46 @@ THREE.ColladaLoader.prototype = {
switch ( child.nodeName ) {
case 'instance_camera':
node.camera = library.cameras[ parseId( child.getAttribute( 'url' ) ) ];
data.camera = parseId( child.getAttribute( 'url' ) );
break;
case 'instance_light':
node.light = library.lights[ parseId( child.getAttribute( 'url' ) ) ];
data.light = parseId( child.getAttribute( 'url' ) );
break;
case 'instance_geometry':
node.geometry = library.geometries[ parseId( child.getAttribute( 'url' ) ) ];
data.geometry = parseId( child.getAttribute( 'url' ) );
break;
case 'instance_node':
node.children.push( library.nodes[ parseId( child.getAttribute( 'url' ) ) ] );
data.nodes.push( parseId( child.getAttribute( 'url' ) ) );
break;
case 'matrix':
var array = parseFloats( child.textContent );
node.matrix.multiply( matrix.fromArray( array ).transpose() ); // .transpose() when Z_UP?
data.matrix.multiply( matrix.fromArray( array ).transpose() ); // .transpose() when Z_UP?
break;
case 'node':
node.children.push( parseNode( child ) );
parseNode( child );
data.nodes.push( child.getAttribute( 'id' ) );
break;
case 'translate':
var array = parseFloats( child.textContent );
vector.fromArray( array );
node.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) );
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 ] );
node.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) );
data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) );
break;
case 'scale':
var array = parseFloats( child.textContent );
node.matrix.scale( vector.fromArray( array ) );
data.matrix.scale( vector.fromArray( array ) );
break;
case 'extra':
......@@ -554,21 +634,31 @@ THREE.ColladaLoader.prototype = {
}
//
if ( xml.getAttribute( 'id' ) !== null ) {
library.nodes[ xml.getAttribute( 'id' ) ] = data;
}
return data;
}
function buildNode( data ) {
var object;
if ( node.camera !== undefined ) {
if ( data.camera !== undefined ) {
object = node.camera.clone();
object = getCamera( data.camera ).clone();
} else if ( node.light !== undefined) {
} else if ( data.light !== undefined) {
object = node.light.clone();
object = getLight( data.light ).clone();
} else if ( node.geometry !== undefined ) {
} else if ( data.geometry !== undefined ) {
object = node.geometry.clone();
object = getGeometry( data.geometry ).clone();
} else {
......@@ -576,14 +666,12 @@ THREE.ColladaLoader.prototype = {
}
object.name = node.name;
node.matrix.decompose( object.position, object.quaternion, object.scale );
object.name = data.name;
data.matrix.decompose( object.position, object.quaternion, object.scale );
var children = node.children;
for ( var i = 0, l = data.nodes.length; i < l; i ++ ) {
for ( var i = 0, l = children.length; i < l; i ++ ) {
object.add( children[ i ] );
object.add( getNode( data.nodes[ i ] ).clone() );
}
......@@ -591,19 +679,43 @@ THREE.ColladaLoader.prototype = {
}
function getNode( id ) {
return getBuild( library.nodes[ id ], buildNode );
}
// visual scenes
function parseVisualScene( xml ) {
var group = new THREE.Group();
group.name = xml.getAttribute( 'name' );
var data = {
name: xml.getAttribute( 'name' ),
children: []
};
var elements = xml.getElementsByTagName( 'node' );
for ( var i = 0; i < elements.length; i ++ ) {
var element = elements[ i ];
group.add( parseNode( element ) );
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 ] ) );
}
......@@ -611,13 +723,19 @@ THREE.ColladaLoader.prototype = {
}
function getVisualScene( id ) {
return getBuild( library.visualScenes[ id ], buildVisualScene );
}
// scenes
function parseScene( xml ) {
var scene = xml.getElementsByTagName( 'scene' )[ 0 ];
var instance = scene.getElementsByTagName( 'instance_visual_scene' )[ 0 ];
return library.visualScenes[ parseId( instance.getAttribute( 'url' ) ) ];
return getVisualScene( parseId( instance.getAttribute( 'url' ) ) );
}
......@@ -631,7 +749,7 @@ THREE.ColladaLoader.prototype = {
var library = {
images: {},
effects: {},
// effects: {},
cameras: {},
lights: {},
geometries: {},
......@@ -639,13 +757,31 @@ THREE.ColladaLoader.prototype = {
visualScenes: {}
};
buildLibrary( library.images, 'library_images', 'image', parseImage );
buildLibrary( library.effects, 'library_effects', 'effect', parseEffect );
buildLibrary( library.cameras, 'library_cameras', 'camera', parseCamera );
buildLibrary( library.lights, 'library_lights', 'light', parseLight );
buildLibrary( library.geometries, 'library_geometries', 'geometry', parseGeometry );
buildLibrary( library.nodes, 'library_nodes', 'node', parseNode );
buildLibrary( library.visualScenes, 'library_visual_scenes', 'visual_scene', parseVisualScene );
console.time( 'ColladaLoader: Parse' );
parseLibrary( library.images, 'library_images', 'image', parseImage );
// parseLibrary( library.effects, 'library_effects', 'effect', parseEffect );
parseLibrary( library.cameras, 'library_cameras', 'camera', parseCamera );
parseLibrary( library.lights, 'library_lights', 'light', parseLight );
parseLibrary( library.geometries, 'library_geometries', 'geometry', parseGeometry );
parseLibrary( library.nodes, 'library_nodes', 'node', parseNode );
parseLibrary( library.visualScenes, 'library_visual_scenes', 'visual_scene', parseVisualScene );
console.timeEnd( 'ColladaLoader: Parse' );
console.time( 'ColladaLoader: Build' );
buildLibrary( library.images, buildImage );
// buildLibrary( library.effects, buildEffect );
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( xml );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册