#include <metal_stdlib>

using namespace metal;
struct tint_symbol_1 {
  float2 a_particlePos [[attribute(0)]];
  float2 a_particleVel [[attribute(1)]];
  float2 a_pos [[attribute(2)]];
};
struct tint_symbol_2 {
  float4 value [[position]];
};
struct tint_symbol_3 {
  float4 value [[color(0)]];
};
struct Particle {
  /* 0x0000 */ packed_float2 pos;
  /* 0x0008 */ packed_float2 vel;
};
struct SimParams {
  /* 0x0000 */ float deltaT;
  /* 0x0004 */ float rule1Distance;
  /* 0x0008 */ float rule2Distance;
  /* 0x000c */ float rule3Distance;
  /* 0x0010 */ float rule1Scale;
  /* 0x0014 */ float rule2Scale;
  /* 0x0018 */ float rule3Scale;
};
struct tint_array_wrapper {
  /* 0x0000 */ Particle arr[5];
};
struct Particles {
  /* 0x0000 */ tint_array_wrapper particles;
};

vertex tint_symbol_2 vert_main(tint_symbol_1 tint_symbol [[stage_in]]) {
  float2 const a_particlePos = tint_symbol.a_particlePos;
  float2 const a_particleVel = tint_symbol.a_particleVel;
  float2 const a_pos = tint_symbol.a_pos;
  float angle = -(atan2(a_particleVel.x, a_particleVel.y));
  float2 pos = float2(((a_pos.x * cos(angle)) - (a_pos.y * sin(angle))), ((a_pos.x * sin(angle)) + (a_pos.y * cos(angle))));
  tint_symbol_2 const tint_symbol_5 = {.value=float4((pos + a_particlePos), 0.0f, 1.0f)};
  return tint_symbol_5;
}

fragment tint_symbol_3 frag_main() {
  tint_symbol_3 const tint_symbol_6 = {.value=float4(1.0f, 1.0f, 1.0f, 1.0f)};
  return tint_symbol_6;
}

kernel void comp_main(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], constant SimParams& params [[buffer(0)]], device Particles& particlesA [[buffer(1)]], device Particles& particlesB [[buffer(2)]]) {
  uint index = gl_GlobalInvocationID.x;
  if ((index >= 5u)) {
    return;
  }
  float2 vPos = particlesA.particles.arr[index].pos;
  float2 vVel = particlesA.particles.arr[index].vel;
  float2 cMass = float2(0.0f, 0.0f);
  float2 cVel = float2(0.0f, 0.0f);
  float2 colVel = float2(0.0f, 0.0f);
  int cMassCount = 0;
  int cVelCount = 0;
  float2 pos = 0.0f;
  float2 vel = 0.0f;
  for(uint i = 0u; (i < 5u); i = (i + 1u)) {
    if ((i == index)) {
      continue;
    }
    pos = particlesA.particles.arr[i].pos.xy;
    vel = particlesA.particles.arr[i].vel.xy;
    if ((distance(pos, vPos) < params.rule1Distance)) {
      cMass = (cMass + pos);
      cMassCount = (cMassCount + 1);
    }
    if ((distance(pos, vPos) < params.rule2Distance)) {
      colVel = (colVel - (pos - vPos));
    }
    if ((distance(pos, vPos) < params.rule3Distance)) {
      cVel = (cVel + vel);
      cVelCount = (cVelCount + 1);
    }
  }
  if ((cMassCount > 0)) {
    cMass = ((cMass / float2(float(cMassCount), float(cMassCount))) - vPos);
  }
  if ((cVelCount > 0)) {
    cVel = (cVel / float2(float(cVelCount), float(cVelCount)));
  }
  vVel = (((vVel + (cMass * params.rule1Scale)) + (colVel * params.rule2Scale)) + (cVel * params.rule3Scale));
  vVel = (normalize(vVel) * clamp(length(vVel), 0.0f, 0.100000001f));
  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.arr[index].pos = vPos;
  particlesB.particles.arr[index].vel = vVel;
  return;
}

