123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- import { serialize, Tools, SerializationHelper } from "Tools";
- import { Nullable } from "types";
- import { Scene } from "scene";
- import { Matrix, Vector3 } from "Math";
- import { Engine } from "Engine";
- import { Material, Texture, BaseTexture } from "Materials";
- import { Animation } from "Animations";
- import { _TimeToken } from "Instrumentation";
- import { _DepthCullingState, _StencilState, _AlphaState } from "States";
- /**
- * Class for creating a cube texture
- */
- export class CubeTexture extends BaseTexture {
- /**
- * 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(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;
- }
- private _noMipmap: boolean;
- private _files: string[];
- private _extensions: string[];
- private _textureMatrix: Matrix;
- private _format: number;
- private _createPolynomials: boolean;
- /** @hidden */
- public readonly _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
- * @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 = Engine.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 = Engine.DELAYLOADSTATE_NOTLOADED;
- }
- } else if (onLoad) {
- if (this._texture.isReady) {
- Tools.SetImmediate(() => onLoad());
- } else {
- this._texture.onLoadedObservable.add(onLoad);
- }
- }
- }
- /**
- * Delays loading of the cube texture
- */
- public delayLoad(): void {
- if (this.delayLoadState !== Engine.DELAYLOADSTATE_NOTLOADED) {
- return;
- }
- let scene = this.getScene();
- if (!scene) {
- return;
- }
- this.delayLoadState = Engine.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, undefined, undefined, this._format, undefined, this._createPolynomials);
- }
- else {
- this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, undefined, undefined, this._format);
- }
- }
- }
- /**
- * 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 {
- 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, 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];
- texture.animations.push(Animation.Parse(parsedAnimation));
- }
- }
- return texture;
- }
- /**
- * Makes a clone, or deep copy, of the cube texture
- * @returns a new cube texture
- */
- public clone(): CubeTexture {
- return SerializationHelper.Clone(() => {
- let scene = this.getScene();
- if (!scene) {
- return this;
- }
- return new CubeTexture(this.url, scene, this._extensions, this._noMipmap, this._files);
- }, this);
- }
- }
|