# Copyright 2020 The Tint Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import "GLSL.std.450" as std;

# vertex shader

[[location 0]] var<in> a_particlePos : vec2<f32>;
[[location 1]] var<in> a_particleVel : vec2<f32>;
[[location 2]] var<in> a_pos : vec2<f32>;
[[builtin position]] var<out> gl_Position : vec4<f32>;

fn vtx_main() -> void {
  var angle : f32 = -std::atan2(a_particleVel.x, a_particleVel.y);
  var pos : vec2<f32> = vec2<f32>(
      (a_pos.x * std::cos(angle)) - (a_pos.y * std::sin(angle)),
      (a_pos.x * std::sin(angle)) + (a_pos.y * std::cos(angle)));
  gl_Position = vec4<f32>(pos + a_particlePos, 0.0, 1.0);
  return;
}
entry_point vertex as "vert_main" = vtx_main;

# fragment shader
[[location 0]] var<out> fragColor : vec4<f32>;

fn frag_main() -> void {
  fragColor = vec4<f32>(1.0, 1.0, 1.0, 1.0);
  return;
}
entry_point fragment as "frag_main" = frag_main;

# compute shader
type Particle = [[block]] struct {
  [[offset 0]] pos : vec2<f32>;
  [[offset 8]] vel : vec2<f32>;
};

type SimParams = [[block]] struct {
  [[offset 0]] deltaT : f32;
  [[offset 4]] rule1Distance : f32;
  [[offset 8]] rule2Distance : f32;
  [[offset 12]] rule3Distance : f32;
  [[offset 16]] rule1Scale : f32;
  [[offset 20]] rule2Scale : f32;
  [[offset 24]] rule3Scale : f32;
};

type Particles = [[block]] struct {
  [[offset 0]] particles : array<Particle, 5>;
};

[[binding 0, set 0]] var<uniform> params : SimParams;
[[binding 1, set 0]] var<storage_buffer> particlesA : Particles;
[[binding 2, set 0]] var<storage_buffer> particlesB : Particles;

[[builtin global_invocation_id]] var<in> gl_GlobalInvocationID : vec3<u32>;

# https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
fn compute_main() -> void {
  var index : u32 = gl_GlobalInvocationID.x;
  if (index >= 5) {
    return;
  }

  var vPos : vec2<f32> = particlesA.particles[index].pos;
  var vVel : vec2<f32> = particlesA.particles[index].vel;

  var cMass : vec2<f32> = vec2<f32>(0.0, 0.0);
  var cVel : vec2<f32> = vec2<f32>(0.0, 0.0);
  var colVel : vec2<f32> = vec2<f32>(0.0, 0.0);
  var cMassCount : i32 = 0;
  var cVelCount : i32 = 0;

  var pos : vec2<f32>;
  var vel : vec2<f32>;
  var i : i32 = 0;
  loop {
    if (i >= 5) {
      break;
    }
    if (i == index) {
      continue;
    }

    pos = particlesA.particles[i].pos.xy;
    vel = particlesA.particles[i].vel.xy;

    if (std::distance(pos, vPos) < params.rule1Distance) {
      cMass = cMass + pos;
      cMassCount = cMassCount + 1;
    }
    if (std::distance(pos, vPos) < params.rule2Distance) {
      colVel = colVel - (pos - vPos);
    }
    if (std::distance(pos, vPos) < params.rule3Distance) {
      cVel = cVel + vel;
      cVelCount = cVelCount + 1;
    }

    continuing {
      i = i + 1;
    }
  }
  if (cMassCount > 0) {
    cMass =
      (cMass / vec2<f32>(cast<f32>(cMassCount), cast<f32>(cMassCount))) - vPos;
  }
  if (cVelCount > 0) {
    cVel = cVel / vec2<f32>(cast<f32>(cVelCount), cast<f32>(cVelCount));
  }

  vVel = vVel + (cMass * params.rule1Scale) + (colVel * params.rule2Scale) +
      (cVel * params.rule3Scale);

  # clamp velocity for a more pleasing simulation
  vVel = std::normalize(vVel) * std::fclamp(std::length(vVel), 0.0, 0.1);

  # kinematic update
  vPos = vPos + (vVel * params.deltaT);

  # Wrap around boundary
  if (vPos.x < -1.0) {
    vPos.x = 1.0;
  }
  if (vPos.x > 1.0) {
    vPos.x = -1.0;
  }
  if (vPos.y < -1.0) {
    vPos.y = 1.0;
  }
  if (vPos.y > 1.0) {
    vPos.y = -1.0;
  }

  # Write back
  particlesB.particles[index].pos = vPos;
  particlesB.particles[index].vel = vVel;

  return;
}
entry_point compute as "comp_main" = compute_main;

