From 379ca647a6298afe7ede1ad82f37863f95509430 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:47:53 +0200 Subject: [PATCH 01/20] TC39 core-infra: TC39 decorator signatures and compiler flip Rewrite Misc/decorators.ts serialize*/expandToProperty/nativeOverride/ addAccessorsForMaterialProperty to TC39 Stage 3 decorator signatures (returning ClassAccessorDecoratorResult where needed). Add GetDirectStoreFromMetadata to decorators.functions.ts for the TC39 context.metadata write path. Drop experimentalDecorators and set useDefineForClassFields:false in tsconfig.json/tsconfig.build.json, add esnext.decorators lib; add esnext.decorators + es2022.object to test lib. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../dev/core/src/Misc/decorators.functions.ts | 12 ++ packages/dev/core/src/Misc/decorators.ts | 160 +++++++++++------- tsconfig.build.json | 7 +- tsconfig.json | 2 +- tsconfig.test.json | 4 +- 5 files changed, 118 insertions(+), 67 deletions(-) diff --git a/packages/dev/core/src/Misc/decorators.functions.ts b/packages/dev/core/src/Misc/decorators.functions.ts index f8809dfcb5a..0364fa7e419 100644 --- a/packages/dev/core/src/Misc/decorators.functions.ts +++ b/packages/dev/core/src/Misc/decorators.functions.ts @@ -60,6 +60,18 @@ function GetOwnMetadata(ctor: any): any { return ctor[GetMetadataSymbol()]; } +/** + * Returns (creating if necessary) the serialization store owned by the provided decorator metadata. + * Used by the TC39 decorators, which receive `context.metadata` directly. + * @internal + */ +export function GetDirectStoreFromMetadata(metadata: DecoratorMetadataObject): Record { + if (!HasOwn(metadata, __bjsSerializableKey)) { + (metadata as any)[__bjsSerializableKey] = {}; + } + return (metadata as any)[__bjsSerializableKey]; +} + /** @internal */ export function GetDirectStore(target: any): any { const metadata = GetOwnMetadata(GetConstructor(target)); diff --git a/packages/dev/core/src/Misc/decorators.ts b/packages/dev/core/src/Misc/decorators.ts index 42b79eb9de2..0aa458db340 100644 --- a/packages/dev/core/src/Misc/decorators.ts +++ b/packages/dev/core/src/Misc/decorators.ts @@ -1,28 +1,46 @@ /* 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. + * `metadata` can be undefined at runtime when `Symbol.metadata` is not available (e.g. tree-shaken + * usage on a runtime that lacks native support and never triggered the polyfill); in that case the + * serialization metadata is simply not recorded. + */ +type SerializableContext = { name: string | symbol; metadata: DecoratorMetadataObject | undefined }; + function generateSerializableMember(type: number, sourceName?: string) { - return (target: any, propertyKey: string | symbol) => { - const classStore = GetDirectStore(target); + return (_value: unknown, context: SerializableContext) => { + if (!context.metadata) { + return; + } + 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 +53,9 @@ function generateExpandMember(setCallback: string, targetKey: Nullable = } this[key] = value; - target[setCallback].apply(this); + this[setCallback](); }, - enumerable: true, - configurable: true, - }); + }; }; } @@ -111,40 +127,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 +164,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 +225,8 @@ export function addAccessorsForMaterialProperty(setCallback: string, targetKey: } this[key].value = value; - target[setCallback].apply(this); + this[setCallback](); }, - enumerable: true, - configurable: true, - }); + }; }; } diff --git a/tsconfig.build.json b/tsconfig.build.json index d9ba8477262..d0813f8602b 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -8,11 +8,11 @@ "strictPropertyInitialization": false, "types": ["node"], "module": "ES2020", - "target": "es2021", // esnext has an issue with class generation and our decoders. TODO - avoid using decorators until in standard + "target": "es2021", + "useDefineForClassFields": false, "declaration": true, "sourceMap": true, "inlineSources": true, - "experimentalDecorators": true, "noImplicitOverride": true, "noImplicitReturns": true, "noUnusedLocals": true, @@ -32,7 +32,8 @@ "es2022.error", "es2022.array", "es2021.string", - "es2022.string" + "es2022.string", + "esnext.decorators" ], "paths": { "core/*": ["./packages/dev/core/dist/*"], diff --git a/tsconfig.json b/tsconfig.json index aa483c50c7b..991ad06f825 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,9 +2,9 @@ "extends": "./tsconfig.build.json", "compilerOptions": { + "useDefineForClassFields": false, "ignoreDeprecations": "6.0", "baseUrl": "packages", - "experimentalDecorators": true, "noImplicitAny": true, "noImplicitOverride": true, "noImplicitReturns": true, diff --git a/tsconfig.test.json b/tsconfig.test.json index db069fb3249..c566b9d3235 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -15,7 +15,9 @@ "es2017", "es2022.error", "es2022.array", - "es2021.string" + "es2021.string", + "esnext.decorators", + "es2022.object" ] } } From 80ef7f00f54599702c3f973c2277925c18d195c6 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:49:20 +0200 Subject: [PATCH 02/20] TC39 core-materials: accessor keyword on all core decorator sites Add the accessor keyword to every @expandToProperty member across packages/dev/core (materials, PBR, lights, rendering, BakedVertexAnimation, standardMaterial, post-processes, layers, cameras, node blocks). Flip openpbrMaterial addAccessorsForMaterialProperty to the TC39 accessor pattern with explicit private backing fields. Edge cases: wrap self-referencing decorator args in arrow functions for deferred evaluation (LightBlock, ReflectionTextureBaseBlock, PBRMetallicRoughnessBlock); imageProcessing.ts mixin registers serialization metadata directly via GetDirectStoreFromMetadata; restructure @expandToProperty on explicit getters in backgroundMaterial and pbrSubSurfaceConfiguration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../bakedVertexAnimationManager.ts | 4 +- .../core/src/Cameras/arcRotateCamera.pure.ts | 2 +- .../dev/core/src/Cameras/followCamera.pure.ts | 4 +- .../dev/core/src/Layers/glowLayer.pure.ts | 2 +- .../core/src/Layers/highlightLayer.pure.ts | 4 +- .../src/Layers/selectionOutlineLayer.pure.ts | 2 +- packages/dev/core/src/Lights/light.ts | 2 +- .../Background/backgroundMaterial.pure.ts | 37 +- ...nSplattingSolidColorMaterialPlugin.pure.ts | 15 +- .../Node/Blocks/Dual/lightBlock.pure.ts | 2 +- .../Dual/reflectionTextureBaseBlock.pure.ts | 2 +- .../PBR/pbrMetallicRoughnessBlock.pure.ts | 2 +- .../src/Materials/PBR/openpbrMaterial.pure.ts | 354 +++++++++--------- .../PBR/pbrAnisotropicConfiguration.ts | 6 +- .../src/Materials/PBR/pbrBRDFConfiguration.ts | 18 +- .../src/Materials/PBR/pbrBaseMaterial.pure.ts | 2 +- .../Materials/PBR/pbrBaseSimpleMaterial.ts | 26 +- .../PBR/pbrClearCoatConfiguration.ts | 20 +- .../PBR/pbrIridescenceConfiguration.ts | 8 +- .../src/Materials/PBR/pbrMaterial.pure.ts | 132 +++---- .../PBR/pbrMetallicRoughnessMaterial.pure.ts | 10 +- .../Materials/PBR/pbrSheenConfiguration.ts | 14 +- .../PBR/pbrSpecularGlossinessMaterial.pure.ts | 10 +- .../PBR/pbrSubSurfaceConfiguration.ts | 44 +-- .../dev/core/src/Materials/imageProcessing.ts | 16 +- .../material.decalMapConfiguration.pure.ts | 4 +- .../material.detailMapConfiguration.ts | 6 +- .../Materials/meshDebugPluginMaterial.pure.ts | 4 +- .../src/Materials/standardMaterial.pure.ts | 64 ++-- .../blackAndWhitePostProcess.pure.ts | 2 +- .../bloomMergePostProcess.pure.ts | 2 +- .../src/PostProcesses/blurPostProcess.pure.ts | 2 +- .../chromaticAberrationPostProcess.pure.ts | 2 +- .../circleOfConfusionPostProcess.pure.ts | 2 +- .../colorCorrectionPostProcess.pure.ts | 2 +- .../convolutionPostProcess.pure.ts | 2 +- .../extractHighlightsPostProcess.pure.ts | 2 +- .../PostProcesses/filterPostProcess.pure.ts | 2 +- .../src/PostProcesses/fxaaPostProcess.pure.ts | 2 +- .../PostProcesses/grainPostProcess.pure.ts | 2 +- .../imageProcessingPostProcess.ts | 2 +- .../motionBlurPostProcess.pure.ts | 2 +- .../src/PostProcesses/passPostProcess.pure.ts | 2 +- .../screenSpaceCurvaturePostProcess.pure.ts | 2 +- .../PostProcesses/sharpenPostProcess.pure.ts | 2 +- .../PostProcesses/tonemapPostProcess.pure.ts | 2 +- .../GlobalIllumination/giRSMManager.pure.ts | 2 +- .../iblShadowsPluginMaterial.pure.ts | 2 +- .../src/Rendering/reflectiveShadowMap.pure.ts | 2 +- 49 files changed, 436 insertions(+), 420 deletions(-) diff --git a/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts b/packages/dev/core/src/BakedVertexAnimation/bakedVertexAnimationManager.ts index 169cda0720f..1eeeaf16840 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 3cb0256666a..f96d922b79a 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 8092c5c4ffb..14df01aa4c8 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/Layers/glowLayer.pure.ts b/packages/dev/core/src/Layers/glowLayer.pure.ts index 327a275b3ce..6c32575e0aa 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 152094bf766..5415d33be80 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 b170d8199ca..be79677f628 100644 --- a/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts +++ b/packages/dev/core/src/Layers/selectionOutlineLayer.pure.ts @@ -108,7 +108,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 870dcf78fd8..e80e1cda930 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 a2fc9dc3f99..07ab6ee7d3c 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 f7c645c5d20..4b4c3ac7cd5 100644 --- a/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts +++ b/packages/dev/core/src/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.pure.ts @@ -6,7 +6,7 @@ import { type AbstractEngine } from "../../Engines/abstractEngine.pure"; import { type SubMesh } from "../../Meshes/subMesh.pure"; import { type UniformBuffer } from "../uniformBuffer"; import { type MaterialDefines } from "../materialDefines"; -import { serialize, expandToProperty } from "../../Misc/decorators"; +import { serialize } from "../../Misc/decorators"; import { type Color3 } from "../../Maths/math.color.pure"; import { MaterialPluginBase } from "../materialPluginBase.pure"; import { ShaderLanguage } from "../shaderLanguage"; @@ -29,8 +29,17 @@ export class GaussianSplattingSolidColorMaterialPlugin extends MaterialPluginBas * Toggled via a shader uniform so no recompilation is required. */ @serialize() - @expandToProperty("_onIsEnabledChanged") - public isEnabled = true; + public get isEnabled(): boolean { + return this._isEnabled; + } + + public set isEnabled(value: boolean) { + if (this._isEnabled === value) { + return; + } + this._isEnabled = value; + this._onIsEnabledChanged(); + } /** @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 2b8de17f492..de8a8ae89e9 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 5695a384477..18a6e94748d 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 37e089ab26c..45fa1d27a2f 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 e3bcbe55652..ce34fc432fa 100644 --- a/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/openpbrMaterial.pure.ts @@ -517,8 +517,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); @@ -526,8 +526,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"); @@ -535,8 +535,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); @@ -544,8 +544,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"); @@ -553,8 +553,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); @@ -562,8 +562,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"); @@ -571,8 +571,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); @@ -580,8 +580,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"); @@ -589,8 +589,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); @@ -598,8 +598,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"); @@ -607,8 +607,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); @@ -616,8 +616,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"); @@ -625,8 +625,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); @@ -634,8 +634,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"); @@ -643,8 +643,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); @@ -652,8 +652,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"); @@ -661,8 +661,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); @@ -670,8 +670,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); @@ -679,8 +679,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"); @@ -688,8 +688,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); @@ -697,8 +697,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"); @@ -706,8 +706,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); @@ -715,8 +715,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"); @@ -724,8 +724,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); @@ -733,8 +733,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"); @@ -742,8 +742,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); @@ -751,8 +751,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); @@ -760,8 +760,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"); @@ -769,8 +769,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); @@ -778,8 +778,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"); @@ -787,8 +787,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"); @@ -796,8 +796,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"); @@ -805,8 +805,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"); @@ -814,8 +814,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"); @@ -823,8 +823,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"); @@ -832,8 +832,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"); @@ -841,8 +841,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"); @@ -850,8 +850,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); @@ -859,8 +859,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"); @@ -868,8 +868,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); @@ -877,8 +877,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"); @@ -886,8 +886,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); @@ -895,8 +895,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"); @@ -904,8 +904,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); @@ -913,8 +913,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"); @@ -922,8 +922,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); @@ -933,8 +933,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); @@ -944,8 +944,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"); @@ -959,8 +959,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); @@ -968,8 +968,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"); @@ -977,8 +977,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); @@ -986,8 +986,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"); @@ -995,8 +995,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); @@ -1004,8 +1004,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"); @@ -1013,8 +1013,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); @@ -1022,8 +1022,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"); @@ -1031,8 +1031,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); @@ -1052,8 +1052,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"); @@ -1061,8 +1061,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"); @@ -1070,8 +1070,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); @@ -1093,8 +1093,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"); @@ -1102,8 +1102,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); @@ -1111,8 +1111,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"); @@ -1120,8 +1120,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); @@ -1129,8 +1129,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"); @@ -1138,8 +1138,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); @@ -1147,8 +1147,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); @@ -1156,24 +1156,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"); @@ -1182,40 +1182,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"); @@ -1299,7 +1299,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 @@ -1307,42 +1307,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. @@ -1415,70 +1415,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. @@ -1486,7 +1486,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. @@ -1494,7 +1494,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. @@ -1505,14 +1505,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. @@ -1521,7 +1521,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 @@ -1529,7 +1529,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 @@ -1537,21 +1537,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. @@ -1900,7 +1900,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 175ebbce46b..860a14af550 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; diff --git a/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrBRDFConfiguration.ts index 240ebbfdb28..f497672f967 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; diff --git a/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrBaseMaterial.pure.ts index 64b368f7693..b12e933b8dc 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 40219680bb4..594ea1eaf51 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 178f083030c..e620c4f77dc 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; diff --git a/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts b/packages/dev/core/src/Materials/PBR/pbrIridescenceConfiguration.ts index bd4ade397d5..a189d5e3b79 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; diff --git a/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts index 9236f7987c7..2c71274336a 100644 --- a/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrMaterial.pure.ts @@ -53,7 +53,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. @@ -61,7 +61,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 @@ -69,7 +69,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 @@ -77,49 +77,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...). @@ -128,42 +128,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. @@ -171,7 +171,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. @@ -179,7 +179,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. @@ -192,7 +192,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallicF0Factor = 1; + public accessor metallicF0Factor = 1; /** * In metallic workflow, specifies an F0 color. @@ -205,7 +205,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. @@ -213,7 +213,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 @@ -222,7 +222,7 @@ export class PBRMaterial extends PBRBaseMaterial { */ @serializeAsTexture() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallicReflectanceTexture: Nullable; + public accessor metallicReflectanceTexture: Nullable; /** * Defines to store reflectanceColor in RGB @@ -232,7 +232,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. @@ -240,21 +240,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. @@ -276,56 +276,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. @@ -371,28 +371,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). @@ -400,21 +400,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. @@ -422,28 +422,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, @@ -451,7 +451,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. @@ -513,77 +513,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. @@ -591,7 +591,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. @@ -599,7 +599,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. @@ -610,14 +610,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. @@ -626,7 +626,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 @@ -634,7 +634,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 @@ -642,21 +642,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 2c764686693..2166b4a24af 100644 --- a/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrMetallicRoughnessMaterial.pure.ts @@ -25,7 +25,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 @@ -33,7 +33,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. @@ -41,7 +41,7 @@ export class PBRMetallicRoughnessMaterial extends PBRBaseSimpleMaterial { */ @serialize() @expandToProperty("_markAllSubMeshesAsTexturesDirty") - public metallic: number; + public accessor metallic: number; /** * Specifies the roughness scalar value of the material. @@ -49,7 +49,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 @@ -57,7 +57,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 c6483710f49..6d9d38a425c 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; diff --git a/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts b/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts index 9ef0f2b7b29..5c8c6a22d31 100644 --- a/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts +++ b/packages/dev/core/src/Materials/PBR/pbrSpecularGlossinessMaterial.pure.ts @@ -22,7 +22,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 @@ -30,28 +30,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 ebaebcef839..1c27fc23653 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. diff --git a/packages/dev/core/src/Materials/imageProcessing.ts b/packages/dev/core/src/Materials/imageProcessing.ts index 1842a077106..15c3b7af61b 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 2bdb277961f..37169b39e9d 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; diff --git a/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts b/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts index 053b6571344..9e5af8162c7 100644 --- a/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts +++ b/packages/dev/core/src/Materials/meshDebugPluginMaterial.pure.ts @@ -466,7 +466,7 @@ export class MeshDebugPluginMaterial extends MaterialPluginBase { */ @serialize() @expandToProperty("_markAllDefinesAsDirty") - public mode: MeshDebugMode; + public accessor mode: MeshDebugMode; private _multiply: boolean; /** @@ -475,7 +475,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 a6e2b9dc88b..ff7e52c05e2 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/PostProcesses/blackAndWhitePostProcess.pure.ts b/packages/dev/core/src/PostProcesses/blackAndWhitePostProcess.pure.ts index dcc4ef609a3..17acb588edb 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 df53964509d..c73394071ab 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 63f8666f1fd..96bd6e18c1c 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 5003bdc4540..25c4e9ad3e7 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 6edd24e7553..068be2889da 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 49dee0cf142..e8a08ba64e2 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 b02f5ec7483..dd56e2b8a62 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 043efaedca7..28a8d56ec3a 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 83ee3626199..44e6d594e9f 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 9341fa43de7..8aa253568db 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 65e872dfe4c..b2f7c95ab98 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 a3df8eb6fdc..c6d72811f4a 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 54170d7ef9c..80f4f46bd33 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 8bafd5ed31c..88bc41c4c72 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 4098dcf85f9..0ac35cf5dc0 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 a0dfd543b94..8141ea4ce09 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 21d64d436e2..fd780ea0063 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 0b59a7c0720..7d25dfc6eec 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 5d0d7d8f475..5867f575566 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 62aaf7e746b..3a7cf98b567 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); From 35c1d7c0f70c3530ab32e791526ee05d3ffc6a94 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:50:02 +0200 Subject: [PATCH 03/20] TC39 materials-lib: accessor keyword on materials library decorator sites Add the accessor keyword to every @expandToProperty member across the standalone material packages (cell, fire, fur, gradient, grid, lava, mix, normal, simple, terrain, triPlanar, water). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../dev/materials/src/cell/cellMaterial.ts | 8 +++---- .../dev/materials/src/fire/fireMaterial.ts | 6 ++--- packages/dev/materials/src/fur/furMaterial.ts | 8 +++---- .../src/gradient/gradientMaterial.ts | 4 ++-- .../dev/materials/src/grid/gridMaterial.ts | 2 +- .../dev/materials/src/lava/lavaMaterial.ts | 8 +++---- packages/dev/materials/src/mix/mixMaterial.ts | 24 +++++++++---------- .../materials/src/normal/normalMaterial.ts | 6 ++--- .../materials/src/simple/simpleMaterial.ts | 6 ++--- .../materials/src/terrain/terrainMaterial.ts | 18 +++++++------- .../src/triPlanar/triPlanarMaterial.ts | 16 ++++++------- .../dev/materials/src/water/waterMaterial.ts | 14 +++++------ 12 files changed, 60 insertions(+), 60 deletions(-) diff --git a/packages/dev/materials/src/cell/cellMaterial.ts b/packages/dev/materials/src/cell/cellMaterial.ts index 5f09c26ed22..b79defef4d9 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 f1fc2c8640e..0f99b9f0105 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 00388dfddd3..379cf0e4c62 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 5b945832f7b..d1d0a0b487d 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 49cd9b0682f..209b5b346cb 100644 --- a/packages/dev/materials/src/grid/gridMaterial.ts +++ b/packages/dev/materials/src/grid/gridMaterial.ts @@ -201,7 +201,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); private _viewportSize: Vector2 = new Vector2(); diff --git a/packages/dev/materials/src/lava/lavaMaterial.ts b/packages/dev/materials/src/lava/lavaMaterial.ts index 1674fb686cf..8be68b4f0b7 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 61938fa7d36..ca325bcaea6 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 adc20fa672f..85e92aee403 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 c20434acedf..52a6615821b 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 f802bb39513..e119c6d45f3 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 a779e46c570..42b92fc6f14 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 0187e432c5b..e70c57e5a3b 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); From 2f29f1f27648947594f717cac82f6bf1a8d7f554 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:50:27 +0200 Subject: [PATCH 04/20] TC39 gui: accessor keyword on fluentMaterial decorator sites Add the accessor keyword to the @expandToProperty members in fluentMaterial.pure.ts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../gui/src/3D/materials/fluent/fluentMaterial.pure.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.pure.ts b/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.pure.ts index 57b2ed199f2..9c95129fe9c 100644 --- a/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.pure.ts +++ b/packages/dev/gui/src/3D/materials/fluent/fluentMaterial.pure.ts @@ -42,7 +42,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) @@ -61,7 +61,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) @@ -86,7 +86,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) @@ -111,7 +111,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 From 02ed4a48bcb543138fc4c123fb0ee43cf71ed2f7 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:52:14 +0200 Subject: [PATCH 05/20] TC39 serializers-3mf: convert 3MF XML decorators to TC39 metadata Rewrite XmlName/XmlAttr/XmlElem/XmlIgnore to TC39 decorator signatures that store field metadata via context.metadata, and rewrite AddXmlMeta/GetXmlFieldMeta to read from Symbol.metadata (walking the metadata prototype chain). Add a Symbol.metadata polyfill side-effect import so the decorated 3MF classes work under tree-shaken core imports. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../src/3MF/core/xml/xml.interfaces.ts | 79 +++++++++++++++---- 1 file changed, 64 insertions(+), 15 deletions(-) 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 333ded04d67..91052a02799 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; } /** From 3ca425d298c7f20b0814c07d3738600df1f36a86 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:57:07 +0200 Subject: [PATCH 06/20] TC39 test-infra: vitest esbuild class-field semantics + Symbol.metadata polyfill Configure vitest's esbuild transform with target es2021 and useDefineForClassFields:false so TC39 accessor decorators and class field assignment semantics match the tsc build. Polyfill Symbol.metadata in vitest.setup.ts because Node does not expose it natively yet. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- vitest.config.mts | 14 ++++++++++++++ vitest.setup.ts | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/vitest.config.mts b/vitest.config.mts index b3ace7719fb..9d96e39b186 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -56,7 +56,20 @@ const createProjectConfig = (type: string) => { }; }; +// 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, + }, + }, +}; + 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 f3caec82e38..b1a7b63e2bc 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(), From f3cce2f183fa8e47f987ac747d6ec0a53701bd98 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:57:21 +0200 Subject: [PATCH 07/20] TC39 node-editor-tooling: Symbol.metadata property store for editable props Rewrite nodeDecorator.editableInPropertyPage and the smart filters EditableInPropertyPage decorator to store editable-property descriptors on context.metadata, and add GetEditableProperties / GetSmartFilterEditableProperties helpers that walk the metadata prototype chain. Update the node/geometry/render-graph/particle/smart-filters editor property components, graphNode.ts, and inputNodePropertyComponent to read via the helpers instead of _propStore. customShaderBlock applies the decorator manually against Symbol.metadata. Fix flowGraphEditor RenderGenericPropStoreSections drift and the GUI editor String.at usage (bracket index). Add defensive Symbol.metadata polyfill imports for tree-shaken smart filter consumers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../dev/core/src/Decorators/nodeDecorator.ts | 44 +++++++++++++++--- .../src/nodeGraphSystem/graphNode.ts | 24 +++++----- .../src/blockFoundation/customShaderBlock.ts | 3 +- .../src/editorUtils/editableInPropertyPage.ts | 46 ++++++++++++++++--- .../test/unit/customShaderBlock.test.ts | 8 ++-- .../genericNodePropertyComponent.tsx | 35 +++----------- .../gui/gridPropertyGridComponent.tsx | 3 +- .../genericNodePropertyComponent.tsx | 20 ++------ .../genericNodePropertyComponent.tsx | 20 ++------ .../genericNodePropertyComponent.tsx | 20 ++------ .../genericNodePropertyComponent.tsx | 20 ++------ .../genericNodePropertyComponent.tsx | 23 +++------- .../properties/inputNodePropertyComponent.tsx | 6 +-- 13 files changed, 128 insertions(+), 144 deletions(-) diff --git a/packages/dev/core/src/Decorators/nodeDecorator.ts b/packages/dev/core/src/Decorators/nodeDecorator.ts index 988d010ad5c..d306c90547d 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/sharedUiComponents/src/nodeGraphSystem/graphNode.ts b/packages/dev/sharedUiComponents/src/nodeGraphSystem/graphNode.ts index 3111fbb33e6..42b1e0964b3 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 f3fcd9edcb2..95e7ccf0aa5 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 d2edf735120..0942c1b2419 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/test/unit/customShaderBlock.test.ts b/packages/dev/smartFilters/test/unit/customShaderBlock.test.ts index 07902fabc81..1be7f6998f9 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/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx b/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx index 5b4e5257481..eef632a4a81 100644 --- a/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx +++ b/packages/tools/flowGraphEditor/src/graphSystem/properties/genericNodePropertyComponent.tsx @@ -19,7 +19,7 @@ import { type IPropertyComponentProps } from "shared-ui-components/nodeGraphSyst 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"; @@ -186,24 +186,13 @@ export function RenderDataConnectionsSection(props: IPropertyComponentProps): JS */ export function RenderGenericPropStoreSections(props: IPropertyComponentProps): JSX.Element[] { const block = props.nodeData.data as FlowGraphBlock; - const propStore = (block as any)._propStore as IPropertyDescriptionForEdition[] | undefined; - if (!propStore) { + const propStore = GetEditableProperties(block); + if (!propStore.length) { return []; } - // Match the class-walk filter inside GenericPropertyTabComponent so we only - // collect groups that will actually render at least one entry. - const classes: string[] = []; - let proto = Object.getPrototypeOf(block); - while (proto && proto.getClassName) { - classes.push(proto.getClassName()); - proto = Object.getPrototypeOf(proto); - } const groupOrder: string[] = []; const seen = new Set(); for (const entry of propStore) { - if (classes.indexOf(entry.className) === -1) { - continue; - } if (!seen.has(entry.groupName)) { seen.add(entry.groupName); groupOrder.push(entry.groupName); @@ -558,30 +547,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 2c36ca8220e..4d54a7fd11b 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 48ca9067276..92741c29dae 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 0f6c7e8affe..c418a9d4a47 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/smartFiltersEditorControl/src/graphSystem/properties/genericNodePropertyComponent.tsx b/packages/tools/smartFiltersEditorControl/src/graphSystem/properties/genericNodePropertyComponent.tsx index b451520aaa2..04df868a5aa 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; } From 15837ed0f1ee823ab7c54ae30e8716e80527c589 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 22:58:59 +0200 Subject: [PATCH 08/20] TC39 lit-viewer: accessor keyword on viewer Lit element decorators Add the accessor keyword to all @property/@state/@query fields in the viewer Lit elements, type @query fields as | null, and move the @property decorator on the environment property from the getter to the setter (accessor decorators cannot target a getter/setter pair). Add a Symbol.metadata polyfill import to the viewer package index because the viewer deep-imports core modules and bypasses core/index's polyfill. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/tools/viewer/src/index.ts | 8 ++ .../viewer/src/viewerAnnotationElement.ts | 2 +- packages/tools/viewer/src/viewerElement.ts | 4 +- .../tools/viewer/src/viewerElementBase.ts | 77 ++++++++++--------- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/packages/tools/viewer/src/index.ts b/packages/tools/viewer/src/index.ts index 9c1cff94c94..16b3ac00542 100644 --- a/packages/tools/viewer/src/index.ts +++ b/packages/tools/viewer/src/index.ts @@ -1,3 +1,11 @@ +// Ensure Symbol.metadata exists before any decorated core class in this bundle is evaluated. +// The viewer deep-imports core modules (e.g. "core/Materials/Textures/...") rather than the core +// package index, so it bypasses the polyfill that index applies. Without this, TC39 decorator +// metadata inheritance breaks and inherited @serialize properties (such as a texture's gammaSpace) +// are lost during serialization/clone. This must be the first statement so it runs before the +// re-exported viewer modules pull in any decorated core class. +import "core/Misc/symbolMetadataPolyfill"; + export type { CameraAutoOrbit, EnvironmentOptions, HotSpot, PostProcessing, ShadowQuality, ToneMapping, ViewerHotSpotQuery } from "./viewerBase"; export type { LoadModelOptions, Model, ViewerDetails, ViewerOptions } from "./viewer"; export type { CanvasViewerOptions } from "./viewerFactory"; diff --git a/packages/tools/viewer/src/viewerAnnotationElement.ts b/packages/tools/viewer/src/viewerAnnotationElement.ts index 6dfdd3fba06..0549e63bdf4 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 47c6ac02110..6abbc29b3a2 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 9c383e5453d..f5ef5812953 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 Date: Wed, 1 Jul 2026 22:59:31 +0200 Subject: [PATCH 09/20] TC39 playground-tooling: drop experimentalDecorators from Monaco/snippet transpilers Remove experimentalDecorators/emitDecoratorMetadata from the Monaco tsPipeline and snippetLoader compiler options so playground and snippet transpilation use TC39 Stage 3 decorator semantics like the rest of the repo. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts | 2 -- packages/tools/snippetLoader/src/snippetLoader.ts | 4 ---- 2 files changed, 6 deletions(-) diff --git a/packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts b/packages/tools/playground/src/tools/monaco/ts/tsPipeline.ts index f70bbe81d69..9af3e38aac9 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/snippetLoader/src/snippetLoader.ts b/packages/tools/snippetLoader/src/snippetLoader.ts index 64b5bf63052..08cd42f7930 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 Date: Wed, 1 Jul 2026 23:01:20 +0200 Subject: [PATCH 10/20] TC39 build-tools: use installed tslib for UMD helpers + Dirent fix storeTsLib copies tslib.es6.mjs from the installed tslib package instead of embedding a hardcoded tslib 2.4.0 copy. The hardcoded copy predates the TC39 decorator runtime helpers (__esDecorate, __runInitializers, __setFunctionName) that the es2015 UMD emit references, so the UMD bundles would break without the up-to-date helpers. Also replace the fs.Dirent cast in the smart filters convertShaders tool with a plain { name, dir } shape to avoid Dirent.parentPath typing issues. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/dev/buildTools/src/pathTransform.ts | 255 +----------------- .../src/utils/buildTools/convertShaders.ts | 20 +- 2 files changed, 10 insertions(+), 265 deletions(-) diff --git a/packages/dev/buildTools/src/pathTransform.ts b/packages/dev/buildTools/src/pathTransform.ts index 32dd867369e..348f166b7c5 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/smartFilters/src/utils/buildTools/convertShaders.ts b/packages/dev/smartFilters/src/utils/buildTools/convertShaders.ts index cbfd80b5026..3e7d39bdd20 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); } } From 67febed735e090aa9fb4f53f86dfda67256c3ebe Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 23:09:13 +0200 Subject: [PATCH 11/20] TC39 node-editor-tooling: defer WebCamInputBlock self-reference in decorator Wrap the WebCamInputBlock._WebCamSourceManager options in a getter so the class self-reference inside the @editableInPropertyPage arguments is evaluated lazily, avoiding TS2449 (class used before its declaration) under TC39 decorator evaluation order. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../editorBlocks/webCamInputBlock/webCamInputBlock.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/tools/smartFiltersEditorControl/src/configuration/editorBlocks/webCamInputBlock/webCamInputBlock.ts b/packages/tools/smartFiltersEditorControl/src/configuration/editorBlocks/webCamInputBlock/webCamInputBlock.ts index 63d9b6cbee5..24ebd31b5ee 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) { From 2e7536f3c21cb2d603e11d8ec9e006d56d4efe90 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Wed, 1 Jul 2026 23:28:27 +0200 Subject: [PATCH 12/20] TC39 tests: port decorator + accessor behavior coverage Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../unit/Decorators/decorators.inline-test.ts | 69 ++++++++++ .../test/unit/Decorators/decorators.test.ts | 124 ++++++++++++++++++ .../babylon.selectionOutlineLayer.test.ts | 7 + .../unit/Materials/babylon.material.test.ts | 28 ++++ .../Meshes/babylon.dictionaryMode.test.ts | 2 +- 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 packages/dev/core/test/unit/Decorators/decorators.inline-test.ts create mode 100644 packages/dev/core/test/unit/Decorators/decorators.test.ts 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 00000000000..deb4f53e84b --- /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 00000000000..33a5cc846e2 --- /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 d96af045304..40c5bd0f40f 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, vi } 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 { type SubMesh } from "core/Meshes/subMesh"; @@ -114,6 +115,12 @@ describe("SelectionOutlineLayer", () => { 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); + }); + it("should bind a depth renderer for compose by default", () => { const layer = new SelectionOutlineLayer("outline", scene); const sphere = MeshBuilder.CreateSphere("sphere", { diameter: 1 }, scene); 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 3e83d365c41..76d827194e0 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 2ea09defb4c..184474258f4 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); }); }); }); From d8d307f5fac66382eb015e0190ffde7ac8bdf159 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Thu, 2 Jul 2026 10:33:05 +0200 Subject: [PATCH 13/20] TC39 decorators: run Symbol.metadata polyfill before decorated classes in all entry styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The es6 `pure` entry (and any deep import of a decorated class) crashed at class-definition time with "Cannot convert undefined or null to object" because `context.metadata` was `void 0`: TypeScript's TC39 emit computes `_metadata = Symbol.metadata ? ... : void 0` at the top of the class `static {}` block, so the metadata bag only exists if `Symbol.metadata` was installed BEFORE the class module evaluated. The polyfill was only imported by `index.ts` (the barrel), so the `pure` barrel — which eagerly evaluates every decorated FrameGraph / node block without importing the polyfill — always threw. Fix: anchor the polyfill in the decorator infrastructure that every decorated class already imports. `decorators.functions.ts` now resolves `Symbol.metadata` into an exported module-load `const MetadataSymbol` (the idempotent `GetMetadataSymbol()` already performed the polyfill); ES module evaluation order guarantees this runs before any importing class body. It is a `const` referenced by the retained decorator helpers so bundlers treating the module as side-effect-free cannot drop it, and the tree-shaking side-effect detector skips `const X = ...` initializers so the module stays pure and remains importable from `.pure` modules — no tooling policy or `sideEffects` allowlist change required. `nodeDecorator.ts` and the smart filters `editableInPropertyPage` import that symbol, route their metadata reads through it, and throw an actionable error instead of a cryptic TypeError if the polyfill somehow did not run. Fixes the ES6 visualization "pure" scenes and the resulting Playground snapshot cascade. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../dev/core/src/Decorators/nodeDecorator.ts | 14 ++++++-- .../dev/core/src/Misc/decorators.functions.ts | 35 ++++++++++++++++--- .../src/editorUtils/editableInPropertyPage.ts | 14 ++++++-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/packages/dev/core/src/Decorators/nodeDecorator.ts b/packages/dev/core/src/Decorators/nodeDecorator.ts index d306c90547d..712f5ff08d5 100644 --- a/packages/dev/core/src/Decorators/nodeDecorator.ts +++ b/packages/dev/core/src/Decorators/nodeDecorator.ts @@ -1,5 +1,6 @@ import { type Nullable } from "../types"; import { type Scene } from "../scene"; +import { MetadataSymbol } from "../Misc/decorators.functions"; /** * Enum defining the type of properties that can be edited in the property pages in the node editor @@ -108,7 +109,16 @@ export function editableInPropertyPage( options?: IEditablePropertyOption ) { return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => { - const meta = context.metadata; + const meta = context.metadata as DecoratorMetadataObject | undefined; + if (!meta) { + // `context.metadata` is `void 0` when `Symbol.metadata` was not installed before this class + // was evaluated. Importing `MetadataSymbol` from decorators.functions runs the polyfill at + // module load (before this class body), so this should never happen; referencing it here also + // keeps that module-load polyfill anchored against bundler tree-shaking. + throw new Error( + `editableInPropertyPage: decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated.` + ); + } let propStore: IPropertyDescriptionForEdition[]; if (Object.prototype.hasOwnProperty.call(meta, __bjsPropStoreKey)) { propStore = meta[__bjsPropStoreKey] as IPropertyDescriptionForEdition[]; @@ -139,7 +149,7 @@ export const __bjsPropStoreKey = "__bjs_prop_store__"; */ export function GetEditableProperties(target: any): IPropertyDescriptionForEdition[] { const ctor = typeof target === "function" ? target : target?.constructor; - const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + const metadata: DecoratorMetadataObject | undefined = ctor?.[MetadataSymbol]; if (!metadata) { return []; } diff --git a/packages/dev/core/src/Misc/decorators.functions.ts b/packages/dev/core/src/Misc/decorators.functions.ts index 0364fa7e419..d93441853bf 100644 --- a/packages/dev/core/src/Misc/decorators.functions.ts +++ b/packages/dev/core/src/Misc/decorators.functions.ts @@ -35,6 +35,24 @@ function GetMetadataSymbol(): symbol { return metadataSymbol; } +/** + * The well-known `Symbol.metadata` symbol, resolved once at module-evaluation time. + * + * Reading (and thereby resolving) this symbol at module load guarantees that `Symbol.metadata` + * exists BEFORE any decorated class which imports the decorator infrastructure evaluates its class + * body. TypeScript's TC39 decorator emit captures `context.metadata` from `Symbol.metadata` at the + * top of the class `static {}` block (before the decorator factory runs), so if the symbol is not + * yet installed the metadata object is `void 0` and every metadata-based decorator throws. + * + * It is intentionally an exported `const` initialized from a function call: bundlers that treat this + * module as side-effect-free may drop bare top-level calls, but they cannot drop a `const` whose + * value is referenced by the retained decorator helpers below. The tree-shaking side-effect detector + * likewise skips `const X = ...` initializers, so this module stays classified as pure and remains + * importable from `.pure` modules. + * @internal + */ +export const MetadataSymbol: symbol = GetMetadataSymbol(); + // Returns the constructor for the provided decorator/serialization target. // Experimental decorators pass a prototype; serialization passes an instance or a constructor. function GetConstructor(target: any): any { @@ -47,17 +65,17 @@ function GetOwnMetadata(ctor: any): any { if (!ctor) { return undefined; } - if (!HasOwn(ctor, GetMetadataSymbol())) { + if (!HasOwn(ctor, MetadataSymbol)) { const parent = Object.getPrototypeOf(ctor); - const parentMetadata = parent ? parent[GetMetadataSymbol()] : null; - Object.defineProperty(ctor, GetMetadataSymbol(), { + const parentMetadata = parent ? parent[MetadataSymbol] : null; + Object.defineProperty(ctor, MetadataSymbol, { value: Object.create(parentMetadata ?? null), configurable: true, writable: true, enumerable: false, }); } - return ctor[GetMetadataSymbol()]; + return ctor[MetadataSymbol]; } /** @@ -66,6 +84,13 @@ function GetOwnMetadata(ctor: any): any { * @internal */ export function GetDirectStoreFromMetadata(metadata: DecoratorMetadataObject): Record { + if (!metadata) { + // `metadata` is `context.metadata`, which is `void 0` when `Symbol.metadata` was not installed + // before the class was evaluated. Referencing `MetadataSymbol` here (a) produces an actionable + // error instead of a cryptic "Cannot convert undefined to object" and (b) keeps the module-load + // polyfill anchored so bundlers cannot tree-shake it away on the decorate-time serialize path. + throw new Error(`Decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated.`); + } if (!HasOwn(metadata, __bjsSerializableKey)) { (metadata as any)[__bjsSerializableKey] = {}; } @@ -90,7 +115,7 @@ export function GetDirectStore(target: any): any { */ export function GetMergedStore(target: any): any { const ctor = GetConstructor(target); - const metadata = ctor ? ctor[GetMetadataSymbol()] : undefined; + const metadata = ctor ? ctor[MetadataSymbol] : undefined; if (!metadata) { return {}; } diff --git a/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts b/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts index 0942c1b2419..be3be45d7fd 100644 --- a/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts +++ b/packages/dev/smartFilters/src/editorUtils/editableInPropertyPage.ts @@ -1,4 +1,5 @@ import { type Observable } from "core/Misc/observable.js"; +import { MetadataSymbol } from "core/Misc/decorators.functions.js"; /** * Enum defining the type of properties that can be edited in the property pages in the node editor @@ -97,7 +98,16 @@ export function EditableInPropertyPage( options?: IEditablePropertyOption ) { return (_value: unknown, context: { name: string | symbol; metadata: DecoratorMetadataObject }) => { - const meta = context.metadata; + const meta = context.metadata as DecoratorMetadataObject | undefined; + if (!meta) { + // `context.metadata` is `void 0` when `Symbol.metadata` was not installed before this class + // was evaluated. Importing `MetadataSymbol` from core runs the polyfill at module load (before + // this class body), so this should never happen; referencing it here also keeps that + // module-load polyfill anchored against bundler tree-shaking. + throw new Error( + `EditableInPropertyPage: decorator metadata is unavailable; the Symbol.metadata (${String(MetadataSymbol)}) polyfill must run before decorated classes are evaluated.` + ); + } let propStore: IPropertyDescriptionForEdition[]; if (Object.prototype.hasOwnProperty.call(meta, __bjsSmartFilterPropStoreKey)) { propStore = meta[__bjsSmartFilterPropStoreKey] as IPropertyDescriptionForEdition[]; @@ -136,7 +146,7 @@ export function EditableInPropertyPage( */ export function GetSmartFilterEditableProperties(target: any): IPropertyDescriptionForEdition[] { const ctor = typeof target === "function" ? target : target?.constructor; - const metadata: DecoratorMetadataObject | undefined = ctor?.[Symbol.metadata]; + const metadata: DecoratorMetadataObject | undefined = ctor?.[MetadataSymbol]; if (!metadata) { return []; } From 1b73d6c3431c9656844da4bfda220d702bdd60da Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Thu, 2 Jul 2026 12:07:57 +0200 Subject: [PATCH 14/20] TC39 class-fields: declare (not override) the two fields clobbered by base-constructor init Flipping to TC39 decorators forces useDefineForClassFields:true. Under define semantics, an uninitialized narrowing `override` field emits a class-field definition that runs after super() and resets the value the base constructor assigned. Only FreeCamera.movement and FlyCamera.movement are actually created by the base TargetCamera constructor and were being clobbered, so only those two are converted to type-only `declare` narrowings. A blanket override->declare conversion was considered and rejected to keep the diff reviewable; the type checker and unit suite guard against future regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/dev/core/src/Cameras/flyCamera.pure.ts | 5 ++++- packages/dev/core/src/Cameras/freeCamera.pure.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/dev/core/src/Cameras/flyCamera.pure.ts b/packages/dev/core/src/Cameras/flyCamera.pure.ts index e811b70ad66..dc7b99924c7 100644 --- a/packages/dev/core/src/Cameras/flyCamera.pure.ts +++ b/packages/dev/core/src/Cameras/flyCamera.pure.ts @@ -98,7 +98,10 @@ export class FlyCamera extends TargetCamera { * inherited {@link TargetCamera.movement} to {@link TargetCameraMovement}; the instance is * created by the {@link TargetCamera} constructor. */ - public override movement: TargetCameraMovement; + // `declare`, not `override`: the value is created by the base TargetCamera constructor. Under TC39 + // decorators a plain field redeclaration is materialized as a constructor field-init that runs after + // super() and would clobber that value back to undefined; `declare` keeps this a type-only narrowing. + declare public movement: TargetCameraMovement; /** * Gets the input sensibility for mouse input. diff --git a/packages/dev/core/src/Cameras/freeCamera.pure.ts b/packages/dev/core/src/Cameras/freeCamera.pure.ts index 94cdaef096d..811d2f4b8bc 100644 --- a/packages/dev/core/src/Cameras/freeCamera.pure.ts +++ b/packages/dev/core/src/Cameras/freeCamera.pure.ts @@ -61,7 +61,10 @@ export class FreeCamera extends TargetCamera { * the inherited {@link TargetCamera.movement} to {@link TargetCameraMovement}; the instance is * created by the {@link TargetCamera} constructor. */ - public override movement: TargetCameraMovement; + // `declare`, not `override`: the value is created by the base TargetCamera constructor. Under TC39 + // decorators a plain field redeclaration is materialized as a constructor field-init that runs after + // super() and would clobber that value back to undefined; `declare` keeps this a type-only narrowing. + declare public movement: TargetCameraMovement; /** * Gets the input sensibility for a mouse input. (default is 2000.0) From 1637c9dc222ea3d5a6647ee7b7f7bc74140c7d80 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Thu, 2 Jul 2026 13:47:34 +0200 Subject: [PATCH 15/20] TC39 Native: emit UMD at es2015 and downlevel to ES5 via tsc (not Babel) The Chakra-based Babylon Native unit tests hard-crash (exit 3, uncatchable, no JS stack) at babylon.max.js load time under the prior pipeline. Root cause: the UMD was built at es2015 and then downleveled to ES5 with @babel/preset-env, which emits _wrapNativeSuper + Reflect.construct + _isNativeReflectConstruct for classes extending native built-ins (Error, Array). Those helpers run at class-definition (load) time and abort this archived ChakraCore build. V8/node tolerate them, so the crash is invisible locally and es-check (parse-only) passes. Fix: keep the 8 UMD tsconfig targets at es2015 (accessor requires es2015+; TS18045 forbids ES5 for accessor source, and building the whole library through a suppressed hard type error is unacceptable), and replace the Babel downlevel in scripts/downlevelNativeScripts.mjs with ts.transpileModule targeting ES5. tsc lowers classes with __extends and never emits Reflect.construct/_wrapNativeSuper, matching the emit shape master has shipped to Chakra for years. Verified: on the built UMD the output passes es-check es5, loads in node, and contains zero Reflect.construct/_wrapNativeSuper occurrences. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../umd/babylonjs-addons/tsconfig.build.json | 3 +- .../umd/babylonjs-gui/tsconfig.build.json | 3 +- .../umd/babylonjs-loaders/tsconfig.build.json | 3 +- .../babylonjs-materials/tsconfig.build.json | 3 +- .../tsconfig.build.json | 3 +- .../tsconfig.build.json | 3 +- .../babylonjs-serializers/tsconfig.build.json | 3 +- .../public/umd/babylonjs/tsconfig.build.json | 3 +- scripts/downlevelNativeScripts.mjs | 84 ++++++++++--------- 9 files changed, 52 insertions(+), 56 deletions(-) diff --git a/packages/public/umd/babylonjs-addons/tsconfig.build.json b/packages/public/umd/babylonjs-addons/tsconfig.build.json index cb3b01f2d70..f452bcac2c3 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 5b5682d2840..56dde1bd0ca 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 c6966c2dd0d..94a841ba983 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 a534d1238b9..e4cdb74b9e2 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 b2e29e4642a..93c9cc1b2bd 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 e48d00ee4b5..a0fb1881638 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 b3ef218824e..6aedbcb1016 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 271cbc291d7..6b7527078c5 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/scripts/downlevelNativeScripts.mjs b/scripts/downlevelNativeScripts.mjs index 936ad869842..9af48d4986f 100644 --- a/scripts/downlevelNativeScripts.mjs +++ b/scripts/downlevelNativeScripts.mjs @@ -1,8 +1,8 @@ #!/usr/bin/env node -import { transformAsync } from "@babel/core"; import { readdir, readFile, stat, writeFile } from "fs/promises"; import { basename, join, resolve } from "path"; +import ts from "typescript"; const targets = process.argv.slice(2); @@ -11,41 +11,31 @@ if (targets.length === 0) { process.exit(1); } -const babelOptions = { - babelrc: false, - configFile: false, - sourceMaps: false, - compact: true, - comments: false, - sourceType: "script", - assumptions: { - constantSuper: true, - noClassCalls: true, - setClassMethods: true, - setPublicClassFields: true, - superIsCallableConstructor: true, - }, - // The TC39 decorator migration forces the Native UMD bundle to be emitted at an ES2015 target - // (the `accessor` keyword requires ES2015+). Babylon Native's Chakra engine consumes ES5-level - // script, so transforming classes alone is not enough: arrow functions, let/const, template - // literals, for-of, destructuring, default/rest params and async/generators all remain and abort - // the engine. Run the full preset-env transform down to ES5. `forceAllTransforms` ignores any - // browserslist target and lowers every ES2015+ construct, and Babel inlines a self-contained - // regenerator runtime for async/generators (no external `regeneratorRuntime` global required). - // `useBuiltIns: false` keeps library behavior untouched (Chakra already provides the ES2015 - // built-ins the previous ES5 TypeScript output relied on). - presets: [ - [ - "@babel/preset-env", - { - bugfixes: true, - modules: false, - useBuiltIns: false, - forceAllTransforms: true, - ignoreBrowserslistConfig: true, - }, - ], - ], +// The TC39 decorator migration forces the Native UMD bundle to be emitted at an ES2015 target (the +// `accessor` keyword requires ES2015+, and esbuild cannot emit ES5 classes). Babylon Native's Chakra +// engine consumes ES5-level script, so the bundle must be down-leveled before it runs. +// +// We use the TypeScript transpiler (not Babel) for this. Babel's ES5 class transform emits +// `Reflect.construct`/`_wrapNativeSuper` machinery for classes that extend native built-ins (e.g. +// `Error`, `Array`); that machinery executes at class-definition time and hard-crashes Chakra when +// the bundle loads. TypeScript instead lowers classes with its `__extends` helper (plain prototype +// assignment, no `Reflect.construct`) - the exact emit Babylon Native ran successfully for years when +// the UMD bundles were built directly at an ES5 target. `ts.transpileModule` performs a purely +// syntactic, single-file transform (no type checking), so it does not choke on the multi-megabyte +// bundle, and it inlines self-contained helpers (no external `tslib`/`regeneratorRuntime` required). +const compilerOptions = { + target: ts.ScriptTarget.ES5, + // The bundles are UMD/IIFE scripts with no top-level module syntax; leave module output untouched. + module: ts.ModuleKind.None, + // Lower `for..of`, spread and other iterator protocols correctly for ES5. + downlevelIteration: true, + // Inline the emit helpers into each file so the bundle stays self-contained on Chakra. + importHelpers: false, + newLine: ts.NewLineKind.LineFeed, + sourceMap: false, + // The ES5/`module: none`/`downlevelIteration` combination emits TS 7.0 deprecation notices; they + // are informational and do not affect the emitted output. + ignoreDeprecations: "6.0", }; function isNativeScriptFile(filePath) { @@ -88,12 +78,26 @@ if (files.length === 0) { for (const file of files) { const code = await readFile(file, "utf8"); - const result = await transformAsync(code, { ...babelOptions, filename: file }); - if (!result?.code) { - throw new Error(`Babel did not produce output for ${file}`); + const result = ts.transpileModule(code, { compilerOptions, fileName: file, reportDiagnostics: true }); + + // `transpileModule` only surfaces syntactic and command-line/config diagnostics (it has no type + // information). Command-line/config diagnostics (code >= 5000) are informational for our + // transpile-only use; a real problem shows up as a syntactic error (code < 5000). + const fatalDiagnostics = (result.diagnostics || []).filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error && diagnostic.code < 5000); + if (fatalDiagnostics.length > 0) { + const formatted = ts.formatDiagnostics(fatalDiagnostics, { + getCanonicalFileName: (fileName) => fileName, + getCurrentDirectory: () => process.cwd(), + getNewLine: () => "\n", + }); + throw new Error(`TypeScript reported errors while down-leveling ${file}:\n${formatted}`); } - await writeFile(file, result.code, "utf8"); + if (!result.outputText) { + throw new Error(`TypeScript did not produce output for ${file}`); + } + + await writeFile(file, result.outputText, "utf8"); process.stdout.write(`Downleveled ${file}\n`); } From 37e114917bd291c85b7d5afc97394c5d864b99d3 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Thu, 2 Jul 2026 19:48:02 +0200 Subject: [PATCH 16/20] TC39 review: drop unnecessary export of internal __bjsPropStoreKey Addresses Copilot PR review: __bjsPropStoreKey is only used inside nodeDecorator.ts, so it should not be exported. Removed the redundant export (and the now-meaningless @internal tag on a module-private const). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/dev/core/src/Decorators/nodeDecorator.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dev/core/src/Decorators/nodeDecorator.ts b/packages/dev/core/src/Decorators/nodeDecorator.ts index 712f5ff08d5..e9bbea9d840 100644 --- a/packages/dev/core/src/Decorators/nodeDecorator.ts +++ b/packages/dev/core/src/Decorators/nodeDecorator.ts @@ -137,9 +137,8 @@ export function editableInPropertyPage( }; } -/** @internal */ // eslint-disable-next-line @typescript-eslint/naming-convention -export const __bjsPropStoreKey = "__bjs_prop_store__"; +const __bjsPropStoreKey = "__bjs_prop_store__"; /** * Gets the editable properties for a given target using TC39 decorator metadata. From bd10f125bc95add7ccecdb5fe3281844b35c66eb Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Fri, 3 Jul 2026 12:32:42 +0200 Subject: [PATCH 17/20] TC39 test-infra: lower Stage 3 decorators via esbuild pre-plugin under Vite 8 Vite 8 (#18649) transforms via Rolldown/Oxc, which only lowers legacy (experimental) decorators and leaves TC39 Stage 3 decorators + the 'accessor' keyword untransformed, causing 'SyntaxError: Invalid or unexpected token' when Node imports @dev/core in the unit suite. Vite 8 also ignores the 'esbuild' config option entirely. Add a 'pre' Vite plugin that runs transformWithEsbuild on all non- node_modules .ts/.tsx files (esbuild does lower TC39 decorators), with useDefineForClassFields:false to preserve class-field semantics, and set oxc:false so Rolldown does not re-run its own transform. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- vitest.config.mts | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/vitest.config.mts b/vitest.config.mts index 9d96e39b186..b49d1a68252 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,4 +1,5 @@ import { defineConfig } from "vitest/config"; +import { transformWithEsbuild } from "vite"; import * as fs from "fs"; import * as path from "path"; import { fileURLToPath } from "url"; @@ -56,10 +57,15 @@ const createProjectConfig = (type: string) => { }; }; -// 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 = { +// TC39 decorators migration: with experimentalDecorators removed, the source uses TC39 Stage 3 +// decorators plus the `accessor` keyword. Vite 8 transforms via Oxc (through Rolldown), but Oxc only +// lowers *legacy* (experimental) decorators — with TC39 Stage 3 decorators it leaves +// `@decorator`/`accessor` untransformed, which Node cannot parse ("SyntaxError: Invalid or unexpected +// token"). esbuild does lower TC39 decorators, so we disable Oxc (`oxc: false`) and run a `pre` +// plugin that transforms every TS/TSX source with esbuild before Rolldown processes it. +// `useDefineForClassFields: false` keeps assignment (not define) class-field semantics so type-only +// field redeclarations do not clobber values that a base constructor assigned. +const esbuildTransformOptions = { target: "es2021" as const, tsconfigRaw: { compilerOptions: { @@ -68,8 +74,22 @@ const esbuildConfig = { }, }; +const esbuildDecoratorPlugin = { + name: "babylon-esbuild-tc39-decorators", + enforce: "pre" as const, + async transform(code: string, id: string) { + const filePath = id.split("?")[0]; + if (!/\.tsx?$/.test(filePath) || filePath.includes("/node_modules/")) { + return null; + } + const result = await transformWithEsbuild(code, id, esbuildTransformOptions); + return { code: result.code, map: result.map }; + }, +}; + export default defineConfig({ - esbuild: esbuildConfig, + oxc: false, + plugins: [esbuildDecoratorPlugin], resolve: { alias: { ...aliases, @@ -84,7 +104,8 @@ export default defineConfig({ outputFile: process.env.CI ? { junit: "./junit.xml" } : undefined, projects: [ { - esbuild: esbuildConfig, + oxc: false, + plugins: [esbuildDecoratorPlugin], test: createProjectConfig("unit"), resolve: { alias: { From b820cc85ad294f17c66bf2bbcdbbab524beeffbd Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Fri, 3 Jul 2026 12:33:03 +0200 Subject: [PATCH 18/20] TC39 core: dedupe nativeOverride, add nativeOverride unit tests Extract the shared resolve-once wrapper into ApplyNativeOverride, used by both nativeOverride and nativeOverride.filter, removing the copy-paste introduced during the TC39 conversion while preserving exact call semantics. Add unit tests covering the JS-only path, native-override path, resolve-once/prototype-replacement behavior, and the filter predicate true/false branches (stubbing the _native global). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/dev/core/src/Misc/decorators.ts | 76 ++++++++-------- .../test/unit/Decorators/decorators.test.ts | 89 ++++++++++++++++++- 2 files changed, 127 insertions(+), 38 deletions(-) diff --git a/packages/dev/core/src/Misc/decorators.ts b/packages/dev/core/src/Misc/decorators.ts index 0aa458db340..c54b77e3478 100644 --- a/packages/dev/core/src/Misc/decorators.ts +++ b/packages/dev/core/src/Misc/decorators.ts @@ -124,14 +124,23 @@ export function serializeAsCameraReference(sourceName?: string) { declare const _native: any; /** - * Decorator used to redirect a function to a native implementation if available. - * @internal + * Shared implementation for the {@link nativeOverride} decorator and its `.filter` variant. + * Both flavors install a wrapper that, on first invocation, resolves the function to use once: + * either the original JS function or (when running in a Babylon Native context) a native-aware + * function produced by `resolveNative`. The resolved function then replaces the wrapper on the + * target so subsequent calls skip this setup entirely. + * @param originalMethod - The decorated JS method. + * @param context - The TC39 method decorator context. + * @param resolveNative - Builds the function to use when a native override is present, given the + * native function and the original JS function. + * @returns The wrapper function that replaces the decorated method. */ -export function nativeOverride( +function ApplyNativeOverride( originalMethod: (this: This, ...args: Args) => Return, - _context: ClassMethodDecoratorContext Return> + context: ClassMethodDecoratorContext Return>, + resolveNative: (nativeFunc: (this: This, ...args: Args) => Return, jsFunc: (this: This, ...args: Args) => Return) => (this: This, ...args: Args) => Return ): (this: This, ...args: Args) => Return { - const propertyKey = String(_context.name); + const propertyKey = String(context.name); let resolvedFunc: ((this: This, ...args: Args) => Return) | null = null; const wrapper = function (this: This, ...params: Args): Return { @@ -141,10 +150,10 @@ export function nativeOverride( // 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; + resolvedFunc = resolveNative(_native[propertyKey] as (this: This, ...args: Args) => Return, originalMethod); } - const target = (this && (_context.static ? this : Object.getPrototypeOf(this))) as any; + const target = (this && (context.static ? this : Object.getPrototypeOf(this))) as any; if (target?.[propertyKey] === wrapper) { target[propertyKey] = resolvedFunc; } @@ -156,6 +165,18 @@ export function nativeOverride( return wrapper; } +/** + * Decorator used to redirect a function to a native implementation if available. + * @internal + */ +export function nativeOverride( + originalMethod: (this: This, ...args: Args) => Return, + context: ClassMethodDecoratorContext Return> +): (this: This, ...args: Args) => Return { + // When a native override exists, use it directly. + return ApplyNativeOverride(originalMethod, context, (nativeFunc) => nativeFunc); +} + /** * Decorator factory that applies the nativeOverride decorator, but determines whether to redirect to the native implementation based on a filter function that evaluates the function arguments. * @param predicate @@ -164,36 +185,19 @@ export function nativeOverride( * @internal */ nativeOverride.filter = function boolean>(predicate: T) { - 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 ( + originalMethod: (this: This, ...args: Args) => Return, + context: ClassMethodDecoratorContext Return> + ): ((this: This, ...args: Args) => Return) => { + // When a native override exists, evaluate the predicate on each call to choose between the native and JS function. + return ApplyNativeOverride(originalMethod, context, (nativeFunc, jsFunc) => { + return function (this: This, ...args: Args): Return { + if (predicate(...(args as unknown as Parameters))) { + return nativeFunc(...args); } - } - - return resolvedFunc!.apply(this, params); - }; - - return wrapper; + return jsFunc.apply(this, args); + }; + }); }; }; diff --git a/packages/dev/core/test/unit/Decorators/decorators.test.ts b/packages/dev/core/test/unit/Decorators/decorators.test.ts index 33a5cc846e2..2d0bd8e931e 100644 --- a/packages/dev/core/test/unit/Decorators/decorators.test.ts +++ b/packages/dev/core/test/unit/Decorators/decorators.test.ts @@ -2,10 +2,10 @@ * 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 { serialize, serializeAsColor3, expandToProperty, nativeOverride } 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"; +import { afterEach, describe, expect, it, vi } from "vitest"; describe("TC39 Decorator Migration", () => { describe("serialize decorator", () => { @@ -121,4 +121,89 @@ describe("TC39 Decorator Migration", () => { expect(callback).toHaveBeenCalledTimes(1); }); }); + + describe("nativeOverride decorator", () => { + afterEach(() => { + delete (globalThis as any)._native; + }); + + it("uses the original JS implementation when no native context is present", () => { + class Test { + @nativeOverride + public compute(a: number, b: number): number { + return a + b; + } + } + + expect(new Test().compute(2, 3)).toBe(5); + }); + + it("redirects to the native implementation when a native context is present", () => { + const nativeCompute = vi.fn(function (this: unknown, a: number, b: number) { + return a * b; + }); + (globalThis as any)._native = { compute: nativeCompute }; + + class Test { + @nativeOverride + public compute(a: number, b: number): number { + return a + b; + } + } + + expect(new Test().compute(2, 3)).toBe(6); + expect(nativeCompute).toHaveBeenCalledTimes(1); + }); + + it("resolves the target function once and replaces the wrapper on the prototype", () => { + class Test { + @nativeOverride + public compute(a: number, b: number): number { + return a + b; + } + } + + const instance = new Test(); + const wrapper = Test.prototype.compute; + instance.compute(1, 1); + // The wrapper should have replaced itself with the resolved function on the prototype. + expect(Test.prototype.compute).not.toBe(wrapper); + expect(instance.compute(4, 5)).toBe(9); + }); + + describe(".filter", () => { + it("uses the JS implementation for every call when no native context is present", () => { + class Test { + @nativeOverride.filter((a: number) => a > 10) + public compute(a: number): number { + return a + 1; + } + } + + const instance = new Test(); + expect(instance.compute(5)).toBe(6); + expect(instance.compute(20)).toBe(21); + }); + + it("redirects to native only when the predicate passes", () => { + const nativeCompute = vi.fn((a: number) => a * 100); + (globalThis as any)._native = { compute: nativeCompute }; + + class Test { + @nativeOverride.filter((a: number) => a > 10) + public compute(a: number): number { + return a + 1; + } + } + + const instance = new Test(); + // Predicate is false -> JS implementation is used. + expect(instance.compute(5)).toBe(6); + expect(nativeCompute).not.toHaveBeenCalled(); + // Predicate is true -> native implementation is used. + expect(instance.compute(20)).toBe(2000); + expect(nativeCompute).toHaveBeenCalledTimes(1); + }); + }); + }); }); From 4547aee954d60f620919df5538199e393417b1cb Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Fri, 3 Jul 2026 18:21:19 +0200 Subject: [PATCH 19/20] TC39 core: fix TS2684 in nativeOverride.filter native call The deduped ApplyNativeOverride typed the native function with a 'this: This' binding, but the filter path invokes it without a this-bind (matching the original behavior). Cast to a this-less signature so tsc type-checks; the unit suite missed this because it transforms via esbuild without type-checking. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/dev/core/src/Misc/decorators.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dev/core/src/Misc/decorators.ts b/packages/dev/core/src/Misc/decorators.ts index c54b77e3478..b6736e85fd3 100644 --- a/packages/dev/core/src/Misc/decorators.ts +++ b/packages/dev/core/src/Misc/decorators.ts @@ -193,7 +193,8 @@ nativeOverride.filter = function boolean>(predica return ApplyNativeOverride(originalMethod, context, (nativeFunc, jsFunc) => { return function (this: This, ...args: Args): Return { if (predicate(...(args as unknown as Parameters))) { - return nativeFunc(...args); + // The native function is invoked without a `this` binding, matching the original behavior. + return (nativeFunc as (...args: Args) => Return)(...args); } return jsFunc.apply(this, args); }; From 2fbc6b90cf3d6fd10bf3a4ccc5b8c4e4417d8fc0 Mon Sep 17 00:00:00 2001 From: Raanan Weber Date: Fri, 3 Jul 2026 21:30:06 +0200 Subject: [PATCH 20/20] TC39 viewer: lower Stage 3 decorators in dev server via esbuild (Vite 8/Oxc) The viewer CI tests serve the viewer's own Lit-element source as raw TS (script type=module src=.../src/index.ts). Under Vite 8 (#18649) the dev server transforms via Oxc, which only lowers legacy decorators and leaves TC39 Stage 3 decorators + the 'accessor' keyword untransformed. The browser then throws 'SyntaxError: Invalid or unexpected token', the babylon-viewer custom element is never defined, and every Playwright test times out waiting for the (hidden, un-upgraded) element to become visible. Mirror the vitest fix in the viewer's vite.config.mjs: set oxc:false and add a 'pre' plugin that transforms .ts/.tsx via esbuild (which does lower TC39 decorators) with target/useDefineForClassFields matching tsconfig.build.json. Only the dev test server is affected; the published package is built by tsc. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- packages/tools/viewer/vite.config.mjs | 34 ++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/tools/viewer/vite.config.mjs b/packages/tools/viewer/vite.config.mjs index 47ef3e37779..d085f3aeab4 100644 --- a/packages/tools/viewer/vite.config.mjs +++ b/packages/tools/viewer/vite.config.mjs @@ -2,12 +2,42 @@ /* eslint-disable no-console */ -import { defineConfig, loadEnv } from "vite"; +import { defineConfig, loadEnv, transformWithEsbuild } from "vite"; import chalk from "chalk"; import { mkdirSync, createWriteStream } from "fs"; import { execSync } from "child_process"; import path from "path"; +// TC39 decorators migration: the viewer's Lit elements use TC39 Stage 3 decorators plus the +// `accessor` keyword. Vite 8 transforms served source via Oxc (through Rolldown), but Oxc only +// lowers *legacy* (experimental) decorators — with TC39 Stage 3 decorators it leaves +// `@decorator`/`accessor` untransformed, which the browser cannot parse ("SyntaxError: Invalid or +// unexpected token"), so the `babylon-viewer` custom element is never defined. esbuild does lower +// TC39 decorators, so we disable Oxc (`oxc: false`) and run a `pre` plugin that transforms every +// TS/TSX source with esbuild before Rolldown processes it. `target`/`useDefineForClassFields` mirror +// tsconfig.build.json so the dev server matches how the published package is compiled by tsc. +const esbuildTransformOptions = { + target: "es2021", + tsconfigRaw: { + compilerOptions: { + useDefineForClassFields: false, + }, + }, +}; + +const esbuildDecoratorPlugin = { + name: "babylon-esbuild-tc39-decorators", + enforce: "pre", + async transform(code, id) { + const filePath = id.split("?")[0]; + if (!/\.tsx?$/.test(filePath) || filePath.includes("/node_modules/")) { + return null; + } + const result = await transformWithEsbuild(code, id, esbuildTransformOptions); + return { code: result.code, map: result.map }; + }, +}; + export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd()); const source = env.source ?? "dev"; @@ -20,12 +50,14 @@ export default defineConfig(({ mode }) => { return { root: "../../../", + oxc: false, server: { port, hmr: process.env.ENABLE_HOT_RELOAD !== undefined ? process.env.ENABLE_HOT_RELOAD === "true" : true, https: process.env.ENABLE_HTTPS === "true", }, plugins: [ + esbuildDecoratorPlugin, { name: "configure-server", configureServer(server) {