@ -1,74 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "nest.hpp" | |||
#include "../../nest.hpp" | |||
#include "math/math.hpp" | |||
namespace entity { | |||
namespace system { | |||
nest::nest(entity::registry& registry, ::resource_manager* resource_manager): | |||
updatable(registry), | |||
resource_manager(resource_manager) | |||
{ | |||
registry.on_construct<component::nest>().connect<&nest::on_nest_construct>(this); | |||
registry.on_destroy<component::nest>().connect<&nest::on_nest_destroy>(this); | |||
} | |||
nest::~nest() | |||
{} | |||
void nest::update(double t, double dt) | |||
{} | |||
void nest::on_nest_construct(entity::registry& registry, entity::id entity_id, component::nest& component) | |||
{ | |||
/* | |||
// Allocate a nest | |||
::nest* nest = new ::nest(); | |||
// Setup initial nest parameters | |||
nest->set_tunnel_radius(1.15f); | |||
nest::shaft* central_shaft = nest->get_central_shaft(); | |||
central_shaft->chirality = -1.0f; | |||
central_shaft->rotation = math::radians(0.0f); | |||
central_shaft->depth = {0.0f, 100.0f}; | |||
central_shaft->current_depth = 0.0f; | |||
central_shaft->radius = {0.0f, 5.0f}; | |||
central_shaft->pitch = {4.0f, 8.0f}; | |||
central_shaft->translation = {{{0.0f, 0.0f}, {20.0f, 11.0f}}}; | |||
for (std::size_t i = 0; i < 4; ++i) | |||
{ | |||
nest::chamber chamber; | |||
chamber.shaft = central_shaft; | |||
chamber.depth = (i + 1) * 23.0f; | |||
chamber.rotation = math::radians(0.0f); | |||
chamber.inner_radius = 4.0f; | |||
chamber.outer_radius = 10.0f; | |||
central_shaft->chambers.push_back(chamber); | |||
} | |||
*/ | |||
} | |||
void nest::on_nest_destroy(entity::registry& registry, entity::id entity_id) | |||
{} | |||
} // namespace system | |||
} // namespace entity |
@ -1,50 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_ENTITY_SYSTEM_NEST_HPP | |||
#define ANTKEEPER_ENTITY_SYSTEM_NEST_HPP | |||
#include "entity/systems/updatable.hpp" | |||
#include "entity/components/nest.hpp" | |||
class nest; | |||
class resource_manager; | |||
namespace entity { | |||
namespace system { | |||
class nest: public updatable | |||
{ | |||
public: | |||
nest(entity::registry& registry, ::resource_manager* resource_manager); | |||
~nest(); | |||
virtual void update(double t, double dt); | |||
private: | |||
resource_manager* resource_manager; | |||
void on_nest_construct(entity::registry& registry, entity::id entity_id, entity::component::nest& component); | |||
void on_nest_destroy(entity::registry& registry, entity::id entity_id); | |||
}; | |||
} // namespace system | |||
} // namespace entity | |||
#endif // ANTKEEPER_ENTITY_SYSTEM_NEST_HPP | |||
@ -1,93 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "nest.hpp" | |||
#include "math/math.hpp" | |||
nest::nest() | |||
{ | |||
dig_radius = 1.25f; | |||
} | |||
float3 nest::extend_shaft(shaft& shaft) | |||
{ | |||
float3 dig_position = get_shaft_position(shaft, shaft.current_depth); | |||
float dr = math::random(dig_radius * 0.75f, dig_radius * 1.25f); | |||
shaft.current_depth += dr * 0.1f; | |||
return dig_position; | |||
} | |||
float3 nest::expand_chamber(chamber& chamber) | |||
{ | |||
float dig_angle = math::random(0.0f, math::two_pi<float>); | |||
float2 dig_direction = math::normalize(float2{std::cos(dig_angle), std::sin(dig_angle)}); | |||
float3 chamber_center = get_shaft_position(*chamber.shaft, chamber.depth); | |||
float3 dig_position = chamber_center; | |||
float dr = math::random(dig_radius * 0.75f, dig_radius * 1.25f); | |||
float t = math::random(0.0f, 1.0f); | |||
dig_position.x += dig_direction.x * (chamber.outer_radius - dr) * t; | |||
dig_position.z += dig_direction.y * (chamber.outer_radius - dr) * t; | |||
return dig_position; | |||
} | |||
void nest::set_tunnel_radius(float radius) | |||
{ | |||
tunnel_radius = radius; | |||
} | |||
float nest::get_shaft_angle(const shaft& shaft, float depth) const | |||
{ | |||
float shaft_length = shaft.depth[1] - shaft.depth[0]; | |||
float depth_factor = (depth - shaft.depth[0]) / shaft_length; | |||
float pitch = math::lerp<float>(shaft.pitch[0], shaft.pitch[1], depth_factor); | |||
return shaft.rotation + (depth / pitch) * shaft.chirality * math::two_pi<float>; | |||
} | |||
float nest::get_shaft_depth(const shaft& shaft, float turns) const | |||
{ | |||
return shaft.pitch[0] * turns; | |||
} | |||
float3 nest::get_shaft_position(const shaft& shaft, float depth) const | |||
{ | |||
float shaft_length = shaft.depth[1] - shaft.depth[0]; | |||
float depth_factor = (depth - shaft.depth[0]) / shaft_length; | |||
float pitch = math::lerp<float>(shaft.pitch[0], shaft.pitch[1], depth_factor); | |||
float radius = math::lerp<float>(shaft.radius[0], shaft.radius[1], depth_factor); | |||
float translation_x = math::lerp<float>(shaft.translation[0][0], shaft.translation[1][0], depth_factor); | |||
float translation_z = math::lerp<float>(shaft.translation[0][1], shaft.translation[1][1], depth_factor); | |||
float angle = shaft.rotation + (depth / pitch) * shaft.chirality * math::two_pi<float>; | |||
float3 position; | |||
position[0] = std::cos(angle) * radius + translation_x; | |||
position[1] = -std::max<float>(shaft.depth[0], std::min<float>(shaft.depth[1], depth)); | |||
position[2] = std::sin(angle) * radius + translation_z; | |||
return position; | |||
} | |||
@ -1,89 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_NEST_HPP | |||
#define ANTKEEPER_NEST_HPP | |||
#include "geom/mesh.hpp" | |||
#include "utility/fundamental-types.hpp" | |||
#include <array> | |||
#include <vector> | |||
class nest | |||
{ | |||
public: | |||
struct chamber; | |||
struct shaft | |||
{ | |||
std::array<float, 2> depth; ///< start and end shaft depth | |||
float chirality; ///< 1 = right-handed, -1 = left-handed | |||
float rotation; ///< starting helix angle, in radians | |||
std::array<float, 2> radius; ///< start and end helix radius | |||
std::array<float, 2> pitch; ///< start and end helix pitch | |||
std::array<float2, 2> translation; ///< start and end helix translation | |||
std::vector<chamber> chambers; | |||
float current_depth; | |||
}; | |||
struct chamber | |||
{ | |||
shaft* shaft; ///< parent shaft | |||
float depth; ///< chamber depth, relative to parent shaft | |||
float rotation; ///< chamber rotation, relative to helix angle | |||
float sector_angle; ///< | |||
float inner_radius; | |||
float outer_radius; | |||
}; | |||
/** | |||
* Creates a nest. | |||
*/ | |||
nest(); | |||
float3 extend_shaft(shaft& shaft); | |||
float3 expand_chamber(chamber& chamber); | |||
void regenerate(); | |||
void set_tunnel_radius(float radius); | |||
shaft* get_central_shaft(); | |||
/** | |||
* Calculates the position on a shaft at the specified depth. | |||
*/ | |||
float3 get_shaft_position(const shaft& shaft, float depth) const; | |||
float get_shaft_angle(const shaft& shaft, float depth) const; | |||
float get_shaft_depth(const shaft& shaft, float turns) const; | |||
private: | |||
float tunnel_radius; | |||
shaft central_shaft; | |||
float dig_radius; | |||
}; | |||
inline nest::shaft* nest::get_central_shaft() | |||
{ | |||
return ¢ral_shaft; | |||
} | |||
#endif // ANTKEEPER_NEST_HPP |
@ -1,90 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "pheromone-matrix.hpp" | |||
#include "math/math.hpp" | |||
void convolve(pheromone_matrix* matrix, const float* kernel, int kernel_size) | |||
{ | |||
float* front = matrix->buffers[matrix->current]; | |||
float* back = matrix->buffers[(matrix->current + 1) % 2]; | |||
const int kernel_radius = kernel_size << 1; | |||
// For each pheromone matrix row | |||
for (int i = 0; i < matrix->rows; ++i) | |||
{ | |||
// For each pheromone in the row | |||
for (int j = 0; j < matrix->columns; ++j) | |||
{ | |||
// Reset accumulator | |||
float accumulator = 0.0f; | |||
// For each kernel row | |||
for (int k = -kernel_radius; k <= kernel_radius; ++k) | |||
{ | |||
// For each kernel element | |||
for (int l = -kernel_radius; l <= kernel_radius; ++l) | |||
{ | |||
// Determine row and column of pheromone corresponding to the kernel element. | |||
int m = i + k; | |||
int n = j + l; | |||
// If the row and column indices are within the matrix | |||
if (m >= 0 && m < matrix->rows && n >= 0 && n < matrix->columns) | |||
{ | |||
// Multiply pheromone strength in the front buffer by the kernel value and add it to the accumulator. | |||
accumulator += front[m * matrix->columns + n] * kernel[(k + kernel_radius) * kernel_size + l + kernel_radius]; | |||
} | |||
} | |||
} | |||
// Set pheromone strength in the back buffer equal to the accumulator value | |||
back[i * matrix->columns + j] = accumulator; | |||
} | |||
} | |||
// Swap buffers | |||
matrix->current = (matrix->current + 1) % 2; | |||
} | |||
void evaporate(pheromone_matrix* matrix, float factor) | |||
{ | |||
const int size = matrix->columns * matrix->rows; | |||
for (int i = 0; i < size; ++i) | |||
{ | |||
matrix->buffers[matrix->current][i] *= factor; | |||
} | |||
} | |||
void diffuse(pheromone_matrix* matrix) | |||
{ | |||
const math::matrix<float, 3, 3> diffusion_kernel = | |||
math::mul( | |||
math::matrix<float, 3, 3> | |||
{{ | |||
{1, 2, 1}, | |||
{2, 4, 2}, | |||
{1, 2, 1} | |||
}}, | |||
1.0f / 16.0f); | |||
convolve(matrix, &diffusion_kernel[0][0], 3); | |||
} | |||
@ -1,64 +0,0 @@ | |||
/* | |||
* Copyright (C) 2021 Christopher J. Howard | |||
* | |||
* This file is part of Antkeeper source code. | |||
* | |||
* Antkeeper source code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* Antkeeper source code is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef ANTKEEPER_PHEROMONE_MATRIX_HPP | |||
#define ANTKEEPER_PHEROMONE_MATRIX_HPP | |||
/** | |||
* A double-buffered matrix containing floating point pheromone strengths. | |||
*/ | |||
struct pheromone_matrix | |||
{ | |||
/// Number of columns in the matrix. | |||
int columns; | |||
/// Number of rows in the matrix. | |||
int rows; | |||
/// Two buffers containing pheromone strengths | |||
float** buffers; | |||
/// Index of the current buffer | |||
int current; | |||
}; | |||
/** | |||
* Performs a convolution on a pheromone matrix. | |||
* | |||
* @param matrix Pointer to a pheromone matrix. | |||
* @param kernel Convolution kernel. | |||
* @param kernel_size Size of the kernel. | |||
*/ | |||
void convolve(pheromone_matrix* matrix, const float* kernel, int kernel_size); | |||
/** | |||
* Causes all pheromones in a pheromone matrix to decrease in strength according to the specified evaporation rate. | |||
* | |||
* @param matrix Pointer to the pheromone matrix. | |||
* @param factor Evaporation factor by which each pheromone strength will be multiplied. | |||
*/ | |||
void evaporate(pheromone_matrix* matrix, float rate); | |||
/** | |||
* Causes all pheromones in a pheromone matrix to diffuse. | |||
*/ | |||
void diffuse(pheromone_matrix* matrix); | |||
#endif // ANTKEEPER_PHEROMONE_MATRIX_HPP | |||