import * as React from "react"; import { PaneComponent, IPaneComponentProps } from "../paneComponent"; import { LineContainerComponent } from "../lineContainerComponent"; import { ButtonLineComponent } from "../lines/buttonLineComponent"; import { Node } from "babylonjs/node"; import { Nullable } from "babylonjs/types"; import { VideoRecorder } from "babylonjs/Misc/videoRecorder"; import { Tools } from "babylonjs/Misc/tools"; import { EnvironmentTextureTools } from "babylonjs/Misc/environmentTextureTools"; import { BackgroundMaterial } from "babylonjs/Materials/Background/backgroundMaterial"; import { StandardMaterial } from "babylonjs/Materials/standardMaterial"; import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial"; import { CubeTexture } from "babylonjs/Materials/Textures/cubeTexture"; import { Texture } from "babylonjs/Materials/Textures/texture"; import { SceneSerializer } from "babylonjs/Misc/sceneSerializer"; import { Mesh } from "babylonjs/Meshes/mesh"; import { GLTFComponent } from "./tools/gltfComponent"; import { GLTFData, GLTF2Export } from "babylonjs-serializers/glTF/2.0/index"; import { FloatLineComponent } from '../lines/floatLineComponent'; import { IScreenshotSize } from 'babylonjs/Misc/interfaces/screenshotSize'; import { NumericInputComponent } from '../lines/numericInputComponent'; import { CheckBoxLineComponent } from '../lines/checkBoxLineComponent'; import { TextLineComponent } from '../lines/textLineComponent'; export class ToolsTabComponent extends PaneComponent { private _videoRecorder: Nullable; private _screenShotSize: IScreenshotSize = { precision: 1 }; private _useWidthHeight = false; private _isExporting = false; constructor(props: IPaneComponentProps) { super(props); this.state = { tag: "Record video" }; } componentDidMount() { if (!(BABYLON as any).GLTF2Export) { Tools.LoadScript("https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js", () => { }); return; } } componentWillUnmount() { if (this._videoRecorder) { this._videoRecorder.stopRecording(); this._videoRecorder.dispose(); this._videoRecorder = null; } } captureScreenshot() { const scene = this.props.scene; if (scene.activeCamera) { Tools.CreateScreenshot(scene.getEngine(), scene.activeCamera, this._screenShotSize); } } captureRender() { const scene = this.props.scene; const oldScreenshotSize: IScreenshotSize = { height: this._screenShotSize.height, width: this._screenShotSize.width, precision: this._screenShotSize.precision }; if (!this._useWidthHeight) { this._screenShotSize.width = undefined; this._screenShotSize.height = undefined; } if (scene.activeCamera) { Tools.CreateScreenshotUsingRenderTarget(scene.getEngine(), scene.activeCamera, this._screenShotSize); } this._screenShotSize = oldScreenshotSize; } recordVideo() { if (this._videoRecorder && this._videoRecorder.isRecording) { this._videoRecorder.stopRecording(); return; } const scene = this.props.scene; if (!this._videoRecorder) { this._videoRecorder = new VideoRecorder(scene.getEngine()); } this._videoRecorder.startRecording().then(() => { this.setState({ tag: "Record video" }); }); this.setState({ tag: "Stop recording" }); } shouldExport(node: Node): boolean { // No skybox if (node instanceof Mesh) { if (node.material) { const material = node.material as PBRMaterial | StandardMaterial | BackgroundMaterial; const reflectionTexture = material.reflectionTexture; if (reflectionTexture && reflectionTexture.coordinatesMode === Texture.SKYBOX_MODE) { return false; } } } return true; } exportGLTF() { const scene = this.props.scene; this._isExporting = true; this.forceUpdate(); GLTF2Export.GLBAsync(scene, "scene", { shouldExportNode: (node) => this.shouldExport(node) }).then((glb: GLTFData) => { glb.downloadFiles(); this._isExporting = false; this.forceUpdate(); }).catch(reason => { this._isExporting = false; this.forceUpdate(); }); } exportBabylon() { const scene = this.props.scene; var strScene = JSON.stringify(SceneSerializer.Serialize(scene)); var blob = new Blob([strScene], { type: "octet/stream" }); Tools.Download(blob, "scene.babylon"); } createEnvTexture() { const scene = this.props.scene; EnvironmentTextureTools.CreateEnvTextureAsync(scene.environmentTexture as CubeTexture) .then((buffer: ArrayBuffer) => { var blob = new Blob([buffer], { type: "octet/stream" }); Tools.Download(blob, "environment.env"); }) .catch((error: any) => { console.error(error); alert(error); }); } resetReplay() { this.props.globalState.recorder.reset(); } exportReplay() { this.props.globalState.recorder.export(); } render() { const scene = this.props.scene; if (!scene) { return null; } return (
this.captureScreenshot()} /> this.recordVideo()} /> this.captureRender()} />
{ this._useWidthHeight = value; this.forceUpdate(); } } isSelected={() => this._useWidthHeight} /> { this._useWidthHeight &&
this._screenShotSize.width = value} /> this._screenShotSize.height = value} />
}
this.exportReplay()} /> this.resetReplay()} /> { this._isExporting && } { !this._isExporting && <> this.exportGLTF()} /> this.exportBabylon()} /> { !scene.getEngine().premultipliedAlpha && scene.environmentTexture && (scene.environmentTexture as CubeTexture).isPrefiltered && scene.activeCamera && this.createEnvTexture()} /> } } { (BABYLON as any).GLTFFileLoader && }
); } }