Menubar.Edit.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import { UIPanel, UIRow, UIHorizontalRule } from './libs/ui.js';
  2. import { AddObjectCommand } from './commands/AddObjectCommand.js';
  3. import { RemoveObjectCommand } from './commands/RemoveObjectCommand.js';
  4. import { MultiCmdsCommand } from './commands/MultiCmdsCommand.js';
  5. import { SetMaterialValueCommand } from './commands/SetMaterialValueCommand.js';
  6. function MenubarEdit( editor ) {
  7. var strings = editor.strings;
  8. var container = new UIPanel();
  9. container.setClass( 'menu' );
  10. var title = new UIPanel();
  11. title.setClass( 'title' );
  12. title.setTextContent( strings.getKey( 'menubar/edit' ) );
  13. container.add( title );
  14. var options = new UIPanel();
  15. options.setClass( 'options' );
  16. container.add( options );
  17. // Undo
  18. var undo = new UIRow();
  19. undo.setClass( 'option' );
  20. undo.setTextContent( strings.getKey( 'menubar/edit/undo' ) );
  21. undo.onClick( function () {
  22. editor.undo();
  23. } );
  24. options.add( undo );
  25. // Redo
  26. var redo = new UIRow();
  27. redo.setClass( 'option' );
  28. redo.setTextContent( strings.getKey( 'menubar/edit/redo' ) );
  29. redo.onClick( function () {
  30. editor.redo();
  31. } );
  32. options.add( redo );
  33. // Clear History
  34. var option = new UIRow();
  35. option.setClass( 'option' );
  36. option.setTextContent( strings.getKey( 'menubar/edit/clear_history' ) );
  37. option.onClick( function () {
  38. if ( confirm( 'The Undo/Redo History will be cleared. Are you sure?' ) ) {
  39. editor.history.clear();
  40. }
  41. } );
  42. options.add( option );
  43. editor.signals.historyChanged.add( function () {
  44. var history = editor.history;
  45. undo.setClass( 'option' );
  46. redo.setClass( 'option' );
  47. if ( history.undos.length == 0 ) {
  48. undo.setClass( 'inactive' );
  49. }
  50. if ( history.redos.length == 0 ) {
  51. redo.setClass( 'inactive' );
  52. }
  53. } );
  54. // ---
  55. options.add( new UIHorizontalRule() );
  56. // Clone
  57. var option = new UIRow();
  58. option.setClass( 'option' );
  59. option.setTextContent( strings.getKey( 'menubar/edit/clone' ) );
  60. option.onClick( function () {
  61. var object = editor.selected;
  62. if ( object.parent === null ) return; // avoid cloning the camera or scene
  63. object = object.clone();
  64. editor.execute( new AddObjectCommand( editor, object ) );
  65. } );
  66. options.add( option );
  67. // Delete
  68. var option = new UIRow();
  69. option.setClass( 'option' );
  70. option.setTextContent( strings.getKey( 'menubar/edit/delete' ) );
  71. option.onClick( function () {
  72. var object = editor.selected;
  73. if ( object !== null && object.parent !== null ) {
  74. editor.execute( new RemoveObjectCommand( editor, object ) );
  75. }
  76. } );
  77. options.add( option );
  78. // Minify shaders
  79. var option = new UIRow();
  80. option.setClass( 'option' );
  81. option.setTextContent( strings.getKey( 'menubar/edit/minify_shaders' ) );
  82. option.onClick( function () {
  83. var root = editor.selected || editor.scene;
  84. var errors = [];
  85. var nMaterialsChanged = 0;
  86. var path = [];
  87. function getPath( object ) {
  88. path.length = 0;
  89. var parent = object.parent;
  90. if ( parent !== undefined ) getPath( parent );
  91. path.push( object.name || object.uuid );
  92. return path;
  93. }
  94. var cmds = [];
  95. root.traverse( function ( object ) {
  96. var material = object.material;
  97. if ( material !== undefined && material.isShaderMaterial ) {
  98. try {
  99. var shader = glslprep.minifyGlsl( [
  100. material.vertexShader, material.fragmentShader ] );
  101. cmds.push( new SetMaterialValueCommand( editor, object, 'vertexShader', shader[ 0 ] ) );
  102. cmds.push( new SetMaterialValueCommand( editor, object, 'fragmentShader', shader[ 1 ] ) );
  103. ++ nMaterialsChanged;
  104. } catch ( e ) {
  105. var path = getPath( object ).join( "/" );
  106. if ( e instanceof glslprep.SyntaxError )
  107. errors.push( path + ":" +
  108. e.line + ":" + e.column + ": " + e.message );
  109. else {
  110. errors.push( path +
  111. ": Unexpected error (see console for details)." );
  112. console.error( e.stack || e );
  113. }
  114. }
  115. }
  116. } );
  117. if ( nMaterialsChanged > 0 ) {
  118. editor.execute( new MultiCmdsCommand( editor, cmds ), 'Minify Shaders' );
  119. }
  120. window.alert( nMaterialsChanged +
  121. " material(s) were changed.\n" + errors.join( "\n" ) );
  122. } );
  123. options.add( option );
  124. options.add( new UIHorizontalRule() );
  125. // Set textures to sRGB. See #15903
  126. var option = new UIRow();
  127. option.setClass( 'option' );
  128. option.setTextContent( strings.getKey( 'menubar/edit/fixcolormaps' ) );
  129. option.onClick( function () {
  130. editor.scene.traverse( fixColorMap );
  131. } );
  132. options.add( option );
  133. var colorMaps = [ 'map', 'envMap', 'emissiveMap' ];
  134. function fixColorMap( obj ) {
  135. var material = obj.material;
  136. if ( material !== undefined ) {
  137. if ( Array.isArray( material ) === true ) {
  138. for ( var i = 0; i < material.length; i ++ ) {
  139. fixMaterial( material[ i ] );
  140. }
  141. } else {
  142. fixMaterial( material );
  143. }
  144. editor.signals.sceneGraphChanged.dispatch();
  145. }
  146. }
  147. function fixMaterial( material ) {
  148. var needsUpdate = material.needsUpdate;
  149. for ( var i = 0; i < colorMaps.length; i ++ ) {
  150. var map = material[ colorMaps[ i ] ];
  151. if ( map ) {
  152. map.encoding = THREE.sRGBEncoding;
  153. needsUpdate = true;
  154. }
  155. }
  156. material.needsUpdate = needsUpdate;
  157. }
  158. return container;
  159. }
  160. export { MenubarEdit };