import * as React from "react"; import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture'; import { FileButtonLineComponent } from '../../sharedComponents/fileButtonLineComponent'; import { Tools } from 'babylonjs/Misc/tools'; import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent'; import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent'; import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent'; import { Texture } from 'babylonjs/Materials/Textures/texture'; import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent'; import { FloatLineComponent } from '../../sharedComponents/floatLineComponent'; import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent'; import { CubeTexture } from 'babylonjs/Materials/Textures/cubeTexture'; import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent'; import { IPropertyComponentProps } from './propertyComponentProps'; import { ReflectionTextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/reflectionTextureBlock'; import { ReflectionBlock } from 'babylonjs/Materials/Node/Blocks/PBR/reflectionBlock'; import { RefractionBlock } from 'babylonjs/Materials/Node/Blocks/PBR/refractionBlock'; import { TextureBlock } from 'babylonjs/Materials/Node/Blocks/Dual/textureBlock'; import { CurrentScreenBlock } from 'babylonjs/Materials/Node/Blocks/Dual/currentScreenBlock'; import { ParticleTextureBlock } from 'babylonjs/Materials/Node/Blocks/Particle/particleTextureBlock'; import { GeneralPropertyTabComponent, GenericPropertyTabComponent } from './genericNodePropertyComponent'; import { NodeMaterialModes } from 'babylonjs/Materials/Node/Enums/nodeMaterialModes'; type ReflectionTexture = ReflectionTextureBlock | ReflectionBlock | RefractionBlock; type AnyTexture = TextureBlock | ReflectionTexture | CurrentScreenBlock | ParticleTextureBlock; export class TexturePropertyTabComponent extends React.Component { get textureBlock(): AnyTexture { return this.props.block as AnyTexture; } constructor(props: IPropertyComponentProps) { super(props); let texture = this.textureBlock.texture as BaseTexture; this.state = {isEmbedded: !texture || texture.name.substring(0, 4) === "data", loadAsCubeTexture: texture && texture.isCube}; } UNSAFE_componentWillUpdate(nextProps: IPropertyComponentProps, nextState: {isEmbedded: boolean, loadAsCubeTexture: boolean}) { if (nextProps.block !== this.props.block) { let texture = (nextProps.block as AnyTexture).texture as BaseTexture; nextState.isEmbedded = !texture || texture.name.substring(0, 4) === "data"; nextState.loadAsCubeTexture = texture && texture.isCube; } } private _generateRandomForCache() { return 'xxxxxxxxxxxxxxxxxxxx'.replace(/[x]/g, (c) => { var r = Math.random() * 10 | 0; return r.toString(); }); } updateAfterTextureLoad() { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); this.props.globalState.onRebuildRequiredObservable.notifyObservers(); this.forceUpdate(); } removeTexture() { let texture = this.textureBlock.texture as BaseTexture; if (texture) { texture.dispose(); (texture as any) = null; this.textureBlock.texture = null; } this.updateAfterTextureLoad(); } _prepareTexture() { let texture = this.textureBlock.texture as BaseTexture; if (texture && texture.isCube !== this.state.loadAsCubeTexture) { texture.dispose(); (texture as any) = null; } if (!texture) { if (!this.state.loadAsCubeTexture) { this.textureBlock.texture = new Texture(null, this.props.globalState.nodeMaterial.getScene(), false, this.textureBlock instanceof ReflectionTextureBlock || this.textureBlock instanceof ReflectionBlock || this.textureBlock instanceof RefractionBlock || this.props.globalState.mode === NodeMaterialModes.PostProcess); texture = this.textureBlock.texture; texture.coordinatesMode = Texture.EQUIRECTANGULAR_MODE; } else { this.textureBlock.texture = new CubeTexture("", this.props.globalState.nodeMaterial.getScene()); texture = this.textureBlock.texture; texture.coordinatesMode = Texture.CUBIC_MODE; } } } /** * Replaces the texture of the node * @param file the file of the texture to use */ replaceTexture(file: File) { this._prepareTexture(); let texture = this.textureBlock.texture as BaseTexture; 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; 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 Texture).updateURL(base64data, extension, () => this.updateAfterTextureLoad()); } }, undefined, true); } replaceTextureWithUrl(url: string) { this._prepareTexture(); let texture = this.textureBlock.texture as BaseTexture; if (texture.isCube || this.textureBlock instanceof ReflectionTextureBlock || this.textureBlock instanceof ReflectionBlock || this.textureBlock instanceof RefractionBlock) { let extension: string | undefined = undefined; if (url.toLowerCase().indexOf(".dds") > 0) { extension = ".dds"; } else if (url.toLowerCase().indexOf(".env") > 0) { extension = ".env"; } (texture as Texture).updateURL(url, extension, () => this.updateAfterTextureLoad()); } else { (texture as Texture).updateURL(url, null, () => this.updateAfterTextureLoad()); } } render() { let url = ""; let texture = this.textureBlock.texture as BaseTexture; if (texture && texture.name && texture.name.substring(0, 4) !== "data") { url = texture.name; } url = url.replace(/\?nocache=\d+/, ""); let isInReflectionMode = this.textureBlock instanceof ReflectionTextureBlock || this.textureBlock instanceof ReflectionBlock || this.textureBlock instanceof RefractionBlock; let isFrozenTexture = this.textureBlock instanceof CurrentScreenBlock || this.textureBlock instanceof ParticleTextureBlock; var reflectionModeOptions: {label: string, value: number}[] = [ { label: "Cubic", value: Texture.CUBIC_MODE }, { label: "Equirectangular", value: Texture.EQUIRECTANGULAR_MODE }, { label: "Explicit", value: Texture.EXPLICIT_MODE }, { label: "Fixed equirectangular", value: Texture.FIXED_EQUIRECTANGULAR_MODE }, { label: "Fixed mirrored equirectangular", 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 }, ]; return (
{ this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }}/> { texture && !isInReflectionMode && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }}/> } { texture && !isInReflectionMode && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }}/> } { texture && isInReflectionMode && { texture.coordinatesMode = value; this.forceUpdate(); this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && texture.wrapU === Texture.CLAMP_ADDRESSMODE} onSelect={(value) => { texture.wrapU = value ? Texture.CLAMP_ADDRESSMODE : Texture.WRAP_ADDRESSMODE; this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && texture.wrapV === Texture.CLAMP_ADDRESSMODE} onSelect={(value) => { texture.wrapV = value ? Texture.CLAMP_ADDRESSMODE : Texture.WRAP_ADDRESSMODE; this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } { texture && !isInReflectionMode && !isFrozenTexture && { this.props.globalState.onUpdateRequiredObservable.notifyObservers(); }} /> } this.state.isEmbedded} onSelect={value => { this.setState({isEmbedded: value}); this.textureBlock.texture = null; this.updateAfterTextureLoad(); }}/> { isInReflectionMode && this.state.loadAsCubeTexture} onSelect={value => this.setState({loadAsCubeTexture: value})}/> } { this.state.isEmbedded && this.replaceTexture(file)} accept=".jpg, .png, .tga, .dds, .env" /> } { !this.state.isEmbedded && this.replaceTextureWithUrl(newUrl)}/> } { !this.state.isEmbedded && url && this.replaceTextureWithUrl(url + "?nocache=" + this._generateRandomForCache())}/> } { texture && this.removeTexture()}/> }
); } }