ObjectLoader.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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.images === undefined || json.images.length === 0 ) {
  36. if ( onLoad !== undefined ) onLoad( object );
  37. }
  38. return object;
  39. },
  40. parseGeometries: function ( json ) {
  41. var geometries = {};
  42. if ( json !== undefined ) {
  43. var geometryLoader = new THREE.JSONLoader();
  44. var bufferGeometryLoader = new THREE.BufferGeometryLoader();
  45. for ( var i = 0, l = json.length; i < l; i ++ ) {
  46. var geometry;
  47. var data = json[ i ];
  48. switch ( data.type ) {
  49. case 'PlaneGeometry':
  50. case 'PlaneBufferGeometry':
  51. geometry = new THREE[ data.type ](
  52. data.width,
  53. data.height,
  54. data.widthSegments,
  55. data.heightSegments
  56. );
  57. break;
  58. case 'BoxGeometry':
  59. case 'CubeGeometry': // backwards compatible
  60. geometry = new THREE.BoxGeometry(
  61. data.width,
  62. data.height,
  63. data.depth,
  64. data.widthSegments,
  65. data.heightSegments,
  66. data.depthSegments
  67. );
  68. break;
  69. case 'CircleGeometry':
  70. geometry = new THREE.CircleGeometry(
  71. data.radius,
  72. data.segments
  73. );
  74. break;
  75. case 'CylinderGeometry':
  76. geometry = new THREE.CylinderGeometry(
  77. data.radiusTop,
  78. data.radiusBottom,
  79. data.height,
  80. data.radialSegments,
  81. data.heightSegments,
  82. data.openEnded
  83. );
  84. break;
  85. case 'SphereGeometry':
  86. geometry = new THREE.SphereGeometry(
  87. data.radius,
  88. data.widthSegments,
  89. data.heightSegments,
  90. data.phiStart,
  91. data.phiLength,
  92. data.thetaStart,
  93. data.thetaLength
  94. );
  95. break;
  96. case 'IcosahedronGeometry':
  97. geometry = new THREE.IcosahedronGeometry(
  98. data.radius,
  99. data.detail
  100. );
  101. break;
  102. case 'TorusGeometry':
  103. geometry = new THREE.TorusGeometry(
  104. data.radius,
  105. data.tube,
  106. data.radialSegments,
  107. data.tubularSegments,
  108. data.arc
  109. );
  110. break;
  111. case 'TorusKnotGeometry':
  112. geometry = new THREE.TorusKnotGeometry(
  113. data.radius,
  114. data.tube,
  115. data.radialSegments,
  116. data.tubularSegments,
  117. data.p,
  118. data.q,
  119. data.heightScale
  120. );
  121. break;
  122. case 'BufferGeometry':
  123. geometry = bufferGeometryLoader.parse( data );
  124. break;
  125. case 'Geometry':
  126. geometry = geometryLoader.parse( data.data ).geometry;
  127. break;
  128. }
  129. geometry.uuid = data.uuid;
  130. if ( data.name !== undefined ) geometry.name = data.name;
  131. geometries[ data.uuid ] = geometry;
  132. }
  133. }
  134. return geometries;
  135. },
  136. parseMaterials: function ( json, textures ) {
  137. var materials = {};
  138. if ( json !== undefined ) {
  139. var getTexture = function ( name ) {
  140. if ( textures[ name ] === undefined ) {
  141. THREE.warn( 'THREE.ObjectLoader: Undefined texture', name );
  142. }
  143. return textures[ name ];
  144. };
  145. var loader = new THREE.MaterialLoader();
  146. for ( var i = 0, l = json.length; i < l; i ++ ) {
  147. var data = json[ i ];
  148. var material = loader.parse( data );
  149. material.uuid = data.uuid;
  150. if ( data.name !== undefined ) material.name = data.name;
  151. if ( data.map !== undefined ) {
  152. material.map = getTexture( data.map );
  153. }
  154. if ( data.bumpMap !== undefined ) {
  155. material.bumpMap = getTexture( data.bumpMap );
  156. if ( data.bumpScale ) {
  157. material.bumpScale = new THREE.Vector2( data.bumpScale, data.bumpScale );
  158. }
  159. }
  160. if ( data.alphaMap !== undefined ) {
  161. material.alphaMap = getTexture( data.alphaMap );
  162. }
  163. if ( data.envMap !== undefined ) {
  164. material.envMap = getTexture( data.envMap );
  165. }
  166. if ( data.normalMap !== undefined ) {
  167. material.normalMap = getTexture( data.normalMap );
  168. if ( data.normalScale ) {
  169. material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale );
  170. }
  171. }
  172. if ( data.lightMap !== undefined ) {
  173. material.lightMap = getTexture( data.lightMap );
  174. }
  175. if ( data.specularMap !== undefined ) {
  176. material.specularMap = getTexture( data.specularMap );
  177. }
  178. materials[ data.uuid ] = material;
  179. }
  180. }
  181. return materials;
  182. },
  183. parseImages: function ( json, onLoad ) {
  184. var scope = this;
  185. var images = {};
  186. if ( json !== undefined && json.length > 0 ) {
  187. var manager = new THREE.LoadingManager( onLoad );
  188. var loader = new THREE.ImageLoader( manager );
  189. loader.setCrossOrigin( this.crossOrigin );
  190. var loadImage = function ( url ) {
  191. scope.manager.itemStart( url );
  192. return loader.load( url, function () {
  193. scope.manager.itemEnd( url );
  194. } );
  195. };
  196. for ( var i = 0, l = json.length; i < l; i ++ ) {
  197. var image = json[ i ];
  198. var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.texturePath + image.url;
  199. images[ image.uuid ] = loadImage( path );
  200. }
  201. }
  202. return images;
  203. },
  204. parseTextures: function ( json, images ) {
  205. var textures = {};
  206. if ( json !== undefined ) {
  207. for ( var i = 0, l = json.length; i < l; i ++ ) {
  208. var data = json[ i ];
  209. if ( data.image === undefined ) {
  210. THREE.warn( 'THREE.ObjectLoader: No "image" speficied for', data.uuid );
  211. }
  212. if ( images[ data.image ] === undefined ) {
  213. THREE.warn( 'THREE.ObjectLoader: Undefined image', data.image );
  214. }
  215. var texture = new THREE.Texture( images[ data.image ] );
  216. texture.needsUpdate = true;
  217. texture.uuid = data.uuid;
  218. if ( data.name !== undefined ) texture.name = data.name;
  219. if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
  220. if ( data.minFilter !== undefined ) texture.minFilter = THREE[ data.minFilter ];
  221. if ( data.magFilter !== undefined ) texture.magFilter = THREE[ data.magFilter ];
  222. if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
  223. if ( data.wrap instanceof Array ) {
  224. texture.wrapS = THREE[ data.wrap[ 0 ] ];
  225. texture.wrapT = THREE[ data.wrap[ 1 ] ];
  226. }
  227. textures[ data.uuid ] = texture;
  228. }
  229. }
  230. return textures;
  231. },
  232. parseObject: function () {
  233. var matrix = new THREE.Matrix4();
  234. return function ( data, geometries, materials ) {
  235. var object;
  236. var getGeometry = function ( name ) {
  237. if ( geometries[ name ] === undefined ) {
  238. THREE.warn( 'THREE.ObjectLoader: Undefined geometry', name );
  239. }
  240. return geometries[ name ];
  241. };
  242. var getMaterial = function ( name ) {
  243. if ( materials[ name ] === undefined ) {
  244. THREE.warn( 'THREE.ObjectLoader: Undefined material', name );
  245. }
  246. return materials[ name ];
  247. };
  248. switch ( data.type ) {
  249. case 'Scene':
  250. object = new THREE.Scene();
  251. break;
  252. case 'PerspectiveCamera':
  253. object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
  254. break;
  255. case 'OrthographicCamera':
  256. object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
  257. break;
  258. case 'AmbientLight':
  259. object = new THREE.AmbientLight( data.color );
  260. break;
  261. case 'DirectionalLight':
  262. object = new THREE.DirectionalLight( data.color, data.intensity );
  263. break;
  264. case 'PointLight':
  265. object = new THREE.PointLight( data.color, data.intensity, data.distance, data.decay );
  266. break;
  267. case 'SpotLight':
  268. object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay );
  269. break;
  270. case 'HemisphereLight':
  271. object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity );
  272. break;
  273. case 'Mesh':
  274. object = new THREE.Mesh( getGeometry( data.geometry ), getMaterial( data.material ) );
  275. break;
  276. case 'Line':
  277. object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
  278. break;
  279. case 'PointCloud':
  280. object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) );
  281. break;
  282. case 'Sprite':
  283. object = new THREE.Sprite( getMaterial( data.material ) );
  284. break;
  285. case 'Group':
  286. object = new THREE.Group();
  287. break;
  288. default:
  289. object = new THREE.Object3D();
  290. }
  291. object.uuid = data.uuid;
  292. if ( data.name !== undefined ) object.name = data.name;
  293. if ( data.matrix !== undefined ) {
  294. matrix.fromArray( data.matrix );
  295. matrix.decompose( object.position, object.quaternion, object.scale );
  296. } else {
  297. if ( data.position !== undefined ) object.position.fromArray( data.position );
  298. if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
  299. if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
  300. }
  301. if ( data.visible !== undefined ) object.visible = data.visible;
  302. if ( data.userData !== undefined ) object.userData = data.userData;
  303. if ( data.children !== undefined ) {
  304. for ( var child in data.children ) {
  305. object.add( this.parseObject( data.children[ child ], geometries, materials ) );
  306. }
  307. }
  308. if (data.castShadow !== undefined) object.castShadow = data.castShadow;
  309. if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow;
  310. return object;
  311. }
  312. }()
  313. };