@kiberon-labs/behave-graph-scene 1.0.1 → 2.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.
Files changed (214) hide show
  1. package/.storybook/main.ts +18 -0
  2. package/.storybook/preview.ts +16 -0
  3. package/.storybook/vscode.css +822 -0
  4. package/.turbo/turbo-build.log +4 -3
  5. package/CHANGELOG.md +84 -0
  6. package/README.md +1 -1
  7. package/dist/Abstractions/Drivers/DummyScene.d.ts +47 -3
  8. package/dist/Abstractions/Drivers/DummyScene.d.ts.map +1 -1
  9. package/dist/Abstractions/Drivers/DummyScene.js +57 -0
  10. package/dist/Abstractions/Drivers/DummyScene.js.map +1 -1
  11. package/dist/Abstractions/IScene.d.ts +63 -4
  12. package/dist/Abstractions/IScene.d.ts.map +1 -1
  13. package/dist/Abstractions/IScene.js +19 -0
  14. package/dist/Abstractions/IScene.js.map +1 -0
  15. package/dist/Nodes/Actions/AddLight.d.ts +21 -0
  16. package/dist/Nodes/Actions/AddLight.d.ts.map +1 -0
  17. package/dist/Nodes/Actions/AddLight.js +38 -0
  18. package/dist/Nodes/Actions/AddLight.js.map +1 -0
  19. package/dist/Nodes/Actions/CloneMesh.d.ts +16 -0
  20. package/dist/Nodes/Actions/CloneMesh.d.ts.map +1 -0
  21. package/dist/Nodes/Actions/CloneMesh.js +28 -0
  22. package/dist/Nodes/Actions/CloneMesh.js.map +1 -0
  23. package/dist/Nodes/Actions/CreateMesh.d.ts +22 -0
  24. package/dist/Nodes/Actions/CreateMesh.d.ts.map +1 -0
  25. package/dist/Nodes/Actions/CreateMesh.js +44 -0
  26. package/dist/Nodes/Actions/CreateMesh.js.map +1 -0
  27. package/dist/Nodes/Actions/DeleteMesh.d.ts +15 -0
  28. package/dist/Nodes/Actions/DeleteMesh.d.ts.map +1 -0
  29. package/dist/Nodes/Actions/DeleteMesh.js +27 -0
  30. package/dist/Nodes/Actions/DeleteMesh.js.map +1 -0
  31. package/dist/Nodes/Actions/EaseSceneProperty.d.ts +1 -1
  32. package/dist/Nodes/Actions/EaseSceneProperty.d.ts.map +1 -1
  33. package/dist/Nodes/Actions/EaseSceneProperty.js +2 -2
  34. package/dist/Nodes/Actions/EaseSceneProperty.js.map +1 -1
  35. package/dist/Nodes/Actions/LookAt.d.ts +16 -0
  36. package/dist/Nodes/Actions/LookAt.d.ts.map +1 -0
  37. package/dist/Nodes/Actions/LookAt.js +35 -0
  38. package/dist/Nodes/Actions/LookAt.js.map +1 -0
  39. package/dist/Nodes/Actions/MoveTowards.d.ts +21 -0
  40. package/dist/Nodes/Actions/MoveTowards.d.ts.map +1 -0
  41. package/dist/Nodes/Actions/MoveTowards.js +46 -0
  42. package/dist/Nodes/Actions/MoveTowards.js.map +1 -0
  43. package/dist/Nodes/Actions/RemoveLight.d.ts +15 -0
  44. package/dist/Nodes/Actions/RemoveLight.d.ts.map +1 -0
  45. package/dist/Nodes/Actions/RemoveLight.js +27 -0
  46. package/dist/Nodes/Actions/RemoveLight.js.map +1 -0
  47. package/dist/Nodes/Actions/SetLightProperty.d.ts +25 -0
  48. package/dist/Nodes/Actions/SetLightProperty.d.ts.map +1 -0
  49. package/dist/Nodes/Actions/SetLightProperty.js +64 -0
  50. package/dist/Nodes/Actions/SetLightProperty.js.map +1 -0
  51. package/dist/Nodes/Actions/SetMaterialProperty.d.ts +25 -0
  52. package/dist/Nodes/Actions/SetMaterialProperty.d.ts.map +1 -0
  53. package/dist/Nodes/Actions/SetMaterialProperty.js +69 -0
  54. package/dist/Nodes/Actions/SetMaterialProperty.js.map +1 -0
  55. package/dist/Nodes/Actions/SetMeshPosition.d.ts +18 -0
  56. package/dist/Nodes/Actions/SetMeshPosition.d.ts.map +1 -0
  57. package/dist/Nodes/Actions/SetMeshPosition.js +34 -0
  58. package/dist/Nodes/Actions/SetMeshPosition.js.map +1 -0
  59. package/dist/Nodes/Actions/SetMeshVisible.d.ts +16 -0
  60. package/dist/Nodes/Actions/SetMeshVisible.d.ts.map +1 -0
  61. package/dist/Nodes/Actions/SetMeshVisible.js +28 -0
  62. package/dist/Nodes/Actions/SetMeshVisible.js.map +1 -0
  63. package/dist/Nodes/Actions/SetSceneProperty.d.ts +12 -1
  64. package/dist/Nodes/Actions/SetSceneProperty.d.ts.map +1 -1
  65. package/dist/Nodes/Actions/SetSceneProperty.js +1 -1
  66. package/dist/Nodes/Actions/SetSceneProperty.js.map +1 -1
  67. package/dist/Nodes/Events/OnAnyMeshClicked.d.ts +13 -0
  68. package/dist/Nodes/Events/OnAnyMeshClicked.d.ts.map +1 -0
  69. package/dist/Nodes/Events/OnAnyMeshClicked.js +34 -0
  70. package/dist/Nodes/Events/OnAnyMeshClicked.js.map +1 -0
  71. package/dist/Nodes/Events/OnSceneChanged.d.ts +12 -0
  72. package/dist/Nodes/Events/OnSceneChanged.d.ts.map +1 -0
  73. package/dist/Nodes/Events/OnSceneChanged.js +28 -0
  74. package/dist/Nodes/Events/OnSceneChanged.js.map +1 -0
  75. package/dist/Nodes/Events/OnSceneNodeClick.d.ts +14 -1
  76. package/dist/Nodes/Events/OnSceneNodeClick.d.ts.map +1 -1
  77. package/dist/Nodes/Events/OnSceneNodeClick.js +1 -1
  78. package/dist/Nodes/Events/OnSceneNodeClick.js.map +1 -1
  79. package/dist/Nodes/Logic/ColorNodes.d.ts +17 -13
  80. package/dist/Nodes/Logic/ColorNodes.d.ts.map +1 -1
  81. package/dist/Nodes/Logic/EulerNodes.d.ts +16 -12
  82. package/dist/Nodes/Logic/EulerNodes.d.ts.map +1 -1
  83. package/dist/Nodes/Logic/Mat3Nodes.d.ts +26 -23
  84. package/dist/Nodes/Logic/Mat3Nodes.d.ts.map +1 -1
  85. package/dist/Nodes/Logic/Mat3Nodes.js +0 -14
  86. package/dist/Nodes/Logic/Mat3Nodes.js.map +1 -1
  87. package/dist/Nodes/Logic/Mat4Nodes.d.ts +32 -28
  88. package/dist/Nodes/Logic/Mat4Nodes.d.ts.map +1 -1
  89. package/dist/Nodes/Logic/QuatNodes.d.ts +22 -18
  90. package/dist/Nodes/Logic/QuatNodes.d.ts.map +1 -1
  91. package/dist/Nodes/Logic/Vec2Nodes.d.ts +16 -12
  92. package/dist/Nodes/Logic/Vec2Nodes.d.ts.map +1 -1
  93. package/dist/Nodes/Logic/Vec3Nodes.d.ts +17 -13
  94. package/dist/Nodes/Logic/Vec3Nodes.d.ts.map +1 -1
  95. package/dist/Nodes/Logic/Vec4Nodes.d.ts +16 -12
  96. package/dist/Nodes/Logic/Vec4Nodes.d.ts.map +1 -1
  97. package/dist/Nodes/Queries/GetDistanceBetween.d.ts +18 -0
  98. package/dist/Nodes/Queries/GetDistanceBetween.d.ts.map +1 -0
  99. package/dist/Nodes/Queries/GetDistanceBetween.js +30 -0
  100. package/dist/Nodes/Queries/GetDistanceBetween.js.map +1 -0
  101. package/dist/Nodes/Queries/GetLightProperty.d.ts +23 -0
  102. package/dist/Nodes/Queries/GetLightProperty.d.ts.map +1 -0
  103. package/dist/Nodes/Queries/GetLightProperty.js +68 -0
  104. package/dist/Nodes/Queries/GetLightProperty.js.map +1 -0
  105. package/dist/Nodes/Queries/GetMaterialProperty.d.ts +23 -0
  106. package/dist/Nodes/Queries/GetMaterialProperty.d.ts.map +1 -0
  107. package/dist/Nodes/Queries/GetMaterialProperty.js +69 -0
  108. package/dist/Nodes/Queries/GetMaterialProperty.js.map +1 -0
  109. package/dist/Nodes/Queries/GetMeshPosition.d.ts +16 -0
  110. package/dist/Nodes/Queries/GetMeshPosition.d.ts.map +1 -0
  111. package/dist/Nodes/Queries/GetMeshPosition.js +29 -0
  112. package/dist/Nodes/Queries/GetMeshPosition.js.map +1 -0
  113. package/dist/Nodes/Queries/GetSceneProperty.d.ts +10 -1
  114. package/dist/Nodes/Queries/GetSceneProperty.d.ts.map +1 -1
  115. package/dist/Nodes/Queries/GetSceneProperty.js +2 -2
  116. package/dist/Nodes/Queries/GetSceneProperty.js.map +1 -1
  117. package/dist/Values/Internal/Mat3.d.ts +1 -1
  118. package/dist/Values/Internal/Mat3.d.ts.map +1 -1
  119. package/dist/Values/Internal/Mat3.js +1 -3
  120. package/dist/Values/Internal/Mat3.js.map +1 -1
  121. package/dist/Values/Internal/Mat4.d.ts.map +1 -1
  122. package/dist/Values/Internal/Mat4.js +1 -3
  123. package/dist/Values/Internal/Mat4.js.map +1 -1
  124. package/dist/Values/Internal/Vec3.d.ts +1 -1
  125. package/dist/Values/Internal/Vec3.d.ts.map +1 -1
  126. package/dist/Values/Internal/Vec3.js +0 -2
  127. package/dist/Values/Internal/Vec3.js.map +1 -1
  128. package/dist/Values/Internal/Vec4.d.ts.map +1 -1
  129. package/dist/Values/Internal/Vec4.js +0 -1
  130. package/dist/Values/Internal/Vec4.js.map +1 -1
  131. package/dist/_virtual/rolldown_runtime.js +23 -1
  132. package/dist/behave-graph.manifest.json +6082 -0
  133. package/dist/buildScene.d.ts.map +1 -1
  134. package/dist/buildScene.js +24 -3
  135. package/dist/buildScene.js.map +1 -1
  136. package/dist/index.d.ts +29 -3
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +22 -4
  139. package/dist/manifest.source.d.ts +7 -0
  140. package/dist/manifest.source.d.ts.map +1 -0
  141. package/dist/manifest.source.js +54 -0
  142. package/dist/manifest.source.js.map +1 -0
  143. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.development.js +207 -0
  144. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.development.js.map +1 -0
  145. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.production.js +40 -0
  146. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.production.js.map +1 -0
  147. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.development.js +766 -0
  148. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.development.js.map +1 -0
  149. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.production.js +367 -0
  150. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.production.js.map +1 -0
  151. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/index.js +15 -0
  152. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/index.js.map +1 -0
  153. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js +15 -0
  154. package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js.map +1 -0
  155. package/dist/packages/nodes/scene/package.js +7 -0
  156. package/dist/packages/nodes/scene/package.js.map +1 -0
  157. package/dist/registerSceneProfile.d.ts +3 -3
  158. package/dist/registerSceneProfile.d.ts.map +1 -1
  159. package/dist/registerSceneProfile.js +35 -1
  160. package/dist/registerSceneProfile.js.map +1 -1
  161. package/dist/ui/controls/vec3.d.ts +9 -0
  162. package/dist/ui/controls/vec3.d.ts.map +1 -0
  163. package/dist/ui/controls/vec3.js +99 -0
  164. package/dist/ui/controls/vec3.js.map +1 -0
  165. package/package.json +28 -9
  166. package/src/Abstractions/Drivers/DummyScene.ts +110 -2
  167. package/src/Abstractions/IScene.ts +74 -3
  168. package/src/Nodes/Actions/AddLight.ts +46 -0
  169. package/src/Nodes/Actions/CloneMesh.ts +31 -0
  170. package/src/Nodes/Actions/CreateMesh.ts +47 -0
  171. package/src/Nodes/Actions/DeleteMesh.ts +29 -0
  172. package/src/Nodes/Actions/EaseSceneProperty.ts +6 -2
  173. package/src/Nodes/Actions/LookAt.ts +34 -0
  174. package/src/Nodes/Actions/MoveTowards.ts +55 -0
  175. package/src/Nodes/Actions/RemoveLight.ts +29 -0
  176. package/src/Nodes/Actions/SetLightProperty.ts +60 -0
  177. package/src/Nodes/Actions/SetMaterialProperty.ts +62 -0
  178. package/src/Nodes/Actions/SetMeshPosition.ts +37 -0
  179. package/src/Nodes/Actions/SetMeshVisible.ts +31 -0
  180. package/src/Nodes/Actions/SetSceneProperty.ts +3 -5
  181. package/src/Nodes/Events/OnAnyMeshClicked.ts +48 -0
  182. package/src/Nodes/Events/OnSceneChanged.ts +43 -0
  183. package/src/Nodes/Events/OnSceneNodeClick.ts +3 -3
  184. package/src/Nodes/Logic/Mat3Nodes.ts +0 -10
  185. package/src/Nodes/Queries/GetDistanceBetween.ts +37 -0
  186. package/src/Nodes/Queries/GetLightProperty.ts +53 -0
  187. package/src/Nodes/Queries/GetMaterialProperty.ts +55 -0
  188. package/src/Nodes/Queries/GetMeshPosition.ts +32 -0
  189. package/src/Nodes/Queries/GetSceneProperty.ts +4 -5
  190. package/src/Values/Internal/Mat3.ts +3 -3
  191. package/src/Values/Internal/Mat4.ts +5 -4
  192. package/src/Values/Internal/Vec3.ts +5 -4
  193. package/src/Values/Internal/Vec4.ts +3 -2
  194. package/src/buildScene.ts +36 -2
  195. package/src/index.ts +26 -2
  196. package/src/manifest.source.ts +61 -0
  197. package/src/registerSceneProfile.ts +41 -4
  198. package/src/ui/controls/vec3.tsx +69 -0
  199. package/stories/click.stories.tsx +112 -0
  200. package/stories/components/DemoScene.ts +610 -0
  201. package/stories/components/SceneViewer.tsx +204 -0
  202. package/stories/components/SceneViewerPanel.tsx +41 -0
  203. package/stories/data/clickDemo.json +94 -0
  204. package/stories/data/rotate.json +402 -0
  205. package/stories/index.stories.tsx +90 -0
  206. package/stories/plugin/sceneViewerPlugin.tsx +88 -0
  207. package/tests/manifest.test.ts +65 -0
  208. package/tests/readSceneGraphs.test.ts +8 -1
  209. package/tests/registerSceneProfile.test.ts +6 -5
  210. package/tsconfig.json +18 -11
  211. package/tsdown.config.ts +5 -1
  212. package/vite.config.js +7 -0
  213. package/src/Values/Internal/Mat2.ts +0 -214
  214. package/src/loadScene.ts +0 -81
@@ -0,0 +1,47 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ import { GeometryType } from '../../Abstractions/IScene.js';
7
+
8
+ const geometryChoices = Object.values(GeometryType).map((v) => ({
9
+ text: v,
10
+ value: v
11
+ }));
12
+
13
+ export const CreateMesh = makeFlowNodeDefinition({
14
+ typeName: 'scene/createMesh',
15
+ category: NodeCategory.Effect,
16
+ label: 'Create Mesh',
17
+ in: {
18
+ flow: 'flow',
19
+ name: 'string',
20
+ geometryType: (_) => ({
21
+ valueType: 'string',
22
+ choices: geometryChoices
23
+ }),
24
+ sizeX: 'float',
25
+ sizeY: 'float',
26
+ sizeZ: 'float'
27
+ },
28
+ out: {
29
+ flow: 'flow'
30
+ },
31
+ initialState: undefined,
32
+ triggered: ({ commit, read, graph }) => {
33
+ const scene = graph.getDependency('IScene');
34
+ const name = read<string>('name');
35
+ const geometryType = read<string>('geometryType');
36
+ const sizeX = read<number>('sizeX');
37
+ const sizeY = read<number>('sizeY');
38
+ const sizeZ = read<number>('sizeZ');
39
+
40
+ scene?.createMesh(
41
+ name,
42
+ geometryType as (typeof GeometryType)[keyof typeof GeometryType],
43
+ { x: sizeX, y: sizeY, z: sizeZ }
44
+ );
45
+ commit('flow');
46
+ }
47
+ });
@@ -0,0 +1,29 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ export const DeleteMesh = makeFlowNodeDefinition({
7
+ typeName: 'scene/deleteMesh',
8
+ category: NodeCategory.Effect,
9
+ label: 'Delete Mesh',
10
+ in: {
11
+ flow: 'flow',
12
+ name: (_, graphApi) => {
13
+ const scene = graphApi.getDependency('IScene');
14
+ return {
15
+ valueType: 'string',
16
+ choices: scene?.getMeshNames()
17
+ };
18
+ }
19
+ },
20
+ out: {
21
+ flow: 'flow'
22
+ },
23
+ initialState: undefined,
24
+ triggered: ({ commit, read, graph }) => {
25
+ const scene = graph.getDependency('IScene');
26
+ scene?.deleteMesh(read<string>('name'));
27
+ commit('flow');
28
+ }
29
+ });
@@ -1,16 +1,19 @@
1
1
  import {
2
2
  AsyncNode,
3
- type Easing,
4
3
  EasingFunctions,
5
4
  EasingModes,
6
5
  Engine,
7
6
  type IGraph,
8
7
  type ILifecycleEventEmitter,
8
+ lerpValue,
9
9
  NodeDescription,
10
10
  Socket,
11
11
  toCamelCase
12
12
  } from '@kiberon-labs/behave-graph';
13
13
 
14
+ /** An easing curve: maps a normalized time `t` in [0,1] to an eased value. */
15
+ type Easing = (typeof EasingFunctions)[keyof typeof EasingFunctions];
16
+
14
17
  import type { IScene } from '../../Abstractions/IScene.js';
15
18
 
16
19
  export class EaseSceneProperty extends AsyncNode {
@@ -129,7 +132,8 @@ export class EaseSceneProperty extends AsyncNode {
129
132
  this.elapsedDuration = (Date.now() - this.startTime) / 1000;
130
133
 
131
134
  const t = Math.min(this.elapsedDuration / this.duration, 1);
132
- const easedValue = valueType.lerp(
135
+ const easedValue = lerpValue(
136
+ valueType,
133
137
  this.initialValue,
134
138
  this.targetValue,
135
139
  this.easing(t)
@@ -0,0 +1,34 @@
1
+ import type { Vec3 } from '@/Values/Internal/Vec3';
2
+ import {
3
+ makeFlowNodeDefinition,
4
+ NodeCategory
5
+ } from '@kiberon-labs/behave-graph';
6
+
7
+ // Orient a mesh to face a world-space target position.
8
+ export const LookAt = makeFlowNodeDefinition({
9
+ typeName: 'scene/lookAt',
10
+ category: NodeCategory.Effect,
11
+ label: 'Look At',
12
+ in: {
13
+ flow: 'flow',
14
+ meshName: (_, graphApi) => {
15
+ const scene = graphApi.getDependency('IScene');
16
+ return {
17
+ valueType: 'string',
18
+ choices: scene?.getMeshNames()
19
+ };
20
+ },
21
+ target: 'vec3'
22
+ },
23
+ out: {
24
+ flow: 'flow'
25
+ },
26
+ initialState: undefined,
27
+ triggered: ({ commit, read, graph }) => {
28
+ const scene = graph.getDependency('IScene');
29
+ const meshName = read<string>('meshName');
30
+ const target = read<Vec3>('target');
31
+ scene?.lookAt(meshName, { x: target.x, y: target.y, z: target.z });
32
+ commit('flow');
33
+ }
34
+ });
@@ -0,0 +1,55 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ // Move a mesh towards a target position by (speed * deltaSeconds).
7
+ // Outputs 'done' when the mesh has arrived, otherwise 'ongoing'.
8
+ // Designed to be driven from an OnTick loop.
9
+ export const MoveTowards = makeFlowNodeDefinition({
10
+ typeName: 'scene/moveTowards',
11
+ category: NodeCategory.Effect,
12
+ label: 'Move Towards',
13
+ in: {
14
+ flow: 'flow',
15
+ meshName: (_, graphApi) => {
16
+ const scene = graphApi.getDependency('IScene');
17
+ return {
18
+ valueType: 'string',
19
+ choices: scene?.getMeshNames()
20
+ };
21
+ },
22
+ targetX: 'float',
23
+ targetY: 'float',
24
+ targetZ: 'float',
25
+ speed: 'float',
26
+ deltaSeconds: 'float'
27
+ },
28
+ out: {
29
+ ongoing: 'flow',
30
+ done: 'flow'
31
+ },
32
+ initialState: undefined,
33
+ triggered: ({ commit, read, graph }) => {
34
+ const scene = graph.getDependency('IScene');
35
+ const meshName = read<string>('meshName');
36
+ const targetX = read<number>('targetX');
37
+ const targetY = read<number>('targetY');
38
+ const targetZ = read<number>('targetZ');
39
+ const speed = read<number>('speed');
40
+ const deltaSeconds = read<number>('deltaSeconds');
41
+
42
+ const arrived = scene?.moveTowards(
43
+ meshName,
44
+ { x: targetX, y: targetY, z: targetZ },
45
+ speed,
46
+ deltaSeconds
47
+ );
48
+
49
+ if (arrived) {
50
+ commit('done');
51
+ } else {
52
+ commit('ongoing');
53
+ }
54
+ }
55
+ });
@@ -0,0 +1,29 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ export const RemoveLight = makeFlowNodeDefinition({
7
+ typeName: 'scene/removeLight',
8
+ category: NodeCategory.Effect,
9
+ label: 'Remove Light',
10
+ in: {
11
+ flow: 'flow',
12
+ name: (_, graphApi) => {
13
+ const scene = graphApi.getDependency('IScene');
14
+ return {
15
+ valueType: 'string',
16
+ choices: scene?.getLightNames()
17
+ };
18
+ }
19
+ },
20
+ out: {
21
+ flow: 'flow'
22
+ },
23
+ initialState: undefined,
24
+ triggered: ({ commit, read, graph }) => {
25
+ const scene = graph.getDependency('IScene');
26
+ scene?.removeLight(read<string>('name'));
27
+ commit('flow');
28
+ }
29
+ });
@@ -0,0 +1,60 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ const lightPropertyChoices = [
7
+ { text: 'color', value: 'color' },
8
+ { text: 'intensity', value: 'intensity' },
9
+ { text: 'position', value: 'position' }
10
+ ];
11
+
12
+ export const SetLightProperty = makeFlowNodeDefinition({
13
+ typeName: 'scene/setLightProperty',
14
+ category: NodeCategory.Effect,
15
+ label: 'Set Light Property',
16
+ in: {
17
+ flow: 'flow',
18
+ name: (_, graphApi) => {
19
+ const scene = graphApi.getDependency('IScene');
20
+ return {
21
+ valueType: 'string',
22
+ choices: scene?.getLightNames()
23
+ };
24
+ },
25
+ property: (_) => ({
26
+ valueType: 'string',
27
+ choices: lightPropertyChoices
28
+ }),
29
+ floatValue: 'float',
30
+ colorValue: 'color',
31
+ vec3Value: 'vec3'
32
+ },
33
+ out: {
34
+ flow: 'flow'
35
+ },
36
+ initialState: undefined,
37
+ triggered: ({ commit, read, graph }) => {
38
+ const scene = graph.getDependency('IScene');
39
+ const name = read<string>('name');
40
+ const property = read<string>('property');
41
+
42
+ let value: unknown;
43
+ switch (property) {
44
+ case 'intensity':
45
+ value = read<number>('floatValue');
46
+ break;
47
+ case 'color':
48
+ value = read('colorValue');
49
+ break;
50
+ case 'position':
51
+ value = read('vec3Value');
52
+ break;
53
+ default:
54
+ value = read<number>('floatValue');
55
+ }
56
+
57
+ scene?.setLightProperty(name, property, value);
58
+ commit('flow');
59
+ }
60
+ });
@@ -0,0 +1,62 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ const materialPropertyChoices = [
7
+ { text: 'color', value: 'color' },
8
+ { text: 'opacity', value: 'opacity' },
9
+ { text: 'visible', value: 'visible' },
10
+ { text: 'wireframe', value: 'wireframe' }
11
+ ];
12
+
13
+ export const SetMaterialProperty = makeFlowNodeDefinition({
14
+ typeName: 'scene/setMaterialProperty',
15
+ category: NodeCategory.Effect,
16
+ label: 'Set Material Property',
17
+ in: {
18
+ flow: 'flow',
19
+ meshName: (_, graphApi) => {
20
+ const scene = graphApi.getDependency('IScene');
21
+ return {
22
+ valueType: 'string',
23
+ choices: scene?.getMeshNames()
24
+ };
25
+ },
26
+ property: (_) => ({
27
+ valueType: 'string',
28
+ choices: materialPropertyChoices
29
+ }),
30
+ floatValue: 'float',
31
+ booleanValue: 'boolean',
32
+ colorValue: 'color'
33
+ },
34
+ out: {
35
+ flow: 'flow'
36
+ },
37
+ initialState: undefined,
38
+ triggered: ({ commit, read, graph }) => {
39
+ const scene = graph.getDependency('IScene');
40
+ const meshName = read<string>('meshName');
41
+ const property = read<string>('property');
42
+
43
+ let value: unknown;
44
+ switch (property) {
45
+ case 'color':
46
+ value = read('colorValue');
47
+ break;
48
+ case 'opacity':
49
+ value = read<number>('floatValue');
50
+ break;
51
+ case 'visible':
52
+ case 'wireframe':
53
+ value = read<boolean>('booleanValue');
54
+ break;
55
+ default:
56
+ value = read<number>('floatValue');
57
+ }
58
+
59
+ scene?.setMaterialProperty(meshName, property, value);
60
+ commit('flow');
61
+ }
62
+ });
@@ -0,0 +1,37 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ // Directly set a mesh's world position.
7
+ export const SetMeshPosition = makeFlowNodeDefinition({
8
+ typeName: 'scene/setMeshPosition',
9
+ category: NodeCategory.Effect,
10
+ label: 'Set Mesh Position',
11
+ in: {
12
+ flow: 'flow',
13
+ meshName: (_, graphApi) => {
14
+ const scene = graphApi.getDependency('IScene');
15
+ return {
16
+ valueType: 'string',
17
+ choices: scene?.getMeshNames()
18
+ };
19
+ },
20
+ x: 'float',
21
+ y: 'float',
22
+ z: 'float'
23
+ },
24
+ out: {
25
+ flow: 'flow'
26
+ },
27
+ initialState: undefined,
28
+ triggered: ({ commit, read, graph }) => {
29
+ const scene = graph.getDependency('IScene');
30
+ scene?.setMeshPosition(read<string>('meshName'), {
31
+ x: read<number>('x'),
32
+ y: read<number>('y'),
33
+ z: read<number>('z')
34
+ });
35
+ commit('flow');
36
+ }
37
+ });
@@ -0,0 +1,31 @@
1
+ import {
2
+ makeFlowNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ // Show or hide a mesh.
7
+ export const SetMeshVisible = makeFlowNodeDefinition({
8
+ typeName: 'scene/setMeshVisible',
9
+ category: NodeCategory.Effect,
10
+ label: 'Set Mesh Visible',
11
+ in: {
12
+ flow: 'flow',
13
+ meshName: (_, graphApi) => {
14
+ const scene = graphApi.getDependency('IScene');
15
+ return {
16
+ valueType: 'string',
17
+ choices: scene?.getMeshNames()
18
+ };
19
+ },
20
+ visible: 'boolean'
21
+ },
22
+ out: {
23
+ flow: 'flow'
24
+ },
25
+ initialState: undefined,
26
+ triggered: ({ commit, read, graph }) => {
27
+ const scene = graph.getDependency('IScene');
28
+ scene?.setMeshVisible(read<string>('meshName'), read<boolean>('visible'));
29
+ commit('flow');
30
+ }
31
+ });
@@ -3,8 +3,6 @@ import {
3
3
  NodeCategory
4
4
  } from '@kiberon-labs/behave-graph';
5
5
 
6
- import type { IScene } from '../../Abstractions/IScene.js';
7
-
8
6
  export const SetSceneProperty = (valueTypeNames: string[]) =>
9
7
  valueTypeNames.map((valueTypeName) =>
10
8
  makeFlowNodeDefinition({
@@ -13,10 +11,10 @@ export const SetSceneProperty = (valueTypeNames: string[]) =>
13
11
  label: `Set Scene ${valueTypeName}`,
14
12
  in: {
15
13
  jsonPath: (_, graphApi) => {
16
- const scene = graphApi.getDependency<IScene>('IScene');
14
+ const scene = graphApi.getDependency('IScene');
17
15
  return {
18
16
  valueType: 'string',
19
- choices: scene?.getProperties()
17
+ choices: scene?.getProperties(valueTypeName)
20
18
  };
21
19
  },
22
20
  value: valueTypeName,
@@ -27,7 +25,7 @@ export const SetSceneProperty = (valueTypeNames: string[]) =>
27
25
  },
28
26
  initialState: undefined,
29
27
  triggered: ({ commit, read, graph }) => {
30
- const scene = graph.getDependency<IScene>('IScene');
28
+ const scene = graph.getDependency('IScene');
31
29
  scene?.setProperty(read('jsonPath'), valueTypeName, read('value'));
32
30
  commit('flow');
33
31
  }
@@ -0,0 +1,48 @@
1
+ import {
2
+ makeEventNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ type State = {
7
+ handleMeshClicked?: ((meshName: string) => void) | undefined;
8
+ };
9
+
10
+ const initialState = (): State => ({});
11
+
12
+ // Fires whenever any mesh in the scene is clicked, outputting which mesh.
13
+ export const OnAnyMeshClicked = makeEventNodeDefinition({
14
+ typeName: 'scene/onAnyMeshClicked',
15
+ category: NodeCategory.Event,
16
+ label: 'On Any Mesh Clicked',
17
+ in: {},
18
+ out: {
19
+ flow: 'flow',
20
+ meshName: 'string'
21
+ },
22
+ initialState: initialState(),
23
+ init: ({ commit, write, graph }) => {
24
+ const handleMeshClicked = (meshName: string) => {
25
+ write('meshName', meshName);
26
+ commit('flow');
27
+ };
28
+
29
+ const scene = graph.getDependency('IScene');
30
+ console.log('[OnAnyMeshClicked] init , scene dependency:', !!scene);
31
+
32
+ scene?.addOnAnyMeshClickedListener(handleMeshClicked);
33
+
34
+ const state: State = {
35
+ handleMeshClicked
36
+ };
37
+
38
+ return state;
39
+ },
40
+ dispose: ({ state: { handleMeshClicked }, graph: { getDependency } }) => {
41
+ if (!handleMeshClicked) return {};
42
+
43
+ const scene = getDependency('IScene');
44
+ scene?.removeOnAnyMeshClickedListener(handleMeshClicked);
45
+
46
+ return {};
47
+ }
48
+ });
@@ -0,0 +1,43 @@
1
+ import {
2
+ makeEventNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ type State = {
7
+ handleSceneChanged?: (() => void) | undefined;
8
+ };
9
+
10
+ const initialState = (): State => ({});
11
+
12
+ export const OnSceneChanged = makeEventNodeDefinition({
13
+ typeName: 'scene/onSceneChanged',
14
+ category: NodeCategory.Event,
15
+ label: 'On Scene Changed',
16
+ in: {},
17
+ out: {
18
+ flow: 'flow'
19
+ },
20
+ initialState: initialState(),
21
+ init: ({ commit, graph }) => {
22
+ const handleSceneChanged = () => {
23
+ commit('flow');
24
+ };
25
+
26
+ const scene = graph.getDependency('IScene');
27
+ scene?.addOnSceneChangedListener(handleSceneChanged);
28
+
29
+ const state: State = {
30
+ handleSceneChanged
31
+ };
32
+
33
+ return state;
34
+ },
35
+ dispose: ({ state: { handleSceneChanged }, graph: { getDependency } }) => {
36
+ if (!handleSceneChanged) return {};
37
+
38
+ const scene = getDependency('IScene');
39
+ scene?.removeOnSceneChangedListener(handleSceneChanged);
40
+
41
+ return {};
42
+ }
43
+ });
@@ -20,7 +20,7 @@ export const OnSceneNodeClick = makeEventNodeDefinition({
20
20
  label: 'On Scene Node Click',
21
21
  in: {
22
22
  jsonPath: (_, graphApi) => {
23
- const scene = graphApi.getDependency<IScene>('IScene');
23
+ const scene = graphApi.getDependency('IScene');
24
24
 
25
25
  return {
26
26
  valueType: 'string',
@@ -39,7 +39,7 @@ export const OnSceneNodeClick = makeEventNodeDefinition({
39
39
 
40
40
  const jsonPath = read<string>('jsonPath');
41
41
 
42
- const scene = graph.getDependency<IScene>('IScene');
42
+ const scene = graph.getDependency('IScene');
43
43
  scene?.addOnClickedListener(jsonPath, handleNodeClick);
44
44
 
45
45
  const state: State = {
@@ -58,7 +58,7 @@ export const OnSceneNodeClick = makeEventNodeDefinition({
58
58
 
59
59
  if (!jsonPath || !handleNodeClick) return {};
60
60
 
61
- const scene = getDependency<IScene>('scene');
61
+ const scene = getDependency('IScene');
62
62
  scene?.removeOnClickedListener(jsonPath, handleNodeClick);
63
63
 
64
64
  return {};
@@ -55,16 +55,6 @@ export const SetRow = makeInNOutFunctionDesc({
55
55
  exec: mat3SetRow3
56
56
  });
57
57
 
58
- export const Elements = makeInNOutFunctionDesc({
59
- name: 'math/toVec3/mat3',
60
- label: 'Mat3 To Vec3',
61
- in: ['mat3'],
62
- out: [{ x: 'vec3' }, { y: 'vec3' }, { z: 'vec3' }],
63
- exec: (a: Mat3) => {
64
- throw new Error('not implemented');
65
- }
66
- });
67
-
68
58
  export const Add = makeInNOutFunctionDesc({
69
59
  name: 'math/add/mat3',
70
60
  label: '+',
@@ -0,0 +1,37 @@
1
+ import {
2
+ makeFunctionNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ // Compute the distance between two meshes.
7
+ export const GetDistanceBetween = makeFunctionNodeDefinition({
8
+ typeName: 'scene/getDistanceBetween',
9
+ category: NodeCategory.Query,
10
+ label: 'Get Distance Between',
11
+ in: {
12
+ meshA: (_, graphApi) => {
13
+ const scene = graphApi.getDependency('IScene');
14
+ return {
15
+ valueType: 'string',
16
+ choices: scene?.getMeshNames()
17
+ };
18
+ },
19
+ meshB: (_, graphApi) => {
20
+ const scene = graphApi.getDependency('IScene');
21
+ return {
22
+ valueType: 'string',
23
+ choices: scene?.getMeshNames()
24
+ };
25
+ }
26
+ },
27
+ out: {
28
+ distance: 'float'
29
+ },
30
+ exec: ({ graph, read, write }) => {
31
+ const scene = graph.getDependency('IScene');
32
+ const distance =
33
+ scene?.getDistanceBetween(read<string>('meshA'), read<string>('meshB')) ??
34
+ 0;
35
+ write('distance', distance);
36
+ }
37
+ });
@@ -0,0 +1,53 @@
1
+ import {
2
+ makeFunctionNodeDefinition,
3
+ NodeCategory
4
+ } from '@kiberon-labs/behave-graph';
5
+
6
+ const lightPropertyChoices = [
7
+ { text: 'color', value: 'color' },
8
+ { text: 'intensity', value: 'intensity' },
9
+ { text: 'position', value: 'position' }
10
+ ];
11
+
12
+ export const GetLightProperty = makeFunctionNodeDefinition({
13
+ typeName: 'scene/getLightProperty',
14
+ category: NodeCategory.Query,
15
+ label: 'Get Light Property',
16
+ in: {
17
+ name: (_, graphApi) => {
18
+ const scene = graphApi.getDependency('IScene');
19
+ return {
20
+ valueType: 'string',
21
+ choices: scene?.getLightNames()
22
+ };
23
+ },
24
+ property: (_) => ({
25
+ valueType: 'string',
26
+ choices: lightPropertyChoices
27
+ })
28
+ },
29
+ out: {
30
+ floatValue: 'float',
31
+ colorValue: 'color',
32
+ vec3Value: 'vec3'
33
+ },
34
+ exec: ({ graph, read, write }) => {
35
+ const scene = graph.getDependency('IScene');
36
+ const name = read<string>('name');
37
+ const property = read<string>('property');
38
+
39
+ const value = scene?.getLightProperty(name, property);
40
+
41
+ switch (property) {
42
+ case 'intensity':
43
+ write('floatValue', value ?? 0);
44
+ break;
45
+ case 'color':
46
+ write('colorValue', value ?? { r: 0, g: 0, b: 0 });
47
+ break;
48
+ case 'position':
49
+ write('vec3Value', value ?? { x: 0, y: 0, z: 0 });
50
+ break;
51
+ }
52
+ }
53
+ });