blob: 9bb4e2ca4f379007be85fa10b46f6e25aaed99d4 [file] [log] [blame]
#include <metal_stdlib>
using namespace metal;
struct SimParams {
float deltaT;
float rule1Distance;
float rule2Distance;
float rule3Distance;
float rule1Scale;
float rule2Scale;
float rule3Scale;
};
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
struct Particle {
float2 pos;
float2 vel;
};
struct Particles {
tint_array<Particle, 5> particles;
};
struct tint_arg_buffer_struct_0 {
const constant SimParams* params [[id(0)]];
device Particles* particlesA [[id(1)]];
device Particles* particlesB [[id(2)]];
};
void comp_main_inner(uint3 gl_GlobalInvocationID, const constant SimParams* const params, device Particles* const particlesA, device Particles* const particlesB) {
uint index = gl_GlobalInvocationID.x;
if ((index >= 5u)) {
return;
}
float2 vPos = (*particlesA).particles[min(index, 4u)].pos;
float2 vVel = (*particlesA).particles[min(index, 4u)].vel;
float2 cMass = float2(0.0f);
float2 cVel = float2(0.0f);
float2 colVel = float2(0.0f);
int cMassCount = 0;
int cVelCount = 0;
float2 pos = 0.0f;
float2 vel = 0.0f;
{
uint i = 0u;
while(true) {
if ((i < 5u)) {
} else {
break;
}
if ((i == index)) {
{
i = (i + 1u);
}
continue;
}
pos = (*particlesA).particles[min(i, 4u)].pos.xy;
vel = (*particlesA).particles[min(i, 4u)].vel.xy;
if ((distance(pos, vPos) < (*params).rule1Distance)) {
cMass = (cMass + pos);
cMassCount = as_type<int>((as_type<uint>(cMassCount) + as_type<uint>(1)));
}
if ((distance(pos, vPos) < (*params).rule2Distance)) {
colVel = (colVel - (pos - vPos));
}
if ((distance(pos, vPos) < (*params).rule3Distance)) {
cVel = (cVel + vel);
cVelCount = as_type<int>((as_type<uint>(cVelCount) + as_type<uint>(1)));
}
{
i = (i + 1u);
}
continue;
}
}
if ((cMassCount > 0)) {
float2 const v = cMass;
float const v_1 = float(cMassCount);
float2 const v_2 = (v / float2(v_1, float(cMassCount)));
cMass = (v_2 - vPos);
}
if ((cVelCount > 0)) {
float2 const v_3 = cVel;
float const v_4 = float(cVelCount);
cVel = (v_3 / float2(v_4, float(cVelCount)));
}
vVel = (((vVel + (cMass * (*params).rule1Scale)) + (colVel * (*params).rule2Scale)) + (cVel * (*params).rule3Scale));
vVel = (normalize(vVel) * clamp(length(vVel), 0.0f, 0.10000000149011611938f));
vPos = (vPos + (vVel * (*params).deltaT));
if ((vPos.x < -1.0f)) {
vPos.x = 1.0f;
}
if ((vPos.x > 1.0f)) {
vPos.x = -1.0f;
}
if ((vPos.y < -1.0f)) {
vPos.y = 1.0f;
}
if ((vPos.y > 1.0f)) {
vPos.y = -1.0f;
}
(*particlesB).particles[min(index, 4u)].pos = vPos;
(*particlesB).particles[min(index, 4u)].vel = vVel;
}
kernel void comp_main(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], const constant tint_arg_buffer_struct_0* tint_arg_buffer_0 [[buffer(0)]]) {
tint_arg_buffer_struct_0 const v_5 = (*tint_arg_buffer_0);
comp_main_inner(gl_GlobalInvocationID, v_5.params, v_5.particlesA, v_5.particlesB);
}