Skip to content

Commit 6828b64

Browse files
committed
animated pixel node, split node, time node, HSV node
1 parent 9b4574e commit 6828b64

File tree

11 files changed

+171
-16
lines changed

11 files changed

+171
-16
lines changed

src/EditorNodes.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Theme } from './colors/Theme';
22
import { UVNode } from './nodes/attribute/UVNode';
33
import { ColorNode } from './nodes/input/ColorNode';
4-
import { TimeNode } from './nodes/input/TimeNode';
4+
import { TimeNode } from './nodes/animation/TimeNode';
55
import { tslInputNodes } from './nodes/input/TslInputNode';
66
import { UniformValueNode } from './nodes/input/UniformValueNode';
77
import { ValueNode } from './nodes/input/ValueNode';
@@ -20,6 +20,9 @@ import { MeshStandardNode } from './nodes/shader/MeshStandardNode';
2020
import { ImageTextureNode } from './nodes/texture/ImageTextureNode';
2121
import { BumpMapNode } from './nodes/vector/BumpMapNode';
2222
import { NormalMapNode } from './nodes/vector/NormalMapNode';
23+
import { AnimatedPixelNode } from './nodes/animation/AnimatedPixelNode';
24+
import { SpliNode } from './nodes/operators/SplitNode';
25+
import { HSVNode } from './nodes/input/HSVNode';
2326

2427
// Define the type for class constructors that extend BaseType
2528
type Constructor<T extends Node> = new (...args: any[]) => T;
@@ -48,14 +51,22 @@ export const NodeTypes: NodeGroupType[] = [
4851
name: 'Uniform Value',
4952
id: 'uniform-value',
5053
},
51-
{ TypeClass: TimeNode, name:"time", id:"timer" },
5254
{ TypeClass: ValueNode, name: 'Value', id: 'input-value' },
5355
{ TypeClass: ColorNode, name: 'Color', id: 'color-value' },
56+
{ TypeClass: HSVNode, name:"HSV", id:"hsv"},
5457
{ TypeClass: UVNode, name: 'UV', id: 'uv' },
5558
//{ TypeClass:PositionPropertiesNode, name:"Position", id:"position" },
5659
...tslInputNodes,
5760
],
5861
},
62+
{
63+
group:'Animation',
64+
color: Theme.config.groupAnimation as string,
65+
nodes: [
66+
{ TypeClass: TimeNode, name:"time", id:"timer" },
67+
{ TypeClass: AnimatedPixelNode, name:"Animated Pixel", id:"timer" },
68+
]
69+
},
5970
{
6071
group: 'Logic',
6172
color: Theme.config.groupLogic as string,
@@ -104,6 +115,7 @@ export const NodeTypes: NodeGroupType[] = [
104115
name: 'Swizzle',
105116
id: 'swizzle',
106117
},
118+
{ TypeClass:SpliNode, name:"Split", id:"split"}
107119
],
108120
},
109121
{

src/colors/Theme.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export class Theme {
4141
readonly groupLogic: FillStyle = '#203c3c';
4242
readonly groupFunction: FillStyle = '#005456';
4343
readonly groupCustomMade: FillStyle = '#785323';
44+
readonly groupAnimation: FillStyle = '#6e1d20';
4445

4546
readonly barBgColor: FillStyle = '#545454';
4647
readonly barFillColor: FillStyle = '#4772b3';

src/components/DraggableValue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class DraggableValue extends InteractiveLayoutElement {
1010
private promptValueOnMouseUp = false;
1111

1212
constructor(
13-
readonly name: string,
13+
public name: string,
1414
readonly usesBar: boolean,
1515
readonly min: number,
1616
readonly max: number,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
3+
import { Theme } from "../../colors/Theme";
4+
import { DataType } from "../../core/IOutlet";
5+
import { Script } from "../../export/Script";
6+
import { Output } from "../../properties/Output";
7+
import { ExecutableLogicNode } from "../logic/ExecutableLogicNode";
8+
import { WinNode } from "../WinNode";
9+
10+
11+
12+
/**
13+
* Use this as skeleton for a new node...
14+
*/
15+
export class AnimatedPixelNode extends WinNode {
16+
17+
protected scriptOutput:Output;
18+
19+
constructor() {
20+
super("Animated Pixel", Theme.config.groupAnimation, [
21+
new Output("color ( VAR )", DataType.vec3, "color" ),
22+
new Output("on update", DataType.script),
23+
new Output("final color", DataType.vec3, "output" ),
24+
]);
25+
26+
this.scriptOutput = this.getChildOfType(Output,1)!;
27+
}
28+
29+
protected override writeNodeScript( script: Script ): string {
30+
// this is where we write our ThreeJs TSL javascript node code...
31+
script.importModule("color");
32+
33+
const colorVar = script.define( this.nodeName+"Var", "color(0,0,0).toVar()");
34+
35+
const scope = script.newScope(false);
36+
37+
( this.scriptOutput.connectedTo?.owner as ExecutableLogicNode )?.writeBlockScript(script);
38+
39+
scope.exit();
40+
41+
const fn = script.defineFunction(
42+
scope,
43+
this.nodeName+"Fn",
44+
false,
45+
);
46+
47+
return script.define( this.nodeName, `{ color:${colorVar}, output:${fn} }`);
48+
}
49+
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { WinNode } from "../WinNode";
1313
export class TimeNode extends WinNode {
1414

1515
constructor() {
16-
super("Timer", Theme.config.groupInput, [
16+
super("Timer", Theme.config.groupAnimation, [
1717
new Output("seconds", DataType.wildcard),
1818
])
1919
}
@@ -33,9 +33,9 @@ export class TimeNode extends WinNode {
3333
this.nodeName,
3434
'0',
3535
);
36-
37-
script.writeLine(`${ref}.onFrameUpdate( frame => ${ref}.value = frame.time )`);
38-
36+
37+
script.importModule("uint");
38+
script.writeLine(`${ref}.onFrameUpdate( frame => ${ref}.value = frame.time )`);
3939

4040
return ref;
4141
}

src/nodes/input/HSVNode.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
import { DataType, IDataType } from '../../core/IOutlet';
3+
import { Script } from '../../export/Script';
4+
import { ValueNode } from './ValueNode';
5+
6+
7+
export class HSVNode extends ValueNode {
8+
9+
constructor() {
10+
super()
11+
this.size = 3;
12+
13+
this.setTitle("HSV")
14+
this.typeCombo.enabled = false;
15+
this.inputs.forEach( (input,i)=>input.label="HSV"[i])
16+
}
17+
18+
override get nodeDataType(): IDataType | undefined {
19+
return DataType.vec3;
20+
}
21+
22+
protected override writeNodeScript(script: Script): string {
23+
24+
script.importModule( ["vec3","mx_hsvtorgb"]);
25+
26+
const values = this.inputs
27+
.filter((input) => input.enabled)
28+
.map((input) => input.writeScript(script));
29+
30+
return script.define(
31+
this.nodeName,
32+
`mx_hsvtorgb(vec3(${values.join(',')}))`,
33+
);
34+
}
35+
}

src/nodes/input/ValueNode.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { InputBaseNode } from './InputBaseNode';
1010
export class ValueNode extends InputBaseNode {
1111
protected inputs: InputOrValue[];
1212
protected output: Output;
13+
protected typeCombo:DataTypeComboBox;
1314

1415
constructor(acceptsInputs = true) {
1516
const lbl = ['X', 'Y', 'Z', 'W'];
@@ -23,6 +24,7 @@ export class ValueNode extends InputBaseNode {
2324
new Output('value', DataType.wildcard),
2425
]);
2526

27+
this.typeCombo = this.getChildOfType(DataTypeComboBox)!;
2628
this.inputs = inputs;
2729
this.output = this.getChildOfType(Output)!;
2830
this.size = 0;

src/nodes/operators/SplitNode.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { Theme } from '../../colors/Theme';
2+
import { DataType, IDataType } from '../../core/IOutlet';
3+
import { Script } from '../../export/Script';
4+
import { BasicInputProperty } from '../../properties/BasicInputProperty';
5+
import { Output } from '../../properties/Output';
6+
import { WinNode } from '../WinNode';
7+
8+
export class SpliNode extends WinNode {
9+
protected channels: Output[];
10+
protected source: BasicInputProperty;
11+
12+
constructor() {
13+
const props = "xyzw";
14+
const channels = Array.from({ length:4 }).map( (_,i)=>new Output(props[i], DataType.float, props[i]) );
15+
16+
super('Split', Theme.config.groupMath, [
17+
new BasicInputProperty(DataType.wildcard, 'source'),
18+
...channels
19+
]);
20+
21+
this.source = this.getChildOfType(BasicInputProperty)!;
22+
this.channels = channels;
23+
}
24+
25+
override width(ctx: CanvasRenderingContext2D): number {
26+
return super.width(ctx)/2
27+
}
28+
29+
override get nodeDataType(): IDataType | undefined {
30+
return this.source.type == DataType.wildcard? DataType.vec4 : this.source.type ;
31+
}
32+
33+
override update(): void {
34+
const size = this.nodeDataType!.size;
35+
36+
this.channels.forEach(( channel, i) => {
37+
channel.enabled = i < size;
38+
});
39+
40+
super.update();
41+
}
42+
43+
protected override writeNodeScript(script: Script): string {
44+
return this.source.writeScript(script);
45+
}
46+
}

src/properties/BasicInputProperty.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ import { Input } from './Input';
66
* Just an input with a label.
77
*/
88
export class BasicInputProperty extends Input {
9+
10+
protected _label:string;
11+
set label(str:string){ this._label=str; }
12+
get label(){ return this._label; }
13+
914
/**
1015
* @param size
1116
* @param label
1217
* @param defaultScriptIfNotConnected If not connected, what should this input add to the script?
1318
*/
1419
constructor(
1520
type: IDataType,
16-
public label: string,
21+
label: string,
1722
protected defaultScriptIfNotConnected?: (script: Script) => string,
1823
) {
1924
super(type);
25+
this._label = label;
2026
}
2127

2228
override renderContents(

src/properties/InputOrValue.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ export class InputOrValue extends BasicInputProperty {
3737
asBar: false,
3838
defaultValue: 0,
3939
...(!hasConfig ? { label } : label),
40-
};
41-
42-
const lbl = !hasConfig ? label : label.label;
40+
};
4341

4442
super(DataType.float, valConfig.label);
4543

@@ -70,7 +68,11 @@ export class InputOrValue extends BasicInputProperty {
7068
}
7169
}
7270
});
73-
}
71+
}
72+
73+
override set label(str: string) {
74+
this.valueSlider.name = str;
75+
}
7476

7577
/**
7678
* Inform the listner or if no listener was passed, then inform the top-most node that "something has changed"

0 commit comments

Comments
 (0)