feat: Bordes como obstáculos + Variables BOIDS ajustables + Fix tecla G
**1. Bordes como obstáculos (no más wrapping):** - Implementada fuerza de repulsión cuando boids se acercan a bordes - Nueva regla: Boundary Avoidance (evitar bordes) - Fuerza proporcional a cercanía (0% en margen, 100% en colisión) - Constantes: BOID_BOUNDARY_MARGIN (50px), BOID_BOUNDARY_WEIGHT (7200 px/s²) **2. Variables ajustables en runtime:** - Añadidas 11 variables miembro en BoidManager (inicializadas con defines.h) - Permite modificar comportamiento sin recompilar - Variables: radios (separation/alignment/cohesion), weights, speeds, boundary - Base para futuras herramientas de debug/tweaking visual **3. Fix tecla G (BOIDS → PHYSICS):** - Corregido: toggleBoidsMode() ahora acepta parámetro force_gravity_on - handleGravityToggle() pasa explícitamente false para preservar inercia - Transición BOIDS→PHYSICS ahora mantiene gravedad OFF correctamente **Implementación:** - defines.h: +2 constantes (BOUNDARY_MARGIN, BOUNDARY_WEIGHT) - boid_manager.h: +11 variables miembro ajustables - boid_manager.cpp: - Constructor inicializa variables - Todas las funciones usan variables en lugar de constantes - applyBoundaries() completamente reescrito (repulsión vs wrapping) - engine.h/cpp: toggleBoidsMode() con parámetro opcional 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,18 @@ BoidManager::BoidManager()
|
|||||||
, screen_width_(0)
|
, screen_width_(0)
|
||||||
, screen_height_(0)
|
, screen_height_(0)
|
||||||
, boids_active_(false)
|
, boids_active_(false)
|
||||||
, spatial_grid_(800, 600, BOID_GRID_CELL_SIZE) { // Tamaño por defecto, se actualiza en initialize()
|
, spatial_grid_(800, 600, BOID_GRID_CELL_SIZE) // Tamaño por defecto, se actualiza en initialize()
|
||||||
|
, separation_radius_(BOID_SEPARATION_RADIUS)
|
||||||
|
, alignment_radius_(BOID_ALIGNMENT_RADIUS)
|
||||||
|
, cohesion_radius_(BOID_COHESION_RADIUS)
|
||||||
|
, separation_weight_(BOID_SEPARATION_WEIGHT)
|
||||||
|
, alignment_weight_(BOID_ALIGNMENT_WEIGHT)
|
||||||
|
, cohesion_weight_(BOID_COHESION_WEIGHT)
|
||||||
|
, max_speed_(BOID_MAX_SPEED)
|
||||||
|
, min_speed_(BOID_MIN_SPEED)
|
||||||
|
, max_force_(BOID_MAX_FORCE)
|
||||||
|
, boundary_margin_(BOID_BOUNDARY_MARGIN)
|
||||||
|
, boundary_weight_(BOID_BOUNDARY_WEIGHT) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BoidManager::~BoidManager() {
|
BoidManager::~BoidManager() {
|
||||||
@@ -146,7 +157,7 @@ void BoidManager::applySeparation(Ball* boid, float delta_time) {
|
|||||||
float center_y = pos.y + pos.h / 2.0f;
|
float center_y = pos.y + pos.h / 2.0f;
|
||||||
|
|
||||||
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
||||||
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, BOID_SEPARATION_RADIUS);
|
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, separation_radius_);
|
||||||
|
|
||||||
for (Ball* other : neighbors) {
|
for (Ball* other : neighbors) {
|
||||||
if (other == boid) continue; // Ignorar a sí mismo
|
if (other == boid) continue; // Ignorar a sí mismo
|
||||||
@@ -159,10 +170,10 @@ void BoidManager::applySeparation(Ball* boid, float delta_time) {
|
|||||||
float dy = center_y - other_y;
|
float dy = center_y - other_y;
|
||||||
float distance = std::sqrt(dx * dx + dy * dy);
|
float distance = std::sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
if (distance > 0.0f && distance < BOID_SEPARATION_RADIUS) {
|
if (distance > 0.0f && distance < separation_radius_) {
|
||||||
// FASE 1.3: Separación más fuerte cuando más cerca (inversamente proporcional a distancia)
|
// FASE 1.3: Separación más fuerte cuando más cerca (inversamente proporcional a distancia)
|
||||||
// Fuerza proporcional a cercanía: 0% en radio máximo, 100% en colisión
|
// Fuerza proporcional a cercanía: 0% en radio máximo, 100% en colisión
|
||||||
float separation_strength = (BOID_SEPARATION_RADIUS - distance) / BOID_SEPARATION_RADIUS;
|
float separation_strength = (separation_radius_ - distance) / separation_radius_;
|
||||||
steer_x += (dx / distance) * separation_strength;
|
steer_x += (dx / distance) * separation_strength;
|
||||||
steer_y += (dy / distance) * separation_strength;
|
steer_y += (dy / distance) * separation_strength;
|
||||||
count++;
|
count++;
|
||||||
@@ -177,8 +188,8 @@ void BoidManager::applySeparation(Ball* boid, float delta_time) {
|
|||||||
// Aplicar fuerza de separación
|
// Aplicar fuerza de separación
|
||||||
float vx, vy;
|
float vx, vy;
|
||||||
boid->getVelocity(vx, vy);
|
boid->getVelocity(vx, vy);
|
||||||
vx += steer_x * BOID_SEPARATION_WEIGHT * delta_time;
|
vx += steer_x * separation_weight_ * delta_time;
|
||||||
vy += steer_y * BOID_SEPARATION_WEIGHT * delta_time;
|
vy += steer_y * separation_weight_ * delta_time;
|
||||||
boid->setVelocity(vx, vy);
|
boid->setVelocity(vx, vy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +205,7 @@ void BoidManager::applyAlignment(Ball* boid, float delta_time) {
|
|||||||
float center_y = pos.y + pos.h / 2.0f;
|
float center_y = pos.y + pos.h / 2.0f;
|
||||||
|
|
||||||
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
||||||
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, BOID_ALIGNMENT_RADIUS);
|
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, alignment_radius_);
|
||||||
|
|
||||||
for (Ball* other : neighbors) {
|
for (Ball* other : neighbors) {
|
||||||
if (other == boid) continue;
|
if (other == boid) continue;
|
||||||
@@ -207,7 +218,7 @@ void BoidManager::applyAlignment(Ball* boid, float delta_time) {
|
|||||||
float dy = center_y - other_y;
|
float dy = center_y - other_y;
|
||||||
float distance = std::sqrt(dx * dx + dy * dy);
|
float distance = std::sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
if (distance < BOID_ALIGNMENT_RADIUS) {
|
if (distance < alignment_radius_) {
|
||||||
float other_vx, other_vy;
|
float other_vx, other_vy;
|
||||||
other->getVelocity(other_vx, other_vy);
|
other->getVelocity(other_vx, other_vy);
|
||||||
avg_vx += other_vx;
|
avg_vx += other_vx;
|
||||||
@@ -224,14 +235,14 @@ void BoidManager::applyAlignment(Ball* boid, float delta_time) {
|
|||||||
// Steering hacia la velocidad promedio
|
// Steering hacia la velocidad promedio
|
||||||
float vx, vy;
|
float vx, vy;
|
||||||
boid->getVelocity(vx, vy);
|
boid->getVelocity(vx, vy);
|
||||||
float steer_x = (avg_vx - vx) * BOID_ALIGNMENT_WEIGHT * delta_time;
|
float steer_x = (avg_vx - vx) * alignment_weight_ * delta_time;
|
||||||
float steer_y = (avg_vy - vy) * BOID_ALIGNMENT_WEIGHT * delta_time;
|
float steer_y = (avg_vy - vy) * alignment_weight_ * delta_time;
|
||||||
|
|
||||||
// Limitar fuerza máxima de steering
|
// Limitar fuerza máxima de steering
|
||||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||||
if (steer_mag > BOID_MAX_FORCE) {
|
if (steer_mag > max_force_) {
|
||||||
steer_x = (steer_x / steer_mag) * BOID_MAX_FORCE;
|
steer_x = (steer_x / steer_mag) * max_force_;
|
||||||
steer_y = (steer_y / steer_mag) * BOID_MAX_FORCE;
|
steer_y = (steer_y / steer_mag) * max_force_;
|
||||||
}
|
}
|
||||||
|
|
||||||
vx += steer_x;
|
vx += steer_x;
|
||||||
@@ -251,7 +262,7 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
|||||||
float center_y = pos.y + pos.h / 2.0f;
|
float center_y = pos.y + pos.h / 2.0f;
|
||||||
|
|
||||||
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
||||||
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, BOID_COHESION_RADIUS);
|
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, cohesion_radius_);
|
||||||
|
|
||||||
for (Ball* other : neighbors) {
|
for (Ball* other : neighbors) {
|
||||||
if (other == boid) continue;
|
if (other == boid) continue;
|
||||||
@@ -264,7 +275,7 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
|||||||
float dy = center_y - other_y;
|
float dy = center_y - other_y;
|
||||||
float distance = std::sqrt(dx * dx + dy * dy);
|
float distance = std::sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
if (distance < BOID_COHESION_RADIUS) {
|
if (distance < cohesion_radius_) {
|
||||||
center_of_mass_x += other_x;
|
center_of_mass_x += other_x;
|
||||||
center_of_mass_y += other_y;
|
center_of_mass_y += other_y;
|
||||||
count++;
|
count++;
|
||||||
@@ -284,14 +295,14 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
|||||||
// Solo aplicar si hay distancia al centro (evitar división por cero)
|
// Solo aplicar si hay distancia al centro (evitar división por cero)
|
||||||
if (distance_to_center > 0.1f) {
|
if (distance_to_center > 0.1f) {
|
||||||
// Normalizar vector dirección (fuerza independiente de distancia)
|
// Normalizar vector dirección (fuerza independiente de distancia)
|
||||||
float steer_x = (dx_to_center / distance_to_center) * BOID_COHESION_WEIGHT * delta_time;
|
float steer_x = (dx_to_center / distance_to_center) * cohesion_weight_ * delta_time;
|
||||||
float steer_y = (dy_to_center / distance_to_center) * BOID_COHESION_WEIGHT * delta_time;
|
float steer_y = (dy_to_center / distance_to_center) * cohesion_weight_ * delta_time;
|
||||||
|
|
||||||
// Limitar fuerza máxima de steering
|
// Limitar fuerza máxima de steering
|
||||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||||
if (steer_mag > BOID_MAX_FORCE) {
|
if (steer_mag > max_force_) {
|
||||||
steer_x = (steer_x / steer_mag) * BOID_MAX_FORCE;
|
steer_x = (steer_x / steer_mag) * max_force_;
|
||||||
steer_y = (steer_y / steer_mag) * BOID_MAX_FORCE;
|
steer_y = (steer_y / steer_mag) * max_force_;
|
||||||
}
|
}
|
||||||
|
|
||||||
float vx, vy;
|
float vx, vy;
|
||||||
@@ -304,32 +315,69 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BoidManager::applyBoundaries(Ball* boid) {
|
void BoidManager::applyBoundaries(Ball* boid) {
|
||||||
// Mantener boids dentro de los límites de la pantalla
|
// NUEVA IMPLEMENTACIÓN: Bordes como obstáculos (repulsión en lugar de wrapping)
|
||||||
// Comportamiento "wrapping" (teletransporte al otro lado)
|
// Cuando un boid se acerca a un borde, se aplica una fuerza alejándolo
|
||||||
SDL_FRect pos = boid->getPosition();
|
SDL_FRect pos = boid->getPosition();
|
||||||
float center_x = pos.x + pos.w / 2.0f;
|
float center_x = pos.x + pos.w / 2.0f;
|
||||||
float center_y = pos.y + pos.h / 2.0f;
|
float center_y = pos.y + pos.h / 2.0f;
|
||||||
|
|
||||||
bool wrapped = false;
|
float steer_x = 0.0f;
|
||||||
|
float steer_y = 0.0f;
|
||||||
|
|
||||||
if (center_x < 0) {
|
// Borde izquierdo (x < boundary_margin_)
|
||||||
pos.x = screen_width_ - pos.w / 2.0f;
|
if (center_x < boundary_margin_) {
|
||||||
wrapped = true;
|
float distance = center_x; // Distancia al borde (0 = colisión)
|
||||||
} else if (center_x > screen_width_) {
|
if (distance < boundary_margin_) {
|
||||||
pos.x = -pos.w / 2.0f;
|
// Fuerza proporcional a cercanía: 0% en margen, 100% en colisión
|
||||||
wrapped = true;
|
float repulsion_strength = (boundary_margin_ - distance) / boundary_margin_;
|
||||||
|
steer_x += repulsion_strength; // Empujar hacia la derecha
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (center_y < 0) {
|
// Borde derecho (x > screen_width_ - boundary_margin_)
|
||||||
pos.y = screen_height_ - pos.h / 2.0f;
|
if (center_x > screen_width_ - boundary_margin_) {
|
||||||
wrapped = true;
|
float distance = screen_width_ - center_x;
|
||||||
} else if (center_y > screen_height_) {
|
if (distance < boundary_margin_) {
|
||||||
pos.y = -pos.h / 2.0f;
|
float repulsion_strength = (boundary_margin_ - distance) / boundary_margin_;
|
||||||
wrapped = true;
|
steer_x -= repulsion_strength; // Empujar hacia la izquierda
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrapped) {
|
// Borde superior (y < boundary_margin_)
|
||||||
boid->setPosition(pos.x, pos.y);
|
if (center_y < boundary_margin_) {
|
||||||
|
float distance = center_y;
|
||||||
|
if (distance < boundary_margin_) {
|
||||||
|
float repulsion_strength = (boundary_margin_ - distance) / boundary_margin_;
|
||||||
|
steer_y += repulsion_strength; // Empujar hacia abajo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Borde inferior (y > screen_height_ - boundary_margin_)
|
||||||
|
if (center_y > screen_height_ - boundary_margin_) {
|
||||||
|
float distance = screen_height_ - center_y;
|
||||||
|
if (distance < boundary_margin_) {
|
||||||
|
float repulsion_strength = (boundary_margin_ - distance) / boundary_margin_;
|
||||||
|
steer_y -= repulsion_strength; // Empujar hacia arriba
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar fuerza de repulsión si hay alguna
|
||||||
|
if (steer_x != 0.0f || steer_y != 0.0f) {
|
||||||
|
float vx, vy;
|
||||||
|
boid->getVelocity(vx, vy);
|
||||||
|
|
||||||
|
// Normalizar fuerza de repulsión (para que todas las direcciones tengan la misma intensidad)
|
||||||
|
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||||
|
if (steer_mag > 0.0f) {
|
||||||
|
steer_x /= steer_mag;
|
||||||
|
steer_y /= steer_mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar aceleración de repulsión (time-based)
|
||||||
|
// boundary_weight_ es más fuerte que separation para garantizar que no escapen
|
||||||
|
vx += steer_x * boundary_weight_ * (1.0f / 60.0f); // Simular delta_time fijo para independencia
|
||||||
|
vy += steer_y * boundary_weight_ * (1.0f / 60.0f);
|
||||||
|
boid->setVelocity(vx, vy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,16 +389,16 @@ void BoidManager::limitSpeed(Ball* boid) {
|
|||||||
float speed = std::sqrt(vx * vx + vy * vy);
|
float speed = std::sqrt(vx * vx + vy * vy);
|
||||||
|
|
||||||
// Limitar velocidad máxima
|
// Limitar velocidad máxima
|
||||||
if (speed > BOID_MAX_SPEED) {
|
if (speed > max_speed_) {
|
||||||
vx = (vx / speed) * BOID_MAX_SPEED;
|
vx = (vx / speed) * max_speed_;
|
||||||
vy = (vy / speed) * BOID_MAX_SPEED;
|
vy = (vy / speed) * max_speed_;
|
||||||
boid->setVelocity(vx, vy);
|
boid->setVelocity(vx, vy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FASE 1.2: Aplicar velocidad mínima (evitar boids estáticos)
|
// FASE 1.2: Aplicar velocidad mínima (evitar boids estáticos)
|
||||||
if (speed > 0.0f && speed < BOID_MIN_SPEED) {
|
if (speed > 0.0f && speed < min_speed_) {
|
||||||
vx = (vx / speed) * BOID_MIN_SPEED;
|
vx = (vx / speed) * min_speed_;
|
||||||
vy = (vy / speed) * BOID_MIN_SPEED;
|
vy = (vy / speed) * min_speed_;
|
||||||
boid->setVelocity(vx, vy);
|
boid->setVelocity(vx, vy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,10 +103,24 @@ class BoidManager {
|
|||||||
// FASE 2: Grid reutilizable para búsquedas de vecinos
|
// FASE 2: Grid reutilizable para búsquedas de vecinos
|
||||||
SpatialGrid spatial_grid_;
|
SpatialGrid spatial_grid_;
|
||||||
|
|
||||||
|
// === Parámetros ajustables en runtime (inicializados con valores de defines.h) ===
|
||||||
|
// Permite modificar comportamiento sin recompilar (para tweaking/debug visual)
|
||||||
|
float separation_radius_; // Radio de separación (evitar colisiones)
|
||||||
|
float alignment_radius_; // Radio de alineación (matching de velocidad)
|
||||||
|
float cohesion_radius_; // Radio de cohesión (centro de masa)
|
||||||
|
float separation_weight_; // Peso fuerza de separación (aceleración px/s²)
|
||||||
|
float alignment_weight_; // Peso fuerza de alineación (steering proporcional)
|
||||||
|
float cohesion_weight_; // Peso fuerza de cohesión (aceleración px/s²)
|
||||||
|
float max_speed_; // Velocidad máxima (px/s)
|
||||||
|
float min_speed_; // Velocidad mínima (px/s)
|
||||||
|
float max_force_; // Fuerza máxima de steering (px/s)
|
||||||
|
float boundary_margin_; // Margen para repulsión de bordes (px)
|
||||||
|
float boundary_weight_; // Peso fuerza de repulsión de bordes (aceleración px/s²)
|
||||||
|
|
||||||
// Métodos privados para las reglas de Reynolds
|
// Métodos privados para las reglas de Reynolds
|
||||||
void applySeparation(Ball* boid, float delta_time);
|
void applySeparation(Ball* boid, float delta_time);
|
||||||
void applyAlignment(Ball* boid, float delta_time);
|
void applyAlignment(Ball* boid, float delta_time);
|
||||||
void applyCohesion(Ball* boid, float delta_time);
|
void applyCohesion(Ball* boid, float delta_time);
|
||||||
void applyBoundaries(Ball* boid); // Mantener boids dentro de pantalla
|
void applyBoundaries(Ball* boid); // Repulsión de bordes (ya no wrapping)
|
||||||
void limitSpeed(Ball* boid); // Limitar velocidad máxima
|
void limitSpeed(Ball* boid); // Limitar velocidad máxima
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -304,6 +304,8 @@ constexpr float BOID_COHESION_WEIGHT = 3.6f; // Aceleración de cohesió
|
|||||||
constexpr float BOID_MAX_SPEED = 150.0f; // Velocidad máxima (px/s) [era 2.5 × 60]
|
constexpr float BOID_MAX_SPEED = 150.0f; // Velocidad máxima (px/s) [era 2.5 × 60]
|
||||||
constexpr float BOID_MAX_FORCE = 3.0f; // Fuerza máxima de steering (px/s) [era 0.05 × 60]
|
constexpr float BOID_MAX_FORCE = 3.0f; // Fuerza máxima de steering (px/s) [era 0.05 × 60]
|
||||||
constexpr float BOID_MIN_SPEED = 18.0f; // Velocidad mínima (px/s) [era 0.3 × 60]
|
constexpr float BOID_MIN_SPEED = 18.0f; // Velocidad mínima (px/s) [era 0.3 × 60]
|
||||||
|
constexpr float BOID_BOUNDARY_MARGIN = 50.0f; // Distancia a borde para activar repulsión (píxeles)
|
||||||
|
constexpr float BOID_BOUNDARY_WEIGHT = 7200.0f; // Aceleración de repulsión de bordes (px/s²) [más fuerte que separation]
|
||||||
|
|
||||||
// FASE 2: Spatial Hash Grid para optimización O(n²) → O(n)
|
// FASE 2: Spatial Hash Grid para optimización O(n²) → O(n)
|
||||||
constexpr float BOID_GRID_CELL_SIZE = 100.0f; // Tamaño de celda del grid (píxeles)
|
constexpr float BOID_GRID_CELL_SIZE = 100.0f; // Tamaño de celda del grid (píxeles)
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ void Engine::handleGravityToggle() {
|
|||||||
// Si estamos en modo boids, salir a modo física CON GRAVEDAD OFF
|
// Si estamos en modo boids, salir a modo física CON GRAVEDAD OFF
|
||||||
// Según RULES.md: "BOIDS a PHYSICS: Pulsando la tecla G: Gravedad OFF"
|
// Según RULES.md: "BOIDS a PHYSICS: Pulsando la tecla G: Gravedad OFF"
|
||||||
if (current_mode_ == SimulationMode::BOIDS) {
|
if (current_mode_ == SimulationMode::BOIDS) {
|
||||||
toggleBoidsMode(); // Cambiar a PHYSICS (preserva inercia, gravedad ya está OFF desde activateBoids)
|
toggleBoidsMode(false); // Cambiar a PHYSICS sin activar gravedad (preserva inercia)
|
||||||
// NO llamar a forceBallsGravityOff() porque aplica impulsos que destruyen la inercia de BOIDS
|
// NO llamar a forceBallsGravityOff() porque aplica impulsos que destruyen la inercia de BOIDS
|
||||||
// La gravedad ya está desactivada por BoidManager::activateBoids() y se mantiene al salir
|
// La gravedad ya está desactivada por BoidManager::activateBoids() y se mantiene al salir
|
||||||
showNotificationForAction("Modo Física - Gravedad Off");
|
showNotificationForAction("Modo Física - Gravedad Off");
|
||||||
@@ -436,11 +436,11 @@ void Engine::toggleDepthZoom() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Boids (comportamiento de enjambre)
|
// Boids (comportamiento de enjambre)
|
||||||
void Engine::toggleBoidsMode() {
|
void Engine::toggleBoidsMode(bool force_gravity_on) {
|
||||||
if (current_mode_ == SimulationMode::BOIDS) {
|
if (current_mode_ == SimulationMode::BOIDS) {
|
||||||
// Salir del modo boids (velocidades ya son time-based, no requiere conversión)
|
// Salir del modo boids (velocidades ya son time-based, no requiere conversión)
|
||||||
current_mode_ = SimulationMode::PHYSICS;
|
current_mode_ = SimulationMode::PHYSICS;
|
||||||
boid_manager_->deactivateBoids(false); // NO activar gravedad (preservar momentum)
|
boid_manager_->deactivateBoids(force_gravity_on); // Pasar parámetro para control preciso
|
||||||
} else {
|
} else {
|
||||||
// Entrar al modo boids (desde PHYSICS o SHAPE)
|
// Entrar al modo boids (desde PHYSICS o SHAPE)
|
||||||
if (current_mode_ == SimulationMode::SHAPE) {
|
if (current_mode_ == SimulationMode::SHAPE) {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class Engine {
|
|||||||
void toggleDepthZoom();
|
void toggleDepthZoom();
|
||||||
|
|
||||||
// Boids (comportamiento de enjambre)
|
// Boids (comportamiento de enjambre)
|
||||||
void toggleBoidsMode();
|
void toggleBoidsMode(bool force_gravity_on = true);
|
||||||
|
|
||||||
// Temas de colores
|
// Temas de colores
|
||||||
void cycleTheme(bool forward);
|
void cycleTheme(bool forward);
|
||||||
|
|||||||
Reference in New Issue
Block a user