Advertisement
AlexD77

Untitled

Nov 28th, 2021
2,309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. [[block]] struct SimParams {
  2.             time: f32;
  3.             count: f32;
  4.         };
  5.  
  6.         [[binding(0), group(0)]] var<uniform> params : SimParams;
  7.  
  8.         struct Object
  9.         {
  10.             position: vec3<f32>;
  11.             collisionMark: f32;
  12.             velocity: vec3<f32>;
  13.             scaleAfterCollision: f32;
  14.             force: vec3<f32>;
  15.             disabled: f32;
  16.             mass: f32;
  17.             size: f32;
  18.             id: f32;
  19.             dummy5: f32;
  20.         };
  21.  
  22.         [[block]] struct Objects {
  23.             data : /*[[stride(64)]]*/ array<Object>;
  24.         };        
  25.  
  26.         [[binding(1), group(0)]] var<storage, read>  ssboIn : Objects;
  27.  
  28.         [[binding(2), group(0)]] var<storage, read_write> ssboOut : Objects;
  29.  
  30.         [[stage(compute), workgroup_size(WORK_GROUP_SIZE)]]
  31.         fn main([[builtin(global_invocation_id)]] GlobalInvocationID : vec3<u32>)
  32.         {
  33.             var threadIndex = GlobalInvocationID.x; // gl_WorkGroupID * gl_WorkGroupSize.x + gl_LocalInvocationID.x
  34.  
  35.             var G = 6.67408313131E-11;
  36.  
  37.             var time = params.time;
  38.             var count = u32(params.count);            
  39.  
  40.             var first = ssboIn.data[threadIndex];
  41.             if (first.disabled > 0.0)
  42.             {
  43.                 // no calculation required
  44.                 return;
  45.             }
  46.  
  47.             var m1 = first.mass;
  48.  
  49.             var forceVector = vec3<f32>(0.0, 0.0, 0.0);
  50.  
  51.             // calculate result force on all objects/planets
  52.             for (var j : u32 = 0u; j < count; j=j+1u)
  53.             {
  54.                 if (threadIndex == j)
  55.                 {
  56.                     continue;
  57.                 }
  58.  
  59.                 var second = ssboIn.data[j];
  60.                 var m2 = second.mass;
  61.                 if (second.disabled > 0.0)
  62.                 {
  63.                     // skip no mass object
  64.                     continue;
  65.                 }
  66.  
  67.                 var dist = distance(first.position, second.position);
  68.                 var distanceSquared = dist * dist;
  69.  
  70.                 if (distanceSquared > 0.0)
  71.                 {
  72.                     var force = G * m1 * m2 / distanceSquared;
  73.  
  74.                     var directionVector = normalize((second.position - first.position));
  75.  
  76.                     forceVector = forceVector + (directionVector * force);
  77.                 }
  78.             }
  79.  
  80.             // calculate new position depends on force
  81.             var a = forceVector / m1;
  82.             var v = a * time;
  83.             var s = v * time / 2.0;
  84.  
  85.             var newPosition = first.position + (first.velocity * time) + s;
  86.             ssboOut.data[threadIndex].force = forceVector;
  87.             ssboOut.data[threadIndex].mass = m1;                          
  88.             ssboOut.data[threadIndex].size = first.size;
  89.             ssboOut.data[threadIndex].position = newPosition;
  90.             ssboOut.data[threadIndex].velocity = first.velocity + v;
  91.             ssboOut.data[threadIndex].scaleAfterCollision = 0.0;
  92.             ssboOut.data[threadIndex].dummy5 = first.dummy5 + time;
  93.  
  94.             // calculate collisions
  95.             for(var j : u32 = 0u; j < count; j=j+1u)
  96.             {
  97.                 if (threadIndex == j)
  98.                 {
  99.                     continue;
  100.                 }
  101.  
  102.                 var second = ssboIn.data[j];
  103.                 var m2 = second.mass;
  104.                 if (second.disabled > 0.0)
  105.                 {
  106.                     // skip no mass object
  107.                     continue;
  108.                 }
  109.  
  110.                 // calculate collision
  111.                 var a = distance(newPosition, first.position);
  112.                 if (a > 0.0)
  113.                 {
  114.                     var b = distance(first.position, second.position);
  115.                     var c = distance(newPosition, second.position);
  116.                     var radius = (first.size + second.size) / 2.0;
  117.                     var id1 = first.id;
  118.                     var id2 = second.id;
  119.  
  120.                     if (b < radius || c < radius) {
  121.                         if (m1 > m2 || (m1 == m2 && id1 > id2)) {
  122.                             // fix  speed  v = (m1v1 + m2v2) / (m1 + m2)
  123.                             var v1 = first.velocity;
  124.                             var v2 = second.velocity;
  125.                             var vresult = (v1 * m1 + v2 * m2) / (m1 + m2);
  126.    
  127.                             var newR = pow((first.size * first.size * first.size
  128.                                             + second.size * second.size * second.size), 1.0 / 3.0);
  129.  
  130.                             // mark collision
  131.                             ssboOut.data[threadIndex].collisionMark = 123.0;
  132.                             ssboOut.data[threadIndex].velocity = vresult;  
  133.                             ssboOut.data[threadIndex].mass = m1 + m2;                          
  134.                             ssboOut.data[threadIndex].size = newR;
  135.                             ssboOut.data[threadIndex].scaleAfterCollision = newR / first.size;
  136.                         } else {
  137.                             // collision from other side
  138.                             ssboOut.data[threadIndex].collisionMark = 246.0;
  139.                             ssboOut.data[threadIndex].mass = 0.0;    
  140.                             ssboOut.data[threadIndex].velocity = vec3<f32>(0.0, 0.0, 0.0);
  141.                             ssboOut.data[threadIndex].force = vec3<f32>(0.0, 0.0, 0.0);
  142.                             ssboOut.data[threadIndex].scaleAfterCollision = 0.0;
  143.                             ssboOut.data[threadIndex].disabled = 9.0;
  144.                         }
  145.  
  146.                         // no more calculations after collision
  147.                         break;
  148.                     }
  149.                 }
  150.             }            
  151.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement