@onerjs/core 8.54.4 → 8.54.6

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 (234) hide show
  1. package/Engines/Native/nativeHelpers.js +5 -0
  2. package/Engines/Native/nativeHelpers.js.map +1 -1
  3. package/Engines/WebGPU/Extensions/engine.cubeTexture.pure.js +1 -1
  4. package/Engines/WebGPU/Extensions/engine.cubeTexture.pure.js.map +1 -1
  5. package/Engines/WebGPU/Extensions/engine.rawTexture.pure.js +2 -2
  6. package/Engines/WebGPU/Extensions/engine.rawTexture.pure.js.map +1 -1
  7. package/Engines/WebGPU/webgpuCacheRenderPipeline.d.ts +1 -0
  8. package/Engines/WebGPU/webgpuCacheRenderPipeline.js +18 -4
  9. package/Engines/WebGPU/webgpuCacheRenderPipeline.js.map +1 -1
  10. package/Engines/WebGPU/webgpuCacheTextureView.d.ts +13 -0
  11. package/Engines/WebGPU/webgpuCacheTextureView.js +32 -0
  12. package/Engines/WebGPU/webgpuCacheTextureView.js.map +1 -0
  13. package/Engines/WebGPU/webgpuRenderTargetWrapper.d.ts +10 -0
  14. package/Engines/WebGPU/webgpuRenderTargetWrapper.js +10 -0
  15. package/Engines/WebGPU/webgpuRenderTargetWrapper.js.map +1 -1
  16. package/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.js +57 -4
  17. package/Engines/WebGPU/webgpuShaderProcessorsWGSL.pure.js.map +1 -1
  18. package/Engines/WebGPU/webgpuTextureManager.d.ts +1 -1
  19. package/Engines/WebGPU/webgpuTextureManager.js +4 -2
  20. package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
  21. package/Engines/abstractEngine.pure.js +2 -2
  22. package/Engines/abstractEngine.pure.js.map +1 -1
  23. package/Engines/engineCapabilities.d.ts +5 -0
  24. package/Engines/engineCapabilities.js.map +1 -1
  25. package/Engines/thinNativeEngine.pure.d.ts +5 -0
  26. package/Engines/thinNativeEngine.pure.js +52 -10
  27. package/Engines/thinNativeEngine.pure.js.map +1 -1
  28. package/Engines/webgpuEngine.pure.d.ts +1 -0
  29. package/Engines/webgpuEngine.pure.js +22 -8
  30. package/Engines/webgpuEngine.pure.js.map +1 -1
  31. package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.d.ts +95 -1
  32. package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js +169 -4
  33. package/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.js.map +1 -1
  34. package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.d.ts +21 -6
  35. package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.js +28 -26
  36. package/FlowGraph/Blocks/Data/Math/flowGraphMathCombineExtractBlocks.pure.js.map +1 -1
  37. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.d.ts +30 -2
  38. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.js +111 -29
  39. package/FlowGraph/Blocks/Data/Math/flowGraphMatrixMathBlocks.pure.js.map +1 -1
  40. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.d.ts +56 -2
  41. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.js +99 -14
  42. package/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.js.map +1 -1
  43. package/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.js +10 -2
  44. package/FlowGraph/Blocks/Data/Transformers/flowGraphJsonPointerParserBlock.pure.js.map +1 -1
  45. package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js +21 -1
  46. package/FlowGraph/Blocks/Data/Utils/flowGraphArrayIndexBlock.pure.js.map +1 -1
  47. package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.d.ts +18 -0
  48. package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.js +29 -2
  49. package/FlowGraph/Blocks/Data/flowGraphCachedOperationBlock.js.map +1 -1
  50. package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.d.ts +15 -0
  51. package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js +44 -7
  52. package/FlowGraph/Blocks/Event/flowGraphReceiveCustomEventBlock.pure.js.map +1 -1
  53. package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.d.ts +9 -0
  54. package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js +9 -1
  55. package/FlowGraph/Blocks/Event/flowGraphSceneReadyEventBlock.pure.js.map +1 -1
  56. package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.d.ts +7 -0
  57. package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js +8 -1
  58. package/FlowGraph/Blocks/Event/flowGraphSceneTickEventBlock.pure.js.map +1 -1
  59. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.d.ts +5 -0
  60. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.js +8 -0
  61. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.js.map +1 -0
  62. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.d.ts +37 -0
  63. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.js +44 -0
  64. package/FlowGraph/Blocks/Event/flowGraphStopEventPropagationBlock.pure.js.map +1 -0
  65. package/FlowGraph/Blocks/Event/index.d.ts +1 -0
  66. package/FlowGraph/Blocks/Event/index.js +1 -0
  67. package/FlowGraph/Blocks/Event/index.js.map +1 -1
  68. package/FlowGraph/Blocks/Event/pure.d.ts +1 -0
  69. package/FlowGraph/Blocks/Event/pure.js +1 -0
  70. package/FlowGraph/Blocks/Event/pure.js.map +1 -1
  71. package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.d.ts +4 -1
  72. package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.js +67 -2
  73. package/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.js.map +1 -1
  74. package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.d.ts +13 -0
  75. package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js +102 -7
  76. package/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.js.map +1 -1
  77. package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js +5 -1
  78. package/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.js.map +1 -1
  79. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.js +5 -1
  80. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.js.map +1 -1
  81. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.d.ts +11 -2
  82. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.js +21 -3
  83. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphForLoopBlock.pure.js.map +1 -1
  84. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.js +25 -4
  85. package/FlowGraph/Blocks/Execution/ControlFlow/flowGraphSetDelayBlock.pure.js.map +1 -1
  86. package/FlowGraph/Blocks/flowGraphBlockFactory.js +18 -0
  87. package/FlowGraph/Blocks/flowGraphBlockFactory.js.map +1 -1
  88. package/FlowGraph/Blocks/flowGraphBlockNames.d.ts +9 -0
  89. package/FlowGraph/Blocks/flowGraphBlockNames.js +9 -0
  90. package/FlowGraph/Blocks/flowGraphBlockNames.js.map +1 -1
  91. package/FlowGraph/CustomTypes/flowGraphMatrix.d.ts +17 -3
  92. package/FlowGraph/CustomTypes/flowGraphMatrix.js +27 -21
  93. package/FlowGraph/CustomTypes/flowGraphMatrix.js.map +1 -1
  94. package/FlowGraph/flowGraphContext.d.ts +23 -0
  95. package/FlowGraph/flowGraphContext.js +29 -0
  96. package/FlowGraph/flowGraphContext.js.map +1 -1
  97. package/FlowGraph/flowGraphCoordinator.d.ts +58 -1
  98. package/FlowGraph/flowGraphCoordinator.js +72 -0
  99. package/FlowGraph/flowGraphCoordinator.js.map +1 -1
  100. package/FlowGraph/flowGraphDelayRegistry.d.ts +31 -0
  101. package/FlowGraph/flowGraphDelayRegistry.js +50 -0
  102. package/FlowGraph/flowGraphDelayRegistry.js.map +1 -0
  103. package/FlowGraph/flowGraphHostResolver.d.ts +69 -0
  104. package/FlowGraph/flowGraphHostResolver.js +25 -0
  105. package/FlowGraph/flowGraphHostResolver.js.map +1 -0
  106. package/FlowGraph/flowGraphMath.d.ts +48 -1
  107. package/FlowGraph/flowGraphMath.js +169 -4
  108. package/FlowGraph/flowGraphMath.js.map +1 -1
  109. package/FlowGraph/flowGraphPathConverterComponent.d.ts +14 -3
  110. package/FlowGraph/flowGraphPathConverterComponent.js +110 -18
  111. package/FlowGraph/flowGraphPathConverterComponent.js.map +1 -1
  112. package/FlowGraph/flowGraphSignalConnection.pure.js +7 -1
  113. package/FlowGraph/flowGraphSignalConnection.pure.js.map +1 -1
  114. package/FlowGraph/index.d.ts +2 -0
  115. package/FlowGraph/index.js +2 -0
  116. package/FlowGraph/index.js.map +1 -1
  117. package/FlowGraph/pure.d.ts +2 -0
  118. package/FlowGraph/pure.js +2 -0
  119. package/FlowGraph/pure.js.map +1 -1
  120. package/Materials/Node/nodeMaterial.pure.d.ts +3 -1
  121. package/Materials/Node/nodeMaterial.pure.js +18 -1
  122. package/Materials/Node/nodeMaterial.pure.js.map +1 -1
  123. package/Materials/Textures/envCubeTexture.pure.js +7 -2
  124. package/Materials/Textures/envCubeTexture.pure.js.map +1 -1
  125. package/Materials/materialHelper.functions.d.ts +14 -0
  126. package/Materials/materialHelper.functions.js +67 -0
  127. package/Materials/materialHelper.functions.js.map +1 -1
  128. package/Maths/math.vector.pure.d.ts +11 -1
  129. package/Maths/math.vector.pure.js +13 -0
  130. package/Maths/math.vector.pure.js.map +1 -1
  131. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.d.ts +216 -1
  132. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +714 -67
  133. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
  134. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +81 -4
  135. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +466 -52
  136. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  137. package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.d.ts +19 -0
  138. package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.js +24 -0
  139. package/Meshes/GaussianSplatting/gaussianSplattingPartProxyMesh.pure.js.map +1 -1
  140. package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js +31 -6
  141. package/Meshes/GaussianSplatting/gaussianSplattingSortWorker.js.map +1 -1
  142. package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js +5 -1
  143. package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js.map +1 -1
  144. package/Meshes/abstractMesh.pure.js +1 -0
  145. package/Meshes/abstractMesh.pure.js.map +1 -1
  146. package/Meshes/mesh.pure.js +5 -0
  147. package/Meshes/mesh.pure.js.map +1 -1
  148. package/Meshes/transformNode.pure.js +1 -0
  149. package/Meshes/transformNode.pure.js.map +1 -1
  150. package/Misc/areaLightsTextureTools.js +1 -1
  151. package/Misc/areaLightsTextureTools.js.map +1 -1
  152. package/Misc/greasedLineTools.js +1 -1
  153. package/Misc/greasedLineTools.js.map +1 -1
  154. package/Misc/tools.pure.js +14 -2
  155. package/Misc/tools.pure.js.map +1 -1
  156. package/Particles/gpuParticleSystem.pure.d.ts +66 -1
  157. package/Particles/gpuParticleSystem.pure.js +189 -49
  158. package/Particles/gpuParticleSystem.pure.js.map +1 -1
  159. package/Physics/v2/characterController.js +69 -17
  160. package/Physics/v2/characterController.js.map +1 -1
  161. package/PostProcesses/RenderPipeline/Pipelines/fsr1RenderingPipeline.d.ts +79 -0
  162. package/PostProcesses/RenderPipeline/Pipelines/fsr1RenderingPipeline.js +171 -0
  163. package/PostProcesses/RenderPipeline/Pipelines/fsr1RenderingPipeline.js.map +1 -0
  164. package/PostProcesses/RenderPipeline/Pipelines/index.d.ts +5 -0
  165. package/PostProcesses/RenderPipeline/Pipelines/index.js +6 -0
  166. package/PostProcesses/RenderPipeline/Pipelines/index.js.map +1 -1
  167. package/PostProcesses/RenderPipeline/Pipelines/pure.d.ts +1 -0
  168. package/PostProcesses/RenderPipeline/Pipelines/pure.js +1 -0
  169. package/PostProcesses/RenderPipeline/Pipelines/pure.js.map +1 -1
  170. package/PostProcesses/thinFSR1SharpenPostProcess.d.ts +32 -0
  171. package/PostProcesses/thinFSR1SharpenPostProcess.js +58 -0
  172. package/PostProcesses/thinFSR1SharpenPostProcess.js.map +1 -0
  173. package/PostProcesses/thinFSR1UpscalePostProcess.d.ts +37 -0
  174. package/PostProcesses/thinFSR1UpscalePostProcess.js +68 -0
  175. package/PostProcesses/thinFSR1UpscalePostProcess.js.map +1 -0
  176. package/Shaders/ShadersInclude/ffxFunctions.d.ts +5 -0
  177. package/Shaders/ShadersInclude/ffxFunctions.js +18 -0
  178. package/Shaders/ShadersInclude/ffxFunctions.js.map +1 -0
  179. package/Shaders/ShadersInclude/hdrFilteringFunctions.js +2 -2
  180. package/Shaders/ShadersInclude/hdrFilteringFunctions.js.map +1 -1
  181. package/Shaders/ShadersInclude/openpbrIblFunctions.js +1 -6
  182. package/Shaders/ShadersInclude/openpbrIblFunctions.js.map +1 -1
  183. package/Shaders/fsr1Sharpen.fragment.d.ts +5 -0
  184. package/Shaders/fsr1Sharpen.fragment.js +26 -0
  185. package/Shaders/fsr1Sharpen.fragment.js.map +1 -0
  186. package/Shaders/fsr1Upscale.fragment.d.ts +5 -0
  187. package/Shaders/fsr1Upscale.fragment.js +77 -0
  188. package/Shaders/fsr1Upscale.fragment.js.map +1 -0
  189. package/ShadersWGSL/ShadersInclude/ffxFunctions.d.ts +5 -0
  190. package/ShadersWGSL/ShadersInclude/ffxFunctions.js +18 -0
  191. package/ShadersWGSL/ShadersInclude/ffxFunctions.js.map +1 -0
  192. package/ShadersWGSL/fsr1Sharpen.fragment.d.ts +5 -0
  193. package/ShadersWGSL/fsr1Sharpen.fragment.js +34 -0
  194. package/ShadersWGSL/fsr1Sharpen.fragment.js.map +1 -0
  195. package/ShadersWGSL/fsr1Upscale.fragment.d.ts +5 -0
  196. package/ShadersWGSL/fsr1Upscale.fragment.js +68 -0
  197. package/ShadersWGSL/fsr1Upscale.fragment.js.map +1 -0
  198. package/XR/features/Layers/WebXRWebGPUCompositionLayer.d.ts +3 -9
  199. package/XR/features/Layers/WebXRWebGPUCompositionLayer.js +4 -11
  200. package/XR/features/Layers/WebXRWebGPUCompositionLayer.js.map +1 -1
  201. package/XR/features/WebXRAbstractFeature.d.ts +9 -0
  202. package/XR/features/WebXRAbstractFeature.js +16 -0
  203. package/XR/features/WebXRAbstractFeature.js.map +1 -1
  204. package/XR/features/WebXRDepthSensing.pure.d.ts +7 -0
  205. package/XR/features/WebXRDepthSensing.pure.js +350 -39
  206. package/XR/features/WebXRDepthSensing.pure.js.map +1 -1
  207. package/XR/features/WebXRImageTracking.pure.js.map +1 -1
  208. package/XR/features/WebXRLayers.pure.d.ts +6 -5
  209. package/XR/features/WebXRLayers.pure.js +65 -8
  210. package/XR/features/WebXRLayers.pure.js.map +1 -1
  211. package/XR/features/WebXRRawCameraAccess.pure.js +9 -2
  212. package/XR/features/WebXRRawCameraAccess.pure.js.map +1 -1
  213. package/XR/features/WebXRSpaceWarp.pure.d.ts +0 -1
  214. package/XR/features/WebXRSpaceWarp.pure.js +13 -4
  215. package/XR/features/WebXRSpaceWarp.pure.js.map +1 -1
  216. package/XR/features/WebXRWalkingLocomotion.pure.js.map +1 -1
  217. package/XR/webXRCamera.js +27 -0
  218. package/XR/webXRCamera.js.map +1 -1
  219. package/XR/webXRFeatureWarningRegistry.d.ts +14 -0
  220. package/XR/webXRFeatureWarningRegistry.js +19 -0
  221. package/XR/webXRFeatureWarningRegistry.js.map +1 -0
  222. package/XR/webXRFeaturesManager.d.ts +5 -0
  223. package/XR/webXRFeaturesManager.js +23 -4
  224. package/XR/webXRFeaturesManager.js.map +1 -1
  225. package/XR/webXRGraphicsBinding.d.ts +17 -10
  226. package/XR/webXRGraphicsBinding.js +8 -5
  227. package/XR/webXRGraphicsBinding.js.map +1 -1
  228. package/XR/webXRSessionManager.d.ts +3 -5
  229. package/XR/webXRSessionManager.js +1 -3
  230. package/XR/webXRSessionManager.js.map +1 -1
  231. package/XR/webXRWebGPURenderTargetTextureProvider.d.ts +21 -5
  232. package/XR/webXRWebGPURenderTargetTextureProvider.js +38 -10
  233. package/XR/webXRWebGPURenderTargetTextureProvider.js.map +1 -1
  234. package/package.json +1 -1
@@ -2,6 +2,7 @@
2
2
  export * from "./flowGraphMeshPickEventBlock.pure.js";
3
3
  export * from "./flowGraphSceneReadyEventBlock.pure.js";
4
4
  export * from "./flowGraphReceiveCustomEventBlock.pure.js";
5
+ export * from "./flowGraphStopEventPropagationBlock.pure.js";
5
6
  export * from "./flowGraphSendCustomEventBlock.pure.js";
6
7
  export * from "./flowGraphSceneTickEventBlock.pure.js";
7
8
  export * from "./flowGraphPointerOutEventBlock.pure.js";
@@ -1 +1 @@
1
- {"version":3,"file":"pure.js","sourceRoot":"","sources":["../../../../../../dev/core/src/FlowGraph/Blocks/Event/pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC","sourcesContent":["/** Pure barrel — re-exports only side-effect-free modules */\nexport * from \"./flowGraphMeshPickEventBlock.pure\";\nexport * from \"./flowGraphSceneReadyEventBlock.pure\";\nexport * from \"./flowGraphReceiveCustomEventBlock.pure\";\nexport * from \"./flowGraphSendCustomEventBlock.pure\";\nexport * from \"./flowGraphSceneTickEventBlock.pure\";\nexport * from \"./flowGraphPointerOutEventBlock.pure\";\nexport * from \"./flowGraphPointerOverEventBlock.pure\";\nexport * from \"./flowGraphPhysicsCollisionEventBlock.pure\";\nexport * from \"./flowGraphSoundEndedEventBlock.pure\";\nexport * from \"./flowGraphKeyboardEventBlock\";\nexport * from \"./flowGraphPointerDownEventBlock.pure\";\nexport * from \"./flowGraphPointerMoveEventBlock.pure\";\nexport * from \"./flowGraphPointerUpEventBlock.pure\";\n"]}
1
+ {"version":3,"file":"pure.js","sourceRoot":"","sources":["../../../../../../dev/core/src/FlowGraph/Blocks/Event/pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC","sourcesContent":["/** Pure barrel — re-exports only side-effect-free modules */\nexport * from \"./flowGraphMeshPickEventBlock.pure\";\nexport * from \"./flowGraphSceneReadyEventBlock.pure\";\nexport * from \"./flowGraphReceiveCustomEventBlock.pure\";\nexport * from \"./flowGraphStopEventPropagationBlock.pure\";\nexport * from \"./flowGraphSendCustomEventBlock.pure\";\nexport * from \"./flowGraphSceneTickEventBlock.pure\";\nexport * from \"./flowGraphPointerOutEventBlock.pure\";\nexport * from \"./flowGraphPointerOverEventBlock.pure\";\nexport * from \"./flowGraphPhysicsCollisionEventBlock.pure\";\nexport * from \"./flowGraphSoundEndedEventBlock.pure\";\nexport * from \"./flowGraphKeyboardEventBlock\";\nexport * from \"./flowGraphPointerDownEventBlock.pure\";\nexport * from \"./flowGraphPointerMoveEventBlock.pure\";\nexport * from \"./flowGraphPointerUpEventBlock.pure\";\n"]}
@@ -5,7 +5,10 @@ import { type FlowGraphContext } from "../../../flowGraphContext.js";
5
5
  import { type FlowGraphDataConnection } from "../../../flowGraphDataConnection.pure.js";
6
6
  import { type Vector2 } from "../../../../Maths/math.vector.pure.js";
7
7
  /**
8
- * An easing block that generates a BezierCurveEase easingFunction object based on the data provided.
8
+ * An easing block that generates a cubic Bézier easing function based on the data provided.
9
+ *
10
+ * Follows CSS cubic-bezier semantics: for input progress `t`, solve the curve parameter where X
11
+ * equals `t`, then use the corresponding Y coordinate as the eased output progress.
9
12
  */
10
13
  export declare class FlowGraphBezierCurveEasingBlock extends FlowGraphBlock {
11
14
  /**
@@ -4,7 +4,72 @@ import { FlowGraphBlock } from "../../../flowGraphBlock.js";
4
4
  import { RichTypeAny, RichTypeNumber, RichTypeVector2 } from "../../../flowGraphRichTypes.pure.js";
5
5
  import { RegisterClass } from "../../../../Misc/typeStore.js";
6
6
  /**
7
- * An easing block that generates a BezierCurveEase easingFunction object based on the data provided.
7
+ * Solves the CSS cubic-bezier easing for input progress `t`: find the curve parameter `u` where the
8
+ * X coordinate equals `t` (implicit endpoints P0=(0,0), P3=(1,1)), then return the Y coordinate at `u`.
9
+ *
10
+ * This is a local solver rather than the shared `BezierCurve.Interpolate` on purpose: KHR_interactivity
11
+ * needs a root finder that stays finite at stationary derivatives (e.g. control points (1,1)/(0,1), where
12
+ * dX/du is 0 at the root). The shared solver uses plain Newton iteration and returns NaN there, so it must
13
+ * not be changed for this consumer. Newton steps are taken when they stay inside the bracketing interval and
14
+ * the derivative is non-negligible; otherwise the step falls back to bisection, which always converges.
15
+ * @param t the input progress in [0, 1]
16
+ * @param x1 X of the first control point
17
+ * @param y1 Y of the first control point
18
+ * @param x2 X of the second control point
19
+ * @param y2 Y of the second control point
20
+ * @returns the eased output progress
21
+ */
22
+ function _SolveCssCubicBezier(t, x1, y1, x2, y2) {
23
+ if (t <= 0) {
24
+ return 0;
25
+ }
26
+ if (t >= 1) {
27
+ return 1;
28
+ }
29
+ const fx0 = 1 - 3 * x2 + 3 * x1;
30
+ const fx1 = 3 * x2 - 6 * x1;
31
+ const fx2 = 3 * x1;
32
+ let lowerBound = 0;
33
+ let upperBound = 1;
34
+ let u = t;
35
+ for (let i = 0; i < 8; i++) {
36
+ const u2 = u * u;
37
+ const u3 = u2 * u;
38
+ const x = fx0 * u3 + fx1 * u2 + fx2 * u;
39
+ const error = x - t;
40
+ if (Math.abs(error) < 1e-7) {
41
+ break;
42
+ }
43
+ if (error > 0) {
44
+ upperBound = u;
45
+ }
46
+ else {
47
+ lowerBound = u;
48
+ }
49
+ const derivative = 3 * fx0 * u2 + 2 * fx1 * u + fx2;
50
+ const newtonU = Math.abs(derivative) > 1e-7 ? u - error / derivative : NaN;
51
+ u = Number.isFinite(newtonU) && newtonU > lowerBound && newtonU < upperBound ? newtonU : (lowerBound + upperBound) * 0.5;
52
+ }
53
+ const fy0 = 1 - 3 * y2 + 3 * y1;
54
+ const fy1 = 3 * y2 - 6 * y1;
55
+ const fy2 = 3 * y1;
56
+ return fy0 * u * u * u + fy1 * u * u + fy2 * u;
57
+ }
58
+ /**
59
+ * A {@link BezierCurveEase} that resolves the curve with {@link _SolveCssCubicBezier} so degenerate control
60
+ * points (stationary X derivative) stay finite. It inherits the public `x1`/`y1`/`x2`/`y2` fields and the
61
+ * easing-mode handling; only the core evaluation is replaced.
62
+ */
63
+ class InteractivityBezierCurveEase extends BezierCurveEase {
64
+ easeInCore(gradient) {
65
+ return _SolveCssCubicBezier(gradient, this.x1, this.y1, this.x2, this.y2);
66
+ }
67
+ }
68
+ /**
69
+ * An easing block that generates a cubic Bézier easing function based on the data provided.
70
+ *
71
+ * Follows CSS cubic-bezier semantics: for input progress `t`, solve the curve parameter where X
72
+ * equals `t`, then use the corresponding Y coordinate as the eased output progress.
8
73
  */
9
74
  export class FlowGraphBezierCurveEasingBlock extends FlowGraphBlock {
10
75
  constructor(
@@ -33,7 +98,7 @@ export class FlowGraphBezierCurveEasingBlock extends FlowGraphBlock {
33
98
  }
34
99
  const key = `${mode}-${controlPoint1.x}-${controlPoint1.y}-${controlPoint2.x}-${controlPoint2.y}`;
35
100
  if (!this._easingFunctions[key]) {
36
- const easing = new BezierCurveEase(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y);
101
+ const easing = new InteractivityBezierCurveEase(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y);
37
102
  easing.setEasingMode(mode);
38
103
  this._easingFunctions[key] = easing;
39
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraphBezierCurveEasingBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAE7D,OAAO,EAAuB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAqC,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAGlG,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAGtG,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,+BAAgC,SAAQ,cAAc;IA2B/D;IACI;;OAEG;IACa,MAAqC;QAErD,KAAK,CAAC,MAAM,CAAC,CAAC;QAFE,WAAM,GAAN,MAAM,CAA+B;QAVzD;;;WAGG;QACK,qBAAgB,GAAsC,EAAE,CAAC;QAU7D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;QAC9E,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;QAE9E,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IACjF,CAAC;IAEe,cAAc,CAAC,OAAyB;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAE3D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,OAAO;QACX,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,aAAa,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,EAAE,CAAC;QAClG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,aAAa,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;YACvG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAEe,YAAY;QACxB,gFAA6C;IACjD,CAAC;CACJ;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB;;;GAGG;AACH,MAAM,UAAU,uCAAuC;IACnD,IAAI,WAAW,EAAE,CAAC;QACd,OAAO;IACX,CAAC;IACD,WAAW,GAAG,IAAI,CAAC;IAEnB,aAAa,2EAAwC,+BAA+B,CAAC,CAAC;AAC1F,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\n\nimport { type EasingFunction, BezierCurveEase } from \"core/Animations/easing\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber, RichTypeVector2 } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Vector2 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * An easing block that generates a BezierCurveEase easingFunction object based on the data provided.\n */\nexport class FlowGraphBezierCurveEasingBlock extends FlowGraphBlock {\n /**\n * Input connection: The mode of the easing function.\n * EasingFunction.EASINGMODE_EASEIN, EasingFunction.EASINGMODE_EASEOUT, EasingFunction.EASINGMODE_EASEINOUT\n */\n public readonly mode: FlowGraphDataConnection<number>;\n\n /**\n * Input connection: Control point 1 for bezier curve.\n */\n public readonly controlPoint1: FlowGraphDataConnection<Vector2>;\n /**\n * Input connection: Control point 2 for bezier curve.\n */\n public readonly controlPoint2: FlowGraphDataConnection<Vector2>;\n\n /**\n * Output connection: The easing function object.\n */\n public readonly easingFunction: FlowGraphDataConnection<EasingFunction>;\n\n /**\n * Internal cache of reusable easing functions.\n * key is type-mode-properties\n */\n private _easingFunctions: { [key: string]: EasingFunction } = {};\n\n constructor(\n /**\n * the configuration of the block\n */\n public override config?: IFlowGraphBlockConfiguration\n ) {\n super(config);\n\n this.mode = this.registerDataInput(\"mode\", RichTypeNumber, 0);\n this.controlPoint1 = this.registerDataInput(\"controlPoint1\", RichTypeVector2);\n this.controlPoint2 = this.registerDataInput(\"controlPoint2\", RichTypeVector2);\n\n this.easingFunction = this.registerDataOutput(\"easingFunction\", RichTypeAny);\n }\n\n public override _updateOutputs(context: FlowGraphContext) {\n const mode = this.mode.getValue(context);\n const controlPoint1 = this.controlPoint1.getValue(context);\n const controlPoint2 = this.controlPoint2.getValue(context);\n\n if (mode === undefined) {\n return;\n }\n\n const key = `${mode}-${controlPoint1.x}-${controlPoint1.y}-${controlPoint2.x}-${controlPoint2.y}`;\n if (!this._easingFunctions[key]) {\n const easing = new BezierCurveEase(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y);\n easing.setEasingMode(mode);\n this._easingFunctions[key] = easing;\n }\n this.easingFunction.setValue(this._easingFunctions[key], context);\n }\n\n public override getClassName(): string {\n return FlowGraphBlockNames.BezierCurveEasing;\n }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphBezierCurveEasingBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphBezierCurveEasingBlock(): void {\n if (_Registered) {\n return;\n }\n _Registered = true;\n\n RegisterClass(FlowGraphBlockNames.BezierCurveEasing, FlowGraphBezierCurveEasingBlock);\n}\n"]}
1
+ {"version":3,"file":"flowGraphBezierCurveEasingBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphBezierCurveEasingBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\n\nimport { BezierCurveEase, type EasingFunction } from \"core/Animations/easing\";\nimport { type IFlowGraphBlockConfiguration, FlowGraphBlock } from \"core/FlowGraph/flowGraphBlock\";\nimport { type FlowGraphContext } from \"core/FlowGraph/flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"core/FlowGraph/flowGraphDataConnection.pure\";\nimport { RichTypeAny, RichTypeNumber, RichTypeVector2 } from \"core/FlowGraph/flowGraphRichTypes.pure\";\nimport { type Vector2 } from \"core/Maths/math.vector.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * Solves the CSS cubic-bezier easing for input progress `t`: find the curve parameter `u` where the\n * X coordinate equals `t` (implicit endpoints P0=(0,0), P3=(1,1)), then return the Y coordinate at `u`.\n *\n * This is a local solver rather than the shared `BezierCurve.Interpolate` on purpose: KHR_interactivity\n * needs a root finder that stays finite at stationary derivatives (e.g. control points (1,1)/(0,1), where\n * dX/du is 0 at the root). The shared solver uses plain Newton iteration and returns NaN there, so it must\n * not be changed for this consumer. Newton steps are taken when they stay inside the bracketing interval and\n * the derivative is non-negligible; otherwise the step falls back to bisection, which always converges.\n * @param t the input progress in [0, 1]\n * @param x1 X of the first control point\n * @param y1 Y of the first control point\n * @param x2 X of the second control point\n * @param y2 Y of the second control point\n * @returns the eased output progress\n */\nfunction _SolveCssCubicBezier(t: number, x1: number, y1: number, x2: number, y2: number): number {\n if (t <= 0) {\n return 0;\n }\n if (t >= 1) {\n return 1;\n }\n const fx0 = 1 - 3 * x2 + 3 * x1;\n const fx1 = 3 * x2 - 6 * x1;\n const fx2 = 3 * x1;\n\n let lowerBound = 0;\n let upperBound = 1;\n let u = t;\n for (let i = 0; i < 8; i++) {\n const u2 = u * u;\n const u3 = u2 * u;\n const x = fx0 * u3 + fx1 * u2 + fx2 * u;\n const error = x - t;\n if (Math.abs(error) < 1e-7) {\n break;\n }\n if (error > 0) {\n upperBound = u;\n } else {\n lowerBound = u;\n }\n const derivative = 3 * fx0 * u2 + 2 * fx1 * u + fx2;\n const newtonU = Math.abs(derivative) > 1e-7 ? u - error / derivative : NaN;\n u = Number.isFinite(newtonU) && newtonU > lowerBound && newtonU < upperBound ? newtonU : (lowerBound + upperBound) * 0.5;\n }\n\n const fy0 = 1 - 3 * y2 + 3 * y1;\n const fy1 = 3 * y2 - 6 * y1;\n const fy2 = 3 * y1;\n return fy0 * u * u * u + fy1 * u * u + fy2 * u;\n}\n\n/**\n * A {@link BezierCurveEase} that resolves the curve with {@link _SolveCssCubicBezier} so degenerate control\n * points (stationary X derivative) stay finite. It inherits the public `x1`/`y1`/`x2`/`y2` fields and the\n * easing-mode handling; only the core evaluation is replaced.\n */\nclass InteractivityBezierCurveEase extends BezierCurveEase {\n public override easeInCore(gradient: number): number {\n return _SolveCssCubicBezier(gradient, this.x1, this.y1, this.x2, this.y2);\n }\n}\n\n/**\n * An easing block that generates a cubic Bézier easing function based on the data provided.\n *\n * Follows CSS cubic-bezier semantics: for input progress `t`, solve the curve parameter where X\n * equals `t`, then use the corresponding Y coordinate as the eased output progress.\n */\nexport class FlowGraphBezierCurveEasingBlock extends FlowGraphBlock {\n /**\n * Input connection: The mode of the easing function.\n * EasingFunction.EASINGMODE_EASEIN, EasingFunction.EASINGMODE_EASEOUT, EasingFunction.EASINGMODE_EASEINOUT\n */\n public readonly mode: FlowGraphDataConnection<number>;\n\n /**\n * Input connection: Control point 1 for bezier curve.\n */\n public readonly controlPoint1: FlowGraphDataConnection<Vector2>;\n /**\n * Input connection: Control point 2 for bezier curve.\n */\n public readonly controlPoint2: FlowGraphDataConnection<Vector2>;\n\n /**\n * Output connection: The easing function object.\n */\n public readonly easingFunction: FlowGraphDataConnection<EasingFunction>;\n\n /**\n * Internal cache of reusable easing functions.\n * key is type-mode-properties\n */\n private _easingFunctions: { [key: string]: EasingFunction } = {};\n\n constructor(\n /**\n * the configuration of the block\n */\n public override config?: IFlowGraphBlockConfiguration\n ) {\n super(config);\n\n this.mode = this.registerDataInput(\"mode\", RichTypeNumber, 0);\n this.controlPoint1 = this.registerDataInput(\"controlPoint1\", RichTypeVector2);\n this.controlPoint2 = this.registerDataInput(\"controlPoint2\", RichTypeVector2);\n\n this.easingFunction = this.registerDataOutput(\"easingFunction\", RichTypeAny);\n }\n\n public override _updateOutputs(context: FlowGraphContext) {\n const mode = this.mode.getValue(context);\n const controlPoint1 = this.controlPoint1.getValue(context);\n const controlPoint2 = this.controlPoint2.getValue(context);\n\n if (mode === undefined) {\n return;\n }\n\n const key = `${mode}-${controlPoint1.x}-${controlPoint1.y}-${controlPoint2.x}-${controlPoint2.y}`;\n if (!this._easingFunctions[key]) {\n const easing = new InteractivityBezierCurveEase(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y);\n easing.setEasingMode(mode);\n this._easingFunctions[key] = easing;\n }\n this.easingFunction.setValue(this._easingFunctions[key], context);\n }\n\n public override getClassName(): string {\n return FlowGraphBlockNames.BezierCurveEasing;\n }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphBezierCurveEasingBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphBezierCurveEasingBlock(): void {\n if (_Registered) {\n return;\n }\n _Registered = true;\n\n RegisterClass(FlowGraphBlockNames.BezierCurveEasing, FlowGraphBezierCurveEasingBlock);\n}\n"]}
@@ -64,7 +64,20 @@ export declare class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecution
64
64
  * @internal
65
65
  * @param context
66
66
  */
67
+ _startPendingTasks(context: FlowGraphContext): void;
68
+ /**
69
+ * @internal
70
+ * @param context the graph context
71
+ */
67
72
  _preparePendingTasks(context: FlowGraphContext): void;
73
+ /**
74
+ * Prepares and starts the animation, reporting whether it could be started. Invalid inputs
75
+ * activate `err` and return false, so the caller neither activates `out` nor registers the
76
+ * block as pending.
77
+ * @param context the graph context
78
+ * @returns whether the animation was prepared and started successfully
79
+ */
80
+ private _tryPreparePendingTasks;
68
81
  protected _reportError(context: FlowGraphContext, error: string | Error): void;
69
82
  /**
70
83
  * @internal
@@ -30,11 +30,38 @@ export class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {
30
30
  * @internal
31
31
  * @param context
32
32
  */
33
+ _startPendingTasks(context) {
34
+ if (context._getExecutionVariable(this, "_initialized", false)) {
35
+ this._cancelPendingTasks(context);
36
+ this._resetAfterCanceled(context);
37
+ }
38
+ if (!this._tryPreparePendingTasks(context)) {
39
+ return;
40
+ }
41
+ context._addPendingBlock(this);
42
+ this.out._activateSignal(context);
43
+ context._setExecutionVariable(this, "_initialized", true);
44
+ }
45
+ /**
46
+ * @internal
47
+ * @param context the graph context
48
+ */
33
49
  _preparePendingTasks(context) {
50
+ this._tryPreparePendingTasks(context);
51
+ }
52
+ /**
53
+ * Prepares and starts the animation, reporting whether it could be started. Invalid inputs
54
+ * activate `err` and return false, so the caller neither activates `out` nor registers the
55
+ * block as pending.
56
+ * @param context the graph context
57
+ * @returns whether the animation was prepared and started successfully
58
+ */
59
+ _tryPreparePendingTasks(context) {
34
60
  const ag = this.animationGroup.getValue(context);
35
61
  const animation = this.animation.getValue(context);
36
62
  if (!ag && !animation) {
37
- return this._reportError(context, "No animation or animation group provided");
63
+ this._reportError(context, "No animation or animation group provided");
64
+ return false;
38
65
  }
39
66
  else {
40
67
  // if an animation group was already created, dispose it and create a new one
@@ -43,16 +70,19 @@ export class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {
43
70
  currentAnimationGroup.dispose();
44
71
  }
45
72
  let animationGroupToUse = ag;
73
+ let isInterpolation = false;
74
+ let interpolationAnimationsArray;
75
+ let interpolationTarget;
46
76
  // check which animation to use. If no animationGroup was defined and an animation was provided, use the animation
47
77
  if (animation && !animationGroupToUse) {
48
78
  const target = this.object.getValue(context);
49
79
  if (!target) {
50
- return this._reportError(context, "No target object provided");
80
+ this._reportError(context, "No target object provided");
81
+ return false;
51
82
  }
52
83
  const animationsArray = Array.isArray(animation) ? animation : [animation];
53
84
  const name = animationsArray[0].name;
54
85
  animationGroupToUse = new AnimationGroup("flowGraphAnimationGroup-" + name + "-" + target.name, context.configuration.scene);
55
- let isInterpolation = false;
56
86
  const interpolationAnimations = context._getGlobalContextVariable("interpolationAnimations", []);
57
87
  for (const anim of animationsArray) {
58
88
  animationGroupToUse.addTargetedAnimation(anim, target);
@@ -60,15 +90,78 @@ export class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {
60
90
  isInterpolation = true;
61
91
  }
62
92
  }
63
- if (isInterpolation) {
64
- this._checkInterpolationDuplications(context, animationsArray, target);
65
- }
93
+ interpolationAnimationsArray = animationsArray;
94
+ interpolationTarget = target;
66
95
  }
67
96
  // not accepting 0
68
97
  const speed = this.speed.getValue(context) || 1;
69
98
  const from = this.from.getValue(context) ?? 0;
99
+ // Read the raw end time before it is defaulted to the animation group's natural end, so that an
100
+ // explicitly provided NaN end time can still be detected by the animation/start validation below.
101
+ const rawTo = this.to.getValue(context);
70
102
  // not accepting 0
71
- const to = this.to.getValue(context) || animationGroupToUse.to;
103
+ const to = rawTo || animationGroupToUse.to;
104
+ // Input validation. Only applies to animation-group playback
105
+ // (animation/start); interpolation uses the `animation` input and has its own validation below.
106
+ // The operation activates its `err` flow when the speed is NaN, infinite, or <= 0, or
107
+ // when the end time is NaN. A NaN or infinite start time is caught by the finite check on `from`.
108
+ if (!animation) {
109
+ if (isNaN(rawTo)) {
110
+ this._reportError(context, "Invalid animation end time");
111
+ return false;
112
+ }
113
+ // Only validate a speed that was explicitly provided; an unconnected speed keeps the engine
114
+ // default of 1 (matching the historical Babylon behavior for animation/start without a speed).
115
+ if (this.speed.isConnected() || context._hasConnectionValue(this.speed)) {
116
+ const providedSpeed = this.speed.getValue(context);
117
+ if (!isFinite(providedSpeed) || providedSpeed <= 0) {
118
+ this._reportError(context, "Invalid animation speed");
119
+ return false;
120
+ }
121
+ }
122
+ }
123
+ // The start value (interpolation start frame / animation start time) must always be finite. For
124
+ // animation/start this also satisfies the spec requirement that a NaN or infinite start time
125
+ // activates the err flow.
126
+ if (!isFinite(from)) {
127
+ this._reportError(context, "Invalid animation duration");
128
+ return false;
129
+ }
130
+ // For interpolation the end value is the animation duration and must be a finite, non-negative number.
131
+ // Animation-group playback (animation/start) instead allows an infinite end time — it means "play to
132
+ // the natural end / loop" (see the `loop` computation below) — and its NaN end time was already
133
+ // rejected above, so the end value is only range-checked here for the interpolation case.
134
+ if (animation && (!isFinite(to) || to < 0)) {
135
+ this._reportError(context, "Invalid animation duration");
136
+ return false;
137
+ }
138
+ // CSS cubic-bezier control points must be finite, and the X components must be in [0, 1].
139
+ if (animation) {
140
+ const animationsArray = Array.isArray(animation) ? animation : [animation];
141
+ for (const anim of animationsArray) {
142
+ const easing = anim.getEasingFunction?.();
143
+ if (easing && "x1" in easing) {
144
+ const bezier = easing;
145
+ if (!Number.isFinite(bezier.x1) ||
146
+ !Number.isFinite(bezier.y1) ||
147
+ !Number.isFinite(bezier.x2) ||
148
+ !Number.isFinite(bezier.y2) ||
149
+ bezier.x1 < 0 ||
150
+ bezier.x1 > 1 ||
151
+ bezier.x2 < 0 ||
152
+ bezier.x2 > 1) {
153
+ this._reportError(context, "Invalid bezier curve control points");
154
+ return false;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ // Stop any interpolation already running on the same target/property, but only after validation has
160
+ // passed. An invalid interpolation (bad duration or NaN control points) must report [err] without
161
+ // disturbing an interpolation that is already running on the same target.
162
+ if (isInterpolation && interpolationAnimationsArray && interpolationTarget !== undefined) {
163
+ this._checkInterpolationDuplications(context, interpolationAnimationsArray, interpolationTarget);
164
+ }
72
165
  const loop = !isFinite(to) || this.loop.getValue(context);
73
166
  this.currentAnimationGroup.setValue(animationGroupToUse, context);
74
167
  const currentlyRunningAnimationGroups = context._getGlobalContextVariable("currentlyRunningAnimationGroups", []);
@@ -87,7 +180,9 @@ export class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {
87
180
  }
88
181
  catch (e) {
89
182
  this._reportError(context, e);
183
+ return false;
90
184
  }
185
+ return true;
91
186
  }
92
187
  }
93
188
  _reportError(context, error) {
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraphPlayAnimationBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"../../../flowGraphAsyncExecutionBlock\";\r\nimport { RichTypeAny, RichTypeNumber, RichTypeBoolean } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { type Animation } from \"core/Animations/animation.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * @experimental\r\n * A block that plays an animation on an animatable object.\r\n */\r\nexport class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {\r\n /**\r\n * Input connection: The speed of the animation.\r\n */\r\n public readonly speed: FlowGraphDataConnection<number>;\r\n /**\r\n * Input connection: Should the animation loop?\r\n * Not in glTF specs, but useful for the engine.\r\n */\r\n public readonly loop: FlowGraphDataConnection<boolean>;\r\n /**\r\n * Input connection: The starting frame of the animation.\r\n */\r\n public readonly from: FlowGraphDataConnection<number>;\r\n /**\r\n * Input connection: The ending frame of the animation.\r\n */\r\n public readonly to: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The current frame of the animation.\r\n */\r\n public readonly currentFrame: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The current time of the animation.\r\n */\r\n public readonly currentTime: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The animatable that is currently running.\r\n */\r\n public readonly currentAnimationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n /**\r\n * Input: Will be initialized if no animation group was provided in the configuration.\r\n */\r\n public readonly animationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n /**\r\n * Input: If provided this animation will be used. Priority will be given to the animation group input.\r\n */\r\n public readonly animation: FlowGraphDataConnection<Animation | Animation[]>;\r\n\r\n /**\r\n * Input connection: The target object that will be animated. If animation group is provided this input will be ignored.\r\n */\r\n public readonly object: FlowGraphDataConnection<any>;\r\n\r\n public constructor(\r\n /**\r\n * the configuration of the block\r\n */\r\n public override config?: IFlowGraphBlockConfiguration\r\n ) {\r\n super(config, [\"animationLoop\", \"animationEnd\", \"animationGroupLoop\"]);\r\n\r\n this.speed = this.registerDataInput(\"speed\", RichTypeNumber);\r\n this.loop = this.registerDataInput(\"loop\", RichTypeBoolean);\r\n this.from = this.registerDataInput(\"from\", RichTypeNumber, 0);\r\n this.to = this.registerDataInput(\"to\", RichTypeNumber);\r\n\r\n this.currentFrame = this.registerDataOutput(\"currentFrame\", RichTypeNumber);\r\n this.currentTime = this.registerDataOutput(\"currentTime\", RichTypeNumber);\r\n\r\n this.currentAnimationGroup = this.registerDataOutput(\"currentAnimationGroup\", RichTypeAny);\r\n this.animationGroup = this.registerDataInput(\"animationGroup\", RichTypeAny, config?.animationGroup);\r\n this.animation = this.registerDataInput(\"animation\", RichTypeAny);\r\n this.object = this.registerDataInput(\"object\", RichTypeAny);\r\n }\r\n\r\n /**\r\n * @internal\r\n * @param context\r\n */\r\n public override _preparePendingTasks(context: FlowGraphContext): void {\r\n const ag = this.animationGroup.getValue(context);\r\n const animation = this.animation.getValue(context);\r\n if (!ag && !animation) {\r\n return this._reportError(context, \"No animation or animation group provided\");\r\n } else {\r\n // if an animation group was already created, dispose it and create a new one\r\n const currentAnimationGroup = this.currentAnimationGroup.getValue(context);\r\n if (currentAnimationGroup && currentAnimationGroup !== ag) {\r\n currentAnimationGroup.dispose();\r\n }\r\n let animationGroupToUse = ag;\r\n // check which animation to use. If no animationGroup was defined and an animation was provided, use the animation\r\n if (animation && !animationGroupToUse) {\r\n const target = this.object.getValue(context);\r\n if (!target) {\r\n return this._reportError(context, \"No target object provided\");\r\n }\r\n const animationsArray = Array.isArray(animation) ? animation : [animation];\r\n const name = animationsArray[0].name;\r\n animationGroupToUse = new AnimationGroup(\"flowGraphAnimationGroup-\" + name + \"-\" + target.name, context.configuration.scene);\r\n let isInterpolation = false;\r\n const interpolationAnimations = context._getGlobalContextVariable(\"interpolationAnimations\", []) as number[];\r\n for (const anim of animationsArray) {\r\n animationGroupToUse.addTargetedAnimation(anim, target);\r\n if (interpolationAnimations.indexOf(anim.uniqueId) !== -1) {\r\n isInterpolation = true;\r\n }\r\n }\r\n\r\n if (isInterpolation) {\r\n this._checkInterpolationDuplications(context, animationsArray, target);\r\n }\r\n }\r\n // not accepting 0\r\n const speed = this.speed.getValue(context) || 1;\r\n const from = this.from.getValue(context) ?? 0;\r\n // not accepting 0\r\n const to = this.to.getValue(context) || animationGroupToUse.to;\r\n const loop = !isFinite(to) || this.loop.getValue(context);\r\n this.currentAnimationGroup.setValue(animationGroupToUse, context);\r\n\r\n const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n // check if it already running\r\n if (currentlyRunningAnimationGroups.indexOf(animationGroupToUse.uniqueId) !== -1) {\r\n animationGroupToUse.stop();\r\n }\r\n try {\r\n animationGroupToUse.start(loop, speed, from, to);\r\n animationGroupToUse.onAnimationGroupEndObservable.add(() => this._onAnimationGroupEnd(context));\r\n animationGroupToUse.onAnimationEndObservable.add(() => this._eventsSignalOutputs[\"animationEnd\"]._activateSignal(context));\r\n animationGroupToUse.onAnimationLoopObservable.add(() => this._eventsSignalOutputs[\"animationLoop\"]._activateSignal(context));\r\n animationGroupToUse.onAnimationGroupLoopObservable.add(() => this._eventsSignalOutputs[\"animationGroupLoop\"]._activateSignal(context));\r\n currentlyRunningAnimationGroups.push(animationGroupToUse.uniqueId);\r\n context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\r\n } catch (e) {\r\n this._reportError(context, e);\r\n }\r\n }\r\n }\r\n\r\n protected override _reportError(context: FlowGraphContext, error: string | Error): void {\r\n super._reportError(context, error);\r\n this.currentFrame.setValue(-1, context);\r\n this.currentTime.setValue(-1, context);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _executeOnTick(_context: FlowGraphContext): void {\r\n const ag = this.currentAnimationGroup.getValue(_context);\r\n if (ag) {\r\n this.currentFrame.setValue(ag.getCurrentFrame(), _context);\r\n this.currentTime.setValue(ag.animatables[0]?.elapsedTime ?? 0, _context);\r\n }\r\n }\r\n\r\n public _execute(context: FlowGraphContext): void {\r\n this._startPendingTasks(context);\r\n }\r\n\r\n private _onAnimationGroupEnd(context: FlowGraphContext) {\r\n this._removeFromCurrentlyRunning(context, this.currentAnimationGroup.getValue(context));\r\n this._resetAfterCanceled(context);\r\n this.done._activateSignal(context);\r\n }\r\n\r\n /**\r\n * The idea behind this function is to check every running animation group and check if the targeted animations it uses are interpolation animations.\r\n * If they are, we want to see that they don't collide with the current interpolation animations that are starting to play.\r\n * If they do, we want to stop the already-running animation group.\r\n * @internal\r\n */\r\n private _checkInterpolationDuplications(context: FlowGraphContext, animation: Animation[], target: any) {\r\n const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n for (const uniqueId of currentlyRunningAnimationGroups) {\r\n const ag = context.assetsContext.animationGroups.find((ag) => ag.uniqueId === uniqueId);\r\n if (ag) {\r\n for (const anim of ag.targetedAnimations) {\r\n for (const animToCheck of animation) {\r\n if (anim.animation.targetProperty === animToCheck.targetProperty && anim.target === target) {\r\n this._stopAnimationGroup(context, ag);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _stopAnimationGroup(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n // stop, while skipping the on AnimationEndObservable to avoid the \"done\" signal\r\n animationGroup.stop(true);\r\n // Only dispose animation groups that were internally created by this block\r\n // (i.e. built from individual animations). Scene-provided animation groups\r\n // must not be disposed as that removes them from the scene catalog and\r\n // breaks the editor dropdown / re-use on replay.\r\n if (animationGroup.name.startsWith(\"flowGraphAnimationGroup-\")) {\r\n animationGroup.dispose();\r\n }\r\n this._removeFromCurrentlyRunning(context, animationGroup);\r\n }\r\n\r\n private _removeFromCurrentlyRunning(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n const idx = currentlyRunningAnimationGroups.indexOf(animationGroup.uniqueId);\r\n if (idx !== -1) {\r\n currentlyRunningAnimationGroups.splice(idx, 1);\r\n context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Stop any currently running animations.\r\n */\r\n public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n const ag = this.currentAnimationGroup.getValue(context);\r\n if (ag) {\r\n this._stopAnimationGroup(context, ag);\r\n }\r\n }\r\n\r\n /**\r\n * @returns class name of the block.\r\n */\r\n public override getClassName(): string {\r\n return FlowGraphBlockNames.PlayAnimation;\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphPlayAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphPlayAnimationBlock(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterClass(FlowGraphBlockNames.PlayAnimation, FlowGraphPlayAnimationBlock);\r\n}\r\n"]}
1
+ {"version":3,"file":"flowGraphPlayAnimationBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphPlayAnimationBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"../../../flowGraphAsyncExecutionBlock\";\r\nimport { RichTypeAny, RichTypeNumber, RichTypeBoolean } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { type Animation } from \"core/Animations/animation.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n\r\n/**\r\n * @experimental\r\n * A block that plays an animation on an animatable object.\r\n */\r\nexport class FlowGraphPlayAnimationBlock extends FlowGraphAsyncExecutionBlock {\r\n /**\r\n * Input connection: The speed of the animation.\r\n */\r\n public readonly speed: FlowGraphDataConnection<number>;\r\n /**\r\n * Input connection: Should the animation loop?\r\n * Not in glTF specs, but useful for the engine.\r\n */\r\n public readonly loop: FlowGraphDataConnection<boolean>;\r\n /**\r\n * Input connection: The starting frame of the animation.\r\n */\r\n public readonly from: FlowGraphDataConnection<number>;\r\n /**\r\n * Input connection: The ending frame of the animation.\r\n */\r\n public readonly to: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The current frame of the animation.\r\n */\r\n public readonly currentFrame: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The current time of the animation.\r\n */\r\n public readonly currentTime: FlowGraphDataConnection<number>;\r\n\r\n /**\r\n * Output connection: The animatable that is currently running.\r\n */\r\n public readonly currentAnimationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n /**\r\n * Input: Will be initialized if no animation group was provided in the configuration.\r\n */\r\n public readonly animationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n /**\r\n * Input: If provided this animation will be used. Priority will be given to the animation group input.\r\n */\r\n public readonly animation: FlowGraphDataConnection<Animation | Animation[]>;\r\n\r\n /**\r\n * Input connection: The target object that will be animated. If animation group is provided this input will be ignored.\r\n */\r\n public readonly object: FlowGraphDataConnection<any>;\r\n\r\n public constructor(\r\n /**\r\n * the configuration of the block\r\n */\r\n public override config?: IFlowGraphBlockConfiguration\r\n ) {\r\n super(config, [\"animationLoop\", \"animationEnd\", \"animationGroupLoop\"]);\r\n\r\n this.speed = this.registerDataInput(\"speed\", RichTypeNumber);\r\n this.loop = this.registerDataInput(\"loop\", RichTypeBoolean);\r\n this.from = this.registerDataInput(\"from\", RichTypeNumber, 0);\r\n this.to = this.registerDataInput(\"to\", RichTypeNumber);\r\n\r\n this.currentFrame = this.registerDataOutput(\"currentFrame\", RichTypeNumber);\r\n this.currentTime = this.registerDataOutput(\"currentTime\", RichTypeNumber);\r\n\r\n this.currentAnimationGroup = this.registerDataOutput(\"currentAnimationGroup\", RichTypeAny);\r\n this.animationGroup = this.registerDataInput(\"animationGroup\", RichTypeAny, config?.animationGroup);\r\n this.animation = this.registerDataInput(\"animation\", RichTypeAny);\r\n this.object = this.registerDataInput(\"object\", RichTypeAny);\r\n }\r\n\r\n /**\r\n * @internal\r\n * @param context\r\n */\r\n public override _startPendingTasks(context: FlowGraphContext): void {\r\n if (context._getExecutionVariable(this, \"_initialized\", false)) {\r\n this._cancelPendingTasks(context);\r\n this._resetAfterCanceled(context);\r\n }\r\n\r\n if (!this._tryPreparePendingTasks(context)) {\r\n return;\r\n }\r\n context._addPendingBlock(this);\r\n this.out._activateSignal(context);\r\n context._setExecutionVariable(this, \"_initialized\", true);\r\n }\r\n\r\n /**\r\n * @internal\r\n * @param context the graph context\r\n */\r\n public override _preparePendingTasks(context: FlowGraphContext): void {\r\n this._tryPreparePendingTasks(context);\r\n }\r\n\r\n /**\r\n * Prepares and starts the animation, reporting whether it could be started. Invalid inputs\r\n * activate `err` and return false, so the caller neither activates `out` nor registers the\r\n * block as pending.\r\n * @param context the graph context\r\n * @returns whether the animation was prepared and started successfully\r\n */\r\n private _tryPreparePendingTasks(context: FlowGraphContext): boolean {\r\n const ag = this.animationGroup.getValue(context);\r\n const animation = this.animation.getValue(context);\r\n if (!ag && !animation) {\r\n this._reportError(context, \"No animation or animation group provided\");\r\n return false;\r\n } else {\r\n // if an animation group was already created, dispose it and create a new one\r\n const currentAnimationGroup = this.currentAnimationGroup.getValue(context);\r\n if (currentAnimationGroup && currentAnimationGroup !== ag) {\r\n currentAnimationGroup.dispose();\r\n }\r\n let animationGroupToUse = ag;\r\n let isInterpolation = false;\r\n let interpolationAnimationsArray: Animation[] | undefined;\r\n let interpolationTarget: any;\r\n // check which animation to use. If no animationGroup was defined and an animation was provided, use the animation\r\n if (animation && !animationGroupToUse) {\r\n const target = this.object.getValue(context);\r\n if (!target) {\r\n this._reportError(context, \"No target object provided\");\r\n return false;\r\n }\r\n const animationsArray = Array.isArray(animation) ? animation : [animation];\r\n const name = animationsArray[0].name;\r\n animationGroupToUse = new AnimationGroup(\"flowGraphAnimationGroup-\" + name + \"-\" + target.name, context.configuration.scene);\r\n const interpolationAnimations = context._getGlobalContextVariable(\"interpolationAnimations\", []) as number[];\r\n for (const anim of animationsArray) {\r\n animationGroupToUse.addTargetedAnimation(anim, target);\r\n if (interpolationAnimations.indexOf(anim.uniqueId) !== -1) {\r\n isInterpolation = true;\r\n }\r\n }\r\n interpolationAnimationsArray = animationsArray;\r\n interpolationTarget = target;\r\n }\r\n // not accepting 0\r\n const speed = this.speed.getValue(context) || 1;\r\n const from = this.from.getValue(context) ?? 0;\r\n // Read the raw end time before it is defaulted to the animation group's natural end, so that an\r\n // explicitly provided NaN end time can still be detected by the animation/start validation below.\r\n const rawTo = this.to.getValue(context);\r\n // not accepting 0\r\n const to = rawTo || animationGroupToUse.to;\r\n\r\n // Input validation. Only applies to animation-group playback\r\n // (animation/start); interpolation uses the `animation` input and has its own validation below.\r\n // The operation activates its `err` flow when the speed is NaN, infinite, or <= 0, or\r\n // when the end time is NaN. A NaN or infinite start time is caught by the finite check on `from`.\r\n if (!animation) {\r\n if (isNaN(rawTo)) {\r\n this._reportError(context, \"Invalid animation end time\");\r\n return false;\r\n }\r\n // Only validate a speed that was explicitly provided; an unconnected speed keeps the engine\r\n // default of 1 (matching the historical Babylon behavior for animation/start without a speed).\r\n if (this.speed.isConnected() || context._hasConnectionValue(this.speed)) {\r\n const providedSpeed = this.speed.getValue(context);\r\n if (!isFinite(providedSpeed) || providedSpeed <= 0) {\r\n this._reportError(context, \"Invalid animation speed\");\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n // The start value (interpolation start frame / animation start time) must always be finite. For\r\n // animation/start this also satisfies the spec requirement that a NaN or infinite start time\r\n // activates the err flow.\r\n if (!isFinite(from)) {\r\n this._reportError(context, \"Invalid animation duration\");\r\n return false;\r\n }\r\n // For interpolation the end value is the animation duration and must be a finite, non-negative number.\r\n // Animation-group playback (animation/start) instead allows an infinite end time — it means \"play to\r\n // the natural end / loop\" (see the `loop` computation below) — and its NaN end time was already\r\n // rejected above, so the end value is only range-checked here for the interpolation case.\r\n if (animation && (!isFinite(to) || to < 0)) {\r\n this._reportError(context, \"Invalid animation duration\");\r\n return false;\r\n }\r\n\r\n // CSS cubic-bezier control points must be finite, and the X components must be in [0, 1].\r\n if (animation) {\r\n const animationsArray = Array.isArray(animation) ? animation : [animation];\r\n for (const anim of animationsArray) {\r\n const easing = anim.getEasingFunction?.();\r\n if (easing && \"x1\" in easing) {\r\n const bezier = easing as unknown as { x1: number; y1: number; x2: number; y2: number };\r\n if (\r\n !Number.isFinite(bezier.x1) ||\r\n !Number.isFinite(bezier.y1) ||\r\n !Number.isFinite(bezier.x2) ||\r\n !Number.isFinite(bezier.y2) ||\r\n bezier.x1 < 0 ||\r\n bezier.x1 > 1 ||\r\n bezier.x2 < 0 ||\r\n bezier.x2 > 1\r\n ) {\r\n this._reportError(context, \"Invalid bezier curve control points\");\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Stop any interpolation already running on the same target/property, but only after validation has\r\n // passed. An invalid interpolation (bad duration or NaN control points) must report [err] without\r\n // disturbing an interpolation that is already running on the same target.\r\n if (isInterpolation && interpolationAnimationsArray && interpolationTarget !== undefined) {\r\n this._checkInterpolationDuplications(context, interpolationAnimationsArray, interpolationTarget);\r\n }\r\n\r\n const loop = !isFinite(to) || this.loop.getValue(context);\r\n this.currentAnimationGroup.setValue(animationGroupToUse, context);\r\n\r\n const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n // check if it already running\r\n if (currentlyRunningAnimationGroups.indexOf(animationGroupToUse.uniqueId) !== -1) {\r\n animationGroupToUse.stop();\r\n }\r\n try {\r\n animationGroupToUse.start(loop, speed, from, to);\r\n animationGroupToUse.onAnimationGroupEndObservable.add(() => this._onAnimationGroupEnd(context));\r\n animationGroupToUse.onAnimationEndObservable.add(() => this._eventsSignalOutputs[\"animationEnd\"]._activateSignal(context));\r\n animationGroupToUse.onAnimationLoopObservable.add(() => this._eventsSignalOutputs[\"animationLoop\"]._activateSignal(context));\r\n animationGroupToUse.onAnimationGroupLoopObservable.add(() => this._eventsSignalOutputs[\"animationGroupLoop\"]._activateSignal(context));\r\n currentlyRunningAnimationGroups.push(animationGroupToUse.uniqueId);\r\n context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\r\n } catch (e) {\r\n this._reportError(context, e);\r\n return false;\r\n }\r\n return true;\r\n }\r\n }\r\n\r\n protected override _reportError(context: FlowGraphContext, error: string | Error): void {\r\n super._reportError(context, error);\r\n this.currentFrame.setValue(-1, context);\r\n this.currentTime.setValue(-1, context);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _executeOnTick(_context: FlowGraphContext): void {\r\n const ag = this.currentAnimationGroup.getValue(_context);\r\n if (ag) {\r\n this.currentFrame.setValue(ag.getCurrentFrame(), _context);\r\n this.currentTime.setValue(ag.animatables[0]?.elapsedTime ?? 0, _context);\r\n }\r\n }\r\n\r\n public _execute(context: FlowGraphContext): void {\r\n this._startPendingTasks(context);\r\n }\r\n\r\n private _onAnimationGroupEnd(context: FlowGraphContext) {\r\n this._removeFromCurrentlyRunning(context, this.currentAnimationGroup.getValue(context));\r\n this._resetAfterCanceled(context);\r\n this.done._activateSignal(context);\r\n }\r\n\r\n /**\r\n * The idea behind this function is to check every running animation group and check if the targeted animations it uses are interpolation animations.\r\n * If they are, we want to see that they don't collide with the current interpolation animations that are starting to play.\r\n * If they do, we want to stop the already-running animation group.\r\n * @internal\r\n */\r\n private _checkInterpolationDuplications(context: FlowGraphContext, animation: Animation[], target: any) {\r\n const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n for (const uniqueId of currentlyRunningAnimationGroups) {\r\n const ag = context.assetsContext.animationGroups.find((ag) => ag.uniqueId === uniqueId);\r\n if (ag) {\r\n for (const anim of ag.targetedAnimations) {\r\n for (const animToCheck of animation) {\r\n if (anim.animation.targetProperty === animToCheck.targetProperty && anim.target === target) {\r\n this._stopAnimationGroup(context, ag);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _stopAnimationGroup(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n // stop, while skipping the on AnimationEndObservable to avoid the \"done\" signal\r\n animationGroup.stop(true);\r\n // Only dispose animation groups that were internally created by this block\r\n // (i.e. built from individual animations). Scene-provided animation groups\r\n // must not be disposed as that removes them from the scene catalog and\r\n // breaks the editor dropdown / re-use on replay.\r\n if (animationGroup.name.startsWith(\"flowGraphAnimationGroup-\")) {\r\n animationGroup.dispose();\r\n }\r\n this._removeFromCurrentlyRunning(context, animationGroup);\r\n }\r\n\r\n private _removeFromCurrentlyRunning(context: FlowGraphContext, animationGroup: AnimationGroup) {\r\n const currentlyRunningAnimationGroups = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n const idx = currentlyRunningAnimationGroups.indexOf(animationGroup.uniqueId);\r\n if (idx !== -1) {\r\n currentlyRunningAnimationGroups.splice(idx, 1);\r\n context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunningAnimationGroups);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Stop any currently running animations.\r\n */\r\n public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n const ag = this.currentAnimationGroup.getValue(context);\r\n if (ag) {\r\n this._stopAnimationGroup(context, ag);\r\n }\r\n }\r\n\r\n /**\r\n * @returns class name of the block.\r\n */\r\n public override getClassName(): string {\r\n return FlowGraphBlockNames.PlayAnimation;\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphPlayAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphPlayAnimationBlock(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterClass(FlowGraphBlockNames.PlayAnimation, FlowGraphPlayAnimationBlock);\r\n}\r\n"]}
@@ -88,7 +88,11 @@ export class FlowGraphStopAnimationBlock extends FlowGraphAsyncExecutionBlock {
88
88
  const currentlyRunning = context._getGlobalContextVariable("currentlyRunningAnimationGroups", []);
89
89
  const index = currentlyRunning.indexOf(animationGroup.uniqueId);
90
90
  if (index !== -1) {
91
- animationGroup.stop();
91
+ // Skip the animation-end observable so that stopping does not activate the originating
92
+ // starting block's `done` flow. When an animation is
93
+ // stopped (animation/stop or animation/stopAt) the previously associated `done` flows MUST NOT be
94
+ // activated; only animation/stopAt's own `done` flow (fired from _executeOnTick) should run.
95
+ animationGroup.stop(true);
92
96
  currentlyRunning.splice(index, 1);
93
97
  // update the global context variable
94
98
  context._setGlobalContextVariable("currentlyRunningAnimationGroups", currentlyRunning);
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraphStopAnimationBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeAny, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { type AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"core/FlowGraph/flowGraphAsyncExecutionBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * @experimental\r\n * Block that stops a running animation\r\n */\r\nexport class FlowGraphStopAnimationBlock extends FlowGraphAsyncExecutionBlock {\r\n /**\r\n * Input connection: The animation to stop.\r\n */\r\n public readonly animationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n /**\r\n * Input connection - if defined (positive integer) the animation will stop at this frame.\r\n */\r\n public readonly stopAtFrame: FlowGraphDataConnection<number>;\r\n\r\n constructor(config?: IFlowGraphBlockConfiguration) {\r\n super(config);\r\n this.animationGroup = this.registerDataInput(\"animationGroup\", RichTypeAny);\r\n this.stopAtFrame = this.registerDataInput(\"stopAtFrame\", RichTypeNumber, -1);\r\n }\r\n\r\n public override _preparePendingTasks(context: FlowGraphContext): void {\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n const stopAtFrame = this.stopAtFrame.getValue(context) ?? -1;\r\n // get the context variable\r\n const pendingStopAnimations = context._getGlobalContextVariable(\r\n \"pendingStopAnimations\",\r\n [] as {\r\n uniqueId: number;\r\n stopAtFrame: number;\r\n }[]\r\n );\r\n // add the animation to the list\r\n pendingStopAnimations.push({ uniqueId: animationToStopValue.uniqueId, stopAtFrame });\r\n // set the global context variable\r\n context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n }\r\n public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n // remove the animation from the list\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n const pendingStopAnimations = context._getGlobalContextVariable(\r\n \"pendingStopAnimations\",\r\n [] as {\r\n uniqueId: number;\r\n stopAtFrame: number;\r\n }[]\r\n );\r\n for (let i = 0; i < pendingStopAnimations.length; i++) {\r\n if (pendingStopAnimations[i].uniqueId === animationToStopValue.uniqueId) {\r\n pendingStopAnimations.splice(i, 1);\r\n // set the global context variable\r\n context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n public _execute(context: FlowGraphContext): void {\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n const stopTime = this.stopAtFrame.getValue(context) ?? -1;\r\n // check the values\r\n if (!animationToStopValue) {\r\n Logger.Warn(\"No animation group provided to stop.\");\r\n return this._reportError(context, \"No animation group provided to stop.\");\r\n }\r\n if (isNaN(stopTime)) {\r\n return this._reportError(context, \"Invalid stop time.\");\r\n }\r\n if (stopTime > 0) {\r\n this._startPendingTasks(context);\r\n } else {\r\n this._stopAnimation(animationToStopValue, context);\r\n }\r\n // note that out will not be triggered in case of an error\r\n this.out._activateSignal(context);\r\n }\r\n\r\n public override _executeOnTick(context: FlowGraphContext): void {\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n // check each frame if any animation should be stopped\r\n const pendingStopAnimations = context._getGlobalContextVariable(\"pendingStopAnimations\", [] as { uniqueId: number; stopAtFrame: number }[]);\r\n for (let i = 0; i < pendingStopAnimations.length; i++) {\r\n // compare the uniqueId to the animation to stop\r\n if (pendingStopAnimations[i].uniqueId === animationToStopValue.uniqueId) {\r\n // check if the current frame is AFTER the stopAtFrame\r\n if (animationToStopValue.getCurrentFrame() >= pendingStopAnimations[i].stopAtFrame) {\r\n // stop the animation\r\n this._stopAnimation(animationToStopValue, context);\r\n // remove the animation from the list\r\n pendingStopAnimations.splice(i, 1);\r\n // set the global context variable\r\n context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n this.done._activateSignal(context);\r\n context._removePendingBlock(this);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns class name of the block.\r\n */\r\n public override getClassName(): string {\r\n return FlowGraphBlockNames.StopAnimation;\r\n }\r\n\r\n private _stopAnimation(animationGroup: AnimationGroup, context: FlowGraphContext): void {\r\n const currentlyRunning = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n const index = currentlyRunning.indexOf(animationGroup.uniqueId);\r\n if (index !== -1) {\r\n animationGroup.stop();\r\n currentlyRunning.splice(index, 1);\r\n // update the global context variable\r\n context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunning);\r\n } else {\r\n // Logger.Warn(\"Trying to stop an animation that is not running.\");\r\n // no-op for now. Probably no need to log anything here.\r\n }\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphStopAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphStopAnimationBlock(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterClass(FlowGraphBlockNames.StopAnimation, FlowGraphStopAnimationBlock);\r\n}\r\n"]}
1
+ {"version":3,"file":"flowGraphStopAnimationBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/Animation/flowGraphStopAnimationBlock.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\r\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\r\nimport { RichTypeAny, RichTypeNumber } from \"../../../flowGraphRichTypes.pure\";\r\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\r\nimport { type AnimationGroup } from \"core/Animations/animationGroup.pure\";\r\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { FlowGraphAsyncExecutionBlock } from \"core/FlowGraph/flowGraphAsyncExecutionBlock\";\r\nimport { RegisterClass } from \"../../../../Misc/typeStore\";\r\n/**\r\n * @experimental\r\n * Block that stops a running animation\r\n */\r\nexport class FlowGraphStopAnimationBlock extends FlowGraphAsyncExecutionBlock {\r\n /**\r\n * Input connection: The animation to stop.\r\n */\r\n public readonly animationGroup: FlowGraphDataConnection<AnimationGroup>;\r\n\r\n /**\r\n * Input connection - if defined (positive integer) the animation will stop at this frame.\r\n */\r\n public readonly stopAtFrame: FlowGraphDataConnection<number>;\r\n\r\n constructor(config?: IFlowGraphBlockConfiguration) {\r\n super(config);\r\n this.animationGroup = this.registerDataInput(\"animationGroup\", RichTypeAny);\r\n this.stopAtFrame = this.registerDataInput(\"stopAtFrame\", RichTypeNumber, -1);\r\n }\r\n\r\n public override _preparePendingTasks(context: FlowGraphContext): void {\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n const stopAtFrame = this.stopAtFrame.getValue(context) ?? -1;\r\n // get the context variable\r\n const pendingStopAnimations = context._getGlobalContextVariable(\r\n \"pendingStopAnimations\",\r\n [] as {\r\n uniqueId: number;\r\n stopAtFrame: number;\r\n }[]\r\n );\r\n // add the animation to the list\r\n pendingStopAnimations.push({ uniqueId: animationToStopValue.uniqueId, stopAtFrame });\r\n // set the global context variable\r\n context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n }\r\n public override _cancelPendingTasks(context: FlowGraphContext): void {\r\n // remove the animation from the list\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n const pendingStopAnimations = context._getGlobalContextVariable(\r\n \"pendingStopAnimations\",\r\n [] as {\r\n uniqueId: number;\r\n stopAtFrame: number;\r\n }[]\r\n );\r\n for (let i = 0; i < pendingStopAnimations.length; i++) {\r\n if (pendingStopAnimations[i].uniqueId === animationToStopValue.uniqueId) {\r\n pendingStopAnimations.splice(i, 1);\r\n // set the global context variable\r\n context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n public _execute(context: FlowGraphContext): void {\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n const stopTime = this.stopAtFrame.getValue(context) ?? -1;\r\n // check the values\r\n if (!animationToStopValue) {\r\n Logger.Warn(\"No animation group provided to stop.\");\r\n return this._reportError(context, \"No animation group provided to stop.\");\r\n }\r\n if (isNaN(stopTime)) {\r\n return this._reportError(context, \"Invalid stop time.\");\r\n }\r\n if (stopTime > 0) {\r\n this._startPendingTasks(context);\r\n } else {\r\n this._stopAnimation(animationToStopValue, context);\r\n }\r\n // note that out will not be triggered in case of an error\r\n this.out._activateSignal(context);\r\n }\r\n\r\n public override _executeOnTick(context: FlowGraphContext): void {\r\n const animationToStopValue = this.animationGroup.getValue(context);\r\n // check each frame if any animation should be stopped\r\n const pendingStopAnimations = context._getGlobalContextVariable(\"pendingStopAnimations\", [] as { uniqueId: number; stopAtFrame: number }[]);\r\n for (let i = 0; i < pendingStopAnimations.length; i++) {\r\n // compare the uniqueId to the animation to stop\r\n if (pendingStopAnimations[i].uniqueId === animationToStopValue.uniqueId) {\r\n // check if the current frame is AFTER the stopAtFrame\r\n if (animationToStopValue.getCurrentFrame() >= pendingStopAnimations[i].stopAtFrame) {\r\n // stop the animation\r\n this._stopAnimation(animationToStopValue, context);\r\n // remove the animation from the list\r\n pendingStopAnimations.splice(i, 1);\r\n // set the global context variable\r\n context._setGlobalContextVariable(\"pendingStopAnimations\", pendingStopAnimations);\r\n this.done._activateSignal(context);\r\n context._removePendingBlock(this);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns class name of the block.\r\n */\r\n public override getClassName(): string {\r\n return FlowGraphBlockNames.StopAnimation;\r\n }\r\n\r\n private _stopAnimation(animationGroup: AnimationGroup, context: FlowGraphContext): void {\r\n const currentlyRunning = context._getGlobalContextVariable(\"currentlyRunningAnimationGroups\", []) as number[];\r\n const index = currentlyRunning.indexOf(animationGroup.uniqueId);\r\n if (index !== -1) {\r\n // Skip the animation-end observable so that stopping does not activate the originating\r\n // starting block's `done` flow. When an animation is\r\n // stopped (animation/stop or animation/stopAt) the previously associated `done` flows MUST NOT be\r\n // activated; only animation/stopAt's own `done` flow (fired from _executeOnTick) should run.\r\n animationGroup.stop(true);\r\n currentlyRunning.splice(index, 1);\r\n // update the global context variable\r\n context._setGlobalContextVariable(\"currentlyRunningAnimationGroups\", currentlyRunning);\r\n } else {\r\n // Logger.Warn(\"Trying to stop an animation that is not running.\");\r\n // no-op for now. Probably no need to log anything here.\r\n }\r\n }\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for flowGraphStopAnimationBlock.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterFlowGraphStopAnimationBlock(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n RegisterClass(FlowGraphBlockNames.StopAnimation, FlowGraphStopAnimationBlock);\r\n}\r\n"]}
@@ -2,6 +2,7 @@
2
2
  import { FlowGraphExecutionBlockWithOutSignal } from "../../../flowGraphExecutionBlockWithOutSignal.js";
3
3
  import { RichTypeFlowGraphInteger } from "../../../flowGraphRichTypes.pure.js";
4
4
  import { getNumericValue } from "../../../utils.js";
5
+ import { MarkDelayInactive } from "../../../flowGraphDelayRegistry.js";
5
6
  import { RegisterClass } from "../../../../Misc/typeStore.js";
6
7
  /**
7
8
  * This block cancels a delay that was previously scheduled.
@@ -20,8 +21,11 @@ export class FlowGraphCancelDelayBlock extends FlowGraphExecutionBlockWithOutSig
20
21
  const timer = timers[delayIndex];
21
22
  if (timer) {
22
23
  timer.dispose();
23
- // not removing it from the array. Disposing it will clear all of its resources
24
+ delete timers[delayIndex];
25
+ context._setGlobalContextVariable("pendingDelays", timers);
24
26
  }
27
+ // The delay is cancelled, so drop it from the active set used by handle validity checks.
28
+ MarkDelayInactive(context, delayIndex);
25
29
  // activate the out output flow
26
30
  this.out._activateSignal(context);
27
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flowGraphCancelDelayBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAM7D,OAAO,EAAE,oCAAoC,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAI5E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,yBAA0B,SAAQ,oCAAoC;IAM/E,YAAY,MAAqC;QAC7C,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;IACrF,CAAC;IAEM,QAAQ,CAAC,OAAyB,EAAE,cAAyC;QAChF,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,IAAI,UAAU,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,eAAe,EAAE,EAAqB,CAAC,CAAC;QACzF,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,+EAA+E;QACnF,CAAC;QACD,+BAA+B;QAC/B,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAEe,YAAY;QACxB,yEAAuC;IAC3C,CAAC;CACJ;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB;;;GAGG;AACH,MAAM,UAAU,iCAAiC;IAC7C,IAAI,WAAW,EAAE,CAAC;QACd,OAAO;IACX,CAAC;IACD,WAAW,GAAG,IAAI,CAAC;IAEnB,aAAa,oEAAkC,yBAAyB,CAAC,CAAC;AAC9E,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\n\nimport { type AdvancedTimer } from \"../../../../Misc/timer\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeFlowGraphInteger } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { getNumericValue } from \"core/FlowGraph/utils\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * This block cancels a delay that was previously scheduled.\n */\nexport class FlowGraphCancelDelayBlock extends FlowGraphExecutionBlockWithOutSignal {\n /**\n * Input connection: The index value of the scheduled activation to be cancelled.\n */\n public readonly delayIndex: FlowGraphDataConnection<FlowGraphInteger>;\n\n constructor(config?: IFlowGraphBlockConfiguration) {\n super(config);\n this.delayIndex = this.registerDataInput(\"delayIndex\", RichTypeFlowGraphInteger);\n }\n\n public _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n const delayIndex = getNumericValue(this.delayIndex.getValue(context));\n if (delayIndex < 0 || isNaN(delayIndex) || !isFinite(delayIndex)) {\n return this._reportError(context, \"Invalid delay index\");\n }\n const timers = context._getGlobalContextVariable(\"pendingDelays\", [] as AdvancedTimer[]);\n const timer = timers[delayIndex];\n if (timer) {\n timer.dispose();\n // not removing it from the array. Disposing it will clear all of its resources\n }\n // activate the out output flow\n this.out._activateSignal(context);\n }\n\n public override getClassName(): string {\n return FlowGraphBlockNames.CancelDelay;\n }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphCancelDelayBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphCancelDelayBlock(): void {\n if (_Registered) {\n return;\n }\n _Registered = true;\n\n RegisterClass(FlowGraphBlockNames.CancelDelay, FlowGraphCancelDelayBlock);\n}\n"]}
1
+ {"version":3,"file":"flowGraphCancelDelayBlock.pure.js","sourceRoot":"","sources":["../../../../../../../dev/core/src/FlowGraph/Blocks/Execution/ControlFlow/flowGraphCancelDelayBlock.pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAM7D,OAAO,EAAE,oCAAoC,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAI5E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,yBAA0B,SAAQ,oCAAoC;IAM/E,YAAY,MAAqC;QAC7C,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC;IACrF,CAAC;IAEM,QAAQ,CAAC,OAAyB,EAAE,cAAyC;QAChF,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,IAAI,UAAU,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,eAAe,EAAE,EAAqB,CAAC,CAAC;QACzF,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC;YAC1B,OAAO,CAAC,yBAAyB,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC/D,CAAC;QACD,yFAAyF;QACzF,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACvC,+BAA+B;QAC/B,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAEe,YAAY;QACxB,yEAAuC;IAC3C,CAAC;CACJ;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB;;;GAGG;AACH,MAAM,UAAU,iCAAiC;IAC7C,IAAI,WAAW,EAAE,CAAC;QACd,OAAO;IACX,CAAC;IACD,WAAW,GAAG,IAAI,CAAC;IAEnB,aAAa,oEAAkC,yBAAyB,CAAC,CAAC;AAC9E,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\n\nimport { type AdvancedTimer } from \"../../../../Misc/timer\";\nimport { type IFlowGraphBlockConfiguration } from \"../../../flowGraphBlock\";\nimport { type FlowGraphContext } from \"../../../flowGraphContext\";\nimport { type FlowGraphDataConnection } from \"../../../flowGraphDataConnection.pure\";\nimport { FlowGraphExecutionBlockWithOutSignal } from \"../../../flowGraphExecutionBlockWithOutSignal\";\nimport { RichTypeFlowGraphInteger } from \"../../../flowGraphRichTypes.pure\";\nimport { type FlowGraphSignalConnection } from \"../../../flowGraphSignalConnection.pure\";\nimport { FlowGraphBlockNames } from \"../../flowGraphBlockNames\";\nimport { type FlowGraphInteger } from \"core/FlowGraph/CustomTypes/flowGraphInteger.pure\";\nimport { getNumericValue } from \"core/FlowGraph/utils\";\nimport { MarkDelayInactive } from \"core/FlowGraph/flowGraphDelayRegistry\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\n\n/**\n * This block cancels a delay that was previously scheduled.\n */\nexport class FlowGraphCancelDelayBlock extends FlowGraphExecutionBlockWithOutSignal {\n /**\n * Input connection: The index value of the scheduled activation to be cancelled.\n */\n public readonly delayIndex: FlowGraphDataConnection<FlowGraphInteger>;\n\n constructor(config?: IFlowGraphBlockConfiguration) {\n super(config);\n this.delayIndex = this.registerDataInput(\"delayIndex\", RichTypeFlowGraphInteger);\n }\n\n public _execute(context: FlowGraphContext, _callingSignal: FlowGraphSignalConnection): void {\n const delayIndex = getNumericValue(this.delayIndex.getValue(context));\n if (delayIndex < 0 || isNaN(delayIndex) || !isFinite(delayIndex)) {\n return this._reportError(context, \"Invalid delay index\");\n }\n const timers = context._getGlobalContextVariable(\"pendingDelays\", [] as AdvancedTimer[]);\n const timer = timers[delayIndex];\n if (timer) {\n timer.dispose();\n delete timers[delayIndex];\n context._setGlobalContextVariable(\"pendingDelays\", timers);\n }\n // The delay is cancelled, so drop it from the active set used by handle validity checks.\n MarkDelayInactive(context, delayIndex);\n // activate the out output flow\n this.out._activateSignal(context);\n }\n\n public override getClassName(): string {\n return FlowGraphBlockNames.CancelDelay;\n }\n}\n\nlet _Registered = false;\n/**\n * Register side effects for flowGraphCancelDelayBlock.\n * Safe to call multiple times; only the first call has an effect.\n */\nexport function RegisterFlowGraphCancelDelayBlock(): void {\n if (_Registered) {\n return;\n }\n _Registered = true;\n\n RegisterClass(FlowGraphBlockNames.CancelDelay, FlowGraphCancelDelayBlock);\n}\n"]}
@@ -21,14 +21,23 @@ export interface IFlowGraphForLoopBlockConfiguration extends IFlowGraphBlockConf
21
21
  * This is the default behavior in glTF interactivity
22
22
  */
23
23
  incrementIndexWhenLoopDone?: boolean;
24
+ /**
25
+ * Overrides {@link FlowGraphForLoopBlock.MaxLoopIterations} for this block only.
26
+ * Lets a single graph opt into a higher (or lower) runaway-loop guard without changing the
27
+ * process-wide default that every other FlowGraph relies on.
28
+ */
29
+ maxLoopIterations?: number;
24
30
  }
25
31
  /**
26
32
  * Block that executes an action in a loop.
27
33
  */
28
34
  export declare class FlowGraphForLoopBlock extends FlowGraphExecutionBlockWithOutSignal {
29
35
  /**
30
- * The maximum number of iterations allowed for the loop.
31
- * If the loop exceeds this number, it will stop. This number is configurable to avoid infinite loops.
36
+ * The default maximum number of iterations allowed for the loop, used as a safety net against
37
+ * runaway loops. Kept conservative so a runaway loop is caught before it can freeze the tab.
38
+ * A single graph that legitimately needs more iterations should set the per-block
39
+ * {@link IFlowGraphForLoopBlockConfiguration.maxLoopIterations} rather than raising this
40
+ * process-wide default that every other FlowGraph relies on.
32
41
  */
33
42
  static MaxLoopIterations: number;
34
43
  /**