@@ -9,18 +9,17 @@ const { none, bounce, merge } = collisionBehaviors;
99
1010// tiebreaker function for merges and bounces
1111const isSmaller = tgpu . fn ( [ d . u32 , d . u32 ] , d . bool ) ( ( currentId , otherId ) => {
12- if (
13- computeLayout . $ . inState [ currentId ] . mass <
14- computeLayout . $ . inState [ otherId ] . mass
15- ) {
12+ const current = computeLayout . $ . inState [ currentId ] ;
13+ const other = computeLayout . $ . inState [ otherId ] ;
14+
15+ if ( current . mass < other . mass ) {
1616 return true ;
1717 }
18- if (
19- computeLayout . $ . inState [ currentId ] . mass ===
20- computeLayout . $ . inState [ otherId ] . mass
21- ) {
18+
19+ if ( current . mass === other . mass ) {
2220 return currentId < otherId ;
2321 }
22+
2423 return false ;
2524} ) ;
2625
@@ -29,35 +28,18 @@ export const computeCollisionsShader = tgpu['~unstable'].computeFn({
2928 workgroupSize : [ 1 ] ,
3029} ) ( ( input ) => {
3130 const currentId = input . gid . x ;
32- // TODO: replace it with struct copy when Chromium is fixed
33- const current = CelestialBody ( {
34- position : computeLayout . $ . inState [ currentId ] . position ,
35- velocity : computeLayout . $ . inState [ currentId ] . velocity ,
36- mass : computeLayout . $ . inState [ currentId ] . mass ,
37- collisionBehavior : computeLayout . $ . inState [ currentId ] . collisionBehavior ,
38- textureIndex : computeLayout . $ . inState [ currentId ] . textureIndex ,
39- radiusMultiplier : computeLayout . $ . inState [ currentId ] . radiusMultiplier ,
40- ambientLightFactor : computeLayout . $ . inState [ currentId ] . ambientLightFactor ,
41- destroyed : computeLayout . $ . inState [ currentId ] . destroyed ,
42- } ) ;
31+ const current = CelestialBody ( computeLayout . $ . inState [ currentId ] ) ;
4332
4433 if ( current . destroyed === 0 ) {
45- for ( let i = 0 ; i < computeLayout . $ . celestialBodiesCount ; i ++ ) {
46- const otherId = d . u32 ( i ) ;
47- // TODO: replace it with struct copy when Chromium is fixed
48- const other = CelestialBody ( {
49- position : computeLayout . $ . inState [ otherId ] . position ,
50- velocity : computeLayout . $ . inState [ otherId ] . velocity ,
51- mass : computeLayout . $ . inState [ otherId ] . mass ,
52- collisionBehavior : computeLayout . $ . inState [ otherId ] . collisionBehavior ,
53- textureIndex : computeLayout . $ . inState [ otherId ] . textureIndex ,
54- radiusMultiplier : computeLayout . $ . inState [ otherId ] . radiusMultiplier ,
55- ambientLightFactor : computeLayout . $ . inState [ otherId ] . ambientLightFactor ,
56- destroyed : computeLayout . $ . inState [ otherId ] . destroyed ,
57- } ) ;
34+ for (
35+ let otherId = d . u32 ( 0 ) ;
36+ otherId < d . u32 ( computeLayout . $ . celestialBodiesCount ) ;
37+ otherId ++
38+ ) {
39+ const other = computeLayout . $ . inState [ otherId ] ;
5840 // no collision occurs...
5941 if (
60- d . u32 ( i ) === input . gid . x || // ...with itself
42+ otherId === currentId || // ...with itself
6143 other . destroyed === 1 || // ...when other is destroyed
6244 current . collisionBehavior === none || // ...when current behavior is none
6345 other . collisionBehavior === none || // ...when other behavior is none
@@ -75,30 +57,20 @@ export const computeCollisionsShader = tgpu['~unstable'].computeFn({
7557 // bounce occurs
7658 // push the smaller object outside
7759 if ( isSmaller ( currentId , otherId ) ) {
78- current . position = std . add (
79- other . position ,
80- std . mul (
81- radiusOf ( current ) + radiusOf ( other ) ,
82- std . normalize ( std . sub ( current . position , other . position ) ) ,
83- ) ,
84- ) ;
60+ const dir = std . normalize ( current . position . sub ( other . position ) ) ;
61+ current . position = other . position
62+ . add ( dir . mul ( radiusOf ( current ) + radiusOf ( other ) ) ) ;
8563 }
64+
8665 // bounce with tiny damping
87- current . velocity = std . mul (
88- 0.99 ,
89- std . sub (
90- current . velocity ,
91- std . mul (
92- ( ( ( 2 * other . mass ) / ( current . mass + other . mass ) ) *
93- std . dot (
94- std . sub ( current . velocity , other . velocity ) ,
95- std . sub ( current . position , other . position ) ,
96- ) ) /
97- std . pow ( std . distance ( current . position , other . position ) , 2 ) ,
98- std . sub ( current . position , other . position ) ,
99- ) ,
100- ) ,
101- ) ;
66+ const posDiff = current . position . sub ( other . position ) ;
67+ const velDiff = current . velocity . sub ( other . velocity ) ;
68+ const posDiffFactor =
69+ ( ( ( 2 * other . mass ) / ( current . mass + other . mass ) ) *
70+ std . dot ( velDiff , posDiff ) ) / std . dot ( posDiff , posDiff ) ;
71+
72+ current . velocity = current . velocity
73+ . sub ( posDiff . mul ( posDiffFactor ) ) . mul ( 0.99 ) ;
10274 } else {
10375 // merge occurs
10476 const isCurrentAbsorbed = current . collisionBehavior === bounce ||
@@ -112,16 +84,16 @@ export const computeCollisionsShader = tgpu['~unstable'].computeFn({
11284 const m1 = current . mass ;
11385 const m2 = other . mass ;
11486 current . velocity = std . add (
115- std . mul ( m1 / ( m1 + m2 ) , current . velocity ) ,
116- std . mul ( m2 / ( m1 + m2 ) , other . velocity ) ,
87+ current . velocity . mul ( m1 / ( m1 + m2 ) ) ,
88+ other . velocity . mul ( m2 / ( m1 + m2 ) ) ,
11789 ) ;
11890 current . mass = m1 + m2 ;
11991 }
12092 }
12193 }
12294 }
12395
124- computeLayout . $ . outState [ input . gid . x ] = CelestialBody ( current ) ;
96+ computeLayout . $ . outState [ currentId ] = CelestialBody ( current ) ;
12597} ) ;
12698
12799export const computeGravityShader = tgpu [ '~unstable' ] . computeFn ( {
@@ -130,23 +102,17 @@ export const computeGravityShader = tgpu['~unstable'].computeFn({
130102} ) ( ( input ) => {
131103 const dt = timeAccess . $ . passed * timeAccess . $ . multiplier ;
132104 const currentId = input . gid . x ;
133- // TODO: replace it with struct copy when Chromium is fixed
134- const current = CelestialBody ( {
135- position : computeLayout . $ . inState [ currentId ] . position ,
136- velocity : computeLayout . $ . inState [ currentId ] . velocity ,
137- mass : computeLayout . $ . inState [ currentId ] . mass ,
138- collisionBehavior : computeLayout . $ . inState [ currentId ] . collisionBehavior ,
139- textureIndex : computeLayout . $ . inState [ currentId ] . textureIndex ,
140- radiusMultiplier : computeLayout . $ . inState [ currentId ] . radiusMultiplier ,
141- ambientLightFactor : computeLayout . $ . inState [ currentId ] . ambientLightFactor ,
142- destroyed : computeLayout . $ . inState [ currentId ] . destroyed ,
143- } ) ;
105+ const current = CelestialBody ( computeLayout . $ . inState [ currentId ] ) ;
144106
145107 if ( current . destroyed === 0 ) {
146- for ( let i = 0 ; i < computeLayout . $ . celestialBodiesCount ; i ++ ) {
147- const other = computeLayout . $ . inState [ i ] ;
108+ for (
109+ let otherId = d . u32 ( 0 ) ;
110+ otherId < d . u32 ( computeLayout . $ . celestialBodiesCount ) ;
111+ otherId ++
112+ ) {
113+ const other = computeLayout . $ . inState [ otherId ] ;
148114
149- if ( d . u32 ( i ) === input . gid . x || other . destroyed === 1 ) {
115+ if ( otherId === currentId || other . destroyed === 1 ) {
150116 continue ;
151117 }
152118
@@ -165,5 +131,5 @@ export const computeGravityShader = tgpu['~unstable'].computeFn({
165131 current . position = current . position . add ( current . velocity . mul ( dt ) ) ;
166132 }
167133
168- computeLayout . $ . outState [ input . gid . x ] = CelestialBody ( current ) ;
134+ computeLayout . $ . outState [ currentId ] = CelestialBody ( current ) ;
169135} ) ;
0 commit comments