Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fn/func in nodes #245

Merged
merged 4 commits into from
Sep 1, 2022
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
@@ -361,14 +361,23 @@
]
},
{
"login": "cosformula",
"login": "cosformula",
"name": "cosformula",
"avatar_url": "https://avatars.githubusercontent.com/u/18232501?v=4",
"profile": "https://github.com/cosformula",
"contributions": [
"contributions": [
"code"
]
},
{
"login": "miko3k",
"name": "Peter Hanula",
"avatar_url": "https://avatars.githubusercontent.com/u/8658482?v=4",
"profile": "https://github.com/miko3k",
"contributions": [
"code"
]
}
}
],
"skipCi": true,
"contributorsPerLine": 7
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@
"scripts": {
"prepare": "husky install",
"test-all": "node node_modules/@definitelytyped/dtslint-runner/dist/index.js --path .",
"test": "dtslint types",
"lint": "dtslint types",
"test": "node node_modules/@definitelytyped/dtslint/dist/index.js types/three",
"lint": "node node_modules/@definitelytyped/dtslint/dist/index.js types/three",
"prettier:write": "prettier --write .",
"prettier:check": "prettier --check .",
"contributors:add": "all-contributors add"
3 changes: 1 addition & 2 deletions types/three/OTHER_FILES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
examples/jsm/animation/AnimationClipCreator.d.ts
examples/jsm/csm/CSMFrustum.d.ts
examples/jsm/csm/CSMShader.d.ts
examples/jsm/curves/NURBSCurve.d.ts
examples/jsm/curves/NURBSSurface.d.ts
@@ -65,8 +64,8 @@ examples/jsm/loaders/PRWMLoader.d.ts
examples/jsm/loaders/PVRLoader.d.ts
examples/jsm/loaders/STLLoader.d.ts
examples/jsm/loaders/TDSLoader.d.ts
examples/jsm/loaders/TIFFLoader.d.ts
examples/jsm/loaders/TiltLoader.d.ts
examples/jsm/loaders/TTFLoader.d.ts
examples/jsm/loaders/VRMLLoader.d.ts
examples/jsm/loaders/VTKLoader.d.ts
examples/jsm/loaders/XYZLoader.d.ts
3 changes: 2 additions & 1 deletion types/three/examples/jsm/nodes/Nodes.d.ts
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ import ConstNode from './core/ConstNode';
import ContextNode from './core/ContextNode';
import ExpressionNode from './core/ExpressionNode';
import FunctionCallNode from './core/FunctionCallNode';
import FunctionNode from './core/FunctionNode';
import FunctionNode, { FunctionNodeArguments } from './core/FunctionNode';
import InstanceIndexNode from './core/InstanceIndexNode';
import Node from './core/Node';
import NodeAttribute from './core/NodeAttribute';
@@ -118,6 +118,7 @@ export {
ExpressionNode,
FunctionCallNode,
FunctionNode,
FunctionNodeArguments,
InstanceIndexNode,
Node,
NodeAttribute,
4 changes: 2 additions & 2 deletions types/three/examples/jsm/nodes/core/CodeNode.d.ts
Original file line number Diff line number Diff line change
@@ -3,13 +3,13 @@ import Node from './Node';
import NodeBuilder from './NodeBuilder';

export interface CodeNodeInclude {
build(): void;
build(builder: NodeBuilder): void;
}

export default class CodeNode extends Node {
isCodeNode: true;
code: string;
constructor(code: string, nodeType?: NodeTypeOption);
constructor(code?: string, includes?: CodeNodeInclude[]);

setIncludes(includes: CodeNodeInclude[]): this;
getIncludes(builder: NodeBuilder): CodeNodeInclude[];
10 changes: 5 additions & 5 deletions types/three/examples/jsm/nodes/core/FunctionCallNode.d.ts
Original file line number Diff line number Diff line change
@@ -2,12 +2,12 @@ import FunctionNode from './FunctionNode';
import TempNode from './TempNode';
import Node from './Node';

export default class FunctionCallNode extends TempNode {
functionNode: FunctionNode;
export default class FunctionCallNode<P extends Node[] | { [name: string]: Node }> extends TempNode {
functionNode: FunctionNode<P>;
parameters: { [name: string]: Node };

constructor(functionNode?: FunctionNode, parameters?: { [name: string]: Node });
constructor(functionNode?: FunctionNode<P>, parameters?: P);

setParameters(parameters: { [name: string]: Node }): this;
getParameters(): { [name: string]: Node };
setParameters(parameters: P): this;
getParameters(): P;
}
10 changes: 6 additions & 4 deletions types/three/examples/jsm/nodes/core/FunctionNode.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import CodeNode from './CodeNode';
import CodeNode, { CodeNodeInclude } from './CodeNode';
import FunctionCallNode from './FunctionCallNode';
import NodeBuilder from './NodeBuilder';
import NodeFunction from './NodeFunction';
import NodeFunctionInput from './NodeFunctionInput';
import Node from './Node';

export default class FunctionNode extends CodeNode {
export type FunctionNodeArguments = Node[] | { [name: string]: Node };

export default class FunctionNode<P extends Node[] | { [name: string]: Node }> extends CodeNode {
keywords: { [key: string]: Node };
constructor(code?: string);
constructor(code?: string, includes?: CodeNodeInclude[]);

getInputs(builder: NodeBuilder): NodeFunctionInput[];
getNodeFunction(builder: NodeBuilder): NodeFunction;
call(parameters: { [name: string]: Node }): FunctionCallNode;
call(parameters: P): FunctionCallNode<P>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Fn, Node, Swizzable } from '../../../Nodes';

export function mx_hsvtorgb(...params: Fn<[Node]>): Swizzable;
export function mx_rgbtohsv(...params: Fn<[Node]>): Swizzable;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Fn, Node, Swizzable } from '../../../Nodes';

export function mx_perlin_noise_float(...params: Fn<[Node]>): Swizzable;
export function mx_cell_noise_float(...params: Fn<[Node]>): Swizzable;
export function mx_worley_noise_float(...params: Fn<[Node]>): Swizzable;
export function mx_fractal_noise_float(...params: Fn<[Node, Node, Node, Node]>): Swizzable;
18 changes: 10 additions & 8 deletions types/three/examples/jsm/nodes/shadernode/ShaderNode.d.ts
Original file line number Diff line number Diff line change
@@ -7,17 +7,19 @@ export type Swizzable<T extends Node = Node> = T &
};

/** anything that can be passed to {@link nodeObject} and returns a proxy */
export type NodeRepresentation = number | boolean | Node | Swizzable;
export type NodeRepresentation<T extends Node = Node> = number | boolean | Node | Swizzable<T>;

/** anything that can be passed to {@link nodeObject} */
export type NodeObjectOption = NodeRepresentation | string;

// same logic as in ShaderNodeObject
// same logic as in ShaderNodeObject: number,boolean,node->swizzable, otherwise do nothing
export type NodeObject<T> = T extends Node ? Swizzable<T> : T extends number | boolean ? Swizzable<ConstNode> : T;

type MakeObjectOption<T> = T extends Node ? NodeRepresentation : T;
// opposite of NodeObject: node -> node|swizzable|boolean|number, otherwise do nothing
type Proxied<T> = T extends Node ? NodeRepresentation<T> : T;
// https://github.com/microsoft/TypeScript/issues/42435#issuecomment-765557874
type MakeObjectOptions<T extends readonly [...unknown[]]> = [...{ [index in keyof T]: MakeObjectOption<T[index]> }];
export type ProxiedTuple<T extends readonly [...unknown[]]> = [...{ [index in keyof T]: Proxied<T[index]> }];
export type ProxiedObject<T> = { [index in keyof T]: Proxied<T[index]> };
type RemoveTail<T extends readonly [...unknown[]]> = T extends [unknown, ...infer X] ? X : [];
type RemoveHeadAndTail<T extends readonly [...unknown[]]> = T extends [unknown, ...infer X, unknown] ? X : [];

@@ -121,22 +123,22 @@ export function nodeArray<T extends NodeObjectOption[]>(obj: readonly [...T]): N

export function nodeProxy<T>(
nodeClass: T,
): (...params: MakeObjectOptions<GetConstructors<T>>) => Swizzable<ConstructedNode<T>>;
): (...params: ProxiedTuple<GetConstructors<T>>) => Swizzable<ConstructedNode<T>>;

export function nodeProxy<T, S extends GetPossibleScopes<T>>(
nodeClass: T,
scope: S,
): (...params: MakeObjectOptions<RemoveTail<GetConstructorsByScope<T, S>>>) => Swizzable<ConstructedNode<T>>;
): (...params: ProxiedTuple<RemoveTail<GetConstructorsByScope<T, S>>>) => Swizzable<ConstructedNode<T>>;

export function nodeProxy<T, S extends GetPossibleScopes<T>>(
nodeClass: T,
scope: S,
factor: NodeObjectOption,
): (...params: MakeObjectOptions<RemoveHeadAndTail<GetConstructorsByScope<T, S>>>) => Swizzable<ConstructedNode<T>>;
): (...params: ProxiedTuple<RemoveHeadAndTail<GetConstructorsByScope<T, S>>>) => Swizzable<ConstructedNode<T>>;

export function nodeImmutable<T>(
nodeClass: T,
...params: MakeObjectOptions<GetConstructors<T>>
...params: ProxiedTuple<GetConstructors<T>>
): Swizzable<ConstructedNode<T>>;

export class ShaderNode<T = {}, R extends Node = Node> {
Original file line number Diff line number Diff line change
@@ -13,6 +13,8 @@ import {
Swizzable,
NodeRepresentation,
NodeOrType,
ProxiedObject,
ProxiedTuple,
} from './ShaderNode';
import { Material, Texture } from '../../../../src/Three';
import { NodeTypeOption, NodeUserData, NodeValueOption } from '../core/constants';
@@ -22,13 +24,14 @@ import {
BypassNode,
CameraNode,
CodeNode,
CodeNodeInclude,
ComputeNode,
ContextNode,
ConvertNode,
ExpressionNode,
FrontFacingNode,
FunctionCallNode,
FunctionNode,
FunctionNodeArguments,
InstanceIndexNode,
MaterialNode,
MaterialReferenceNode,
@@ -83,8 +86,6 @@ export const imat4: ConvertType;
export const umat4: ConvertType;
export const bmat4: ConvertType;

export function func(code: string): ShaderNode<FunctionNode>;

export function uniform(nodeOrType: Node | Swizzable | NodeValueOption): Swizzable;

export function attribute(attributeName: string, nodeType: NodeTypeOption): Swizzable;
@@ -95,10 +96,27 @@ export function code(code: string, nodeType?: NodeTypeOption): Swizzable<CodeNod
export function context(node: NodeRepresentation, context: NodeBuilderContext): Swizzable<ContextNode>;
export function expression(snipped?: string, nodeType?: NodeTypeOption): Swizzable<ExpressionNode>;

export function call(
functionNode?: NodeRepresentation,
parameters?: { [name: string]: Node },
): Swizzable<FunctionCallNode>;
// definition: const call = nodeProxy(FunctionCallNode);
export function call<P extends FunctionNodeArguments>(
functionNode?: FunctionNode<P>,
parameters?: ProxiedObject<P>,
): Swizzable<FunctionCallNode<P>>;

export type Fn<P extends FunctionNodeArguments> = P extends readonly [...unknown[]]
? ProxiedTuple<P>
: readonly [ProxiedObject<P>];

// tslint:disable:no-unnecessary-generics
export function func<P extends FunctionNodeArguments>(
code: string,
includes?: CodeNodeInclude[],
): { call: (...params: Fn<P>) => Swizzable };

export function fn<P extends FunctionNodeArguments>(
code: string,
includes?: CodeNodeInclude[],
): (...params: Fn<P>) => Swizzable;
// tslint:enable:no-unnecessary-generics

export const instanceIndex: Swizzable<InstanceIndexNode>;
export function label(node: NodeRepresentation, name?: string): Swizzable<VarNode>;
57 changes: 57 additions & 0 deletions types/three/test/nodes/nodes-FunctionNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Various tests of func, fn and call
*/

import {
code,
fn,
uv,
func,
Node,
FunctionNode,
call,
Swizzable,
FunctionCallNode,
} from 'three/examples/jsm/nodes/Nodes';

import { ProxiedObject } from 'three/examples/jsm/nodes/shadernode/ShaderNode';

export const mx_noise = code('whatever');
const includes = [mx_noise];

const someFunc1 = new FunctionNode<[a: Node]>();
const someFunc2 = new FunctionNode<{ a: Node }>();

// tslint:disable-next-line:no-unnecessary-generics
function assertSwizzable<T extends Node>(_s: Swizzable<T>) {}

type a = ProxiedObject<readonly [Node]>;

assertSwizzable<FunctionCallNode<[Node]>>(call(someFunc1, [1]));
assertSwizzable<FunctionCallNode<[Node]>>(call(someFunc1, [uv()]));
assertSwizzable<FunctionCallNode<[Node]>>(call(someFunc1, [uv().xy]));
assertSwizzable<FunctionCallNode<{ a: Node }>>(call(someFunc2, { a: 1 }));
assertSwizzable<FunctionCallNode<{ a: Node }>>(call(someFunc2, { a: uv() }));
assertSwizzable<FunctionCallNode<{ a: Node }>>(call(someFunc2, { a: uv().xy }));

export const mx_cell_noise_float_call = func<[Node]>('float mx_cell_noise_float( vec3 p )', includes);
export const mx_worley_noise_float_call = func<[Node, Node, Node]>(
'float mx_worley_noise_float( vec3 p, float jitter, int metric )',
includes,
);
export const ab_call = func<{ a: Node; b: Node }>('float mx_cell_noise_float( vec3 p )', includes);

assertSwizzable<Node>(mx_cell_noise_float_call.call(uv()));
assertSwizzable<Node>(mx_worley_noise_float_call.call(uv(), 1, 1));
assertSwizzable<Node>(ab_call.call({ a: 1, b: uv() }));

export const mx_cell_noise_float = fn<[Node]>('float mx_cell_noise_float( vec3 p )', includes);
export const mx_worley_noise_float = fn<[Node, Node, Node]>(
'float mx_worley_noise_float( vec3 p, float jitter, int metric )',
includes,
);
export const ab = fn<{ a: Node; b: Node }>('float mx_cell_noise_float( vec3 p )', includes);

assertSwizzable<Node>(mx_cell_noise_float(uv()));
assertSwizzable<Node>(mx_worley_noise_float(uv(), 1, 1));
assertSwizzable<Node>(ab({ a: 1, b: uv() }));
1 change: 0 additions & 1 deletion types/three/test/nodes/nodes-ShaderNode.ts
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@ import { ConvertType, Swizzable } from 'three/examples/jsm/nodes/shadernode/Shad
// just to type check
// tslint:disable-next-line:no-unnecessary-generics
function assertSwizzable<T extends Node>(_s: Swizzable<T>) {}
function assertNode(_s: Node) {}

export const color = new ConvertType('color');
const s = color(1);
15 changes: 15 additions & 0 deletions types/three/test/nodes/nodes-materialx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
mx_perlin_noise_float,
mx_cell_noise_float,
mx_worley_noise_float,
mx_fractal_noise_float,
} from 'three/examples/jsm/nodes/materialx/functions/lib/mx_noise';

import { mx_hsvtorgb, mx_rgbtohsv } from 'three/examples/jsm/nodes/materialx/functions/lib/mx_hsv';

mx_perlin_noise_float(1);
mx_cell_noise_float(1);
mx_worley_noise_float(1);
mx_fractal_noise_float(1, 1, 1, 1);
mx_hsvtorgb(1);
mx_rgbtohsv(1);
2 changes: 2 additions & 0 deletions types/three/tsconfig.json
Original file line number Diff line number Diff line change
@@ -63,6 +63,8 @@
"test/misc/misc-gpucomputationrender.ts",
"test/nodes/nodes-ColorAdjustmentNode.ts",
"test/nodes/nodes-Iridescence.ts",
"test/nodes/nodes-FunctionNode.ts",
"test/nodes/nodes-materialx.ts",
"test/nodes/nodes-ShaderNode.ts",
"test/nodes/nodes-ShaderNodeBaseElements.ts",
"test/nodes/nodes-ShaderNodeElements.ts",
2 changes: 1 addition & 1 deletion types/three/tslint.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "extends": "dtslint/dt.json" }
{ "extends": "@definitelytyped/dtslint/dt.json" }