diff --git a/.github/instructions/tree-shaking.instructions.md b/.github/instructions/tree-shaking.instructions.md index 9caca5eef140..952374344271 100644 --- a/.github/instructions/tree-shaking.instructions.md +++ b/.github/instructions/tree-shaking.instructions.md @@ -112,6 +112,8 @@ Do not add `export {}` just to force module mode. If the augmentation needs an i 6. **Do not create pure shader files.** Generated shader modules remain generated side-effect modules. If a pure implementation needs a shader, load the generated shader module from the owning registration/readiness path; do not split the shader file itself. +7. **TC39 decorators in `.pure.ts` must be class-local.** Decorators are allowed in pure implementation files only when their runtime effects are confined to the class or member being defined. Allowed examples include writing metadata to that class via `Symbol.metadata`, returning accessor or method descriptors for that member, and initializing per-instance backing fields through `init`. Decorators in `.pure.ts` files must not register classes or parsers globally, mutate shared registries, patch prototypes, perform side-effect imports, write to shader stores, install global polyfills, or depend on wrapper-only registration having already run. If a decorator needs any of those effects, move that work into the module's `Register*()` function and keep the decorator as a class-local metadata or descriptor operation. The only approved exception is the `Symbol.metadata` compatibility shim in `Misc/decorators.functions.ts`, which must run before TypeScript's TC39 decorator emit evaluates decorated classes on runtimes that do not yet provide `Symbol.metadata`. + ## Tooling After adding, renaming, or removing files, run these scripts to keep everything in sync: diff --git a/packages/dev/buildTools/src/pathTransform.ts b/packages/dev/buildTools/src/pathTransform.ts index 32dd867369e8..348f166b7c58 100644 --- a/packages/dev/buildTools/src/pathTransform.ts +++ b/packages/dev/buildTools/src/pathTransform.ts @@ -225,256 +225,9 @@ function TransformerFactory(context: ts.Transformatio export const storeTsLib = () => { const tsLibPath = path.resolve(path.resolve(".", "tslib.es6.js")); if (!fs.existsSync(tsLibPath)) { - fs.writeFileSync(tsLibPath, TslibContent); + // Read from the installed tslib package instead of using a hardcoded copy, + // so that the helpers stay in sync with the TypeScript version. + const tslibSource = require.resolve("tslib/tslib.es6.mjs"); + fs.copyFileSync(tslibSource, tsLibPath); } }; - -// tslib 2.4.0 -const TslibContent = ` -/****************************************************************************** -Copyright (c) Microsoft Corporation. -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -export function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -export var __assign = function() { - __assign = Object.assign || function __assign(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; - } - return t; - } - return __assign.apply(this, arguments); -} - -export function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -} - -export function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} - -export function __param(paramIndex, decorator) { - return function (target, key) { decorator(target, key, paramIndex); } -} - -export function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); -} - -export function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -export function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -export var __createBinding = Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -}); - -export function __exportStar(m, o) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); -} - -export function __values(o) { - var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; - if (m) return m.call(o); - if (o && typeof o.length === "number") return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; - throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); -} - -export function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -} - -/** @deprecated */ -export function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; -} - -/** @deprecated */ -export function __spreadArrays() { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; -} - -export function __spreadArray(to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -} - -export function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); -} - -export function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; - function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } - function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } - function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } - function fulfill(value) { resume("next", value); } - function reject(value) { resume("throw", value); } - function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } -} - -export function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; - function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } -} - -export function __asyncValues(o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } -} - -export function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } - return cooked; -}; - -var __setModuleDefault = Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}; - -export function __importStar(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -} - -export function __importDefault(mod) { - return (mod && mod.__esModule) ? mod : { default: mod }; -} - -export function __classPrivateFieldGet(receiver, state, kind, f) { - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); -} - -export function __classPrivateFieldSet(receiver, state, value, kind, f) { - if (kind === "m") throw new TypeError("Private method is not writable"); - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); - return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; -} - -export function __classPrivateFieldIn(state, receiver) { - if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); - return typeof state === "function" ? receiver === state : state.has(receiver); -} -`; diff --git a/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts b/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts index a0005a15ce98..065460b87dd8 100644 --- a/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts +++ b/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts @@ -75,7 +75,7 @@ export class BakedVertexAnimationManager implements IBakedVertexAnimationManager */ @serializeAsTexture() @expandToProperty("_markSubMeshesAsAttributesDirty") - public texture: Nullable; + public accessor texture: Nullable; private _isEnabled = true; /** @@ -83,7 +83,7 @@ export class BakedVertexAnimationManager implements IBakedVertexAnimationManager */ @serialize() @expandToProperty("_markSubMeshesAsAttributesDirty") - public isEnabled = true; + public accessor isEnabled = true; /** * The animation parameters for the mesh. See setAnimationParameters() diff --git a/packages/dev/core/src/Cameras/arcRotateCamera.pure.ts b/packages/dev/core/src/Cameras/arcRotateCamera.pure.ts index 91d98eedbd75..99549ce3dcb5 100644 --- a/packages/dev/core/src/Cameras/arcRotateCamera.pure.ts +++ b/packages/dev/core/src/Cameras/arcRotateCamera.pure.ts @@ -694,7 +694,7 @@ export class ArcRotateCamera extends TargetCamera { /** * Defines the input associated to the camera. */ - public override inputs: ArcRotateCameraInputsManager; + declare public inputs: ArcRotateCameraInputsManager; /** * Movement controller that provides framerate-independent physics and the declarative diff --git a/packages/dev/core/src/Cameras/followCamera.pure.ts b/packages/dev/core/src/Cameras/followCamera.pure.ts index 8092c5c4ffb9..14df01aa4c83 100644 --- a/packages/dev/core/src/Cameras/followCamera.pure.ts +++ b/packages/dev/core/src/Cameras/followCamera.pure.ts @@ -96,12 +96,12 @@ export class FollowCamera extends TargetCamera { * Define the target of the camera. */ @serializeAsMeshReference("lockedTargetId") - public override lockedTarget: Nullable; + public override lockedTarget: Nullable = null; /** * Defines the input associated with the camera. */ - public override inputs: FollowCameraInputsManager; + declare public inputs: FollowCameraInputsManager; /** * Instantiates the follow camera. diff --git a/packages/dev/core/src/Decorators/nodeDecorator.ts b/packages/dev/core/src/Decorators/nodeDecorator.ts index 988d010ad5c6..d306c90547db 100644 --- a/packages/dev/core/src/Decorators/nodeDecorator.ts +++ b/packages/dev/core/src/Decorators/nodeDecorator.ts @@ -107,19 +107,51 @@ export function editableInPropertyPage( groupName: string = "PROPERTIES", options?: IEditablePropertyOption ) { - return (target: any, propertyKey: string) => { - let propStore: IPropertyDescriptionForEdition[] = target._propStore; - if (!propStore) { + return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => { + const meta = context.metadata; + let propStore: IPropertyDescriptionForEdition[]; + if (Object.prototype.hasOwnProperty.call(meta, __bjsPropStoreKey)) { + propStore = meta[__bjsPropStoreKey] as IPropertyDescriptionForEdition[]; + } else { propStore = []; - target._propStore = propStore; + meta[__bjsPropStoreKey] = propStore; } propStore.push({ - propertyName: propertyKey, + propertyName: String(context.name), displayName: displayName, type: propertyType, groupName: groupName, options: options ?? {}, - className: target.getClassName(), + className: "", }); }; } + +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export const __bjsPropStoreKey = "__bjs_prop_store__"; + +/** + * Gets the editable properties for a given target using TC39 decorator metadata. + * Walks the metadata prototype chain to include properties from parent classes. + * @param target - the target object (instance or constructor) + * @returns array of property descriptions + */ +export function GetEditableProperties(target: any): IPropertyDescriptionForEdition[] { + const ctor = typeof target === "function" ? target : target?.constructor; + const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + if (!metadata) { + return []; + } + + const result: IPropertyDescriptionForEdition[] = []; + let currentMeta: any = metadata; + while (currentMeta) { + if (Object.prototype.hasOwnProperty.call(currentMeta, __bjsPropStoreKey)) { + const store = currentMeta[__bjsPropStoreKey] as IPropertyDescriptionForEdition[]; + result.push(...store); + } + currentMeta = Object.getPrototypeOf(currentMeta); + } + return result; +} diff --git a/packages/dev/core/src/Layers/glowLayer.pure.ts b/packages/dev/core/src/Layers/glowLayer.pure.ts index 327a275b3ce9..6c32575e0aa4 100644 --- a/packages/dev/core/src/Layers/glowLayer.pure.ts +++ b/packages/dev/core/src/Layers/glowLayer.pure.ts @@ -96,7 +96,7 @@ export class GlowLayer extends EffectLayer { @serialize("options") protected _options: IGlowLayerOptions; - protected override readonly _thinEffectLayer: ThinGlowLayer; + declare protected readonly _thinEffectLayer: ThinGlowLayer; private _horizontalBlurPostprocess1: BlurPostProcess; private _verticalBlurPostprocess1: BlurPostProcess; private _horizontalBlurPostprocess2: BlurPostProcess; diff --git a/packages/dev/core/src/Layers/highlightLayer.pure.ts b/packages/dev/core/src/Layers/highlightLayer.pure.ts index 152094bf7664..5415d33be80a 100644 --- a/packages/dev/core/src/Layers/highlightLayer.pure.ts +++ b/packages/dev/core/src/Layers/highlightLayer.pure.ts @@ -41,7 +41,7 @@ interface IBlurPostProcess extends PostProcess { * It enforces keeping the most luminous color in the color channel. */ class GlowBlurPostProcess extends PostProcess { - protected override _effectWrapper: ThinGlowBlurPostProcess; + declare protected _effectWrapper: ThinGlowBlurPostProcess; constructor( name: string, @@ -210,7 +210,7 @@ export class HighlightLayer extends EffectLayer { @serialize("options") private _options: Required; - protected override readonly _thinEffectLayer: ThinHighlightLayer; + declare protected readonly _thinEffectLayer: ThinHighlightLayer; private _downSamplePostprocess: PassPostProcess; private _horizontalBlurPostprocess: IBlurPostProcess; private _verticalBlurPostprocess: IBlurPostProcess; diff --git a/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts b/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts index e1cc25652a1a..6aa1756cdd87 100644 --- a/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts +++ b/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts @@ -92,7 +92,7 @@ export class SelectionOutlineLayer extends EffectLayer { @serialize("options") private _options: Required; - protected override readonly _thinEffectLayer: ThinSelectionOutlineLayer; + declare protected readonly _thinEffectLayer: ThinSelectionOutlineLayer; /** * Instantiates a new selection outline Layer and references it to the scene.. diff --git a/packages/dev/core/src/Lights/light.ts b/packages/dev/core/src/Lights/light.ts index 0b63c13e0278..9276504a3ae5 100644 --- a/packages/dev/core/src/Lights/light.ts +++ b/packages/dev/core/src/Lights/light.ts @@ -209,7 +209,7 @@ export abstract class Light extends Node implements ISortableLight { * exceeding the number allowed of the materials. */ @expandToProperty("_reorderLightsInScene") - public renderPriority: number = 0; + public accessor renderPriority: number = 0; @serialize("shadowEnabled") private _shadowEnabled: boolean = true; diff --git a/packages/dev/core/src/Materials/Background/backgroundMaterial.pure.ts b/packages/dev/core/src/Materials/Background/backgroundMaterial.pure.ts index a49cd04a4bfa..7d75b1ee51fb 100644 --- a/packages/dev/core/src/Materials/Background/backgroundMaterial.pure.ts +++ b/packages/dev/core/src/Materials/Background/backgroundMaterial.pure.ts @@ -249,7 +249,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Key light Color (multiply against the environment texture) */ @expandToProperty("_markAllSubMeshesAsLightsDirty") - public primaryColor = Color3.White(); + public accessor primaryColor = Color3.White(); @serializeAsColor3() protected __perceptualColor: Nullable; @@ -293,7 +293,6 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Defines the level of the highlights (highlight area of the reflection map) in order to help scaling the colors. * The primary color is used at the level chosen to define what the white area would look. */ - @expandToProperty("_markAllSubMeshesAsLightsDirty") public get primaryColorHighlightLevel(): float { return this._primaryColorHighlightLevel; } @@ -310,7 +309,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Should be author in a specific way for the best result (refer to the documentation). */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionTexture: Nullable = null; + public accessor reflectionTexture: Nullable = null; @serialize() protected _reflectionBlur: float; @@ -321,7 +320,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * texture twice. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionBlur: float = 0; + public accessor reflectionBlur: float = 0; @serializeAsTexture() protected _diffuseTexture: Nullable; @@ -330,7 +329,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Should be author in a specific way for the best result (refer to the documentation). */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: Nullable = null; + public accessor diffuseTexture: Nullable = null; protected _shadowLights: Nullable = null; /** @@ -338,7 +337,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * All scene shadow lights will be included if null. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public shadowLights: Nullable = null; + public accessor shadowLights: Nullable = null; @serialize() protected _shadowLevel: float; @@ -347,7 +346,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * 0 means black shadows and 1 means no shadows. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public shadowLevel: float = 0; + public accessor shadowLevel: float = 0; @serializeAsVector3() protected _sceneCenter: Vector3; @@ -356,7 +355,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * It is usually zero but might be interesting to modify according to your setup. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public sceneCenter: Vector3 = Vector3.Zero(); + public accessor sceneCenter: Vector3 = Vector3.Zero(); @serialize() protected _opacityFresnel: boolean; @@ -365,7 +364,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This helps ensuring a nice transition when the camera goes under the ground. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public opacityFresnel: boolean = true; + public accessor opacityFresnel: boolean = true; @serialize() protected _reflectionFresnel: boolean; @@ -374,7 +373,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This helps adding a mirror texture on the ground. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionFresnel: boolean = false; + public accessor reflectionFresnel: boolean = false; @serialize() protected _reflectionFalloffDistance: number; @@ -383,7 +382,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This helps adding a nice falloff effect to the reflection if used as a mirror for instance. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionFalloffDistance: number = 0.0; + public accessor reflectionFalloffDistance: number = 0.0; @serialize() protected _reflectionAmount: number; @@ -391,7 +390,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This specifies the weight of the reflection against the background in case of reflection Fresnel. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionAmount: number = 1.0; + public accessor reflectionAmount: number = 1.0; @serialize() protected _reflectionReflectance0: number; @@ -399,7 +398,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This specifies the weight of the reflection at grazing angle. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionReflectance0: number = 0.05; + public accessor reflectionReflectance0: number = 0.05; @serialize() protected _reflectionReflectance90: number; @@ -407,7 +406,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This specifies the weight of the reflection at a perpendicular point of view. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionReflectance90: number = 0.5; + public accessor reflectionReflectance90: number = 0.5; /** * Sets the reflection reflectance fresnel values according to the default standard @@ -433,7 +432,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Helps to directly use the maps channels instead of their level. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRGBColor: boolean = true; + public accessor useRGBColor: boolean = true; @serialize() protected _enableNoise: boolean; @@ -441,7 +440,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * This helps reducing the banding effect that could occur on the background. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public enableNoise: boolean = false; + public accessor enableNoise: boolean = false; /** * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values "zoom in" and higher values "zoom out". @@ -470,7 +469,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Number of Simultaneous lights allowed on the material. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public maxSimultaneousLights: int = 4; + public accessor maxSimultaneousLights: int = 4; @serialize() private _shadowOnly: boolean = false; @@ -478,7 +477,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { * Make the material only render shadows */ @expandToProperty("_markAllSubMeshesAsLightsDirty") - public shadowOnly: boolean = false; + public accessor shadowOnly: boolean = false; /** * Due to a bug in iOS10, video tags (which are using the background material) are in BGR and not RGB. @@ -493,7 +492,7 @@ export class BackgroundMaterial extends BackgroundMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public enableGroundProjection: boolean = false; + public accessor enableGroundProjection: boolean = false; /** * Defines the radius of the projected ground if enableGroundProjection is true. diff --git a/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts b/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts index f7c645c5d205..f58453a4444f 100644 --- a/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts +++ b/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts @@ -30,7 +30,7 @@ export class GaussianSplattingSolidColorMaterialPlugin extends MaterialPluginBas */ @serialize() @expandToProperty("_onIsEnabledChanged") - public isEnabled = true; + public accessor isEnabled = true; /** @internal */ public _onIsEnabledChanged(): void { diff --git a/packages/dev/core/src/Materials/Node/Blocks/Dual/lightBlock.pure.ts b/packages/dev/core/src/Materials/Node/Blocks/Dual/lightBlock.pure.ts index 2b8de17f492d..de8a8ae89e90 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Dual/lightBlock.pure.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Dual/lightBlock.pure.ts @@ -33,7 +33,7 @@ export class LightBlock extends NodeMaterialBlock { /** Indicates that no code should be generated in the vertex shader. Can be useful in some specific circumstances (like when doing ray marching for eg) */ @editableInPropertyPage("Generate only fragment code", PropertyTypeForEdition.Boolean, "ADVANCED", { - notifiers: { rebuild: true, update: true, onValidation: LightBlock._OnGenerateOnlyFragmentCodeChanged }, + notifiers: { rebuild: true, update: true, onValidation: (block, prop) => LightBlock._OnGenerateOnlyFragmentCodeChanged(block, prop) }, }) public generateOnlyFragmentCode = false; diff --git a/packages/dev/core/src/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.ts b/packages/dev/core/src/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.ts index 343ea1d25a27..a1adc03a6bcc 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/Dual/reflectionTextureBaseBlock.pure.ts @@ -102,7 +102,7 @@ export abstract class ReflectionTextureBaseBlock extends NodeMaterialBlock { /** Indicates that no code should be generated in the vertex shader. Can be useful in some specific circumstances (like when doing ray marching for eg) */ @editableInPropertyPage("Generate only fragment code", PropertyTypeForEdition.Boolean, "ADVANCED", { - notifiers: { rebuild: true, update: true, onValidation: ReflectionTextureBaseBlock._OnGenerateOnlyFragmentCodeChanged }, + notifiers: { rebuild: true, update: true, onValidation: (block, prop) => ReflectionTextureBaseBlock._OnGenerateOnlyFragmentCodeChanged(block, prop) }, }) public generateOnlyFragmentCode = false; diff --git a/packages/dev/core/src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.ts b/packages/dev/core/src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.ts index 37e089ab26cb..45fa1d27a2f5 100644 --- a/packages/dev/core/src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.ts +++ b/packages/dev/core/src/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.pure.ts @@ -321,7 +321,7 @@ export class PBRMetallicRoughnessBlock extends NodeMaterialBlock { /** Indicates that no code should be generated in the vertex shader. Can be useful in some specific circumstances (like when doing ray marching for eg) */ @editableInPropertyPage("Generate only fragment code", PropertyTypeForEdition.Boolean, "ADVANCED", { - notifiers: { rebuild: true, update: true, onValidation: PBRMetallicRoughnessBlock._OnGenerateOnlyFragmentCodeChanged }, + notifiers: { rebuild: true, update: true, onValidation: (block, prop) => PBRMetallicRoughnessBlock._OnGenerateOnlyFragmentCodeChanged(block, prop) }, }) public generateOnlyFragmentCode = false; diff --git a/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts index 7aa7e5b577b8..232e6bea822b 100644 --- a/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts @@ -500,8 +500,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Base Weight is a multiplier on the diffuse and metal lobes. * See OpenPBR's specs for base_weight */ - public baseWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseWeight: Property = new Property("base_weight", 1, "vBaseWeight", 1); @@ -509,8 +509,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Base Weight is a multiplier on the diffuse and metal lobes. * See OpenPBR's specs for base_weight */ - public baseWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseWeightTexture: Sampler = new Sampler("base_weight", "baseWeight", "BASE_WEIGHT"); @@ -518,8 +518,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Color of the base diffuse lobe. * See OpenPBR's specs for base_color */ - public baseColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseColor: Property = new Property("base_color", Color3.White(), "vBaseColor", 4); @@ -527,8 +527,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Base Color Texture property. * See OpenPBR's specs for base_color */ - public baseColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseColorTexture: Sampler = new Sampler("base_color", "baseColor", "BASE_COLOR"); @@ -536,8 +536,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Roughness of the diffuse lobe. * See OpenPBR's specs for base_diffuse_roughness */ - public baseDiffuseRoughness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseDiffuseRoughness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseDiffuseRoughness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseDiffuseRoughness: Property = new Property("base_diffuse_roughness", 0, "vBaseDiffuseRoughness", 1); @@ -545,8 +545,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Roughness texture of the diffuse lobe. * See OpenPBR's specs for base_diffuse_roughness */ - public baseDiffuseRoughnessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseDiffuseRoughnessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseDiffuseRoughnessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseDiffuseRoughnessTexture: Sampler = new Sampler("base_diffuse_roughness", "baseDiffuseRoughness", "BASE_DIFFUSE_ROUGHNESS"); @@ -554,8 +554,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Metalness of the base lobe. * See OpenPBR's specs for base_metalness */ - public baseMetalness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseMetalness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseMetalness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseMetalness: Property = new Property("base_metalness", 0, "vReflectanceInfo", 4, 0); @@ -563,8 +563,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Metalness texture. * See OpenPBR's specs for base_metalness */ - public baseMetalnessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "baseMetalnessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor baseMetalnessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _baseMetalnessTexture: Sampler = new Sampler("base_metalness", "baseMetalness", "BASE_METALNESS"); @@ -572,8 +572,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Weight of the specular lobe. * See OpenPBR's specs for specular_weight */ - public specularWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularWeight: Property = new Property("specular_weight", 1, "vReflectanceInfo", 4, 3); @@ -581,8 +581,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Weight texture of the specular lobe. * See OpenPBR's specs for specular_weight */ - public specularWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularWeightTexture: Sampler = new Sampler("specular_weight", "specularWeight", "SPECULAR_WEIGHT"); @@ -590,8 +590,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Color of the specular lobe. * See OpenPBR's specs for specular_color */ - public specularColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularColor: Property = new Property("specular_color", Color3.White(), "vSpecularColor", 4); @@ -599,8 +599,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Specular Color Texture property. * See OpenPBR's specs for specular_color */ - public specularColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularColorTexture: Sampler = new Sampler("specular_color", "specularColor", "SPECULAR_COLOR"); @@ -608,8 +608,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Roughness of the specular lobe. * See OpenPBR's specs for specular_roughness */ - public specularRoughness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularRoughness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularRoughness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularRoughness: Property = new Property("specular_roughness", 0.3, "vReflectanceInfo", 4, 1); @@ -617,8 +617,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Roughness texture of the specular lobe. * See OpenPBR's specs for specular_roughness */ - public specularRoughnessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularRoughnessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularRoughnessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularRoughnessTexture: Sampler = new Sampler("specular_roughness", "specularRoughness", "SPECULAR_ROUGHNESS"); @@ -626,8 +626,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Anisotropic roughness of the specular lobe. * See OpenPBR's specs for specular_roughness_anisotropy */ - public specularRoughnessAnisotropy: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularRoughnessAnisotropy") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularRoughnessAnisotropy: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularRoughnessAnisotropy: Property = new Property("specular_roughness_anisotropy", 0, "vSpecularAnisotropy", 3, 2); @@ -635,8 +635,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Anisotropic Roughness texture. * See OpenPBR's specs for specular_roughness */ - public specularRoughnessAnisotropyTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularRoughnessAnisotropyTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularRoughnessAnisotropyTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularRoughnessAnisotropyTexture: Sampler = new Sampler("specular_roughness_anisotropy", "specularRoughnessAnisotropy", "SPECULAR_ROUGHNESS_ANISOTROPY"); @@ -644,8 +644,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * IOR of the specular lobe. * See OpenPBR's specs for specular_ior */ - public specularIor: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "specularIor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor specularIor: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _specularIor: Property = new Property("specular_ior", 1.5, "vReflectanceInfo", 4, 2); @@ -653,8 +653,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission weight of the surface. * See OpenPBR's specs for transmission_weight */ - public transmissionWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionWeight: Property = new Property("transmission_weight", 0.0, "vTransmissionWeight", 1); @@ -662,8 +662,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission weight texture. * See OpenPBR's specs for transmission_weight */ - public transmissionWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionWeightTexture: Sampler = new Sampler("transmission_weight", "transmissionWeight", "TRANSMISSION_WEIGHT"); @@ -671,8 +671,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission color of the surface. * See OpenPBR's specs for transmission_color */ - public transmissionColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionColor: Property = new Property("transmission_color", Color3.White(), "vTransmissionColor", 3, 0); @@ -680,8 +680,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission color texture. * See OpenPBR's specs for transmission_color */ - public transmissionColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionColorTexture: Sampler = new Sampler("transmission_color", "transmissionColor", "TRANSMISSION_COLOR"); @@ -689,8 +689,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission depth of the volume * See OpenPBR's specs for transmission_depth */ - public transmissionDepth: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionDepth") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionDepth: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionDepth: Property = new Property("transmission_depth", 0.0, "vTransmissionDepth", 1, 0); @@ -698,8 +698,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission depth texture. * See OpenPBR's specs for transmission_depth */ - public transmissionDepthTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionDepthTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionDepthTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionDepthTexture: Sampler = new Sampler("transmission_depth", "transmissionDepth", "TRANSMISSION_DEPTH"); @@ -707,8 +707,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission scatter of the surface. * See OpenPBR's specs for transmission_scatter */ - public transmissionScatter: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionScatter") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionScatter: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionScatter: Property = new Property("transmission_scatter", Color3.Black(), "vTransmissionScatter", 3, 0); @@ -716,8 +716,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission scatter texture. * See OpenPBR's specs for transmission_scatter */ - public transmissionScatterTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionScatterTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionScatterTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionScatterTexture: Sampler = new Sampler("transmission_scatter", "transmissionScatter", "TRANSMISSION_SCATTER"); @@ -725,8 +725,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission scatter anisotropy * See OpenPBR's specs for transmission_scatter_anisotropy */ - public transmissionScatterAnisotropy: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionScatterAnisotropy") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionScatterAnisotropy: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionScatterAnisotropy: Property = new Property("transmission_scatter_anisotropy", 0.0, "vTransmissionScatterAnisotropy", 1, 0); @@ -734,8 +734,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission Dispersion Scale factor. * See OpenPBR's specs for transmission_dispersion_scale */ - public transmissionDispersionScale: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionDispersionScale") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionDispersionScale: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionDispersionScale: Property = new Property("transmission_dispersion_scale", 0.0, "vTransmissionDispersionScale", 1, 0); @@ -743,8 +743,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission Dispersion Scale texture. * See OpenPBR's specs for transmission_dispersion_scale */ - public transmissionDispersionScaleTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionDispersionScaleTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionDispersionScaleTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionDispersionScaleTexture: Sampler = new Sampler("transmission_dispersion_scale", "transmissionDispersionScale", "TRANSMISSION_DISPERSION_SCALE"); @@ -752,8 +752,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Transmission Dispersion Abbe number. * See OpenPBR's specs for transmission_dispersion_abbe_number */ - public transmissionDispersionAbbeNumber: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "transmissionDispersionAbbeNumber") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor transmissionDispersionAbbeNumber: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _transmissionDispersionAbbeNumber: Property = new Property("transmission_dispersion_abbe_number", 20.0, "vTransmissionDispersionAbbeNumber", 1, 0); @@ -761,8 +761,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the amount of subsurface scattering on the surface. * See OpenPBR's specs for subsurface_weight */ - public subsurfaceWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceWeight: Property = new Property("subsurface_weight", 0.0, "vSubsurfaceWeight", 1, 0, "SUBSURFACE_SLAB"); @@ -770,8 +770,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Subsurface weight texture. * See OpenPBR's specs for subsurface_weight */ - public subsurfaceWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceWeightTexture: Sampler = new Sampler("subsurface_weight", "subsurfaceWeight", "SUBSURFACE_WEIGHT"); @@ -779,8 +779,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the color of the subsurface scattering in the volume. * See OpenPBR's specs for subsurface_color */ - public subsurfaceColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceColor: Property = new Property("subsurface_color", new Color3(0.8, 0.8, 0.8), "vSubsurfaceColor", 3, 0, "SUBSURFACE_SLAB"); @@ -788,8 +788,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Subsurface color texture. * See OpenPBR's specs for subsurface_color */ - public subsurfaceColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceColorTexture: Sampler = new Sampler("subsurface_color", "subsurfaceColor", "SUBSURFACE_COLOR"); @@ -797,8 +797,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the radius of the subsurface scattering in the volume. * See OpenPBR's specs for subsurface_radius */ - public subsurfaceRadius: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceRadius") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceRadius: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceRadius: Property = new Property("subsurface_radius", 0.1, "vSubsurfaceRadius", 1, 0, "SUBSURFACE_SLAB"); @@ -806,8 +806,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the scale factor applied to the subsurface radius. * See OpenPBR's specs for subsurface_radius_scale */ - public subsurfaceRadiusScale: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceRadiusScale") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceRadiusScale: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceRadiusScale: Property = new Property("subsurface_radius_scale", new Color3(1, 0.5, 0.25), "vSubsurfaceRadiusScale", 3, 0, "SUBSURFACE_SLAB"); @@ -815,8 +815,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Subsurface radius scale texture. * See OpenPBR's specs for subsurface_radius_scale */ - public subsurfaceRadiusScaleTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceRadiusScaleTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceRadiusScaleTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceRadiusScaleTexture: Sampler = new Sampler("subsurface_radius_scale", "subsurfaceRadiusScale", "SUBSURFACE_RADIUS_SCALE"); @@ -824,8 +824,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the anisotropy of the subsurface scattering in the volume. * See OpenPBR's specs for subsurface_scatter_anisotropy */ - public subsurfaceScatterAnisotropy: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "subsurfaceScatterAnisotropy") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor subsurfaceScatterAnisotropy: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _subsurfaceScatterAnisotropy: Property = new Property("subsurface_scatter_anisotropy", 0.0, "vSubsurfaceScatterAnisotropy", 1, 0, "SUBSURFACE_SLAB"); @@ -833,8 +833,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the amount of clear coat on the surface. * See OpenPBR's specs for coat_weight */ - public coatWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatWeight: Property = new Property("coat_weight", 0.0, "vCoatWeight", 1, 0); @@ -842,8 +842,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Coat weight texture. * See OpenPBR's specs for coat_weight */ - public coatWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatWeightTexture: Sampler = new Sampler("coat_weight", "coatWeight", "COAT_WEIGHT"); @@ -851,8 +851,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the color of the clear coat on the surface. * See OpenPBR's specs for coat_color */ - public coatColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatColor: Property = new Property("coat_color", Color3.White(), "vCoatColor", 3, 0); @@ -860,8 +860,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Color texture of the clear coat. * See OpenPBR's specs for coat_color */ - public coatColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatColorTexture: Sampler = new Sampler("coat_color", "coatColor", "COAT_COLOR"); @@ -869,8 +869,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the roughness of the clear coat on the surface. * See OpenPBR's specs for coat_roughness */ - public coatRoughness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatRoughness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatRoughness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatRoughness: Property = new Property("coat_roughness", 0.0, "vCoatRoughness", 1, 0); @@ -878,8 +878,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Roughness texture of the clear coat. * See OpenPBR's specs for coat_roughness */ - public coatRoughnessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatRoughnessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatRoughnessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatRoughnessTexture: Sampler = new Sampler("coat_roughness", "coatRoughness", "COAT_ROUGHNESS"); @@ -887,8 +887,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the anisotropy of the clear coat on the surface. * See OpenPBR's specs for coat_roughness_anisotropy */ - public coatRoughnessAnisotropy: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatRoughnessAnisotropy") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatRoughnessAnisotropy: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatRoughnessAnisotropy: Property = new Property("coat_roughness_anisotropy", 0, "vCoatRoughnessAnisotropy", 1); @@ -896,8 +896,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Anisotropic Roughness texture of the clear coat. * See OpenPBR's specs for coat_roughness_anisotropy */ - public coatRoughnessAnisotropyTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatRoughnessAnisotropyTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatRoughnessAnisotropyTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatRoughnessAnisotropyTexture: Sampler = new Sampler("coat_roughness_anisotropy", "coatRoughnessAnisotropy", "COAT_ROUGHNESS_ANISOTROPY"); @@ -905,8 +905,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the IOR of the clear coat on the surface. * See OpenPBR's specs for coat_ior */ - public coatIor: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatIor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatIor: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatIor: Property = new Property("coat_ior", 1.5, "vCoatIor", 1, 0); @@ -916,8 +916,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * is applied, while a value of 0.0 means that no darkening is applied. * See OpenPBR's specs for coat_darkening */ - public coatDarkening: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatDarkening") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatDarkening: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatDarkening: Property = new Property("coat_darkening", 1.0, "vCoatDarkening", 1, 0); @@ -927,8 +927,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * is applied, while a value of 0.0 means that no darkening is applied. * See OpenPBR's specs for coat_darkening */ - public coatDarkeningTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "coatDarkeningTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor coatDarkeningTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _coatDarkeningTexture: Sampler = new Sampler("coat_darkening", "coatDarkening", "COAT_DARKENING"); @@ -942,8 +942,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the weight of the fuzz layer on the surface. * See OpenPBR's specs for fuzz_weight */ - public fuzzWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor fuzzWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _fuzzWeight: Property = new Property("fuzz_weight", 0.0, "vFuzzWeight", 1, 0); @@ -951,8 +951,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Weight texture of the fuzz layer. * See OpenPBR's specs for fuzz_weight */ - public fuzzWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor fuzzWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _fuzzWeightTexture: Sampler = new Sampler("fuzz_weight", "fuzzWeight", "FUZZ_WEIGHT"); @@ -960,8 +960,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the color of the fuzz layer on the surface. * See OpenPBR's specs for fuzz_color */ - public fuzzColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor fuzzColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _fuzzColor: Property = new Property("fuzz_color", Color3.White(), "vFuzzColor", 3, 0); @@ -969,8 +969,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Color texture of the fuzz layer. * See OpenPBR's specs for fuzz_color */ - public fuzzColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor fuzzColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _fuzzColorTexture: Sampler = new Sampler("fuzz_color", "fuzzColor", "FUZZ_COLOR"); @@ -978,8 +978,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the roughness of the fuzz layer on the surface. * See OpenPBR's specs for fuzz_roughness */ - public fuzzRoughness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzRoughness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor fuzzRoughness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _fuzzRoughness: Property = new Property("fuzz_roughness", 0.5, "vFuzzRoughness", 1, 0); @@ -987,8 +987,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Roughness texture of the fuzz layer. * See OpenPBR's specs for fuzz_roughness */ - public fuzzRoughnessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "fuzzRoughnessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor fuzzRoughnessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _fuzzRoughnessTexture: Sampler = new Sampler("fuzz_roughness", "fuzzRoughness", "FUZZ_ROUGHNESS"); @@ -996,8 +996,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines whether the geometry is thin-walled (like a sheet of paper) or not. * See OpenPBR's specs for geometry_thin_walled */ - public geometryThinWalled: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryThinWalled") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryThinWalled: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryThinWalled: Property = new Property("geometry_thin_walled", 0, "vGeometryThinWalled", 1, 0); @@ -1005,8 +1005,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the normal of the material's geometry. * See OpenPBR's specs for geometry_normal */ - public geometryNormalTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryNormalTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryNormalTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryNormalTexture: Sampler = new Sampler("geometry_normal", "geometryNormal", "GEOMETRY_NORMAL"); @@ -1014,8 +1014,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the tangent of the material's geometry. Used only for anisotropic reflections. * See OpenPBR's specs for geometry_tangent */ - public geometryTangent: Vector2; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryTangent") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryTangent: Vector2; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryTangent: Property = new Property("geometry_tangent", new Vector2(1, 0), "vSpecularAnisotropy", 3, 0); @@ -1035,8 +1035,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the tangent of the material's geometry. Used only for anisotropic reflections. * See OpenPBR's specs for geometry_tangent */ - public geometryTangentTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryTangentTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryTangentTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryTangentTexture: Sampler = new Sampler("geometry_tangent", "geometryTangent", "GEOMETRY_TANGENT"); @@ -1044,8 +1044,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the normal of the material's coat layer. * See OpenPBR's specs for geometry_coat_normal */ - public geometryCoatNormalTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryCoatNormalTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryCoatNormalTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryCoatNormalTexture: Sampler = new Sampler("geometry_coat_normal", "geometryCoatNormal", "GEOMETRY_COAT_NORMAL"); @@ -1053,8 +1053,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the tangent of the material's coat layer. Used only for anisotropic reflections. * See OpenPBR's specs for geometry_coat_tangent */ - public geometryCoatTangent: Vector2; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryCoatTangent") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryCoatTangent: Vector2; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryCoatTangent: Property = new Property("geometry_coat_tangent", new Vector2(1, 0), "vGeometryCoatTangent", 2, 0); @@ -1076,8 +1076,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the tangent of the material's coat layer. Used only for anisotropic reflections. * See OpenPBR's specs for geometry_coat_tangent */ - public geometryCoatTangentTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryCoatTangentTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryCoatTangentTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryCoatTangentTexture: Sampler = new Sampler("geometry_coat_tangent", "geometryCoatTangent", "GEOMETRY_COAT_TANGENT"); @@ -1085,8 +1085,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the opacity of the material's geometry. * See OpenPBR's specs for geometry_opacity */ - public geometryOpacity: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryOpacity") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryOpacity: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryOpacity: Property = new Property("geometry_opacity", 1.0, "vBaseColor", 4, 3); @@ -1094,8 +1094,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the opacity texture of the material's geometry. * See OpenPBR's specs for geometry_opacity */ - public geometryOpacityTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryOpacityTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryOpacityTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryOpacityTexture: Sampler = new Sampler("geometry_opacity", "geometryOpacity", "GEOMETRY_OPACITY"); @@ -1103,8 +1103,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the thickness of the material's geometry. * Not part of OpenPBR's specs but useful for rasterization approximations of volume. */ - public geometryThickness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryThickness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryThickness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryThickness: Property = new Property("geometry_thickness", 0.0, "vGeometryThickness", 1, 0); @@ -1112,8 +1112,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the thickness of the material's geometry. * Not part of OpenPBR's specs but useful for rasterization approximations of volume. */ - public geometryThicknessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "geometryThicknessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor geometryThicknessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _geometryThicknessTexture: Sampler = new Sampler("geometry_thickness", "geometryThickness", "GEOMETRY_THICKNESS"); @@ -1121,8 +1121,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the luminance of the material's emission. * See OpenPBR's specs for emission_luminance */ - public emissionLuminance: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "emissionLuminance") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor emissionLuminance: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _emissionLuminance: Property = new Property("emission_luminance", 1.0, "vLightingIntensity", 4, 1); @@ -1130,8 +1130,8 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the color of the material's emission. * See OpenPBR's specs for emission_color */ - public emissionColor: Color3; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "emissionColor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor emissionColor: Color3; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _emissionColor: Property = new Property("emission_color", Color3.Black(), "vEmissionColor", 3); @@ -1139,24 +1139,24 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * Defines the texture of the material's emission color. * See OpenPBR's specs for emission_color */ - public emissionColorTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "emissionColorTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor emissionColorTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _emissionColorTexture: Sampler = new Sampler("emission_color", "emissionColor", "EMISSION_COLOR"); /** * Defines the weight of the thin film layer on top of the base layer for iridescent effects. */ - public thinFilmWeight: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "thinFilmWeight") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor thinFilmWeight: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _thinFilmWeight: Property = new Property("thin_film_weight", 0.0, "vThinFilmWeight", 1, 0); /** * Thin film weight texture. */ - public thinFilmWeightTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "thinFilmWeightTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor thinFilmWeightTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _thinFilmWeightTexture: Sampler = new Sampler("thin_film_weight", "thinFilmWeight", "THIN_FILM_WEIGHT"); @@ -1165,40 +1165,40 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * this value will act as a multiplier to the texture values. * See OpenPBR's specs for thin_film_thickness */ - public thinFilmThickness: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "thinFilmThickness") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor thinFilmThickness: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _thinFilmThickness: Property = new Property("thin_film_thickness", 0.5, "vThinFilmThickness", 2, 0); /** * Defines the minimum thickness of the thin film layer in μm. */ - public thinFilmThicknessMin: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "thinFilmThicknessMin") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor thinFilmThicknessMin: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _thinFilmThicknessMin: Property = new Property("thin_film_thickness_min", 0.0, "vThinFilmThickness", 2, 1); /** * Defines the maximum thickness of the thin film layer in μm. */ - public thinFilmThicknessTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "thinFilmThicknessTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor thinFilmThicknessTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _thinFilmThicknessTexture: Sampler = new Sampler("thin_film_thickness", "thinFilmThickness", "THIN_FILM_THICKNESS"); /** * Defines the index of refraction of the thin film layer. */ - public thinFilmIor: number; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "thinFilmIor") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor thinFilmIor: number; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _thinFilmIor: Property = new Property("thin_film_ior", 1.4, "vThinFilmIor", 1, 0); /** * Defines the ambient occlusion texture. */ - public ambientOcclusionTexture: Nullable; - @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty", "ambientOcclusionTexture") + @addAccessorsForMaterialProperty("_markAllSubMeshesAsTexturesDirty") + accessor ambientOcclusionTexture: Nullable; // eslint-disable-next-line @typescript-eslint/no-unused-vars private _ambientOcclusionTexture: Sampler = new Sampler("ambient_occlusion", "ambientOcclusion", "AMBIENT_OCCLUSION"); @@ -1282,7 +1282,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public directIntensity: number = 1.0; + public accessor directIntensity: number = 1.0; /** * Intensity of the environment e.g. how much the environment will light the object @@ -1290,42 +1290,42 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public environmentIntensity: number = 1.0; + public accessor environmentIntensity: number = 1.0; /** * Specifies that the specular weight is stored in the alpha channel of the specular weight texture. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useSpecularWeightFromTextureAlpha = false; + public accessor useSpecularWeightFromTextureAlpha = false; /** * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public forceAlphaTest = false; + public accessor forceAlphaTest = false; /** * Defines the alpha limits in alpha test mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public alphaCutOff = 0.4; + public accessor alphaCutOff = 0.4; /** * Specifies if the metallic texture contains the ambient occlusion information in its red channel. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAmbientOcclusionFromMetallicTextureRed = false; + public accessor useAmbientOcclusionFromMetallicTextureRed = false; /** * Specifies if the ambient texture contains the ambient occlusion information in its red channel only. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAmbientInGrayScale = false; + public accessor useAmbientInGrayScale = false; /** * Specifies if we can see through the surface of the material due to subsurface scattering or transmission. @@ -1398,70 +1398,70 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useObjectSpaceNormalMap = false; + public accessor useObjectSpaceNormalMap = false; /** * Allows using the normal map in parallax mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useParallax = false; + public accessor useParallax = false; /** * Allows using the normal map in parallax occlusion mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useParallaxOcclusion = false; + public accessor useParallaxOcclusion = false; /** * Controls the scale bias of the parallax mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public parallaxScaleBias = 0.05; + public accessor parallaxScaleBias = 0.05; /** * If sets to true, disables all the lights affecting the material. */ @serialize() @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting = false; + public accessor disableLighting = false; /** * Force the shader to compute irradiance in the fragment shader in order to take normal mapping into account. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public forceIrradianceInFragment = false; + public accessor forceIrradianceInFragment = false; /** * Number of Simultaneous lights allowed on the material. */ @serialize() @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights = 4; + public accessor maxSimultaneousLights = 4; /** * If sets to true, x component of normal map value will invert (x = 1.0 - x). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapX = false; + public accessor invertNormalMapX = false; /** * If sets to true, y component of normal map value will invert (y = 1.0 - y). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapY = false; + public accessor invertNormalMapY = false; /** * If sets to true and backfaceCulling is false, normals will be flipped on the backside. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public twoSidedLighting = false; + public accessor twoSidedLighting = false; /** * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested. @@ -1469,7 +1469,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAlphaFresnel = false; + public accessor useAlphaFresnel = false; /** * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested. @@ -1477,7 +1477,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useLinearAlphaFresnel = false; + public accessor useLinearAlphaFresnel = false; /** * Let user defines the brdf lookup texture used for IBL. @@ -1488,14 +1488,14 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * * LEGACY Default None correlated 16bit pixel depth https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public environmentBRDFTexture: Nullable = null; + public accessor environmentBRDFTexture: Nullable = null; /** * Force normal to face away from face. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public forceNormalForward = false; + public accessor forceNormalForward = false; /** * Enables specular anti aliasing in the PBR shader. @@ -1504,7 +1504,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public enableSpecularAntiAliasing = false; + public accessor enableSpecularAntiAliasing = false; /** * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal @@ -1512,7 +1512,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useHorizonOcclusion = true; + public accessor useHorizonOcclusion = true; /** * This parameters will enable/disable radiance occlusion by preventing the radiance to lit @@ -1520,21 +1520,21 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRadianceOcclusion = true; + public accessor useRadianceOcclusion = true; /** * If set to true, no lighting calculations will be applied. */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public unlit = false; + public accessor unlit = false; /** * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false) */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public applyDecalMapAfterDetailMap = false; + public accessor applyDecalMapAfterDetailMap = false; /** * Force all the PBR materials to compile to glsl even on WebGPU engines. @@ -1883,7 +1883,7 @@ export class OpenPBRMaterial extends OpenPBRMaterialBase { * It helps seeing only some components of the material while troubleshooting. */ @expandToProperty("_markAllSubMeshesAsMiscDirty") - public debugMode = 0; + public accessor debugMode = 0; /** * @internal diff --git a/packages/dev/core/src/Materials/PBR/pbrAnisotropicConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrAnisotropicConfiguration.ts index ab9b08218126..2a6996d53230 100644 --- a/packages/dev/core/src/Materials/PBR/pbrAnisotropicConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrAnisotropicConfiguration.ts @@ -38,7 +38,7 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; /** * Defines the anisotropy strength (between 0 and 1) it defaults to 1. @@ -77,7 +77,7 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public texture: Nullable = null; + public accessor texture: Nullable = null; private _legacy = false; /** @@ -85,7 +85,7 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public legacy: boolean = false; + public accessor legacy: boolean = false; /** @internal */ private _internalMarkAllSubMeshesAsTexturesDirty: () => void; @@ -120,6 +120,12 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { this._internalMarkAllSubMeshesAsMiscDirty = material._dirtyCallbacks[Constants.MATERIAL_MiscDirtyFlag]; } + /** + * Checks whether the anisotropy configuration is ready for the current submesh. + * @param defines defines the material defines to evaluate + * @param scene defines the scene to use for texture readiness checks + * @returns true if the configuration is ready + */ public override isReadyForSubMesh(defines: MaterialAnisotropicDefines, scene: Scene): boolean { if (!this._isEnabled) { return true; @@ -138,6 +144,12 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { return true; } + /** + * Updates the anisotropy shader defines before attribute processing. + * @param defines defines the material defines to update + * @param scene defines the scene to use for texture define checks + * @param mesh defines the mesh being rendered + */ public override prepareDefinesBeforeAttributes(defines: MaterialAnisotropicDefines, scene: Scene, mesh: AbstractMesh): void { if (this._isEnabled) { defines.ANISOTROPIC = this._isEnabled; @@ -167,6 +179,11 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { } } + /** + * Binds the anisotropy data for the current submesh. + * @param uniformBuffer defines the uniform buffer to update + * @param scene defines the scene the material belongs to + */ public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene): void { if (!this._isEnabled) { return; @@ -192,6 +209,11 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { } } + /** + * Checks whether the anisotropy configuration references a texture. + * @param texture defines the texture to check + * @returns true if the texture is used by the configuration + */ public override hasTexture(texture: BaseTexture): boolean { if (this._texture === texture) { return true; @@ -200,18 +222,30 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { return false; } + /** + * Adds the active anisotropy textures to the provided array. + * @param activeTextures defines the active texture array to update + */ public override getActiveTextures(activeTextures: BaseTexture[]): void { if (this._texture) { activeTextures.push(this._texture); } } + /** + * Adds the animatable anisotropy textures to the provided array. + * @param animatables defines the animatable array to update + */ public override getAnimatables(animatables: IAnimatable[]): void { if (this._texture && this._texture.animations && this._texture.animations.length > 0) { animatables.push(this._texture); } } + /** + * Disposes the anisotropy configuration resources. + * @param forceDisposeTextures defines whether to dispose associated textures + */ public override dispose(forceDisposeTextures?: boolean): void { if (forceDisposeTextures) { if (this._texture) { @@ -231,6 +265,10 @@ export class PBRAnisotropicConfiguration extends MaterialPluginBase { return currentRank; } + /** + * Adds the anisotropy sampler names to the provided array. + * @param samplers defines the sampler array to update + */ public override getSamplers(samplers: string[]): void { samplers.push("anisotropySampler"); } diff --git a/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts index 20c03c07349c..29e8a49f49f0 100644 --- a/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts @@ -83,7 +83,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public useEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION; + public accessor useEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION; private _useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED; /** @@ -96,7 +96,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED; + public accessor useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED; private _useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS; /** @@ -108,7 +108,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS; + public accessor useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS; private _useSpecularGlossinessInputEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION; /** @@ -119,7 +119,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public useSpecularGlossinessInputEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION; + public accessor useSpecularGlossinessInputEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_SPECULAR_GLOSSINESS_INPUT_ENERGY_CONSERVATION; private _mixIblRadianceWithIrradiance = PBRBRDFConfiguration.DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE; /** @@ -129,7 +129,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public mixIblRadianceWithIrradiance = PBRBRDFConfiguration.DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE; + public accessor mixIblRadianceWithIrradiance = PBRBRDFConfiguration.DEFAULT_MIX_IBL_RADIANCE_WITH_IRRADIANCE; private _useLegacySpecularEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION; /** @@ -138,7 +138,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public useLegacySpecularEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION; + public accessor useLegacySpecularEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_LEGACY_SPECULAR_ENERGY_CONSERVATION; private _baseDiffuseModel: number = PBRBRDFConfiguration.DEFAULT_DIFFUSE_MODEL; /** @@ -146,7 +146,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize("baseDiffuseModel") @expandToProperty("_markAllSubMeshesAsMiscDirty") - public baseDiffuseModel: number = PBRBRDFConfiguration.DEFAULT_DIFFUSE_MODEL; + public accessor baseDiffuseModel: number = PBRBRDFConfiguration.DEFAULT_DIFFUSE_MODEL; private _dielectricSpecularModel: number = PBRBRDFConfiguration.DEFAULT_DIELECTRIC_SPECULAR_MODEL; /** @@ -154,7 +154,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize("dielectricSpecularModel") @expandToProperty("_markAllSubMeshesAsMiscDirty") - public dielectricSpecularModel: number = PBRBRDFConfiguration.DEFAULT_DIELECTRIC_SPECULAR_MODEL; + public accessor dielectricSpecularModel: number = PBRBRDFConfiguration.DEFAULT_DIELECTRIC_SPECULAR_MODEL; private _conductorSpecularModel: number = PBRBRDFConfiguration.DEFAULT_CONDUCTOR_SPECULAR_MODEL; /** @@ -162,7 +162,7 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { */ @serialize("conductorSpecularModel") @expandToProperty("_markAllSubMeshesAsMiscDirty") - public conductorSpecularModel: number = PBRBRDFConfiguration.DEFAULT_CONDUCTOR_SPECULAR_MODEL; + public accessor conductorSpecularModel: number = PBRBRDFConfiguration.DEFAULT_CONDUCTOR_SPECULAR_MODEL; /** @internal */ private _internalMarkAllSubMeshesAsMiscDirty: () => void; @@ -187,6 +187,10 @@ export class PBRBRDFConfiguration extends MaterialPluginBase { this._enable(true); } + /** + * Updates the BRDF shader defines. + * @param defines defines the material defines to update + */ public override prepareDefines(defines: MaterialBRDFDefines): void { defines.BRDF_V_HEIGHT_CORRELATED = this._useSmithVisibilityHeightCorrelated; defines.MS_BRDF_ENERGY_CONSERVATION = this._useEnergyConservation && this._useSmithVisibilityHeightCorrelated; diff --git a/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts index 64b368f76937..b12e933b8dcf 100644 --- a/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts @@ -834,7 +834,7 @@ export abstract class PBRBaseMaterial extends PBRBaseMaterialBase { * It helps seeing only some components of the material while troubleshooting. */ @expandToProperty("_markAllSubMeshesAsMiscDirty") - public debugMode = 0; + public accessor debugMode = 0; /** * @internal diff --git a/packages/dev/core/src/Materials/PBR/pbrBaseSimpleMaterial.ts b/packages/dev/core/src/Materials/PBR/pbrBaseSimpleMaterial.ts index 2d80a6515092..58e3891ab224 100644 --- a/packages/dev/core/src/Materials/PBR/pbrBaseSimpleMaterial.ts +++ b/packages/dev/core/src/Materials/PBR/pbrBaseSimpleMaterial.ts @@ -17,77 +17,77 @@ export abstract class PBRBaseSimpleMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights = 4; + public accessor maxSimultaneousLights = 4; /** * If sets to true, disables all the lights affecting the material. */ @serialize() @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting = false; + public accessor disableLighting = false; /** * Environment Texture used in the material (this is use for both reflection and environment lighting). */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_reflectionTexture") - public environmentTexture: Nullable; + public accessor environmentTexture: Nullable; /** * If sets to true, x component of normal map value will invert (x = 1.0 - x). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapX = false; + public accessor invertNormalMapX = false; /** * If sets to true, y component of normal map value will invert (y = 1.0 - y). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapY = false; + public accessor invertNormalMapY = false; /** * Normal map used in the model. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_bumpTexture") - public normalTexture: Nullable; + public accessor normalTexture: Nullable; /** * Emissivie color used to self-illuminate the model. */ @serializeAsColor3("emissive") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public emissiveColor = new Color3(0, 0, 0); + public accessor emissiveColor = new Color3(0, 0, 0); /** * Emissivie texture used to self-illuminate the model. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public emissiveTexture: Nullable; + public accessor emissiveTexture: Nullable; /** * Occlusion Channel Strength. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_ambientTextureStrength") - public occlusionStrength: number = 1.0; + public accessor occlusionStrength: number = 1.0; /** * Occlusion Texture of the material (adding extra occlusion effects). */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_ambientTexture") - public occlusionTexture: Nullable; + public accessor occlusionTexture: Nullable; /** * Defines the alpha limits in alpha test mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_alphaCutOff") - public alphaCutOff: number; + public accessor alphaCutOff: number; /** * Gets the current double sided mode. @@ -113,14 +113,14 @@ export abstract class PBRBaseSimpleMaterial extends PBRBaseMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", null) - public lightmapTexture: Nullable; + public accessor lightmapTexture: Nullable; /** * If true, the light map contains occlusion information instead of lighting info. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useLightmapAsShadowmap = false; + public accessor useLightmapAsShadowmap = false; /** * Instantiates a new PBRMaterial instance. diff --git a/packages/dev/core/src/Materials/PBR/pbrClearCoatConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrClearCoatConfiguration.ts index abd09119d2c3..949c02ce4b9e 100644 --- a/packages/dev/core/src/Materials/PBR/pbrClearCoatConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrClearCoatConfiguration.ts @@ -42,7 +42,7 @@ export class MaterialClearCoatDefines extends MaterialDefines { * Plugin that implements the clear coat component of the PBR material */ export class PBRClearCoatConfiguration extends MaterialPluginBase { - protected override _material: PBRBaseMaterial; + declare protected _material: PBRBaseMaterial; /** * This defaults to 1.5 corresponding to a 0.04 f0 or a 4% reflectance at normal incidence @@ -57,7 +57,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; /** * Defines the clear coat layer strength (between 0 and 1) it defaults to 1. @@ -80,7 +80,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public indexOfRefraction = PBRClearCoatConfiguration._DefaultIndexOfRefraction; + public accessor indexOfRefraction = PBRClearCoatConfiguration._DefaultIndexOfRefraction; private _texture: Nullable = null; /** @@ -90,7 +90,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public texture: Nullable = null; + public accessor texture: Nullable = null; private _useRoughnessFromMainTexture = true; /** @@ -99,7 +99,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRoughnessFromMainTexture = true; + public accessor useRoughnessFromMainTexture = true; private _textureRoughness: Nullable = null; /** @@ -108,7 +108,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public textureRoughness: Nullable = null; + public accessor textureRoughness: Nullable = null; private _remapF0OnInterfaceChange = true; /** @@ -116,7 +116,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public remapF0OnInterfaceChange = true; + public accessor remapF0OnInterfaceChange = true; private _bumpTexture: Nullable = null; /** @@ -124,7 +124,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture: Nullable = null; + public accessor bumpTexture: Nullable = null; private _isTintEnabled = false; /** @@ -132,7 +132,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isTintEnabled = false; + public accessor isTintEnabled = false; /** * Defines the clear coat tint of the material. @@ -164,7 +164,7 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public tintTexture: Nullable = null; + public accessor tintTexture: Nullable = null; /** @internal */ private _internalMarkAllSubMeshesAsTexturesDirty: () => void; @@ -189,6 +189,13 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag]; } + /** + * Checks whether the clear coat configuration is ready for the current submesh. + * @param defines defines the material defines to evaluate + * @param scene defines the scene to use for texture readiness checks + * @param engine defines the engine to use for capability checks + * @returns true if the configuration is ready + */ public override isReadyForSubMesh(defines: MaterialClearCoatDefines, scene: Scene, engine: Engine): boolean { if (!this._isEnabled) { return true; @@ -227,6 +234,11 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { return true; } + /** + * Updates the clear coat shader defines before attribute processing. + * @param defines defines the material defines to update + * @param scene defines the scene to use for texture define checks + */ public override prepareDefinesBeforeAttributes(defines: MaterialClearCoatDefines, scene: Scene): void { if (this._isEnabled) { defines.CLEARCOAT = true; @@ -287,6 +299,13 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { } } + /** + * Binds the clear coat data for the current submesh. + * @param uniformBuffer defines the uniform buffer to update + * @param scene defines the scene the material belongs to + * @param engine defines the engine to use for capability checks + * @param subMesh defines the submesh being rendered + */ public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void { if (!this._isEnabled) { return; @@ -369,6 +388,11 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { } } + /** + * Checks whether the clear coat configuration references a texture. + * @param texture defines the texture to check + * @returns true if the texture is used by the configuration + */ public override hasTexture(texture: BaseTexture): boolean { if (this._texture === texture) { return true; @@ -389,6 +413,10 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { return false; } + /** + * Adds the active clear coat textures to the provided array. + * @param activeTextures defines the active texture array to update + */ public override getActiveTextures(activeTextures: BaseTexture[]): void { if (this._texture) { activeTextures.push(this._texture); @@ -407,6 +435,10 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { } } + /** + * Adds the animatable clear coat textures to the provided array. + * @param animatables defines the animatable array to update + */ public override getAnimatables(animatables: IAnimatable[]): void { if (this._texture && this._texture.animations && this._texture.animations.length > 0) { animatables.push(this._texture); @@ -425,6 +457,10 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { } } + /** + * Disposes the clear coat configuration resources. + * @param forceDisposeTextures defines whether to dispose associated textures + */ public override dispose(forceDisposeTextures?: boolean): void { if (forceDisposeTextures) { this._texture?.dispose(); @@ -451,6 +487,10 @@ export class PBRClearCoatConfiguration extends MaterialPluginBase { return currentRank; } + /** + * Adds the clear coat sampler names to the provided array. + * @param samplers defines the sampler array to update + */ public override getSamplers(samplers: string[]): void { samplers.push("clearCoatSampler", "clearCoatRoughnessSampler", "clearCoatBumpSampler", "clearCoatTintSampler"); } diff --git a/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts index 5d563cfc554e..ec08232a716c 100644 --- a/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts @@ -29,7 +29,7 @@ export class MaterialIridescenceDefines extends MaterialDefines { * Plugin that implements the iridescence (thin film) component of the PBR material */ export class PBRIridescenceConfiguration extends MaterialPluginBase { - protected override _material: PBRBaseMaterial; + declare protected _material: PBRBaseMaterial; /** * The default minimum thickness of the thin-film layer given in nanometers (nm). @@ -58,7 +58,7 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; /** * Defines the iridescence layer strength (between 0 and 1) it defaults to 1. @@ -90,7 +90,7 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public texture: Nullable = null; + public accessor texture: Nullable = null; private _thicknessTexture: Nullable = null; /** @@ -98,7 +98,7 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public thicknessTexture: Nullable = null; + public accessor thicknessTexture: Nullable = null; /** @internal */ private _internalMarkAllSubMeshesAsTexturesDirty: () => void; @@ -123,6 +123,12 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag]; } + /** + * Checks whether the iridescence configuration is ready for the current submesh. + * @param defines defines the material defines to evaluate + * @param scene defines the scene to use for texture readiness checks + * @returns true if the configuration is ready + */ public override isReadyForSubMesh(defines: MaterialIridescenceDefines, scene: Scene): boolean { if (!this._isEnabled) { return true; @@ -147,6 +153,11 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { return true; } + /** + * Updates the iridescence shader defines before attribute processing. + * @param defines defines the material defines to update + * @param scene defines the scene to use for texture define checks + */ public override prepareDefinesBeforeAttributes(defines: MaterialIridescenceDefines, scene: Scene): void { if (this._isEnabled) { defines.IRIDESCENCE = true; @@ -175,6 +186,11 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { } } + /** + * Binds the iridescence data for the current submesh. + * @param uniformBuffer defines the uniform buffer to update + * @param scene defines the scene the material belongs to + */ public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene): void { if (!this._isEnabled) { return; @@ -215,6 +231,11 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { } } + /** + * Checks whether the iridescence configuration references a texture. + * @param texture defines the texture to check + * @returns true if the texture is used by the configuration + */ public override hasTexture(texture: BaseTexture): boolean { if (this._texture === texture) { return true; @@ -227,6 +248,10 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { return false; } + /** + * Adds the active iridescence textures to the provided array. + * @param activeTextures defines the active texture array to update + */ public override getActiveTextures(activeTextures: BaseTexture[]): void { if (this._texture) { activeTextures.push(this._texture); @@ -237,6 +262,10 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { } } + /** + * Adds the animatable iridescence textures to the provided array. + * @param animatables defines the animatable array to update + */ public override getAnimatables(animatables: IAnimatable[]): void { if (this._texture && this._texture.animations && this._texture.animations.length > 0) { animatables.push(this._texture); @@ -247,6 +276,10 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { } } + /** + * Disposes the iridescence configuration resources. + * @param forceDisposeTextures defines whether to dispose associated textures + */ public override dispose(forceDisposeTextures?: boolean): void { if (forceDisposeTextures) { this._texture?.dispose(); @@ -265,6 +298,10 @@ export class PBRIridescenceConfiguration extends MaterialPluginBase { return currentRank; } + /** + * Adds the iridescence sampler names to the provided array. + * @param samplers defines the sampler array to update + */ public override getSamplers(samplers: string[]): void { samplers.push("iridescenceSampler", "iridescenceThicknessSampler"); } diff --git a/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts index 62e492d212dc..3d890d5ab7a9 100644 --- a/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts @@ -52,7 +52,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public directIntensity: number = 1.0; + public accessor directIntensity: number = 1.0; /** * Intensity of the emissive part of the material. @@ -60,7 +60,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public emissiveIntensity: number = 1.0; + public accessor emissiveIntensity: number = 1.0; /** * Intensity of the environment e.g. how much the environment will light the object @@ -68,7 +68,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public environmentIntensity: number = 1.0; + public accessor environmentIntensity: number = 1.0; /** * This is a special control allowing the reduction of the specular highlights coming from the @@ -76,49 +76,49 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public specularIntensity: number = 1.0; + public accessor specularIntensity: number = 1.0; /** * Debug Control allowing disabling the bump map on this material. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public disableBumpMap: boolean = false; + public accessor disableBumpMap: boolean = false; /** * AKA Diffuse Texture in standard nomenclature. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public albedoTexture: Nullable; + public accessor albedoTexture: Nullable; /** * OpenPBR Base Weight texture (multiplier to the diffuse and metal lobes). */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public baseWeightTexture: Nullable; + public accessor baseWeightTexture: Nullable; /** * OpenPBR Base Diffuse Roughness texture (roughness of the diffuse lobe). */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public baseDiffuseRoughnessTexture: Nullable; + public accessor baseDiffuseRoughnessTexture: Nullable; /** * AKA Occlusion Texture in other nomenclature. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public ambientTexture: Nullable; + public accessor ambientTexture: Nullable; /** * AKA Occlusion Texture Intensity in other nomenclature. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public ambientTextureStrength: number = 1.0; + public accessor ambientTextureStrength: number = 1.0; /** * Defines how much the AO map is occluding the analytical lights (point spot...). @@ -127,42 +127,42 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public ambientTextureImpactOnAnalyticalLights: number = PBRMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS; + public accessor ambientTextureImpactOnAnalyticalLights: number = PBRMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS; /** * Stores the alpha values in a texture. Use luminance if texture.getAlphaFromRGB is true. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public opacityTexture: Nullable; + public accessor opacityTexture: Nullable; /** * Stores the reflection values in a texture. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionTexture: Nullable; + public accessor reflectionTexture: Nullable; /** * Stores the emissive values in a texture. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public emissiveTexture: Nullable; + public accessor emissiveTexture: Nullable; /** * AKA Specular texture in other nomenclature. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectivityTexture: Nullable; + public accessor reflectivityTexture: Nullable; /** * Used to switch from specular/glossiness to metallic/roughness workflow. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallicTexture: Nullable; + public accessor metallicTexture: Nullable; /** * Specifies the metallic scalar of the metallic/roughness workflow. @@ -170,7 +170,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallic: Nullable; + public accessor metallic: Nullable; /** * Specifies the roughness scalar of the metallic/roughness workflow. @@ -178,7 +178,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public roughness: Nullable; + public accessor roughness: Nullable; /** * In metallic workflow, specifies an F0 factor to help configuring the material F0. @@ -191,7 +191,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallicF0Factor = 1; + public accessor metallicF0Factor = 1; /** * In metallic workflow, specifies an F0 color. @@ -204,7 +204,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serializeAsColor3() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallicReflectanceColor = Color3.White(); + public accessor metallicReflectanceColor = Color3.White(); /** * Specifies that only the A channel from metallicReflectanceTexture should be used. @@ -212,7 +212,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useOnlyMetallicFromMetallicReflectanceTexture = false; + public accessor useOnlyMetallicFromMetallicReflectanceTexture = false; /** * Defines to store metallicReflectanceColor in RGB and metallicF0Factor in A @@ -221,7 +221,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallicReflectanceTexture: Nullable; + public accessor metallicReflectanceTexture: Nullable; /** * Defines to store reflectanceColor in RGB @@ -231,7 +231,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectanceTexture: Nullable; + public accessor reflectanceTexture: Nullable; /** * Used to enable roughness/glossiness fetch from a separate channel depending on the current mode. @@ -239,21 +239,21 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public microSurfaceTexture: Nullable; + public accessor microSurfaceTexture: Nullable; /** * Stores surface normal data used to displace a mesh in a texture. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture: Nullable; + public accessor bumpTexture: Nullable; /** * Stores the pre-calculated light information of a mesh in a texture. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", null) - public lightmapTexture: Nullable; + public accessor lightmapTexture: Nullable; /** * Stores the refracted light information in a texture. @@ -275,56 +275,56 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serializeAsColor3("ambient") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public ambientColor = new Color3(0, 0, 0); + public accessor ambientColor = new Color3(0, 0, 0); /** * AKA Diffuse Color in other nomenclature. */ @serializeAsColor3("albedo") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public albedoColor = new Color3(1, 1, 1); + public accessor albedoColor = new Color3(1, 1, 1); /** * OpenPBR Base Weight (multiplier to the diffuse and metal lobes). */ @serialize("baseWeight") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public baseWeight = 1; + public accessor baseWeight = 1; /** * OpenPBR Base Diffuse Roughness (roughness of the diffuse lobe). */ @serialize("baseDiffuseRoughness") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public baseDiffuseRoughness: Nullable; + public accessor baseDiffuseRoughness: Nullable; /** * AKA Specular Color in other nomenclature. */ @serializeAsColor3("reflectivity") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectivityColor = new Color3(1, 1, 1); + public accessor reflectivityColor = new Color3(1, 1, 1); /** * The color reflected from the material. */ @serializeAsColor3("reflection") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionColor = new Color3(1.0, 1.0, 1.0); + public accessor reflectionColor = new Color3(1.0, 1.0, 1.0); /** * The color emitted from the material. */ @serializeAsColor3("emissive") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public emissiveColor = new Color3(0, 0, 0); + public accessor emissiveColor = new Color3(0, 0, 0); /** * AKA Glossiness in other nomenclature. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public microSurface = 1.0; + public accessor microSurface = 1.0; /** * Index of refraction of the material base layer. @@ -370,28 +370,28 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useLightmapAsShadowmap = false; + public accessor useLightmapAsShadowmap = false; /** * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public useAlphaFromAlbedoTexture = false; + public accessor useAlphaFromAlbedoTexture = false; /** * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public forceAlphaTest = false; + public accessor forceAlphaTest = false; /** * Defines the alpha limits in alpha test mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public alphaCutOff = 0.4; + public accessor alphaCutOff = 0.4; /** * Specifies that the material will keep the specular highlights over a transparent surface (only the most luminous ones). @@ -399,21 +399,21 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useSpecularOverAlpha = true; + public accessor useSpecularOverAlpha = true; /** * Specifies if the reflectivity texture contains the glossiness information in its alpha channel. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useMicroSurfaceFromReflectivityMapAlpha = false; + public accessor useMicroSurfaceFromReflectivityMapAlpha = false; /** * Specifies if the metallic texture contains the roughness information in its alpha channel. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRoughnessFromMetallicTextureAlpha = true; + public accessor useRoughnessFromMetallicTextureAlpha = true; /** * Specifies if the metallic texture contains the roughness information in its green channel. @@ -421,28 +421,28 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRoughnessFromMetallicTextureGreen = false; + public accessor useRoughnessFromMetallicTextureGreen = false; /** * Specifies if the metallic texture contains the metallness information in its blue channel. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useMetallnessFromMetallicTextureBlue = false; + public accessor useMetallnessFromMetallicTextureBlue = false; /** * Specifies if the metallic texture contains the ambient occlusion information in its red channel. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAmbientOcclusionFromMetallicTextureRed = false; + public accessor useAmbientOcclusionFromMetallicTextureRed = false; /** * Specifies if the ambient texture contains the ambient occlusion information in its red channel only. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAmbientInGrayScale = false; + public accessor useAmbientInGrayScale = false; /** * In case the reflectivity map does not contain the microsurface information in its alpha channel, @@ -450,7 +450,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAutoMicroSurfaceFromReflectivityMap = false; + public accessor useAutoMicroSurfaceFromReflectivityMap = false; /** * BJS is using an hardcoded light falloff based on a manually sets up range. @@ -512,77 +512,77 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRadianceOverAlpha = true; + public accessor useRadianceOverAlpha = true; /** * Allows using an object space normal map (instead of tangent space). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useObjectSpaceNormalMap = false; + public accessor useObjectSpaceNormalMap = false; /** * Allows using the bump map in parallax mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useParallax = false; + public accessor useParallax = false; /** * Allows using the bump map in parallax occlusion mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useParallaxOcclusion = false; + public accessor useParallaxOcclusion = false; /** * Controls the scale bias of the parallax mode. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public parallaxScaleBias = 0.05; + public accessor parallaxScaleBias = 0.05; /** * If sets to true, disables all the lights affecting the material. */ @serialize() @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting = false; + public accessor disableLighting = false; /** * Force the shader to compute irradiance in the fragment shader in order to take bump in account. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public forceIrradianceInFragment = false; + public accessor forceIrradianceInFragment = false; /** * Number of Simultaneous lights allowed on the material. */ @serialize() @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights = 4; + public accessor maxSimultaneousLights = 4; /** * If sets to true, x component of normal map value will invert (x = 1.0 - x). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapX = false; + public accessor invertNormalMapX = false; /** * If sets to true, y component of normal map value will invert (y = 1.0 - y). */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapY = false; + public accessor invertNormalMapY = false; /** * If sets to true and backfaceCulling is false, normals will be flipped on the backside. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public twoSidedLighting = false; + public accessor twoSidedLighting = false; /** * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested. @@ -590,7 +590,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAlphaFresnel = false; + public accessor useAlphaFresnel = false; /** * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested. @@ -598,7 +598,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useLinearAlphaFresnel = false; + public accessor useLinearAlphaFresnel = false; /** * Let user defines the brdf lookup texture used for IBL. @@ -609,14 +609,14 @@ export class PBRMaterial extends PBRBaseMaterial { * * LEGACY Default None correlated 16bit pixel depth https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public environmentBRDFTexture: Nullable = null; + public accessor environmentBRDFTexture: Nullable = null; /** * Force normal to face away from face. */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public forceNormalForward = false; + public accessor forceNormalForward = false; /** * Enables specular anti aliasing in the PBR shader. @@ -625,7 +625,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public enableSpecularAntiAliasing = false; + public accessor enableSpecularAntiAliasing = false; /** * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal @@ -633,7 +633,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useHorizonOcclusion = true; + public accessor useHorizonOcclusion = true; /** * This parameters will enable/disable radiance occlusion by preventing the radiance to lit @@ -641,21 +641,21 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRadianceOcclusion = true; + public accessor useRadianceOcclusion = true; /** * If set to true, no lighting calculations will be applied. */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public unlit = false; + public accessor unlit = false; /** * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false) */ @serialize() @expandToProperty("_markAllSubMeshesAsMiscDirty") - public applyDecalMapAfterDetailMap = false; + public accessor applyDecalMapAfterDetailMap = false; /** * Instantiates a new PBRMaterial instance. diff --git a/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts index a40e676b20fb..253af21e141d 100644 --- a/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts @@ -24,7 +24,7 @@ export class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial { */ @serializeAsColor3() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_albedoColor") - public baseColor: Color3; + public accessor baseColor: Color3; /** * Base texture of the metallic workflow. It contains both the baseColor information in RGB as @@ -32,7 +32,7 @@ export class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_albedoTexture") - public baseTexture: Nullable; + public accessor baseTexture: Nullable; /** * Specifies the metallic scalar value of the material. @@ -40,7 +40,7 @@ export class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallic: number; + public accessor metallic: number; /** * Specifies the roughness scalar value of the material. @@ -48,7 +48,7 @@ export class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public roughness: number; + public accessor roughness: number; /** * Texture containing both the metallic value in the B channel and the @@ -56,7 +56,7 @@ export class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_metallicTexture") - public metallicRoughnessTexture: Nullable; + public accessor metallicRoughnessTexture: Nullable; /** * Instantiates a new PBRMetalRoughnessMaterial instance. diff --git a/packages/dev/core/src/Materials/PBR/pbrSheenConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrSheenConfiguration.ts index 178532345706..72671080f268 100644 --- a/packages/dev/core/src/Materials/PBR/pbrSheenConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrSheenConfiguration.ts @@ -43,7 +43,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; private _linkSheenWithAlbedo = false; /** @@ -51,7 +51,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public linkSheenWithAlbedo = false; + public accessor linkSheenWithAlbedo = false; /** * Defines the sheen intensity. @@ -74,7 +74,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public texture: Nullable = null; + public accessor texture: Nullable = null; private _useRoughnessFromMainTexture = true; /** @@ -83,7 +83,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useRoughnessFromMainTexture = true; + public accessor useRoughnessFromMainTexture = true; private _roughness: Nullable = null; /** @@ -93,7 +93,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public roughness: Nullable = null; + public accessor roughness: Nullable = null; private _textureRoughness: Nullable = null; /** @@ -102,7 +102,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public textureRoughness: Nullable = null; + public accessor textureRoughness: Nullable = null; private _albedoScaling = false; /** @@ -112,7 +112,7 @@ export class PBRSheenConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public albedoScaling = false; + public accessor albedoScaling = false; /** @internal */ private _internalMarkAllSubMeshesAsTexturesDirty: () => void; @@ -137,6 +137,12 @@ export class PBRSheenConfiguration extends MaterialPluginBase { this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag]; } + /** + * Checks whether the sheen configuration is ready for the current submesh. + * @param defines defines the material defines to evaluate + * @param scene defines the scene to use for texture readiness checks + * @returns true if the configuration is ready + */ public override isReadyForSubMesh(defines: MaterialSheenDefines, scene: Scene): boolean { if (!this._isEnabled) { return true; @@ -161,6 +167,11 @@ export class PBRSheenConfiguration extends MaterialPluginBase { return true; } + /** + * Updates the sheen shader defines before attribute processing. + * @param defines defines the material defines to update + * @param scene defines the scene to use for texture define checks + */ public override prepareDefinesBeforeAttributes(defines: MaterialSheenDefines, scene: Scene): void { if (this._isEnabled) { defines.SHEEN = true; @@ -199,6 +210,13 @@ export class PBRSheenConfiguration extends MaterialPluginBase { } } + /** + * Binds the sheen data for the current submesh. + * @param uniformBuffer defines the uniform buffer to update + * @param scene defines the scene the material belongs to + * @param engine defines the engine the material belongs to + * @param subMesh defines the submesh being rendered + */ public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void { if (!this._isEnabled) { return; @@ -245,6 +263,11 @@ export class PBRSheenConfiguration extends MaterialPluginBase { } } + /** + * Checks whether the sheen configuration references a texture. + * @param texture defines the texture to check + * @returns true if the texture is used by the configuration + */ public override hasTexture(texture: BaseTexture): boolean { if (this._texture === texture) { return true; @@ -257,6 +280,10 @@ export class PBRSheenConfiguration extends MaterialPluginBase { return false; } + /** + * Adds the active sheen textures to the provided array. + * @param activeTextures defines the active texture array to update + */ public override getActiveTextures(activeTextures: BaseTexture[]): void { if (this._texture) { activeTextures.push(this._texture); @@ -267,6 +294,10 @@ export class PBRSheenConfiguration extends MaterialPluginBase { } } + /** + * Adds the animatable sheen textures to the provided array. + * @param animatables defines the animatable array to update + */ public override getAnimatables(animatables: IAnimatable[]): void { if (this._texture && this._texture.animations && this._texture.animations.length > 0) { animatables.push(this._texture); @@ -277,6 +308,10 @@ export class PBRSheenConfiguration extends MaterialPluginBase { } } + /** + * Disposes the sheen configuration resources. + * @param forceDisposeTextures defines whether to dispose associated textures + */ public override dispose(forceDisposeTextures?: boolean): void { if (forceDisposeTextures) { this._texture?.dispose(); @@ -295,6 +330,10 @@ export class PBRSheenConfiguration extends MaterialPluginBase { return currentRank; } + /** + * Adds the sheen sampler names to the provided array. + * @param samplers defines the sampler array to update + */ public override getSamplers(samplers: string[]): void { samplers.push("sheenSampler", "sheenRoughnessSampler"); } diff --git a/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts index cf16a382cd7f..2f7bcc444951 100644 --- a/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts @@ -21,7 +21,7 @@ export class PBRSpecularGlossinessMaterial extends PBRBaseSimpleMaterial { */ @serializeAsColor3("diffuse") @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_albedoColor") - public diffuseColor: Color3; + public accessor diffuseColor: Color3; /** * Specifies the diffuse texture of the material. This can also contains the opacity value in its alpha @@ -29,28 +29,28 @@ export class PBRSpecularGlossinessMaterial extends PBRBaseSimpleMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_albedoTexture") - public diffuseTexture: Nullable; + public accessor diffuseTexture: Nullable; /** * Specifies the specular color of the material. This indicates how reflective is the material (none to mirror). */ @serializeAsColor3("specular") @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_reflectivityColor") - public specularColor: Color3; + public accessor specularColor: Color3; /** * Specifies the glossiness of the material. This indicates "how sharp is the reflection". */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_microSurface") - public glossiness: number; + public accessor glossiness: number; /** * Specifies both the specular color RGB and the glossiness A of the material per pixels. */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty", "_reflectivityTexture") - public specularGlossinessTexture: Nullable; + public accessor specularGlossinessTexture: Nullable; /** * Specifies if the reflectivity texture contains the glossiness information in its alpha channel. diff --git a/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts index 65d7a2eb5dd9..6d44fa299397 100644 --- a/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts +++ b/packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts @@ -83,7 +83,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ public static DEFAULT_LEGACY_TRANSLUCENCY = false; - protected override _material: PBRBaseMaterial; + declare protected _material: PBRBaseMaterial; private _isRefractionEnabled = false; /** @@ -91,7 +91,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isRefractionEnabled = false; + public accessor isRefractionEnabled = false; private _isTranslucencyEnabled = false; /** @@ -99,7 +99,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isTranslucencyEnabled = false; + public accessor isTranslucencyEnabled = false; private _isDispersionEnabled = false; /** @@ -107,7 +107,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isDispersionEnabled = false; + public accessor isDispersionEnabled = false; private _isScatteringEnabled = false; /** @@ -115,7 +115,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markScenePrePassDirty") - public isScatteringEnabled = false; + public accessor isScatteringEnabled = false; @serialize() private _scatteringDiffusionProfileIndex = 0; @@ -166,7 +166,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAlbedoToTintRefraction: boolean = false; + public accessor useAlbedoToTintRefraction: boolean = false; private _useAlbedoToTintTranslucency = false; /** @@ -174,7 +174,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useAlbedoToTintTranslucency: boolean = false; + public accessor useAlbedoToTintTranslucency: boolean = false; private _thicknessTexture: Nullable = null; /** @@ -186,7 +186,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public thicknessTexture: Nullable = null; + public accessor thicknessTexture: Nullable = null; private _refractionTexture: Nullable = null; /** @@ -194,7 +194,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public refractionTexture: Nullable = null; + public accessor refractionTexture: Nullable = null; /** @internal */ public _indexOfRefraction = 1.5; @@ -208,7 +208,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public indexOfRefraction = 1.5; + public accessor indexOfRefraction = 1.5; @serialize() private _volumeIndexOfRefraction = -1.0; @@ -220,7 +220,6 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { * This ONLY impacts refraction. If not provided or given a non-valid value, * the volume will use the same IOR as the surface. */ - @expandToProperty("_markAllSubMeshesAsTexturesDirty") public get volumeIndexOfRefraction(): number { if (this._volumeIndexOfRefraction >= 1.0) { return this._volumeIndexOfRefraction; @@ -228,11 +227,12 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { return this._indexOfRefraction; } public set volumeIndexOfRefraction(value: number) { - if (value >= 1.0) { - this._volumeIndexOfRefraction = value; - } else { - this._volumeIndexOfRefraction = -1.0; + const volumeIndexOfRefraction = value >= 1.0 ? value : -1.0; + if (this._volumeIndexOfRefraction === volumeIndexOfRefraction) { + return; } + this._volumeIndexOfRefraction = volumeIndexOfRefraction; + this._markAllSubMeshesAsTexturesDirty(); } private _invertRefractionY = false; @@ -241,7 +241,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertRefractionY = false; + public accessor invertRefractionY = false; /** @internal */ public _linkRefractionWithTransparency = false; @@ -251,7 +251,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public linkRefractionWithTransparency = false; + public accessor linkRefractionWithTransparency = false; /** * Defines the minimum thickness stored in the thickness map. @@ -308,7 +308,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useMaskFromThicknessTexture: boolean = false; + public accessor useMaskFromThicknessTexture: boolean = false; private _refractionIntensityTexture: Nullable = null; /** @@ -317,7 +317,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public refractionIntensityTexture: Nullable = null; + public accessor refractionIntensityTexture: Nullable = null; private _translucencyIntensityTexture: Nullable = null; /** @@ -326,7 +326,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public translucencyIntensityTexture: Nullable = null; + public accessor translucencyIntensityTexture: Nullable = null; /** * Defines the translucency tint of the material. @@ -343,7 +343,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public translucencyColorTexture: Nullable = null; + public accessor translucencyColorTexture: Nullable = null; private _useGltfStyleTextures = true; /** @@ -354,7 +354,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useGltfStyleTextures: boolean = true; + public accessor useGltfStyleTextures: boolean = true; /** * This property only exists for backward compatibility reasons. @@ -419,6 +419,12 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { this._internalMarkScenePrePassDirty = material._dirtyCallbacks[Constants.MATERIAL_PrePassDirtyFlag]; } + /** + * Checks whether the subsurface configuration is ready for the current submesh. + * @param defines defines the material defines to evaluate + * @param scene defines the scene to use for texture readiness checks + * @returns true if the configuration is ready + */ public override isReadyForSubMesh(defines: MaterialSubSurfaceDefines, scene: Scene): boolean { if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) { return true; @@ -462,6 +468,11 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { return true; } + /** + * Updates the subsurface shader defines before attribute processing. + * @param defines defines the material defines to update + * @param scene defines the scene to use for texture define checks + */ public override prepareDefinesBeforeAttributes(defines: MaterialSubSurfaceDefines, scene: Scene): void { if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) { defines.SUBSURFACE = false; @@ -599,6 +610,13 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { } } + /** + * Binds the subsurface data for the current submesh. + * @param uniformBuffer defines the uniform buffer to update + * @param scene defines the scene the material belongs to + * @param engine defines the engine the material belongs to + * @param subMesh defines the submesh being rendered + */ public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene, engine: Engine, subMesh: SubMesh): void { if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) { return; @@ -744,6 +762,11 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { } } + /** + * Checks whether the subsurface configuration references a texture. + * @param texture defines the texture to check + * @returns true if the texture is used by the configuration + */ public override hasTexture(texture: BaseTexture): boolean { if (this._thicknessTexture === texture) { return true; @@ -776,6 +799,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { return false; } + /** + * Adds the active subsurface textures to the provided array. + * @param activeTextures defines the active texture array to update + */ public override getActiveTextures(activeTextures: BaseTexture[]): void { if (this._thicknessTexture) { activeTextures.push(this._thicknessTexture); @@ -798,6 +825,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { } } + /** + * Adds the animatable subsurface textures to the provided array. + * @param animatables defines the animatable array to update + */ public override getAnimatables(animatables: IAnimatable[]): void { if (this._thicknessTexture && this._thicknessTexture.animations && this._thicknessTexture.animations.length > 0) { animatables.push(this._thicknessTexture); @@ -820,6 +851,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { } } + /** + * Disposes the subsurface configuration resources. + * @param forceDisposeTextures defines whether to dispose associated textures + */ public override dispose(forceDisposeTextures?: boolean): void { if (forceDisposeTextures) { if (this._thicknessTexture) { @@ -858,6 +893,10 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase { return currentRank; } + /** + * Adds the subsurface sampler names to the provided array. + * @param samplers defines the sampler array to update + */ public override getSamplers(samplers: string[]): void { samplers.push( "thicknessSampler", diff --git a/packages/dev/core/src/Materials/imageProcessing.ts b/packages/dev/core/src/Materials/imageProcessing.ts index 1842a0771063..15c3b7af61ba 100644 --- a/packages/dev/core/src/Materials/imageProcessing.ts +++ b/packages/dev/core/src/Materials/imageProcessing.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { serializeAsImageProcessingConfiguration } from "../Misc/decorators"; +import { GetDirectStoreFromMetadata } from "../Misc/decorators.functions"; import { type Nullable } from "../types"; import { type ImageProcessingConfiguration } from "./imageProcessingConfiguration"; import { type Observer } from "../Misc/observable"; @@ -20,9 +20,17 @@ export function ImageProcessingMixin void; diff --git a/packages/dev/core/src/Materials/material.detailMapConfiguration.ts b/packages/dev/core/src/Materials/material.detailMapConfiguration.ts index 1b63b95dac95..97e3689a5ee7 100644 --- a/packages/dev/core/src/Materials/material.detailMapConfiguration.ts +++ b/packages/dev/core/src/Materials/material.detailMapConfiguration.ts @@ -40,7 +40,7 @@ export class DetailMapConfiguration extends MaterialPluginBase { */ @serializeAsTexture("detailTexture") @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public texture: Nullable; + public accessor texture: Nullable; /** * Defines how strongly the detail diffuse/albedo channel is blended with the regular diffuse/albedo texture @@ -69,7 +69,7 @@ export class DetailMapConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public normalBlendMethod: number; + public accessor normalBlendMethod: number; private _isEnabled = false; /** @@ -77,7 +77,7 @@ export class DetailMapConfiguration extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; /** @internal */ private _internalMarkAllSubMeshesAsTexturesDirty: () => void; @@ -102,6 +102,13 @@ export class DetailMapConfiguration extends MaterialPluginBase { this._internalMarkAllSubMeshesAsTexturesDirty = material._dirtyCallbacks[Constants.MATERIAL_TextureDirtyFlag]; } + /** + * Checks whether the detail map configuration is ready for the current submesh. + * @param defines defines the material defines to evaluate + * @param scene defines the scene to use for texture readiness checks + * @param engine defines the engine to use for capability checks + * @returns true if the configuration is ready + */ public override isReadyForSubMesh(defines: MaterialDetailMapDefines, scene: Scene, engine: AbstractEngine): boolean { if (!this._isEnabled) { return true; @@ -119,6 +126,11 @@ export class DetailMapConfiguration extends MaterialPluginBase { return true; } + /** + * Updates the detail map shader defines. + * @param defines defines the material defines to update + * @param scene defines the scene to use for engine capability checks + */ public override prepareDefines(defines: MaterialDetailMapDefines, scene: Scene): void { if (this._isEnabled) { defines.DETAIL_NORMALBLENDMETHOD = this._normalBlendMethod; @@ -138,6 +150,11 @@ export class DetailMapConfiguration extends MaterialPluginBase { } } + /** + * Binds the detail map data for the current submesh. + * @param uniformBuffer defines the uniform buffer to update + * @param scene defines the scene the material belongs to + */ public override bindForSubMesh(uniformBuffer: UniformBuffer, scene: Scene): void { if (!this._isEnabled) { return; @@ -160,6 +177,11 @@ export class DetailMapConfiguration extends MaterialPluginBase { } } + /** + * Checks whether the detail map configuration references a texture. + * @param texture defines the texture to check + * @returns true if the texture is used by the configuration + */ public override hasTexture(texture: BaseTexture): boolean { if (this._texture === texture) { return true; @@ -168,18 +190,30 @@ export class DetailMapConfiguration extends MaterialPluginBase { return false; } + /** + * Adds the active detail map textures to the provided array. + * @param activeTextures defines the active texture array to update + */ public override getActiveTextures(activeTextures: BaseTexture[]): void { if (this._texture) { activeTextures.push(this._texture); } } + /** + * Adds the animatable detail map textures to the provided array. + * @param animatables defines the animatable array to update + */ public override getAnimatables(animatables: IAnimatable[]): void { if (this._texture && this._texture.animations && this._texture.animations.length > 0) { animatables.push(this._texture); } } + /** + * Disposes the detail map configuration resources. + * @param forceDisposeTextures defines whether to dispose associated textures + */ public override dispose(forceDisposeTextures?: boolean): void { if (forceDisposeTextures) { this._texture?.dispose(); @@ -190,6 +224,10 @@ export class DetailMapConfiguration extends MaterialPluginBase { return "DetailMapConfiguration"; } + /** + * Adds the detail map sampler names to the provided array. + * @param samplers defines the sampler array to update + */ public override getSamplers(samplers: string[]): void { samplers.push("detailSampler"); } diff --git a/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts b/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts index 4a55dac96cd3..f15bbecd8ffe 100644 --- a/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts +++ b/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts @@ -464,7 +464,7 @@ export class MeshDebugPluginMaterial extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllDefinesAsDirty") - public mode: MeshDebugMode; + public accessor mode: MeshDebugMode; private _multiply: boolean; /** @@ -473,7 +473,7 @@ export class MeshDebugPluginMaterial extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllDefinesAsDirty") - public multiply: boolean; + public accessor multiply: boolean; /** * Diffuse color used to shade the mesh. diff --git a/packages/dev/core/src/Materials/standardMaterial.pure.ts b/packages/dev/core/src/Materials/standardMaterial.pure.ts index b20d6ef3002d..db50ef236412 100644 --- a/packages/dev/core/src/Materials/standardMaterial.pure.ts +++ b/packages/dev/core/src/Materials/standardMaterial.pure.ts @@ -232,7 +232,7 @@ export class StandardMaterial extends StandardMaterialBase { * The basic texture of the material as viewed under a light. */ @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public diffuseTexture: Nullable; + public accessor diffuseTexture: Nullable; @serializeAsTexture("ambientTexture") private _ambientTexture: Nullable = null; @@ -240,7 +240,7 @@ export class StandardMaterial extends StandardMaterialBase { * AKA Occlusion Texture in other nomenclature, it helps adding baked shadows into your material. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public ambientTexture: Nullable; + public accessor ambientTexture: Nullable; @serializeAsTexture("opacityTexture") private _opacityTexture: Nullable = null; @@ -250,7 +250,7 @@ export class StandardMaterial extends StandardMaterialBase { * or from the luminance or the current texel (if texture.getAlphaFromRGB is true) */ @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public opacityTexture: Nullable; + public accessor opacityTexture: Nullable; @serializeAsTexture("reflectionTexture") private _reflectionTexture: Nullable = null; @@ -259,7 +259,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#how-to-obtain-reflections-and-refractions */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public reflectionTexture: Nullable; + public accessor reflectionTexture: Nullable; @serializeAsTexture("emissiveTexture") private _emissiveTexture: Nullable = null; @@ -268,7 +268,7 @@ export class StandardMaterial extends StandardMaterialBase { * This will be mixed in the final result even in the absence of light. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public emissiveTexture: Nullable; + public accessor emissiveTexture: Nullable; @serializeAsTexture("specularTexture") private _specularTexture: Nullable = null; @@ -276,7 +276,7 @@ export class StandardMaterial extends StandardMaterialBase { * Define how the color and intensity of the highlight given by the light in the material. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public specularTexture: Nullable; + public accessor specularTexture: Nullable; @serializeAsTexture("bumpTexture") private _bumpTexture: Nullable = null; @@ -286,7 +286,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#bump-map */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture: Nullable; + public accessor bumpTexture: Nullable; @serializeAsTexture("lightmapTexture") private _lightmapTexture: Nullable = null; @@ -296,7 +296,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction#lightmaps */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public lightmapTexture: Nullable; + public accessor lightmapTexture: Nullable; @serializeAsTexture("refractionTexture") private _refractionTexture: Nullable = null; @@ -305,7 +305,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/reflectionTexture#how-to-obtain-reflections-and-refractions */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public refractionTexture: Nullable; + public accessor refractionTexture: Nullable; /** * The color of the material lit by the environmental background lighting. @@ -347,7 +347,7 @@ export class StandardMaterial extends StandardMaterialBase { * Does the transparency come from the diffuse texture alpha channel. */ @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public useAlphaFromDiffuseTexture: boolean; + public accessor useAlphaFromDiffuseTexture: boolean; @serialize("useEmissiveAsIllumination") private _useEmissiveAsIllumination = false; @@ -355,7 +355,7 @@ export class StandardMaterial extends StandardMaterialBase { * If true, the emissive value is added into the end result, otherwise it is multiplied in. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useEmissiveAsIllumination: boolean; + public accessor useEmissiveAsIllumination: boolean; @serialize("linkEmissiveWithDiffuse") private _linkEmissiveWithDiffuse = false; @@ -364,7 +364,7 @@ export class StandardMaterial extends StandardMaterialBase { * the emissive level when the final color is close to one. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public linkEmissiveWithDiffuse: boolean; + public accessor linkEmissiveWithDiffuse: boolean; @serialize("useSpecularOverAlpha") private _useSpecularOverAlpha = false; @@ -373,7 +373,7 @@ export class StandardMaterial extends StandardMaterialBase { * A car glass is a good exemple of that. When sun reflects on it you can not see what is behind. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useSpecularOverAlpha: boolean; + public accessor useSpecularOverAlpha: boolean; @serialize("useReflectionOverAlpha") private _useReflectionOverAlpha = false; @@ -382,7 +382,7 @@ export class StandardMaterial extends StandardMaterialBase { * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useReflectionOverAlpha: boolean; + public accessor useReflectionOverAlpha: boolean; @serialize("disableLighting") private _disableLighting = false; @@ -391,7 +391,7 @@ export class StandardMaterial extends StandardMaterialBase { * It can be a nice trick for performance to disable lighting on a fully emissive material. */ @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("useObjectSpaceNormalMap") private _useObjectSpaceNormalMap = false; @@ -399,7 +399,7 @@ export class StandardMaterial extends StandardMaterialBase { * Allows using an object space normal map (instead of tangent space). */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useObjectSpaceNormalMap: boolean; + public accessor useObjectSpaceNormalMap: boolean; @serialize("useParallax") private _useParallax = false; @@ -408,7 +408,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/parallaxMapping */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useParallax: boolean; + public accessor useParallax: boolean; @serialize("useParallaxOcclusion") private _useParallaxOcclusion = false; @@ -418,7 +418,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/parallaxMapping */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useParallaxOcclusion: boolean; + public accessor useParallaxOcclusion: boolean; /** * Apply a scaling factor that determine which "depth" the height map should reprensent. A value between 0.05 and 0.1 is reasonnable in Parallax, you can reach 0.2 using Parallax Occlusion. @@ -432,7 +432,7 @@ export class StandardMaterial extends StandardMaterialBase { * Helps to define how blurry the reflections should appears in the material. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public roughness: number; + public accessor roughness: number; /** * In case of refraction, define the value of the index of refraction. @@ -461,7 +461,7 @@ export class StandardMaterial extends StandardMaterialBase { * In case of light mapping, define whether the map contains light or shadow informations. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useLightmapAsShadowmap: boolean; + public accessor useLightmapAsShadowmap: boolean; // Fresnel @serializeAsFresnelParameters("diffuseFresnelParameters") @@ -471,7 +471,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters */ @expandToProperty("_markAllSubMeshesAsFresnelDirty") - public diffuseFresnelParameters: FresnelParameters; + public accessor diffuseFresnelParameters: FresnelParameters; @serializeAsFresnelParameters("opacityFresnelParameters") private _opacityFresnelParameters: FresnelParameters; @@ -480,7 +480,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters */ @expandToProperty("_markAllSubMeshesAsFresnelAndMiscDirty") - public opacityFresnelParameters: FresnelParameters; + public accessor opacityFresnelParameters: FresnelParameters; @serializeAsFresnelParameters("reflectionFresnelParameters") private _reflectionFresnelParameters: FresnelParameters; @@ -489,7 +489,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters */ @expandToProperty("_markAllSubMeshesAsFresnelDirty") - public reflectionFresnelParameters: FresnelParameters; + public accessor reflectionFresnelParameters: FresnelParameters; @serializeAsFresnelParameters("refractionFresnelParameters") private _refractionFresnelParameters: FresnelParameters; @@ -498,7 +498,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters */ @expandToProperty("_markAllSubMeshesAsFresnelDirty") - public refractionFresnelParameters: FresnelParameters; + public accessor refractionFresnelParameters: FresnelParameters; @serializeAsFresnelParameters("emissiveFresnelParameters") private _emissiveFresnelParameters: FresnelParameters; @@ -507,7 +507,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters */ @expandToProperty("_markAllSubMeshesAsFresnelDirty") - public emissiveFresnelParameters: FresnelParameters; + public accessor emissiveFresnelParameters: FresnelParameters; @serialize("useReflectionFresnelFromSpecular") private _useReflectionFresnelFromSpecular = false; @@ -516,7 +516,7 @@ export class StandardMaterial extends StandardMaterialBase { * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/fresnelParameters */ @expandToProperty("_markAllSubMeshesAsFresnelDirty") - public useReflectionFresnelFromSpecular: boolean; + public accessor useReflectionFresnelFromSpecular: boolean; @serialize("useGlossinessFromSpecularMapAlpha") private _useGlossinessFromSpecularMapAlpha = false; @@ -524,7 +524,7 @@ export class StandardMaterial extends StandardMaterialBase { * Defines if the glossiness/roughness of the material should be read from the specular map alpha channel */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public useGlossinessFromSpecularMapAlpha: boolean; + public accessor useGlossinessFromSpecularMapAlpha: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @@ -532,7 +532,7 @@ export class StandardMaterial extends StandardMaterialBase { * Defines the maximum number of lights that can be used in the material */ @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; @serialize("invertNormalMapX") private _invertNormalMapX = false; @@ -540,7 +540,7 @@ export class StandardMaterial extends StandardMaterialBase { * If sets to true, x component of normal map value will invert (x = 1.0 - x). */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapX: boolean; + public accessor invertNormalMapX: boolean; @serialize("invertNormalMapY") private _invertNormalMapY = false; @@ -548,7 +548,7 @@ export class StandardMaterial extends StandardMaterialBase { * If sets to true, y component of normal map value will invert (y = 1.0 - y). */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public invertNormalMapY: boolean; + public accessor invertNormalMapY: boolean; @serialize("twoSidedLighting") private _twoSidedLighting = false; @@ -556,7 +556,7 @@ export class StandardMaterial extends StandardMaterialBase { * If sets to true and backfaceCulling is false, normals will be flipped on the backside. */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public twoSidedLighting: boolean; + public accessor twoSidedLighting: boolean; @serialize("applyDecalMapAfterDetailMap") private _applyDecalMapAfterDetailMap = false; @@ -564,7 +564,7 @@ export class StandardMaterial extends StandardMaterialBase { * If sets to true, the decal map will be applied after the detail map. Else, it is applied before (default: false) */ @expandToProperty("_markAllSubMeshesAsMiscDirty") - public applyDecalMapAfterDetailMap: boolean; + public accessor applyDecalMapAfterDetailMap: boolean; private _shadersLoaded = false; private _vertexPullingMetadata: Map | null = null; diff --git a/packages/dev/core/src/Misc/decorators.functions.ts b/packages/dev/core/src/Misc/decorators.functions.ts index fefc5ec2bba3..6df96218571a 100644 --- a/packages/dev/core/src/Misc/decorators.functions.ts +++ b/packages/dev/core/src/Misc/decorators.functions.ts @@ -1,64 +1,77 @@ -const MergedStore = {}; - -const DecoratorInitialStore = {}; - -/** @internal */ -export function GetDirectStore(target: any): any { - const classKey = target.getClassName(); - - if (!(DecoratorInitialStore)[classKey]) { - (DecoratorInitialStore)[classKey] = {}; - } - - return (DecoratorInitialStore)[classKey]; -} - -/** - * @returns the list of properties flagged as serializable - * @param target host object - */ -export function GetMergedStore(target: any): any { - const classKey = target.getClassName(); - - if ((MergedStore)[classKey]) { - return (MergedStore)[classKey]; - } - - (MergedStore)[classKey] = {}; - - const store = (MergedStore)[classKey]; - let currentTarget = target; - let currentKey = classKey; - while (currentKey) { - const initialStore = (DecoratorInitialStore)[currentKey]; - for (const property in initialStore) { - store[property] = initialStore[property]; - } - - let parent: any; - let done = false; - - do { - parent = Object.getPrototypeOf(currentTarget); - if (!parent.getClassName) { - done = true; - break; - } - - if (parent.getClassName() !== currentKey) { - break; - } - - currentTarget = parent; - } while (parent); - - if (done) { - break; - } - - currentKey = parent.getClassName(); - currentTarget = parent; - } - - return store; -} +// Provide the TC39 decorator metadata key for runtimes that support Symbol but do not yet expose Symbol.metadata. +// TypeScript's decorator emit reads Symbol.metadata before decorator callbacks run; if it is absent, +// context.metadata is undefined and decorators such as @serialize cannot store class metadata. +if (typeof Symbol !== "undefined" && !Symbol.metadata) { + Object.defineProperty(Symbol, "metadata", { + configurable: true, + writable: true, + value: Symbol("Symbol.metadata"), + }); +} + +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export const __bjsSerializableKey = "__bjs_serializable__"; + +// eslint-disable-next-line @typescript-eslint/naming-convention +const _mergedStoreCache = new WeakMap>(); + +/** + * Returns the metadata object for the decorator context. + * Used internally by decorator functions to store serialization info. + * @internal + */ +export function GetDirectStoreFromMetadata(metadata: DecoratorMetadataObject): Record { + let ownStore = Object.prototype.hasOwnProperty.call(metadata, __bjsSerializableKey) ? (metadata[__bjsSerializableKey] as Record) : undefined; + if (!ownStore) { + ownStore = {}; + metadata[__bjsSerializableKey] = ownStore; + } + return ownStore; +} + +/** @internal */ +export function GetDirectStore(target: any): any { + const ctor = typeof target === "function" ? target : target?.constructor; + const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + if (!metadata) { + return {}; + } + return Object.prototype.hasOwnProperty.call(metadata, __bjsSerializableKey) ? (metadata[__bjsSerializableKey] as Record) : {}; +} + +/** + * @returns the list of properties flagged as serializable + * @param target host object + */ +export function GetMergedStore(target: any): any { + const ctor = typeof target === "function" ? target : target?.constructor; + const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + if (!metadata) { + return {}; + } + + // Check cache + const cached = _mergedStoreCache.get(metadata); + if (cached) { + return cached; + } + + // Walk the metadata prototype chain and merge all serializable stores + const store: Record = {}; + let currentMeta: any = metadata; + while (currentMeta) { + if (Object.prototype.hasOwnProperty.call(currentMeta, __bjsSerializableKey)) { + const classStore = currentMeta[__bjsSerializableKey] as Record; + for (const property in classStore) { + if (Object.prototype.hasOwnProperty.call(classStore, property) && !(property in store)) { + store[property] = classStore[property]; + } + } + } + currentMeta = Object.getPrototypeOf(currentMeta); + } + + _mergedStoreCache.set(metadata, store); + return store; +} diff --git a/packages/dev/core/src/Misc/decorators.ts b/packages/dev/core/src/Misc/decorators.ts index 42b79eb9de27..cfe288ad2461 100644 --- a/packages/dev/core/src/Misc/decorators.ts +++ b/packages/dev/core/src/Misc/decorators.ts @@ -1,28 +1,40 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/naming-convention */ import { type Nullable } from "../types"; -import { GetDirectStore } from "./decorators.functions"; +import { GetDirectStoreFromMetadata } from "./decorators.functions"; import { _WarnImport } from "./devTools"; +/** + * TC39 decorator context types that serialization decorators can be applied to. + * Serialization decorators can be applied to fields, getters, setters, and auto-accessors. + */ +type SerializableContext = { name: string | symbol; metadata: DecoratorMetadataObject }; + function generateSerializableMember(type: number, sourceName?: string) { - return (target: any, propertyKey: string | symbol) => { - const classStore = GetDirectStore(target); + return (_value: unknown, context: SerializableContext) => { + const propertyKey = String(context.name); + const store = GetDirectStoreFromMetadata(context.metadata); - if (!classStore[propertyKey]) { - classStore[propertyKey] = { type: type, sourceName: sourceName }; + if (!store[propertyKey]) { + store[propertyKey] = { type: type, sourceName: sourceName }; } }; } function generateExpandMember(setCallback: string, targetKey: Nullable = null) { - return (target: any, propertyKey: string) => { - const key = targetKey || "_" + propertyKey; - Object.defineProperty(target, propertyKey, { - get: function (this: any) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return (_value: ClassAccessorDecoratorTarget, context: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult => { + const key = targetKey || "_" + String(context.name); + return { + init(this: any, value: V) { + if (value !== undefined || !(key in this)) { + this[key] = value; + } + return value; + }, + get(this: any) { return this[key]; }, - set: function (this: any, value) { + set(this: any, value: V) { // does this object (i.e. vector3) has an equals function? use it! // Note - not using "with epsilon" here, it is expected te behave like the internal cache does. if (typeof this[key]?.equals === "function") { @@ -35,11 +47,9 @@ function generateExpandMember(setCallback: string, targetKey: Nullable = } this[key] = value; - target[setCallback].apply(this); + this[setCallback](); }, - enumerable: true, - configurable: true, - }); + }; }; } @@ -111,40 +121,33 @@ declare const _native: any; * Decorator used to redirect a function to a native implementation if available. * @internal */ -export function nativeOverride boolean>( - target: any, - propertyKey: string, - descriptor: TypedPropertyDescriptor<(...params: Parameters) => any>, - predicate?: T -) { - // Cache the original JS function for later. - const jsFunc = descriptor.value!; - - // Override the JS function to check for a native override on first invocation. Setting descriptor.value overrides the function at the early stage of code being loaded/imported. - descriptor.value = (...params: Parameters): unknown => { - // Assume the resolved function will be the original JS function, then we will check for the Babylon Native context. - let func = jsFunc; - - // Check if we are executing in a Babylon Native context (e.g. check the presence of the _native global property) and if so also check if a function override is available. - if (typeof _native !== "undefined" && _native[propertyKey]) { - const nativeFunc = _native[propertyKey] as (...params: Parameters) => unknown; - // If a predicate was provided, then we'll need to invoke the predicate on each invocation of the underlying function to determine whether to call the native function or the JS function. - if (predicate) { - // The resolved function will execute the predicate and then either execute the native function or the JS function. - func = (...params: Parameters) => (predicate(...params) ? nativeFunc(...params) : jsFunc(...params)); - } else { - // The resolved function will directly execute the native function. - func = nativeFunc; +export function nativeOverride( + originalMethod: (this: This, ...args: Args) => Return, + _context: ClassMethodDecoratorContext Return> +): (this: This, ...args: Args) => Return { + const propertyKey = String(_context.name); + let resolvedFunc: ((this: This, ...args: Args) => Return) | null = null; + + const wrapper = function (this: This, ...params: Args): Return { + if (resolvedFunc === null) { + // Default to the original JS function. + resolvedFunc = originalMethod; + + // Check if we are executing in a Babylon Native context and if so, check for a function override. + if (typeof _native !== "undefined" && _native[propertyKey]) { + resolvedFunc = _native[propertyKey] as (this: This, ...args: Args) => Return; } - } - // Override the JS function again with the final resolved target function. - target[propertyKey] = func; + const target = (this && (_context.static ? this : Object.getPrototypeOf(this))) as any; + if (target?.[propertyKey] === wrapper) { + target[propertyKey] = resolvedFunc; + } + } - // The JS function has now been overridden based on whether we're executing in the context of Babylon Native, but we still need to invoke that function. - // Future invocations of the function will just directly invoke the final overridden function, not any of the decorator setup logic above. - return func(...params); + return resolvedFunc.apply(this, params); }; + + return wrapper; } /** @@ -155,26 +158,55 @@ export function nativeOverride boolean>( * @internal */ nativeOverride.filter = function boolean>(predicate: T) { - return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<(...params: Parameters) => unknown>) => - nativeOverride(target, propertyKey, descriptor, predicate); + return (originalMethod: (...args: any[]) => any, _context: ClassMethodDecoratorContext): ((...args: any[]) => any) => { + const propertyKey = String(_context.name); + let resolvedFunc: ((this: any, ...args: any[]) => any) | undefined; + let resolved = false; + + const wrapper = function (this: any, ...params: any[]): unknown { + if (!resolved) { + resolved = true; + if (typeof _native !== "undefined" && _native[propertyKey]) { + const nativeFunc = _native[propertyKey] as (...args: any[]) => any; + resolvedFunc = function (this: any, ...args: any[]): unknown { + if (predicate(...(args as Parameters))) { + return nativeFunc(...args); + } + return originalMethod.apply(this, args); + }; + } else { + resolvedFunc = originalMethod; + } + + const target = this && (_context.static ? this : Object.getPrototypeOf(this)); + if (target?.[propertyKey] === wrapper) { + target[propertyKey] = resolvedFunc; + } + } + + return resolvedFunc!.apply(this, params); + }; + + return wrapper; + }; }; /** * Adds accessors for a material property. + * Applied to an auto-accessor field. Reads/writes from a private backing field named by sourceKey (default: "_" + property name). + * The backing field is expected to have a `.value` property. * @param setCallback - The name of the callback function to call when the property is set. - * @param targetKey - The key to use for the target property (defaults to the original property key). - * @returns A property decorator. + * @param sourceKey - The name of the private field that stores the value (defaults to "_" + accessor name). + * @returns An accessor decorator. */ -export function addAccessorsForMaterialProperty(setCallback: string, targetKey: Nullable = null) { - return (target: any, propertyKey: string) => { - const key = propertyKey; - const newKey = targetKey || ""; - Object.defineProperty(target, newKey, { - get: function (this: any) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return this[key].value; +export function addAccessorsForMaterialProperty(setCallback: string, sourceKey: Nullable = null) { + return (_value: ClassAccessorDecoratorTarget, context: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult => { + const key = sourceKey || "_" + String(context.name); + return { + get(this: any) { + return this[key]?.value; }, - set: function (this: any, value) { + set(this: any, value: V) { // does this object (i.e. vector3) has an equals function? use it! // Note - not using "with epsilon" here, it is expected te behave like the internal cache does. if (typeof this[key]?.value?.equals === "function") { @@ -187,10 +219,8 @@ export function addAccessorsForMaterialProperty(setCallback: string, targetKey: } this[key].value = value; - target[setCallback].apply(this); + this[setCallback](); }, - enumerable: true, - configurable: true, - }); + }; }; } diff --git a/packages/dev/core/src/PostProcesses/blackAndWhitePostProcess.pure.ts b/packages/dev/core/src/PostProcesses/blackAndWhitePostProcess.pure.ts index dcc4ef609a39..17acb588edbb 100644 --- a/packages/dev/core/src/PostProcesses/blackAndWhitePostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/blackAndWhitePostProcess.pure.ts @@ -36,7 +36,7 @@ export class BlackAndWhitePostProcess extends PostProcess { return "BlackAndWhitePostProcess"; } - protected override _effectWrapper: ThinBlackAndWhitePostProcess; + declare protected _effectWrapper: ThinBlackAndWhitePostProcess; /** * Creates a black and white post process diff --git a/packages/dev/core/src/PostProcesses/bloomMergePostProcess.pure.ts b/packages/dev/core/src/PostProcesses/bloomMergePostProcess.pure.ts index df53964509d2..c73394071ab0 100644 --- a/packages/dev/core/src/PostProcesses/bloomMergePostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/bloomMergePostProcess.pure.ts @@ -33,7 +33,7 @@ export class BloomMergePostProcess extends PostProcess { return "BloomMergePostProcess"; } - protected override _effectWrapper: ThinBloomMergePostProcess; + declare protected _effectWrapper: ThinBloomMergePostProcess; /** * Creates a new instance of @see BloomMergePostProcess diff --git a/packages/dev/core/src/PostProcesses/blurPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/blurPostProcess.pure.ts index 63f8666f1fd4..96bd6e18c1c3 100644 --- a/packages/dev/core/src/PostProcesses/blurPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/blurPostProcess.pure.ts @@ -68,7 +68,7 @@ export class BlurPostProcess extends PostProcess { return "BlurPostProcess"; } - protected override _effectWrapper: ThinBlurPostProcess; + declare protected _effectWrapper: ThinBlurPostProcess; /** * Creates a new instance BlurPostProcess diff --git a/packages/dev/core/src/PostProcesses/chromaticAberrationPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/chromaticAberrationPostProcess.pure.ts index 5003bdc45403..25c4e9ad3e72 100644 --- a/packages/dev/core/src/PostProcesses/chromaticAberrationPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/chromaticAberrationPostProcess.pure.ts @@ -94,7 +94,7 @@ export class ChromaticAberrationPostProcess extends PostProcess { return "ChromaticAberrationPostProcess"; } - protected override _effectWrapper: ThinChromaticAberrationPostProcess; + declare protected _effectWrapper: ThinChromaticAberrationPostProcess; /** * Creates a new instance ChromaticAberrationPostProcess diff --git a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.pure.ts index 6edd24e75533..068be2889da6 100644 --- a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.pure.ts @@ -75,7 +75,7 @@ export class CircleOfConfusionPostProcess extends PostProcess { return "CircleOfConfusionPostProcess"; } - protected override _effectWrapper: ThinCircleOfConfusionPostProcess; + declare protected _effectWrapper: ThinCircleOfConfusionPostProcess; private _depthTexture: Nullable = null; /** diff --git a/packages/dev/core/src/PostProcesses/colorCorrectionPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/colorCorrectionPostProcess.pure.ts index 49dee0cf1420..e8a08ba64e2d 100644 --- a/packages/dev/core/src/PostProcesses/colorCorrectionPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/colorCorrectionPostProcess.pure.ts @@ -44,7 +44,7 @@ export class ColorCorrectionPostProcess extends PostProcess { return "ColorCorrectionPostProcess"; } - protected override _effectWrapper: ThinColorCorrectionPostProcess; + declare protected _effectWrapper: ThinColorCorrectionPostProcess; constructor( name: string, diff --git a/packages/dev/core/src/PostProcesses/convolutionPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/convolutionPostProcess.pure.ts index b02f5ec74837..dd56e2b8a626 100644 --- a/packages/dev/core/src/PostProcesses/convolutionPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/convolutionPostProcess.pure.ts @@ -38,7 +38,7 @@ export class ConvolutionPostProcess extends PostProcess { return "ConvolutionPostProcess"; } - protected override _effectWrapper: ThinConvolutionPostProcess; + declare protected _effectWrapper: ThinConvolutionPostProcess; /** * Creates a new instance ConvolutionPostProcess diff --git a/packages/dev/core/src/PostProcesses/extractHighlightsPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/extractHighlightsPostProcess.pure.ts index 043efaedca7d..28a8d56ec3a7 100644 --- a/packages/dev/core/src/PostProcesses/extractHighlightsPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/extractHighlightsPostProcess.pure.ts @@ -51,7 +51,7 @@ export class ExtractHighlightsPostProcess extends PostProcess { return "ExtractHighlightsPostProcess"; } - protected override _effectWrapper: ThinExtractHighlightsPostProcess; + declare protected _effectWrapper: ThinExtractHighlightsPostProcess; constructor( name: string, diff --git a/packages/dev/core/src/PostProcesses/filterPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/filterPostProcess.pure.ts index 83ee36261991..44e6d594e9f6 100644 --- a/packages/dev/core/src/PostProcesses/filterPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/filterPostProcess.pure.ts @@ -35,7 +35,7 @@ export class FilterPostProcess extends PostProcess { return "FilterPostProcess"; } - protected override _effectWrapper: ThinFilterPostProcess; + declare protected _effectWrapper: ThinFilterPostProcess; /** * diff --git a/packages/dev/core/src/PostProcesses/fxaaPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/fxaaPostProcess.pure.ts index 9341fa43de78..8aa253568db7 100644 --- a/packages/dev/core/src/PostProcesses/fxaaPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/fxaaPostProcess.pure.ts @@ -26,7 +26,7 @@ export class FxaaPostProcess extends PostProcess { return "FxaaPostProcess"; } - protected override _effectWrapper: ThinFXAAPostProcess; + declare protected _effectWrapper: ThinFXAAPostProcess; constructor( name: string, diff --git a/packages/dev/core/src/PostProcesses/grainPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/grainPostProcess.pure.ts index 65e872dfe4c9..b2f7c95ab986 100644 --- a/packages/dev/core/src/PostProcesses/grainPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/grainPostProcess.pure.ts @@ -49,7 +49,7 @@ export class GrainPostProcess extends PostProcess { return "GrainPostProcess"; } - protected override _effectWrapper: ThinGrainPostProcess; + declare protected _effectWrapper: ThinGrainPostProcess; /** * Creates a new instance of @see GrainPostProcess diff --git a/packages/dev/core/src/PostProcesses/imageProcessingPostProcess.ts b/packages/dev/core/src/PostProcesses/imageProcessingPostProcess.ts index d5baa0b734ec..fd8e0e13427d 100644 --- a/packages/dev/core/src/PostProcesses/imageProcessingPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/imageProcessingPostProcess.ts @@ -318,7 +318,7 @@ export class ImageProcessingPostProcess extends PostProcess { this._effectWrapper.fromLinearSpace = value; } - protected override _effectWrapper: ThinImageProcessingPostProcess; + declare protected _effectWrapper: ThinImageProcessingPostProcess; constructor( name: string, diff --git a/packages/dev/core/src/PostProcesses/motionBlurPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/motionBlurPostProcess.pure.ts index 54170d7ef9cf..80f4f46bd330 100644 --- a/packages/dev/core/src/PostProcesses/motionBlurPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/motionBlurPostProcess.pure.ts @@ -105,7 +105,7 @@ export class MotionBlurPostProcess extends PostProcess { return "MotionBlurPostProcess"; } - protected override _effectWrapper: ThinMotionBlurPostProcess; + declare protected _effectWrapper: ThinMotionBlurPostProcess; /** * Creates a new instance MotionBlurPostProcess diff --git a/packages/dev/core/src/PostProcesses/passPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/passPostProcess.pure.ts index 8bafd5ed31c7..88bc41c4c72f 100644 --- a/packages/dev/core/src/PostProcesses/passPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/passPostProcess.pure.ts @@ -114,7 +114,7 @@ export class PassCubePostProcess extends PostProcess { return "PassCubePostProcess"; } - protected override _effectWrapper: ThinPassCubePostProcess; + declare protected _effectWrapper: ThinPassCubePostProcess; /** * Creates the PassCubePostProcess diff --git a/packages/dev/core/src/PostProcesses/screenSpaceCurvaturePostProcess.pure.ts b/packages/dev/core/src/PostProcesses/screenSpaceCurvaturePostProcess.pure.ts index 4098dcf85f94..0ac35cf5dc0c 100644 --- a/packages/dev/core/src/PostProcesses/screenSpaceCurvaturePostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/screenSpaceCurvaturePostProcess.pure.ts @@ -54,7 +54,7 @@ export class ScreenSpaceCurvaturePostProcess extends PostProcess { return "ScreenSpaceCurvaturePostProcess"; } - protected override _effectWrapper: ThinScreenSpaceCurvaturePostProcess; + declare protected _effectWrapper: ThinScreenSpaceCurvaturePostProcess; /** * Creates a new instance ScreenSpaceCurvaturePostProcess diff --git a/packages/dev/core/src/PostProcesses/sharpenPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/sharpenPostProcess.pure.ts index a0dfd543b941..8141ea4ce090 100644 --- a/packages/dev/core/src/PostProcesses/sharpenPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/sharpenPostProcess.pure.ts @@ -50,7 +50,7 @@ export class SharpenPostProcess extends PostProcess { return "SharpenPostProcess"; } - protected override _effectWrapper: ThinSharpenPostProcess; + declare protected _effectWrapper: ThinSharpenPostProcess; /** * Creates a new instance ConvolutionPostProcess diff --git a/packages/dev/core/src/PostProcesses/tonemapPostProcess.pure.ts b/packages/dev/core/src/PostProcesses/tonemapPostProcess.pure.ts index 21d64d436e25..fd780ea00633 100644 --- a/packages/dev/core/src/PostProcesses/tonemapPostProcess.pure.ts +++ b/packages/dev/core/src/PostProcesses/tonemapPostProcess.pure.ts @@ -47,7 +47,7 @@ export class TonemapPostProcess extends PostProcess { return "TonemapPostProcess"; } - protected override _effectWrapper: ThinTonemapPostProcess; + declare protected _effectWrapper: ThinTonemapPostProcess; /** * Creates a new TonemapPostProcess diff --git a/packages/dev/core/src/Rendering/GlobalIllumination/giRSMManager.pure.ts b/packages/dev/core/src/Rendering/GlobalIllumination/giRSMManager.pure.ts index 0b59a7c0720b..7d25dfc6eecc 100644 --- a/packages/dev/core/src/Rendering/GlobalIllumination/giRSMManager.pure.ts +++ b/packages/dev/core/src/Rendering/GlobalIllumination/giRSMManager.pure.ts @@ -933,7 +933,7 @@ export class GIRSMRenderPluginMaterial extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; protected _markAllSubMeshesAsTexturesDirty(): void { this._enable(this._isEnabled); diff --git a/packages/dev/core/src/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.ts b/packages/dev/core/src/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.ts index 5d0d7d8f4750..5867f5755666 100644 --- a/packages/dev/core/src/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.ts +++ b/packages/dev/core/src/Rendering/IBLShadows/iblShadowsPluginMaterial.pure.ts @@ -71,7 +71,7 @@ export class IBLShadowsPluginMaterial extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; protected _markAllSubMeshesAsTexturesDirty(): void { this._enable(this._isEnabled); diff --git a/packages/dev/core/src/Rendering/reflectiveShadowMap.pure.ts b/packages/dev/core/src/Rendering/reflectiveShadowMap.pure.ts index 62aaf7e746bb..3a7cf98b5670 100644 --- a/packages/dev/core/src/Rendering/reflectiveShadowMap.pure.ts +++ b/packages/dev/core/src/Rendering/reflectiveShadowMap.pure.ts @@ -349,7 +349,7 @@ export class RSMCreatePluginMaterial extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public isEnabled = false; + public accessor isEnabled = false; protected _markAllSubMeshesAsTexturesDirty(): void { this._enable(this._isEnabled); diff --git a/packages/dev/core/test/unit/Decorators/decorators.inline-test.ts b/packages/dev/core/test/unit/Decorators/decorators.inline-test.ts new file mode 100644 index 000000000000..deb4f53e84be --- /dev/null +++ b/packages/dev/core/test/unit/Decorators/decorators.inline-test.ts @@ -0,0 +1,69 @@ +/* eslint-disable no-console */ +/** + * Quick inline test to verify TC39 decorators work correctly. + * Run with: npx ts-node --esm --project tsconfig.test.json packages/dev/core/test/unit/Decorators/decorators.inline-test.ts + */ + +// Test 1: Symbol.metadata polyfill +(Symbol as any).metadata ??= Symbol.for("Symbol.metadata"); + +// Test 2: A simple TC39 class field decorator +function trackField(displayName: string) { + return function (_value: undefined, context: ClassFieldDecoratorContext) { + const key = `__tracked_${String(context.name)}`; + if (!Object.hasOwn(context.metadata, key)) { + (context.metadata as any)[key] = displayName; + } + }; +} + +// Test 3: A TC39 accessor decorator (like expandToProperty) +function doubleAccessor( + _value: ClassAccessorDecoratorTarget, + _context: ClassAccessorDecoratorContext +): ClassAccessorDecoratorResult { + return { + get(this: This): V { + return (_value.get.call(this) * 2) as V; + }, + set(this: This, value: V) { + _value.set.call(this, value); + }, + }; +} + +class TestClass { + @trackField("My Number") + myNum: number = 42; + + @doubleAccessor + accessor doubled: number = 5; +} + +// Verify metadata +const metadata = (TestClass as any)[Symbol.metadata]; +console.assert(metadata !== undefined, "Symbol.metadata should be set on class"); +console.assert((metadata as any).__tracked_myNum === "My Number", "Field decorator should store metadata"); + +// Verify accessor +const instance = new TestClass(); +console.assert(instance.doubled === 10, `Accessor should return doubled value, got ${instance.doubled}`); +instance.doubled = 7; +console.assert(instance.doubled === 14, `After setting 7, accessor should return 14, got ${instance.doubled}`); + +// Test 4: Inheritance +class ChildClass extends TestClass { + @trackField("Child Prop") + childProp: string = "hello"; +} + +const childMeta = (ChildClass as any)[Symbol.metadata]; +console.assert(childMeta !== undefined, "Child should have metadata"); +console.assert((childMeta as any).__tracked_childProp === "Child Prop", "Child metadata should have its own properties"); + +// Walk the prototype chain +const parentMeta = Object.getPrototypeOf(childMeta); +console.assert(parentMeta !== null, "Child metadata prototype should be parent metadata"); +console.assert((parentMeta as any).__tracked_myNum === "My Number", "Parent metadata should be accessible via prototype chain"); + +console.log("All decorator tests passed!"); diff --git a/packages/dev/core/test/unit/Decorators/decorators.test.ts b/packages/dev/core/test/unit/Decorators/decorators.test.ts new file mode 100644 index 000000000000..33a5cc846e20 --- /dev/null +++ b/packages/dev/core/test/unit/Decorators/decorators.test.ts @@ -0,0 +1,124 @@ +/** + * Quick sanity test for TC39 decorator migration. + * Tests the core decorator functions work correctly with Symbol.metadata. + */ +import { serialize, serializeAsColor3, expandToProperty } from "core/Misc/decorators"; +import { GetDirectStore, GetMergedStore } from "core/Misc/decorators.functions"; +import { Color3 } from "core/Maths/math.color"; +import { describe, expect, it, vi } from "vitest"; + +describe("TC39 Decorator Migration", () => { + describe("serialize decorator", () => { + it("should store serialization metadata via Symbol.metadata", () => { + class TestClass { + @serialize() + public myProp: number = 42; + + @serialize("renamedProp") + public anotherProp: string = "hello"; + } + + const store = GetDirectStore(new TestClass()); + expect(store).toBeDefined(); + expect(store["myProp"]).toBeDefined(); + expect(store["myProp"].type).toBe(0); // default type + expect(store["anotherProp"]).toBeDefined(); + expect(store["anotherProp"].sourceName).toBe("renamedProp"); + }); + + it("should merge stores from parent and child classes", () => { + class Parent { + @serialize() + public parentProp: number = 1; + } + + class Child extends Parent { + @serialize() + public childProp: number = 2; + } + + const child = new Child(); + const merged = GetMergedStore(child); + expect(merged["parentProp"]).toBeDefined(); + expect(merged["childProp"]).toBeDefined(); + }); + }); + + describe("serializeAsColor3 decorator", () => { + it("should serialize color3 properties", () => { + class ColorClass { + @serializeAsColor3() + public color: Color3 = new Color3(1, 0, 0); + } + + const store = GetDirectStore(new ColorClass()); + expect(store["color"]).toBeDefined(); + }); + }); + + describe("expandToProperty decorator", () => { + it("should create getter/setter that reads from backing field", () => { + class ExpandClass { + // @ts-expect-error Accessed dynamically by expandToProperty decorator + private _myCallback() { + // no-op + } + + @expandToProperty("_myCallback") + public accessor myExpanded: number; + + // @ts-expect-error Backing field accessed dynamically by expandToProperty + private _myExpanded: number = 10; + } + + const instance = new ExpandClass(); + expect(instance.myExpanded).toBe(10); + + instance.myExpanded = 20; + expect(instance.myExpanded).toBe(20); + }); + + it("should preserve initialized backing fields when the auto-accessor has no initializer", () => { + class ExpandClass { + // @ts-expect-error Backing field is accessed dynamically by expandToProperty + private _myExpanded: number = 10; + + @expandToProperty("_myCallback") + public accessor myExpanded: number; + + // @ts-expect-error Accessed dynamically by expandToProperty decorator + private _myCallback() { + // no-op + } + } + + const instance = new ExpandClass(); + expect(instance.myExpanded).toBe(10); + }); + + it("should copy auto-accessor initializers to the backing field", () => { + const callback = vi.fn(); + + class ExpandClass { + // @ts-expect-error Backing field is accessed dynamically by expandToProperty + private _myExpanded: number; + + @expandToProperty("_myCallback") + public accessor myExpanded: number = 10; + + // @ts-expect-error Accessed dynamically by expandToProperty decorator + private _myCallback() { + callback(); + } + } + + const instance = new ExpandClass(); + expect(instance.myExpanded).toBe(10); + expect(callback).not.toHaveBeenCalled(); + + instance.myExpanded = 20; + expect(instance.myExpanded).toBe(20); + expect(callback).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/packages/dev/core/test/unit/Layers/babylon.selectionOutlineLayer.test.ts b/packages/dev/core/test/unit/Layers/babylon.selectionOutlineLayer.test.ts index 6d41917757e1..bb53dc9e0189 100644 --- a/packages/dev/core/test/unit/Layers/babylon.selectionOutlineLayer.test.ts +++ b/packages/dev/core/test/unit/Layers/babylon.selectionOutlineLayer.test.ts @@ -2,6 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { type Engine } from "core/Engines/engine"; import { NullEngine } from "core/Engines/nullEngine"; import { Scene } from "core/scene"; +import { GlowLayer } from "core/Layers/glowLayer"; import { SelectionOutlineLayer } from "core/Layers/selectionOutlineLayer"; import { MeshBuilder } from "core/Meshes/meshBuilder"; import { ArcRotateCamera } from "core/Cameras/arcRotateCamera"; @@ -49,4 +50,10 @@ describe("SelectionOutlineLayer", () => { layer.addSelection(sphere); expect(layer.shouldRender()).toBe(true); }); + + it("should preserve the thin effect layer assigned by the base constructor", () => { + const layer = new GlowLayer("glow", scene); + + expect(layer.getEffectName()).toBe(GlowLayer.EffectName); + }); }); diff --git a/packages/dev/core/test/unit/Materials/babylon.material.test.ts b/packages/dev/core/test/unit/Materials/babylon.material.test.ts index 3e83d365c41a..76d827194e04 100644 --- a/packages/dev/core/test/unit/Materials/babylon.material.test.ts +++ b/packages/dev/core/test/unit/Materials/babylon.material.test.ts @@ -104,6 +104,22 @@ describe("Babylon Material", function () { expect(Object.is(noRepeatCloneMaterial.albedoTexture, noRepeatCloneMaterial.opacityTexture)).toBe(true); }); + it("uses the surface index of refraction as the default volume index", () => { + const scene = new Scene(subject); + const material = new PBRMaterial("material", scene); + + expect(material.subSurface.volumeIndexOfRefraction).toBe(1.5); + + material.subSurface.indexOfRefraction = 1.3; + expect(material.subSurface.volumeIndexOfRefraction).toBe(1.3); + + material.subSurface.volumeIndexOfRefraction = 1.1; + expect(material.subSurface.volumeIndexOfRefraction).toBe(1.1); + + material.subSurface.volumeIndexOfRefraction = 0; + expect(material.subSurface.volumeIndexOfRefraction).toBe(1.3); + }); + it("Clone Standard material with and without cloning repeated textures", () => { const scene = new Scene(subject); const baseMaterial = new StandardMaterial("material", scene); @@ -116,5 +132,17 @@ describe("Babylon Material", function () { const noRepeatCloneMaterial = baseMaterial.clone("noRepeatClonedMaterial", true); expect(Object.is(noRepeatCloneMaterial.diffuseTexture, noRepeatCloneMaterial.opacityTexture)).toBe(true); }); + + it("updates primary colors when changing background material highlight level", () => { + const scene = new Scene(subject); + const material = new BackgroundMaterial("material", scene); + const computePrimaryColorsSpy = vi.spyOn(material as any, "_computePrimaryColors"); + + expect(material.primaryColor.r).toBe(1); + + material.primaryColorHighlightLevel = 0.5; + + expect(computePrimaryColorsSpy).toHaveBeenCalledTimes(1); + }); }); }); diff --git a/packages/dev/core/test/unit/Meshes/babylon.dictionaryMode.test.ts b/packages/dev/core/test/unit/Meshes/babylon.dictionaryMode.test.ts index 2ea09defb4cf..184474258f42 100644 --- a/packages/dev/core/test/unit/Meshes/babylon.dictionaryMode.test.ts +++ b/packages/dev/core/test/unit/Meshes/babylon.dictionaryMode.test.ts @@ -33,7 +33,7 @@ describe("Babylon Mesh", () => { } } - expect(count).toBeLessThan(128); + expect(count).toBeLessThan(136); }); }); }); diff --git a/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.ts b/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.ts index f6251b5df22e..94f21a3d641f 100644 --- a/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.ts +++ b/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.ts @@ -41,7 +41,7 @@ export class FluentMaterial extends PushMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public innerGlowColorIntensity = 0.5; + public accessor innerGlowColorIntensity = 0.5; /** * Gets or sets the inner glow color (white by default) @@ -60,7 +60,7 @@ export class FluentMaterial extends PushMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public renderBorders = false; + public accessor renderBorders = false; /** * Gets or sets border width (default is 0.5) @@ -85,7 +85,7 @@ export class FluentMaterial extends PushMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public renderHoverLight = false; + public accessor renderHoverLight = false; /** * Gets or sets the radius used to render the hover light (default is 0.01) @@ -110,7 +110,7 @@ export class FluentMaterial extends PushMaterial { /** Gets or sets the texture to use for albedo color */ @expandToProperty("_markAllSubMeshesAsTexturesAndMiscDirty") - public albedoTexture: Nullable; + public accessor albedoTexture: Nullable; /** * Creates a new Fluent material @@ -305,6 +305,10 @@ export class FluentMaterial extends PushMaterial { return false; } + /** + * Disposes the material and its associated resources. + * @param forceDisposeEffect defines whether to dispose the effect + */ public override dispose(forceDisposeEffect?: boolean): void { super.dispose(forceDisposeEffect); } @@ -323,7 +327,13 @@ export class FluentMaterial extends PushMaterial { return "FluentMaterial"; } - // Statics + /** + * Parses a serialized fluent material. + * @param source defines the serialized material source + * @param scene defines the scene to parse into + * @param rootUrl defines the root URL for referenced resources + * @returns the parsed fluent material + */ public static override Parse(source: any, scene: Scene, rootUrl: string): FluentMaterial { return SerializationHelper.Parse(() => new FluentMaterial(source.name, scene), source, scene, rootUrl); } diff --git a/packages/dev/materials/src/cell/cellMaterial.ts b/packages/dev/materials/src/cell/cellMaterial.ts index 5f09c26ed22c..b79defef4d9f 100644 --- a/packages/dev/materials/src/cell/cellMaterial.ts +++ b/packages/dev/materials/src/cell/cellMaterial.ts @@ -75,7 +75,7 @@ export class CellMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture") private _diffuseTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: BaseTexture; + public accessor diffuseTexture: BaseTexture; @serializeAsColor3("diffuse") public diffuseColor = new Color3(1, 1, 1); @@ -83,17 +83,17 @@ export class CellMaterial extends PushMaterial { @serialize("computeHighLevel") public _computeHighLevel: boolean = false; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public computeHighLevel: boolean; + public accessor computeHighLevel: boolean; @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/fire/fireMaterial.ts b/packages/dev/materials/src/fire/fireMaterial.ts index f1fc2c8640eb..0f99b9f01059 100644 --- a/packages/dev/materials/src/fire/fireMaterial.ts +++ b/packages/dev/materials/src/fire/fireMaterial.ts @@ -64,17 +64,17 @@ export class FireMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture") private _diffuseTexture: Nullable; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: Nullable; + public accessor diffuseTexture: Nullable; @serializeAsTexture("distortionTexture") private _distortionTexture: Nullable; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public distortionTexture: Nullable; + public accessor distortionTexture: Nullable; @serializeAsTexture("opacityTexture") private _opacityTexture: Nullable; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public opacityTexture: Nullable; + public accessor opacityTexture: Nullable; @serializeAsColor3("diffuse") public diffuseColor = new Color3(1, 1, 1); diff --git a/packages/dev/materials/src/fur/furMaterial.ts b/packages/dev/materials/src/fur/furMaterial.ts index 00388dfddd31..379cf0e4c626 100644 --- a/packages/dev/materials/src/fur/furMaterial.ts +++ b/packages/dev/materials/src/fur/furMaterial.ts @@ -77,12 +77,12 @@ export class FurMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture") private _diffuseTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: BaseTexture; + public accessor diffuseTexture: BaseTexture; @serializeAsTexture("heightTexture") private _heightTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public heightTexture: BaseTexture; + public accessor heightTexture: BaseTexture; @serializeAsColor3() public diffuseColor = new Color3(1, 1, 1); @@ -119,12 +119,12 @@ export class FurMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; @serialize() public highLevelFur: boolean = true; diff --git a/packages/dev/materials/src/gradient/gradientMaterial.ts b/packages/dev/materials/src/gradient/gradientMaterial.ts index 5b945832f7b6..d1d0a0b487d9 100644 --- a/packages/dev/materials/src/gradient/gradientMaterial.ts +++ b/packages/dev/materials/src/gradient/gradientMaterial.ts @@ -71,7 +71,7 @@ export class GradientMaterial extends PushMaterial { @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; // The gradient top color, red by default @serializeAsColor3() @@ -100,7 +100,7 @@ export class GradientMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/grid/gridMaterial.ts b/packages/dev/materials/src/grid/gridMaterial.ts index f5d2b71ed6f5..c60c10fb94e3 100644 --- a/packages/dev/materials/src/grid/gridMaterial.ts +++ b/packages/dev/materials/src/grid/gridMaterial.ts @@ -123,7 +123,7 @@ export class GridMaterial extends PushMaterial { * Texture to define opacity of the grid */ @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public opacityTexture: BaseTexture; + public accessor opacityTexture: BaseTexture; private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity); @@ -368,6 +368,13 @@ export class GridMaterial extends PushMaterial { return "GridMaterial"; } + /** + * Parses a serialized grid material. + * @param source defines the serialized material source + * @param scene defines the scene to parse into + * @param rootUrl defines the root URL for referenced resources + * @returns the parsed grid material + */ public static override Parse(source: any, scene: Scene, rootUrl: string): GridMaterial { return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl); } diff --git a/packages/dev/materials/src/lava/lavaMaterial.ts b/packages/dev/materials/src/lava/lavaMaterial.ts index 1674fb686cf1..8be68b4f0b7a 100644 --- a/packages/dev/materials/src/lava/lavaMaterial.ts +++ b/packages/dev/materials/src/lava/lavaMaterial.ts @@ -114,7 +114,7 @@ export class LavaMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture") private _diffuseTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: BaseTexture; + public accessor diffuseTexture: BaseTexture; @serializeAsTexture() public noiseTexture: BaseTexture; @@ -142,17 +142,17 @@ export class LavaMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("unlit") private _unlit = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public unlit: boolean; + public accessor unlit: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _scaledDiffuse = new Color3(); private _shadersLoaded = false; diff --git a/packages/dev/materials/src/mix/mixMaterial.ts b/packages/dev/materials/src/mix/mixMaterial.ts index 61938fa7d364..ca325bcaea66 100644 --- a/packages/dev/materials/src/mix/mixMaterial.ts +++ b/packages/dev/materials/src/mix/mixMaterial.ts @@ -77,12 +77,12 @@ export class MixMaterial extends PushMaterial { @serializeAsTexture("mixTexture1") private _mixTexture1: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public mixTexture1: BaseTexture; + public accessor mixTexture1: BaseTexture; @serializeAsTexture("mixTexture2") private _mixTexture2: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public mixTexture2: BaseTexture; + public accessor mixTexture2: BaseTexture; /** * Diffuse textures @@ -91,42 +91,42 @@ export class MixMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture1") private _diffuseTexture1: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture1: Texture; + public accessor diffuseTexture1: Texture; @serializeAsTexture("diffuseTexture2") private _diffuseTexture2: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture2: Texture; + public accessor diffuseTexture2: Texture; @serializeAsTexture("diffuseTexture3") private _diffuseTexture3: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture3: Texture; + public accessor diffuseTexture3: Texture; @serializeAsTexture("diffuseTexture4") private _diffuseTexture4: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture4: Texture; + public accessor diffuseTexture4: Texture; @serializeAsTexture("diffuseTexture1") private _diffuseTexture5: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture5: Texture; + public accessor diffuseTexture5: Texture; @serializeAsTexture("diffuseTexture2") private _diffuseTexture6: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture6: Texture; + public accessor diffuseTexture6: Texture; @serializeAsTexture("diffuseTexture3") private _diffuseTexture7: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture7: Texture; + public accessor diffuseTexture7: Texture; @serializeAsTexture("diffuseTexture4") private _diffuseTexture8: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture8: Texture; + public accessor diffuseTexture8: Texture; /** * Uniforms @@ -144,12 +144,12 @@ export class MixMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/normal/normalMaterial.ts b/packages/dev/materials/src/normal/normalMaterial.ts index adc20fa672fb..85e92aee4039 100644 --- a/packages/dev/materials/src/normal/normalMaterial.ts +++ b/packages/dev/materials/src/normal/normalMaterial.ts @@ -112,7 +112,7 @@ export class NormalMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture") private _diffuseTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: BaseTexture; + public accessor diffuseTexture: BaseTexture; @serializeAsColor3() public diffuseColor = new Color3(1, 1, 1); @@ -120,12 +120,12 @@ export class NormalMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/simple/simpleMaterial.ts b/packages/dev/materials/src/simple/simpleMaterial.ts index c20434acedf5..52a6615821b5 100644 --- a/packages/dev/materials/src/simple/simpleMaterial.ts +++ b/packages/dev/materials/src/simple/simpleMaterial.ts @@ -72,7 +72,7 @@ export class SimpleMaterial extends PushMaterial { @serializeAsTexture("diffuseTexture") private _diffuseTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture: BaseTexture; + public accessor diffuseTexture: BaseTexture; @serializeAsColor3("diffuse") public diffuseColor = new Color3(1, 1, 1); @@ -80,12 +80,12 @@ export class SimpleMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/terrain/terrainMaterial.ts b/packages/dev/materials/src/terrain/terrainMaterial.ts index f802bb39513d..e119c6d45f3d 100644 --- a/packages/dev/materials/src/terrain/terrainMaterial.ts +++ b/packages/dev/materials/src/terrain/terrainMaterial.ts @@ -75,37 +75,37 @@ export class TerrainMaterial extends PushMaterial { @serializeAsTexture("mixTexture") private _mixTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public mixTexture: BaseTexture; + public accessor mixTexture: BaseTexture; @serializeAsTexture("diffuseTexture1") private _diffuseTexture1: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture1: Texture; + public accessor diffuseTexture1: Texture; @serializeAsTexture("diffuseTexture2") private _diffuseTexture2: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture2: Texture; + public accessor diffuseTexture2: Texture; @serializeAsTexture("diffuseTexture3") private _diffuseTexture3: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTexture3: Texture; + public accessor diffuseTexture3: Texture; @serializeAsTexture("bumpTexture1") private _bumpTexture1: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture1: Texture; + public accessor bumpTexture1: Texture; @serializeAsTexture("bumpTexture2") private _bumpTexture2: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture2: Texture; + public accessor bumpTexture2: Texture; @serializeAsTexture("bumpTexture3") private _bumpTexture3: Texture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture3: Texture; + public accessor bumpTexture3: Texture; @serializeAsColor3() public diffuseColor = new Color3(1, 1, 1); @@ -119,12 +119,12 @@ export class TerrainMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/triPlanar/triPlanarMaterial.ts b/packages/dev/materials/src/triPlanar/triPlanarMaterial.ts index a779e46c5707..42b92fc6f144 100644 --- a/packages/dev/materials/src/triPlanar/triPlanarMaterial.ts +++ b/packages/dev/materials/src/triPlanar/triPlanarMaterial.ts @@ -83,32 +83,32 @@ export class TriPlanarMaterial extends PushMaterial { @serializeAsTexture("diffuseTextureX") private _diffuseTextureX: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTextureX: BaseTexture; + public accessor diffuseTextureX: BaseTexture; @serializeAsTexture("diffuseTexturY") private _diffuseTextureY: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTextureY: BaseTexture; + public accessor diffuseTextureY: BaseTexture; @serializeAsTexture("diffuseTextureZ") private _diffuseTextureZ: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public diffuseTextureZ: BaseTexture; + public accessor diffuseTextureZ: BaseTexture; @serializeAsTexture("normalTextureX") private _normalTextureX: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public normalTextureX: BaseTexture; + public accessor normalTextureX: BaseTexture; @serializeAsTexture("normalTextureY") private _normalTextureY: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public normalTextureY: BaseTexture; + public accessor normalTextureY: BaseTexture; @serializeAsTexture("normalTextureZ") private _normalTextureZ: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public normalTextureZ: BaseTexture; + public accessor normalTextureZ: BaseTexture; @serialize() public tileSize: number = 1; @@ -125,12 +125,12 @@ export class TriPlanarMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; private _shadersLoaded = false; diff --git a/packages/dev/materials/src/water/waterMaterial.ts b/packages/dev/materials/src/water/waterMaterial.ts index 0187e432c5b5..e70c57e5a3bb 100644 --- a/packages/dev/materials/src/water/waterMaterial.ts +++ b/packages/dev/materials/src/water/waterMaterial.ts @@ -107,7 +107,7 @@ export class WaterMaterial extends PushMaterial { @serializeAsTexture("bumpTexture") private _bumpTexture: BaseTexture; @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public bumpTexture: BaseTexture; + public accessor bumpTexture: BaseTexture; @serializeAsColor3() public diffuseColor = new Color3(1, 1, 1); @@ -121,12 +121,12 @@ export class WaterMaterial extends PushMaterial { @serialize("disableLighting") private _disableLighting = false; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public disableLighting: boolean; + public accessor disableLighting: boolean; @serialize("maxSimultaneousLights") private _maxSimultaneousLights = 4; @expandToProperty("_markAllSubMeshesAsLightsDirty") - public maxSimultaneousLights: number; + public accessor maxSimultaneousLights: number; /** * Defines the wind force. @@ -154,7 +154,7 @@ export class WaterMaterial extends PushMaterial { @serialize("bumpSuperimpose") private _bumpSuperimpose = false; @expandToProperty("_markAllSubMeshesAsMiscDirty") - public bumpSuperimpose: boolean; + public accessor bumpSuperimpose: boolean; /** * Defines wether or not color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel. @@ -162,7 +162,7 @@ export class WaterMaterial extends PushMaterial { @serialize("fresnelSeparate") private _fresnelSeparate = false; @expandToProperty("_markAllSubMeshesAsMiscDirty") - public fresnelSeparate: boolean; + public accessor fresnelSeparate: boolean; /** * Defines wether or not bump Wwves modify the reflection. @@ -170,7 +170,7 @@ export class WaterMaterial extends PushMaterial { @serialize("bumpAffectsReflection") private _bumpAffectsReflection = false; @expandToProperty("_markAllSubMeshesAsMiscDirty") - public bumpAffectsReflection: boolean; + public accessor bumpAffectsReflection: boolean; /** * Defines the water color blended with the refraction (near). @@ -224,7 +224,7 @@ export class WaterMaterial extends PushMaterial { @serialize("useWorldCoordinatesForWaveDeformation") private _useWorldCoordinatesForWaveDeformation = false; @expandToProperty("_markAllSubMeshesAsMiscDirty") - public useWorldCoordinatesForWaveDeformation: boolean; + public accessor useWorldCoordinatesForWaveDeformation: boolean; protected _renderTargets = new SmartArray(16); diff --git a/packages/dev/serializers/src/3MF/core/xml/xml.interfaces.ts b/packages/dev/serializers/src/3MF/core/xml/xml.interfaces.ts index 333ded04d673..91052a027995 100644 --- a/packages/dev/serializers/src/3MF/core/xml/xml.interfaces.ts +++ b/packages/dev/serializers/src/3MF/core/xml/xml.interfaces.ts @@ -1,19 +1,48 @@ import { type IXmlSerializerFormatOptions } from "./xml.serializer.format"; -/** */ +/** Describes an XML qualified name with an optional namespace. */ export interface IQualifiedName { - /** */ + /** The namespace URI or prefix. */ ns?: string; - /** */ + /** The local XML name. */ name: string; } -/** */ +/** Provides a fluent interface for writing XML content. */ export interface IXmlBuilder { + /** + * Writes the XML declaration. + * @param version defines the XML version + * @param encoding defines the optional XML encoding + * @param standalone defines the optional standalone flag + * @returns the XML builder + */ dec(version: string, encoding?: string, standalone?: boolean): IXmlBuilder; + /** + * Writes an XML attribute. + * @param ns defines the attribute namespace + * @param n defines the attribute name + * @param v defines the attribute value + * @returns the XML builder + */ att(ns: string | null, n: string, v: string): IXmlBuilder; + /** + * Writes an XML element. + * @param ns defines the element namespace + * @param n defines the element name + * @returns the XML builder + */ ele(ns: string | null, n: string): IXmlBuilder; + /** + * Writes text content. + * @param txt defines the text to write + * @returns the XML builder + */ text(txt: string): IXmlBuilder; + /** + * Ends the current XML element. + * @returns the XML builder + */ end(): IXmlBuilder; } @@ -29,10 +58,13 @@ export type XmlName = string | IQualifiedName; type FieldKind = "attr" | "elem" | "none"; -/** - * - */ +/** Formats values for XML serialization. */ export interface IFormatter { + /** + * Converts a value to its XML string representation. + * @param value defines the value to format + * @returns the XML string representation + */ toString(value: T): string; } @@ -49,9 +81,11 @@ type FieldMeta = { const XML_CLASS_META = Symbol("__xml:meta$__"); const XML_CLASS_NAME = Symbol("__xml:name$__"); -function AddXmlMeta(target: any, meta: FieldMeta) { - const ctor = target.constructor; - (ctor[XML_CLASS_META] ??= []).push(meta); +function AddXmlMeta(context: { metadata: DecoratorMetadataObject }, meta: FieldMeta) { + if (!Object.prototype.hasOwnProperty.call(context.metadata, XML_CLASS_META)) { + context.metadata[XML_CLASS_META] = []; + } + (context.metadata[XML_CLASS_META] as FieldMeta[]).push(meta); } /** @@ -59,7 +93,7 @@ function AddXmlMeta(target: any, meta: FieldMeta) { * @returns */ export function XmlName(name: XmlName) { - return (ctor: Function) => { + return (ctor: Function, _context: ClassDecoratorContext) => { (ctor as any)[XML_CLASS_NAME] = name; }; } @@ -69,7 +103,8 @@ export function XmlName(name: XmlName) { * @returns */ export function XmlIgnore() { - return (target: any, prop: string) => AddXmlMeta(target, { kind: "none", prop, ignore: true }); + return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => + AddXmlMeta(context, { kind: "none", prop: String(context.name), ignore: true }); } /** @@ -77,7 +112,7 @@ export function XmlIgnore() { * @returns */ export function XmlAttr(opts?: { name: XmlName; formatter?: FormatterCtor }) { - return (target: any, prop: string) => AddXmlMeta(target, { kind: "attr", prop, ...opts }); + return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => AddXmlMeta(context, { kind: "attr", prop: String(context.name), ...opts }); } /** @@ -86,7 +121,7 @@ export function XmlAttr(opts?: { name: XmlName; formatter?: FormatterCtor } * @returns */ export function XmlElem(opts?: { name: XmlName }) { - return (target: any, prop: string) => AddXmlMeta(target, { kind: "elem", prop, ...opts }); + return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => AddXmlMeta(context, { kind: "elem", prop: String(context.name), ...opts }); } /** @@ -95,7 +130,21 @@ export function XmlElem(opts?: { name: XmlName }) { * @returns */ export function GetXmlFieldMeta(obj: any): FieldMeta[] { - return (obj?.constructor?.[XML_CLASS_META] ?? []) as FieldMeta[]; + const ctor = typeof obj === "function" ? obj : obj?.constructor; + const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + if (!metadata) { + return []; + } + // Walk metadata chain to collect all field metadata + const result: FieldMeta[] = []; + let currentMeta: any = metadata; + while (currentMeta) { + if (Object.prototype.hasOwnProperty.call(currentMeta, XML_CLASS_META)) { + result.push(...(currentMeta[XML_CLASS_META] as FieldMeta[])); + } + currentMeta = Object.getPrototypeOf(currentMeta); + } + return result; } /** diff --git a/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphNode.ts b/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphNode.ts index c55d7dd966b1..148f741c20e5 100644 --- a/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphNode.ts +++ b/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphNode.ts @@ -14,7 +14,13 @@ import { type INodeData } from "./interfaces/nodeData"; import { type IPortData } from "./interfaces/portData"; import * as localStyles from "./graphNode.module.scss"; import * as commonStyles from "./common.module.scss"; -import { type IEditablePropertyListOption, type IEditablePropertyOption, type IPropertyDescriptionForEdition, PropertyTypeForEdition } from "core/Decorators/nodeDecorator"; +import { + type IEditablePropertyListOption, + type IEditablePropertyOption, + type IPropertyDescriptionForEdition, + GetEditableProperties, + PropertyTypeForEdition, +} from "core/Decorators/nodeDecorator"; import { ForceRebuild } from "./automaticProperties"; import dropdownArrowIcon from "../imgs/dropdownArrowIcon_white.svg"; import { BuildFloatUI } from "./tools"; @@ -940,20 +946,12 @@ export class GraphNode { } // Options - const propStore: IPropertyDescriptionForEdition[] = this.content.data._propStore; - if (propStore) { + const propStore: IPropertyDescriptionForEdition[] = GetEditableProperties(this.content.data); + if (propStore.length) { const source = this.content.data; - const classes: string[] = []; - - let proto = Object.getPrototypeOf(source); - while (proto && proto.getClassName) { - classes.push(proto.getClassName()); - proto = Object.getPrototypeOf(proto); - } - - for (const { propertyName, displayName, type, options, className } of propStore) { - if (!options || !options.embedded || classes.indexOf(className) === -1) { + for (const { propertyName, displayName, type, options } of propStore) { + if (!options || !options.embedded) { continue; } diff --git a/packages/dev/smartFilters/src/blockFoundation/customShaderBlock.ts b/packages/dev/smartFilters/src/blockFoundation/customShaderBlock.ts index f3fcd9edcb23..95e7ccf0aa52 100644 --- a/packages/dev/smartFilters/src/blockFoundation/customShaderBlock.ts +++ b/packages/dev/smartFilters/src/blockFoundation/customShaderBlock.ts @@ -245,7 +245,8 @@ export class CustomShaderBlock extends ShaderBlock { const propertyType: PropertyTypeForEdition = constProperty.options ? PropertyTypeForEdition.List : PropertyTypeForEdition.Float; const decoratorApplier = EditableInPropertyPage(constProperty.friendlyName, propertyType, "PROPERTIES", editablePropertyOptions); - decoratorApplier(this, constProperty.friendlyName); + const metadata = (this.constructor as any)[Symbol.metadata] ?? ((this.constructor as any)[Symbol.metadata] = Object.create(null)); + decoratorApplier(undefined, { name: constProperty.friendlyName, metadata }); } /** diff --git a/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts b/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts index d2edf7351209..0942c1b24191 100644 --- a/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts +++ b/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts @@ -78,6 +78,10 @@ export interface IPropertyDescriptionForEdition { className: string; } +/** @internal */ +// eslint-disable-next-line @typescript-eslint/naming-convention +const __bjsSmartFilterPropStoreKey = "__bjs_sf_prop_store__"; + /** * Decorator that flags a property in a node block as being editable * @param displayName - the display name of the property @@ -92,25 +96,30 @@ export function EditableInPropertyPage( groupName: string = "PROPERTIES", options?: IEditablePropertyOption ) { - return (target: any, propertyKey: string) => { - let propStore: IPropertyDescriptionForEdition[] = target._propStore; - if (!propStore) { + return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => { + const meta = context.metadata; + let propStore: IPropertyDescriptionForEdition[]; + if (Object.prototype.hasOwnProperty.call(meta, __bjsSmartFilterPropStoreKey)) { + propStore = meta[__bjsSmartFilterPropStoreKey] as IPropertyDescriptionForEdition[]; + } else { propStore = []; - target._propStore = propStore; + meta[__bjsSmartFilterPropStoreKey] = propStore; } + const propertyKey = String(context.name); + const propToAdd: IPropertyDescriptionForEdition = { propertyName: propertyKey, displayName: displayName, type: propertyType, groupName: groupName, options: options ?? {}, - className: target.constructor.name, + className: "", }; // If the property already exists, overwrite it, otherwise add it // Note: It may have been redefined since the application started - const existingIndex = propStore.findIndex((p) => p.propertyName === propertyKey && p.className === target.constructor.name && options?.blockType === p.options?.blockType); + const existingIndex = propStore.findIndex((p) => p.propertyName === propertyKey && options?.blockType === p.options?.blockType); if (existingIndex !== -1) { propStore[existingIndex] = propToAdd; } else { @@ -118,3 +127,28 @@ export function EditableInPropertyPage( } }; } + +/** + * Gets the editable properties for a given target using TC39 decorator metadata. + * Walks the metadata prototype chain to include properties from parent classes. + * @param target - the target object (instance or constructor) + * @returns array of property descriptions + */ +export function GetSmartFilterEditableProperties(target: any): IPropertyDescriptionForEdition[] { + const ctor = typeof target === "function" ? target : target?.constructor; + const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + if (!metadata) { + return []; + } + + const result: IPropertyDescriptionForEdition[] = []; + let currentMeta: any = metadata; + while (currentMeta) { + if (Object.prototype.hasOwnProperty.call(currentMeta, __bjsSmartFilterPropStoreKey)) { + const store = currentMeta[__bjsSmartFilterPropStoreKey] as IPropertyDescriptionForEdition[]; + result.push(...store); + } + currentMeta = Object.getPrototypeOf(currentMeta); + } + return result; +} diff --git a/packages/dev/smartFilters/src/utils/buildTools/convertShaders.ts b/packages/dev/smartFilters/src/utils/buildTools/convertShaders.ts index cbfd80b50267..3e7d39bdd202 100644 --- a/packages/dev/smartFilters/src/utils/buildTools/convertShaders.ts +++ b/packages/dev/smartFilters/src/utils/buildTools/convertShaders.ts @@ -14,26 +14,18 @@ import { log, error } from "./buildToolsLogger.js"; export function ConvertShaders(shaderPath: string, smartFiltersCorePath: string, babylonCorePath?: string) { const stats = fs.statSync(shaderPath); - let shaderFiles: fs.Dirent[]; + let shaderFiles: { name: string; dir: string }[]; if (stats.isFile()) { - // If it's a file, create a Dirent-like object for consistency - const fileName = path.basename(shaderPath); - const dirPath = path.dirname(shaderPath); - shaderFiles = [ - { - name: fileName, - parentPath: dirPath, - isFile: () => true, - isDirectory: () => false, - } as unknown as fs.Dirent, - ]; + shaderFiles = [{ name: path.basename(shaderPath), dir: path.dirname(shaderPath) }]; } else if (stats.isDirectory()) { // Get all files in the directory const allFiles = fs.readdirSync(shaderPath, { withFileTypes: true, recursive: true }); // Find all shaders (files with .fragment.glsl or .block.glsl extensions) - shaderFiles = allFiles.filter((file) => file.isFile() && (file.name.endsWith(".fragment.glsl") || file.name.endsWith(".block.glsl"))); + shaderFiles = allFiles + .filter((file) => file.isFile() && (file.name.endsWith(".fragment.glsl") || file.name.endsWith(".block.glsl"))) + .map((file) => ({ name: file.name, dir: file.parentPath })); } else { error(`Error: ${shaderPath} is neither a file nor a directory.`); return; @@ -41,7 +33,7 @@ export function ConvertShaders(shaderPath: string, smartFiltersCorePath: string, // Convert all shaders for (const shaderFile of shaderFiles) { - const fullPathAndFileName = path.join(shaderFile.parentPath, shaderFile.name); + const fullPathAndFileName = path.join(shaderFile.dir, shaderFile.name); ConvertShader(fullPathAndFileName, smartFiltersCorePath, babylonCorePath); } } diff --git a/packages/dev/smartFilters/test/unit/customShaderBlock.test.ts b/packages/dev/smartFilters/test/unit/customShaderBlock.test.ts index 07902fabc812..1be7f6998f98 100644 --- a/packages/dev/smartFilters/test/unit/customShaderBlock.test.ts +++ b/packages/dev/smartFilters/test/unit/customShaderBlock.test.ts @@ -1,10 +1,10 @@ /* eslint-disable vitest/no-conditional-expect */ -import { Logger } from "../../src"; +import { Logger } from "../../src/index.js"; import { SmartFilter } from "../../src/smartFilter.js"; import { ImportCustomBlockDefinition } from "../../src/serialization/importCustomBlockDefinition.js"; import { CustomShaderBlock } from "../../src/blockFoundation/customShaderBlock.js"; import { SerializedShaderBlockDefinitionV1 } from "../../src/serialization/v1/shaderBlockSerialization.types"; -import { IPropertyDescriptionForEdition, PropertyTypeForEdition } from "../../src/editorUtils/editableInPropertyPage.js"; +import { PropertyTypeForEdition, GetSmartFilterEditableProperties } from "../../src/editorUtils/editableInPropertyPage.js"; const glslValidFloatDefaultValue = ` // { "smartFilterBlockType": "TestBlock", "namespace": "Bug.Repro" } @@ -245,7 +245,7 @@ vec4 test(vec2 vUV) { // main const customShaderBlock = CustomShaderBlock.Create(smartFilter, "TestBlock", blockDefinition); // Assert - expect((customShaderBlock as any)._propStore as IPropertyDescriptionForEdition[]).toContainEqual({ + expect(GetSmartFilterEditableProperties(customShaderBlock)).toContainEqual({ propertyName: "cp", displayName: "cp", type: PropertyTypeForEdition.List, @@ -261,7 +261,7 @@ vec4 test(vec2 vUV) { // main { label: "full", value: 1 }, ], }, - className: "CustomShaderBlock", + className: "", }); }); diff --git a/packages/public/@babylonjs/core/package.json b/packages/public/@babylonjs/core/package.json index 688c7cccb904..d71b83152869 100644 --- a/packages/public/@babylonjs/core/package.json +++ b/packages/public/@babylonjs/core/package.json @@ -660,6 +660,7 @@ "Misc/PerformanceViewer/performanceViewerSceneExtension.js", "Misc/basis.js", "Misc/dds.js", + "Misc/decorators.functions.js", "Misc/dumpTools.js", "Misc/environmentTextureTools.js", "Misc/equirectangularCapture.js", diff --git a/packages/public/umd/babylonjs-addons/tsconfig.build.json b/packages/public/umd/babylonjs-addons/tsconfig.build.json index cb3b01f2d70e..f452bcac2c39 100644 --- a/packages/public/umd/babylonjs-addons/tsconfig.build.json +++ b/packages/public/umd/babylonjs-addons/tsconfig.build.json @@ -3,8 +3,7 @@ "compilerOptions": { "outDir": "./dist", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "rootDir": "../../../", "declaration": false, "importHelpers": true, diff --git a/packages/public/umd/babylonjs-gui/tsconfig.build.json b/packages/public/umd/babylonjs-gui/tsconfig.build.json index 5b5682d28400..56dde1bd0ca4 100644 --- a/packages/public/umd/babylonjs-gui/tsconfig.build.json +++ b/packages/public/umd/babylonjs-gui/tsconfig.build.json @@ -4,8 +4,7 @@ "compilerOptions": { "outDir": "./dist", "rootDir": "../../../", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "declaration": false, "importHelpers": true, "paths": { diff --git a/packages/public/umd/babylonjs-loaders/tsconfig.build.json b/packages/public/umd/babylonjs-loaders/tsconfig.build.json index c6966c2dd0d1..94a841ba9838 100644 --- a/packages/public/umd/babylonjs-loaders/tsconfig.build.json +++ b/packages/public/umd/babylonjs-loaders/tsconfig.build.json @@ -3,8 +3,7 @@ "compilerOptions": { "outDir": "./dist", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "rootDir": "../../../", "declaration": false, "importHelpers": true, diff --git a/packages/public/umd/babylonjs-materials/tsconfig.build.json b/packages/public/umd/babylonjs-materials/tsconfig.build.json index a534d1238b96..e4cdb74b9e23 100644 --- a/packages/public/umd/babylonjs-materials/tsconfig.build.json +++ b/packages/public/umd/babylonjs-materials/tsconfig.build.json @@ -3,8 +3,7 @@ "compilerOptions": { "outDir": "./dist", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "rootDir": "../../../", "declaration": false, "importHelpers": true, diff --git a/packages/public/umd/babylonjs-post-process/tsconfig.build.json b/packages/public/umd/babylonjs-post-process/tsconfig.build.json index b2e29e4642a4..93c9cc1b2bd5 100644 --- a/packages/public/umd/babylonjs-post-process/tsconfig.build.json +++ b/packages/public/umd/babylonjs-post-process/tsconfig.build.json @@ -4,8 +4,7 @@ "compilerOptions": { "outDir": "./dist", "rootDir": "../../../", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "declaration": false, "importHelpers": true, "paths": { diff --git a/packages/public/umd/babylonjs-procedural-textures/tsconfig.build.json b/packages/public/umd/babylonjs-procedural-textures/tsconfig.build.json index e48d00ee4b50..a0fb18816388 100644 --- a/packages/public/umd/babylonjs-procedural-textures/tsconfig.build.json +++ b/packages/public/umd/babylonjs-procedural-textures/tsconfig.build.json @@ -4,8 +4,7 @@ "compilerOptions": { "outDir": "./dist", "rootDir": "../../../", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "declaration": false, "importHelpers": true, "paths": { diff --git a/packages/public/umd/babylonjs-serializers/tsconfig.build.json b/packages/public/umd/babylonjs-serializers/tsconfig.build.json index b3ef218824ee..6aedbcb10163 100644 --- a/packages/public/umd/babylonjs-serializers/tsconfig.build.json +++ b/packages/public/umd/babylonjs-serializers/tsconfig.build.json @@ -4,8 +4,7 @@ "compilerOptions": { "outDir": "./dist", "rootDir": "../../../", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "declaration": false, "importHelpers": true, "paths": { diff --git a/packages/public/umd/babylonjs/tsconfig.build.json b/packages/public/umd/babylonjs/tsconfig.build.json index 271cbc291d76..6b7527078c5e 100644 --- a/packages/public/umd/babylonjs/tsconfig.build.json +++ b/packages/public/umd/babylonjs/tsconfig.build.json @@ -3,8 +3,7 @@ "compilerOptions": { "outDir": "./dist", - "target": "ES5", - "ignoreDeprecations": "6.0", + "target": "es2015", "rootDir": "../../../", "declaration": false, "importHelpers": true, diff --git a/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx b/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx index 7535c67c5061..62fa23682277 100644 --- a/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx +++ b/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx @@ -16,7 +16,7 @@ import { Vector4LineComponent } from "shared-ui-components/lines/vector4LineComp import { type FlowGraphBlock } from "core/FlowGraph/flowGraphBlock"; import { type FlowGraphDataConnection } from "core/FlowGraph/flowGraphDataConnection"; import { FlowGraphInteger } from "core/FlowGraph/CustomTypes/flowGraphInteger"; -import { type IEditablePropertyListOption, type IPropertyDescriptionForEdition, PropertyTypeForEdition } from "core/Decorators/nodeDecorator"; +import { type IEditablePropertyListOption, type IPropertyDescriptionForEdition, PropertyTypeForEdition, GetEditableProperties } from "core/Decorators/nodeDecorator"; import { ForceRebuild } from "shared-ui-components/nodeGraphSystem/automaticProperties"; import { EDITABLE_INPUTS } from "./editableInputsRegistry"; import { CONSTRUCTOR_CONFIG, FLOW_GRAPH_TYPE_OPTIONS } from "./constructorConfigRegistry"; @@ -509,30 +509,18 @@ export class GenericPropertyTabComponent extends React.Component; } const componentList: { [groupName: string]: JSX.Element[] } = {}, groups: string[] = []; - const classes: string[] = []; - - let proto = Object.getPrototypeOf(block); - while (proto && proto.getClassName) { - classes.push(proto.getClassName()); - proto = Object.getPrototypeOf(proto); - } - - for (const { propertyName, displayName, type, groupName, options, className } of propStore) { + for (const { propertyName, displayName, type, groupName, options } of propStore) { let components = componentList[groupName]; - if (classes.indexOf(className) === -1) { - continue; - } - if (!components) { components = []; componentList[groupName] = components; diff --git a/packages/tools/guiEditor/src/components/propertyTab/propertyGrids/gui/gridPropertyGridComponent.tsx b/packages/tools/guiEditor/src/components/propertyTab/propertyGrids/gui/gridPropertyGridComponent.tsx index 2c36ca8220e9..4d54a7fd11bc 100644 --- a/packages/tools/guiEditor/src/components/propertyTab/propertyGrids/gui/gridPropertyGridComponent.tsx +++ b/packages/tools/guiEditor/src/components/propertyTab/propertyGrids/gui/gridPropertyGridComponent.tsx @@ -158,7 +158,8 @@ export class GridPropertyGridComponent extends React.Component { @@ -145,30 +145,18 @@ export class GenericPropertyTabComponent extends React.Component; } const componentList: { [groupName: string]: JSX.Element[] } = {}, groups: string[] = []; - const classes: string[] = []; - - let proto = Object.getPrototypeOf(block); - while (proto && proto.getClassName) { - classes.push(proto.getClassName()); - proto = Object.getPrototypeOf(proto); - } - - for (const { propertyName, displayName, type, groupName, options, className } of propStore) { + for (const { propertyName, displayName, type, groupName, options } of propStore) { let components = componentList[groupName]; - if (classes.indexOf(className) === -1) { - continue; - } - if (!components) { components = []; componentList[groupName] = components; diff --git a/packages/tools/nodeParticleEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx b/packages/tools/nodeParticleEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx index 48ca90672761..92741c29dae2 100644 --- a/packages/tools/nodeParticleEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx +++ b/packages/tools/nodeParticleEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx @@ -9,7 +9,7 @@ import { TextLineComponent } from "shared-ui-components/lines/textLineComponent" import { FloatLineComponent } from "shared-ui-components/lines/floatLineComponent"; import { SliderLineComponent } from "shared-ui-components/lines/sliderLineComponent"; import { Vector3LineComponent } from "shared-ui-components/lines/vector3LineComponent"; -import { type IEditablePropertyListOption, PropertyTypeForEdition, type IPropertyDescriptionForEdition } from "core/Decorators/nodeDecorator"; +import { type IEditablePropertyListOption, PropertyTypeForEdition, GetEditableProperties, type IPropertyDescriptionForEdition } from "core/Decorators/nodeDecorator"; import { ForceRebuild } from "shared-ui-components/nodeGraphSystem/automaticProperties"; import { NodeParticleBlockConnectionPointTypes } from "core/Particles/Node/Enums/nodeParticleBlockConnectionPointTypes"; import { type NodeParticleConnectionPoint } from "core/Particles/Node/nodeParticleBlockConnectionPoint"; @@ -142,30 +142,18 @@ export class GenericPropertyTabComponent extends React.Component; } const componentList: { [groupName: string]: JSX.Element[] } = {}, groups: string[] = []; - const classes: string[] = []; - - let proto = Object.getPrototypeOf(block); - while (proto && proto.getClassName) { - classes.push(proto.getClassName()); - proto = Object.getPrototypeOf(proto); - } - - for (const { propertyName, displayName, type, groupName, options, className } of propStore) { + for (const { propertyName, displayName, type, groupName, options } of propStore) { let components = componentList[groupName]; - if (classes.indexOf(className) === -1) { - continue; - } - if (!components) { components = []; componentList[groupName] = components; diff --git a/packages/tools/nodeRenderGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx b/packages/tools/nodeRenderGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx index 0f6c7e8affed..c418a9d4a47c 100644 --- a/packages/tools/nodeRenderGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx +++ b/packages/tools/nodeRenderGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx @@ -12,7 +12,7 @@ import { SliderLineComponent } from "shared-ui-components/lines/sliderLineCompon import { Color4LineComponent } from "shared-ui-components/lines/color4LineComponent"; import { MatrixLineComponent } from "shared-ui-components/lines/matrixLineComponent"; import { type NodeRenderGraphBlock } from "core/FrameGraph/Node/nodeRenderGraphBlock"; -import { type IEditablePropertyListOption, type IPropertyDescriptionForEdition, PropertyTypeForEdition } from "core/Decorators/nodeDecorator"; +import { type IEditablePropertyListOption, type IPropertyDescriptionForEdition, PropertyTypeForEdition, GetEditableProperties } from "core/Decorators/nodeDecorator"; import { Constants } from "core/Engines/constants"; import { ForceRebuild } from "shared-ui-components/nodeGraphSystem/automaticProperties"; import { Color3LineComponent } from "shared-ui-components/lines/color3LineComponent"; @@ -144,30 +144,18 @@ export class GenericPropertyTabComponent extends React.Component; } const componentList: { [groupName: string]: JSX.Element[] } = {}, groups: string[] = []; - const classes: string[] = []; - - let proto = Object.getPrototypeOf(block); - while (proto && proto.getClassName) { - classes.push(proto.getClassName()); - proto = Object.getPrototypeOf(proto); - } - - for (const { propertyName, displayName, type, groupName, options, className } of propStore) { + for (const { propertyName, displayName, type, groupName, options } of propStore) { let components = componentList[groupName]; - if (classes.indexOf(className) === -1) { - continue; - } - if (!components) { components = []; componentList[groupName] = components; diff --git a/packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts b/packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts index 49b790bbe2a3..dc6dbab25e02 100644 --- a/packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts +++ b/packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts @@ -22,8 +22,6 @@ const TsOptions = { baseUrl: "file:///pg/", typeRoots: [], isolatedModules: true, - experimentalDecorators: true, - emitDecoratorMetadata: false, allowUmdGlobalAccess: true, inlineSourceMap: true, inlineSources: true, diff --git a/packages/tools/smartFiltersEditorControl/src/configuration/editorBlocks/webCamInputBlock/webCamInputBlock.ts b/packages/tools/smartFiltersEditorControl/src/configuration/editorBlocks/webCamInputBlock/webCamInputBlock.ts index 63d9b6cbee5f..24ebd31b5ee7 100644 --- a/packages/tools/smartFiltersEditorControl/src/configuration/editorBlocks/webCamInputBlock/webCamInputBlock.ts +++ b/packages/tools/smartFiltersEditorControl/src/configuration/editorBlocks/webCamInputBlock/webCamInputBlock.ts @@ -125,7 +125,9 @@ export class WebCamInputBlock extends InputBlock { */ @editableInPropertyPage("Source", PropertyTypeForEdition.List, "PROPERTIES", { notifiers: { update: true }, - options: WebCamInputBlock._WebCamSourceManager.onSourcesLoaded as Observable, + get options() { + return WebCamInputBlock._WebCamSourceManager.onSourcesLoaded as Observable; + }, valuesAreStrings: true, }) public set webcamSourceId(id: string) { diff --git a/packages/tools/smartFiltersEditorControl/src/graphSystem/properties/genericNodePropertyComponent.tsx b/packages/tools/smartFiltersEditorControl/src/graphSystem/properties/genericNodePropertyComponent.tsx index b451520aaa2f..04df868a5aab 100644 --- a/packages/tools/smartFiltersEditorControl/src/graphSystem/properties/genericNodePropertyComponent.tsx +++ b/packages/tools/smartFiltersEditorControl/src/graphSystem/properties/genericNodePropertyComponent.tsx @@ -3,7 +3,7 @@ import { LineContainerComponent } from "../../sharedComponents/lineContainerComp import { TextInputLineComponent } from "shared-ui-components/lines/textInputLineComponent.js"; import { TextLineComponent } from "shared-ui-components/lines/textLineComponent.js"; import { type IPropertyComponentProps } from "shared-ui-components/nodeGraphSystem/interfaces/propertyComponentProps"; -import { type BaseBlock, PropertyTypeForEdition, type IEditablePropertyOption, type IPropertyDescriptionForEdition } from "smart-filters"; +import { type BaseBlock, PropertyTypeForEdition, type IEditablePropertyOption, type IPropertyDescriptionForEdition, GetSmartFilterEditableProperties } from "smart-filters"; import { CheckBoxLineComponent } from "../../sharedComponents/checkBoxLineComponent.js"; import { FloatSliderComponent } from "../../sharedComponents/floatSliderComponent.js"; import { FloatLineComponent } from "shared-ui-components/lines/floatLineComponent.js"; @@ -99,8 +99,8 @@ export class GenericPropertyTabComponent extends react.Component; } const componentList: { [groupName: string]: JSX.Element[] } = {}; const groups: string[] = []; - const classes: string[] = []; - let proto = Object.getPrototypeOf(block); - while (proto) { - classes.push(proto.constructor.name); - proto = Object.getPrototypeOf(proto); - } - for (const propDescription of propStore) { - const { displayName, type, groupName, options, className } = propDescription; + const { displayName, type, groupName, options } = propDescription; let propertyName = propDescription.propertyName; let target: unknown = block; @@ -138,10 +131,6 @@ export class GenericPropertyTabComponent extends react.Component; } diff --git a/packages/tools/snippetLoader/src/snippetLoader.ts b/packages/tools/snippetLoader/src/snippetLoader.ts index 64b5bf630528..08cd42f79303 100644 --- a/packages/tools/snippetLoader/src/snippetLoader.ts +++ b/packages/tools/snippetLoader/src/snippetLoader.ts @@ -68,8 +68,6 @@ async function BuiltInTranspile(source: string, fileName: string): Promise = null; @@ -2352,7 +2353,9 @@ export class Viewer extends ViewerBase implements IDisposable, IViewer { } protected _markSceneMutated() { - this._sceneMutated = true; + if (!this._suppressMutations) { + this._sceneMutated = true; + } } protected _suspendRendering(): IDisposable { @@ -2401,7 +2404,12 @@ export class Viewer extends ViewerBase implements IDisposable, IViewer { this._engine.performanceMonitor.disable(); this._engine.setHardwareScalingLevel(this._defaultHardwareScalingLevel); this._engine.beginFrame(); + // The idle sync render should not trigger a new render cycle (e.g. due to camera inertia + // firing onViewMatrixChangedObservable), so suppress any mutations it may cause. + this._suppressMutations = true; this._scene.render(); + this._suppressMutations = false; + this._sceneMutated = false; this._engine.endFrame(); }; diff --git a/packages/tools/viewer/src/viewerAnnotationElement.ts b/packages/tools/viewer/src/viewerAnnotationElement.ts index 6dfdd3fba061..0549e63bdf4c 100644 --- a/packages/tools/viewer/src/viewerAnnotationElement.ts +++ b/packages/tools/viewer/src/viewerAnnotationElement.ts @@ -70,7 +70,7 @@ export class HTML3DAnnotationElement extends LitElement { * The name of the hotspot to track. */ @property({ attribute: "hotspot" }) - public hotSpot: string = ""; + public accessor hotSpot: string = ""; /** @internal */ public override connectedCallback(): void { diff --git a/packages/tools/viewer/src/viewerElement.ts b/packages/tools/viewer/src/viewerElement.ts index 47c6ac021108..6abbc29b3a20 100644 --- a/packages/tools/viewer/src/viewerElement.ts +++ b/packages/tools/viewer/src/viewerElement.ts @@ -59,7 +59,7 @@ export abstract class ViewerElement extends toAttribute: (color: Nullable) => (color ? color.toHexString() : null), }, }) - public override clearColor: Nullable = this._options.clearColor + public override accessor clearColor: Nullable = this._options.clearColor ? new Color4(this._options.clearColor[0], this._options.clearColor[1], this._options.clearColor[2], this._options.clearColor[3] ?? 1) : null; @@ -67,7 +67,7 @@ export abstract class ViewerElement extends * The engine to use for rendering. */ @property({ converter: coerceEngineAttribute }) - public engine: CanvasViewerOptions["engine"] = this._options.engine; + public accessor engine: CanvasViewerOptions["engine"] = this._options.engine; protected override _needsReload(changedProperties: Map): boolean { if (super._needsReload(changedProperties)) { diff --git a/packages/tools/viewer/src/viewerElementBase.ts b/packages/tools/viewer/src/viewerElementBase.ts index 9c383e5453df..f5ef58129530 100644 --- a/packages/tools/viewer/src/viewerElementBase.ts +++ b/packages/tools/viewer/src/viewerElementBase.ts @@ -598,7 +598,7 @@ export abstract class ViewerElementBase = this._options.source ?? null; + public accessor source: Nullable = this._options.source ?? null; /** * Forces the model to be loaded with the specified extension. @@ -622,26 +622,27 @@ export abstract class ViewerElementBase = null; + public accessor extension: Nullable = null; /** * If true, load glTF files using the OpenPBR material instead of the default PBR material. * @experimental */ @property({ attribute: "use-open-pbr", type: Boolean }) - public useOpenPBR: boolean = this._options.useOpenPBR ?? false; + public accessor useOpenPBR: boolean = this._options.useOpenPBR ?? false; /** * The texture URLs used for lighting and skybox. Setting this property will set both environmentLighting and environmentSkybox. */ - @property({ - hasChanged: (newValue: ViewerElementBase["environment"], oldValue: ViewerElementBase["environment"]) => { - return newValue.lighting !== oldValue.lighting || newValue.skybox !== oldValue.skybox; - }, - }) public get environment(): { lighting: Nullable; skybox: Nullable } { return { lighting: this.environmentLighting, skybox: this.environmentSkybox }; } + @property({ + hasChanged: (newValue: string, oldValue: ViewerElementBase["environment"]) => { + const environmentUrl = newValue || null; + return environmentUrl !== oldValue.lighting || environmentUrl !== oldValue.skybox; + }, + }) public set environment(url: string) { this.environmentLighting = url || null; this.environmentSkybox = url || null; @@ -651,19 +652,19 @@ export abstract class ViewerElementBase = this._options.environmentLighting ?? null; + public accessor environmentLighting: Nullable = this._options.environmentLighting ?? null; /** * The texture URL for the skybox. */ @property({ attribute: "environment-skybox" }) - public environmentSkybox: Nullable = this._options.environmentSkybox ?? null; + public accessor environmentSkybox: Nullable = this._options.environmentSkybox ?? null; /** * A value between 0 and 2 that specifies the intensity of the environment lighting. */ @property({ type: Number, attribute: "environment-intensity" }) - public environmentIntensity: Nullable = this._options.environmentConfig?.intensity ?? null; + public accessor environmentIntensity: Nullable = this._options.environmentConfig?.intensity ?? null; /** * A value in radians that specifies the rotation of the environment. @@ -672,7 +673,7 @@ export abstract class ViewerElementBase = this._options.environmentConfig?.rotation ?? null; + public accessor environmentRotation: Nullable = this._options.environmentConfig?.rotation ?? null; /** * The type of shadows to use. @@ -680,10 +681,10 @@ export abstract class ViewerElementBase = null; + public accessor shadowQuality: Nullable = null; @state() - private _loadingProgress: boolean | number = false; + private accessor _loadingProgress: boolean | number = false; /** * Gets information about loading activity. @@ -700,7 +701,7 @@ export abstract class ViewerElementBase = this._options.environmentConfig?.blur ?? null; + public accessor skyboxBlur: Nullable = this._options.environmentConfig?.blur ?? null; /** * The tone mapping to use for rendering the scene. @@ -714,25 +715,25 @@ export abstract class ViewerElementBase = this._options.postProcessing?.toneMapping ?? null; + public accessor toneMapping: Nullable = this._options.postProcessing?.toneMapping ?? null; /** * The contrast applied to the scene. */ @property() - public contrast: Nullable = this._options.postProcessing?.contrast ?? null; + public accessor contrast: Nullable = this._options.postProcessing?.contrast ?? null; /** * The exposure applied to the scene. */ @property() - public exposure: Nullable = this._options.postProcessing?.exposure ?? null; + public accessor exposure: Nullable = this._options.postProcessing?.exposure ?? null; /** * Enables or disables screen space ambient occlusion (SSAO). */ @property({ type: String }) - public ssao: Nullable = this._options.postProcessing?.ssao ?? null; + public accessor ssao: Nullable = this._options.postProcessing?.ssao ?? null; /** * The clear color (e.g. background color) for the viewer. @@ -744,7 +745,7 @@ export abstract class ViewerElementBase) => (color ? colorToHex(color) : null), }, }) - public clearColor: Nullable = this._options.clearColor + public accessor clearColor: Nullable = this._options.clearColor ? { r: this._options.clearColor[0], g: this._options.clearColor[1], b: this._options.clearColor[2], a: this._options.clearColor[3] ?? 1 } : null; @@ -755,7 +756,7 @@ export abstract class ViewerElementBase = this._options.cameraAutoOrbit?.speed ?? null; + public accessor cameraAutoOrbitSpeed: Nullable = this._options.cameraAutoOrbit?.speed ?? null; /** * The delay in milliseconds before the camera starts auto-orbiting. @@ -773,7 +774,7 @@ export abstract class ViewerElementBase = this._options.cameraAutoOrbit?.delay ?? null; + public accessor cameraAutoOrbitDelay: Nullable = this._options.cameraAutoOrbit?.delay ?? null; /** * The set of defined hot spots. @@ -788,7 +789,7 @@ export abstract class ViewerElementBase = this._options.hotSpots ?? {}; + public accessor hotSpots: Record = this._options.hotSpots ?? {}; /** * True if the viewer has any hotspots. @@ -801,7 +802,7 @@ export abstract class ViewerElementBase = this._options.selectedAnimation ?? null; + public accessor selectedAnimation: Nullable = this._options.selectedAnimation ?? null; /** * True if an animation is currently playing. @@ -834,22 +835,22 @@ export abstract class ViewerElementBase = this._options.selectedMaterialVariant ?? null; + public accessor selectedMaterialVariant: Nullable = this._options.selectedMaterialVariant ?? null; /** * True if scene cameras should be used as hotspots. */ @property({ attribute: "cameras-as-hotspots", type: Boolean }) - public camerasAsHotSpots = false; + public accessor camerasAsHotSpots = false; /** * Determines the behavior of the reset function, and the associated default reset button. @@ -878,13 +879,13 @@ export abstract class ViewerElementBase { }; }; +// TC39 decorators migration: removing experimentalDecorators changes esbuild's +// default class field semantics. Explicitly keep assignment semantics to prevent +// type-only field overrides from shadowing parent constructor assignments. +const esbuildConfig = { + target: "es2021" as const, + tsconfigRaw: { + compilerOptions: { + useDefineForClassFields: false, + }, + }, +}; + // babylonjs-gltf2interface is a types-only package (const enums inlined by // TypeScript at compile time). It has no JS entry point, so Vite's resolver // cannot find one. Provide a runtime stub so glTF loader tests can import @@ -57,6 +69,7 @@ const createProjectConfig = (type: string) => { const gltf2InterfaceStub = path.resolve(__dirname, "packages/public/glTF2Interface/babylonjs-gltf2interface.stub.ts"); export default defineConfig({ + esbuild: esbuildConfig, resolve: { alias: { ...aliases, @@ -71,6 +84,7 @@ export default defineConfig({ outputFile: process.env.CI ? { junit: "./junit.xml" } : undefined, projects: [ { + esbuild: esbuildConfig, test: createProjectConfig("unit"), resolve: { alias: { diff --git a/vitest.setup.ts b/vitest.setup.ts index f3caec82e38e..b1a7b63e2bc0 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -4,6 +4,10 @@ */ import { vi } from "vitest"; +// Polyfill Symbol.metadata for TC39 Stage 3 decorators +// Node.js does not yet support Symbol.metadata natively +(Symbol as any).metadata ??= Symbol.for("Symbol.metadata"); + // Mock optional external packages that may not be installed vi.mock("draco3dgltf", () => ({ DracoDecoderModule: vi.fn(),