blob: 547e870311371bedf53ec10b87635b87868afa84 [file] [log] [blame] [edit]
#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_module_vars_struct {
const constant SimParams* params;
device Particles* particlesA;
device Particles* particlesB;
};
struct vert_main_outputs {
float4 tint_symbol [[position]];
};
struct vert_main_inputs {
float2 a_particlePos [[attribute(0)]];
float2 a_particleVel [[attribute(1)]];
float2 a_pos [[attribute(2)]];
};
struct frag_main_outputs {
float4 tint_symbol_1 [[color(0)]];
};
float4 vert_main_inner(float2 a_particlePos, float2 a_particleVel, float2 a_pos) {
float angle = -(atan2(a_particleVel[0u], a_particleVel[1u]));
float const v = (a_pos[0u] * cos(angle));
float const v_1 = (v - (a_pos[1u] * sin(angle)));
float const v_2 = (a_pos[0u] * sin(angle));
float2 pos = float2(v_1, (v_2 + (a_pos[1u] * cos(angle))));
return float4((pos + a_particlePos), 0.0f, 1.0f);
}
float4 frag_main_inner() {
return float4(1.0f);
}
void comp_main_inner(uint3 gl_GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
uint index = gl_GlobalInvocationID[0u];
if ((index >= 5u)) {
return;
}
float2 vPos = (*tint_module_vars.particlesA).particles[index].pos;
float2 vVel = (*tint_module_vars.particlesA).particles[index].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 = (*tint_module_vars.particlesA).particles[i].pos.xy;
vel = (*tint_module_vars.particlesA).particles[i].vel.xy;
float const v_3 = distance(pos, vPos);
if ((v_3 < (*tint_module_vars.params).rule1Distance)) {
cMass = (cMass + pos);
cMassCount = (cMassCount + 1);
}
float const v_4 = distance(pos, vPos);
if ((v_4 < (*tint_module_vars.params).rule2Distance)) {
colVel = (colVel - (pos - vPos));
}
float const v_5 = distance(pos, vPos);
if ((v_5 < (*tint_module_vars.params).rule3Distance)) {
cVel = (cVel + vel);
cVelCount = (cVelCount + 1);
}
{
i = (i + 1u);
}
continue;
}
}
if ((cMassCount > 0)) {
float2 const v_6 = cMass;
float const v_7 = float(cMassCount);
float2 const v_8 = (v_6 / float2(v_7, float(cMassCount)));
cMass = (v_8 - vPos);
}
if ((cVelCount > 0)) {
float2 const v_9 = cVel;
float const v_10 = float(cVelCount);
cVel = (v_9 / float2(v_10, float(cVelCount)));
}
vVel = (((vVel + (cMass * (*tint_module_vars.params).rule1Scale)) + (colVel * (*tint_module_vars.params).rule2Scale)) + (cVel * (*tint_module_vars.params).rule3Scale));
float2 const v_11 = normalize(vVel);
vVel = (v_11 * clamp(length(vVel), 0.0f, 0.10000000149011611938f));
vPos = (vPos + (vVel * (*tint_module_vars.params).deltaT));
if ((vPos[0u] < -1.0f)) {
vPos[0u] = 1.0f;
}
if ((vPos[0u] > 1.0f)) {
vPos[0u] = -1.0f;
}
if ((vPos[1u] < -1.0f)) {
vPos[1u] = 1.0f;
}
if ((vPos[1u] > 1.0f)) {
vPos[1u] = -1.0f;
}
(*tint_module_vars.particlesB).particles[index].pos = vPos;
(*tint_module_vars.particlesB).particles[index].vel = vVel;
}
vertex vert_main_outputs vert_main(vert_main_inputs inputs [[stage_in]]) {
return vert_main_outputs{.tint_symbol=vert_main_inner(inputs.a_particlePos, inputs.a_particleVel, inputs.a_pos)};
}
fragment frag_main_outputs frag_main() {
return frag_main_outputs{.tint_symbol_1=frag_main_inner()};
}
kernel void comp_main(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], const constant SimParams* params [[buffer(0)]], device Particles* particlesA [[buffer(1)]], device Particles* particlesB [[buffer(2)]]) {
tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.params=params, .particlesA=particlesA, .particlesB=particlesB};
comp_main_inner(gl_GlobalInvocationID, tint_module_vars);
}