import * as React from "react"; import { Nullable } from "babylonjs/types"; import { Tools } from "babylonjs/Misc/tools"; import { Observable } from "babylonjs/Misc/observable"; import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture"; import { Texture } from "babylonjs/Materials/Textures/texture"; import { CubeTexture } from "babylonjs/Materials/Textures/cubeTexture"; import { PropertyChangedEvent } from "../../../../propertyChangedEvent"; import { LineContainerComponent } from "../../../lineContainerComponent"; import { SliderLineComponent } from "../../../lines/sliderLineComponent"; import { TextLineComponent } from "../../../../../sharedUiComponents/lines/textLineComponent"; import { CheckBoxLineComponent } from "../../../../../sharedUiComponents/lines/checkBoxLineComponent"; import { TextureLineComponent } from "../../../lines/textureLineComponent"; import { FloatLineComponent } from "../../../lines/floatLineComponent"; import { OptionsLineComponent } from "../../../../../sharedUiComponents/lines/optionsLineComponent"; import { FileButtonLineComponent } from "../../../../../sharedUiComponents/lines/fileButtonLineComponent"; import { LockObject } from "../lockObject"; import { ValueLineComponent } from "../../../../../sharedUiComponents/lines/valueLineComponent"; import { GlobalState } from "../../../../../components/globalState"; import { AdvancedDynamicTextureInstrumentation } from "babylonjs-gui/2D/adtInstrumentation"; import { AdvancedDynamicTexture } from "babylonjs-gui/2D/advancedDynamicTexture"; import { CustomPropertyGridComponent } from '../customPropertyGridComponent'; import { ButtonLineComponent } from '../../../../../sharedUiComponents/lines/buttonLineComponent'; import { TextInputLineComponent } from '../../../lines/textInputLineComponent'; import { AnimationGridComponent } from '../animations/animationPropertyGridComponent'; import { PopupComponent } from '../../../../popupComponent'; import { TextureEditorComponent } from './textures/textureEditorComponent'; interface ITexturePropertyGridComponentProps { texture: BaseTexture, lockObject: LockObject, globalState: GlobalState, onPropertyChangedObservable?: Observable } interface ITexturePropertyGridComponentState { isTextureEditorOpen : boolean, textureEditing : Nullable } export class TexturePropertyGridComponent extends React.Component { private _adtInstrumentation: Nullable; private popoutWindowRef : React.RefObject; private textureLineRef: React.RefObject; private _textureInspectorSize = {width: 1024, height: 490}; constructor(props: ITexturePropertyGridComponentProps) { super(props); this.state = { isTextureEditorOpen: false, textureEditing: null } const texture = this.props.texture; this.textureLineRef = React.createRef(); this.popoutWindowRef = React.createRef(); if (!texture || !(texture as any).rootContainer) { return; } const adt = texture as AdvancedDynamicTexture; this._adtInstrumentation = new AdvancedDynamicTextureInstrumentation(adt); this._adtInstrumentation!.captureRenderTime = true; this._adtInstrumentation!.captureLayoutTime = true; this.onOpenTextureEditor.bind(this); this.onCloseTextureEditor.bind(this); this.openTextureEditor.bind(this); } componentWillUnmount() { if (this._adtInstrumentation) { this._adtInstrumentation.dispose(); this._adtInstrumentation = null; } } updateTexture(file: File) { const texture = this.props.texture; Tools.ReadFile(file, (data) => { var blob = new Blob([data], { type: "octet/stream" }); var reader = new FileReader(); reader.readAsDataURL(blob); reader.onloadend = () => { let base64data = reader.result as string; if (texture.isCube) { let extension: string | undefined = undefined; if (file.name.toLowerCase().indexOf(".dds") > 0) { extension = ".dds"; } else if (file.name.toLowerCase().indexOf(".env") > 0) { extension = ".env"; } (texture as CubeTexture).updateURL(base64data, extension, () => this.forceRefresh()); } else { (texture as Texture).updateURL(base64data, null, () => this.forceRefresh()); } }; }, undefined, true); } openTextureEditor() { if (this.state.isTextureEditorOpen) { this.onCloseTextureEditor(() => this.openTextureEditor()); return; } this.setState({ isTextureEditorOpen: true, textureEditing: this.props.texture }); } onOpenTextureEditor(window: Window) {} onCloseTextureEditor(callback?: {() : void}) { this.setState({ isTextureEditorOpen: false, textureEditing: null }, callback); } forceRefresh() { this.forceUpdate(); (this.textureLineRef.current as TextureLineComponent).updatePreview(); } render() { const texture = this.props.texture; var samplingMode = [ { label: "Nearest", value: Texture.NEAREST_NEAREST }, // 1 { label: "Linear", value: Texture.LINEAR_LINEAR }, // 2 { label: "Linear & linear mip", value: Texture.LINEAR_LINEAR_MIPLINEAR }, // 3 { label: "Linear & nearest mip", value: Texture.LINEAR_LINEAR_MIPNEAREST }, // 11 { label: "Nearest & linear mip", value: Texture.NEAREST_NEAREST_MIPLINEAR }, // 8 { label: "Nearest & nearest mip", value: Texture.NEAREST_NEAREST_MIPNEAREST }, // 4 { label: "Nearest/Linear", value: Texture.NEAREST_LINEAR }, // 7 { label: "Nearest/Linear & linear mip", value: Texture.NEAREST_LINEAR_MIPLINEAR }, // 6 { label: "Nearest/Linear & nearest mip", value: Texture.NEAREST_LINEAR_MIPNEAREST }, // 5 { label: "Linear/Nearest", value: Texture.LINEAR_NEAREST }, // 12 { label: "Linear/Nearest & linear mip", value: Texture.LINEAR_NEAREST_MIPLINEAR }, // 10 { label: "Linear/Nearest & nearest mip", value: Texture.LINEAR_NEAREST_MIPNEAREST }, // 9 ]; var coordinatesMode = [ { label: "Explicit", value: Texture.EXPLICIT_MODE }, { label: "Cubic", value: Texture.CUBIC_MODE }, { label: "Inverse cubic", value: Texture.INVCUBIC_MODE }, { label: "Equirectangular", value: Texture.EQUIRECTANGULAR_MODE }, { label: "Fixed equirectangular", value: Texture.FIXED_EQUIRECTANGULAR_MODE }, { label: "Fixed equirectangular mirrored", value: Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE }, { label: "Planar", value: Texture.PLANAR_MODE }, { label: "Projection", value: Texture.PROJECTION_MODE }, { label: "Skybox", value: Texture.SKYBOX_MODE }, { label: "Spherical", value: Texture.SPHERICAL_MODE }, ]; let extension = ""; let url = (texture as Texture).url; let textureUrl = (!url || url.substring(0, 4) === "data" || url.substring(0, 4) === "blob") ? "" : url; if (textureUrl) { for (var index = textureUrl.length - 1; index >= 0; index--) { if (textureUrl[index] === ".") { break; } extension = textureUrl[index] + extension; } } return (
this.updateTexture(file)} accept=".jpg, .png, .tga, .dds, .env" /> this.openTextureEditor()} /> { (texture as Texture).updateURL(url); this.forceRefresh(); }} /> {this.state.isTextureEditorOpen && ( this.onCloseTextureEditor} ref={this.popoutWindowRef} > this.forceRefresh()} /> )} { texture.isRenderTarget && { let scene = texture.getScene()!; texture.scale(2); setTimeout(() => { this.props.globalState.onSelectionChangedObservable.notifyObservers(scene.getTextureByUniqueID(texture.uniqueId)); }); }} /> } { texture.isRenderTarget && { let scene = texture.getScene()!; texture.scale(0.5); setTimeout(() => { this.props.globalState.onSelectionChangedObservable.notifyObservers(scene.getTextureByUniqueID(texture.uniqueId)); }); }} /> } { extension && } { (texture instanceof Texture) && } texture.coordinatesMode = value} /> { texture.updateSamplingMode && texture.updateSamplingMode(value)} /> } { texture.getScene() && } { (texture as any).rootContainer && this._adtInstrumentation && } { !texture.isCube &&
texture.wrapU === Texture.CLAMP_ADDRESSMODE} onSelect={(value) => texture.wrapU = value ? Texture.CLAMP_ADDRESSMODE : Texture.WRAP_ADDRESSMODE} /> texture.wrapV === Texture.CLAMP_ADDRESSMODE} onSelect={(value) => texture.wrapV = value ? Texture.CLAMP_ADDRESSMODE : Texture.WRAP_ADDRESSMODE} />
} { texture.isCube &&
}
); } }