@@ -26,13 +26,11 @@ export class BallShooter extends xb.Script {
2626 this . spheres . push ( sphere ) ;
2727 }
2828
29- const matrix = new THREE . Matrix4 ( ) ;
3029 for ( let i = 0 ; i < this . spheres . length ; i ++ ) {
3130 const x = Math . random ( ) * 2 - 2 ;
3231 const y = Math . random ( ) * 2 ;
3332 const z = Math . random ( ) * 2 - 2 ;
3433
35- matrix . setPosition ( x , y , z ) ;
3634 this . spheres [ i ] . position . set ( x , y , z ) ;
3735 if ( palette != null ) {
3836 this . spheres [ i ] . material . color . copy ( palette . getRandomLiteGColor ( ) ) ;
@@ -69,20 +67,10 @@ export class BallShooter extends xb.Script {
6967 colliderActiveEvents = 0 ,
7068 continuousCollisionDetection = false ,
7169 } ) {
72- for ( let i = 0 ; i < this . spheres . length ; ++ i ) {
73- const position = this . spheres [ i ] . position ;
74- const desc = RAPIER . RigidBodyDesc . dynamic ( )
75- . setTranslation ( ...position )
76- . setCcdEnabled ( continuousCollisionDetection ) ;
77- const body = blendedWorld . createRigidBody ( desc ) ;
78- const shape = RAPIER . ColliderDesc . ball (
79- this . spheres [ i ] . geometry . parameters . radius
80- ) . setActiveEvents ( colliderActiveEvents ) ;
81- const collider = blendedWorld . createCollider ( shape , body ) ;
82- this . colliderHandleToIndex . set ( collider . handle , i ) ;
83- this . rigidBodies . push ( body ) ;
84- this . colliders . push ( collider ) ;
85- }
70+ this . RAPIER = RAPIER ;
71+ this . blendedWorld = blendedWorld ;
72+ this . colliderActiveEvents = colliderActiveEvents ;
73+ this . continuousCollisionDetection = continuousCollisionDetection ;
8674 }
8775
8876 /**
@@ -100,23 +88,46 @@ export class BallShooter extends xb.Script {
10088 ball . position . copy ( position ) ;
10189 ball . scale . setScalar ( 1.0 ) ;
10290 ball . opacity = 1.0 ;
103- if ( this . rigidBodies . length > 0 ) {
104- const body = this . rigidBodies [ this . nextBall ] ;
105- body . setTranslation ( position ) ;
106- body . setLinvel ( velocity ) ;
107- }
91+ this . _createRigidBody (
92+ this . nextBall ,
93+ position ,
94+ velocity ,
95+ ball . geometry . parameters . radius
96+ ) ;
10897 this . spawnTimes [ this . nextBall ] = now ;
10998 this . nextBall = ( this . nextBall + 1 ) % this . spheres . length ;
11099 this . add ( ball ) ;
111100 }
112101
102+ _createRigidBody ( index , position , velocity , radius ) {
103+ // Delete existing body if one already exists for this index
104+ if ( this . rigidBodies [ index ] != null ) {
105+ const existingBody = this . rigidBodies [ index ] ;
106+ this . blendedWorld . removeRigidBody ( existingBody ) ;
107+ }
108+
109+ // Create new body
110+ const desc = this . RAPIER . RigidBodyDesc . dynamic ( )
111+ . setTranslation ( position . x , position . y , position . z )
112+ . setLinvel ( velocity . x , velocity . y , velocity . z )
113+ . setCcdEnabled ( this . continuousCollisionDetection ) ;
114+ const body = this . blendedWorld . createRigidBody ( desc ) ;
115+ const shape = this . RAPIER . ColliderDesc . ball ( radius ) . setActiveEvents (
116+ this . colliderActiveEvents
117+ ) ;
118+ const collider = this . blendedWorld . createCollider ( shape , body ) ;
119+ this . colliderHandleToIndex . set ( collider . handle , index ) ;
120+ this . rigidBodies [ index ] = body ;
121+ this . colliders [ index ] = collider ;
122+ }
123+
113124 physicsStep ( now = performance . now ( ) ) {
114125 for ( let i = 0 ; i < this . spheres . length ; i ++ ) {
115126 const sphere = this . spheres [ i ] ;
116127 const body = this . rigidBodies [ i ] ;
117128 let spawnTime = this . spawnTimes [ i ] ;
118129
119- if ( this . isBallActive ( i ) ) {
130+ if ( this . isBallActive ( i ) && body != null ) {
120131 let ballVisibility = 1.0 ;
121132 const position = sphere . position . copy ( body . translation ( ) ) ;
122133 // If the ball falls behind the depth then adjust the spawnTime to begin
@@ -165,20 +176,15 @@ export class BallShooter extends xb.Script {
165176 ballVisibility = 1.0 - deflateAmount ;
166177 }
167178
168- body . setTranslation ( position ) ;
169179 sphere . material . opacity = ballVisibility ;
170180
171181 if ( ballVisibility < 0.001 ) {
172- sphere . material . opacity = 0.0 ;
173- sphere . scale . setScalar ( 0 ) ;
174- position . set ( 0.0 , - 1000.0 , 0.0 ) ;
175- body . setTranslation ( position ) ;
176182 this . removeBall ( i ) ;
183+ } else {
184+ sphere . position . copy ( body . translation ( ) ) ;
185+ sphere . quaternion . copy ( body . rotation ( ) ) ;
177186 }
178187 }
179-
180- sphere . position . copy ( body . translation ( ) ) ;
181- sphere . quaternion . copy ( body . rotation ( ) ) ;
182188 }
183189 }
184190
@@ -188,9 +194,14 @@ export class BallShooter extends xb.Script {
188194
189195 removeBall ( index ) {
190196 const ball = this . spheres [ index ] ;
197+ ball . material . opacity = 0.0 ;
198+ ball . scale . setScalar ( 0 ) ;
191199 const body = this . rigidBodies [ index ] ;
192- ball . position . set ( 0.0 , - 1000.0 , 0.0 ) ;
193- body . setTranslation ( ball . position ) ;
200+ if ( body != null ) {
201+ this . blendedWorld . removeRigidBody ( body ) ;
202+ this . rigidBodies [ index ] = null ;
203+ this . colliders [ index ] = null ;
204+ }
194205 this . remove ( ball ) ;
195206 }
196207
0 commit comments