ObjectLoader.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. import { TextureMapping, TextureWrapping, TextureFilter } from '../constants';
  2. import { Color } from '../math/Color';
  3. import { Matrix4 } from '../math/Matrix4';
  4. import { Object3D } from '../core/Object3D';
  5. import { Group } from '../objects/Group';
  6. import { Sprite } from '../objects/Sprite';
  7. import { Points } from '../objects/Points';
  8. import { Line } from '../objects/Line';
  9. import { LineSegments } from '../objects/LineSegments';
  10. import { LOD } from '../objects/LOD';
  11. import { Mesh } from '../objects/Mesh';
  12. import { SkinnedMesh } from '../objects/SkinnedMesh';
  13. import { Fog } from '../scenes/Fog';
  14. import { FogExp2 } from '../scenes/FogExp2';
  15. import { HemisphereLight } from '../lights/HemisphereLight';
  16. import { SpotLight } from '../lights/SpotLight';
  17. import { PointLight } from '../lights/PointLight';
  18. import { DirectionalLight } from '../lights/DirectionalLight';
  19. import { AmbientLight } from '../lights/AmbientLight';
  20. import { OrthographicCamera } from '../cameras/OrthographicCamera';
  21. import { PerspectiveCamera } from '../cameras/PerspectiveCamera';
  22. import { Scene } from '../scenes/Scene';
  23. import { Texture } from '../textures/Texture';
  24. import { ImageLoader } from './ImageLoader';
  25. import { LoadingManager, DefaultLoadingManager } from './LoadingManager';
  26. import { AnimationClip } from '../animation/AnimationClip';
  27. import { MaterialLoader } from './MaterialLoader';
  28. import { BufferGeometryLoader } from './BufferGeometryLoader';
  29. import { JSONLoader } from './JSONLoader';
  30. import { FileLoader } from './FileLoader';
  31. import * as Geometries from '../geometries/Geometries';
  32. /**
  33. * @author mrdoob / http://mrdoob.com/
  34. */
  35. function ObjectLoader( manager ) {
  36. this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
  37. this.texturePath = '';
  38. }
  39. Object.assign( ObjectLoader.prototype, {
  40. load: function ( url, onLoad, onProgress, onError ) {
  41. if ( this.texturePath === '' ) {
  42. this.texturePath = url.substring( 0, url.lastIndexOf( '/' ) + 1 );
  43. }
  44. var scope = this;
  45. var loader = new FileLoader( scope.manager );
  46. loader.load( url, function ( text ) {
  47. var json = null;
  48. try {
  49. json = JSON.parse( text );
  50. } catch ( error ) {
  51. console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );
  52. return;
  53. }
  54. var metadata = json.metadata;
  55. if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
  56. console.error( 'THREE.ObjectLoader: Can\'t load ' + url + '. Use THREE.JSONLoader instead.' );
  57. return;
  58. }
  59. scope.parse( json, onLoad );
  60. }, onProgress, onError );
  61. },
  62. setTexturePath: function ( value ) {
  63. this.texturePath = value;
  64. },
  65. setCrossOrigin: function ( value ) {
  66. this.crossOrigin = value;
  67. },
  68. parse: function ( json, onLoad ) {
  69. var geometries = this.parseGeometries( json.geometries );
  70. var images = this.parseImages( json.images, function () {
  71. if ( onLoad !== undefined ) onLoad( object );
  72. } );
  73. var textures = this.parseTextures( json.textures, images );
  74. var materials = this.parseMaterials( json.materials, textures );
  75. var object = this.parseObject( json.object, geometries, materials );
  76. if ( json.animations ) {
  77. object.animations = this.parseAnimations( json.animations );
  78. }
  79. if ( json.images === undefined || json.images.length === 0 ) {
  80. if ( onLoad !== undefined ) onLoad( object );
  81. }
  82. return object;
  83. },
  84. parseGeometries: function ( json ) {
  85. var geometries = {};
  86. if ( json !== undefined ) {
  87. var geometryLoader = new JSONLoader();
  88. var bufferGeometryLoader = new BufferGeometryLoader();
  89. for ( var i = 0, l = json.length; i < l; i ++ ) {
  90. var geometry;
  91. var data = json[ i ];
  92. switch ( data.type ) {
  93. case 'PlaneGeometry':
  94. case 'PlaneBufferGeometry':
  95. geometry = new Geometries[ data.type ](
  96. data.width,
  97. data.height,
  98. data.widthSegments,
  99. data.heightSegments
  100. );
  101. break;
  102. case 'BoxGeometry':
  103. case 'BoxBufferGeometry':
  104. case 'CubeGeometry': // backwards compatible
  105. geometry = new Geometries[ data.type ](
  106. data.width,
  107. data.height,
  108. data.depth,
  109. data.widthSegments,
  110. data.heightSegments,
  111. data.depthSegments
  112. );
  113. break;
  114. case 'CircleGeometry':
  115. case 'CircleBufferGeometry':
  116. geometry = new Geometries[ data.type ](
  117. data.radius,
  118. data.segments,
  119. data.thetaStart,
  120. data.thetaLength
  121. );
  122. break;
  123. case 'CylinderGeometry':
  124. case 'CylinderBufferGeometry':
  125. geometry = new Geometries[ data.type ](
  126. data.radiusTop,
  127. data.radiusBottom,
  128. data.height,
  129. data.radialSegments,
  130. data.heightSegments,
  131. data.openEnded,
  132. data.thetaStart,
  133. data.thetaLength
  134. );
  135. break;
  136. case 'ConeGeometry':
  137. case 'ConeBufferGeometry':
  138. geometry = new Geometries[ data.type ](
  139. data.radius,
  140. data.height,
  141. data.radialSegments,
  142. data.heightSegments,
  143. data.openEnded,
  144. data.thetaStart,
  145. data.thetaLength
  146. );
  147. break;
  148. case 'SphereGeometry':
  149. case 'SphereBufferGeometry':
  150. geometry = new Geometries[ data.type ](
  151. data.radius,
  152. data.widthSegments,
  153. data.heightSegments,
  154. data.phiStart,
  155. data.phiLength,
  156. data.thetaStart,
  157. data.thetaLength
  158. );
  159. break;
  160. case 'DodecahedronGeometry':
  161. case 'IcosahedronGeometry':
  162. case 'OctahedronGeometry':
  163. case 'TetrahedronGeometry':
  164. geometry = new Geometries[ data.type ](
  165. data.radius,
  166. data.detail
  167. );
  168. break;
  169. case 'RingGeometry':
  170. case 'RingBufferGeometry':
  171. geometry = new Geometries[ data.type ](
  172. data.innerRadius,
  173. data.outerRadius,
  174. data.thetaSegments,
  175. data.phiSegments,
  176. data.thetaStart,
  177. data.thetaLength
  178. );
  179. break;
  180. case 'TorusGeometry':
  181. case 'TorusBufferGeometry':
  182. geometry = new Geometries[ data.type ](
  183. data.radius,
  184. data.tube,
  185. data.radialSegments,
  186. data.tubularSegments,
  187. data.arc
  188. );
  189. break;
  190. case 'TorusKnotGeometry':
  191. case 'TorusKnotBufferGeometry':
  192. geometry = new Geometries[ data.type ](
  193. data.radius,
  194. data.tube,
  195. data.tubularSegments,
  196. data.radialSegments,
  197. data.p,
  198. data.q
  199. );
  200. break;
  201. case 'LatheGeometry':
  202. case 'LatheBufferGeometry':
  203. geometry = new Geometries[ data.type ](
  204. data.points,
  205. data.segments,
  206. data.phiStart,
  207. data.phiLength
  208. );
  209. break;
  210. case 'BufferGeometry':
  211. geometry = bufferGeometryLoader.parse( data );
  212. break;
  213. case 'Geometry':
  214. geometry = geometryLoader.parse( data.data, this.texturePath ).geometry;
  215. break;
  216. default:
  217. console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
  218. continue;
  219. }
  220. geometry.uuid = data.uuid;
  221. if ( data.name !== undefined ) geometry.name = data.name;
  222. geometries[ data.uuid ] = geometry;
  223. }
  224. }
  225. return geometries;
  226. },
  227. parseMaterials: function ( json, textures ) {
  228. var materials = {};
  229. if ( json !== undefined ) {
  230. var loader = new MaterialLoader();
  231. loader.setTextures( textures );
  232. for ( var i = 0, l = json.length; i < l; i ++ ) {
  233. var material = loader.parse( json[ i ] );
  234. materials[ material.uuid ] = material;
  235. }
  236. }
  237. return materials;
  238. },
  239. parseAnimations: function ( json ) {
  240. var animations = [];
  241. for ( var i = 0; i < json.length; i ++ ) {
  242. var clip = AnimationClip.parse( json[ i ] );
  243. animations.push( clip );
  244. }
  245. return animations;
  246. },
  247. parseImages: function ( json, onLoad ) {
  248. var scope = this;
  249. var images = {};
  250. function loadImage( url ) {
  251. scope.manager.itemStart( url );
  252. return loader.load( url, function () {
  253. scope.manager.itemEnd( url );
  254. }, undefined, function () {
  255. scope.manager.itemError( url );
  256. } );
  257. }
  258. if ( json !== undefined && json.length > 0 ) {
  259. var manager = new LoadingManager( onLoad );
  260. var loader = new ImageLoader( manager );
  261. loader.setCrossOrigin( this.crossOrigin );
  262. for ( var i = 0, l = json.length; i < l; i ++ ) {
  263. var image = json[ i ];
  264. var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;
  265. images[ image.uuid ] = loadImage( path );
  266. }
  267. }
  268. return images;
  269. },
  270. parseTextures: function ( json, images ) {
  271. function parseConstant( value, type ) {
  272. if ( typeof( value ) === 'number' ) return value;
  273. console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
  274. return type[ value ];
  275. }
  276. var textures = {};
  277. if ( json !== undefined ) {
  278. for ( var i = 0, l = json.length; i < l; i ++ ) {
  279. var data = json[ i ];
  280. if ( data.image === undefined ) {
  281. console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
  282. }
  283. if ( images[ data.image ] === undefined ) {
  284. console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
  285. }
  286. var texture = new Texture( images[ data.image ] );
  287. texture.needsUpdate = true;
  288. texture.uuid = data.uuid;
  289. if ( data.name !== undefined ) texture.name = data.name;
  290. if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TextureMapping );
  291. if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
  292. if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
  293. if ( data.wrap !== undefined ) {
  294. texture.wrapS = parseConstant( data.wrap[ 0 ], TextureWrapping );
  295. texture.wrapT = parseConstant( data.wrap[ 1 ], TextureWrapping );
  296. }
  297. if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TextureFilter );
  298. if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TextureFilter );
  299. if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
  300. if ( data.flipY !== undefined ) texture.flipY = data.flipY;
  301. textures[ data.uuid ] = texture;
  302. }
  303. }
  304. return textures;
  305. },
  306. parseObject: function () {
  307. var matrix = new Matrix4();
  308. return function parseObject( data, geometries, materials ) {
  309. var object;
  310. function getGeometry( name ) {
  311. if ( geometries[ name ] === undefined ) {
  312. console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
  313. }
  314. return geometries[ name ];
  315. }
  316. function getMaterial( name ) {
  317. if ( name === undefined ) return undefined;
  318. if ( materials[ name ] === undefined ) {
  319. console.warn( 'THREE.ObjectLoader: Undefined material', name );
  320. }
  321. return materials[ name ];
  322. }
  323. switch ( data.type ) {
  324. case 'Scene':
  325. object = new Scene();
  326. if ( data.background !== undefined ) {
  327. if ( Number.isInteger( data.background ) ) {
  328. object.background = new Color( data.background );
  329. }
  330. }
  331. if ( data.fog !== undefined ) {
  332. if ( data.fog.type === 'Fog' ) {
  333. object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
  334. } else if ( data.fog.type === 'FogExp2' ) {
  335. object.fog = new FogExp2( data.fog.color, data.fog.density );
  336. }
  337. }
  338. break;
  339. case 'PerspectiveCamera':
  340. object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
  341. if ( data.focus !== undefined ) object.focus = data.focus;
  342. if ( data.zoom !== undefined ) object.zoom = data.zoom;
  343. if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
  344. if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
  345. if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );
  346. break;
  347. case 'OrthographicCamera':
  348. object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
  349. break;
  350. case 'AmbientLight':
  351. object = new AmbientLight( data.color, data.intensity );
  352. break;
  353. case 'DirectionalLight':
  354. object = new DirectionalLight( data.color, data.intensity );
  355. break;
  356. case 'PointLight':
  357. object = new PointLight( data.color, data.intensity, data.distance, data.decay );
  358. break;
  359. case 'SpotLight':
  360. object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
  361. break;
  362. case 'HemisphereLight':
  363. object = new HemisphereLight( data.color, data.groundColor, data.intensity );
  364. break;
  365. case 'Mesh':
  366. var geometry = getGeometry( data.geometry );
  367. var material = getMaterial( data.material );
  368. if ( geometry.bones && geometry.bones.length > 0 ) {
  369. object = new SkinnedMesh( geometry, material );
  370. } else {
  371. object = new Mesh( geometry, material );
  372. }
  373. break;
  374. case 'LOD':
  375. object = new LOD();
  376. break;
  377. case 'Line':
  378. object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
  379. break;
  380. case 'LineSegments':
  381. object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );
  382. break;
  383. case 'PointCloud':
  384. case 'Points':
  385. object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );
  386. break;
  387. case 'Sprite':
  388. object = new Sprite( getMaterial( data.material ) );
  389. break;
  390. case 'Group':
  391. object = new Group();
  392. break;
  393. case 'SkinnedMesh':
  394. console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh type. Instantiates Object3D instead.' );
  395. default:
  396. object = new Object3D();
  397. }
  398. object.uuid = data.uuid;
  399. if ( data.name !== undefined ) object.name = data.name;
  400. if ( data.matrix !== undefined ) {
  401. matrix.fromArray( data.matrix );
  402. matrix.decompose( object.position, object.quaternion, object.scale );
  403. } else {
  404. if ( data.position !== undefined ) object.position.fromArray( data.position );
  405. if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
  406. if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
  407. if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
  408. }
  409. if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
  410. if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
  411. if ( data.shadow ) {
  412. if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
  413. if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
  414. if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
  415. if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );
  416. }
  417. if ( data.visible !== undefined ) object.visible = data.visible;
  418. if ( data.userData !== undefined ) object.userData = data.userData;
  419. if ( data.children !== undefined ) {
  420. for ( var child in data.children ) {
  421. object.add( this.parseObject( data.children[ child ], geometries, materials ) );
  422. }
  423. }
  424. if ( data.type === 'LOD' ) {
  425. var levels = data.levels;
  426. for ( var l = 0; l < levels.length; l ++ ) {
  427. var level = levels[ l ];
  428. var child = object.getObjectByProperty( 'uuid', level.object );
  429. if ( child !== undefined ) {
  430. object.addLevel( child, level.distance );
  431. }
  432. }
  433. }
  434. return object;
  435. };
  436. }()
  437. } );
  438. export { ObjectLoader };
粤ICP备19079148号