ObjectLoader.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  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. case 'TextGeometry':
  129. geometry = new THREE.TextGeometry(
  130. data.text,
  131. data.data
  132. );
  133. break;
  134. }
  135. geometry.uuid = data.uuid;
  136. if ( data.name !== undefined ) geometry.name = data.name;
  137. geometries[ data.uuid ] = geometry;
  138. }
  139. }
  140. return geometries;
  141. },
  142. parseMaterials: function ( json, textures ) {
  143. var materials = {};
  144. if ( json !== undefined ) {
  145. var getTexture = function ( name ) {
  146. if ( textures[ name ] === undefined ) {
  147. console.warn( 'THREE.ObjectLoader: Undefined texture', name );
  148. }
  149. return textures[ name ];
  150. };
  151. var loader = new THREE.MaterialLoader();
  152. for ( var i = 0, l = json.length; i < l; i ++ ) {
  153. var data = json[ i ];
  154. var material = loader.parse( data );
  155. material.uuid = data.uuid;
  156. if ( data.depthTest !== undefined ) material.depthTest = data.depthTest;
  157. if ( data.depthWrite !== undefined ) material.depthWrite = data.depthWrite;
  158. if ( data.name !== undefined ) material.name = data.name;
  159. if ( data.map !== undefined ) material.map = getTexture( data.map );
  160. if ( data.alphaMap !== undefined ) {
  161. material.alphaMap = getTexture( data.alphaMap );
  162. material.transparent = true;
  163. }
  164. if ( data.bumpMap !== undefined ) material.bumpMap = getTexture( data.bumpMap );
  165. if ( data.bumpScale !== undefined ) material.bumpScale = data.bumpScale;
  166. if ( data.normalMap !== undefined ) material.normalMap = getTexture( data.normalMap );
  167. if ( data.normalScale ) material.normalScale = new THREE.Vector2( data.normalScale, data.normalScale );
  168. if ( data.specularMap !== undefined ) material.specularMap = getTexture( data.specularMap );
  169. if ( data.envMap !== undefined ) {
  170. material.envMap = getTexture( data.envMap );
  171. material.combine = THREE.MultiplyOperation;
  172. }
  173. if ( data.reflectivity ) material.reflectivity = data.reflectivity;
  174. if ( data.lightMap !== undefined ) material.lightMap = getTexture( data.lightMap );
  175. if ( data.lightMapIntensity !== undefined ) material.lightMapIntensity = data.lightMapIntensity;
  176. if ( data.aoMap !== undefined ) material.aoMap = getTexture( data.aoMap );
  177. if ( data.aoMapIntensity !== undefined ) material.aoMapIntensity = data.aoMapIntensity;
  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. url = scope.texturePath + url;
  192. scope.manager.itemStart( url );
  193. return loader.load( url, function () {
  194. scope.manager.itemEnd( url );
  195. } );
  196. };
  197. for ( var i = 0, l = json.length; i < l; i ++ ) {
  198. var image = json[ i ];
  199. images[ image.uuid ] = loadImage( image.url );
  200. }
  201. }
  202. return images;
  203. },
  204. parseTextures: function ( json, images ) {
  205. function parseConstant( value ) {
  206. if ( typeof( value ) === 'number' ) return value;
  207. console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
  208. return THREE[ value ];
  209. }
  210. var textures = {};
  211. if ( json !== undefined ) {
  212. for ( var i = 0, l = json.length; i < l; i ++ ) {
  213. var data = json[ i ];
  214. if ( data.image === undefined ) {
  215. console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
  216. }
  217. if ( images[ data.image ] === undefined ) {
  218. console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
  219. }
  220. var texture = new THREE.Texture( images[ data.image ] );
  221. texture.needsUpdate = true;
  222. texture.uuid = data.uuid;
  223. if ( data.name !== undefined ) texture.name = data.name;
  224. if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping );
  225. if ( data.repeat !== undefined ) texture.repeat = new THREE.Vector2( data.repeat[ 0 ], data.repeat[ 1 ] );
  226. if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter );
  227. if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter );
  228. if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;
  229. if ( Array.isArray( data.wrap ) ) {
  230. texture.wrapS = parseConstant( data.wrap[ 0 ] );
  231. texture.wrapT = parseConstant( data.wrap[ 1 ] );
  232. }
  233. textures[ data.uuid ] = texture;
  234. }
  235. }
  236. return textures;
  237. },
  238. parseObject: function () {
  239. var matrix = new THREE.Matrix4();
  240. return function ( data, geometries, materials ) {
  241. var object;
  242. var getGeometry = function ( name ) {
  243. if ( geometries[ name ] === undefined ) {
  244. console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
  245. }
  246. return geometries[ name ];
  247. };
  248. var getMaterial = function ( name ) {
  249. if ( materials[ name ] === undefined ) {
  250. console.warn( 'THREE.ObjectLoader: Undefined material', name );
  251. }
  252. return materials[ name ];
  253. };
  254. switch ( data.type ) {
  255. case 'Scene':
  256. object = new THREE.Scene();
  257. break;
  258. case 'PerspectiveCamera':
  259. object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
  260. break;
  261. case 'OrthographicCamera':
  262. object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
  263. break;
  264. case 'AmbientLight':
  265. object = new THREE.AmbientLight( data.color );
  266. break;
  267. case 'DirectionalLight':
  268. object = new THREE.DirectionalLight( data.color, data.intensity );
  269. break;
  270. case 'PointLight':
  271. object = new THREE.PointLight( data.color, data.intensity, data.distance, data.decay );
  272. break;
  273. case 'SpotLight':
  274. object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay );
  275. break;
  276. case 'HemisphereLight':
  277. object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity );
  278. break;
  279. case 'Mesh':
  280. object = new THREE.Mesh( getGeometry( data.geometry ), getMaterial( data.material ) );
  281. break;
  282. case 'Line':
  283. object = new THREE.Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
  284. break;
  285. case 'PointCloud':
  286. object = new THREE.PointCloud( getGeometry( data.geometry ), getMaterial( data.material ) );
  287. break;
  288. case 'Sprite':
  289. object = new THREE.Sprite( getMaterial( data.material ) );
  290. break;
  291. case 'Group':
  292. object = new THREE.Group();
  293. break;
  294. default:
  295. object = new THREE.Object3D();
  296. }
  297. object.uuid = data.uuid;
  298. if ( data.name !== undefined ) object.name = data.name;
  299. if ( data.matrix !== undefined ) {
  300. matrix.fromArray( data.matrix );
  301. matrix.decompose( object.position, object.quaternion, object.scale );
  302. } else {
  303. if ( data.position !== undefined ) object.position.fromArray( data.position );
  304. if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
  305. if ( data.scale !== undefined ) object.scale.fromArray( data.scale );
  306. }
  307. if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
  308. if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
  309. if ( data.visible !== undefined ) object.visible = data.visible;
  310. if ( data.userData !== undefined ) object.userData = data.userData;
  311. if ( data.children !== undefined ) {
  312. for ( var child in data.children ) {
  313. object.add( this.parseObject( data.children[ child ], geometries, materials ) );
  314. }
  315. }
  316. return object;
  317. }
  318. }()
  319. };