ObjectLoader.js 12 KB

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