💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.2 KiB

  1. /*
  2. * Copyright (C) 2020 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "nest.hpp"
  20. #include "animation/easings.hpp"
  21. #include "marching-cubes.hpp"
  22. #include "geometry/mesh-functions.hpp"
  23. #include "sdf.hpp"
  24. #include <functional>
  25. #include <iostream>
  26. #include <map>
  27. #include <vector>
  28. #include "math.hpp"
  29. #include <functional>
  30. #include <limits>
  31. nest::nest()
  32. {
  33. dig_radius = 1.25f;
  34. }
  35. float3 nest::extend_shaft(shaft& shaft)
  36. {
  37. float3 dig_position = get_shaft_position(shaft, shaft.current_depth);
  38. float dr = frand(dig_radius * 0.75f, dig_radius * 1.25f);
  39. shaft.current_depth += dr * 0.1f;
  40. return dig_position;
  41. }
  42. float3 nest::expand_chamber(chamber& chamber)
  43. {
  44. float dig_angle = frand(0.0f, vmq::two_pi<float>);
  45. float2 dig_direction = vmq::normalize(float2{std::cos(dig_angle), std::sin(dig_angle)});
  46. float3 chamber_center = get_shaft_position(*chamber.shaft, chamber.depth);
  47. float3 dig_position = chamber_center;
  48. float dr = frand(dig_radius * 0.75f, dig_radius * 1.25f);
  49. float t = frand(0.0f, 1.0f);
  50. dig_position.x += dig_direction.x * (chamber.outer_radius - dr) * t;
  51. dig_position.z += dig_direction.y * (chamber.outer_radius - dr) * t;
  52. return dig_position;
  53. }
  54. void nest::set_tunnel_radius(float radius)
  55. {
  56. tunnel_radius = radius;
  57. }
  58. float nest::get_shaft_angle(const shaft& shaft, float depth) const
  59. {
  60. float shaft_length = shaft.depth[1] - shaft.depth[0];
  61. float depth_factor = (depth - shaft.depth[0]) / shaft_length;
  62. float pitch = ease_linear(shaft.pitch[0], shaft.pitch[1], depth_factor);
  63. return shaft.rotation + (depth / pitch) * shaft.chirality * vmq::two_pi<float>;
  64. }
  65. float nest::get_shaft_depth(const shaft& shaft, float turns) const
  66. {
  67. return shaft.pitch[0] * turns;
  68. }
  69. float3 nest::get_shaft_position(const shaft& shaft, float depth) const
  70. {
  71. float shaft_length = shaft.depth[1] - shaft.depth[0];
  72. float depth_factor = (depth - shaft.depth[0]) / shaft_length;
  73. float pitch = ease_linear(shaft.pitch[0], shaft.pitch[1], depth_factor);
  74. float radius = ease_out_expo(shaft.radius[0], shaft.radius[1], depth_factor);
  75. float translation_x = ease_linear(shaft.translation[0][0], shaft.translation[1][0], depth_factor);
  76. float translation_z = ease_linear(shaft.translation[0][1], shaft.translation[1][1], depth_factor);
  77. float angle = shaft.rotation + (depth / pitch) * shaft.chirality * vmq::two_pi<float>;
  78. float3 position;
  79. position[0] = std::cos(angle) * radius + translation_x;
  80. position[1] = -std::max<float>(shaft.depth[0], std::min<float>(shaft.depth[1], depth));
  81. position[2] = std::sin(angle) * radius + translation_z;
  82. return position;
  83. }