123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- /**
- * @author mrdoob / http://mrdoob.com/
- */
- THREE.GLTFLoader = function ( manager ) {
- this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
- };
- THREE.GLTFLoader.prototype = {
- constructor: THREE.GLTFLoader,
- load: function ( url, onLoad, onProgress, onError ) {
- var scope = this;
- var loader = new THREE.XHRLoader( scope.manager );
- loader.load( url, function ( text ) {
- onLoad( scope.parse( JSON.parse( text ) ) );
- }, onProgress, onError );
- },
- setCrossOrigin: function ( value ) {
- this.crossOrigin = value;
- },
- parse: function ( json ) {
- function stringToArrayBuffer( string ) {
- var bytes = atob( string );
- var buffer = new ArrayBuffer( bytes.length );
- var bufferView = new Uint8Array( buffer );
- for ( var i = 0; i < bytes.length; i ++ ) {
- bufferView[ i ] = bytes.charCodeAt( i );
- }
- return buffer;
- }
- console.time( 'GLTFLoader' );
- // buffers
- var buffers = json.buffers;
- for ( var bufferId in buffers ) {
- var buffer = buffers[ bufferId ];
- if ( buffer.type === 'arraybuffer' ) {
- var header = 'data:application/octet-stream;base64,';
- if ( buffer.uri.indexOf( header ) === 0 ) {
- buffer._arraybuffer = stringToArrayBuffer( buffer.uri.substr( header.length ) );
- }
- }
- }
- // buffer views
- var bufferViews = json.bufferViews;
- for ( var bufferViewId in bufferViews ) {
- var bufferView = bufferViews[ bufferViewId ];
- var arraybuffer = buffers[ bufferView.buffer ]._arraybuffer;
- bufferView._arraybuffer = arraybuffer.slice( bufferView.byteOffset, bufferView.byteOffset + bufferView.byteLength );
- }
- // accessors
- var COMPONENT_TYPES = {
- 5120: Int8Array,
- 5121: Uint8Array,
- 5122: Int16Array,
- 5123: Uint16Array,
- 5126: Float32Array,
- };
- var TYPE_SIZES = {
- 'SCALAR': 1, 'VEC2': 2, 'VEC3': 3, 'VEC4': 4,
- 'MAT2': 4, 'MAT3': 9, 'MAT4': 16
- };
- var accessors = json.accessors;
- for ( var accessorId in accessors ) {
- var accessor = accessors[ accessorId ];
- var arraybuffer = bufferViews[ accessor.bufferView ]._arraybuffer;
- var itemSize = TYPE_SIZES[ accessor.type ];
- var TypedArray = COMPONENT_TYPES[ accessor.componentType ];
- var array = new TypedArray( arraybuffer, accessor.byteOffset, accessor.count * itemSize );
- accessor._bufferattribute = new THREE.BufferAttribute( array, itemSize );
- }
- // meshes
- var meshes = json.meshes;
- for ( var meshId in meshes ) {
- var mesh = meshes[ meshId ];
- var geometry = new THREE.BufferGeometry();
- geometry.name = mesh.name;
- var primitives = mesh.primitives;
- for ( var i = 0; i < 1; /*primitives.length;*/ i ++ ) {
- var primitive = primitives[ 0 ];
- var attributes = primitive.attributes;
- if ( primitive.indices ) {
- geometry.setIndex( accessors[ primitive.indices ]._bufferattribute );
- }
- for ( var attributeId in attributes ) {
- var attribute = attributes[ attributeId ];
- var bufferAttribute = accessors[ attribute ]._bufferattribute;
- switch ( attributeId ) {
- case 'POSITION':
- geometry.addAttribute( 'position', bufferAttribute );
- break;
- case 'NORMAL':
- geometry.addAttribute( 'normal', bufferAttribute );
- break;
- case 'TEXCOORD_0':
- geometry.addAttribute( 'uv', bufferAttribute );
- break;
- }
- }
- }
- mesh._geometry = geometry;
- }
- // nodes
- var nodes = json.nodes;
- var matrix = new THREE.Matrix4();
- for ( var nodeId in nodes ) {
- var node = nodes[ nodeId ];
- var object = new THREE.Group();
- object.name = node.name;
- if ( node.translation !== undefined ) {
- object.position.fromArray( node.translation );
- }
- if ( node.rotation !== undefined ) {
- object.quaternion.fromArray( node.rotation );
- }
- if ( node.scale !== undefined ) {
- object.scale.fromArray( node.scale );
- }
- if ( node.matrix !== undefined ) {
- matrix.fromArray( node.matrix );
- matrix.decompose( object.position, object.quaternion, object.scale );
- }
- if ( node.meshes !== undefined ) {
- for ( var i = 0; i < node.meshes.length; i ++ ) {
- var meshId = node.meshes[ i ];
- object.add( new THREE.Mesh( meshes[ meshId ]._geometry, new THREE.MeshNormalMaterial() ) );
- }
- }
- node._object = object;
- }
- for ( var nodeId in nodes ) {
- var node = nodes[ nodeId ];
- for ( var i = 0; i < node.children.length; i ++ ) {
- var child = node.children[ i ];
- node._object.add( nodes[ child ]._object );
- }
- }
- // scenes
- var scenes = json.scenes;
- for ( var sceneId in scenes ) {
- var scene = scenes[ sceneId ];
- var container = new THREE.Scene();
- for ( var i = 0; i < scene.nodes.length; i ++ ) {
- var node = scene.nodes[ i ];
- container.add( nodes[ node ]._object );
- }
- scene._container = container;
- }
- console.timeEnd( 'GLTFLoader' );
- return {
- scene: json.scenes[ json.scene ]._container
- };
- }
- };
|