Editor.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. var Editor = function ( scene ) {
  2. this.geometries = {};
  3. this.materials = {};
  4. this.textures = {};
  5. this.objects = {};
  6. this.selected = {};
  7. this.helpers = {};
  8. this.scene = new THREE.Scene();
  9. this.scene.name = ( scene && scene.name ) ? scene.name : 'Scene';
  10. this.addObject( this.scene );
  11. this.sceneHelpers = new THREE.Scene();
  12. this.defaultMaterial = new THREE.MeshPhongMaterial();
  13. this.defaultMaterial.name = 'Default Material';
  14. this.addMaterial( this.defaultMaterial );
  15. }
  16. Editor.prototype = {
  17. // Assets
  18. setScene: function( scene ) {
  19. this.deleteAll(); // WARNING! deletes everything
  20. if ( scene ) {
  21. this.scene.name = scene.name ? scene.name : 'Scene';
  22. this.scene.userData = JSON.parse( JSON.stringify( scene.userData ) );
  23. if ( scene.children.length ) this.addObject( scene.children );
  24. }
  25. signals.sceneChanged.dispatch( this.scene );
  26. return this.scene
  27. },
  28. createObject: function( type, parameters, material ) {
  29. type = type ? type.toLowerCase() : null;
  30. var object;
  31. var geometry;
  32. material = material ? material : this.defaultMaterial;
  33. parameters = parameters ? parameters : {};
  34. var color = parameters.color ? parameters.color : null;
  35. var groundColor = parameters.groundColor ? parameters.groundColor : null;
  36. var intensity = parameters.intensity ? parameters.intensity : null;
  37. var distance = parameters.distance ? parameters.distance : null;
  38. var angle = parameters.angle ? parameters.angle : null;
  39. var exponent = parameters.exponent ? parameters.exponent : null;
  40. if ( !type ) {
  41. object = new THREE.Object3D();
  42. object.name = parameters.name ? parameters.name : 'Group ' + object.id;
  43. } else if ( type == 'plane' ) {
  44. geometry = this.createGeometry( type, parameters );
  45. object = new THREE.Mesh( geometry, this.defaultMaterial );
  46. object.name = name ? name : type + object.id;
  47. object.rotation.x = - Math.PI/2;
  48. } else if ( type == 'cube' ) {
  49. geometry = this.createGeometry( type, parameters );
  50. object = new THREE.Mesh( geometry, this.defaultMaterial );
  51. object.name = name ? name : type + object.id;
  52. } else if ( type == 'cylinder' ) {
  53. geometry = this.createGeometry( type, parameters );
  54. object = new THREE.Mesh( geometry, this.defaultMaterial );
  55. object.name = name ? name : type + object.id;
  56. } else if ( type == 'sphere' ) {
  57. geometry = this.createGeometry( type, parameters );
  58. object = new THREE.Mesh( geometry, this.defaultMaterial );
  59. object.name = name ? name : type + object.id;
  60. } else if ( type == 'icosahedron' ) {
  61. geometry = this.createGeometry( type, parameters );
  62. object = new THREE.Mesh( geometry, this.defaultMaterial );
  63. object.name = name ? name : type + object.id;
  64. } else if ( type == 'torus' ) {
  65. geometry = this.createGeometry( type, parameters );
  66. object = new THREE.Mesh( geometry, this.defaultMaterial );
  67. object.name = name ? name : type + object.id;
  68. } else if ( type == 'torusknot' ) {
  69. geometry = this.createGeometry( type, parameters );
  70. object = new THREE.Mesh( geometry, this.defaultMaterial );
  71. object.name = name ? name : type + object.id;
  72. } else if ( type == 'pointlight' ) {
  73. color = color ? color : 0xffffff;
  74. intensity = intensity ? intensity : 1;
  75. distance = distance ? distance : 0;
  76. var object = new THREE.PointLight( color, intensity, distance );
  77. object.name = name ? name : 'PointLight ' + object.id;
  78. } else if ( type == 'spotlight' ) {
  79. color = color ? color : 0xffffff;
  80. intensity = intensity ? intensity : 1;
  81. distance = distance ? distance : 0;
  82. angle = angle ? angle : Math.PI * 0.1;
  83. exponent = exponent ? exponent : 10;
  84. var object = new THREE.SpotLight( color, intensity, distance, angle, exponent );
  85. object.name = name ? name : 'SpotLight ' + object.id;
  86. object.target.name = object.name + ' Target';
  87. object.position.set( 0, 1, 0 ).multiplyScalar( 200 );
  88. } else if ( type == 'directionallight' ) {
  89. color = color ? color : 0xffffff;
  90. intensity = intensity ? intensity : 1;
  91. var object = new THREE.DirectionalLight( color, intensity );
  92. object.name = name ? name : 'DirectionalLight ' + object.id;
  93. object.target.name = object.name + ' Target';
  94. object.position.set( 1, 1, 1 ).multiplyScalar( 200 );
  95. } else if ( type == 'hemispherelight' ) {
  96. color = color ? color : 0x00aaff;
  97. groundColor = groundColor ? groundColor : 0xffaa00;
  98. intensity = intensity ? intensity : 1;
  99. var object = new THREE.HemisphereLight( color, groundColor, intensity );
  100. object.name = name ? name : 'HemisphereLight ' + object.id;
  101. object.position.set( 1, 1, 1 ).multiplyScalar( 200 );
  102. } else if ( type == 'ambientlight' ) {
  103. color = color ? color : 0x222222;
  104. var object = new THREE.AmbientLight( color );
  105. object.name = name ? name : 'AmbientLight ' + object.id;
  106. }
  107. if ( object ) this.addObject( object );
  108. return object;
  109. },
  110. createGeometry: function( type, parameters ) {
  111. type = type ? type : null;
  112. parameters = parameters ? parameters : {};
  113. var name = parameters.name ? parameters.name : type + 'Geometry';
  114. var width = parameters.width ? parameters.width : null;
  115. var height = parameters.height ? parameters.height : null;
  116. var depth = parameters.depth ? parameters.depth : null;
  117. var widthSegments = parameters.widthSegments ? parameters.widthSegments : null;
  118. var heightSegments = parameters.heightSegments ? parameters.heightSegments : null;
  119. var depthSegments = parameters.depthSegments ? parameters.depthSegments : null;
  120. var radialSegments = parameters.radialSegments ? parameters.radialSegments : null;
  121. var tubularSegments = parameters.tubularSegments ? parameters.tubularSegments : null;
  122. var radius = parameters.radius ? parameters.radius : null;
  123. var radiusTop = parameters.radiusTop ? parameters.radiusTop : null;
  124. var radiusBottom = parameters.radiusBottom ? parameters.radiusBottom : null;
  125. var phiStart = parameters.phiStart ? parameters.phiStart : null;
  126. var phiLength = parameters.phiLength ? parameters.phiLength : null;
  127. var thetaStart = parameters.thetaStart ? parameters.thetaStart : null;
  128. var thetaLength = parameters.thetaLength ? parameters.thetaLength : null;
  129. var tube = parameters.tube ? parameters.tube : null;
  130. var arc = parameters.arc ? parameters.arc : null;
  131. var detail = parameters.detail ? parameters.detail : null;
  132. var p = parameters.p ? parameters.p : null;
  133. var q = parameters.q ? parameters.q : null;
  134. var heightScale = parameters.heightScale ? parameters.heightScale : null;
  135. var openEnded = parameters.openEnded ? parameters.openEnded : false;
  136. var geometry;
  137. if ( !type ) {
  138. geometry = new THREE.Geometry();
  139. } else if ( type == 'plane' ) {
  140. width = width ? width : 200;
  141. height = height ? height : 200;
  142. widthSegments = widthSegments ? widthSegments : 1;
  143. heightSegments = heightSegments ? heightSegments : 1;
  144. geometry = new THREE.PlaneGeometry( width, height, widthSegments, heightSegments );
  145. } else if ( type == 'cube' ) {
  146. width = width ? width : 100;
  147. height = height ? height : 100;
  148. depth = depth ? depth : 100;
  149. widthSegments = widthSegments ? widthSegments : 1;
  150. heightSegments = heightSegments ? heightSegments : 1;
  151. depthSegments = depthSegments ? depthSegments : 1;
  152. geometry = new THREE.CubeGeometry( width, height, depth, widthSegments, heightSegments, depthSegments );
  153. } else if ( type == 'cylinder' ) {
  154. radiusTop = radiusTop ? radiusTop : 20;
  155. radiusBottom = radiusBottom ? radiusBottom : 20;
  156. height = height ? height : 100;
  157. radialSegments = radialSegments ? radialSegments : 8;
  158. heightSegments = heightSegments ? heightSegments : 1;
  159. openEnded = openEnded ? openEnded : false;
  160. geometry = new THREE.CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded );
  161. } else if ( type == 'sphere' ) {
  162. radius = radius ? radius : 75;
  163. widthSegments = widthSegments ? widthSegments : 32;
  164. heightSegments = heightSegments ? heightSegments : 16;
  165. widthSegments = widthSegments ? widthSegments : 32;
  166. heightSegments = heightSegments ? heightSegments : 16;
  167. phiStart = phiStart ? phiStart : 0;
  168. phiLength = phiLength ? phiLength : Math.PI * 2;
  169. thetaStart = thetaStart ? thetaStart : 0;
  170. thetaLength = thetaLength ? thetaLength : Math.PI;
  171. geometry = new THREE.SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength );
  172. } else if ( type == 'icosahedron' ) {
  173. radius = radius ? radius : 75;
  174. detail = detail ? detail : 2;
  175. geometry = new THREE.IcosahedronGeometry ( radius, detail );
  176. } else if ( type == 'torus' ) {
  177. radius = radius ? radius : 100;
  178. tube = tube ? tube : 40;
  179. radialSegments = radialSegments ? radialSegments : 8;
  180. tubularSegments = tubularSegments ? tubularSegments : 6;
  181. arc = arc ? arc : Math.PI * 2;
  182. geometry = new THREE.TorusGeometry( radius, tube, radialSegments, tubularSegments, arc );
  183. } else if ( type == 'torusknot' ) {
  184. radius = radius ? radius : 100;
  185. tube = tube ? tube : 40;
  186. radialSegments = radialSegments ? radialSegments : 64;
  187. tubularSegments = tubularSegments ? tubularSegments : 8;
  188. p = p ? p : 2;
  189. q = q ? q : 3;
  190. heightScale = heightScale ? heightScale : 1;
  191. geometry = new THREE.TorusKnotGeometry( radius, tube, radialSegments, tubularSegments, p, q, heightScale );
  192. }
  193. geometry.name = name;
  194. geometry.computeBoundingSphere();
  195. return geometry;
  196. },
  197. createMaterial: function( type, parameters ) {
  198. var material;
  199. type = type ? type.toLowerCase() : 'phong';
  200. parameters = parameters ? parameters : {};
  201. var name = parameters.name ? parameters.name : null;
  202. if ( type == 'phong' ) {
  203. material = new THREE.MeshPhongMaterial( parameters );
  204. material.name = name ? name : 'Phong Material ' + material.id;
  205. } else if ( type == 'lambert' ) {
  206. material = new THREE.MeshLambertMaterial( parameters );
  207. material.name = name ? name : 'Lambert Material ' + material.id;
  208. } else if ( type == 'normal' ) {
  209. material = new THREE.MeshNormalMaterial( parameters );
  210. material.name = name ? name : 'Normal Material ' + material.id;
  211. } else if ( type == 'basic' ) {
  212. material = new THREE.MeshBasicMaterial( parameters );
  213. material.name = name ? name : 'Basic Material ' + material.id;
  214. }
  215. if ( material ) this.addMaterial( material );
  216. return material;
  217. },
  218. createTexture: function( image, parameters ) {
  219. image = image ? image : '../examples/textures/ash_uvgrid01.jpg';
  220. parameters = parameters ? parameters : {};
  221. // TODO: implement parameters
  222. var texture = THREE.ImageUtils.loadTexture( image );
  223. texture.name = parameters.name ? parameters.name : 'Texture ' + texture.id;
  224. this.addTexture( texture );
  225. return texture;
  226. },
  227. addObject: function( list, parent ) {
  228. list = ( list instanceof Array ) ? [].concat( list ) : [ list ];
  229. parent = parent ? parent : this.scene;
  230. for ( var i in list ) {
  231. if ( !list[ i ].uuid ) list[ i ].uuid = this.uuid();
  232. this.objects[ list[ i ].uuid ] = list[ i ];
  233. this.addHelper( list[ i ] );
  234. if ( list[ i ].target ) {
  235. if ( !list[ i ].target.uuid ) list[ i ].target.uuid = this.uuid();
  236. this.objects[ list[ i ].target.uuid ] = list[ i ].target;
  237. }
  238. if ( list[ i ].material ) this.addMaterial( list[ i ].material );
  239. if ( list[ i ].geometry ) this.addGeometry( list[ i ].geometry );
  240. if ( parent != list[ i ] ) {
  241. // Add object to the scene
  242. parent.add( list[ i ] );
  243. if ( list[ i ] instanceof THREE.Light ) this.updateMaterials();
  244. signals.objectAdded.dispatch( list[ i ] );
  245. // Continue adding children
  246. if ( list[ i ].children && list[ i ].children.length ) {
  247. this.addObject( list[ i ].children, list[ i ] );
  248. }
  249. }
  250. }
  251. signals.sceneChanged.dispatch( this.scene );
  252. },
  253. addHelper: function( object ) {
  254. if ( object instanceof THREE.PointLight ) {
  255. this.helpers[ object.uuid ] = new THREE.PointLightHelper( object, 10 );
  256. this.sceneHelpers.add( this.helpers[ object.uuid ] );
  257. this.helpers[ object.uuid ].lightSphere.uuid = object.uuid;
  258. } else if ( object instanceof THREE.DirectionalLight ) {
  259. this.helpers[ object.uuid ] = new THREE.DirectionalLightHelper( object, 10 );
  260. this.sceneHelpers.add( this.helpers[ object.uuid ] );
  261. this.helpers[ object.uuid ].lightSphere.uuid = object.uuid;
  262. } else if ( object instanceof THREE.SpotLight ) {
  263. this.helpers[ object.uuid ] = new THREE.SpotLightHelper( object, 10 );
  264. this.sceneHelpers.add( this.helpers[ object.uuid ] );
  265. this.helpers[ object.uuid ].lightSphere.uuid = object.uuid;
  266. } else if ( object instanceof THREE.HemisphereLight ) {
  267. this.helpers[ object.uuid ] = new THREE.HemisphereLightHelper( object, 10 );
  268. this.sceneHelpers.add( this.helpers[ object.uuid ] );
  269. this.helpers[ object.uuid ].lightSphere.uuid = object.uuid;
  270. }
  271. },
  272. deleteHelper: function( object ) {
  273. if ( this.helpers[ object.uuid ] ) {
  274. this.helpers[ object.uuid ].parent.remove( this.helpers[ object.uuid ] );
  275. delete this.helpers[ object.uuid ];
  276. }
  277. },
  278. addGeometry: function( geometry ) {
  279. if (!geometry.uuid) geometry.uuid = this.uuid();
  280. this.geometries[ geometry.uuid ] = geometry;
  281. signals.geometryAdded.dispatch( geometry );
  282. },
  283. addMaterial: function( material ) {
  284. if ( material.name == 'Default Material' ) {
  285. this.delete( this.defaultMaterial );
  286. this.defaultMaterial = material;
  287. }
  288. if (!material.uuid) material.uuid = this.uuid();
  289. this.materials[ material.uuid ] = material;
  290. signals.materialAdded.dispatch( material );
  291. },
  292. addTexture: function( texture ) {
  293. if (!texture.uuid) texture.uuid = this.uuid();
  294. this.textures[ texture.uuid ] = texture;
  295. signals.textureAdded.dispatch( texture );
  296. },
  297. // Selection
  298. select: function( list, additive ) {
  299. //TODO toggle
  300. list = ( list instanceof Array ) ? list : [ list ];
  301. if ( !additive ) this.selected = {};
  302. for ( var i in list ) {
  303. this.selected[ list[ i ].uuid ] = list[ i ];
  304. }
  305. signals.selected.dispatch( this.selected );
  306. },
  307. selectByUuid: function( uuid, additive ) {
  308. var list = this.list();
  309. if ( !additive ) this.selected = {};
  310. for ( var i in list ) {
  311. if ( list[ i ].uuid == uuid ) this.select( list[ i ], true );
  312. }
  313. },
  314. selectByName: function( name, type, additive ) {
  315. type = type ? type : "all";
  316. this.select( this.listByName( name, type ), additive );
  317. },
  318. selectAll: function( type, additive ) {
  319. type = type ? type : "all";
  320. this.select( this.listByName( '*', type ), additive );
  321. },
  322. deselect: function( list ) {
  323. list = ( list instanceof Array ) ? list : [ list ];
  324. for ( var i in list ) {
  325. if ( this.selected[ list[ i ].uuid ] ) delete this.selected[ list[ i ].uuid ];
  326. }
  327. signals.selected.dispatch( this.selected );
  328. },
  329. deselectByUuid: function( uuid ) {
  330. if ( this.selected[ uuid ] ) delete this.selected[ uuid ];
  331. },
  332. deselectByName: function( name, type ) {
  333. type = type ? type : "all";
  334. this.deselect( this.listByName( name, type ) );
  335. },
  336. deselectAll: function( type ) {
  337. type = type ? type : "all";
  338. this.deselect( this.list( "all" ) );
  339. },
  340. pickWalk: function( direction ) {
  341. direction = direction.toLowerCase();
  342. var selection = this.listSelected();
  343. var newSelection = [];
  344. if ( direction === 'up' ) {
  345. for ( var i in selection ) {
  346. if ( selection[ i ].parent )
  347. newSelection.push( selection[ i ].parent );
  348. else newSelection.push( selection[ i ] );
  349. }
  350. } else if ( direction === 'down' ) {
  351. for ( var i in selection ) {
  352. if ( selection[ i ].children && selection[ i ].children.length )
  353. newSelection.push( selection[ i ].children[0] );
  354. else newSelection.push( selection[ i ] );
  355. }
  356. } else if ( direction === 'left' || direction === 'right' ) {
  357. for ( var i in selection ) {
  358. var siblings = null;
  359. var index = null;
  360. var newIndex = null;
  361. if ( selection[ i ].parent ) {
  362. siblings = selection[ i ].parent.children;
  363. index = selection[ i ].parent.children.indexOf( selection[ i ] );
  364. newIndex = index;
  365. if ( siblings.length > 1 && direction === 'left' )
  366. newIndex = ( index + siblings.length + 1 ) % siblings.length;
  367. else if ( siblings.length > 1 && direction === 'right' )
  368. newIndex = ( index + siblings.length - 1 ) % siblings.length;
  369. newSelection.push( siblings[ newIndex ] );
  370. } else {
  371. newSelection.push( selection[ i ] );
  372. }
  373. }
  374. }
  375. if ( newSelection.length ) this.select( newSelection );
  376. },
  377. // List
  378. list: function( type ) {
  379. type = type ? type : "all";
  380. var list = this.listByName( '*', type );
  381. return list;
  382. },
  383. listSelected: function( type ) {
  384. var list = this.listByName( '*', 'selected' );
  385. if ( type ) {
  386. var typeList = this.listByName( '*', type );
  387. var list = list.filter(function(n) {
  388. if(typeList.indexOf(n) == -1) return false;
  389. return true;
  390. });
  391. }
  392. return list;
  393. },
  394. listByName: function( name, type ) {
  395. type = type ? type.toLowerCase() : "all";
  396. var scope = this;
  397. var list = [];
  398. function listFromMap( map, name ) {
  399. for ( var uuid in map ) {
  400. if ( scope.regexMatch( map[ uuid ].name, name ) ) {
  401. list.push( map[ uuid ] );
  402. }
  403. }
  404. }
  405. if ( type == 'all' || type == 'object' ) {
  406. listFromMap( this.objects, name );
  407. }
  408. if ( type == 'all' || type == 'geometry' ) {
  409. listFromMap( this.geometries, name );
  410. }
  411. if ( type == 'all' || type == 'material' ) {
  412. listFromMap( this.materials, name );
  413. }
  414. if ( type == 'all' || type == 'texture' ) {
  415. listFromMap( this.textures, name );
  416. }
  417. if ( type == 'all' || type == 'selected' ) {
  418. listFromMap( this.selected, name );
  419. }
  420. return list;
  421. },
  422. // Delete
  423. delete: function( list ) {
  424. list = list ? list : this.list( 'selected' );
  425. list = ( list instanceof Array ) ? list : [ list ];
  426. this.deselect( list );
  427. var deletedObjects = {};
  428. for ( var i in list ) {
  429. if ( this.objects[ list[ i ].uuid ] && list[ i ] != this.scene ) {
  430. delete this.objects[ list[ i ].uuid ];
  431. this.deleteHelper( list[ i ] );
  432. deletedObjects[ list[ i ].uuid ] = list[ i ];
  433. if ( list[ i ] instanceof THREE.Light ) this.updateMaterials();
  434. signals.objectDeleted.dispatch();
  435. if ( list[ i ].children.length ) this.delete( list[ i ].children );
  436. }
  437. if ( this.geometries[ list[ i ].uuid ] ) {
  438. delete this.geometries[ list[ i ].uuid ];
  439. signals.objectDeleted.dispatch();
  440. }
  441. if ( this.materials[ list[ i ].uuid ] ) {
  442. delete this.materials[ list[ i ].uuid ];
  443. signals.materialDeleted.dispatch();
  444. }
  445. if ( this.textures[ list[ i ].uuid ] ) {
  446. delete this.textures[ list[ i ].uuid ];
  447. signals.textureDeleted.dispatch();
  448. }
  449. }
  450. for ( var i in deletedObjects ) {
  451. if ( deletedObjects[ i ].parent ) {
  452. deletedObjects[ i ].parent.remove( deletedObjects[ i ] );
  453. }
  454. }
  455. delete deletedObjects;
  456. signals.sceneChanged.dispatch( this.scene );
  457. },
  458. deleteByName: function( name, type ) {
  459. type = type ? type : "all";
  460. this.delete( this.listByName( name, type ) );
  461. },
  462. deleteAll: function( type ) {
  463. type = type ? type : 'all';
  464. this.delete( this.listByName( '*', type ) );
  465. },
  466. deleteUnused: function( type ) {
  467. // TODO: test with textures
  468. type = type ? type.toLowerCase() : 'all';
  469. var used = {};
  470. this.scene.traverse( function( object ) {
  471. used[ object.uuid ] = object;
  472. if ( object.geometry ) used[ object.geometry.uuid ] = object.geometry;
  473. if ( object.material ) {
  474. used[ object.material.uuid ] = object.material;
  475. for ( var i in object.material ){
  476. if ( object.material[ i ] instanceof THREE.Texture ) {
  477. used[ object.material[ i ].uuid ] = object.material[ i ];
  478. }
  479. }
  480. }
  481. } );
  482. if ( !type || type == 'object' ) {
  483. for ( var uuid in this.objects ) {
  484. if ( !used[ uuid ] ) this.delete( this.objects[ uuid ] );
  485. }
  486. }
  487. if ( !type || type == 'geometry' ) {
  488. for ( var uuid in this.geometries ) {
  489. if ( !used[ uuid ] ) this.delete( this.geometries[ uuid ] );
  490. }
  491. }
  492. if ( !type || type == 'material' ) {
  493. for ( var uuid in this.materials ) {
  494. if ( !used[ uuid ] ) this.delete( this.materials[ uuid ] );
  495. }
  496. }
  497. if ( !type || type == 'texture' ) {
  498. for ( var uuid in this.textures ) {
  499. if ( !used[ uuid ] ) this.delete( this.textures[ uuid ] );
  500. }
  501. }
  502. delete used;
  503. },
  504. // Hierarchy
  505. clone: function( assets, recursive, deep ) {
  506. // TODO: consider using list
  507. // TODO: Implement non-recursive and deep
  508. var assets = assets ? assets : this.selected;
  509. // recursive = recursive ? recursive : true;
  510. // deep = deep ? deep : false;
  511. var clones = {};
  512. for ( var i in assets ){
  513. if ( this.objects[ i ] ) {
  514. var clonedObject = this.objects[assets[ i ].uuid ].clone();
  515. clonedObject.traverse( function( child ) {
  516. child.name += ' Clone';
  517. } );
  518. this.addObject( clonedObject, assets[ i ].parent );
  519. clones[ clonedObject.uuid ] = clonedObject;
  520. }
  521. }
  522. return clones;
  523. },
  524. parent: function( list, parent, locked ) {
  525. //TODO: implement locked
  526. list = list ? list : this.list( 'selected' );
  527. list = ( list instanceof Array ) ? list : [ list ];
  528. parent = parent ? parent : this.scene;
  529. for ( var i in list ) {
  530. if ( list[ i ] !== parent && list[ i ] !== this.scene ) {
  531. parent.add( list[ i ] );
  532. signals.objectChanged.dispatch( list[ i ] );
  533. }
  534. }
  535. signals.sceneChanged.dispatch( this.scene );
  536. },
  537. unparent: function( list ) {
  538. this.parent( list, this.scene );
  539. },
  540. group: function( list ) {
  541. list = list ? list : this.listSelected( 'objects' );
  542. list = ( list instanceof Array ) ? list : [ list ];
  543. var parent = ( list.length && list[0].parent ) ? list[0].parent : this.scene;
  544. var group = this.createObject();
  545. this.parent( group, parent );
  546. console.log(group);
  547. this.parent( list, group );
  548. },
  549. // Utils
  550. updateObject: function( object, parameters ) {
  551. parameters = parameters ? parameters : {};
  552. if ( parameters.parent && object.parent && object.parent != parameters.parent)
  553. editor.parent( object, parameters.parent );
  554. if ( parameters.geometry && object.geometry && object.geometry != parameters.geometry) {
  555. object.geometry = parameters.geometry;
  556. this.updateGeometry( object.geometry );
  557. }
  558. if ( parameters.material && object.material && object.material != parameters.material)
  559. object.material = parameters.material;
  560. if ( parameters.name !== undefined ) object.name = parameters.name;
  561. if ( parameters.position !== undefined ) object.position = parameters.position;
  562. if ( parameters.rotation !== undefined ) object.rotation = parameters.rotation;
  563. if ( parameters.scale !== undefined ) object.scale = parameters.scale;
  564. if ( object.fov !== undefined && parameters.fov !== undefined ) object.fov = parameters.fov;
  565. if ( object.near !== undefined && parameters.near !== undefined ) object.near = parameters.near;
  566. if ( object.far !== undefined && parameters.far !== undefined ) object.far = parameters.far;
  567. if ( object.intensity !== undefined && parameters.intensity !== undefined ) object.intensity = parameters.intensity;
  568. if ( object.color && parameters.color !== undefined ) object.color.setHex( parameters.color );
  569. if ( object.groundColor && parameters.groundColor !== undefined ) object.groundColor.setHex( parameters.groundColor );
  570. if ( object.distance !== undefined && parameters.distance !== undefined ) object.distance = parameters.distance;
  571. if ( object.angle !== undefined && parameters.angle !== undefined ) object.angle = parameters.angle;
  572. if ( object.exponent !== undefined && parameters.exponent !== undefined ) object.exponent = parameters.exponent;
  573. if ( object.visible !== undefined && parameters.visible !== undefined ) object.visible = parameters.visible;
  574. if ( parameters.userData !== undefined ) {
  575. try {
  576. object.userData = JSON.parse( parameters.userData );
  577. } catch ( error ) {
  578. console.log( error );
  579. }
  580. };
  581. if ( object.updateProjectionMatrix ) object.updateProjectionMatrix();
  582. signals.objectChanged.dispatch( object );
  583. },
  584. updateMaterials: function( list ) {
  585. list = list ? list : this.list( 'material' );
  586. list = ( list instanceof Array ) ? list : [ list ];
  587. for ( var i in list ) {
  588. list[ i ].needsUpdate = true;
  589. if ( list[ i ] instanceof THREE.MeshFaceMaterial ) {
  590. for ( var j in list[ i ].materials ) {
  591. list[ i ].materials[ j ].needsUpdate = true;
  592. }
  593. }
  594. }
  595. },
  596. updateGeometry: function( geometry, parameters ) {
  597. parameters = parameters ? parameters : {};
  598. var uuid = geometry.uuid;
  599. var name = geometry.name;
  600. if ( geometry instanceof THREE.PlaneGeometry )
  601. geometry = this.createGeometry( 'plane', parameters );
  602. if ( geometry instanceof THREE.CubeGeometry )
  603. geometry = this.createGeometry( 'cube', parameters );
  604. if ( geometry instanceof THREE.CylinderGeometry )
  605. geometry = this.createGeometry( 'cylinder', parameters );
  606. if ( geometry instanceof THREE.SphereGeometry )
  607. geometry = this.createGeometry( 'sphere', parameters );
  608. if ( geometry instanceof THREE.IcosahedronGeometry )
  609. geometry = this.createGeometry( 'icosahedron', parameters );
  610. if ( geometry instanceof THREE.TorusGeometry )
  611. geometry = this.createGeometry( 'torus', parameters );
  612. if ( geometry instanceof THREE.TorusKnotGeometry )
  613. geometry = this.createGeometry( 'torusknot', parameters );
  614. geometry.computeBoundingSphere();
  615. geometry.uuid = uuid;
  616. geometry.name = name;
  617. for ( var i in editor.objects ) {
  618. var object = editor.objects[i];
  619. if ( object.geometry && object.geometry.uuid == uuid ) {
  620. delete object.__webglInit; // TODO: Remove hack (WebGLRenderer refactoring)
  621. object.geometry.dispose();
  622. object.geometry = geometry;
  623. signals.objectChanged.dispatch( object );
  624. }
  625. }
  626. },
  627. setFog: function( parameters ) {
  628. var fogType = parameters.fogType ? parameters.fogType : null;
  629. var near = parameters.near ? parameters.near : null;
  630. var far = parameters.far ? parameters.far : null;
  631. var density = parameters.density ? parameters.density : null;
  632. var color = parameters.color ? parameters.color : null;
  633. if ( fogType ) {
  634. if ( fogType === "None" ) this.scene.fog = null;
  635. else if ( fogType === "Fog" ) this.scene.fog = new THREE.Fog();
  636. else if ( fogType === "FogExp2" ) this.scene.fog = new THREE.FogExp2();
  637. }
  638. if ( this.scene.fog ) {
  639. if ( fogType ) this.scene.fog.fogType = fogType;
  640. if ( near ) this.scene.fog.near = near;
  641. if ( far ) this.scene.fog.far = far;
  642. if ( density ) this.scene.fog.density = density;
  643. if ( color ) this.scene.fog.color.setHex( color );
  644. }
  645. this.updateMaterials();
  646. signals.fogChanged.dispatch( this.scene.fog );
  647. },
  648. regexMatch: function( name, filter ) {
  649. name = name.toLowerCase();
  650. filter = '^' + filter.toLowerCase().replace(/\*/g, '.*').replace(/\?/g, '.') + '$';
  651. var regex = new RegExp(filter);
  652. return regex.test( name );
  653. },
  654. uuid: function() {
  655. // http://note19.com/2007/05/27/javascript-guid-generator/
  656. function s4() {
  657. return Math.floor( ( 1 + Math.random() ) * 0x10000 ).toString( 16 ).substring( 1 );
  658. };
  659. return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
  660. }
  661. }