| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- import { serialize, serializeAsMatrix, SerializationHelper } from "../../Misc/decorators";
- import { Tools } from "../../Misc/tools";
- import { Nullable } from "../../types";
- import { Scene } from "../../scene";
- import { Matrix, Vector3 } from "../../Maths/math.vector";
- import { BaseTexture } from "../../Materials/Textures/baseTexture";
- import { Texture } from "../../Materials/Textures/texture";
- import { _TimeToken } from "../../Instrumentation/timeToken";
- import { Constants } from "../../Engines/constants";
- import { _TypeStore } from '../../Misc/typeStore';
- import "../../Engines/Extensions/engine.cubeTexture";
- /**
- * Class for creating a cube texture
- */
- export class CubeTexture extends BaseTexture {
- private _delayedOnLoad: Nullable<() => void>;
- /**
- * The url of the texture
- */
- public url: string;
- /**
- * Gets or sets the center of the bounding box associated with the cube texture.
- * It must define where the camera used to render the texture was set
- * @see http://doc.babylonjs.com/how_to/reflect#using-local-cubemap-mode
- */
- public boundingBoxPosition = Vector3.Zero();
- private _boundingBoxSize: Vector3;
- /**
- * Gets or sets the size of the bounding box associated with the cube texture
- * When defined, the cubemap will switch to local mode
- * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity
- * @example https://www.babylonjs-playground.com/#RNASML
- */
- public set boundingBoxSize(value: Vector3) {
- if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {
- return;
- }
- this._boundingBoxSize = value;
- let scene = this.getScene();
- if (scene) {
- scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);
- }
- }
- /**
- * Returns the bounding box size
- * @see http://doc.babylonjs.com/how_to/reflect#using-local-cubemap-mode
- */
- public get boundingBoxSize(): Vector3 {
- return this._boundingBoxSize;
- }
- protected _rotationY: number = 0;
- /**
- * Sets texture matrix rotation angle around Y axis in radians.
- */
- @serialize("rotationY")
- public set rotationY(value: number) {
- this._rotationY = value;
- this.setReflectionTextureMatrix(Matrix.RotationY(this._rotationY));
- }
- /**
- * Gets texture matrix rotation angle around Y axis radians.
- */
- public get rotationY(): number {
- return this._rotationY;
- }
- /**
- * Are mip maps generated for this texture or not.
- */
- public get noMipmap(): boolean {
- return this._noMipmap;
- }
- private _noMipmap: boolean;
- @serialize("files")
- private _files: string[];
- private _extensions: string[];
- @serializeAsMatrix("textureMatrix")
- private _textureMatrix: Matrix;
- private _format: number;
- private _createPolynomials: boolean;
- /** @hidden */
- public _prefiltered: boolean = false;
- /**
- * Creates a cube texture from an array of image urls
- * @param files defines an array of image urls
- * @param scene defines the hosting scene
- * @param noMipmap specifies if mip maps are not used
- * @returns a cube texture
- */
- public static CreateFromImages(files: string[], scene: Scene, noMipmap?: boolean): CubeTexture {
- let rootUrlKey = "";
- files.forEach((url) => rootUrlKey += url);
- return new CubeTexture(rootUrlKey, scene, null, noMipmap, files);
- }
- /**
- * Creates and return a texture created from prefilterd data by tools like IBL Baker or Lys.
- * @param url defines the url of the prefiltered texture
- * @param scene defines the scene the texture is attached to
- * @param forcedExtension defines the extension of the file if different from the url
- * @param createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary
- * @return the prefiltered texture
- */
- public static CreateFromPrefilteredData(url: string, scene: Scene, forcedExtension: any = null, createPolynomials: boolean = true) {
- return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
- }
- /**
- * Creates a cube texture to use with reflection for instance. It can be based upon dds or six images as well
- * as prefiltered data.
- * @param rootUrl defines the url of the texture or the root name of the six images
- * @param scene defines the scene the texture is attached to
- * @param extensions defines the suffixes add to the picture name in case six images are in use like _px.jpg...
- * @param noMipmap defines if mipmaps should be created or not
- * @param files defines the six files to load for the different faces in that order: px, py, pz, nx, ny, nz
- * @param onLoad defines a callback triggered at the end of the file load if no errors occured
- * @param onError defines a callback triggered in case of error during load
- * @param format defines the internal format to use for the texture once loaded
- * @param prefiltered defines whether or not the texture is created from prefiltered data
- * @param forcedExtension defines the extensions to use (force a special type of file to load) in case it is different from the file name
- * @param createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary
- * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
- * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
- * @return the cube texture
- */
- constructor(rootUrl: string, scene: Scene, extensions: Nullable<string[]> = null, noMipmap: boolean = false, files: Nullable<string[]> = null,
- onLoad: Nullable<() => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, format: number = Constants.TEXTUREFORMAT_RGBA, prefiltered = false,
- forcedExtension: any = null, createPolynomials: boolean = false,
- lodScale: number = 0.8, lodOffset: number = 0) {
- super(scene);
- this.name = rootUrl;
- this.url = rootUrl;
- this._noMipmap = noMipmap;
- this.hasAlpha = false;
- this._format = format;
- this.isCube = true;
- this._textureMatrix = Matrix.Identity();
- this._createPolynomials = createPolynomials;
- this.coordinatesMode = Texture.CUBIC_MODE;
- if (!rootUrl && !files) {
- return;
- }
- const lastDot = rootUrl.lastIndexOf(".");
- const extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
- const isDDS = (extension === ".dds");
- const isEnv = (extension === ".env");
- if (isEnv) {
- this.gammaSpace = false;
- this._prefiltered = false;
- }
- else {
- this._prefiltered = prefiltered;
- if (prefiltered) {
- this.gammaSpace = false;
- }
- }
- this._texture = this._getFromCache(rootUrl, noMipmap);
- if (!files) {
- if (!isEnv && !isDDS && !extensions) {
- extensions = ["_px.jpg", "_py.jpg", "_pz.jpg", "_nx.jpg", "_ny.jpg", "_nz.jpg"];
- }
- files = [];
- if (extensions) {
- for (var index = 0; index < extensions.length; index++) {
- files.push(rootUrl + extensions[index]);
- }
- }
- }
- this._files = files;
- if (!this._texture) {
- if (!scene.useDelayedTextureLoading) {
- if (prefiltered) {
- this._texture = scene.getEngine().createPrefilteredCubeTexture(rootUrl, scene, lodScale, lodOffset, onLoad, onError, format, forcedExtension, this._createPolynomials);
- }
- else {
- this._texture = scene.getEngine().createCubeTexture(rootUrl, scene, files, noMipmap, onLoad, onError, this._format, forcedExtension, false, lodScale, lodOffset);
- }
- } else {
- this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;
- }
- } else if (onLoad) {
- if (this._texture.isReady) {
- Tools.SetImmediate(() => onLoad());
- } else {
- this._texture.onLoadedObservable.add(onLoad);
- }
- }
- }
- /**
- * Gets a boolean indicating if the cube texture contains prefiltered mips (used to simulate roughness with PBR)
- */
- public get isPrefiltered(): boolean {
- return this._prefiltered;
- }
- /**
- * Get the current class name of the texture useful for serialization or dynamic coding.
- * @returns "CubeTexture"
- */
- public getClassName(): string {
- return "CubeTexture";
- }
- /**
- * Update the url (and optional buffer) of this texture if url was null during construction.
- * @param url the url of the texture
- * @param forcedExtension defines the extension to use
- * @param onLoad callback called when the texture is loaded (defaults to null)
- */
- public updateURL(url: string, forcedExtension?: string, onLoad?: () => void): void {
- if (this.url) {
- this.releaseInternalTexture();
- this.getScene()!.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);
- }
- this.name = url;
- this.url = url;
- this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;
- this._prefiltered = false;
- if (onLoad) {
- this._delayedOnLoad = onLoad;
- }
- this.delayLoad(forcedExtension);
- }
- /**
- * Delays loading of the cube texture
- * @param forcedExtension defines the extension to use
- */
- public delayLoad(forcedExtension?: string): void {
- if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {
- return;
- }
- let scene = this.getScene();
- if (!scene) {
- return;
- }
- this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;
- this._texture = this._getFromCache(this.url, this._noMipmap);
- if (!this._texture) {
- if (this._prefiltered) {
- this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
- }
- else {
- this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, null, this._format, forcedExtension);
- }
- }
- }
- /**
- * Returns the reflection texture matrix
- * @returns the reflection texture matrix
- */
- public getReflectionTextureMatrix(): Matrix {
- return this._textureMatrix;
- }
- /**
- * Sets the reflection texture matrix
- * @param value Reflection texture matrix
- */
- public setReflectionTextureMatrix(value: Matrix): void {
- if (value.updateFlag === this._textureMatrix.updateFlag) {
- return;
- }
- if (value.isIdentity() !== this._textureMatrix.isIdentity()) {
- this.getScene()!.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => mat.getActiveTextures().indexOf(this) !== -1);
- }
- this._textureMatrix = value;
- }
- /**
- * Parses text to create a cube texture
- * @param parsedTexture define the serialized text to read from
- * @param scene defines the hosting scene
- * @param rootUrl defines the root url of the cube texture
- * @returns a cube texture
- */
- public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): CubeTexture {
- var texture = SerializationHelper.Parse(() => {
- var prefiltered: boolean = false;
- if (parsedTexture.prefiltered) {
- prefiltered = parsedTexture.prefiltered;
- }
- return new CubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.extensions, false, parsedTexture.files || null, null, null, undefined, prefiltered);
- }, parsedTexture, scene);
- // Local Cubemaps
- if (parsedTexture.boundingBoxPosition) {
- texture.boundingBoxPosition = Vector3.FromArray(parsedTexture.boundingBoxPosition);
- }
- if (parsedTexture.boundingBoxSize) {
- texture.boundingBoxSize = Vector3.FromArray(parsedTexture.boundingBoxSize);
- }
- // Animations
- if (parsedTexture.animations) {
- for (var animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {
- var parsedAnimation = parsedTexture.animations[animationIndex];
- const internalClass = _TypeStore.GetClass("BABYLON.Animation");
- if (internalClass) {
- texture.animations.push(internalClass.Parse(parsedAnimation));
- }
- }
- }
- return texture;
- }
- /**
- * Makes a clone, or deep copy, of the cube texture
- * @returns a new cube texture
- */
- public clone(): CubeTexture {
- let scene = this.getScene();
- let uniqueId = 0;
- let newCubeTexture = SerializationHelper.Clone(() => {
- if (!scene) {
- return this;
- }
- const cubeTexture = new CubeTexture(this.url, scene, this._extensions, this._noMipmap, this._files);
- uniqueId = cubeTexture.uniqueId;
- return cubeTexture;
- }, this);
- newCubeTexture.uniqueId = uniqueId;
- return newCubeTexture;
- }
- }
- Texture._CubeTextureParser = CubeTexture.Parse;
- // Some exporters relies on Tools.Instantiate
- _TypeStore.RegisteredTypes["BABYLON.CubeTexture"] = CubeTexture;
|