@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.
- package/dist/blocks/baseBlock.d.ts +1 -1
- package/dist/blocks/baseBlock.d.ts.map +1 -1
- package/dist/blocks/baseBlock.js +1 -1
- package/dist/blocks/baseBlock.js.map +1 -1
- package/dist/blocks/copyBlock.d.ts +2 -3
- package/dist/blocks/copyBlock.d.ts.map +1 -1
- package/dist/blocks/copyBlock.js +4 -24
- package/dist/blocks/copyBlock.js.map +1 -1
- package/dist/blocks/copyBlock.shader.d.ts +13 -0
- package/dist/blocks/copyBlock.shader.d.ts.map +1 -0
- package/dist/blocks/copyBlock.shader.js +34 -0
- package/dist/blocks/copyBlock.shader.js.map +1 -0
- package/dist/blocks/inputBlock.d.ts +41 -5
- package/dist/blocks/inputBlock.d.ts.map +1 -1
- package/dist/blocks/inputBlock.deserializer.d.ts +14 -0
- package/dist/blocks/inputBlock.deserializer.d.ts.map +1 -0
- package/dist/blocks/inputBlock.deserializer.js +46 -0
- package/dist/blocks/inputBlock.deserializer.js.map +1 -0
- package/dist/blocks/inputBlock.js +16 -6
- package/dist/blocks/inputBlock.js.map +1 -1
- package/dist/blocks/inputBlock.serialization.types.d.ts +74 -0
- package/dist/blocks/inputBlock.serialization.types.d.ts.map +1 -0
- package/dist/blocks/inputBlock.serialization.types.js +2 -0
- package/dist/blocks/inputBlock.serialization.types.js.map +1 -0
- package/dist/blocks/inputBlock.serializer.d.ts +6 -0
- package/dist/blocks/inputBlock.serializer.d.ts.map +1 -0
- package/dist/blocks/inputBlock.serializer.js +115 -0
- package/dist/blocks/inputBlock.serializer.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/serialization/index.d.ts +5 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/index.js +5 -0
- package/dist/serialization/index.js.map +1 -0
- package/dist/serialization/serializedSmartFilter.d.ts +6 -0
- package/dist/serialization/serializedSmartFilter.d.ts.map +1 -0
- package/dist/serialization/serializedSmartFilter.js +2 -0
- package/dist/serialization/serializedSmartFilter.js.map +1 -0
- package/dist/serialization/smartFilterDeserializer.d.ts +25 -0
- package/dist/serialization/smartFilterDeserializer.d.ts.map +1 -0
- package/dist/serialization/smartFilterDeserializer.js +90 -0
- package/dist/serialization/smartFilterDeserializer.js.map +1 -0
- package/dist/serialization/smartFilterSerializer.d.ts +23 -0
- package/dist/serialization/smartFilterSerializer.d.ts.map +1 -0
- package/dist/serialization/smartFilterSerializer.js +91 -0
- package/dist/serialization/smartFilterSerializer.js.map +1 -0
- package/dist/serialization/v1/defaultBlockSerializer.d.ts +9 -0
- package/dist/serialization/v1/defaultBlockSerializer.d.ts.map +1 -0
- package/dist/serialization/v1/defaultBlockSerializer.js +16 -0
- package/dist/serialization/v1/defaultBlockSerializer.js.map +1 -0
- package/dist/serialization/v1/index.d.ts +3 -0
- package/dist/serialization/v1/index.d.ts.map +1 -0
- package/dist/serialization/v1/index.js +3 -0
- package/dist/serialization/v1/index.js.map +1 -0
- package/dist/serialization/v1/serialization.types.d.ts +83 -0
- package/dist/serialization/v1/serialization.types.d.ts.map +1 -0
- package/dist/serialization/v1/serialization.types.js +2 -0
- package/dist/serialization/v1/serialization.types.js.map +1 -0
- package/dist/smartFilter.d.ts +2 -2
- package/dist/smartFilter.d.ts.map +1 -1
- package/dist/smartFilter.js +9 -6
- package/dist/smartFilter.js.map +1 -1
- package/dist/utils/buildTools/determineVersion.d.ts +36 -0
- package/dist/utils/buildTools/determineVersion.d.ts.map +1 -0
- package/dist/utils/buildTools/determineVersion.js +109 -0
- package/dist/utils/buildTools/determineVersion.js.map +1 -0
- package/dist/utils/buildTools/shaderConverter.d.ts +2 -0
- package/dist/utils/buildTools/shaderConverter.d.ts.map +1 -0
- package/dist/utils/buildTools/shaderConverter.js +277 -0
- package/dist/utils/buildTools/shaderConverter.js.map +1 -0
- package/dist/utils/buildTools/versionUp.d.ts +2 -0
- package/dist/utils/buildTools/versionUp.d.ts.map +1 -0
- package/dist/utils/buildTools/versionUp.js +45 -0
- package/dist/utils/buildTools/versionUp.js.map +1 -0
- package/dist/utils/textureLoaders.d.ts +3 -1
- package/dist/utils/textureLoaders.d.ts.map +1 -1
- package/dist/utils/textureLoaders.js +3 -2
- package/dist/utils/textureLoaders.js.map +1 -1
- package/dist/utils/uniqueIdGenerator.d.ts +19 -0
- package/dist/utils/uniqueIdGenerator.d.ts.map +1 -0
- package/dist/utils/uniqueIdGenerator.js +27 -0
- package/dist/utils/uniqueIdGenerator.js.map +1 -0
- package/package.json +11 -6
- package/readme.md +12 -0
- package/src/blocks/baseBlock.ts +2 -3
- package/src/blocks/copyBlock.fragment.glsl +5 -0
- package/src/blocks/copyBlock.shader.ts +36 -0
- package/src/blocks/copyBlock.ts +4 -29
- package/src/blocks/inputBlock.deserializer.ts +60 -0
- package/src/blocks/inputBlock.serialization.types.ts +95 -0
- package/src/blocks/inputBlock.serializer.ts +132 -0
- package/src/blocks/inputBlock.ts +51 -7
- package/src/index.ts +2 -1
- package/src/serialization/index.ts +4 -0
- package/src/serialization/serializedSmartFilter.ts +6 -0
- package/src/serialization/smartFilterDeserializer.ts +127 -0
- package/src/serialization/smartFilterSerializer.ts +113 -0
- package/src/serialization/v1/defaultBlockSerializer.ts +18 -0
- package/src/serialization/v1/index.ts +2 -0
- package/src/serialization/v1/serialization.types.ts +108 -0
- package/src/smartFilter.ts +10 -8
- package/src/utils/buildTools/determineVersion.ts +127 -0
- package/src/utils/buildTools/shaderConverter.ts +399 -0
- package/src/utils/buildTools/versionUp.ts +52 -0
- package/src/utils/textureLoaders.ts +18 -3
- package/src/utils/uniqueIdGenerator.ts +28 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
const TYPE_IMPORT_PATH = "@TYPE_IMPORT_PATH@";
|
|
5
|
+
const VERTEX_SHADER = "@VERTEX_SHADER@";
|
|
6
|
+
const UNIFORMS = "@UNIFORMS@";
|
|
7
|
+
const CONSTS_VALUE = "@CONSTS@";
|
|
8
|
+
const CONSTS_PROPERTY = "@CONSTS_PROPERTY@";
|
|
9
|
+
const MAIN_INPUT_NAME = "@MAIN_INPUT_NAME@";
|
|
10
|
+
const MAIN_FUNCTION_NAME = "@MAIN_FUNCTION_NAME@";
|
|
11
|
+
const FUNCTIONS = "@FUNCTIONS@";
|
|
12
|
+
const FUNCTION_NAME = "@FUNCTION_NAME@";
|
|
13
|
+
const FUNCTION_CODE = "@FUNCTION_CODE@";
|
|
14
|
+
const UNIFORM_NAMES = "@UNIFORM_NAMES@";
|
|
15
|
+
|
|
16
|
+
const ConstsTemplate = `
|
|
17
|
+
const: \`${CONSTS_VALUE}\`,`;
|
|
18
|
+
|
|
19
|
+
const FunctionTemplate = `
|
|
20
|
+
{
|
|
21
|
+
name: "${FUNCTION_NAME}",
|
|
22
|
+
code: \`
|
|
23
|
+
${FUNCTION_CODE}
|
|
24
|
+
\`,
|
|
25
|
+
},`;
|
|
26
|
+
|
|
27
|
+
const CodeLinePrefix = " ";
|
|
28
|
+
const UniformLinePrefix = " ";
|
|
29
|
+
const ConstLinePrefix = " ";
|
|
30
|
+
|
|
31
|
+
const ShaderTemplate = `import type { ShaderProgram } from "${TYPE_IMPORT_PATH}";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The shader program for the block.
|
|
35
|
+
*/
|
|
36
|
+
export const shaderProgram: ShaderProgram = {
|
|
37
|
+
vertex: ${VERTEX_SHADER},
|
|
38
|
+
fragment: {
|
|
39
|
+
uniform: \`${UNIFORMS}
|
|
40
|
+
uniform bool _disabled_;\`,${CONSTS_PROPERTY}
|
|
41
|
+
mainInputTexture: "${MAIN_INPUT_NAME}",
|
|
42
|
+
mainFunctionName: "${MAIN_FUNCTION_NAME}",
|
|
43
|
+
functions: [${FUNCTIONS}
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The uniform names for this shader, to be used in the shader binding so
|
|
50
|
+
* that the names are always in sync.
|
|
51
|
+
*/
|
|
52
|
+
export const uniforms = {
|
|
53
|
+
${UNIFORM_NAMES}
|
|
54
|
+
};
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
const UniformNameLinePrefix = " ";
|
|
58
|
+
|
|
59
|
+
const GetFunctionNamesRegEx = /\S*\w+\s+(\w+)\s*\(/g;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Converts a single shader
|
|
63
|
+
* @param fragmentShaderPath - The path to the fragment file for the shader
|
|
64
|
+
* @param importPath - The path to import the ShaderProgram type from
|
|
65
|
+
*/
|
|
66
|
+
function convertShader(fragmentShaderPath: string, importPath: string): void {
|
|
67
|
+
console.log(`Processing fragment shader: ${fragmentShaderPath}`);
|
|
68
|
+
|
|
69
|
+
// See if there is a corresponding vertex shader
|
|
70
|
+
let vertexShader: string | undefined = undefined;
|
|
71
|
+
const vertexShaderPath = fragmentShaderPath.replace(".fragment.glsl", ".vertex.glsl");
|
|
72
|
+
if (fs.existsSync(vertexShaderPath)) {
|
|
73
|
+
vertexShader = fs.readFileSync(vertexShaderPath, "utf8");
|
|
74
|
+
}
|
|
75
|
+
if (vertexShader) {
|
|
76
|
+
console.log("Found vertex shader");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Read the fragment shader
|
|
80
|
+
const fragmentShader = fs.readFileSync(fragmentShaderPath, "utf8");
|
|
81
|
+
|
|
82
|
+
// Version check
|
|
83
|
+
const versionsFound = [...fragmentShader.matchAll(/\/\/\s+\[Smart Filter Shader Version\]\s*=\s*(\d+)/g)].map(
|
|
84
|
+
(match) => match[1]
|
|
85
|
+
);
|
|
86
|
+
let version: number = 1;
|
|
87
|
+
if (versionsFound.length === 1 && versionsFound[0]) {
|
|
88
|
+
version = parseInt(versionsFound[0]);
|
|
89
|
+
}
|
|
90
|
+
console.log(`Shader version: ${version}`);
|
|
91
|
+
|
|
92
|
+
let fragmentShaderInfo: FragmentShaderInfo;
|
|
93
|
+
|
|
94
|
+
switch (version) {
|
|
95
|
+
case 1:
|
|
96
|
+
{
|
|
97
|
+
fragmentShaderInfo = processFragmentShaderV1(fragmentShader);
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
default: {
|
|
101
|
+
throw new Error(`Unsupported shader version: ${version}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Write the shader TS file
|
|
106
|
+
const shaderFile = fragmentShaderPath.replace(".fragment.glsl", ".shader.ts");
|
|
107
|
+
const finalContents = ShaderTemplate.replace(VERTEX_SHADER, vertexShader ? `\`${vertexShader}\`` : "undefined")
|
|
108
|
+
.replace(TYPE_IMPORT_PATH, importPath)
|
|
109
|
+
.replace(UNIFORMS, "\n" + addLinePrefixes(fragmentShaderInfo.finalUniforms.join("\n"), UniformLinePrefix))
|
|
110
|
+
.replace(MAIN_FUNCTION_NAME, fragmentShaderInfo.mainFunctionName)
|
|
111
|
+
.replace(MAIN_INPUT_NAME, fragmentShaderInfo.mainInputName)
|
|
112
|
+
.replace(
|
|
113
|
+
CONSTS_PROPERTY,
|
|
114
|
+
fragmentShaderInfo.finalConsts.length > 0
|
|
115
|
+
? ConstsTemplate.replace(
|
|
116
|
+
CONSTS_VALUE,
|
|
117
|
+
addLinePrefixes(fragmentShaderInfo.finalConsts.join("\n"), ConstLinePrefix)
|
|
118
|
+
)
|
|
119
|
+
: ""
|
|
120
|
+
)
|
|
121
|
+
.replace(FUNCTIONS, fragmentShaderInfo.extractedFunctions.join(""))
|
|
122
|
+
.replace(UNIFORM_NAMES, addLinePrefixes(fragmentShaderInfo.uniformNames.join("\n"), UniformNameLinePrefix));
|
|
123
|
+
|
|
124
|
+
fs.writeFileSync(shaderFile, finalContents);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Information about a fragment shader
|
|
129
|
+
*/
|
|
130
|
+
type FragmentShaderInfo = {
|
|
131
|
+
/**
|
|
132
|
+
* The lines of code which declare the uniforms
|
|
133
|
+
*/
|
|
134
|
+
finalUniforms: (string | undefined)[];
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The main function name
|
|
138
|
+
*/
|
|
139
|
+
mainFunctionName: string;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The main input name
|
|
143
|
+
*/
|
|
144
|
+
mainInputName: string;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The lines of code which declare the consts
|
|
148
|
+
*/
|
|
149
|
+
finalConsts: (string | undefined)[];
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* The lines of code which declare the functions
|
|
153
|
+
*/
|
|
154
|
+
extractedFunctions: string[];
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* The lines of code which declare the uniform names
|
|
158
|
+
*/
|
|
159
|
+
uniformNames: string[];
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Processes a fragment shader
|
|
164
|
+
* @param fragmentShader - The fragment shader to process
|
|
165
|
+
* @returns The processed fragment shader
|
|
166
|
+
*/
|
|
167
|
+
function processFragmentShaderV1(fragmentShader: string): FragmentShaderInfo {
|
|
168
|
+
const fragmentShaderWithNoFunctionBodies = removeFunctionBodies(fragmentShader);
|
|
169
|
+
|
|
170
|
+
// Collect uniform, const, and function names which need to be decorated
|
|
171
|
+
// eslint-disable-next-line prettier/prettier
|
|
172
|
+
const uniforms = [...fragmentShader.matchAll(/\S*uniform.*\s(\w*);/g)].map((match) => match[1]);
|
|
173
|
+
console.log(`Uniforms found: ${JSON.stringify(uniforms)}`);
|
|
174
|
+
const consts = [...fragmentShader.matchAll(/\S*const\s+\w*\s+(\w*)\s*=.*;/g)].map((match) => match[1]);
|
|
175
|
+
console.log(`Consts found: ${JSON.stringify(consts)}`);
|
|
176
|
+
const functionNames = [...fragmentShaderWithNoFunctionBodies.matchAll(GetFunctionNamesRegEx)].map(
|
|
177
|
+
(match) => match[1]
|
|
178
|
+
);
|
|
179
|
+
console.log(`Functions found: ${JSON.stringify(functionNames)}`);
|
|
180
|
+
|
|
181
|
+
// Decorate the uniforms, consts, and functions
|
|
182
|
+
const symbolsToDecorate = [...uniforms, ...consts, ...functionNames];
|
|
183
|
+
let fragmentShaderWithRenamedSymbols = fragmentShader;
|
|
184
|
+
for (const symbol of symbolsToDecorate) {
|
|
185
|
+
const regex = new RegExp(`(\\S*(?:\\s|;|,|\\)|\\()+)${symbol}((\\s|;|,|\\)|\\()+)`, "gs");
|
|
186
|
+
fragmentShaderWithRenamedSymbols = fragmentShaderWithRenamedSymbols.replace(regex, `$1_${symbol}_$2`);
|
|
187
|
+
}
|
|
188
|
+
console.log(`${symbolsToDecorate.length} symbol(s) renamed`);
|
|
189
|
+
const uniformNames = uniforms.map((uniform) => `${uniform}: "${uniform}",`);
|
|
190
|
+
|
|
191
|
+
// Extract all the uniforms
|
|
192
|
+
const finalUniforms = [...fragmentShaderWithRenamedSymbols.matchAll(/^\s*(uniform\s.*)/gm)].map(
|
|
193
|
+
(match) => match[1]
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
// Extract all the consts
|
|
197
|
+
const finalConsts = [...fragmentShaderWithRenamedSymbols.matchAll(/^\s*(const\s.*)/gm)].map((match) => match[1]);
|
|
198
|
+
|
|
199
|
+
// Find the main input
|
|
200
|
+
const mainInputs = [...fragmentShaderWithRenamedSymbols.matchAll(/\S*uniform.*\s(\w*);\s*\/\/\s*main/gm)].map(
|
|
201
|
+
(match) => match[1]
|
|
202
|
+
);
|
|
203
|
+
if (mainInputs.length !== 1 || !mainInputs[0]) {
|
|
204
|
+
throw new Error("Exactly one main input must be defined in the shader");
|
|
205
|
+
}
|
|
206
|
+
const mainInputName = mainInputs[0];
|
|
207
|
+
|
|
208
|
+
// Extract all the functions
|
|
209
|
+
const { extractedFunctions, mainFunctionName } = extractFunctions(fragmentShaderWithRenamedSymbols, mainInputName);
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
finalUniforms,
|
|
213
|
+
mainFunctionName,
|
|
214
|
+
mainInputName,
|
|
215
|
+
finalConsts,
|
|
216
|
+
extractedFunctions,
|
|
217
|
+
uniformNames,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Prefixes each line in the input
|
|
223
|
+
* @param input - The input string
|
|
224
|
+
* @param prefix - The prefix to add to each line
|
|
225
|
+
* @returns The input with each line prefixed
|
|
226
|
+
*/
|
|
227
|
+
function addLinePrefixes(input: string, prefix: string): string {
|
|
228
|
+
return input
|
|
229
|
+
.split("\n")
|
|
230
|
+
.map((line) => prefix + line)
|
|
231
|
+
.join("\n");
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Extracts all the functions from the shader
|
|
236
|
+
* @param fragment - The shader code to process
|
|
237
|
+
* @param mainInputName - The name of the main input
|
|
238
|
+
* @returns A list of functions
|
|
239
|
+
*/
|
|
240
|
+
function extractFunctions(
|
|
241
|
+
fragment: string,
|
|
242
|
+
mainInputName: string
|
|
243
|
+
): {
|
|
244
|
+
/**
|
|
245
|
+
* The extracted functions
|
|
246
|
+
*/
|
|
247
|
+
extractedFunctions: string[];
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* The name of the main function
|
|
251
|
+
*/
|
|
252
|
+
mainFunctionName: string;
|
|
253
|
+
} {
|
|
254
|
+
const lines = fragment.split("\n");
|
|
255
|
+
const extractedFunctions: string[] = [];
|
|
256
|
+
let mainFunctionName: string | undefined;
|
|
257
|
+
let inFunction = false;
|
|
258
|
+
let depth = 0;
|
|
259
|
+
let currentFunction = "";
|
|
260
|
+
|
|
261
|
+
for (const line of lines) {
|
|
262
|
+
if (!inFunction && line.includes("{")) {
|
|
263
|
+
inFunction = true;
|
|
264
|
+
}
|
|
265
|
+
if (inFunction) {
|
|
266
|
+
currentFunction += line + "\n";
|
|
267
|
+
}
|
|
268
|
+
for (let pos = 0; pos < line.length; pos++) {
|
|
269
|
+
if (line[pos] === "{") {
|
|
270
|
+
depth++;
|
|
271
|
+
} else if (line[pos] === "}") {
|
|
272
|
+
depth--;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (inFunction && depth === 0) {
|
|
276
|
+
inFunction = false;
|
|
277
|
+
const { functionBody, functionName, isMainFunction } = processFunctionBody(currentFunction);
|
|
278
|
+
|
|
279
|
+
let body = functionBody;
|
|
280
|
+
if (isMainFunction) {
|
|
281
|
+
body = functionBody.replace("{", `{\n if (_disabled_) return texture2D(${mainInputName}, vUV);\n`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
extractedFunctions.push(
|
|
285
|
+
FunctionTemplate.replace(FUNCTION_NAME, functionName).replace(
|
|
286
|
+
FUNCTION_CODE,
|
|
287
|
+
addLinePrefixes(body, CodeLinePrefix)
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
if (isMainFunction) {
|
|
291
|
+
if (mainFunctionName) {
|
|
292
|
+
throw new Error("Multiple main functions found in shader code");
|
|
293
|
+
}
|
|
294
|
+
mainFunctionName = functionName;
|
|
295
|
+
}
|
|
296
|
+
currentFunction = "";
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (!mainFunctionName) {
|
|
301
|
+
throw new Error("No main function found in shader code");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return { extractedFunctions, mainFunctionName };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Creates code for a ShaderFunction instance from the body of a function
|
|
309
|
+
* @param functionBody - The body of the function
|
|
310
|
+
* @returns The body, name, and whether the function is the main function
|
|
311
|
+
*/
|
|
312
|
+
function processFunctionBody(functionBody: string): {
|
|
313
|
+
/**
|
|
314
|
+
* The body of the function
|
|
315
|
+
*/
|
|
316
|
+
functionBody: string;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* The name of the function
|
|
320
|
+
*/
|
|
321
|
+
functionName: string;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Whether the function is the main function
|
|
325
|
+
*/
|
|
326
|
+
isMainFunction: boolean;
|
|
327
|
+
} {
|
|
328
|
+
// Extract the function name
|
|
329
|
+
const functionNamesFound = [...functionBody.matchAll(GetFunctionNamesRegEx)].map((match) => match[1]);
|
|
330
|
+
const functionName = functionNamesFound[0];
|
|
331
|
+
if (!functionName) {
|
|
332
|
+
throw new Error("No function name found in shader code");
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const isMainFunction = functionBody.includes("// main");
|
|
336
|
+
|
|
337
|
+
return { functionBody, functionName, isMainFunction };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Removes all function bodies from the shader code, leaving just curly braces behind at the top level
|
|
342
|
+
* @param input - The shader code to process
|
|
343
|
+
* @returns The shader code with all function bodies removed
|
|
344
|
+
*/
|
|
345
|
+
function removeFunctionBodies(input: string): string {
|
|
346
|
+
let output: string = "";
|
|
347
|
+
let depth: number = 0;
|
|
348
|
+
|
|
349
|
+
for (let pos = 0; pos < input.length; pos++) {
|
|
350
|
+
if (input[pos] === "{") {
|
|
351
|
+
depth++;
|
|
352
|
+
// Special case - if we just hit the first { then include it
|
|
353
|
+
if (depth === 1) {
|
|
354
|
+
output += "{";
|
|
355
|
+
}
|
|
356
|
+
} else if (input[pos] === "}") {
|
|
357
|
+
depth--;
|
|
358
|
+
// Special case - if we just hit the last } then include it
|
|
359
|
+
if (depth === 0) {
|
|
360
|
+
output += "}";
|
|
361
|
+
}
|
|
362
|
+
} else if (depth === 0) {
|
|
363
|
+
output += input[pos];
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (depth !== 0) {
|
|
368
|
+
console.error("Unbalanced curly braces in shader code");
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return output;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Converts .fragment.glsl and vertex.glsl file pairs into .shader.ts files which export a ShaderProgram object.
|
|
376
|
+
* @param shaderPath - The path to the .glsl files to convert.
|
|
377
|
+
* @param importPath - The path to import the ShaderProgram type from.
|
|
378
|
+
*/
|
|
379
|
+
function convertShaders(shaderPath: string, importPath: string) {
|
|
380
|
+
// Get all files in the path
|
|
381
|
+
const allFiles = fs.readdirSync(shaderPath, { withFileTypes: true, recursive: true });
|
|
382
|
+
|
|
383
|
+
// Find all fragment shaders (excluding the template)
|
|
384
|
+
const fragmentShaderFiles = allFiles.filter(
|
|
385
|
+
(file) => file.isFile() && file.name.endsWith(".fragment.glsl") && !file.name.endsWith("template.fragment.glsl")
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
// Convert all shaders
|
|
389
|
+
for (const fragmentShaderFile of fragmentShaderFiles) {
|
|
390
|
+
convertShader(path.join(fragmentShaderFile.path, fragmentShaderFile.name), importPath);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const externalArguments = process.argv.slice(2);
|
|
395
|
+
if (externalArguments.length >= 2 && externalArguments[0] && externalArguments[1]) {
|
|
396
|
+
convertShaders(externalArguments[0], externalArguments[1]);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// TODO: simple copy from shader file to .ts, get it to build (including import trick)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { exec, type ExecException } from "child_process";
|
|
3
|
+
import { compareVersions, determineVersion, getNpmVersion, type VersionType } from "./determineVersion.js";
|
|
4
|
+
import type { Nullable } from "@babylonjs/core/types.js";
|
|
5
|
+
|
|
6
|
+
const alpha = process.argv.includes("--alpha");
|
|
7
|
+
const packageText = fs.readFileSync("package.json");
|
|
8
|
+
const packageJSON = JSON.parse(packageText.toString());
|
|
9
|
+
|
|
10
|
+
const packageName = packageJSON.name;
|
|
11
|
+
console.log("Processing package:", packageName);
|
|
12
|
+
console.log("Alpha flag:", alpha);
|
|
13
|
+
console.log("Current package.json version:", packageJSON.version);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Queries the NPM registry for the specified version type
|
|
17
|
+
* @param versionType - The type of version to query
|
|
18
|
+
* @param callback - The callback to call with the NPM version
|
|
19
|
+
*/
|
|
20
|
+
function queryNpmFeed(versionType: VersionType, callback: (npmVersion: Nullable<string>) => void) {
|
|
21
|
+
exec(`npm view ${packageName} dist-tags.${versionType}`, (err: Nullable<ExecException>, stdout) => {
|
|
22
|
+
let npmVersion = getNpmVersion(versionType, err, stdout);
|
|
23
|
+
if (npmVersion !== null) {
|
|
24
|
+
npmVersion = npmVersion.trim();
|
|
25
|
+
console.log(`NPM Registry ${versionType} version:`, npmVersion);
|
|
26
|
+
}
|
|
27
|
+
callback(npmVersion);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
queryNpmFeed("preview", (npmPreviewVersion) => {
|
|
32
|
+
queryNpmFeed("latest", (npmLatestVersion) => {
|
|
33
|
+
let highestNpmVersion: Nullable<string> = npmLatestVersion;
|
|
34
|
+
if (npmPreviewVersion && (!highestNpmVersion || compareVersions(npmPreviewVersion, highestNpmVersion) === 1)) {
|
|
35
|
+
highestNpmVersion = npmPreviewVersion;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log("Highest NPM Registry version:", highestNpmVersion);
|
|
39
|
+
|
|
40
|
+
const versionToUse = determineVersion(highestNpmVersion, packageJSON.version, alpha);
|
|
41
|
+
|
|
42
|
+
console.log("Version to use:", versionToUse);
|
|
43
|
+
|
|
44
|
+
if (packageJSON.version !== versionToUse) {
|
|
45
|
+
packageJSON.version = versionToUse;
|
|
46
|
+
fs.writeFileSync("package.json", JSON.stringify(packageJSON, null, 4));
|
|
47
|
+
console.log("Version updated in package.json");
|
|
48
|
+
} else {
|
|
49
|
+
console.log("No need to update package.json");
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ThinTexture } from "@babylonjs/core/Materials/Textures/thinTexture.js";
|
|
2
2
|
import { type ThinEngine } from "@babylonjs/core/Engines/thinEngine.js";
|
|
3
|
+
import type { Nullable } from "@babylonjs/core/types";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Helper that takes in a URL to an image and returns a ThinTexture
|
|
@@ -9,15 +10,29 @@ import { type ThinEngine } from "@babylonjs/core/Engines/thinEngine.js";
|
|
|
9
10
|
* * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
|
|
10
11
|
* @param flipY - Indicates if the Y axis should be flipped
|
|
11
12
|
* @param samplingMode - The sampling mode to use
|
|
13
|
+
* @param forcedExtension - defines the extension to use to pick the right loader
|
|
12
14
|
* @returns A ThinTexture of the image
|
|
13
15
|
*/
|
|
14
16
|
export function createImageTexture(
|
|
15
17
|
engine: ThinEngine,
|
|
16
18
|
url: string,
|
|
17
|
-
flipY: boolean =
|
|
18
|
-
samplingMode: number | undefined = undefined
|
|
19
|
+
flipY: Nullable<boolean> = null,
|
|
20
|
+
samplingMode: number | undefined = undefined,
|
|
21
|
+
forcedExtension: string | null = null
|
|
19
22
|
): ThinTexture {
|
|
20
|
-
const internalTexture = engine.createTexture(
|
|
23
|
+
const internalTexture = engine.createTexture(
|
|
24
|
+
url,
|
|
25
|
+
true,
|
|
26
|
+
flipY ?? true,
|
|
27
|
+
null,
|
|
28
|
+
samplingMode,
|
|
29
|
+
null,
|
|
30
|
+
null,
|
|
31
|
+
null,
|
|
32
|
+
null,
|
|
33
|
+
null,
|
|
34
|
+
forcedExtension
|
|
35
|
+
);
|
|
21
36
|
return new ThinTexture(internalTexture);
|
|
22
37
|
}
|
|
23
38
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper class used to generate IDs unique to the current session
|
|
3
|
+
*/
|
|
4
|
+
export class UniqueIdGenerator {
|
|
5
|
+
/**
|
|
6
|
+
* The next unique ID to be returned
|
|
7
|
+
*/
|
|
8
|
+
public static _NextUniqueId = 1;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Gets a unique (relatively to the current session) Id
|
|
12
|
+
*/
|
|
13
|
+
public static get UniqueId() {
|
|
14
|
+
const result = this._NextUniqueId;
|
|
15
|
+
this._NextUniqueId++;
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Ensures future generated IDs are greater than the specified value
|
|
21
|
+
* @param minimum - The minimum value that future generated IDs should be greater than
|
|
22
|
+
*/
|
|
23
|
+
public static EnsureIdsGreaterThan(minimum: number): void {
|
|
24
|
+
if (this._NextUniqueId <= minimum) {
|
|
25
|
+
this._NextUniqueId = minimum + 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|