@@ -25,7 +25,13 @@ import type {
2525 Triplet ,
2626 VectorName ,
2727} 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' ;
2935import { NGTC_PHYSICS_API , NgtcCannonEvents } from 'angular-three-cannon' ;
3036import { NGTC_DEBUG_API } from 'angular-three-cannon/debug' ;
3137import * as THREE from 'three' ;
@@ -242,72 +248,74 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
242248 const physicsApi = inject ( NGTC_PHYSICS_API ) ;
243249 const debugApi = inject ( NGTC_DEBUG_API , { optional : true } ) ;
244250
245- const { refs, worker, subscriptions, scaleOverrides, events } = physicsApi ( ) ;
246251 const { add : debugAdd , remove : debugRemove } = debugApi ?.( ) || { } ;
252+ const { refs, worker, subscriptions, scaleOverrides, events } = physicsApi ( ) ;
247253
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,
305305 } ) ;
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+ } ) ;
311319
312320 const api = computed ( ( ) => {
313321 const makeAtomic = < T extends AtomicName > ( type : T , index ?: number ) => {
@@ -317,12 +325,12 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
317325 set : ( value : PropValue < T > ) => {
318326 const uuid = getUUID ( bodyRef , index ) ;
319327 uuid &&
320- worker [ op ] ( {
328+ worker ( ) [ op ] ( {
321329 props : value ,
322330 uuid,
323331 } as never ) ;
324332 } ,
325- subscribe : subscribe ( bodyRef , worker , subscriptions , type , index ) ,
333+ subscribe : subscribe ( bodyRef , worker ( ) , subscriptions , type , index ) ,
326334 } ;
327335 } ;
328336
@@ -331,25 +339,25 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
331339 return {
332340 copy : ( { w, x, y, z } : THREE . Quaternion ) => {
333341 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 } ) ;
335343 } ,
336344 set : ( x : number , y : number , z : number , w : number ) => {
337345 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 } ) ;
339347 } ,
340- subscribe : subscribe ( bodyRef , worker , subscriptions , type , index ) ,
348+ subscribe : subscribe ( bodyRef , worker ( ) , subscriptions , type , index ) ,
341349 } ;
342350 } ;
343351
344352 const makeRotation = ( index ?: number ) => {
345353 return {
346354 copy : ( { x, y, z } : THREE . Vector3 | THREE . Euler ) => {
347355 const uuid = getUUID ( bodyRef , index ) ;
348- uuid && worker . setRotation ( { props : [ x , y , z ] , uuid } ) ;
356+ uuid && worker ( ) . setRotation ( { props : [ x , y , z ] , uuid } ) ;
349357 } ,
350358 set : ( x : number , y : number , z : number ) => {
351359 const uuid = getUUID ( bodyRef , index ) ;
352- uuid && worker . setRotation ( { props : [ x , y , z ] , uuid } ) ;
360+ uuid && worker ( ) . setRotation ( { props : [ x , y , z ] , uuid } ) ;
353361 } ,
354362 subscribe : ( callback : ( value : Triplet ) => void ) => {
355363 const id = incrementingId ++ ;
@@ -358,10 +366,10 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
358366 const uuid = getUUID ( bodyRef , index ) ;
359367
360368 subscriptions [ id ] = { [ type ] : quaternionToRotation ( callback ) } ;
361- uuid && worker . subscribe ( { props : { id, target, type } , uuid } ) ;
369+ uuid && worker ( ) . subscribe ( { props : { id, target, type } , uuid } ) ;
362370 return ( ) => {
363371 delete subscriptions [ id ] ;
364- worker . unsubscribe ( { props : id } ) ;
372+ worker ( ) . unsubscribe ( { props : id } ) ;
365373 } ;
366374 } ,
367375 } ;
@@ -372,20 +380,20 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
372380 return {
373381 copy : ( { x, y, z } : THREE . Vector3 | THREE . Euler ) => {
374382 const uuid = getUUID ( bodyRef , index ) ;
375- uuid && worker [ op ] ( { props : [ x , y , z ] , uuid } ) ;
383+ uuid && worker ( ) [ op ] ( { props : [ x , y , z ] , uuid } ) ;
376384 } ,
377385 set : ( x : number , y : number , z : number ) => {
378386 const uuid = getUUID ( bodyRef , index ) ;
379- uuid && worker [ op ] ( { props : [ x , y , z ] , uuid } ) ;
387+ uuid && worker ( ) [ op ] ( { props : [ x , y , z ] , uuid } ) ;
380388 } ,
381- subscribe : subscribe ( bodyRef , worker , subscriptions , type , index ) ,
389+ subscribe : subscribe ( bodyRef , worker ( ) , subscriptions , type , index ) ,
382390 } ;
383391 } ;
384392
385393 const makeRemove = ( index ?: number ) => {
386394 const uuid = getUUID ( bodyRef , index ) ;
387395 return ( ) => {
388- if ( uuid ) worker . removeBodies ( { uuid : [ uuid ] } ) ;
396+ if ( uuid ) worker ( ) . removeBodies ( { uuid : [ uuid ] } ) ;
389397 } ;
390398 } ;
391399
@@ -397,23 +405,23 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
397405 angularVelocity : makeVec ( 'angularVelocity' , index ) ,
398406 applyForce ( force : Triplet , worldPoint : Triplet ) {
399407 const uuid = getUUID ( bodyRef , index ) ;
400- uuid && worker . applyForce ( { props : [ force , worldPoint ] , uuid } ) ;
408+ uuid && worker ( ) . applyForce ( { props : [ force , worldPoint ] , uuid } ) ;
401409 } ,
402410 applyImpulse ( impulse : Triplet , worldPoint : Triplet ) {
403411 const uuid = getUUID ( bodyRef , index ) ;
404- uuid && worker . applyImpulse ( { props : [ impulse , worldPoint ] , uuid } ) ;
412+ uuid && worker ( ) . applyImpulse ( { props : [ impulse , worldPoint ] , uuid } ) ;
405413 } ,
406414 applyLocalForce ( force : Triplet , localPoint : Triplet ) {
407415 const uuid = getUUID ( bodyRef , index ) ;
408- uuid && worker . applyLocalForce ( { props : [ force , localPoint ] , uuid } ) ;
416+ uuid && worker ( ) . applyLocalForce ( { props : [ force , localPoint ] , uuid } ) ;
409417 } ,
410418 applyLocalImpulse ( impulse : Triplet , localPoint : Triplet ) {
411419 const uuid = getUUID ( bodyRef , index ) ;
412- uuid && worker . applyLocalImpulse ( { props : [ impulse , localPoint ] , uuid } ) ;
420+ uuid && worker ( ) . applyLocalImpulse ( { props : [ impulse , localPoint ] , uuid } ) ;
413421 } ,
414422 applyTorque ( torque : Triplet ) {
415423 const uuid = getUUID ( bodyRef , index ) ;
416- uuid && worker . applyTorque ( { props : [ torque ] , uuid } ) ;
424+ uuid && worker ( ) . applyTorque ( { props : [ torque ] , uuid } ) ;
417425 } ,
418426 collisionFilterGroup : makeAtomic ( 'collisionFilterGroup' , index ) ,
419427 collisionFilterMask : makeAtomic ( 'collisionFilterMask' , index ) ,
@@ -433,7 +441,7 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
433441 } ,
434442 sleep ( ) {
435443 const uuid = getUUID ( bodyRef , index ) ;
436- uuid && worker . sleep ( { uuid } ) ;
444+ uuid && worker ( ) . sleep ( { uuid } ) ;
437445 } ,
438446 sleepSpeedLimit : makeAtomic ( 'sleepSpeedLimit' , index ) ,
439447 sleepTimeLimit : makeAtomic ( 'sleepTimeLimit' , index ) ,
@@ -442,7 +450,7 @@ function injectBody<TBodyProps extends BodyProps, TObject extends THREE.Object3D
442450 remove : makeRemove ( index ) ,
443451 wakeUp ( ) {
444452 const uuid = getUUID ( bodyRef , index ) ;
445- uuid && worker . wakeUp ( { uuid } ) ;
453+ uuid && worker ( ) . wakeUp ( { uuid } ) ;
446454 } ,
447455 } ;
448456 }
0 commit comments