1
- import type { IFlowGraphBlockConfiguration } from "core/FlowGraph/flowGraphBlock" ;
1
+ import { FlowGraphBlock , type IFlowGraphBlockConfiguration } from "core/FlowGraph/flowGraphBlock" ;
2
2
import {
3
3
RichTypeVector3 ,
4
4
FlowGraphTypes ,
@@ -8,16 +8,25 @@ import {
8
8
RichTypeMatrix ,
9
9
getRichTypeByFlowGraphType ,
10
10
RichTypeQuaternion ,
11
+ RichTypeBoolean ,
11
12
} from "core/FlowGraph/flowGraphRichTypes" ;
12
13
import { RegisterClass } from "core/Misc/typeStore" ;
13
14
import { FlowGraphBlockNames } from "../../flowGraphBlockNames" ;
14
15
import { FlowGraphBinaryOperationBlock } from "../flowGraphBinaryOperationBlock" ;
15
16
import { FlowGraphUnaryOperationBlock } from "../flowGraphUnaryOperationBlock" ;
16
- import { Vector3 , Vector4 } from "core/Maths/math.vector" ;
17
- import type { Matrix , Quaternion , Vector2 } from "core/Maths/math.vector" ;
17
+ import { Quaternion , Vector3 , Vector4 } from "core/Maths/math.vector" ;
18
+ import type { Matrix , Vector2 } from "core/Maths/math.vector" ;
18
19
import type { FlowGraphMatrix2D , FlowGraphMatrix3D } from "core/FlowGraph/CustomTypes" ;
19
20
import type { FlowGraphMatrix , FlowGraphVector } from "core/FlowGraph/utils" ;
20
21
import { _GetClassNameOf } from "core/FlowGraph/utils" ;
22
+ import type { FlowGraphDataConnection } from "../../../flowGraphDataConnection" ;
23
+ import type { FlowGraphContext } from "../../../flowGraphContext" ;
24
+ import { GetAngleBetweenQuaternions , GetQuaternionFromDirections } from "../../../../Maths/math.vector.functions" ;
25
+ import type { Nullable } from "../../../../types" ;
26
+
27
+ const AxisCacheName = "cachedOperationAxis" ;
28
+ const AngleCacheName = "cachedOperationAngle" ;
29
+ const CacheExecIdName = "cachedExecutionId" ;
21
30
22
31
/**
23
32
* Vector length block.
@@ -200,3 +209,111 @@ export class FlowGraphTransformCoordinatesBlock extends FlowGraphBinaryOperation
200
209
}
201
210
202
211
RegisterClass ( FlowGraphBlockNames . TransformCoordinates , FlowGraphTransformCoordinatesBlock ) ;
212
+
213
+ /**
214
+ * Conjugate the quaternion.
215
+ */
216
+ export class FlowGraphConjugateBlock extends FlowGraphUnaryOperationBlock < Quaternion , Quaternion > {
217
+ constructor ( config ?: IFlowGraphBlockConfiguration ) {
218
+ super ( RichTypeQuaternion , RichTypeQuaternion , ( a ) => a . conjugate ( ) , FlowGraphBlockNames . Conjugate , config ) ;
219
+ }
220
+ }
221
+
222
+ RegisterClass ( FlowGraphBlockNames . Conjugate , FlowGraphConjugateBlock ) ;
223
+
224
+ /**
225
+ * Get the angle between two quaternions.
226
+ */
227
+ export class FlowGraphAngleBetweenBlock extends FlowGraphBinaryOperationBlock < Quaternion , Quaternion , number > {
228
+ constructor ( config ?: IFlowGraphBlockConfiguration ) {
229
+ super ( RichTypeQuaternion , RichTypeQuaternion , RichTypeNumber , ( a , b ) => GetAngleBetweenQuaternions ( a , b ) , FlowGraphBlockNames . AngleBetween , config ) ;
230
+ }
231
+ }
232
+
233
+ RegisterClass ( FlowGraphBlockNames . AngleBetween , FlowGraphAngleBetweenBlock ) ;
234
+
235
+ /**
236
+ * Get the quaternion from an axis and an angle.
237
+ */
238
+ export class FlowGraphQuaternionFromAxisAngleBlock extends FlowGraphBinaryOperationBlock < Vector3 , number , Quaternion > {
239
+ constructor ( config ?: IFlowGraphBlockConfiguration ) {
240
+ super ( RichTypeVector3 , RichTypeNumber , RichTypeQuaternion , ( a , b ) => Quaternion . RotationAxis ( a , b ) , FlowGraphBlockNames . QuaternionFromAxisAngle , config ) ;
241
+ }
242
+ }
243
+
244
+ RegisterClass ( FlowGraphBlockNames . QuaternionFromAxisAngle , FlowGraphQuaternionFromAxisAngleBlock ) ;
245
+
246
+ /**
247
+ * Get the axis and angle from a quaternion.
248
+ */
249
+ export class FlowGraphAxisAngleFromQuaternionBlock extends FlowGraphBlock {
250
+ /**
251
+ * The input of this block.
252
+ */
253
+ public readonly a : FlowGraphDataConnection < Quaternion > ;
254
+
255
+ /**
256
+ * The output axis of rotation.
257
+ */
258
+ public readonly axis : FlowGraphDataConnection < Vector3 > ;
259
+
260
+ /**
261
+ * The output angle of rotation.
262
+ */
263
+ public readonly angle : FlowGraphDataConnection < number > ;
264
+
265
+ /**
266
+ * Output connection: Whether the value is valid.
267
+ */
268
+ public readonly isValid : FlowGraphDataConnection < boolean > ;
269
+
270
+ constructor ( config ?: IFlowGraphBlockConfiguration ) {
271
+ super ( config ) ;
272
+
273
+ this . a = this . registerDataInput ( "a" , RichTypeQuaternion ) ;
274
+
275
+ this . axis = this . registerDataOutput ( "axis" , RichTypeVector3 ) ;
276
+ this . angle = this . registerDataOutput ( "angle" , RichTypeNumber ) ;
277
+
278
+ this . isValid = this . registerDataOutput ( "isValid" , RichTypeBoolean ) ;
279
+ }
280
+
281
+ /** @override */
282
+ public override _updateOutputs ( context : FlowGraphContext ) {
283
+ const cachedExecutionId = context . _getExecutionVariable ( this , CacheExecIdName , - 1 ) ;
284
+ const cachedAxis = context . _getExecutionVariable < Nullable < Vector3 > > ( this , AxisCacheName , null ) ;
285
+ const cachedAngle = context . _getExecutionVariable < Nullable < number > > ( this , AngleCacheName , null ) ;
286
+ if ( cachedAxis !== undefined && cachedAxis !== null && cachedAngle !== undefined && cachedAngle !== null && cachedExecutionId === context . executionId ) {
287
+ this . axis . setValue ( cachedAxis , context ) ;
288
+ this . angle . setValue ( cachedAngle , context ) ;
289
+ } else {
290
+ try {
291
+ const { axis, angle } = this . a . getValue ( context ) . toAxisAngle ( ) ;
292
+ context . _setExecutionVariable ( this , AxisCacheName , axis ) ;
293
+ context . _setExecutionVariable ( this , AngleCacheName , angle ) ;
294
+ context . _setExecutionVariable ( this , CacheExecIdName , context . executionId ) ;
295
+ this . axis . setValue ( axis , context ) ;
296
+ this . angle . setValue ( angle , context ) ;
297
+ this . isValid . setValue ( true , context ) ;
298
+ } catch ( e ) {
299
+ this . isValid . setValue ( false , context ) ;
300
+ }
301
+ }
302
+ }
303
+
304
+ /** @override */
305
+ public override getClassName ( ) : string {
306
+ return FlowGraphBlockNames . AxisAngleFromQuaternion ;
307
+ }
308
+ }
309
+
310
+ RegisterClass ( FlowGraphBlockNames . AxisAngleFromQuaternion , FlowGraphAxisAngleFromQuaternionBlock ) ;
311
+
312
+ /**
313
+ * Get the quaternion from two direction vectors.
314
+ */
315
+ export class FlowGraphQuaternionFromDirectionsBlock extends FlowGraphBinaryOperationBlock < Vector3 , Vector3 , Quaternion > {
316
+ constructor ( config ?: IFlowGraphBlockConfiguration ) {
317
+ super ( RichTypeVector3 , RichTypeVector3 , RichTypeQuaternion , ( a , b ) => GetQuaternionFromDirections ( a , b ) , FlowGraphBlockNames . QuaternionFromDirections , config ) ;
318
+ }
319
+ }
0 commit comments