@babylonjs/smart-filters 0.2.0-alpha → 0.3.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/blocks/baseBlock.d.ts +1 -1
  2. package/dist/blocks/baseBlock.d.ts.map +1 -1
  3. package/dist/blocks/baseBlock.js +1 -1
  4. package/dist/blocks/baseBlock.js.map +1 -1
  5. package/dist/blocks/copyBlock.d.ts +2 -3
  6. package/dist/blocks/copyBlock.d.ts.map +1 -1
  7. package/dist/blocks/copyBlock.js +4 -24
  8. package/dist/blocks/copyBlock.js.map +1 -1
  9. package/dist/blocks/copyBlock.shader.d.ts +13 -0
  10. package/dist/blocks/copyBlock.shader.d.ts.map +1 -0
  11. package/dist/blocks/copyBlock.shader.js +34 -0
  12. package/dist/blocks/copyBlock.shader.js.map +1 -0
  13. package/dist/blocks/inputBlock.d.ts +41 -5
  14. package/dist/blocks/inputBlock.d.ts.map +1 -1
  15. package/dist/blocks/inputBlock.deserializer.d.ts +14 -0
  16. package/dist/blocks/inputBlock.deserializer.d.ts.map +1 -0
  17. package/dist/blocks/inputBlock.deserializer.js +46 -0
  18. package/dist/blocks/inputBlock.deserializer.js.map +1 -0
  19. package/dist/blocks/inputBlock.js +16 -6
  20. package/dist/blocks/inputBlock.js.map +1 -1
  21. package/dist/blocks/inputBlock.serialization.types.d.ts +74 -0
  22. package/dist/blocks/inputBlock.serialization.types.d.ts.map +1 -0
  23. package/dist/blocks/inputBlock.serialization.types.js +2 -0
  24. package/dist/blocks/inputBlock.serialization.types.js.map +1 -0
  25. package/dist/blocks/inputBlock.serializer.d.ts +6 -0
  26. package/dist/blocks/inputBlock.serializer.d.ts.map +1 -0
  27. package/dist/blocks/inputBlock.serializer.js +115 -0
  28. package/dist/blocks/inputBlock.serializer.js.map +1 -0
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/serialization/index.d.ts +5 -0
  34. package/dist/serialization/index.d.ts.map +1 -0
  35. package/dist/serialization/index.js +5 -0
  36. package/dist/serialization/index.js.map +1 -0
  37. package/dist/serialization/serializedSmartFilter.d.ts +6 -0
  38. package/dist/serialization/serializedSmartFilter.d.ts.map +1 -0
  39. package/dist/serialization/serializedSmartFilter.js +2 -0
  40. package/dist/serialization/serializedSmartFilter.js.map +1 -0
  41. package/dist/serialization/smartFilterDeserializer.d.ts +25 -0
  42. package/dist/serialization/smartFilterDeserializer.d.ts.map +1 -0
  43. package/dist/serialization/smartFilterDeserializer.js +90 -0
  44. package/dist/serialization/smartFilterDeserializer.js.map +1 -0
  45. package/dist/serialization/smartFilterSerializer.d.ts +23 -0
  46. package/dist/serialization/smartFilterSerializer.d.ts.map +1 -0
  47. package/dist/serialization/smartFilterSerializer.js +91 -0
  48. package/dist/serialization/smartFilterSerializer.js.map +1 -0
  49. package/dist/serialization/v1/defaultBlockSerializer.d.ts +9 -0
  50. package/dist/serialization/v1/defaultBlockSerializer.d.ts.map +1 -0
  51. package/dist/serialization/v1/defaultBlockSerializer.js +16 -0
  52. package/dist/serialization/v1/defaultBlockSerializer.js.map +1 -0
  53. package/dist/serialization/v1/index.d.ts +3 -0
  54. package/dist/serialization/v1/index.d.ts.map +1 -0
  55. package/dist/serialization/v1/index.js +3 -0
  56. package/dist/serialization/v1/index.js.map +1 -0
  57. package/dist/serialization/v1/serialization.types.d.ts +83 -0
  58. package/dist/serialization/v1/serialization.types.d.ts.map +1 -0
  59. package/dist/serialization/v1/serialization.types.js +2 -0
  60. package/dist/serialization/v1/serialization.types.js.map +1 -0
  61. package/dist/smartFilter.d.ts +2 -2
  62. package/dist/smartFilter.d.ts.map +1 -1
  63. package/dist/smartFilter.js +9 -6
  64. package/dist/smartFilter.js.map +1 -1
  65. package/dist/utils/buildTools/determineVersion.d.ts +36 -0
  66. package/dist/utils/buildTools/determineVersion.d.ts.map +1 -0
  67. package/dist/utils/buildTools/determineVersion.js +109 -0
  68. package/dist/utils/buildTools/determineVersion.js.map +1 -0
  69. package/dist/utils/buildTools/shaderConverter.d.ts +2 -0
  70. package/dist/utils/buildTools/shaderConverter.d.ts.map +1 -0
  71. package/dist/utils/buildTools/shaderConverter.js +277 -0
  72. package/dist/utils/buildTools/shaderConverter.js.map +1 -0
  73. package/dist/utils/buildTools/versionUp.d.ts +2 -0
  74. package/dist/utils/buildTools/versionUp.d.ts.map +1 -0
  75. package/dist/utils/buildTools/versionUp.js +45 -0
  76. package/dist/utils/buildTools/versionUp.js.map +1 -0
  77. package/dist/utils/textureLoaders.d.ts +3 -1
  78. package/dist/utils/textureLoaders.d.ts.map +1 -1
  79. package/dist/utils/textureLoaders.js +3 -2
  80. package/dist/utils/textureLoaders.js.map +1 -1
  81. package/dist/utils/uniqueIdGenerator.d.ts +19 -0
  82. package/dist/utils/uniqueIdGenerator.d.ts.map +1 -0
  83. package/dist/utils/uniqueIdGenerator.js +27 -0
  84. package/dist/utils/uniqueIdGenerator.js.map +1 -0
  85. package/package.json +11 -6
  86. package/readme.md +12 -0
  87. package/src/blocks/baseBlock.ts +2 -3
  88. package/src/blocks/copyBlock.fragment.glsl +5 -0
  89. package/src/blocks/copyBlock.shader.ts +36 -0
  90. package/src/blocks/copyBlock.ts +4 -29
  91. package/src/blocks/inputBlock.deserializer.ts +60 -0
  92. package/src/blocks/inputBlock.serialization.types.ts +95 -0
  93. package/src/blocks/inputBlock.serializer.ts +132 -0
  94. package/src/blocks/inputBlock.ts +51 -7
  95. package/src/index.ts +2 -1
  96. package/src/serialization/index.ts +4 -0
  97. package/src/serialization/serializedSmartFilter.ts +6 -0
  98. package/src/serialization/smartFilterDeserializer.ts +127 -0
  99. package/src/serialization/smartFilterSerializer.ts +113 -0
  100. package/src/serialization/v1/defaultBlockSerializer.ts +18 -0
  101. package/src/serialization/v1/index.ts +2 -0
  102. package/src/serialization/v1/serialization.types.ts +108 -0
  103. package/src/smartFilter.ts +10 -8
  104. package/src/utils/buildTools/determineVersion.ts +127 -0
  105. package/src/utils/buildTools/shaderConverter.ts +399 -0
  106. package/src/utils/buildTools/versionUp.ts +52 -0
  107. package/src/utils/textureLoaders.ts +18 -3
  108. package/src/utils/uniqueIdGenerator.ts +28 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniqueIdGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/uniqueIdGenerator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,iBAAiB;IAC1B;;OAEG;IACH,OAAc,aAAa,SAAK;IAEhC;;OAEG;IACH,WAAkB,QAAQ,WAIzB;IAED;;;OAGG;WACW,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAK5D"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Helper class used to generate IDs unique to the current session
3
+ */
4
+ export class UniqueIdGenerator {
5
+ /**
6
+ * Gets a unique (relatively to the current session) Id
7
+ */
8
+ static get UniqueId() {
9
+ const result = this._NextUniqueId;
10
+ this._NextUniqueId++;
11
+ return result;
12
+ }
13
+ /**
14
+ * Ensures future generated IDs are greater than the specified value
15
+ * @param minimum - The minimum value that future generated IDs should be greater than
16
+ */
17
+ static EnsureIdsGreaterThan(minimum) {
18
+ if (this._NextUniqueId <= minimum) {
19
+ this._NextUniqueId = minimum + 1;
20
+ }
21
+ }
22
+ }
23
+ /**
24
+ * The next unique ID to be returned
25
+ */
26
+ UniqueIdGenerator._NextUniqueId = 1;
27
+ //# sourceMappingURL=uniqueIdGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniqueIdGenerator.js","sourceRoot":"","sources":["../../src/utils/uniqueIdGenerator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,iBAAiB;IAM1B;;OAEG;IACI,MAAM,KAAK,QAAQ;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;QAClC,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,oBAAoB,CAAC,OAAe;QAC9C,IAAI,IAAI,CAAC,aAAa,IAAI,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,GAAG,OAAO,GAAG,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;;AAtBD;;GAEG;AACW,+BAAa,GAAG,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@babylonjs/smart-filters",
3
- "version": "0.2.0-alpha",
4
- "description": "Babylon.js Smart Filter core and common block library",
3
+ "version": "0.3.1-alpha",
4
+ "description": "Babylon.js Smart Filter core",
5
5
  "author": {
6
6
  "name": "Sebastien VANDENBERGHE"
7
7
  },
@@ -24,7 +24,9 @@
24
24
  "esnext": "dist/index",
25
25
  "types": "dist/index",
26
26
  "type": "module",
27
- "sideEffects": false,
27
+ "sideEffects": [
28
+ "./dist/utils/buildTools/**"
29
+ ],
28
30
  "repository": {
29
31
  "type": "git",
30
32
  "url": "git+https://github.com/BabylonJS/SmartFilters.git"
@@ -36,9 +38,12 @@
36
38
  "readme.md"
37
39
  ],
38
40
  "scripts": {
39
- "clean": "rimraf dist && rimraf tsconfig.build.tsbuildinfo",
40
- "versionUp": "node tools/versionUp.js",
41
- "build": "tsc -p ./tsconfig.build.json",
41
+ "clean": "rimraf dist && rimraf buildTools && rimraf tsconfig.build.tsbuildinfo && rimraf ../../tsconfig.buildTools.build.tsbuildinfo",
42
+ "preparePublish": "node buildTools/versionUp.js --alpha",
43
+ "build": "npm run build:buildTools && npm run build:runTools && npm run build:core",
44
+ "build:core": "tsc -p ./tsconfig.build.json",
45
+ "build:buildTools": "tsc -p ./tsconfig.buildTools.build.json",
46
+ "build:runTools": "node buildTools/shaderConverter.js ./src/blocks ../utils/shaderCodeUtils",
42
47
  "watch": "tsc -p ./tsconfig.build.json --watch",
43
48
  "test": "echo \"Error: run test from the root of the monorepo\" && exit 1"
44
49
  },
package/readme.md CHANGED
@@ -163,3 +163,15 @@ The overall system is trying at best to follow 3 simple rules:
163
163
  - Be CPU efficient: for instance, we are trying to be branchless in most of our commands and we try to keep the number of commands as low as possible.
164
164
  - Be memory efficient: no commands should allocate memory as it could trigger some garbage collection at the expense of frame loss.
165
165
  - Be GPU efficient: the graph and texture optimizers minimize the number of "passes" required to render an image and the GPU resources used by the graph.
166
+
167
+ ## Requirements for GLSL code
168
+
169
+ To be imported into blocks, the following requirements must be met by .glsl files:
170
+
171
+ 1. There must be a sampler2D uniform designed as the main input texture (the one to be passed along) if this block is disabled. It must have a comment on its line like this:
172
+ `// main`
173
+ 1. There must be a single main function which takes in a vec2 named vUV and returns a vec4, and it must have a comment on its line like this:
174
+ `// main`
175
+ 1. Any uniforms which should have the same value across all instances of the same block should have a comment on its line like this:
176
+ `// single`
177
+ 1. Functions must be declared with the open { on the same line as the function name
@@ -1,12 +1,11 @@
1
1
  import type { Nullable } from "@babylonjs/core/types";
2
- import { UniqueIdGenerator } from "@babylonjs/core/Misc/uniqueIdGenerator.js";
3
-
4
2
  import { ConnectionPointType, type ConnectionPointValue } from "../connection/connectionPointType.js";
5
3
  import type { InitializationData, SmartFilter } from "../smartFilter";
6
4
  import type { ICommandOwner } from "../command/command";
7
5
  import { ConnectionPoint, type RuntimeData } from "../connection/connectionPoint.js";
8
6
  import { ConnectionPointWithDefault } from "../connection/connectionPointWithDefault.js";
9
7
  import { ConnectionPointDirection } from "../connection/connectionPointDirection.js";
8
+ import { UniqueIdGenerator } from "../utils/uniqueIdGenerator.js";
10
9
 
11
10
  /**
12
11
  * Defines a callback function that is triggered when visiting a block,
@@ -38,7 +37,7 @@ export abstract class BaseBlock implements ICommandOwner {
38
37
  /**
39
38
  * Global unique id of the block (This is unique for the current session).
40
39
  */
41
- public readonly uniqueId: number;
40
+ public uniqueId: number;
42
41
 
43
42
  /**
44
43
  * The name of the block. This is used to identify the block in the smart filter or in debug.
@@ -0,0 +1,5 @@
1
+ uniform sampler2D input; // main
2
+
3
+ vec4 copy(vec2 vUV) { // main
4
+ return texture2D(input, vUV);
5
+ }
@@ -0,0 +1,36 @@
1
+ import type { ShaderProgram } from "../utils/shaderCodeUtils";
2
+
3
+ /**
4
+ * The shader program for the block.
5
+ */
6
+ export const shaderProgram: ShaderProgram = {
7
+ vertex: undefined,
8
+ fragment: {
9
+ uniform: `
10
+ uniform sampler2D _input_; // main
11
+ uniform bool _disabled_;`,
12
+ mainInputTexture: "_input_",
13
+ mainFunctionName: "_copy_",
14
+ functions: [
15
+ {
16
+ name: "_copy_",
17
+ code: `
18
+ vec4 _copy_(vec2 vUV) {
19
+ if (_disabled_) return texture2D(_input_, vUV);
20
+ // main
21
+ return texture2D(_input_, vUV);
22
+ }
23
+
24
+ `,
25
+ },
26
+ ],
27
+ },
28
+ };
29
+
30
+ /**
31
+ * The uniform names for this shader, to be used in the shader binding so
32
+ * that the names are always in sync.
33
+ */
34
+ export const uniforms = {
35
+ input: "input",
36
+ };
@@ -1,32 +1,11 @@
1
1
  import type { Effect } from "@babylonjs/core/Materials/effect";
2
2
 
3
- import type { ShaderProgram } from "../utils/shaderCodeUtils";
4
3
  import type { SmartFilter } from "../smartFilter";
5
4
  import { ConnectionPointType } from "../connection/connectionPointType.js";
6
5
  import { ShaderBlock } from "./shaderBlock.js";
7
6
  import { ShaderBinding } from "../runtime/shaderRuntime.js";
8
7
  import type { RuntimeData } from "../connection/connectionPoint";
9
-
10
- const shaderProgram: ShaderProgram = {
11
- fragment: {
12
- uniform: `
13
- uniform sampler2D _input_;
14
- `,
15
-
16
- mainFunctionName: "_copy_",
17
-
18
- functions: [
19
- {
20
- name: "_copy_",
21
- code: `
22
- vec4 _copy_(vec2 vUV) {
23
- return texture2D(_input_, vUV);
24
- }
25
- `,
26
- },
27
- ],
28
- },
29
- };
8
+ import { shaderProgram, uniforms } from "./copyBlock.shader.js";
30
9
 
31
10
  /**
32
11
  * The shader bindings for the Copy block.
@@ -50,7 +29,7 @@ export class CopyShaderBinding extends ShaderBinding {
50
29
  * @internal
51
30
  */
52
31
  public override bind(effect: Effect): void {
53
- effect.setTexture(this.getRemappedName("input"), this._inputTexture.value);
32
+ effect.setTexture(this.getRemappedName(uniforms.input), this._inputTexture.value);
54
33
  }
55
34
  }
56
35
 
@@ -59,7 +38,7 @@ export class CopyShaderBinding extends ShaderBinding {
59
38
  *
60
39
  * This might be helpful to duplicate a texture if necessary.
61
40
  *
62
- * It simply takes a texture as input and outputs it to another texture or the main canvas.
41
+ * It simply takes a texture as input and outputs it to another texture or to the main canvas.
63
42
  */
64
43
  export class CopyBlock extends ShaderBlock {
65
44
  /**
@@ -91,11 +70,7 @@ export class CopyBlock extends ShaderBlock {
91
70
  * @returns The class instance that binds the data to the effect
92
71
  */
93
72
  public getShaderBinding(): ShaderBinding {
94
- const input = this.input.runtimeData;
95
-
96
- if (!input) {
97
- throw new Error(`The input texture is missing for the CopyBlock named ${this.name}`);
98
- }
73
+ const input = this._confirmRuntimeDataSupplied(this.input);
99
74
 
100
75
  return new CopyShaderBinding(this, input);
101
76
  }
@@ -0,0 +1,60 @@
1
+ import { InputBlock } from "./inputBlock.js";
2
+ import type { SerializedInputBlockData } from "./inputBlock.serialization.types.js";
3
+ import { ConnectionPointType } from "../connection/connectionPointType.js";
4
+ import type { SmartFilter } from "../smartFilter.js";
5
+ import type { ISerializedBlockV1 } from "../serialization/v1/serialization.types.js";
6
+ import { createImageTexture } from "../utils/textureLoaders.js";
7
+ import type { ThinEngine } from "@babylonjs/core/Engines/thinEngine.js";
8
+ import type { Nullable } from "@babylonjs/core/types.js";
9
+ import type { ThinTexture } from "@babylonjs/core/Materials/Textures/thinTexture.js";
10
+ /**
11
+ * V1 Input Block Deserializer
12
+ * @param smartFilter - The SmartFilter to deserialize the block into
13
+ * @param serializedBlock - The serialized block data
14
+ * @param engine - The ThinEngine to use for loading textures
15
+ * @returns A deserialized InputBlock
16
+ */
17
+ export function inputBlockDeserializer(
18
+ smartFilter: SmartFilter,
19
+ serializedBlock: ISerializedBlockV1,
20
+ engine: ThinEngine
21
+ ) {
22
+ const blockData = serializedBlock.data as SerializedInputBlockData;
23
+
24
+ switch (blockData.inputType) {
25
+ case ConnectionPointType.Boolean:
26
+ return new InputBlock(smartFilter, serializedBlock.name, ConnectionPointType.Boolean, blockData.value);
27
+ case ConnectionPointType.Float:
28
+ return new InputBlock(smartFilter, serializedBlock.name, ConnectionPointType.Float, blockData.value);
29
+ case ConnectionPointType.Texture: {
30
+ // If information necessary to load an image was serialized, load the image
31
+ const texture: Nullable<ThinTexture> = blockData.url
32
+ ? createImageTexture(engine, blockData.url, blockData.flipY)
33
+ : null;
34
+ if (texture && blockData.anisotropicFilteringLevel !== null) {
35
+ texture.anisotropicFilteringLevel = blockData.anisotropicFilteringLevel;
36
+ }
37
+
38
+ // Create the input block
39
+ const inputBlock = new InputBlock(smartFilter, serializedBlock.name, ConnectionPointType.Texture, texture);
40
+
41
+ // If editor data was serialized, set it on the deserialized block
42
+ inputBlock.editorData = {
43
+ url: blockData.url,
44
+ anisotropicFilteringLevel: blockData.anisotropicFilteringLevel,
45
+ flipY: blockData.flipY,
46
+ forcedExtension: blockData.forcedExtension,
47
+ };
48
+
49
+ return inputBlock;
50
+ }
51
+ case ConnectionPointType.Color3:
52
+ return new InputBlock(smartFilter, serializedBlock.name, ConnectionPointType.Color3, blockData.value);
53
+ case ConnectionPointType.Color4:
54
+ return new InputBlock(smartFilter, serializedBlock.name, ConnectionPointType.Color4, blockData.value);
55
+ case ConnectionPointType.Vector2:
56
+ return new InputBlock(smartFilter, serializedBlock.name, ConnectionPointType.Vector2, blockData.value);
57
+ }
58
+
59
+ throw new Error("Could not deserialize input block, unknown input type");
60
+ }
@@ -0,0 +1,95 @@
1
+ import type { Nullable } from "@babylonjs/core/types.js";
2
+ import type { ConnectionPointType } from "../connection/connectionPointType.js";
3
+ import type { IColor3Like, IColor4Like, IVector2Like } from "@babylonjs/core/Maths/math.like.js";
4
+
5
+ /**
6
+ * The data for an InputBlock for ConnectionPointType.Texture inputs
7
+ */
8
+ export type TextureInputBlockData = {
9
+ /** The type of the input block */
10
+ inputType: ConnectionPointType.Texture;
11
+
12
+ /** The URL, if available, of the texture */
13
+ url: Nullable<string>;
14
+
15
+ /**
16
+ * Defines the anisotropic level to use, or default if null
17
+ */
18
+ anisotropicFilteringLevel: Nullable<number>;
19
+
20
+ /**
21
+ * Indicates if the Y axis should be flipped, or default if null
22
+ */
23
+ flipY: Nullable<boolean>;
24
+
25
+ /**
26
+ * The file extension to use, or default if null.
27
+ */
28
+ forcedExtension: Nullable<string>;
29
+ };
30
+
31
+ /**
32
+ * The data for an InputBlock for ConnectionPointType.Boolean inputs
33
+ */
34
+ export type BooleanInputBlockData = {
35
+ /** The type of the input block */
36
+ inputType: ConnectionPointType.Boolean;
37
+
38
+ /** The value of the input block */
39
+ value: boolean;
40
+ };
41
+
42
+ /**
43
+ * The data for an InputBlock for ConnectionPointType.Float inputs
44
+ */
45
+ export type FloatInputBlockData = {
46
+ /** The type of the input block */
47
+ inputType: ConnectionPointType.Float;
48
+
49
+ /** The value of the input block */
50
+ value: number;
51
+ };
52
+
53
+ /**
54
+ * The data for an InputBlock for ConnectionPointType.Color3 inputs
55
+ */
56
+ export type Color3InputBlockData = {
57
+ /** The type of the input block */
58
+ inputType: ConnectionPointType.Color3;
59
+
60
+ /** The value of the input block */
61
+ value: IColor3Like;
62
+ };
63
+
64
+ /**
65
+ * The data for an InputBlock for ConnectionPointType.Color4 inputs
66
+ */
67
+ export type Color4InputBlockData = {
68
+ /** The type of the input block */
69
+ inputType: ConnectionPointType.Color4;
70
+
71
+ /** The value of the input block */
72
+ value: IColor4Like;
73
+ };
74
+
75
+ /**
76
+ * The data for an InputBlock for ConnectionPointType.Vector2 inputs
77
+ */
78
+ export type Vector2InputBlockData = {
79
+ /** The type of the input block */
80
+ inputType: ConnectionPointType.Vector2;
81
+
82
+ /** The value of the input block */
83
+ value: IVector2Like;
84
+ };
85
+
86
+ /**
87
+ * Type union of all possible InputBlock data types
88
+ */
89
+ export type SerializedInputBlockData =
90
+ | TextureInputBlockData
91
+ | BooleanInputBlockData
92
+ | FloatInputBlockData
93
+ | Color3InputBlockData
94
+ | Color4InputBlockData
95
+ | Vector2InputBlockData;
@@ -0,0 +1,132 @@
1
+ import { InputBlockBase, type InputBlock } from "./inputBlock.js";
2
+ import type { BaseBlock } from "./baseBlock.js";
3
+ import { ConnectionPointType } from "../connection/connectionPointType.js";
4
+ import type {
5
+ BooleanInputBlockData,
6
+ Color3InputBlockData,
7
+ Color4InputBlockData,
8
+ FloatInputBlockData,
9
+ SerializedInputBlockData,
10
+ TextureInputBlockData,
11
+ Vector2InputBlockData,
12
+ } from "./inputBlock.serialization.types";
13
+ import type { IBlockSerializerV1 } from "../serialization/v1/serialization.types";
14
+
15
+ /**
16
+ * Determines which generic type of InputBlock we are trying to serialize and calls the appropriate function
17
+ * to serialize the specifics for that type of InputBlock
18
+ * @param inputBlock - The InputBlock to serialize
19
+ * @returns Serialized data for the InputBlock
20
+ */
21
+ function serializeInputBlockData(inputBlock: InputBlockBase): SerializedInputBlockData {
22
+ switch (inputBlock.type) {
23
+ case ConnectionPointType.Texture:
24
+ return serializeTextureInputBlock(inputBlock as InputBlock<ConnectionPointType.Texture>);
25
+ case ConnectionPointType.Boolean:
26
+ return serializeBooleanInputBlock(inputBlock as InputBlock<ConnectionPointType.Boolean>);
27
+ case ConnectionPointType.Float:
28
+ return serializeFloatInputBlock(inputBlock as InputBlock<ConnectionPointType.Float>);
29
+ case ConnectionPointType.Color3:
30
+ return serializeColor3InputBlock(inputBlock as InputBlock<ConnectionPointType.Color3>);
31
+ case ConnectionPointType.Color4:
32
+ return serializeColor4InputBlock(inputBlock as InputBlock<ConnectionPointType.Color4>);
33
+ case ConnectionPointType.Vector2:
34
+ return serializeVector2InputBlock(inputBlock as InputBlock<ConnectionPointType.Vector2>);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Generates the serialized data for a Texture InputBlock
40
+ * @param inputBlock - The Texture InputBlock to serialize
41
+ * @returns The serialized data for the InputBlock
42
+ */
43
+ function serializeTextureInputBlock(inputBlock: InputBlock<ConnectionPointType.Texture>): TextureInputBlockData {
44
+ const internalTexture = inputBlock.runtimeValue.value?.getInternalTexture();
45
+ const forcedExtension = internalTexture?._extension ?? null;
46
+ return {
47
+ inputType: ConnectionPointType.Texture,
48
+ url: internalTexture?.url ?? null,
49
+ flipY: internalTexture?.invertY ?? null,
50
+ anisotropicFilteringLevel: internalTexture?.anisotropicFilteringLevel ?? null,
51
+ forcedExtension: forcedExtension !== "" ? forcedExtension : null,
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Generates the serialized data for a Boolean InputBlock
57
+ * @param inputBlock - The Boolean InputBlock to serialize
58
+ * @returns The serialized data for the InputBlock
59
+ */
60
+ function serializeBooleanInputBlock(inputBlock: InputBlock<ConnectionPointType.Boolean>): BooleanInputBlockData {
61
+ return {
62
+ inputType: ConnectionPointType.Boolean,
63
+ value: inputBlock.runtimeValue.value,
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Generates the serialized data for a Float InputBlock
69
+ * @param inputBlock - The Float InputBlock to serialize
70
+ * @returns The serialized data for the InputBlock
71
+ */
72
+ function serializeFloatInputBlock(inputBlock: InputBlock<ConnectionPointType.Float>): FloatInputBlockData {
73
+ return {
74
+ inputType: ConnectionPointType.Float,
75
+ value: inputBlock.runtimeValue.value,
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Generates the serialized data for a Color3 InputBlock
81
+ * @param inputBlock - The Color3 InputBlock to serialize
82
+ * @returns The serialized data for the InputBlock
83
+ */
84
+ function serializeColor3InputBlock(inputBlock: InputBlock<ConnectionPointType.Color3>): Color3InputBlockData {
85
+ return {
86
+ inputType: ConnectionPointType.Color3,
87
+ value: inputBlock.runtimeValue.value,
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Generates the serialized data for a Color4 InputBlock
93
+ * @param inputBlock - The Color4 InputBlock to serialize
94
+ * @returns The serialized data for the InputBlock
95
+ */
96
+ function serializeColor4InputBlock(inputBlock: InputBlock<ConnectionPointType.Color4>): Color4InputBlockData {
97
+ return {
98
+ inputType: ConnectionPointType.Color4,
99
+ value: inputBlock.runtimeValue.value,
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Generates the serialized data for a Vector2 InputBlock
105
+ * @param inputBlock - The Vector2 InputBlock to serialize
106
+ * @returns The serialized data for the InputBlock
107
+ */
108
+ function serializeVector2InputBlock(inputBlock: InputBlock<ConnectionPointType.Vector2>): Vector2InputBlockData {
109
+ return {
110
+ inputType: ConnectionPointType.Vector2,
111
+ value: inputBlock.runtimeValue.value,
112
+ };
113
+ }
114
+
115
+ /**
116
+ * The V1 serializer for an InputBlock
117
+ */
118
+ export const inputBlockSerializer: IBlockSerializerV1 = {
119
+ className: InputBlockBase.ClassName,
120
+ serialize: (block: BaseBlock) => {
121
+ if (block.getClassName() !== InputBlockBase.ClassName) {
122
+ throw new Error("Was asked to serialize an unrecognized block type");
123
+ }
124
+ return {
125
+ name: block.name,
126
+ uniqueId: block.uniqueId,
127
+ className: InputBlockBase.ClassName,
128
+ comments: block.comments,
129
+ data: serializeInputBlockData(block as unknown as InputBlockBase),
130
+ };
131
+ },
132
+ };
@@ -6,6 +6,7 @@ import type { DisableableBlock } from "./disableableBlock";
6
6
  import { BaseBlock } from "../blocks/baseBlock.js";
7
7
  import { createStrongRef } from "../runtime/strongRef.js";
8
8
  import { ConnectionPointType } from "../connection/connectionPointType.js";
9
+ import type { Nullable } from "@babylonjs/core/types";
9
10
 
10
11
  /**
11
12
  * Type predicate to check if value is a strong ref or a direct value
@@ -15,7 +16,7 @@ import { ConnectionPointType } from "../connection/connectionPointType.js";
15
16
  function isRuntimeData<U extends ConnectionPointType>(
16
17
  value: ConnectionPointValue<U> | RuntimeData<U>
17
18
  ): value is RuntimeData<U> {
18
- return (value as RuntimeData<ConnectionPointType>).value !== undefined;
19
+ return value && (value as RuntimeData<ConnectionPointType>).value !== undefined;
19
20
  }
20
21
 
21
22
  /**
@@ -37,18 +38,56 @@ export function isDisableableBlock(block: BaseBlock): block is DisableableBlock
37
38
  }
38
39
 
39
40
  /**
40
- * This represents any inputs used in the graph.
41
- *
42
- * This is used to provide a way to connect the graph to the outside world.
43
- *
44
- * The value is dynamically set by the user.
41
+ * This base class exists to provide a type that the serializer can use to represent
42
+ * any InputBlock without knowing the exact type it is.
45
43
  */
46
- export class InputBlock<U extends ConnectionPointType> extends BaseBlock {
44
+ export abstract class InputBlockBase extends BaseBlock {
47
45
  /**
48
46
  * The class name of the block.
49
47
  */
50
48
  public static override ClassName = "InputBlock";
51
49
 
50
+ /**
51
+ * The type of the input.
52
+ */
53
+ public abstract readonly type: ConnectionPointType;
54
+ }
55
+
56
+ /**
57
+ * Describes the editor data that can be stored with an InputBlock of a given type.
58
+ */
59
+ export type InputBlockEditorData<T extends ConnectionPointType> = T extends ConnectionPointType.Texture
60
+ ? {
61
+ /**
62
+ * The URL of the texture, or default if null.
63
+ */
64
+ url: Nullable<string>;
65
+
66
+ /**
67
+ * The anisotropic filtering level of the texture, or default if null.
68
+ */
69
+ anisotropicFilteringLevel: Nullable<number>;
70
+
71
+ /**
72
+ * Whether the Y axis should be flipped, or default if null.
73
+ */
74
+ flipY: Nullable<boolean>;
75
+
76
+ /**
77
+ * The file extension to use, or default if null.
78
+ */
79
+ forcedExtension: Nullable<string>;
80
+ }
81
+ : {};
82
+
83
+ /**
84
+ * This represents any inputs used in the graph.
85
+ *
86
+ * This is used to provide a way to connect the graph to the outside world.
87
+ *
88
+ * The value is dynamically set by the user.
89
+ */
90
+ export class InputBlock<U extends ConnectionPointType> extends InputBlockBase {
52
91
  /**
53
92
  * The output connection point of the block.
54
93
  */
@@ -59,6 +98,11 @@ export class InputBlock<U extends ConnectionPointType> extends BaseBlock {
59
98
  */
60
99
  public readonly type: U;
61
100
 
101
+ /**
102
+ * Data used by the Editor to store options required for instantiating the block in the Editor.
103
+ */
104
+ public editorData: Nullable<InputBlockEditorData<U>> = null;
105
+
62
106
  /**
63
107
  * Gets the current value of the input.
64
108
  */
package/src/index.ts CHANGED
@@ -17,7 +17,7 @@ export { ConnectionPoint } from "./connection/connectionPoint.js";
17
17
  export { type RuntimeData } from "./connection/connectionPoint.js";
18
18
 
19
19
  export { BaseBlock } from "./blocks/baseBlock.js";
20
- export { InputBlock } from "./blocks/inputBlock.js";
20
+ export { InputBlock, type InputBlockEditorData } from "./blocks/inputBlock.js";
21
21
  export { type AnyInputBlock } from "./blocks/inputBlock.js";
22
22
  export { ShaderBlock } from "./blocks/shaderBlock.js";
23
23
  export { AggregateBlock } from "./blocks/aggregateBlock.js";
@@ -34,3 +34,4 @@ export { SmartFilter } from "./smartFilter.js";
34
34
 
35
35
  export { SmartFilterOptimizer } from "./optimization/smartFilterOptimizer.js";
36
36
  export * from "./utils/textureLoaders.js";
37
+ export * from "./serialization/index.js";
@@ -0,0 +1,4 @@
1
+ export * from "./v1/index.js";
2
+ export * from "./serializedSmartFilter.js";
3
+ export * from "./smartFilterDeserializer.js";
4
+ export * from "./smartFilterSerializer.js";
@@ -0,0 +1,6 @@
1
+ import type { SerializedSmartFilterV1 } from "./v1/serialization.types";
2
+
3
+ /**
4
+ * Type union of all versions of serialized SmartFilters
5
+ */
6
+ export type SerializedSmartFilter = SerializedSmartFilterV1;