Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [[block]] struct SimParams {
- time: f32;
- count: f32;
- };
- [[binding(0), group(0)]] var<uniform> params : SimParams;
- struct Object
- {
- position: vec3<f32>;
- collisionMark: f32;
- velocity: vec3<f32>;
- scaleAfterCollision: f32;
- force: vec3<f32>;
- disabled: f32;
- mass: f32;
- size: f32;
- id: f32;
- dummy5: f32;
- };
- [[block]] struct Objects {
- data : /*[[stride(64)]]*/ array<Object>;
- };
- [[binding(1), group(0)]] var<storage, read> ssboIn : Objects;
- [[binding(2), group(0)]] var<storage, read_write> ssboOut : Objects;
- [[stage(compute), workgroup_size(WORK_GROUP_SIZE)]]
- fn main([[builtin(global_invocation_id)]] GlobalInvocationID : vec3<u32>)
- {
- var threadIndex = GlobalInvocationID.x; // gl_WorkGroupID * gl_WorkGroupSize.x + gl_LocalInvocationID.x
- var G = 6.67408313131E-11;
- var time = params.time;
- var count = u32(params.count);
- var first = ssboIn.data[threadIndex];
- if (first.disabled > 0.0)
- {
- // no calculation required
- return;
- }
- var m1 = first.mass;
- var forceVector = vec3<f32>(0.0, 0.0, 0.0);
- // calculate result force on all objects/planets
- for (var j : u32 = 0u; j < count; j=j+1u)
- {
- if (threadIndex == j)
- {
- continue;
- }
- var second = ssboIn.data[j];
- var m2 = second.mass;
- if (second.disabled > 0.0)
- {
- // skip no mass object
- continue;
- }
- var dist = distance(first.position, second.position);
- var distanceSquared = dist * dist;
- if (distanceSquared > 0.0)
- {
- var force = G * m1 * m2 / distanceSquared;
- var directionVector = normalize((second.position - first.position));
- forceVector = forceVector + (directionVector * force);
- }
- }
- // calculate new position depends on force
- var a = forceVector / m1;
- var v = a * time;
- var s = v * time / 2.0;
- var newPosition = first.position + (first.velocity * time) + s;
- ssboOut.data[threadIndex].force = forceVector;
- ssboOut.data[threadIndex].mass = m1;
- ssboOut.data[threadIndex].size = first.size;
- ssboOut.data[threadIndex].position = newPosition;
- ssboOut.data[threadIndex].velocity = first.velocity + v;
- ssboOut.data[threadIndex].scaleAfterCollision = 0.0;
- ssboOut.data[threadIndex].dummy5 = first.dummy5 + time;
- // calculate collisions
- for(var j : u32 = 0u; j < count; j=j+1u)
- {
- if (threadIndex == j)
- {
- continue;
- }
- var second = ssboIn.data[j];
- var m2 = second.mass;
- if (second.disabled > 0.0)
- {
- // skip no mass object
- continue;
- }
- // calculate collision
- var a = distance(newPosition, first.position);
- if (a > 0.0)
- {
- var b = distance(first.position, second.position);
- var c = distance(newPosition, second.position);
- var radius = (first.size + second.size) / 2.0;
- var id1 = first.id;
- var id2 = second.id;
- if (b < radius || c < radius) {
- if (m1 > m2 || (m1 == m2 && id1 > id2)) {
- // fix speed v = (m1v1 + m2v2) / (m1 + m2)
- var v1 = first.velocity;
- var v2 = second.velocity;
- var vresult = (v1 * m1 + v2 * m2) / (m1 + m2);
- var newR = pow((first.size * first.size * first.size
- + second.size * second.size * second.size), 1.0 / 3.0);
- // mark collision
- ssboOut.data[threadIndex].collisionMark = 123.0;
- ssboOut.data[threadIndex].velocity = vresult;
- ssboOut.data[threadIndex].mass = m1 + m2;
- ssboOut.data[threadIndex].size = newR;
- ssboOut.data[threadIndex].scaleAfterCollision = newR / first.size;
- } else {
- // collision from other side
- ssboOut.data[threadIndex].collisionMark = 246.0;
- ssboOut.data[threadIndex].mass = 0.0;
- ssboOut.data[threadIndex].velocity = vec3<f32>(0.0, 0.0, 0.0);
- ssboOut.data[threadIndex].force = vec3<f32>(0.0, 0.0, 0.0);
- ssboOut.data[threadIndex].scaleAfterCollision = 0.0;
- ssboOut.data[threadIndex].disabled = 9.0;
- }
- // no more calculations after collision
- break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement