Skip to content

Commit 3adce48

Browse files
committed
destroy input connection if it is being rewired + tsl standalone properties nodes + normal nodes + blend modes
1 parent 368e48e commit 3adce48

File tree

6 files changed

+157
-4
lines changed

6 files changed

+157
-4
lines changed

src/Editor.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,9 @@ export class Editor {
679679
const chosenTarget = this.chosenOutlet[0].outlet;
680680

681681
if( this.selectedOutlet.isInput )
682-
this.destroyConnectionsUsing( this.selectedOutlet, true );
682+
this.destroyConnectionsUsing( this.selectedOutlet, true );
683+
else
684+
this.destroyConnectionsUsing( chosenTarget, true );
683685

684686
//
685687
// all the connections that were following the mouse will not have this outlet as their endpoint connection.

src/EditorNodes.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Theme } from "./colors/Theme";
2-
import { UVNode } from "./nodes/attribute/UVNode";
2+
import { UVNode } from "./nodes/attribute/UVNode";
3+
import { tslInputNodes } from "./nodes/input/TslInputNode";
34
import { ValueNode } from "./nodes/input/ValueNode";
45
import { Node } from "./nodes/Node";
56
import { mathFunctions, mathOperations } from "./nodes/operators/list";
@@ -28,7 +29,9 @@ export const NodeTypes : NodeGroupType[] = [
2829
color:Theme.config.groupInput as string,
2930
nodes: [
3031
{ TypeClass:ValueNode, name:"Value", id:"input-value"},
31-
{ TypeClass:UVNode, name:"UV", id:"uv" }
32+
{ TypeClass:UVNode, name:"UV", id:"uv" },
33+
//{ TypeClass:PositionPropertiesNode, name:"Position", id:"position" },
34+
...tslInputNodes
3235
]
3336
},
3437
{

src/nodes/input/PropertiesNode.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Theme } from "../../colors/Theme";
2+
import { OutletSize } from "../../core/IOutlet";
3+
import { Script } from "../../export/Script";
4+
import { Output } from "../../properties/Output";
5+
import { decamelcase } from "../../util/decamelcase";
6+
import { WinNode } from "../WinNode";
7+
8+
type PropertyDef = {
9+
name:string
10+
desc:string
11+
type:string
12+
}
13+
14+
/**
15+
* An output that returns a standalone node from tsl, it doesn't read anything from it's owner node.
16+
*/
17+
class PropertyOutput extends Output {
18+
19+
constructor( protected prop:PropertyDef, nameFormatter?:(name:string)=>string )
20+
{
21+
const toSize = (s:string) => s=="float"? 1 : Number(s.match(/\d+/)?.[0] ?? 0);
22+
23+
const title = decamelcase( nameFormatter?.(prop.name) ?? prop.name );
24+
25+
super( title==""? prop.name : title , toSize( prop.type ) as OutletSize );
26+
}
27+
28+
override writeScript(script: Script): string {
29+
script.importModule( this.prop.name );
30+
return this.prop.name;
31+
}
32+
}
33+
34+
/**
35+
* A shell node exposing standalone properties from tsl.
36+
*/
37+
export class PropertiesNode extends WinNode {
38+
constructor(title:string, props:PropertyDef[], nameFormatter?:(name:string)=>string) {
39+
super(title, Theme.config.groupInput, props.map( prop=>new PropertyOutput( prop , nameFormatter )));
40+
}
41+
}

src/nodes/input/TslInputNode.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { string } from "three/tsl"
2+
import { PropertiesNode } from "./PropertiesNode"
3+
4+
const tslInputs : [string, any][] = [
5+
["Bitangent", [
6+
{ "name": "bitangentGeometry", "desc": "Normalized bitangent in geometry space.", "type": "vec3" },
7+
{ "name": "bitangentLocal", "desc": "Normalized bitangent in local space.", "type": "vec3" },
8+
{ "name": "bitangentView", "desc": "Normalized bitangent in view space.", "type": "vec3" },
9+
{ "name": "bitangentWorld", "desc": "Normalized bitangent in world space.", "type": "vec3" },
10+
{ "name": "transformedBitangentView", "desc": "Normalized transformed bitangent in view space.", "type": "vec3" },
11+
{ "name": "transformedBitangentWorld", "desc": "Normalized transformed bitangent in world space.", "type": "vec3" }
12+
]],
13+
14+
["Camera", [
15+
{ "name": "cameraNear", "desc": "Near plane distance of the camera.", "type": "float" },
16+
{ "name": "cameraFar", "desc": "Far plane distance of the camera.", "type": "float" },
17+
{ "name": "cameraProjectionMatrix", "desc": "Projection matrix of the camera.", "type": "mat4" },
18+
{ "name": "cameraProjectionMatrixInverse", "desc": "Inverse projection matrix of the camera.", "type": "mat4" },
19+
{ "name": "cameraViewMatrix", "desc": "View matrix of the camera.", "type": "mat4" },
20+
{ "name": "cameraWorldMatrix", "desc": "World matrix of the camera.", "type": "mat4" },
21+
{ "name": "cameraNormalMatrix", "desc": "Normal matrix of the camera.", "type": "mat3" },
22+
{ "name": "cameraPosition", "desc": "World position of the camera.", "type": "vec3" }
23+
]],
24+
25+
["Model", [
26+
{ "name": "modelDirection", "desc": "Direction of the model.", "type": "vec3" },
27+
{ "name": "modelViewMatrix", "desc": "View-space matrix of the model.", "type": "mat4" },
28+
{ "name": "modelNormalMatrix", "desc": "View-space matrix of the model.", "type": "mat3" },
29+
{ "name": "modelWorldMatrix", "desc": "World-space matrix of the model.", "type": "mat4" },
30+
{ "name": "modelPosition", "desc": "Position of the model.", "type": "vec3" },
31+
{ "name": "modelScale", "desc": "Scale of the model.", "type": "vec3" },
32+
{ "name": "modelViewPosition", "desc": "View-space position of the model.", "type": "vec3" },
33+
{ "name": "modelWorldMatrixInverse", "desc": "Inverse world matrix of the model.", "type": "mat4" },
34+
{ "name": "highpModelViewMatrix", "desc": "View-space matrix of the model computed on CPU using 64-bit.", "type": "mat4" },
35+
{ "name": "highpModelNormalViewMatrix", "desc": "View-space normal matrix of the model computed on CPU using 64-bit.", "type": "mat3" }
36+
]],
37+
38+
["Normal", [
39+
{ "name": "normalGeometry", "desc": "Normal attribute of geometry.", "type": "vec3" },
40+
{ "name": "normalLocal", "desc": "Local variable for normal.", "type": "vec3" },
41+
{ "name": "normalView", "desc": "Normalized view normal.", "type": "vec3" },
42+
{ "name": "normalWorld", "desc": "Normalized world normal.", "type": "vec3" },
43+
{ "name": "transformedNormalView", "desc": "Transformed normal in view space.", "type": "vec3" },
44+
{ "name": "transformedNormalWorld", "desc": "Normalized transformed normal in world space.", "type": "vec3" },
45+
{ "name": "transformedClearcoatNormalView", "desc": "Transformed clearcoat normal in view space.", "type": "vec3" }
46+
]],
47+
48+
["Position", [
49+
{ "name": "positionGeometry", "desc": "Position attribute of geometry.", "type": "vec3" },
50+
{ "name": "positionLocal", "desc": "Local variable for position.", "type": "vec3" },
51+
{ "name": "positionWorld", "desc": "World position.", "type": "vec3" },
52+
{ "name": "positionWorldDirection", "desc": "Normalized world direction.", "type": "vec3" },
53+
{ "name": "positionView", "desc": "View position.", "type": "vec3" },
54+
{ "name": "positionViewDirection", "desc": "Normalized view direction.", "type": "vec3" }
55+
]],
56+
57+
["Tangent", [
58+
{ "name": "tangentGeometry", "desc": "Tangent attribute of geometry.", "type": "vec4" },
59+
{ "name": "tangentLocal", "desc": "Local variable for tangent.", "type": "vec3" },
60+
{ "name": "tangentView", "desc": "Normalized view tangent.", "type": "vec3" },
61+
{ "name": "tangentWorld", "desc": "Normalized world tangent.", "type": "vec3" },
62+
{ "name": "transformedTangentView", "desc": "Transformed tangent in view space.", "type": "vec3" },
63+
{ "name": "transformedTangentWorld", "desc": "Normalized transformed tangent in world space.", "type": "vec3" }
64+
]],
65+
66+
["Screen",[
67+
{ "name": "screenUV", "desc": "Returns the normalized frame buffer coordinate.", "type": "vec2" },
68+
{ "name": "screenCoordinate", "desc": "Returns the frame buffer coordinate in physical pixel units.", "type": "vec2" },
69+
{ "name": "screentSize", "desc": "Returns the frame buffer size in physical pixel units.", "type": "vec2" }
70+
]],
71+
72+
["Viewport",[
73+
{ "name": "viewportUV", "desc": "Returns the normalized viewport coordinate.", "type": "vec2" },
74+
{ "name": "viewport", "desc": "Returns the viewport dimension in physical pixel units.", "type": "vec4" },
75+
{ "name": "viewportCoordinate", "desc": "Returns the viewport coordinate in physical pixel units.", "type": "vec2" },
76+
{ "name": "viewportSize", "desc": "Returns the viewport size in physical pixel units.", "type": "vec2" }
77+
]],
78+
79+
["Reflect",[
80+
{ "name": "reflectView", "desc": "Computes reflection direction in view space.", "type": "vec3" },
81+
{ "name": "reflectVector", "desc": "Transforms the reflection direction to world space.", "type": "vec3" }
82+
]]
83+
]
84+
85+
86+
export const tslInputNodes = tslInputs.map( group =>({
87+
TypeClass: PropertiesNode,
88+
name: group[0] ,
89+
id: group[0].toLowerCase(),
90+
constructorArgs: [ group[0], group[1], (s:string)=>s.replace(group[0].toLowerCase(),"") ]
91+
}) )

src/nodes/operators/list.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,12 @@ export const mathFunctions :MethodCallDef[] = [
9292
{ "name": "step", "params": 2, "desc": "Generate a step function by comparing two values." },
9393
{ "name": "tan", "params": 1, "desc": "Return the tangent of the parameter." },
9494
{ "name": "transformDirection", "params": 2, "desc": "Transform the direction of a vector by a matrix and then normalize the result." },
95-
{ "name": "trunc", "params": 1, "desc": "Truncate the parameter, removing the fractional part." }
95+
{ "name": "trunc", "params": 1, "desc": "Truncate the parameter, removing the fractional part." },
96+
97+
//blend modes
98+
{ "name": "blendBurn", "params": 2, "desc": "Returns the burn blend mode." },
99+
{ "name": "blendDodge", "params": 2, "desc": "Returns the dodge blend mode." },
100+
{ "name": "blendOverlay", "params": 2, "desc": "Returns the overlay blend mode." },
101+
{ "name": "blendScreen", "params": 2, "desc": "Returns the screen blend mode." },
102+
{ "name": "blendColor", "params": 2, "desc": "Returns the (normal) color blend mode." }
96103
]

src/util/decamelcase.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* Convert a string in camel case to something human readable...
3+
*/
4+
export function decamelcase(str:string) {
5+
return str
6+
.replace(/([A-Z])/g, " $1") // Add space before capital letters
7+
.trim() // Remove leading space if any
8+
.toLowerCase(); // Convert to lowercase
9+
}

0 commit comments

Comments
 (0)