@kiberon-labs/behave-graph-scene 1.0.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/package.json +34 -0
- package/src/Abstractions/Drivers/DummyScene.ts +79 -0
- package/src/Abstractions/IScene.ts +18 -0
- package/src/GLTFJson.ts +34 -0
- package/src/Nodes/Actions/EaseSceneProperty.ts +162 -0
- package/src/Nodes/Actions/SetSceneProperty.ts +35 -0
- package/src/Nodes/Events/OnSceneNodeClick.ts +66 -0
- package/src/Nodes/Logic/ColorNodes.ts +121 -0
- package/src/Nodes/Logic/EulerNodes.ts +115 -0
- package/src/Nodes/Logic/Mat3Nodes.ts +202 -0
- package/src/Nodes/Logic/Mat4Nodes.ts +257 -0
- package/src/Nodes/Logic/QuatNodes.ts +178 -0
- package/src/Nodes/Logic/Vec2Nodes.ts +111 -0
- package/src/Nodes/Logic/Vec3Nodes.ts +121 -0
- package/src/Nodes/Logic/Vec4Nodes.ts +112 -0
- package/src/Nodes/Logic/VecElements.ts +34 -0
- package/src/Nodes/Queries/GetSceneProperty.ts +35 -0
- package/src/Values/ColorValue.ts +22 -0
- package/src/Values/EulerValue.ts +22 -0
- package/src/Values/Internal/Mat2.ts +214 -0
- package/src/Values/Internal/Mat3.ts +422 -0
- package/src/Values/Internal/Mat4.ts +831 -0
- package/src/Values/Internal/Vec2.ts +97 -0
- package/src/Values/Internal/Vec3.ts +244 -0
- package/src/Values/Internal/Vec4.ts +350 -0
- package/src/Values/Mat3Value.ts +20 -0
- package/src/Values/Mat4Value.ts +20 -0
- package/src/Values/QuatValue.ts +22 -0
- package/src/Values/Vec2Value.ts +14 -0
- package/src/Values/Vec3Value.ts +22 -0
- package/src/Values/Vec4Value.ts +21 -0
- package/src/buildScene.ts +479 -0
- package/src/index.ts +38 -0
- package/src/loadScene.ts +81 -0
- package/src/registerSceneProfile.ts +105 -0
- package/tests/graphs/logic/Color.json +53 -0
- package/tests/graphs/logic/Euler.json +53 -0
- package/tests/graphs/logic/Quaternion.json +56 -0
- package/tests/graphs/logic/Vector2.json +50 -0
- package/tests/graphs/logic/Vector3.json +53 -0
- package/tests/graphs/logic/Vector4.json +56 -0
- package/tests/readSceneGraphs.test.ts +57 -0
- package/tests/registerSceneProfile.test.ts +62 -0
- package/tests/tsconfig.json +11 -0
- package/tests/values/internal/Vec2.test.ts +74 -0
- package/tests/values/internal/Vec3.test.ts +83 -0
- package/tests/values/internal/Vec4.test.ts +91 -0
- package/tsconfig.json +55 -0
- package/tsdown.config.ts +13 -0
- package/vitest.config.ts +15 -0
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kiberon-labs/behave-graph-scene",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"source": "./src/index.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsdown",
|
|
10
|
+
"check": "oxfmt --check",
|
|
11
|
+
"format": "oxfmt",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"dev": "tsdown --watch src",
|
|
14
|
+
"lint": "oxlint",
|
|
15
|
+
"typecheck": "tsc"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/glob": "^8.0.0",
|
|
19
|
+
"@types/node": "^24.10.1",
|
|
20
|
+
"@types/offscreencanvas": "^2019.7.0",
|
|
21
|
+
"@types/three": "0.152.1",
|
|
22
|
+
"oxfmt": "^0.14.0",
|
|
23
|
+
"oxlint": "^1.29.0",
|
|
24
|
+
"tsdown": "^0.16.5",
|
|
25
|
+
"vitest": "^4.0.10"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {},
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"@kiberon-labs/behave-graph": "*",
|
|
31
|
+
"three": "0.152.2",
|
|
32
|
+
"three-stdlib": "^2.22.4"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BooleanValue,
|
|
3
|
+
EventEmitter,
|
|
4
|
+
FloatValue,
|
|
5
|
+
IntegerValue,
|
|
6
|
+
StringValue,
|
|
7
|
+
type ValueType
|
|
8
|
+
} from '@kiberon-labs/behave-graph';
|
|
9
|
+
|
|
10
|
+
import { ColorValue } from '../../Values/ColorValue.js';
|
|
11
|
+
import { EulerValue } from '../../Values/EulerValue.js';
|
|
12
|
+
import { QuatValue } from '../../Values/QuatValue.js';
|
|
13
|
+
import { Vec2Value } from '../../Values/Vec2Value.js';
|
|
14
|
+
import { Vec3Value } from '../../Values/Vec3Value.js';
|
|
15
|
+
import { Vec4Value } from '../../Values/Vec4Value.js';
|
|
16
|
+
import type { IScene } from '../IScene.js';
|
|
17
|
+
|
|
18
|
+
export class DummyScene implements IScene {
|
|
19
|
+
public onSceneChanged = new EventEmitter<void>();
|
|
20
|
+
|
|
21
|
+
private valueRegistry: Record<string, ValueType>;
|
|
22
|
+
|
|
23
|
+
constructor() {
|
|
24
|
+
this.valueRegistry = Object.fromEntries(
|
|
25
|
+
[
|
|
26
|
+
BooleanValue,
|
|
27
|
+
StringValue,
|
|
28
|
+
IntegerValue,
|
|
29
|
+
FloatValue,
|
|
30
|
+
Vec2Value,
|
|
31
|
+
Vec3Value,
|
|
32
|
+
Vec4Value,
|
|
33
|
+
ColorValue,
|
|
34
|
+
EulerValue,
|
|
35
|
+
QuatValue
|
|
36
|
+
].map((valueType) => [valueType.name, valueType])
|
|
37
|
+
);
|
|
38
|
+
// pull in value type nodes
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getProperty(jsonPath: string, valueTypeName: string): any {
|
|
42
|
+
return this.valueRegistry[valueTypeName]?.creator();
|
|
43
|
+
}
|
|
44
|
+
setProperty(): void {
|
|
45
|
+
this.onSceneChanged.emit();
|
|
46
|
+
}
|
|
47
|
+
addOnClickedListener(
|
|
48
|
+
jsonPath: string,
|
|
49
|
+
callback: (jsonPath: string) => void
|
|
50
|
+
): void {
|
|
51
|
+
console.log('added on clicked listener');
|
|
52
|
+
}
|
|
53
|
+
removeOnClickedListener(
|
|
54
|
+
jsonPath: string,
|
|
55
|
+
callback: (jsonPath: string) => void
|
|
56
|
+
): void {
|
|
57
|
+
console.log('removed on clicked listener');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getQueryableProperties() {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
getRaycastableProperties() {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
getProperties() {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
addOnSceneChangedListener() {
|
|
73
|
+
console.log('added on scene changed listener');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
removeOnSceneChangedListener(): void {
|
|
77
|
+
console.log('removed on scene changed listener');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Choices } from '@kiberon-labs/behave-graph';
|
|
2
|
+
|
|
3
|
+
export interface IScene {
|
|
4
|
+
getProperty(jsonPath: string, valueTypeName: string): any;
|
|
5
|
+
setProperty(jsonPath: string, valueTypeName: string, value: any): void;
|
|
6
|
+
addOnClickedListener(
|
|
7
|
+
jsonPath: string,
|
|
8
|
+
callback: (jsonPath: string) => void
|
|
9
|
+
): void;
|
|
10
|
+
removeOnClickedListener(
|
|
11
|
+
jsonPath: string,
|
|
12
|
+
callback: (jsonPath: string) => void
|
|
13
|
+
): void;
|
|
14
|
+
getRaycastableProperties: () => Choices;
|
|
15
|
+
getProperties: () => Choices;
|
|
16
|
+
addOnSceneChangedListener(listener: () => void): void;
|
|
17
|
+
removeOnSceneChangedListener(listener: () => void): void;
|
|
18
|
+
}
|
package/src/GLTFJson.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type GLTFAssetJson = {
|
|
2
|
+
generator: string;
|
|
3
|
+
version: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type GLTFSceneJson = {
|
|
7
|
+
name: string;
|
|
8
|
+
nodes: number[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type GLTFNodeJson = {
|
|
12
|
+
name?: string;
|
|
13
|
+
mesh?: number;
|
|
14
|
+
translation?: number[];
|
|
15
|
+
children?: number[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type GLTFMaterialJson = {
|
|
19
|
+
name?: string;
|
|
20
|
+
doubleSided?: boolean;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type GLTFMeshJson = {
|
|
24
|
+
name?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type GLTFJson = {
|
|
28
|
+
asset: GLTFAssetJson;
|
|
29
|
+
scene: number;
|
|
30
|
+
scenes: GLTFSceneJson[];
|
|
31
|
+
nodes: GLTFNodeJson[];
|
|
32
|
+
materials: GLTFMaterialJson[];
|
|
33
|
+
meshes: GLTFMeshJson[];
|
|
34
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AsyncNode,
|
|
3
|
+
type Easing,
|
|
4
|
+
EasingFunctions,
|
|
5
|
+
EasingModes,
|
|
6
|
+
Engine,
|
|
7
|
+
type IGraph,
|
|
8
|
+
type ILifecycleEventEmitter,
|
|
9
|
+
NodeDescription,
|
|
10
|
+
Socket,
|
|
11
|
+
toCamelCase
|
|
12
|
+
} from '@kiberon-labs/behave-graph';
|
|
13
|
+
|
|
14
|
+
import type { IScene } from '../../Abstractions/IScene.js';
|
|
15
|
+
|
|
16
|
+
export class EaseSceneProperty extends AsyncNode {
|
|
17
|
+
public static GetDescriptions(
|
|
18
|
+
scene: IScene,
|
|
19
|
+
lifecycleEventEmitter: ILifecycleEventEmitter,
|
|
20
|
+
...valueTypeNames: string[]
|
|
21
|
+
) {
|
|
22
|
+
return valueTypeNames.map(
|
|
23
|
+
(valueTypeName) =>
|
|
24
|
+
new NodeDescription(
|
|
25
|
+
`scene/ease/${valueTypeName}`,
|
|
26
|
+
'Action',
|
|
27
|
+
`Ease Scene ${toCamelCase(valueTypeName)}`,
|
|
28
|
+
(description, graph, config, id) =>
|
|
29
|
+
new EaseSceneProperty(
|
|
30
|
+
description,
|
|
31
|
+
graph,
|
|
32
|
+
valueTypeName,
|
|
33
|
+
scene,
|
|
34
|
+
lifecycleEventEmitter,
|
|
35
|
+
id
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public readonly valueTypeName: string;
|
|
42
|
+
private readonly scene: IScene;
|
|
43
|
+
private readonly lifecycleEventEmitter: ILifecycleEventEmitter;
|
|
44
|
+
|
|
45
|
+
constructor(
|
|
46
|
+
description: NodeDescription,
|
|
47
|
+
graph: IGraph,
|
|
48
|
+
valueTypeName: string,
|
|
49
|
+
scene: IScene,
|
|
50
|
+
lifecycleEventEmitter: ILifecycleEventEmitter,
|
|
51
|
+
id: string
|
|
52
|
+
) {
|
|
53
|
+
super(
|
|
54
|
+
description,
|
|
55
|
+
graph,
|
|
56
|
+
[
|
|
57
|
+
new Socket('flow', 'flow'),
|
|
58
|
+
new Socket('string', 'jsonPath'),
|
|
59
|
+
new Socket(valueTypeName, 'value'),
|
|
60
|
+
new Socket(
|
|
61
|
+
'string',
|
|
62
|
+
'easingFunction',
|
|
63
|
+
'linear',
|
|
64
|
+
undefined,
|
|
65
|
+
Object.keys(EasingFunctions)
|
|
66
|
+
),
|
|
67
|
+
new Socket(
|
|
68
|
+
'string',
|
|
69
|
+
'easingMode',
|
|
70
|
+
'inOut',
|
|
71
|
+
undefined,
|
|
72
|
+
Object.keys(EasingModes)
|
|
73
|
+
),
|
|
74
|
+
new Socket('float', 'easeDuration'),
|
|
75
|
+
new Socket('flow', 'cancel')
|
|
76
|
+
],
|
|
77
|
+
[new Socket('flow', 'flow')],
|
|
78
|
+
{},
|
|
79
|
+
id
|
|
80
|
+
);
|
|
81
|
+
this.valueTypeName = valueTypeName;
|
|
82
|
+
this.scene = scene;
|
|
83
|
+
this.lifecycleEventEmitter = lifecycleEventEmitter;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private initialValue: any = undefined;
|
|
87
|
+
private targetValue: any = undefined;
|
|
88
|
+
private duration = 0;
|
|
89
|
+
private elapsedDuration = 0;
|
|
90
|
+
private easing: Easing = EasingFunctions['linear'];
|
|
91
|
+
private startTime = 0;
|
|
92
|
+
private onTick: (() => void) | undefined = undefined;
|
|
93
|
+
|
|
94
|
+
override triggered(
|
|
95
|
+
engine: Engine,
|
|
96
|
+
triggeringSocketName: string,
|
|
97
|
+
finished: () => void
|
|
98
|
+
) {
|
|
99
|
+
if (triggeringSocketName === 'cancel') {
|
|
100
|
+
this.dispose();
|
|
101
|
+
finished();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// if existing ease in progress, do nothing
|
|
106
|
+
if (this.elapsedDuration >= this.duration) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.initialValue = this.scene.getProperty(
|
|
111
|
+
this.readInput('jsonPath'),
|
|
112
|
+
this.valueTypeName
|
|
113
|
+
);
|
|
114
|
+
this.targetValue = this.readInput('value');
|
|
115
|
+
this.duration = this.readInput<number>('duration');
|
|
116
|
+
this.elapsedDuration = 0;
|
|
117
|
+
this.startTime = Date.now();
|
|
118
|
+
|
|
119
|
+
const easingFunction =
|
|
120
|
+
EasingFunctions[
|
|
121
|
+
this.readInput('easingFunction') as keyof typeof EasingFunctions
|
|
122
|
+
];
|
|
123
|
+
const easingMode =
|
|
124
|
+
EasingModes[this.readInput('easingMode') as keyof typeof EasingModes];
|
|
125
|
+
this.easing = easingMode(easingFunction);
|
|
126
|
+
|
|
127
|
+
const updateOnTick = () => {
|
|
128
|
+
const valueType = this.graph.values[this.valueTypeName]!;
|
|
129
|
+
this.elapsedDuration = (Date.now() - this.startTime) / 1000;
|
|
130
|
+
|
|
131
|
+
const t = Math.min(this.elapsedDuration / this.duration, 1);
|
|
132
|
+
const easedValue = valueType.lerp(
|
|
133
|
+
this.initialValue,
|
|
134
|
+
this.targetValue,
|
|
135
|
+
this.easing(t)
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
this.scene.setProperty(
|
|
139
|
+
this.readInput('jsonPath'),
|
|
140
|
+
this.valueTypeName,
|
|
141
|
+
easedValue
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
if (this.elapsedDuration >= this.duration) {
|
|
145
|
+
this.dispose();
|
|
146
|
+
engine.commitToNewFiber(this, 'flow');
|
|
147
|
+
finished();
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
this.onTick = updateOnTick;
|
|
152
|
+
this.lifecycleEventEmitter.tickEvent.addListener(this.onTick);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
override dispose() {
|
|
156
|
+
this.elapsedDuration = this.duration = 0;
|
|
157
|
+
if (this.onTick !== undefined) {
|
|
158
|
+
this.lifecycleEventEmitter.tickEvent.removeListener(this.onTick);
|
|
159
|
+
this.onTick = undefined;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
makeFlowNodeDefinition,
|
|
3
|
+
NodeCategory
|
|
4
|
+
} from '@kiberon-labs/behave-graph';
|
|
5
|
+
|
|
6
|
+
import type { IScene } from '../../Abstractions/IScene.js';
|
|
7
|
+
|
|
8
|
+
export const SetSceneProperty = (valueTypeNames: string[]) =>
|
|
9
|
+
valueTypeNames.map((valueTypeName) =>
|
|
10
|
+
makeFlowNodeDefinition({
|
|
11
|
+
typeName: `scene/set/${valueTypeName}`,
|
|
12
|
+
category: NodeCategory.Effect,
|
|
13
|
+
label: `Set Scene ${valueTypeName}`,
|
|
14
|
+
in: {
|
|
15
|
+
jsonPath: (_, graphApi) => {
|
|
16
|
+
const scene = graphApi.getDependency<IScene>('IScene');
|
|
17
|
+
return {
|
|
18
|
+
valueType: 'string',
|
|
19
|
+
choices: scene?.getProperties()
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
value: valueTypeName,
|
|
23
|
+
flow: 'flow'
|
|
24
|
+
},
|
|
25
|
+
out: {
|
|
26
|
+
flow: 'flow'
|
|
27
|
+
},
|
|
28
|
+
initialState: undefined,
|
|
29
|
+
triggered: ({ commit, read, graph }) => {
|
|
30
|
+
const scene = graph.getDependency<IScene>('IScene');
|
|
31
|
+
scene?.setProperty(read('jsonPath'), valueTypeName, read('value'));
|
|
32
|
+
commit('flow');
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Assert,
|
|
3
|
+
makeEventNodeDefinition,
|
|
4
|
+
NodeCategory
|
|
5
|
+
} from '@kiberon-labs/behave-graph';
|
|
6
|
+
|
|
7
|
+
import type { IScene } from '../../Abstractions/IScene.js';
|
|
8
|
+
|
|
9
|
+
type State = {
|
|
10
|
+
jsonPath?: string | undefined;
|
|
11
|
+
handleNodeClick?: ((jsonPath: string) => void) | undefined;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const initialState = (): State => ({});
|
|
15
|
+
|
|
16
|
+
// very 3D specific.
|
|
17
|
+
export const OnSceneNodeClick = makeEventNodeDefinition({
|
|
18
|
+
typeName: 'scene/nodeClick',
|
|
19
|
+
category: NodeCategory.Event,
|
|
20
|
+
label: 'On Scene Node Click',
|
|
21
|
+
in: {
|
|
22
|
+
jsonPath: (_, graphApi) => {
|
|
23
|
+
const scene = graphApi.getDependency<IScene>('IScene');
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
valueType: 'string',
|
|
27
|
+
choices: scene?.getRaycastableProperties()
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
out: {
|
|
32
|
+
flow: 'flow'
|
|
33
|
+
},
|
|
34
|
+
initialState: initialState(),
|
|
35
|
+
init: ({ read, commit, graph }) => {
|
|
36
|
+
const handleNodeClick = () => {
|
|
37
|
+
commit('flow');
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const jsonPath = read<string>('jsonPath');
|
|
41
|
+
|
|
42
|
+
const scene = graph.getDependency<IScene>('IScene');
|
|
43
|
+
scene?.addOnClickedListener(jsonPath, handleNodeClick);
|
|
44
|
+
|
|
45
|
+
const state: State = {
|
|
46
|
+
handleNodeClick,
|
|
47
|
+
jsonPath
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return state;
|
|
51
|
+
},
|
|
52
|
+
dispose: ({
|
|
53
|
+
state: { handleNodeClick, jsonPath },
|
|
54
|
+
graph: { getDependency }
|
|
55
|
+
}) => {
|
|
56
|
+
Assert.mustBeTrue(handleNodeClick !== undefined);
|
|
57
|
+
Assert.mustBeTrue(jsonPath !== undefined);
|
|
58
|
+
|
|
59
|
+
if (!jsonPath || !handleNodeClick) return {};
|
|
60
|
+
|
|
61
|
+
const scene = getDependency<IScene>('scene');
|
|
62
|
+
scene?.removeOnClickedListener(jsonPath, handleNodeClick);
|
|
63
|
+
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { makeInNOutFunctionDesc } from '@kiberon-labs/behave-graph';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
hexToRGB,
|
|
5
|
+
hslToRGB,
|
|
6
|
+
rgbToHex,
|
|
7
|
+
rgbToHSL,
|
|
8
|
+
Vec3,
|
|
9
|
+
vec3Add,
|
|
10
|
+
vec3Equals,
|
|
11
|
+
vec3Mix,
|
|
12
|
+
vec3MultiplyByScalar,
|
|
13
|
+
vec3Negate,
|
|
14
|
+
vec3Subtract
|
|
15
|
+
} from '../../Values/Internal/Vec3.js';
|
|
16
|
+
|
|
17
|
+
export const Constant = makeInNOutFunctionDesc({
|
|
18
|
+
name: 'math/color',
|
|
19
|
+
label: 'Color',
|
|
20
|
+
in: ['color'],
|
|
21
|
+
out: 'color',
|
|
22
|
+
exec: (a: Vec3) => a
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const Create = makeInNOutFunctionDesc({
|
|
26
|
+
name: 'math/toColor/rgb',
|
|
27
|
+
label: 'RGB To Color',
|
|
28
|
+
in: [{ r: 'float' }, { g: 'float' }, { b: 'float' }],
|
|
29
|
+
out: 'color',
|
|
30
|
+
exec: (r: number, g: number, b: number) => new Vec3(r, g, b)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const Elements = makeInNOutFunctionDesc({
|
|
34
|
+
name: 'math/toRgb/color',
|
|
35
|
+
label: 'Color to RGB',
|
|
36
|
+
in: ['color'],
|
|
37
|
+
out: [{ r: 'float' }, { g: 'float' }, { b: 'float' }],
|
|
38
|
+
exec: (a: Vec3) => {
|
|
39
|
+
return { r: a.x, g: a.y, b: a.z };
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const Add = makeInNOutFunctionDesc({
|
|
44
|
+
name: 'math/add/color',
|
|
45
|
+
label: '+',
|
|
46
|
+
in: ['color', 'color'],
|
|
47
|
+
out: 'color',
|
|
48
|
+
exec: vec3Add
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const Subtract = makeInNOutFunctionDesc({
|
|
52
|
+
name: 'math/subtract/color',
|
|
53
|
+
label: '-',
|
|
54
|
+
in: ['color', 'color'],
|
|
55
|
+
out: 'color',
|
|
56
|
+
exec: vec3Subtract
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export const Negate = makeInNOutFunctionDesc({
|
|
60
|
+
name: 'math/negate/color',
|
|
61
|
+
label: '-',
|
|
62
|
+
in: ['color'],
|
|
63
|
+
out: 'color',
|
|
64
|
+
exec: vec3Negate
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
export const Scale = makeInNOutFunctionDesc({
|
|
68
|
+
name: 'math/scale/color',
|
|
69
|
+
label: '×',
|
|
70
|
+
in: ['color', 'float'],
|
|
71
|
+
out: 'color',
|
|
72
|
+
exec: vec3MultiplyByScalar
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
export const Mix = makeInNOutFunctionDesc({
|
|
76
|
+
name: 'math/mix/color',
|
|
77
|
+
label: '÷',
|
|
78
|
+
in: [{ a: 'color' }, { b: 'color' }, { t: 'float' }],
|
|
79
|
+
out: 'color',
|
|
80
|
+
exec: vec3Mix
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export const HslToColor = makeInNOutFunctionDesc({
|
|
84
|
+
name: 'math/ToColor/hsl',
|
|
85
|
+
label: 'HSL to Color',
|
|
86
|
+
in: ['vec3'],
|
|
87
|
+
out: 'color',
|
|
88
|
+
exec: hslToRGB
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
export const ColorToHsl = makeInNOutFunctionDesc({
|
|
92
|
+
name: 'math/toHsl/color',
|
|
93
|
+
label: 'Color to HSL',
|
|
94
|
+
in: ['color'],
|
|
95
|
+
out: 'vec3',
|
|
96
|
+
exec: rgbToHSL
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
export const HexToColor = makeInNOutFunctionDesc({
|
|
100
|
+
name: 'math/toColor/hex',
|
|
101
|
+
label: 'HEX to Color',
|
|
102
|
+
in: ['float'],
|
|
103
|
+
out: 'color',
|
|
104
|
+
exec: hexToRGB
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const ColorToHex = makeInNOutFunctionDesc({
|
|
108
|
+
name: 'math/toHex/color',
|
|
109
|
+
label: 'Color to HEX',
|
|
110
|
+
in: ['color'],
|
|
111
|
+
out: 'float',
|
|
112
|
+
exec: rgbToHex
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export const Equal = makeInNOutFunctionDesc({
|
|
116
|
+
name: 'math/equal/color',
|
|
117
|
+
label: '=',
|
|
118
|
+
in: [{ a: 'color' }, { b: 'color' }, { tolerance: 'float' }],
|
|
119
|
+
out: 'boolean',
|
|
120
|
+
exec: vec3Equals
|
|
121
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { makeInNOutFunctionDesc } from '@kiberon-labs/behave-graph';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
mat3ToEuler,
|
|
5
|
+
mat4ToEuler,
|
|
6
|
+
quatToEuler,
|
|
7
|
+
Vec3,
|
|
8
|
+
vec3Add,
|
|
9
|
+
vec3Equals,
|
|
10
|
+
vec3Mix,
|
|
11
|
+
vec3MultiplyByScalar,
|
|
12
|
+
vec3Negate,
|
|
13
|
+
vec3Subtract
|
|
14
|
+
} from '../../Values/Internal/Vec3.js';
|
|
15
|
+
|
|
16
|
+
export const Constant = makeInNOutFunctionDesc({
|
|
17
|
+
name: 'math/euler',
|
|
18
|
+
label: 'Euler',
|
|
19
|
+
in: ['euler'],
|
|
20
|
+
out: 'euler',
|
|
21
|
+
exec: (a: Vec3) => a
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const Create = makeInNOutFunctionDesc({
|
|
25
|
+
name: 'math/toEuler/float',
|
|
26
|
+
label: 'Float to Euler',
|
|
27
|
+
in: [{ x: 'float' }, { y: 'float' }, { z: 'float' }],
|
|
28
|
+
out: 'euler',
|
|
29
|
+
exec: (x: number, y: number, z: number) => new Vec3(x, y, z)
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const Elements = makeInNOutFunctionDesc({
|
|
33
|
+
name: 'math/toFloat/euler',
|
|
34
|
+
label: 'Euler to Float',
|
|
35
|
+
in: ['euler'],
|
|
36
|
+
out: [{ x: 'float' }, { y: 'float' }, { z: 'float' }],
|
|
37
|
+
exec: (a: Vec3) => {
|
|
38
|
+
return { x: a.x, y: a.y, z: a.z };
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const Add = makeInNOutFunctionDesc({
|
|
43
|
+
name: 'math/add/euler',
|
|
44
|
+
label: '+',
|
|
45
|
+
in: ['euler', 'euler'],
|
|
46
|
+
out: 'euler',
|
|
47
|
+
exec: vec3Add
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const Subtract = makeInNOutFunctionDesc({
|
|
51
|
+
name: 'math/subtract/euler',
|
|
52
|
+
label: '-',
|
|
53
|
+
in: ['euler', 'euler'],
|
|
54
|
+
out: 'euler',
|
|
55
|
+
exec: vec3Subtract
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const Negate = makeInNOutFunctionDesc({
|
|
59
|
+
name: 'math/negate/euler',
|
|
60
|
+
label: '-',
|
|
61
|
+
in: ['euler'],
|
|
62
|
+
out: 'euler',
|
|
63
|
+
exec: vec3Negate
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export const Scale = makeInNOutFunctionDesc({
|
|
67
|
+
name: 'math/scale/euler',
|
|
68
|
+
label: '×',
|
|
69
|
+
in: ['euler', 'float'],
|
|
70
|
+
out: 'euler',
|
|
71
|
+
exec: vec3MultiplyByScalar
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export const Mix = makeInNOutFunctionDesc({
|
|
75
|
+
name: 'math/mix/euler',
|
|
76
|
+
label: '÷',
|
|
77
|
+
in: [{ a: 'euler' }, { b: 'euler' }, { t: 'float' }],
|
|
78
|
+
out: 'euler',
|
|
79
|
+
exec: (a: Vec3, b: Vec3, t: number) => {
|
|
80
|
+
console.warn('TODO: this is not shortest path');
|
|
81
|
+
return vec3Mix(a, b, t);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export const Mat3ToEuler = makeInNOutFunctionDesc({
|
|
86
|
+
name: 'math/toEuler/mat3',
|
|
87
|
+
label: 'To Euler',
|
|
88
|
+
in: ['mat3'],
|
|
89
|
+
out: 'euler',
|
|
90
|
+
exec: mat3ToEuler
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export const Mat4ToEuler = makeInNOutFunctionDesc({
|
|
94
|
+
name: 'math/toEuler/mat4',
|
|
95
|
+
label: 'To Euler',
|
|
96
|
+
in: ['mat4'],
|
|
97
|
+
out: 'euler',
|
|
98
|
+
exec: mat4ToEuler
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
export const QuatToEuler = makeInNOutFunctionDesc({
|
|
102
|
+
name: 'math/toEuler/quat',
|
|
103
|
+
label: 'To Euler',
|
|
104
|
+
in: ['quat'],
|
|
105
|
+
out: 'euler',
|
|
106
|
+
exec: quatToEuler
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
export const Equal = makeInNOutFunctionDesc({
|
|
110
|
+
name: 'math/equal/euler',
|
|
111
|
+
label: '=',
|
|
112
|
+
in: [{ a: 'euler' }, { b: 'euler' }, { tolerance: 'float' }],
|
|
113
|
+
out: 'boolean',
|
|
114
|
+
exec: vec3Equals
|
|
115
|
+
});
|