glre 0.25.0 → 0.27.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/src/node/const.ts CHANGED
@@ -1,5 +1,6 @@
1
- // 基本型定数
2
- export const TYPES = [
1
+ export const SWIZZLES = ['x', 'y', 'z', 'w', 'r', 'g', 'b', 'a', 's', 't', 'p', 'q'] as const
2
+
3
+ export const NODE_TYPES = [
3
4
  'float',
4
5
  'int',
5
6
  'uint',
@@ -22,48 +23,29 @@ export const TYPES = [
22
23
  'bvec4',
23
24
  ] as const
24
25
 
25
- export type NodeType = (typeof TYPES)[number]
26
-
27
- // スウィズル定数
28
- export const SWIZZLES = ['x', 'y', 'z', 'w', 'r', 'g', 'b', 'a', 's', 't', 'p', 'q'] as const
29
-
30
- type AllSwizzles<T extends string> = T | `${T}${T}` | `${T}${T}${T}` | `${T}${T}${T}${T}`
26
+ export const OPERATORS = {
27
+ add: '+',
28
+ sub: '-',
29
+ mul: '*',
30
+ div: '/',
31
+ mod: '%',
32
+ equal: '==',
33
+ notEqual: '!=',
34
+ lessThan: '<',
35
+ lessThanEqual: '<=',
36
+ greaterThan: '>',
37
+ greaterThanEqual: '>=',
38
+ and: '&&',
39
+ or: '||',
40
+ bitAnd: '&',
41
+ bitOr: '|',
42
+ bitXor: '^',
43
+ shiftLeft: '<<',
44
+ shiftRight: '>>',
45
+ } as const
31
46
 
32
- export type Swillzes =
33
- | AllSwizzles<'x' | 'y' | 'z' | 'w'>
34
- | AllSwizzles<'r' | 'g' | 'b' | 'a'>
35
- | AllSwizzles<'p' | 'q'>
36
- | AllSwizzles<'s' | 't'>
47
+ export const OPERATOR_KEYS = Object.keys(OPERATORS) as (keyof typeof OPERATORS)[]
37
48
 
38
- // 演算子定数
39
- export const OPERATORS = [
40
- 'add',
41
- 'sub',
42
- 'mul',
43
- 'div',
44
- 'mod',
45
- 'equal',
46
- 'notEqual',
47
- 'lessThan',
48
- 'lessThanEqual',
49
- 'greaterThan',
50
- 'greaterThanEqual',
51
- 'and',
52
- 'or',
53
- 'not',
54
- 'assign',
55
- 'xor',
56
- 'bitAnd',
57
- 'bitNot',
58
- 'bitOr',
59
- 'bitXor',
60
- 'shiftLeft',
61
- 'shiftRight',
62
- ] as const
63
-
64
- export type Operator = (typeof OPERATORS)[number]
65
-
66
- // 数学関数定数
67
49
  export const FUNCTIONS = [
68
50
  'abs',
69
51
  'acos',
@@ -122,9 +104,24 @@ export const FUNCTIONS = [
122
104
  'trunc',
123
105
  ] as const
124
106
 
125
- export type MathFunction = (typeof FUNCTIONS)[number]
126
-
127
- // キャッシュ用定数
128
- export const CACHE_BOOLS = [true, false] as const
129
- export const CACHE_INTS = [0, 1, 2, 3, 4, 5] as const
130
- export const CACHE_FLOATS = [0.0, 1.0, 0.5, 2.0] as const
107
+ export const TYPE_MAPPING = {
108
+ float: 'f32',
109
+ int: 'i32',
110
+ uint: 'u32',
111
+ bool: 'bool',
112
+ vec2: 'vec2f',
113
+ vec3: 'vec3f',
114
+ vec4: 'vec4f',
115
+ mat2: 'mat2x2f',
116
+ mat3: 'mat3x3f',
117
+ mat4: 'mat4x4f',
118
+ ivec2: 'vec2i',
119
+ ivec3: 'vec3i',
120
+ ivec4: 'vec4i',
121
+ uvec2: 'vec2u',
122
+ uvec3: 'vec3u',
123
+ uvec4: 'vec4u',
124
+ bvec2: 'vec2<bool>',
125
+ bvec3: 'vec3<bool>',
126
+ bvec4: 'vec4<bool>',
127
+ } as const
package/src/node/index.ts CHANGED
@@ -1,93 +1,91 @@
1
- import { float } from './conv'
2
- import { node } from './node'
3
- import { uniform } from './uniform'
4
- import { is } from '../utils/helpers'
5
- import type { X, FunctionNode, ConditionalNode } from './types'
6
- export type { X, FunctionNode, ConditionalNode }
7
- export * from './cache'
1
+ import { f, n, node, u } from './node'
2
+ import type { X } from './types'
3
+ export * from './code'
8
4
  export * from './const'
9
- export * from './conv'
10
5
  export * from './node'
6
+ export * from './scope'
11
7
  export * from './types'
12
- export * from './uniform'
8
+ export * from './utils'
13
9
 
14
- // 関数定義
15
- export const Fn = (jsFunc: Function): FunctionNode => {
16
- const functionNode = (...args: any[]) => {
17
- const inputs = args.map((arg) => {
18
- if (is.obj(arg) && 'type' in arg && arg.type) return arg
19
- return float(arg)
20
- })
21
- const result = jsFunc(inputs)
22
- return result || float(0)
23
- }
24
- functionNode.call = (inputs: X[]) => jsFunc(inputs)
25
- return functionNode as FunctionNode
26
- }
10
+ // Default uniforms
11
+ export const iResolution = u('iResolution', [1280, 800])
12
+ export const iMouse = u('iMouse', [0, 0])
13
+ export const iTime = u('iTime', 0)
14
+ export const fragCoord = node('variable', { id: 'fragCoord' })
27
15
 
28
- // 条件分岐
29
- export const If = (condition: X, callback: () => void): ConditionalNode => {
30
- callback()
16
+ // Type constructors
17
+ export const float = (x: X) => n('float', x)
18
+ export const int = (x: X) => n('int', x)
19
+ export const uint = (x: X) => n('uint', x)
20
+ export const bool = (x: X) => n('bool', x)
21
+ export const vec2 = (x?: X, y?: X) => n('vec2', x, y)
22
+ export const vec3 = (x?: X, y?: X, z?: X) => n('vec3', x, y, z)
23
+ export const vec4 = (x?: X, y?: X, z?: X, w?: X) => n('vec4', x, y, z, w)
24
+ export const mat2 = (...args: X[]) => n('mat2', ...args)
25
+ export const mat3 = (...args: X[]) => n('mat3', ...args)
26
+ export const mat4 = (...args: X[]) => n('mat4', ...args)
27
+ export const ivec2 = (x?: X, y?: X) => n('ivec2', x, y)
28
+ export const ivec3 = (x?: X, y?: X, z?: X) => n('ivec3', x, y, z)
29
+ export const ivec4 = (x?: X, y?: X, z?: X, w?: X) => n('ivec4', x, y, z, w)
30
+ export const uvec2 = (x?: X, y?: X) => n('uvec2', x, y)
31
+ export const uvec3 = (x?: X, y?: X, z?: X) => n('uvec3', x, y, z)
32
+ export const uvec4 = (x?: X, y?: X, z?: X, w?: X) => n('uvec4', x, y, z, w)
33
+ export const bvec2 = (x?: X, y?: X) => n('bvec2', x, y)
34
+ export const bvec3 = (x?: X, y?: X, z?: X) => n('bvec3', x, y, z)
35
+ export const bvec4 = (x?: X, y?: X, z?: X, w?: X) => n('bvec4', x, y, z, w)
31
36
 
32
- const conditionalNode = {
33
- ElseIf(newCondition: X, newCallback: () => void): ConditionalNode {
34
- newCallback()
35
- return conditionalNode
36
- },
37
- Else(elseCallback: () => void) {
38
- elseCallback()
39
- },
40
- }
41
-
42
- return conditionalNode
43
- }
44
-
45
- // 組み込み変数
46
- export const fragCoord = node('vec4', undefined)
47
- export const position = node('vec4', undefined)
48
- export const iTime = uniform(0.0)
49
- export const iResolution = uniform([1920, 1080])
50
- export const iMouse = uniform([0, 0])
51
-
52
- // 数学関数
53
- export const abs = (x: X) => x.abs()
54
- export const sin = (x: X) => x.sin()
55
- export const cos = (x: X) => x.cos()
56
- export const tan = (x: X) => x.tan()
57
- export const sqrt = (x: X) => x.sqrt()
58
- export const floor = (x: X) => x.floor()
59
- export const ceil = (x: X) => x.ceil()
60
- export const fract = (x: X) => x.fract()
61
- export const normalize = (x: X) => x.normalize()
62
- export const length = (x: X) => x.length()
63
-
64
- /**
65
- * @TODO FIX
66
- export const min = (a: X, b: X) => {
67
- return node('float', undefined, {
68
- mathFunction: 'min',
69
- children: [a as any, b as any],
70
- })
71
- }
72
-
73
- export const max = (a: X, b: X) => {
74
- return node('float', undefined, {
75
- mathFunction: 'max',
76
- children: [a as any, b as any],
77
- })
78
- }
79
-
80
- export const mix = (a: X, b: X, t: X) => {
81
- return node('float', undefined, {
82
- mathFunction: 'mix',
83
- children: [a as any, b as any, t as any],
84
- })
85
- }
86
-
87
- export const clamp = (x: X, min: X, max: X) => {
88
- return node('float', undefined, {
89
- mathFunction: 'clamp',
90
- children: [x as any, min as any, max as any],
91
- })
92
- }
93
- */
37
+ // Math Functions
38
+ export const abs = (x: X) => f('abs', x) // Return the absolute value of the parameter.
39
+ export const acos = (x: X) => f('acos', x) // Return the arccosine of the parameter.
40
+ export const all = (x: X) => f('all', x) // Return true if all components of x are true.
41
+ export const any = (x: X) => f('any', x) // Return true if any component of x is true.
42
+ export const asin = (x: X) => f('asin', x) // Return the arcsine of the parameter.
43
+ export const atan = (y: X, x: X) => f('atan', y, x) // Return the arc-tangent of the parameters.
44
+ export const bitcast = (x: X, y: X) => f('bitcast', x, y) // Reinterpret the bits of a value as a different type.
45
+ export const cbrt = (x: X) => f('cbrt', x) // Return the cube root of the parameter.
46
+ export const ceil = (x: X) => f('ceil', x) // Find the nearest integer that is greater than or equal to the parameter.
47
+ export const clamp = (x: X, min: X, max: X) => f('clamp', x, min, max) // Constrain a value to lie between two further values.
48
+ export const cos = (x: X) => f('cos', x) // Return the cosine of the parameter.
49
+ export const cross = (x: X, y: X) => f('cross', x, y) // Calculate the cross product of two vectors.
50
+ export const dFdx = (p: X) => f('dFdx', p) // Return the partial derivative of an argument with respect to x.
51
+ export const dFdy = (p: X) => f('dFdy', p) // Return the partial derivative of an argument with respect to y.
52
+ export const degrees = (radians: X) => f('degrees', radians) // Convert a quantity in radians to degrees.
53
+ export const difference = (x: X, y: X) => f('difference', x, y) // Calculate the absolute difference between two values.
54
+ export const distance = (x: X, y: X) => f('distance', x, y) // Calculate the distance between two points.
55
+ export const dot = (x: X, y: X) => f('dot', x, y) // Calculate the dot product of two vectors.
56
+ export const equals = (x: X, y: X) => f('equals', x, y) // Return true if x equals y.
57
+ export const exp = (x: X) => f('exp', x) // Return the natural exponentiation of the parameter.
58
+ export const exp2 = (x: X) => f('exp2', x) // Return 2 raised to the power of the parameter.
59
+ export const faceforward = (N: X, I: X, Nref: X) => f('faceforward', N, I, Nref) // Return a vector pointing in the same direction as another.
60
+ export const floor = (x: X) => f('floor', x) // Find the nearest integer less than or equal to the parameter.
61
+ export const fract = (x: X) => f('fract', x) // Compute the fractional part of the argument.
62
+ export const fwidth = (x: X) => f('fwidth', x) // Return the sum of the absolute derivatives in x and y.
63
+ export const inverseSqrt = (x: X) => f('inverseSqrt', x) // Return the inverse of the square root of the parameter.
64
+ export const length = (x: X) => f('length', x) // Calculate the length of a vector.
65
+ export const lengthSq = (x: X) => f('lengthSq', x) // Calculate the squared length of a vector.
66
+ export const log = (x: X) => f('log', x) // Return the natural logarithm of the parameter.
67
+ export const log2 = (x: X) => f('log2', x) // Return the base 2 logarithm of the parameter.
68
+ export const max = (x: X, y: X) => f('max', x, y) // Return the greater of two values.
69
+ export const min = (x: X, y: X) => f('min', x, y) // Return the lesser of two values.
70
+ export const mix = (x: X, y: X, a: X) => f('mix', x, y, a) // Linearly interpolate between two values.
71
+ export const negate = (x: X) => f('negate', x) // Negate the value of the parameter ( -x ).
72
+ export const normalize = (x: X) => f('normalize', x) // Calculate the unit vector in the same direction as the original vector.
73
+ export const oneMinus = (x: X) => f('oneMinus', x) // Return 1 minus the parameter.
74
+ export const pow = (x: X, y: X) => f('pow', x, y) // Return the value of the first parameter raised to the power of the second.
75
+ export const pow2 = (x: X) => f('pow2', x) // Return the square of the parameter.
76
+ export const pow3 = (x: X) => f('pow3', x) // Return the cube of the parameter.
77
+ export const pow4 = (x: X) => f('pow4', x) // Return the fourth power of the parameter.
78
+ export const radians = (degrees: X) => f('radians', degrees) // Convert a quantity in degrees to radians.
79
+ export const reciprocal = (x: X) => f('reciprocal', x) // Return the reciprocal of the parameter (1/x).
80
+ export const reflect = (I: X, N: X) => f('reflect', I, N) // Calculate the reflection direction for an incident vector.
81
+ export const refract = (I: X, N: X, eta: X) => f('refract', I, N, eta) // Calculate the refraction direction for an incident vector.
82
+ export const round = (x: X) => f('round', x) // Round the parameter to the nearest integer.
83
+ export const saturate = (x: X) => f('saturate', x) // Constrain a value between 0 and 1.
84
+ export const sign = (x: X) => f('sign', x) // Extract the sign of the parameter.
85
+ export const sin = (x: X) => f('sin', x) // Return the sine of the parameter.
86
+ export const smoothstep = (e0: X, e1: X, x: X) => f('smoothstep', e0, e1, x) // Perform Hermite interpolation between two values.
87
+ export const sqrt = (x: X) => f('sqrt', x) // Return the square root of the parameter.
88
+ export const step = (edge: X, x: X) => f('step', edge, x) // Generate a step function by comparing two values.
89
+ export const tan = (x: X) => f('tan', x) // Return the tangent of the parameter.
90
+ export const transformDirection = (dir: X, matrix: X) => f('transformDirection', dir, matrix) // Transform the direction of a vector by a matrix and then normalize the result.
91
+ export const trunc = (x: X) => f('trunc', x) // Truncate the parameter, removing the fractional part.
package/src/node/node.ts CHANGED
@@ -1,100 +1,46 @@
1
- import { OPERATORS, FUNCTIONS, SWIZZLES } from './const'
2
- import { is } from '../utils/helpers'
3
- import type { NodeType } from './const'
4
- import type { Node, ProxyCallback, X } from './types'
5
-
6
- let nodeIdCounter = 0
7
-
8
- // ノードIDを生成
9
- const generateNodeId = () => `node_${++nodeIdCounter}`
10
-
11
- // ノードを作成
12
- export const createNode = (type: NodeType, value?: any, options?: Partial<Node>): Node => {
13
- return {
14
- id: generateNodeId(),
15
- type,
16
- value,
17
- children: [],
18
- ...options,
1
+ import { code } from './code'
2
+ import { assign, toVar } from './scope'
3
+ import { getId, isFunction, isOperator, isSwizzle } from './utils'
4
+ import type { Functions, NodeProps, NodeProxy, NodeTypes, Operators, Swizzles, X } from './types'
5
+
6
+ const toPrimitive = (x: X) => {
7
+ return (hint: string) => {
8
+ if (hint === 'string') return code(x)
19
9
  }
20
10
  }
21
11
 
22
- const isSwizzleProperty = (key = '') => SWIZZLES.includes(key as any)
23
- const isOperatorMethod = (key = '') => OPERATORS.includes(key as any)
24
- const isMathMethod = (key = '') => FUNCTIONS.includes(key as any)
25
-
26
- // Proxyハンドラーを作成
27
- const createNodeProxy = (node: Node, callback?: (info: ProxyCallback) => X) => {
28
- const get = (_target: unknown, key: unknown) => {
29
- if (!is.str(key) || key === 'then') return void 0
30
-
31
- if (key === 'id') return node.id
32
- if (key === 'type') return node.type
33
- if (key === 'value') return node.value
34
- if (key === 'property') return node.property
35
-
36
- // swizzle prooerty
37
- if (isSwizzleProperty(key))
38
- return createNodeProxy(
39
- createNode(getSwizzleType(key), undefined, {
40
- parent: node,
41
- property: key,
42
- }),
43
- callback
44
- )
45
-
46
- // 演算子メソッド
47
- if (isOperatorMethod(key))
48
- return (...args: any[]) => {
49
- return createNodeProxy(
50
- createNode(node.type, undefined, {
51
- operator: key as any,
52
- children: [node, ...args],
53
- }),
54
- callback
55
- )
56
- }
57
-
58
- // 数学関数メソッド
59
- if (isMathMethod(key))
60
- return (...args: any[]) => {
61
- return createNodeProxy(
62
- createNode(getMathReturnType(key, node.type), undefined, {
63
- mathFunction: key as any,
64
- children: [node, ...args],
65
- }),
66
- callback
67
- )
12
+ export const node = (type: NodeTypes, props?: NodeProps | null, ...args: X[]) => {
13
+ if (!props) props = {}
14
+ if (args.length) props.children = args
15
+ const x = new Proxy(() => {}, {
16
+ get(_, key) {
17
+ if (key === 'type') return type
18
+ if (key === 'props') return props
19
+ if (key === 'toVar') return toVar(x)
20
+ if (key === 'assign') return assign(x)
21
+ if (key === 'isProxy') return true
22
+ if (key === 'toString') return code.bind(null, x)
23
+ if (key === Symbol.toPrimitive) return toPrimitive(x)
24
+ if (isSwizzle(key)) return s(key, x)
25
+ if (isOperator(key)) return (...y: X[]) => o(key, x, ...y)
26
+ if (isFunction(key)) return (...y: X[]) => f(key, x, ...y)
27
+ return toVar(x)('')
28
+ },
29
+ set(_, key, value) {
30
+ if (isSwizzle(key)) {
31
+ s(key, x).assign(value)
32
+ return true
68
33
  }
69
-
70
- return callback?.({ path: [key], args: [] })
71
- }
72
- const apply = (_target: unknown, _thisArg: unknown, args: any) => {
73
- return callback?.({ path: [], args })
74
- }
75
-
76
- return new Proxy(() => {}, { get, apply }) as X
34
+ return false
35
+ },
36
+ }) as unknown as NodeProxy
37
+ return x
77
38
  }
78
39
 
79
- // スウィズルの戻り値型を取得
80
- const getSwizzleType = (swizzle: string): NodeType => {
81
- if (swizzle.length === 1) return 'float'
82
- if (swizzle.length === 2) return 'vec2'
83
- if (swizzle.length === 3) return 'vec3'
84
- if (swizzle.length === 4) return 'vec4'
85
- return 'float'
86
- }
87
-
88
- // 数学関数の戻り値型を取得
89
- const getMathReturnType = (func: string, inputType: NodeType): NodeType => {
90
- if (func === 'length') return 'float'
91
- if (func === 'normalize') return inputType
92
- if (func === 'toVar') return inputType
93
- return inputType
94
- }
95
-
96
- // 公開API
97
- export const node = (type: NodeType, value?: any, options?: Partial<Node>) => {
98
- const nodeInstance = createNode(type, value, options)
99
- return createNodeProxy(nodeInstance)
100
- }
40
+ // Node shorthands
41
+ export const v = (...args: X[]) => node('variable', { id: getId() }, ...args)
42
+ export const u = (key: string, defaultValue?: number | number[]) => node('uniform', { defaultValue }, key)
43
+ export const s = (key: Swizzles, arg: X) => node('swizzle', null, key, arg)
44
+ export const n = (key: string, ...args: X[]) => node('node_type', null, key, ...args)
45
+ export const o = (key: Operators, ...args: X[]) => node('operator', null, key, ...args)
46
+ export const f = (key: Functions, ...args: X[]) => node('math_fun', null, key, ...args)
@@ -0,0 +1,68 @@
1
+ import { node } from './node'
2
+ import { getId } from './utils'
3
+ import type { NodeProxy, X } from './types'
4
+
5
+ let _scope: NodeProxy | null = null
6
+
7
+ const scoped = (x: NodeProxy | null, callback = () => {}) => {
8
+ const prev = _scope
9
+ _scope = x
10
+ callback()
11
+ _scope = prev
12
+ }
13
+
14
+ const addToScope = (x: NodeProxy) => {
15
+ if (!_scope) return // ignore
16
+ if (!_scope.props.children) _scope.props.children = []
17
+ _scope.props.children.push(x)
18
+ }
19
+
20
+ export const If = (x: X, callback: () => void) => {
21
+ const y = node('scope')
22
+ scoped(y, callback)
23
+ const ifNode = node('if', null, x, y)
24
+ addToScope(ifNode)
25
+ return {
26
+ ElseIf: (y: X, elseCallback: () => void) => {
27
+ const z = node('scope')
28
+ scoped(z, elseCallback)
29
+ ifNode.props.children!.push(y, z)
30
+ },
31
+ Else: (elseCallback: () => void) => {
32
+ const z = node('scope')
33
+ scoped(z, elseCallback)
34
+ ifNode.props.children!.push(z)
35
+ },
36
+ }
37
+ }
38
+
39
+ export const Loop = (x: X, callback?: (params: { i: NodeProxy }) => void) => {
40
+ const y = node('scope')
41
+ scoped(y, () => callback?.({ i: node('variable', { id: 'i' }) }))
42
+ const ret = node('loop', null, x, y)
43
+ addToScope(ret)
44
+ return ret
45
+ }
46
+
47
+ export const Fn = (callback: (args: X[]) => NodeProxy) => {
48
+ return (...args: X[]) => {
49
+ let result
50
+ const fnScope = node('scope')
51
+ scoped(fnScope, () => (result = callback(args)))
52
+ return node('fn', null, fnScope, result)
53
+ }
54
+ }
55
+
56
+ export const toVar = (x: X) => (id: string) => {
57
+ if (!id) id = getId()
58
+ const y = node('variable', { id })
59
+ const z = node('declare', null, y, x)
60
+ addToScope(z)
61
+ return y
62
+ }
63
+
64
+ export const assign = (x: X) => (y: X) => {
65
+ const assignNode = node('assign', null, x, y)
66
+ addToScope(assignNode)
67
+ return x
68
+ }