glre 0.38.0 → 0.40.0
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/README.md +8 -4
- package/dist/addons.cjs +2 -0
- package/dist/addons.cjs.map +1 -0
- package/dist/addons.d.ts +1287 -0
- package/dist/addons.js +2 -0
- package/dist/addons.js.map +1 -0
- package/dist/index.cjs +31 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +187 -323
- package/dist/index.js +31 -43
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +1 -48
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.ts +536 -10
- package/dist/native.js +1 -48
- package/dist/native.js.map +1 -1
- package/dist/node.cjs +69 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.ts +626 -0
- package/dist/node.js +69 -0
- package/dist/node.js.map +1 -0
- package/dist/react.cjs +1 -48
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +524 -4
- package/dist/react.js +1 -48
- package/dist/react.js.map +1 -1
- package/dist/solid.cjs +1 -48
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.d.ts +524 -4
- package/dist/solid.js +1 -48
- package/dist/solid.js.map +1 -1
- package/package.json +64 -11
- package/src/addons/animation/easing/backIn.ts +10 -0
- package/src/addons/animation/easing/backInOut.ts +12 -0
- package/src/addons/animation/easing/backOut.ts +10 -0
- package/src/addons/animation/easing/bounceIn.ts +10 -0
- package/src/addons/animation/easing/bounceInOut.ts +13 -0
- package/src/addons/animation/easing/bounceOut.ts +30 -0
- package/src/addons/animation/easing/circularIn.ts +9 -0
- package/src/addons/animation/easing/circularInOut.ts +11 -0
- package/src/addons/animation/easing/circularOut.ts +9 -0
- package/src/addons/animation/easing/cubicIn.ts +9 -0
- package/src/addons/animation/easing/cubicInOut.ts +11 -0
- package/src/addons/animation/easing/cubicOut.ts +10 -0
- package/src/addons/animation/easing/elasticIn.ts +10 -0
- package/src/addons/animation/easing/elasticInOut.ts +21 -0
- package/src/addons/animation/easing/elasticOut.ts +12 -0
- package/src/addons/animation/easing/exponentialIn.ts +9 -0
- package/src/addons/animation/easing/exponentialInOut.ts +13 -0
- package/src/addons/animation/easing/exponentialOut.ts +9 -0
- package/src/addons/animation/easing/index.ts +33 -0
- package/src/addons/animation/easing/linearIn.ts +9 -0
- package/src/addons/animation/easing/linearInOut.ts +9 -0
- package/src/addons/animation/easing/linearOut.ts +9 -0
- package/src/addons/animation/easing/quadraticIn.ts +9 -0
- package/src/addons/animation/easing/quadraticInOut.ts +10 -0
- package/src/addons/animation/easing/quadraticOut.ts +9 -0
- package/src/addons/animation/easing/quarticIn.ts +9 -0
- package/src/addons/animation/easing/quarticInOut.ts +11 -0
- package/src/addons/animation/easing/quarticOut.ts +10 -0
- package/src/addons/animation/easing/quinticIn.ts +9 -0
- package/src/addons/animation/easing/quinticInOut.ts +11 -0
- package/src/addons/animation/easing/quinticOut.ts +9 -0
- package/src/addons/animation/easing/sineIn.ts +10 -0
- package/src/addons/animation/easing/sineInOut.ts +10 -0
- package/src/addons/animation/easing/sineOut.ts +10 -0
- package/src/addons/color/palette/macbeth.ts +42 -0
- package/src/addons/color/space/cmyk2rgb.ts +12 -0
- package/src/addons/color/space/gamma2linear.ts +19 -0
- package/src/addons/color/space/hsl2rgb.ts +20 -0
- package/src/addons/color/space/hsv2rgb.ts +18 -0
- package/src/addons/color/space/hue2rgb.ts +12 -0
- package/src/addons/color/space/index.ts +29 -0
- package/src/addons/color/space/lab2lch.ts +22 -0
- package/src/addons/color/space/lab2rgb.ts +19 -0
- package/src/addons/color/space/lab2xyz.ts +32 -0
- package/src/addons/color/space/lch2lab.ts +21 -0
- package/src/addons/color/space/lch2rgb.ts +22 -0
- package/src/addons/color/space/linear2gamma.ts +19 -0
- package/src/addons/color/space/oklab2rgb.ts +35 -0
- package/src/addons/color/space/rgb2cmyk.ts +13 -0
- package/src/addons/color/space/rgb2hcv.ts +29 -0
- package/src/addons/color/space/rgb2hsl.ts +23 -0
- package/src/addons/color/space/rgb2hsv.ts +36 -0
- package/src/addons/color/space/rgb2hue.ts +29 -0
- package/src/addons/color/space/rgb2lab.ts +19 -0
- package/src/addons/color/space/rgb2lch.ts +22 -0
- package/src/addons/color/space/rgb2oklab.ts +45 -0
- package/src/addons/color/space/rgb2srgb.ts +34 -0
- package/src/addons/color/space/rgb2xyz.ts +20 -0
- package/src/addons/color/space/rgb2yiq.ts +22 -0
- package/src/addons/color/space/rgb2yuv.ts +32 -0
- package/src/addons/color/space/srgb2rgb.ts +34 -0
- package/src/addons/color/space/xyz2lab.ts +27 -0
- package/src/addons/color/space/xyz2rgb.ts +30 -0
- package/src/addons/color/space/yiq2rgb.ts +22 -0
- package/src/addons/color/space/yuv2rgb.ts +32 -0
- package/src/addons/draw/arrows.ts +75 -0
- package/src/addons/draw/axis.ts +57 -0
- package/src/addons/draw/bridge.ts +81 -0
- package/src/addons/draw/char.ts +30 -0
- package/src/addons/draw/circle.ts +29 -0
- package/src/addons/draw/fill.ts +25 -0
- package/src/addons/draw/flip.ts +45 -0
- package/src/addons/draw/hex.ts +29 -0
- package/src/addons/draw/index.ts +13 -0
- package/src/addons/draw/line.ts +16 -0
- package/src/addons/draw/point.ts +30 -0
- package/src/addons/draw/rect.ts +52 -0
- package/src/addons/draw/stroke.ts +31 -0
- package/src/addons/draw/tri.ts +29 -0
- package/src/addons/generative/cnoise.ts +239 -0
- package/src/addons/generative/curl.ts +64 -0
- package/src/addons/generative/fbm.ts +69 -0
- package/src/addons/generative/gerstnerWave.ts +21 -0
- package/src/addons/generative/gnoise.ts +113 -0
- package/src/addons/generative/index.ts +15 -0
- package/src/addons/generative/noised.ts +139 -0
- package/src/addons/generative/pnoise.ts +249 -0
- package/src/addons/generative/psrdnoise.ts +277 -0
- package/src/addons/generative/random.ts +136 -0
- package/src/addons/generative/snoise.ts +199 -0
- package/src/addons/generative/srandom.ts +90 -0
- package/src/addons/generative/voronoi.ts +134 -0
- package/src/addons/generative/voronoise.ts +69 -0
- package/src/addons/generative/wavelet.ts +77 -0
- package/src/addons/generative/worley.ts +99 -0
- package/src/addons/geometry/aabb/aabb.ts +8 -0
- package/src/addons/geometry/aabb/centroid.ts +10 -0
- package/src/addons/geometry/aabb/contain.ts +19 -0
- package/src/addons/geometry/aabb/diagonal.ts +10 -0
- package/src/addons/geometry/aabb/expand.ts +16 -0
- package/src/addons/geometry/aabb/index.ts +7 -0
- package/src/addons/geometry/aabb/intersect.ts +20 -0
- package/src/addons/geometry/aabb/square.ts +17 -0
- package/src/addons/geometry/index.ts +2 -0
- package/src/addons/geometry/triangle/area.ts +10 -0
- package/src/addons/geometry/triangle/barycentric.ts +50 -0
- package/src/addons/geometry/triangle/centroid.ts +10 -0
- package/src/addons/geometry/triangle/closestPoint.ts +85 -0
- package/src/addons/geometry/triangle/contain.ts +19 -0
- package/src/addons/geometry/triangle/distanceSq.ts +38 -0
- package/src/addons/geometry/triangle/index.ts +10 -0
- package/src/addons/geometry/triangle/intersect.ts +49 -0
- package/src/addons/geometry/triangle/normal.ts +12 -0
- package/src/addons/geometry/triangle/signedDistance.ts +31 -0
- package/src/addons/geometry/triangle/triangle.ts +9 -0
- package/src/addons/index.ts +8 -0
- package/src/addons/lighting/ray.ts +8 -0
- package/src/addons/math/aafloor.ts +13 -0
- package/src/addons/math/aafract.ts +38 -0
- package/src/addons/math/aamirror.ts +12 -0
- package/src/addons/math/aastep.ts +14 -0
- package/src/addons/math/absi.ts +9 -0
- package/src/addons/math/adaptiveThreshold.ts +24 -0
- package/src/addons/math/bump.ts +20 -0
- package/src/addons/math/const.ts +19 -0
- package/src/addons/math/cubic.ts +101 -0
- package/src/addons/math/cubicMix.ts +49 -0
- package/src/addons/math/decimate.ts +12 -0
- package/src/addons/math/dist.ts +143 -0
- package/src/addons/math/fcos.ts +11 -0
- package/src/addons/math/frac.ts +9 -0
- package/src/addons/math/gain.ts +14 -0
- package/src/addons/math/gaussian.ts +14 -0
- package/src/addons/math/grad4.ts +19 -0
- package/src/addons/math/hammersley.ts +54 -0
- package/src/addons/math/highPass.ts +12 -0
- package/src/addons/math/index.ts +63 -0
- package/src/addons/math/inside.ts +68 -0
- package/src/addons/math/invCubic.ts +9 -0
- package/src/addons/math/invQuartic.ts +9 -0
- package/src/addons/math/inverse.ts +9 -0
- package/src/addons/math/lengthSq.ts +10 -0
- package/src/addons/math/map.ts +27 -0
- package/src/addons/math/mirror.ts +12 -0
- package/src/addons/math/mmax.ts +27 -0
- package/src/addons/math/mmin.ts +28 -0
- package/src/addons/math/mmix.ts +47 -0
- package/src/addons/math/mod2.ts +44 -0
- package/src/addons/math/mod289.ts +46 -0
- package/src/addons/math/modi.ts +15 -0
- package/src/addons/math/nyquist.ts +15 -0
- package/src/addons/math/pack.ts +15 -0
- package/src/addons/math/parabola.ts +12 -0
- package/src/addons/math/permute.ts +42 -0
- package/src/addons/math/pow2.ts +10 -0
- package/src/addons/math/pow3.ts +9 -0
- package/src/addons/math/pow5.ts +10 -0
- package/src/addons/math/pow7.ts +12 -0
- package/src/addons/math/powFast.ts +18 -0
- package/src/addons/math/quartic.ts +15 -0
- package/src/addons/math/quat/index.ts +14 -0
- package/src/addons/math/quat/quat2mat3.ts +28 -0
- package/src/addons/math/quat/quat2mat4.ts +16 -0
- package/src/addons/math/quat/quatAdd.ts +18 -0
- package/src/addons/math/quat/quatConj.ts +14 -0
- package/src/addons/math/quat/quatDiv.ts +18 -0
- package/src/addons/math/quat/quatIdentity.ts +9 -0
- package/src/addons/math/quat/quatInverse.ts +17 -0
- package/src/addons/math/quat/quatLength.ts +15 -0
- package/src/addons/math/quat/quatLengthSq.ts +14 -0
- package/src/addons/math/quat/quatLerp.ts +40 -0
- package/src/addons/math/quat/quatMul.ts +38 -0
- package/src/addons/math/quat/quatNeg.ts +14 -0
- package/src/addons/math/quat/quatNorm.ts +16 -0
- package/src/addons/math/quat/quatSub.ts +18 -0
- package/src/addons/math/quintic.ts +16 -0
- package/src/addons/math/rotate2d.ts +16 -0
- package/src/addons/math/rotate3d.ts +37 -0
- package/src/addons/math/rotate3dX.ts +20 -0
- package/src/addons/math/rotate3dY.ts +20 -0
- package/src/addons/math/rotate3dZ.ts +20 -0
- package/src/addons/math/rotate4d.ts +41 -0
- package/src/addons/math/rotate4dX.ts +21 -0
- package/src/addons/math/rotate4dY.ts +16 -0
- package/src/addons/math/rotate4dZ.ts +21 -0
- package/src/addons/math/saturateMediump.ts +11 -0
- package/src/addons/math/scale2d.ts +44 -0
- package/src/addons/math/scale3d.ts +17 -0
- package/src/addons/math/scale4d.ts +50 -0
- package/src/addons/math/smootherstep.ts +16 -0
- package/src/addons/math/taylorInvSqrt.ts +9 -0
- package/src/addons/math/toMat3.ts +14 -0
- package/src/addons/math/toMat4.ts +14 -0
- package/src/addons/math/translate4d.ts +31 -0
- package/src/addons/math/unpack.ts +88 -0
- package/src/addons/sdf/boxSDF.ts +24 -0
- package/src/addons/sdf/circleSDF.ts +20 -0
- package/src/addons/sdf/crossSDF.ts +17 -0
- package/src/addons/sdf/hexSDF.ts +18 -0
- package/src/addons/sdf/index.ts +7 -0
- package/src/addons/sdf/lineSDF.ts +33 -0
- package/src/addons/sdf/rectSDF.ts +46 -0
- package/src/addons/sdf/sphereSDF.ts +20 -0
- package/src/addons/sdf/triSDF.ts +14 -0
- package/src/addons/space/aspect.ts +14 -0
- package/src/addons/space/bracketing.ts +44 -0
- package/src/addons/space/brickTile.ts +44 -0
- package/src/addons/space/cart2polar.ts +20 -0
- package/src/addons/space/center.ts +32 -0
- package/src/addons/space/checkerTile.ts +41 -0
- package/src/addons/space/depth2viewZ.ts +43 -0
- package/src/addons/space/displace.ts +55 -0
- package/src/addons/space/equirect2xyz.ts +17 -0
- package/src/addons/space/eulerView.ts +19 -0
- package/src/addons/space/fisheye2xyz.ts +18 -0
- package/src/addons/space/flipY.ts +25 -0
- package/src/addons/space/hexTile.ts +18 -0
- package/src/addons/space/index.ts +38 -0
- package/src/addons/space/kaleidoscope.ts +48 -0
- package/src/addons/space/linearizeDepth.ts +17 -0
- package/src/addons/space/lookAt.ts +49 -0
- package/src/addons/space/lookAtView.ts +40 -0
- package/src/addons/space/mirrorTile.ts +73 -0
- package/src/addons/space/nearest.ts +13 -0
- package/src/addons/space/orthographic.ts +25 -0
- package/src/addons/space/parallaxMapping.ts +149 -0
- package/src/addons/space/perspective.ts +24 -0
- package/src/addons/space/polar2cart.ts +24 -0
- package/src/addons/space/ratio.ts +14 -0
- package/src/addons/space/rotate.ts +37 -0
- package/src/addons/space/rotateX.ts +54 -0
- package/src/addons/space/rotateY.ts +54 -0
- package/src/addons/space/rotateZ.ts +54 -0
- package/src/addons/space/scale.ts +13 -0
- package/src/addons/space/sprite.ts +16 -0
- package/src/addons/space/sqTile.ts +20 -0
- package/src/addons/space/tbn.ts +26 -0
- package/src/addons/space/translate.ts +12 -0
- package/src/addons/space/triTile.ts +32 -0
- package/src/addons/space/uncenter.ts +32 -0
- package/src/addons/space/unratio.ts +12 -0
- package/src/addons/space/viewZ2depth.ts +25 -0
- package/src/addons/space/windmillTile.ts +58 -0
- package/src/addons/space/xyz2equirect.ts +10 -0
- package/src/index.ts +10 -23
- package/src/node/build.ts +127 -0
- package/src/node/create.ts +76 -0
- package/src/node/index.ts +64 -49
- package/src/node/scope.ts +66 -62
- package/src/node/types.ts +221 -187
- package/src/node/utils/const.ts +74 -13
- package/src/node/utils/index.ts +19 -14
- package/src/node/utils/infer.ts +32 -34
- package/src/node/utils/parse.ts +48 -24
- package/src/node/utils/utils.ts +52 -29
- package/src/types.ts +11 -6
- package/src/utils/helpers.ts +56 -0
- package/src/utils/pipeline.ts +24 -8
- package/src/utils/program.ts +62 -38
- package/src/{webgl.ts → utils/webgl.ts} +46 -30
- package/src/{webgpu.ts → utils/webgpu.ts} +22 -17
- package/src/node/core.ts +0 -121
- package/src/node/node.ts +0 -65
package/src/node/utils/const.ts
CHANGED
|
@@ -3,20 +3,20 @@ export const SWIZZLES = ['x', 'y', 'z', 'w', 'r', 'g', 'b', 'a', 's', 't', 'p',
|
|
|
3
3
|
// Unified order with TYPE_MAPPING array
|
|
4
4
|
export const CONVERSIONS = [
|
|
5
5
|
'toBool',
|
|
6
|
-
'
|
|
6
|
+
'toUInt',
|
|
7
7
|
'toInt',
|
|
8
8
|
'toFloat',
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
9
|
+
'toBVec2',
|
|
10
|
+
'toIVec2',
|
|
11
|
+
'toUVec2',
|
|
12
12
|
'toVec2',
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
13
|
+
'toBVec3',
|
|
14
|
+
'toIVec3',
|
|
15
|
+
'toUVec3',
|
|
16
16
|
'toVec3',
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
17
|
+
'toBVec4',
|
|
18
|
+
'toIVec4',
|
|
19
|
+
'toUVec4',
|
|
20
20
|
'toVec4',
|
|
21
21
|
'toColor',
|
|
22
22
|
'toMat2',
|
|
@@ -73,6 +73,16 @@ export const OPERATORS = {
|
|
|
73
73
|
bitXor: '^',
|
|
74
74
|
shiftLeft: '<<',
|
|
75
75
|
shiftRight: '>>',
|
|
76
|
+
addAssign: '+=',
|
|
77
|
+
subAssign: '-=',
|
|
78
|
+
mulAssign: '*=',
|
|
79
|
+
divAssign: '/=',
|
|
80
|
+
modAssign: '%=',
|
|
81
|
+
bitAndAssign: '&=',
|
|
82
|
+
bitOrAssign: '|=',
|
|
83
|
+
bitXorAssign: '^=',
|
|
84
|
+
shiftLeftAssign: '<<=',
|
|
85
|
+
shiftRightAssign: '>>=',
|
|
76
86
|
} as const
|
|
77
87
|
|
|
78
88
|
export const OPERATOR_KEYS = Object.keys(OPERATORS) as (keyof typeof OPERATORS)[]
|
|
@@ -135,6 +145,28 @@ export const COMPARISON_OPERATORS = [
|
|
|
135
145
|
|
|
136
146
|
export const LOGICAL_OPERATORS = ['and', 'or'] as const
|
|
137
147
|
|
|
148
|
+
// Operator type rules [L, R, Result] format (no duplicates, same-type handled by logic)
|
|
149
|
+
export const OPERATOR_TYPE_RULES = [
|
|
150
|
+
// Scalar broadcast operations (result follows vector type)
|
|
151
|
+
['float', 'vec2', 'vec2'],
|
|
152
|
+
['float', 'vec3', 'vec3'],
|
|
153
|
+
['float', 'vec4', 'vec4'],
|
|
154
|
+
['int', 'ivec2', 'ivec2'],
|
|
155
|
+
['int', 'ivec3', 'ivec3'],
|
|
156
|
+
['int', 'ivec4', 'ivec4'],
|
|
157
|
+
['uint', 'uvec2', 'uvec2'],
|
|
158
|
+
['uint', 'uvec3', 'uvec3'],
|
|
159
|
+
['uint', 'uvec4', 'uvec4'],
|
|
160
|
+
// Matrix-vector operations (mat * vec → vec)
|
|
161
|
+
['mat2', 'vec2', 'vec2'],
|
|
162
|
+
['mat3', 'vec3', 'vec3'],
|
|
163
|
+
['mat4', 'vec4', 'vec4'],
|
|
164
|
+
// Vector-matrix operations (vec * mat → vec)
|
|
165
|
+
['vec2', 'mat2', 'vec2'],
|
|
166
|
+
['vec3', 'mat3', 'vec3'],
|
|
167
|
+
['vec4', 'mat4', 'vec4'],
|
|
168
|
+
] as const
|
|
169
|
+
|
|
138
170
|
export const WGSL_TO_GLSL_BUILTIN = {
|
|
139
171
|
position: 'gl_FragCoord',
|
|
140
172
|
vertex_index: 'gl_VertexID',
|
|
@@ -150,7 +182,7 @@ export const WGSL_TO_GLSL_BUILTIN = {
|
|
|
150
182
|
/**
|
|
151
183
|
* 2.1. unified with:
|
|
152
184
|
* 1.1. index.ts functions and
|
|
153
|
-
* 3.1. types.ts
|
|
185
|
+
* 3.1. types.ts _N
|
|
154
186
|
*/
|
|
155
187
|
// Function return type mapping for method chaining
|
|
156
188
|
export const FUNCTION_RETURN_TYPES = {
|
|
@@ -176,7 +208,7 @@ export const FUNCTION_RETURN_TYPES = {
|
|
|
176
208
|
/**
|
|
177
209
|
* 2.2. unified with:
|
|
178
210
|
* 1.2. index.ts functions and
|
|
179
|
-
* 3.2. types.ts
|
|
211
|
+
* 3.2. types.ts _N
|
|
180
212
|
*/
|
|
181
213
|
// All shader functions (type inference now handled by inferFrom)
|
|
182
214
|
export const FUNCTIONS = [
|
|
@@ -200,6 +232,7 @@ export const FUNCTIONS = [
|
|
|
200
232
|
'floor',
|
|
201
233
|
'fract',
|
|
202
234
|
'fwidth',
|
|
235
|
+
'inverse',
|
|
203
236
|
'inverseSqrt',
|
|
204
237
|
'log',
|
|
205
238
|
'log2',
|
|
@@ -209,7 +242,6 @@ export const FUNCTIONS = [
|
|
|
209
242
|
'radians',
|
|
210
243
|
'reciprocal',
|
|
211
244
|
'round',
|
|
212
|
-
'saturate',
|
|
213
245
|
'sign',
|
|
214
246
|
'sin',
|
|
215
247
|
'sinh',
|
|
@@ -217,6 +249,7 @@ export const FUNCTIONS = [
|
|
|
217
249
|
'tan',
|
|
218
250
|
'tanh',
|
|
219
251
|
'trunc',
|
|
252
|
+
'saturate',
|
|
220
253
|
// 1. Functions where first argument determines return type
|
|
221
254
|
'atan2',
|
|
222
255
|
'clamp',
|
|
@@ -231,3 +264,31 @@ export const FUNCTIONS = [
|
|
|
231
264
|
'step',
|
|
232
265
|
// @NOTE: mod is operator
|
|
233
266
|
] as const
|
|
267
|
+
|
|
268
|
+
// Check if two types are the same (for same-type operations)
|
|
269
|
+
const isSameType = (L: string, R: string): boolean => L === R
|
|
270
|
+
|
|
271
|
+
// Check if combination exists in rules (handles bidirectional matching)
|
|
272
|
+
const isValidCombination = (L: string, R: string): boolean => {
|
|
273
|
+
return OPERATOR_TYPE_RULES.some(
|
|
274
|
+
([left, right, _]) => (left === L && right === R) || (left === R && right === L)
|
|
275
|
+
)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Type constraint validation for operators ([L, R, Result] format)
|
|
279
|
+
export const validateOperatorTypes = (L: string, R: string, op: string): boolean => {
|
|
280
|
+
if (COMPARISON_OPERATORS.includes(op as any) || LOGICAL_OPERATORS.includes(op as any)) return isSameType(L, R)
|
|
281
|
+
if (isSameType(L, R)) return true
|
|
282
|
+
return isValidCombination(L, R)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Get result type for operator (used by inferOperator)
|
|
286
|
+
export const getOperatorResultType = (L: string, R: string, op: string): string => {
|
|
287
|
+
if (COMPARISON_OPERATORS.includes(op as any) || LOGICAL_OPERATORS.includes(op as any)) return 'bool'
|
|
288
|
+
// Same type operations return the same type
|
|
289
|
+
if (isSameType(L, R)) return L
|
|
290
|
+
const rule = OPERATOR_TYPE_RULES.find(
|
|
291
|
+
([left, right, _]) => (left === L && right === R) || (left === R && right === L)
|
|
292
|
+
)
|
|
293
|
+
return rule ? rule[2] : L
|
|
294
|
+
}
|
package/src/node/utils/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
parseDefine,
|
|
8
8
|
parseGather,
|
|
9
9
|
parseIf,
|
|
10
|
+
parseLoop,
|
|
10
11
|
parseScatter,
|
|
11
12
|
parseStorageHead,
|
|
12
13
|
parseStruct,
|
|
@@ -16,13 +17,14 @@ import {
|
|
|
16
17
|
parseUniformHead,
|
|
17
18
|
parseVaryingHead,
|
|
18
19
|
} from './parse'
|
|
19
|
-
import { getBluiltin,
|
|
20
|
+
import { getBluiltin, getConversions, getOperator, initNodeContext, setupEvent } from './utils'
|
|
20
21
|
import { is } from '../../utils/helpers'
|
|
21
|
-
import
|
|
22
|
+
import { mod } from '..'
|
|
23
|
+
import type { Constants as C, NodeContext, Y } from '../types'
|
|
22
24
|
|
|
23
25
|
export * from './utils'
|
|
24
26
|
|
|
25
|
-
export const code = <T extends
|
|
27
|
+
export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string => {
|
|
26
28
|
if (!c) c = {}
|
|
27
29
|
initNodeContext(c)
|
|
28
30
|
if (is.arr(target)) return parseArray(target, c)
|
|
@@ -62,13 +64,21 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
62
64
|
if (type === 'conversion') return `${getConversions(x, c)}(${parseArray(children.slice(1), c)})`
|
|
63
65
|
if (type === 'operator') {
|
|
64
66
|
if (x === 'not' || x === 'bitNot') return `!${code(y, c)}`
|
|
67
|
+
if (x === 'mod') return code(mod(y, z), c)
|
|
68
|
+
if (x.endsWith('Assign')) return `${code(y, c)} ${getOperator(x)} ${code(z, c)};`
|
|
65
69
|
return `(${code(y, c)} ${getOperator(x)} ${code(z, c)})`
|
|
66
70
|
}
|
|
67
71
|
if (type === 'function') {
|
|
68
72
|
if (x === 'negate') return `(-${code(y, c)})`
|
|
73
|
+
if (x === 'reciprocal') return `(1.0 / ${code(y, c)})`
|
|
69
74
|
if (x === 'oneMinus') return `(1.0-${code(y, c)})`
|
|
75
|
+
if (x === 'saturate') return `clamp(${code(y, c)}, 0.0, 1.0)`
|
|
70
76
|
if (x === 'texture') return parseTexture(c, y, z, w)
|
|
71
77
|
if (x === 'atan2' && c.isWebGL) return `atan(${code(y, c)}, ${code(z, c)})`
|
|
78
|
+
if (!c.isWebGL) {
|
|
79
|
+
if (x === 'dFdx') return `dpdx(${code(y, c)})`
|
|
80
|
+
if (x === 'dFdy') return `dpdy(${code(y, c)})`
|
|
81
|
+
}
|
|
72
82
|
return `${x}(${parseArray(children.slice(1), c)})`
|
|
73
83
|
}
|
|
74
84
|
/**
|
|
@@ -77,10 +87,9 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
77
87
|
if (type === 'scope') return children.map((child: any) => code(child, c)).join('\n')
|
|
78
88
|
if (type === 'assign') return `${code(x, c)} = ${code(y, c)};`
|
|
79
89
|
if (type === 'return') return `return ${code(x, c)};`
|
|
80
|
-
if (type === '
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
: `for (var ${id}: i32 = 0; ${id} < ${code(x, c)}; ${id}++) {\n${code(y, c)}\n}`
|
|
90
|
+
if (type === 'break') return 'break;'
|
|
91
|
+
if (type === 'continue') return 'continue;'
|
|
92
|
+
if (type === 'loop') return parseLoop(c, x, y, id)
|
|
84
93
|
if (type === 'if') return parseIf(c, x, y, children)
|
|
85
94
|
if (type === 'switch') return parseSwitch(c, x, children)
|
|
86
95
|
if (type === 'declare') return parseDeclare(c, x, y)
|
|
@@ -112,10 +121,8 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
112
121
|
else if (c.label === 'vert') c.code?.vertInputs.set(id, field)
|
|
113
122
|
return `in.${id}`
|
|
114
123
|
}
|
|
115
|
-
if (type === 'attribute') {
|
|
116
|
-
|
|
117
|
-
safeEventCall(x, fun)
|
|
118
|
-
target.listeners.add(fun)
|
|
124
|
+
if (type === 'attribute' || type === 'instance') {
|
|
125
|
+
setupEvent(c, id, type, target, x)
|
|
119
126
|
c.code?.vertInputs.set(id, parseAttribHead(c, id, infer(target, c)))
|
|
120
127
|
return c.isWebGL ? `${id}` : `in.${id}`
|
|
121
128
|
}
|
|
@@ -123,9 +130,7 @@ export const code = <T extends Constants>(target: X<T>, c?: NodeContext | null):
|
|
|
123
130
|
let head = ''
|
|
124
131
|
if (type === 'uniform') {
|
|
125
132
|
const varType = infer(target, c)
|
|
126
|
-
|
|
127
|
-
safeEventCall(x, fun)
|
|
128
|
-
target.listeners.add(fun)
|
|
133
|
+
setupEvent(c, id, varType, target, x)
|
|
129
134
|
head = parseUniformHead(c, id, varType)
|
|
130
135
|
}
|
|
131
136
|
if (type === 'storage') head = parseStorageHead(c, id, infer(target, c))
|
package/src/node/utils/infer.ts
CHANGED
|
@@ -1,63 +1,54 @@
|
|
|
1
|
-
import { isConstants,
|
|
1
|
+
import { isConstants, isX, isSwizzle } from './utils'
|
|
2
2
|
import {
|
|
3
3
|
BUILTIN_TYPES,
|
|
4
|
-
COMPARISON_OPERATORS,
|
|
5
4
|
COMPONENT_COUNT_TO_TYPE,
|
|
6
5
|
FUNCTION_RETURN_TYPES,
|
|
7
|
-
|
|
6
|
+
getOperatorResultType,
|
|
7
|
+
validateOperatorTypes,
|
|
8
8
|
} from './const'
|
|
9
|
-
import { is } from '../../utils/helpers'
|
|
10
|
-
import type { Constants as C, NodeContext,
|
|
9
|
+
import { is, getStride } from '../../utils/helpers'
|
|
10
|
+
import type { Constants as C, NodeContext, X, Y } from '../types'
|
|
11
11
|
|
|
12
12
|
const inferBuiltin = <T extends C>(id: string | undefined) => {
|
|
13
13
|
return BUILTIN_TYPES[id as keyof typeof BUILTIN_TYPES] as T
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
// Unified logic with types.ts InferOperator type
|
|
17
16
|
const inferOperator = <T extends C>(L: T, R: T, op: string): T => {
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (L === 'float' || L === 'int') return R
|
|
22
|
-
if (R === 'float' || R === 'int') return L
|
|
23
|
-
// mat * vec → vec
|
|
24
|
-
if (L === 'mat4' && R === 'vec4') return R
|
|
25
|
-
if (L === 'mat3' && R === 'vec3') return R
|
|
26
|
-
if (L === 'mat2' && R === 'vec2') return R
|
|
27
|
-
// vec * mat → vec
|
|
28
|
-
if (L === 'vec4' && R === 'mat4') return L
|
|
29
|
-
if (L === 'vec3' && R === 'mat3') return L
|
|
30
|
-
if (L === 'vec2' && R === 'mat2') return L
|
|
31
|
-
return L
|
|
17
|
+
if (!validateOperatorTypes(L, R, op))
|
|
18
|
+
console.warn(`GLRE Type Warning: Invalid operator '${op}' between types '${L}' and '${R}'`)
|
|
19
|
+
return getOperatorResultType(L, R, op) as T
|
|
32
20
|
}
|
|
33
21
|
|
|
34
|
-
export const inferPrimitiveType = <T extends C>(x:
|
|
22
|
+
export const inferPrimitiveType = <T extends C>(x: Y<T>) => {
|
|
35
23
|
if (is.bol(x)) return 'bool' as T
|
|
36
24
|
if (is.str(x)) return 'texture' as T
|
|
37
25
|
if (is.num(x)) return 'float' as T // @TODO FIX: Number.isInteger(x) ? 'int' : 'float'
|
|
38
26
|
if (is.arr(x)) return COMPONENT_COUNT_TO_TYPE[x.length as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
|
|
39
|
-
return '
|
|
27
|
+
return 'void' as T
|
|
40
28
|
}
|
|
41
29
|
|
|
42
30
|
const inferFromCount = <T extends C>(count: number) => {
|
|
43
|
-
|
|
31
|
+
const ret = COMPONENT_COUNT_TO_TYPE[count as keyof typeof COMPONENT_COUNT_TO_TYPE] as T
|
|
32
|
+
if (!ret)
|
|
33
|
+
throw `glre node system error: Cannot infer type from array length ${count}. Check your data size. Supported: 1(float), 2(vec2), 3(vec3), 4(vec4), 9(mat3), 16(mat4)`
|
|
34
|
+
return ret
|
|
44
35
|
}
|
|
45
36
|
|
|
46
|
-
const inferFromArray = <T extends C>(arr:
|
|
37
|
+
const inferFromArray = <T extends C>(arr: Y<T>[], c: NodeContext) => {
|
|
47
38
|
if (arr.length === 0) return 'void' as T
|
|
48
39
|
const [x] = arr
|
|
49
40
|
if (is.str(x)) return x as T // for struct
|
|
50
41
|
const ret = infer(x, c)
|
|
51
42
|
// for (const x of arr.slice(1))
|
|
52
|
-
// if (ret !== infer(x, c)) throw
|
|
43
|
+
// if (ret !== infer(x, c)) throw `glre node system error: defined scope return mismatch`
|
|
53
44
|
return ret
|
|
54
45
|
}
|
|
55
46
|
|
|
56
|
-
export const inferFunction = <T extends C>(x:
|
|
47
|
+
export const inferFunction = <T extends C>(x: Y) => {
|
|
57
48
|
return FUNCTION_RETURN_TYPES[x as keyof typeof FUNCTION_RETURN_TYPES] as T
|
|
58
49
|
}
|
|
59
50
|
|
|
60
|
-
export const inferImpl = <T extends C>(target:
|
|
51
|
+
export const inferImpl = <T extends C>(target: X<T>, c: NodeContext): T => {
|
|
61
52
|
const { type, props } = target
|
|
62
53
|
const { id, children = [], inferFrom, layout } = props
|
|
63
54
|
const [x, y, z] = children
|
|
@@ -70,25 +61,32 @@ export const inferImpl = <T extends C>(target: NodeProxy<T>, c: NodeContext): T
|
|
|
70
61
|
if (!inferFrom || inferFrom.length === 0) return 'void' as T
|
|
71
62
|
return inferFromArray(inferFrom, c)
|
|
72
63
|
}
|
|
73
|
-
if (type === 'attribute' && is.arr(x)
|
|
64
|
+
if (type === 'attribute' && is.arr(x)) {
|
|
65
|
+
const stride = getStride(x.length, c.gl?.count, c.gl?.error)
|
|
66
|
+
return inferFromCount(stride)
|
|
67
|
+
}
|
|
68
|
+
if (type === 'instance' && is.arr(x)) {
|
|
69
|
+
const stride = getStride(x.length, c.gl?.instanceCount, c.gl?.error)
|
|
70
|
+
return inferFromCount(stride)
|
|
71
|
+
}
|
|
74
72
|
if (type === 'member') {
|
|
75
73
|
if (isSwizzle(y)) return inferFromCount(y.length)
|
|
76
|
-
if (
|
|
74
|
+
if (isX(x)) {
|
|
77
75
|
const structType = infer(x, c)
|
|
78
|
-
const fields = c.code?.
|
|
76
|
+
const fields = c.code?.structStructFields?.get(structType)
|
|
79
77
|
if (fields && fields[y]) return infer(fields[y], c) as T
|
|
80
78
|
}
|
|
81
79
|
return 'float' as T
|
|
82
80
|
}
|
|
83
81
|
if (inferFrom) return inferFromArray(inferFrom, c)
|
|
84
|
-
return infer(x, c) // for uniform and storage gather and scatter
|
|
82
|
+
return x ? infer(x, c) : ('void' as T) // for uniform and storage gather and scatter
|
|
85
83
|
}
|
|
86
84
|
|
|
87
|
-
export const infer = <T extends C>(target:
|
|
85
|
+
export const infer = <T extends C>(target: Y<T>, c?: NodeContext | null): T => {
|
|
88
86
|
if (!c) c = {}
|
|
89
|
-
if (!
|
|
87
|
+
if (!isX(target)) return inferPrimitiveType(target)
|
|
90
88
|
if (is.arr(target)) return inferFromCount(target.length)
|
|
91
|
-
if (!c.infers) c.infers = new WeakMap<
|
|
89
|
+
if (!c.infers) c.infers = new WeakMap<X<T>, C>()
|
|
92
90
|
if (c.infers.has(target)) return c.infers.get(target) as T
|
|
93
91
|
const ret = inferImpl(target, c)
|
|
94
92
|
c.infers.set(target, ret)
|
package/src/node/utils/parse.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { code } from '.'
|
|
|
2
2
|
import { infer } from './infer'
|
|
3
3
|
import { getConversions, addDependency } from './utils'
|
|
4
4
|
import { is } from '../../utils/helpers'
|
|
5
|
-
import type { Constants, NodeContext, NodeProps,
|
|
5
|
+
import type { Constants, NodeContext, NodeProps, StructFields, Y } from '../types'
|
|
6
|
+
import { storageSize } from '../../utils/program'
|
|
6
7
|
|
|
7
|
-
export const parseArray = (children:
|
|
8
|
+
export const parseArray = (children: Y[], c: NodeContext) => {
|
|
8
9
|
return children
|
|
9
10
|
.filter((x) => !is.und(x) && !is.nul(x))
|
|
10
11
|
.map((x) => code(x, c))
|
|
@@ -12,7 +13,7 @@ export const parseArray = (children: X[], c: NodeContext) => {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
// only for webgl
|
|
15
|
-
export const parseGather = (c: NodeContext, x:
|
|
16
|
+
export const parseGather = (c: NodeContext, x: Y, y: Y, target: Y) => {
|
|
16
17
|
const parseSwizzle = () => {
|
|
17
18
|
const valueType = infer(target, c)
|
|
18
19
|
if (valueType === 'float') return '.x'
|
|
@@ -22,14 +23,14 @@ export const parseGather = (c: NodeContext, x: X, y: X, target: X) => {
|
|
|
22
23
|
throw new Error(`Unsupported storage scatter type: ${valueType}`)
|
|
23
24
|
}
|
|
24
25
|
const indexVar = code(y, c)
|
|
25
|
-
const
|
|
26
|
-
const coordX = `int(${indexVar}) % ${
|
|
27
|
-
const coordY = `int(${indexVar}) / ${
|
|
26
|
+
const size = storageSize(c.gl?.particleCount)
|
|
27
|
+
const coordX = `int(${indexVar}) % ${size.x}`
|
|
28
|
+
const coordY = `int(${indexVar}) / ${size.x}`
|
|
28
29
|
return `texelFetch(${code(x, c)}, ivec2(${coordX}, ${coordY}), 0)${parseSwizzle()}`
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// only for webgl
|
|
32
|
-
export const parseScatter = (c: NodeContext, storageNode:
|
|
33
|
+
export const parseScatter = (c: NodeContext, storageNode: Y, valueNode: Y) => {
|
|
33
34
|
const storageId = code(storageNode, c)
|
|
34
35
|
const valueCode = code(valueNode, c)
|
|
35
36
|
const valueType = infer(valueNode, c)
|
|
@@ -40,7 +41,7 @@ export const parseScatter = (c: NodeContext, storageNode: X, valueNode: X) => {
|
|
|
40
41
|
throw new Error(`Unsupported storage scatter type: ${valueType}`)
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
export const parseTexture = (c: NodeContext, y:
|
|
44
|
+
export const parseTexture = (c: NodeContext, y: Y, z: Y, w: Y) => {
|
|
44
45
|
if (c.isWebGL) {
|
|
45
46
|
const args = w ? [y, z, w] : [y, z]
|
|
46
47
|
return `texture(${parseArray(args, c)})`
|
|
@@ -55,7 +56,7 @@ export const parseTexture = (c: NodeContext, y: X, z: X, w: X) => {
|
|
|
55
56
|
/**
|
|
56
57
|
* scopes
|
|
57
58
|
*/
|
|
58
|
-
export const parseIf = (c: NodeContext, x:
|
|
59
|
+
export const parseIf = (c: NodeContext, x: Y, y: Y, children: Y[]) => {
|
|
59
60
|
let ret = `if (${code(x, c)}) {\n${code(y, c)}\n}`
|
|
60
61
|
for (let i = 2; i < children.length; i += 2) {
|
|
61
62
|
const isElse = i >= children.length - 1
|
|
@@ -66,7 +67,7 @@ export const parseIf = (c: NodeContext, x: X, y: X, children: X[]) => {
|
|
|
66
67
|
return ret
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
export const parseSwitch = (c: NodeContext, x:
|
|
70
|
+
export const parseSwitch = (c: NodeContext, x: Y, children: Y[]) => {
|
|
70
71
|
let ret = `switch (${code(x, c)}) {\n`
|
|
71
72
|
for (let i = 1; i < children.length; i += 2) {
|
|
72
73
|
const isDefault = i >= children.length - 1
|
|
@@ -79,7 +80,7 @@ export const parseSwitch = (c: NodeContext, x: X, children: X[]) => {
|
|
|
79
80
|
return ret
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
export const parseDeclare = (c: NodeContext, x:
|
|
83
|
+
export const parseDeclare = (c: NodeContext, x: Y, y: Y) => {
|
|
83
84
|
const type = infer(x, c)
|
|
84
85
|
const varName = (y as any)?.props?.id
|
|
85
86
|
if (c.isWebGL) return `${type} ${varName} = ${code(x, c)};`
|
|
@@ -88,7 +89,7 @@ export const parseDeclare = (c: NodeContext, x: X, y: X) => {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
export const parseStructHead = (c: NodeContext, id: string, fields: StructFields = {}) => {
|
|
91
|
-
c.code?.
|
|
92
|
+
c.code?.structStructFields?.set(id, fields)
|
|
92
93
|
const lines: string[] = []
|
|
93
94
|
for (const key in fields) {
|
|
94
95
|
const fieldType = fields[key]
|
|
@@ -101,7 +102,7 @@ export const parseStructHead = (c: NodeContext, id: string, fields: StructFields
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
export const parseStruct = (c: NodeContext, id: string, instanceId = '', initialValues?: StructFields) => {
|
|
104
|
-
const fields = c.code?.
|
|
105
|
+
const fields = c.code?.structStructFields?.get(id) || {}
|
|
105
106
|
if (c.isWebGL) {
|
|
106
107
|
if (initialValues) {
|
|
107
108
|
const ordered = []
|
|
@@ -120,19 +121,16 @@ export const parseStruct = (c: NodeContext, id: string, instanceId = '', initial
|
|
|
120
121
|
/**
|
|
121
122
|
* define
|
|
122
123
|
*/
|
|
123
|
-
export const parseDefine = (c: NodeContext, props: NodeProps, target:
|
|
124
|
+
export const parseDefine = (c: NodeContext, props: NodeProps, target: Y) => {
|
|
124
125
|
const { id, children = [], layout } = props
|
|
125
126
|
const [x, ...args] = children
|
|
126
|
-
const argParams: [name: string, type:
|
|
127
|
+
const argParams: [name: string, type: Constants][] = []
|
|
127
128
|
const params: string[] = []
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
for (let i = 0; i < args.length; i++) {
|
|
134
|
-
argParams.push([`p${i}`, infer(args[i], c)])
|
|
135
|
-
}
|
|
129
|
+
for (let i = 0; i < args.length; i++) {
|
|
130
|
+
const input = layout?.inputs?.[i]
|
|
131
|
+
if (!input) argParams.push([`p${i}`, infer(args[i], c)])
|
|
132
|
+
else argParams.push([input.name, input.type === 'auto' ? infer(args[i], c) : input.type])
|
|
133
|
+
}
|
|
136
134
|
const scopeCode = code(x, c) // build struct headers before inferring returnType
|
|
137
135
|
const returnType = infer(target, c)
|
|
138
136
|
const ret = []
|
|
@@ -158,7 +156,7 @@ export const parseDefine = (c: NodeContext, props: NodeProps, target: NodeProxy)
|
|
|
158
156
|
/**
|
|
159
157
|
* headers
|
|
160
158
|
*/
|
|
161
|
-
export const parseVaryingHead = (c: NodeContext, id: string, type:
|
|
159
|
+
export const parseVaryingHead = (c: NodeContext, id: string, type: Constants) => {
|
|
162
160
|
return c.isWebGL
|
|
163
161
|
? `${type} ${id};`
|
|
164
162
|
: `@location(${c.code?.vertVaryings?.size || 0}) ${id}: ${getConversions(type, c)}`
|
|
@@ -201,6 +199,32 @@ export const parseStorageHead = (c: NodeContext, id: string, type: Constants) =>
|
|
|
201
199
|
return `@group(${group}) @binding(${binding}) var<storage, read_write> ${id}: array<${wgslType}>;`
|
|
202
200
|
}
|
|
203
201
|
|
|
202
|
+
export const parseLoop = (c: NodeContext, x: Y, y: Y, id: string) => {
|
|
203
|
+
const conditionType = infer(x, c)
|
|
204
|
+
const bodyCode = code(y, c)
|
|
205
|
+
const conditionCode = code(x, c)
|
|
206
|
+
if (c.isWebGL) {
|
|
207
|
+
if (conditionType === 'int')
|
|
208
|
+
return `for (int ${id} = 0; ${id} < ${conditionCode}; ${id} += 1) {\n${bodyCode}\n}`
|
|
209
|
+
if (conditionType === 'float')
|
|
210
|
+
return `for (float ${id} = 0.0; ${id} < ${conditionCode}; ${id} += 1.0) {\n${bodyCode}\n}`
|
|
211
|
+
if (conditionType === 'vec2')
|
|
212
|
+
return `for (vec2 ${id} = vec2(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y; ${id} += vec2(1.0)) {\n${bodyCode}\n}`
|
|
213
|
+
if (conditionType === 'vec3')
|
|
214
|
+
return `for (vec3 ${id} = vec3(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y && ${id}.z < ${conditionCode}.z; ${id} += vec3(1.0)) {\n${bodyCode}\n}`
|
|
215
|
+
return `for (int ${id} = 0; ${id} < ${conditionCode}; ${id} += 1) {\n${bodyCode}\n}`
|
|
216
|
+
}
|
|
217
|
+
if (conditionType === 'int')
|
|
218
|
+
return `for (var ${id}: i32 = 0; ${id} < ${conditionCode}; ${id}++) {\n${bodyCode}\n}`
|
|
219
|
+
if (conditionType === 'float')
|
|
220
|
+
return `for (var ${id}: f32 = 0.0; ${id} < ${conditionCode}; ${id} += 1.0) {\n${bodyCode}\n}`
|
|
221
|
+
if (conditionType === 'vec2')
|
|
222
|
+
return `for (var ${id}: vec2f = vec2f(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y; ${id} += vec2f(1.0)) {\n${bodyCode}\n}`
|
|
223
|
+
if (conditionType === 'vec3')
|
|
224
|
+
return `for (var ${id}: vec3f = vec3f(0.0); ${id}.x < ${conditionCode}.x && ${id}.y < ${conditionCode}.y && ${id}.z < ${conditionCode}.z; ${id} += vec3f(1.0)) {\n${bodyCode}\n}`
|
|
225
|
+
return `for (var ${id}: i32 = 0; ${id} < ${conditionCode}; ${id}++) {\n${bodyCode}\n}`
|
|
226
|
+
}
|
|
227
|
+
|
|
204
228
|
export const parseConstantHead = (c: NodeContext, id: string, type: Constants, value: string) => {
|
|
205
229
|
return c.isWebGL ? `const ${type} ${id} = ${value};` : `const ${id}: ${getConversions(type, c)} = ${value};`
|
|
206
230
|
}
|
package/src/node/utils/utils.ts
CHANGED
|
@@ -8,7 +8,18 @@ import {
|
|
|
8
8
|
WGSL_TO_GLSL_BUILTIN,
|
|
9
9
|
} from './const'
|
|
10
10
|
import { is } from '../../utils/helpers'
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
Constants as C,
|
|
13
|
+
Conversions,
|
|
14
|
+
Functions,
|
|
15
|
+
NodeContext,
|
|
16
|
+
NodeTypes,
|
|
17
|
+
Operators,
|
|
18
|
+
Swizzles,
|
|
19
|
+
X,
|
|
20
|
+
Y,
|
|
21
|
+
} from '../types'
|
|
22
|
+
import { storageSize } from '../../utils/program'
|
|
12
23
|
|
|
13
24
|
export const isSwizzle = (key: unknown): key is Swizzles => {
|
|
14
25
|
return is.str(key) && /^[xyzwrgbastpq]{1,4}$/.test(key)
|
|
@@ -26,13 +37,13 @@ export const isConversion = (key: unknown): key is Conversions => {
|
|
|
26
37
|
return CONVERSIONS.includes(key as Conversions)
|
|
27
38
|
}
|
|
28
39
|
|
|
29
|
-
export const
|
|
40
|
+
export const isX = (x: unknown): x is X => {
|
|
30
41
|
if (!x) return false
|
|
31
42
|
if (typeof x !== 'object') return false // @ts-ignore
|
|
32
43
|
return x.isProxy
|
|
33
44
|
}
|
|
34
45
|
|
|
35
|
-
export const isConstants = (type?: unknown): type is
|
|
46
|
+
export const isConstants = (type?: unknown): type is C => {
|
|
36
47
|
if (!is.str(type)) return false
|
|
37
48
|
return CONSTANTS.includes(type as any)
|
|
38
49
|
}
|
|
@@ -50,49 +61,29 @@ export const getId = () => `x${count++}`
|
|
|
50
61
|
|
|
51
62
|
export const getBluiltin = (c: NodeContext, id: string) => {
|
|
52
63
|
if (id === 'global_invocation_id') {
|
|
53
|
-
const size =
|
|
54
|
-
return `uvec3(uint(gl_FragCoord.y) * uint(${size}) + uint(gl_FragCoord.x), 0u, 0u)`
|
|
64
|
+
const size = storageSize(c.gl?.particleCount)
|
|
65
|
+
return `uvec3(uint(gl_FragCoord.y) * uint(${size.x}) + uint(gl_FragCoord.x), 0u, 0u)`
|
|
55
66
|
}
|
|
56
67
|
const ret = WGSL_TO_GLSL_BUILTIN[id as keyof typeof WGSL_TO_GLSL_BUILTIN]
|
|
57
68
|
if (!ret) throw new Error(`Error: unknown builtin variable ${id}`)
|
|
58
69
|
return ret
|
|
59
70
|
}
|
|
60
71
|
|
|
61
|
-
export const getConversions = <T extends
|
|
72
|
+
export const getConversions = <T extends C>(x: T, c?: NodeContext) => {
|
|
62
73
|
if (!is.str(x)) return ''
|
|
63
74
|
if (c?.isWebGL) return x
|
|
64
75
|
return TYPE_MAPPING[x as keyof typeof TYPE_MAPPING] || x // for struct type
|
|
65
76
|
}
|
|
66
77
|
|
|
67
|
-
export const getOperator = (op:
|
|
78
|
+
export const getOperator = (op: Y) => {
|
|
68
79
|
return OPERATORS[op as keyof typeof OPERATORS] || op
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
export const getConstant = (conversionKey: string):
|
|
82
|
+
export const getConstant = (conversionKey: string): C => {
|
|
72
83
|
const index = CONVERSIONS.indexOf(conversionKey as Conversions)
|
|
73
84
|
return index !== -1 ? CONSTANTS[index] : 'float'
|
|
74
85
|
}
|
|
75
86
|
|
|
76
|
-
export const getEventFun = (c: NodeContext, id: string, isAttribute = false, isTexture = false) => {
|
|
77
|
-
if (c.isWebGL) {
|
|
78
|
-
if (isAttribute) return (value: any) => c.gl?.attribute?.(id, value)
|
|
79
|
-
if (isTexture) return (value: any) => c.gl?.texture?.(id, value)
|
|
80
|
-
return (value: any) => c.gl?.uniform?.(id, value)
|
|
81
|
-
}
|
|
82
|
-
if (isAttribute) return (value: any) => c.gl?._attribute?.(id, value)
|
|
83
|
-
if (isTexture) return (value: any) => c.gl?._texture?.(id, value)
|
|
84
|
-
return (value: any) => c.gl?._uniform?.(id, value)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export const safeEventCall = <T extends Constants>(x: X<T>, fun: (value: unknown) => void) => {
|
|
88
|
-
if (is.und(x)) return
|
|
89
|
-
if (!isNodeProxy(x)) return fun(x) // for uniform(0) or uniform([0, 1])
|
|
90
|
-
if (x.type !== 'conversion') return
|
|
91
|
-
const args = x.props.children?.slice(1)
|
|
92
|
-
if (is.und(args?.[0])) return // ignore if uniform(vec2())
|
|
93
|
-
fun(args.map((x) => x ?? args[0])) // for uniform(vec2(1)) or uniform(vec2(1, 1))
|
|
94
|
-
}
|
|
95
|
-
|
|
96
87
|
export const initNodeContext = (c: NodeContext) => {
|
|
97
88
|
if (c.code) return c
|
|
98
89
|
c.code = {
|
|
@@ -103,7 +94,7 @@ export const initNodeContext = (c: NodeContext) => {
|
|
|
103
94
|
vertVaryings: new Map(),
|
|
104
95
|
computeInputs: new Map(),
|
|
105
96
|
dependencies: new Map(),
|
|
106
|
-
|
|
97
|
+
structStructFields: new Map(),
|
|
107
98
|
}
|
|
108
99
|
if (c.isWebGL) return c
|
|
109
100
|
c.code.fragInputs.set('position', '@builtin(position) position: vec4f')
|
|
@@ -119,3 +110,35 @@ export const addDependency = (c: NodeContext, id = '', type: string) => {
|
|
|
119
110
|
if (!c.code?.dependencies?.has(id)) c.code!.dependencies.set(id, new Set())
|
|
120
111
|
if (!isConstants(type)) c.code!.dependencies.get(id)!.add(type)
|
|
121
112
|
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* uniform ant attribute event listeners
|
|
116
|
+
*/
|
|
117
|
+
const getEventFun = (c: NodeContext, id: string, type: string) => {
|
|
118
|
+
if (c.isWebGL) {
|
|
119
|
+
if (type === 'attribute') return (value: any) => c.gl?.attribute?.(id, value)
|
|
120
|
+
if (type === 'instance') return (value: any) => c.gl?.instance?.(id, value)
|
|
121
|
+
if (type === 'texture') return (value: any) => c.gl?.texture?.(id, value)
|
|
122
|
+
return (value: any) => c.gl?.uniform?.(id, value)
|
|
123
|
+
}
|
|
124
|
+
if (type === 'attribute') return (value: any) => c.gl?._attribute?.(id, value)
|
|
125
|
+
if (type === 'instance') return (value: any) => c.gl?._instance?.(id, value)
|
|
126
|
+
if (type === 'texture') return (value: any) => c.gl?._texture?.(id, value)
|
|
127
|
+
return (value: any) => c.gl?._uniform?.(id, value)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const safeEventCall = <T extends C>(x: X<T>, fun: (value: unknown) => void) => {
|
|
131
|
+
if (is.und(x)) return
|
|
132
|
+
if (!isX(x)) return fun(x) // for uniform(0) or uniform([0, 1])
|
|
133
|
+
if (x.type !== 'conversion') return
|
|
134
|
+
const args = x.props.children?.slice(1)
|
|
135
|
+
if (is.und(args?.[0])) return // ignore if uniform(vec2())
|
|
136
|
+
fun(args.map((x) => x ?? args[0])) // for uniform(vec2(1)) or uniform(vec2(1, 1))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const setupEvent = (c: NodeContext, id: string, type: string, target: X, child: X) => {
|
|
140
|
+
const fun = getEventFun(c, id, type)
|
|
141
|
+
safeEventCall(child, fun)
|
|
142
|
+
target.listeners.add(fun)
|
|
143
|
+
return fun
|
|
144
|
+
}
|