Sidebar.Project.Image.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import * as THREE from 'three';
  2. import { UIBreak, UIButton, UIInteger, UIPanel, UIRow, UISelect, UIText } from './libs/ui.js';
  3. import { ViewportPathtracer } from './Viewport.Pathtracer.js';
  4. function SidebarProjectImage( editor ) {
  5. const strings = editor.strings;
  6. const container = new UIPanel();
  7. container.setId( 'render' );
  8. // Image
  9. container.add( new UIText( strings.getKey( 'sidebar/project/image' ) ).setTextTransform( 'uppercase' ) );
  10. container.add( new UIBreak(), new UIBreak() );
  11. // Shading
  12. const shadingRow = new UIRow();
  13. // container.add( shadingRow );
  14. shadingRow.add( new UIText( strings.getKey( 'sidebar/project/shading' ) ).setClass( 'Label' ) );
  15. const shadingTypeSelect = new UISelect().setOptions( {
  16. 0: 'Solid',
  17. 1: 'Realistic'
  18. } ).setWidth( '125px' );
  19. shadingTypeSelect.setValue( 0 );
  20. shadingRow.add( shadingTypeSelect );
  21. // Resolution
  22. const resolutionRow = new UIRow();
  23. container.add( resolutionRow );
  24. resolutionRow.add( new UIText( strings.getKey( 'sidebar/project/resolution' ) ).setClass( 'Label' ) );
  25. const imageWidth = new UIInteger( 1024 ).setTextAlign( 'center' ).setWidth( '28px' );
  26. resolutionRow.add( imageWidth );
  27. resolutionRow.add( new UIText( '×' ).setTextAlign( 'center' ).setFontSize( '12px' ).setWidth( '12px' ) );
  28. const imageHeight = new UIInteger( 1024 ).setTextAlign( 'center' ).setWidth( '28px' );
  29. resolutionRow.add( imageHeight );
  30. // Render
  31. const renderButton = new UIButton( strings.getKey( 'sidebar/project/render' ) );
  32. renderButton.setWidth( '170px' );
  33. renderButton.setMarginLeft( '120px' );
  34. renderButton.onClick( async () => {
  35. const json = editor.toJSON();
  36. const project = json.project;
  37. //
  38. const loader = new THREE.ObjectLoader();
  39. const camera = loader.parse( json.camera );
  40. camera.aspect = imageWidth.getValue() / imageHeight.getValue();
  41. camera.updateProjectionMatrix();
  42. camera.updateMatrixWorld();
  43. const scene = loader.parse( json.scene );
  44. const renderer = new THREE.WebGLRenderer( { antialias: true } );
  45. renderer.setSize( imageWidth.getValue(), imageHeight.getValue() );
  46. if ( project.shadows !== undefined ) renderer.shadowMap.enabled = project.shadows;
  47. if ( project.shadowType !== undefined ) renderer.shadowMap.type = project.shadowType;
  48. if ( project.toneMapping !== undefined ) renderer.toneMapping = project.toneMapping;
  49. if ( project.toneMappingExposure !== undefined ) renderer.toneMappingExposure = project.toneMappingExposure;
  50. // popup
  51. const width = imageWidth.getValue() / window.devicePixelRatio;
  52. const height = imageHeight.getValue() / window.devicePixelRatio;
  53. const left = ( screen.width - width ) / 2;
  54. const top = ( screen.height - height ) / 2;
  55. const output = window.open( '', '_blank', `location=no,left=${left},top=${top},width=${width},height=${height}` );
  56. const meta = document.createElement( 'meta' );
  57. meta.name = 'viewport';
  58. meta.content = 'width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0';
  59. output.document.head.appendChild( meta );
  60. output.document.body.style.background = '#000';
  61. output.document.body.style.margin = '0px';
  62. output.document.body.style.overflow = 'hidden';
  63. const canvas = renderer.domElement;
  64. canvas.style.width = width + 'px';
  65. canvas.style.height = height + 'px';
  66. output.document.body.appendChild( canvas );
  67. //
  68. switch ( Number( shadingTypeSelect.getValue() ) ) {
  69. case 0: // SOLID
  70. renderer.render( scene, camera );
  71. renderer.dispose();
  72. break;
  73. /*
  74. case 1: // REALISTIC
  75. const status = document.createElement( 'div' );
  76. status.style.position = 'absolute';
  77. status.style.top = '10px';
  78. status.style.left = '10px';
  79. status.style.color = 'white';
  80. status.style.fontFamily = 'system-ui';
  81. status.style.fontSize = '12px';
  82. output.document.body.appendChild( status );
  83. const pathtracer = new ViewportPathtracer( renderer );
  84. pathtracer.init( scene, camera );
  85. pathtracer.setSize( imageWidth.getValue(), imageHeight.getValue());
  86. function animate() {
  87. if ( output.closed === true ) return;
  88. requestAnimationFrame( animate );
  89. pathtracer.update();
  90. // status.textContent = Math.floor( samples );
  91. }
  92. animate();
  93. break;
  94. */
  95. }
  96. } );
  97. container.add( renderButton );
  98. //
  99. return container;
  100. }
  101. export { SidebarProjectImage };