toolsTabComponent.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import * as React from "react";
  2. import { PaneComponent, IPaneComponentProps } from "../paneComponent";
  3. import { LineContainerComponent } from "../lineContainerComponent";
  4. import { ButtonLineComponent } from "../lines/buttonLineComponent";
  5. import { Node } from "babylonjs/node";
  6. import { Nullable } from "babylonjs/types";
  7. import { VideoRecorder } from "babylonjs/Misc/videoRecorder";
  8. import { Tools } from "babylonjs/Misc/tools";
  9. import { EnvironmentTextureTools } from "babylonjs/Misc/environmentTextureTools";
  10. import { BackgroundMaterial } from "babylonjs/Materials/Background/backgroundMaterial";
  11. import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
  12. import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial";
  13. import { CubeTexture } from "babylonjs/Materials/Textures/cubeTexture";
  14. import { Texture } from "babylonjs/Materials/Textures/texture";
  15. import { SceneSerializer } from "babylonjs/Misc/sceneSerializer";
  16. import { Mesh } from "babylonjs/Meshes/mesh";
  17. import { GLTFComponent } from "./tools/gltfComponent";
  18. import { GLTFData, GLTF2Export } from "babylonjs-serializers/glTF/2.0/index";
  19. export class ToolsTabComponent extends PaneComponent {
  20. private _videoRecorder: Nullable<VideoRecorder>;
  21. constructor(props: IPaneComponentProps) {
  22. super(props);
  23. this.state = { tag: "Record video" };
  24. }
  25. componentWillMount() {
  26. if (!(BABYLON as any).GLTF2Export) {
  27. Tools.LoadScript("https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js", () => {
  28. });
  29. return;
  30. }
  31. }
  32. componentWillUnmount() {
  33. if (this._videoRecorder) {
  34. this._videoRecorder.stopRecording();
  35. this._videoRecorder.dispose();
  36. this._videoRecorder = null;
  37. }
  38. }
  39. captureScreenshot() {
  40. const scene = this.props.scene;
  41. if (scene.activeCamera) {
  42. Tools.CreateScreenshotUsingRenderTarget(scene.getEngine(), scene.activeCamera, { precision: 1.0 }, undefined, undefined, 4, true);
  43. }
  44. }
  45. recordVideo() {
  46. if (this._videoRecorder && this._videoRecorder.isRecording) {
  47. this._videoRecorder.stopRecording();
  48. return;
  49. }
  50. const scene = this.props.scene;
  51. if (!this._videoRecorder) {
  52. this._videoRecorder = new VideoRecorder(scene.getEngine());
  53. }
  54. this._videoRecorder.startRecording().then(() => {
  55. this.setState({ tag: "Record video" });
  56. });
  57. this.setState({ tag: "Stop recording" });
  58. }
  59. shouldExport(node: Node): boolean {
  60. // No skybox
  61. if (node instanceof Mesh) {
  62. if (node.material) {
  63. const material = node.material as PBRMaterial | StandardMaterial | BackgroundMaterial;
  64. const reflectionTexture = material.reflectionTexture;
  65. if (reflectionTexture && reflectionTexture.coordinatesMode === Texture.SKYBOX_MODE) {
  66. return false;
  67. }
  68. }
  69. }
  70. return true;
  71. }
  72. exportGLTF() {
  73. const scene = this.props.scene;
  74. GLTF2Export.GLBAsync(scene, "scene", {
  75. shouldExportNode: (node) => this.shouldExport(node)
  76. }).then((glb: GLTFData) => {
  77. glb.downloadFiles();
  78. });
  79. }
  80. exportBabylon() {
  81. const scene = this.props.scene;
  82. var strScene = JSON.stringify(SceneSerializer.Serialize(scene));
  83. var blob = new Blob([strScene], { type: "octet/stream" });
  84. Tools.Download(blob, "scene.babylon");
  85. }
  86. createEnvTexture() {
  87. const scene = this.props.scene;
  88. EnvironmentTextureTools.CreateEnvTextureAsync(scene.environmentTexture as CubeTexture)
  89. .then((buffer: ArrayBuffer) => {
  90. var blob = new Blob([buffer], { type: "octet/stream" });
  91. Tools.Download(blob, "environment.env");
  92. })
  93. .catch((error: any) => {
  94. console.error(error);
  95. alert(error);
  96. });
  97. }
  98. render() {
  99. const scene = this.props.scene;
  100. if (!scene) {
  101. return null;
  102. }
  103. return (
  104. <div className="pane">
  105. <LineContainerComponent title="CAPTURE">
  106. <ButtonLineComponent label="Screenshot" onClick={() => this.captureScreenshot()} />
  107. <ButtonLineComponent label={this.state.tag} onClick={() => this.recordVideo()} />
  108. </LineContainerComponent>
  109. <LineContainerComponent title="SCENE EXPORT">
  110. <ButtonLineComponent label="Export to GLB" onClick={() => this.exportGLTF()} />
  111. <ButtonLineComponent label="Export to Babylon" onClick={() => this.exportBabylon()} />
  112. {
  113. !scene.getEngine().premultipliedAlpha && scene.environmentTexture && scene.activeCamera &&
  114. <ButtonLineComponent label="Generate .env texture" onClick={() => this.createEnvTexture()} />
  115. }
  116. </LineContainerComponent>
  117. {
  118. (BABYLON as any).GLTFFileLoader &&
  119. <GLTFComponent scene={scene} globalState={this.props.globalState!} />
  120. }
  121. </div>
  122. );
  123. }
  124. }