@@ -5,124 +5,124 @@ import ParticleRigidBody from './ParticleRigidBody';
5
5
import { BallCollider } from '@react-three/rapier' ;
6
6
import _ from 'lodash' ;
7
7
import { getColor } from './utils.js' ;
8
-
9
- // The Particle uses ParticleRigidBody which extends RigidBody to allow for impulses to be accumulated before being applied
10
- const Particle = React . memo ( React . forwardRef ( ( { id, index, indexArray, scope, initialPosition, radius, config, ...props } , ref ) => {
11
-
8
+
9
+ // The Particle uses ParticleRigidBody which extends RigidBody to allow for impulses to be accumulated before being applied
10
+ const Particle = React . memo ( React . forwardRef ( ( { id, index, indexArray, scope, initialPosition, radius, config, ...props } , ref ) => {
11
+
12
12
const internalRef = useRef ( ) ; // because we forwardRef and want to use the ref locally too
13
13
useImperativeHandle ( ref , ( ) => internalRef . current ) ;
14
-
14
+
15
15
const isDebug = props . debug || config . debug ;
16
16
const color = useMemo ( ( ) => getColor ( config , scope , props . color || "blue" ) ) ;
17
17
const [ colliderRadius , setColliderRadius ] = useState ( radius ) ;
18
18
const registeredRef = useRef ( false ) ;
19
19
const [ initialize , setInitialize ] = useState ( true ) ;
20
-
20
+
21
21
// Calculate the unique global index for the Particle
22
22
const calculateUniqueIndex = ( indexArray , entityCounts ) => {
23
- let multiplier = 1 ;
24
- let uniqueIndex = 0 ;
25
- for ( let i = indexArray . length - 1 ; i >= 0 ; i -- ) {
26
- uniqueIndex += indexArray [ i ] * multiplier ;
27
- multiplier *= entityCounts [ i ] ;
28
- }
29
- return uniqueIndex ;
23
+ let multiplier = 1 ;
24
+ let uniqueIndex = 0 ;
25
+ for ( let i = indexArray . length - 1 ; i >= 0 ; i -- ) {
26
+ uniqueIndex += indexArray [ i ] * multiplier ;
27
+ multiplier *= entityCounts [ i ] ;
28
+ }
29
+ return uniqueIndex ;
30
30
} ;
31
-
31
+
32
32
// With adding/removing Particles this may not be unique - use a singleton to get a unique id
33
33
const uniqueIndex = useMemo ( ( ) => calculateUniqueIndex ( indexArray , config . entityCounts ) , [ indexArray , config . entityCounts ] ) ;
34
-
34
+
35
35
// When scaling a Particle we need to modify the joint positions
36
36
useFrame ( ( ) => {
37
- if ( internalRef . current ) {
38
- if ( internalRef . current . applyImpulses ) {
39
- internalRef . current . applyImpulses ( ) ;
40
- }
41
- //
42
- const userData = internalRef . current . getUserData ( ) ;
43
- // Could adjust scale over multiple frames
44
- if ( userData ?. scale !== userData ?. rigidScale ) {
45
- let relativeScale = userData . scale ;
46
- if ( userData . rigidScale ) {
47
- relativeScale = userData . scale / userData . rigidScale ;
48
- }
49
- const newRadius = relativeScale * colliderRadius
50
- setColliderRadius ( newRadius ) ;
51
- internalRef . current . setUserData ( userData )
52
- props . particleJointsRef . current [ uniqueIndex ] . forEach ( ( jointIndex ) => {
53
- const joint = props . jointRefsRef . current [ jointIndex ] . current ;
54
- if ( joint . body1 ( ) . userData . uniqueIndex == uniqueIndex ) {
55
- const a1 = joint . anchor1 ( ) ;
56
- joint . setAnchor1 ( {
57
- x : a1 . x * relativeScale ,
58
- y : a1 . y * relativeScale ,
59
- z : a1 . z * relativeScale ,
60
- } )
37
+ if ( internalRef . current ) {
38
+ if ( internalRef . current . applyImpulses ) {
39
+ internalRef . current . applyImpulses ( ) ;
61
40
}
62
- if ( joint . body2 ( ) . userData . uniqueIndex == uniqueIndex ) {
63
- const a2 = joint . anchor2 ( ) ;
64
- joint . setAnchor2 ( {
65
- x : a2 . x * relativeScale ,
66
- y : a2 . y * relativeScale ,
67
- z : a2 . z * relativeScale ,
68
- } )
41
+ //
42
+ const userData = internalRef . current . getUserData ( ) ;
43
+ // Could adjust scale over multiple frames
44
+ if ( userData ?. scale !== userData ?. rigidScale ) {
45
+ let relativeScale = userData . scale ;
46
+ if ( userData . rigidScale ) {
47
+ relativeScale = userData . scale / userData . rigidScale ;
48
+ }
49
+ const newRadius = relativeScale * colliderRadius
50
+ setColliderRadius ( newRadius ) ;
51
+ internalRef . current . setUserData ( userData )
52
+ props . particleJointsRef . current [ uniqueIndex ] . forEach ( ( jointIndex ) => {
53
+ const joint = props . jointRefsRef . current [ jointIndex ] . current ;
54
+ if ( joint . body1 ( ) . userData . uniqueIndex == uniqueIndex ) {
55
+ const a1 = joint . anchor1 ( ) ;
56
+ joint . setAnchor1 ( {
57
+ x : a1 . x * relativeScale ,
58
+ y : a1 . y * relativeScale ,
59
+ z : a1 . z * relativeScale ,
60
+ } )
61
+ }
62
+ if ( joint . body2 ( ) . userData . uniqueIndex == uniqueIndex ) {
63
+ const a2 = joint . anchor2 ( ) ;
64
+ joint . setAnchor2 ( {
65
+ x : a2 . x * relativeScale ,
66
+ y : a2 . y * relativeScale ,
67
+ z : a2 . z * relativeScale ,
68
+ } )
69
+ }
70
+ } )
71
+ userData . rigidScale = userData . scale ;
72
+ internalRef . current . setUserData ( userData ) ;
69
73
}
70
- } )
71
- userData . rigidScale = userData . scale ;
72
- internalRef . current . setUserData ( userData ) ;
73
74
}
74
- }
75
75
} ) ;
76
-
76
+
77
77
useEffect ( ( ) => {
78
- // Don't need registeredRef as sensitive to internalRef
79
- if ( props . registerParticlesFn && internalRef . current && ! registeredRef . current ) {
80
- props . registerParticlesFn ( index , [ internalRef . current ] , radius ) ;
81
- registeredRef . current = true ;
82
- }
78
+ // Don't need registeredRef as sensitive to internalRef
79
+ if ( props . registerParticlesFn && internalRef . current && ! registeredRef . current ) {
80
+ props . registerParticlesFn ( index , [ internalRef . current ] , radius ) ;
81
+ registeredRef . current = true ;
82
+ }
83
83
} , [ props . registerParticlesFn , internalRef ] ) ;
84
-
84
+
85
85
// Set the initial userData, don't do this in JSX (it would overwrite on renders)
86
86
useEffect ( ( ) => {
87
- if ( initialize && internalRef . current ) {
88
- internalRef . current . setUserData ( { color : color , uniqueIndex : uniqueIndex } ) ;
89
- setInitialize ( false ) ;
90
- }
87
+ if ( initialize && internalRef . current ) {
88
+ internalRef . current . setUserData ( { color : color , uniqueIndex : uniqueIndex } ) ;
89
+ setInitialize ( false ) ;
90
+ }
91
91
} , [ internalRef ] ) ;
92
-
92
+
93
93
return (
94
- < >
95
- < ParticleRigidBody
96
- ref = { internalRef }
97
- position = { initialPosition }
98
- type = "dynamic"
99
- colliders = { false }
100
- linearDamping = { 0.5 }
101
- angularDamping = { 0.5 }
102
- enabledTranslations = { [ true , true , false ] }
103
- enabledRotations = { [ false , false , true ] }
104
- restitution = { config . particleRestitution }
105
- ccd = { config . ccd }
106
- >
107
- < BallCollider args = { [ colliderRadius ] } />
108
- </ ParticleRigidBody >
109
- { isDebug && (
110
94
< >
111
- < Text
112
- position = { [ initialPosition [ 0 ] , initialPosition [ 1 ] , 0.1 ] } // Slightly offset in the z-axis to avoid z-fighting
113
- fontSize = { radius / 2 }
114
- color = "black"
115
- anchorX = "center"
116
- anchorY = "middle"
117
- >
118
- { uniqueIndex }
119
- </ Text >
95
+ < ParticleRigidBody
96
+ ref = { internalRef }
97
+ position = { initialPosition }
98
+ type = "dynamic"
99
+ colliders = { false }
100
+ linearDamping = { 0.5 }
101
+ angularDamping = { 0.5 }
102
+ enabledTranslations = { [ true , true , false ] }
103
+ enabledRotations = { [ false , false , true ] }
104
+ restitution = { config . particleRestitution }
105
+ ccd = { config . ccd }
106
+ >
107
+ < BallCollider args = { [ colliderRadius ] } />
108
+ </ ParticleRigidBody >
109
+ { isDebug && (
110
+ < >
111
+ < Text
112
+ position = { [ initialPosition [ 0 ] , initialPosition [ 1 ] , 0.1 ] } // Slightly offset in the z-axis to avoid z-fighting
113
+ fontSize = { radius / 2 }
114
+ color = "black"
115
+ anchorX = "center"
116
+ anchorY = "middle"
117
+ >
118
+ { uniqueIndex }
119
+ </ Text >
120
+ </ >
121
+ ) }
120
122
</ >
121
- ) }
122
- </ >
123
123
) ;
124
- } ) ) ;
125
-
126
- Particle . displayName = 'Particle' ; // the name property doesn't exist because it uses forwardRef
124
+ } ) ) ;
125
+
126
+ Particle . displayName = 'Particle' ; // the name property doesn't exist because it uses forwardRef
127
127
128
- export default Particle ;
128
+ export default Particle ;
0 commit comments