@@ -25,7 +25,13 @@ import type {
25
25
Triplet ,
26
26
VectorName ,
27
27
} from '@pmndrs/cannon-worker-api' ;
28
- import { NgtAnyRecord , NgtInjectedRef , assertInjectionContext , injectNgtRef } from 'angular-three' ;
28
+ import {
29
+ NgtAnyRecord ,
30
+ NgtInjectedRef ,
31
+ assertInjectionContext ,
32
+ injectNgtRef ,
33
+ queueMicrotaskInInjectionContext ,
34
+ } from 'angular-three' ;
29
35
import { NGTC_PHYSICS_API , NgtcCannonEvents } from 'angular-three-cannon' ;
30
36
import { NGTC_DEBUG_API } from 'angular-three-cannon/debug' ;
31
37
import * as THREE from 'three' ;
@@ -242,72 +248,74 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
242
248
const physicsApi = inject ( NGTC_PHYSICS_API ) ;
243
249
const debugApi = inject ( NGTC_DEBUG_API , { optional : true } ) ;
244
250
245
- const { refs, worker, subscriptions, scaleOverrides, events } = physicsApi ( ) ;
246
251
const { add : debugAdd , remove : debugRemove } = debugApi ?.( ) || { } ;
252
+ const { refs, worker, subscriptions, scaleOverrides, events } = physicsApi ( ) ;
247
253
248
- effect (
249
- ( onCleanup ) => {
250
- // register deps
251
- deps ( ) ;
252
-
253
- if ( ! bodyRef . untracked ) {
254
- bodyRef . nativeElement = new THREE . Object3D ( ) as TObject ;
255
- }
256
-
257
- const object = bodyRef . untracked ;
258
- const currentWorker = worker ;
259
-
260
- const objectCount =
261
- object instanceof THREE . InstancedMesh
262
- ? ( object . instanceMatrix . setUsage ( THREE . DynamicDrawUsage ) , object . count )
263
- : 1 ;
264
-
265
- const uuid =
266
- object instanceof THREE . InstancedMesh
267
- ? new Array ( objectCount ) . fill ( 0 ) . map ( ( _ , i ) => `${ object . uuid } /${ i } ` )
268
- : [ object . uuid ] ;
269
-
270
- const props : ( TBodyProps & { args : unknown } ) [ ] =
271
- object instanceof THREE . InstancedMesh
272
- ? uuid . map ( ( id , i ) => {
273
- const props = getPropsFn ( i ) ;
274
- prepare ( temp , props ) ;
275
- object . setMatrixAt ( i , temp . matrix ) ;
276
- object . instanceMatrix . needsUpdate = true ;
277
- refs [ id ] = object ;
278
- debugAdd ?.( id , props , type ) ;
279
- setupCollision ( events , props , id ) ;
280
- return { ...props , args : argsFn ( props . args ) } ;
281
- } )
282
- : uuid . map ( ( id , i ) => {
283
- const props = getPropsFn ( i ) ;
284
- prepare ( object , props ) ;
285
- refs [ id ] = object ;
286
- debugAdd ?.( id , props , type ) ;
287
- setupCollision ( events , props , id ) ;
288
- return { ...props , args : argsFn ( props . args ) } ;
289
- } ) ;
290
-
291
- // Register on mount, unregister on unmount
292
- currentWorker . addBodies ( {
293
- props : props . map ( ( { onCollide, onCollideBegin, onCollideEnd, ...serializableProps } ) => {
294
- return { onCollide : Boolean ( onCollide ) , ...serializableProps } ;
295
- } ) ,
296
- type,
297
- uuid,
298
- } ) ;
299
-
300
- onCleanup ( ( ) => {
301
- uuid . forEach ( ( id ) => {
302
- delete refs [ id ] ;
303
- debugRemove ?.( id ) ;
304
- delete events [ id ] ;
254
+ queueMicrotaskInInjectionContext ( ( ) => {
255
+ effect (
256
+ ( onCleanup ) => {
257
+ // register deps
258
+ deps ( ) ;
259
+
260
+ if ( ! bodyRef . nativeElement ) {
261
+ bodyRef . nativeElement = new THREE . Object3D ( ) as TObject ;
262
+ }
263
+
264
+ const object = bodyRef . nativeElement ;
265
+ const currentWorker = worker ( ) ;
266
+
267
+ const objectCount =
268
+ object instanceof THREE . InstancedMesh
269
+ ? ( object . instanceMatrix . setUsage ( THREE . DynamicDrawUsage ) , object . count )
270
+ : 1 ;
271
+
272
+ const uuid =
273
+ object instanceof THREE . InstancedMesh
274
+ ? new Array ( objectCount ) . fill ( 0 ) . map ( ( _ , i ) => `${ object . uuid } /${ i } ` )
275
+ : [ object . uuid ] ;
276
+
277
+ const props : ( TBodyProps & { args : unknown } ) [ ] =
278
+ object instanceof THREE . InstancedMesh
279
+ ? uuid . map ( ( id , i ) => {
280
+ const props = getPropsFn ( i ) ;
281
+ prepare ( temp , props ) ;
282
+ object . setMatrixAt ( i , temp . matrix ) ;
283
+ object . instanceMatrix . needsUpdate = true ;
284
+ refs [ id ] = object ;
285
+ debugAdd ?.( id , props , type ) ;
286
+ setupCollision ( events , props , id ) ;
287
+ return { ...props , args : argsFn ( props . args ) } ;
288
+ } )
289
+ : uuid . map ( ( id , i ) => {
290
+ const props = getPropsFn ( i ) ;
291
+ prepare ( object , props ) ;
292
+ refs [ id ] = object ;
293
+ debugAdd ?.( id , props , type ) ;
294
+ setupCollision ( events , props , id ) ;
295
+ return { ...props , args : argsFn ( props . args ) } ;
296
+ } ) ;
297
+
298
+ // Register on mount, unregister on unmount
299
+ currentWorker . addBodies ( {
300
+ props : props . map ( ( { onCollide, onCollideBegin, onCollideEnd, ...serializableProps } ) => {
301
+ return { onCollide : Boolean ( onCollide ) , ...serializableProps } ;
302
+ } ) ,
303
+ type,
304
+ uuid,
305
305
} ) ;
306
- currentWorker . removeBodies ( { uuid } ) ;
307
- } ) ;
308
- } ,
309
- { allowSignalWrites : true }
310
- ) ;
306
+
307
+ onCleanup ( ( ) => {
308
+ uuid . forEach ( ( id ) => {
309
+ delete refs [ id ] ;
310
+ debugRemove ?.( id ) ;
311
+ delete events [ id ] ;
312
+ } ) ;
313
+ currentWorker . removeBodies ( { uuid } ) ;
314
+ } ) ;
315
+ } ,
316
+ { allowSignalWrites : true }
317
+ ) ;
318
+ } ) ;
311
319
312
320
const api = computed ( ( ) => {
313
321
const makeAtomic = < T extends AtomicName > ( type : T , index ?: number ) => {
@@ -317,12 +325,12 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
317
325
set : ( value : PropValue < T > ) => {
318
326
const uuid = getUUID ( bodyRef , index ) ;
319
327
uuid &&
320
- worker [ op ] ( {
328
+ worker ( ) [ op ] ( {
321
329
props : value ,
322
330
uuid,
323
331
} as never ) ;
324
332
} ,
325
- subscribe : subscribe ( bodyRef , worker , subscriptions , type , index ) ,
333
+ subscribe : subscribe ( bodyRef , worker ( ) , subscriptions , type , index ) ,
326
334
} ;
327
335
} ;
328
336
@@ -331,25 +339,25 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
331
339
return {
332
340
copy : ( { w, x, y, z } : THREE . Quaternion ) => {
333
341
const uuid = getUUID ( bodyRef , index ) ;
334
- uuid && worker . setQuaternion ( { props : [ x , y , z , w ] , uuid } ) ;
342
+ uuid && worker ( ) . setQuaternion ( { props : [ x , y , z , w ] , uuid } ) ;
335
343
} ,
336
344
set : ( x : number , y : number , z : number , w : number ) => {
337
345
const uuid = getUUID ( bodyRef , index ) ;
338
- uuid && worker . setQuaternion ( { props : [ x , y , z , w ] , uuid } ) ;
346
+ uuid && worker ( ) . setQuaternion ( { props : [ x , y , z , w ] , uuid } ) ;
339
347
} ,
340
- subscribe : subscribe ( bodyRef , worker , subscriptions , type , index ) ,
348
+ subscribe : subscribe ( bodyRef , worker ( ) , subscriptions , type , index ) ,
341
349
} ;
342
350
} ;
343
351
344
352
const makeRotation = ( index ?: number ) => {
345
353
return {
346
354
copy : ( { x, y, z } : THREE . Vector3 | THREE . Euler ) => {
347
355
const uuid = getUUID ( bodyRef , index ) ;
348
- uuid && worker . setRotation ( { props : [ x , y , z ] , uuid } ) ;
356
+ uuid && worker ( ) . setRotation ( { props : [ x , y , z ] , uuid } ) ;
349
357
} ,
350
358
set : ( x : number , y : number , z : number ) => {
351
359
const uuid = getUUID ( bodyRef , index ) ;
352
- uuid && worker . setRotation ( { props : [ x , y , z ] , uuid } ) ;
360
+ uuid && worker ( ) . setRotation ( { props : [ x , y , z ] , uuid } ) ;
353
361
} ,
354
362
subscribe : ( callback : ( value : Triplet ) => void ) => {
355
363
const id = incrementingId ++ ;
@@ -358,10 +366,10 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
358
366
const uuid = getUUID ( bodyRef , index ) ;
359
367
360
368
subscriptions [ id ] = { [ type ] : quaternionToRotation ( callback ) } ;
361
- uuid && worker . subscribe ( { props : { id, target, type } , uuid } ) ;
369
+ uuid && worker ( ) . subscribe ( { props : { id, target, type } , uuid } ) ;
362
370
return ( ) => {
363
371
delete subscriptions [ id ] ;
364
- worker . unsubscribe ( { props : id } ) ;
372
+ worker ( ) . unsubscribe ( { props : id } ) ;
365
373
} ;
366
374
} ,
367
375
} ;
@@ -372,20 +380,20 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
372
380
return {
373
381
copy : ( { x, y, z } : THREE . Vector3 | THREE . Euler ) => {
374
382
const uuid = getUUID ( bodyRef , index ) ;
375
- uuid && worker [ op ] ( { props : [ x , y , z ] , uuid } ) ;
383
+ uuid && worker ( ) [ op ] ( { props : [ x , y , z ] , uuid } ) ;
376
384
} ,
377
385
set : ( x : number , y : number , z : number ) => {
378
386
const uuid = getUUID ( bodyRef , index ) ;
379
- uuid && worker [ op ] ( { props : [ x , y , z ] , uuid } ) ;
387
+ uuid && worker ( ) [ op ] ( { props : [ x , y , z ] , uuid } ) ;
380
388
} ,
381
- subscribe : subscribe ( bodyRef , worker , subscriptions , type , index ) ,
389
+ subscribe : subscribe ( bodyRef , worker ( ) , subscriptions , type , index ) ,
382
390
} ;
383
391
} ;
384
392
385
393
const makeRemove = ( index ?: number ) => {
386
394
const uuid = getUUID ( bodyRef , index ) ;
387
395
return ( ) => {
388
- if ( uuid ) worker . removeBodies ( { uuid : [ uuid ] } ) ;
396
+ if ( uuid ) worker ( ) . removeBodies ( { uuid : [ uuid ] } ) ;
389
397
} ;
390
398
} ;
391
399
@@ -397,23 +405,23 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
397
405
angularVelocity : makeVec ( 'angularVelocity' , index ) ,
398
406
applyForce ( force : Triplet , worldPoint : Triplet ) {
399
407
const uuid = getUUID ( bodyRef , index ) ;
400
- uuid && worker . applyForce ( { props : [ force , worldPoint ] , uuid } ) ;
408
+ uuid && worker ( ) . applyForce ( { props : [ force , worldPoint ] , uuid } ) ;
401
409
} ,
402
410
applyImpulse ( impulse : Triplet , worldPoint : Triplet ) {
403
411
const uuid = getUUID ( bodyRef , index ) ;
404
- uuid && worker . applyImpulse ( { props : [ impulse , worldPoint ] , uuid } ) ;
412
+ uuid && worker ( ) . applyImpulse ( { props : [ impulse , worldPoint ] , uuid } ) ;
405
413
} ,
406
414
applyLocalForce ( force : Triplet , localPoint : Triplet ) {
407
415
const uuid = getUUID ( bodyRef , index ) ;
408
- uuid && worker . applyLocalForce ( { props : [ force , localPoint ] , uuid } ) ;
416
+ uuid && worker ( ) . applyLocalForce ( { props : [ force , localPoint ] , uuid } ) ;
409
417
} ,
410
418
applyLocalImpulse ( impulse : Triplet , localPoint : Triplet ) {
411
419
const uuid = getUUID ( bodyRef , index ) ;
412
- uuid && worker . applyLocalImpulse ( { props : [ impulse , localPoint ] , uuid } ) ;
420
+ uuid && worker ( ) . applyLocalImpulse ( { props : [ impulse , localPoint ] , uuid } ) ;
413
421
} ,
414
422
applyTorque ( torque : Triplet ) {
415
423
const uuid = getUUID ( bodyRef , index ) ;
416
- uuid && worker . applyTorque ( { props : [ torque ] , uuid } ) ;
424
+ uuid && worker ( ) . applyTorque ( { props : [ torque ] , uuid } ) ;
417
425
} ,
418
426
collisionFilterGroup : makeAtomic ( 'collisionFilterGroup' , index ) ,
419
427
collisionFilterMask : makeAtomic ( 'collisionFilterMask' , index ) ,
@@ -433,7 +441,7 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
433
441
} ,
434
442
sleep ( ) {
435
443
const uuid = getUUID ( bodyRef , index ) ;
436
- uuid && worker . sleep ( { uuid } ) ;
444
+ uuid && worker ( ) . sleep ( { uuid } ) ;
437
445
} ,
438
446
sleepSpeedLimit : makeAtomic ( 'sleepSpeedLimit' , index ) ,
439
447
sleepTimeLimit : makeAtomic ( 'sleepTimeLimit' , index ) ,
@@ -442,7 +450,7 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
442
450
remove : makeRemove ( index ) ,
443
451
wakeUp ( ) {
444
452
const uuid = getUUID ( bodyRef , index ) ;
445
- uuid && worker . wakeUp ( { uuid } ) ;
453
+ uuid && worker ( ) . wakeUp ( { uuid } ) ;
446
454
} ,
447
455
} ;
448
456
}
0 commit comments