Browse Source

apply format

djeada 1 month ago
parent
commit
58c2fd7995

+ 9 - 18
app/core/game_engine.cpp

@@ -109,7 +109,8 @@
 #include <vector>
 
 GameEngine::GameEngine(QObject *parent)
-    : QObject(parent), m_selectedUnitsModel(new SelectedUnitsModel(this, this)) {
+    : QObject(parent),
+      m_selectedUnitsModel(new SelectedUnitsModel(this, this)) {
 
   Game::Systems::NationRegistry::instance().initializeDefaults();
   Game::Systems::TroopCountRegistry::instance().initialize();
@@ -297,30 +298,21 @@ GameEngine::~GameEngine() {
 
 void GameEngine::cleanupOpenGLResources() {
   qInfo() << "Cleaning up OpenGL resources...";
-  
-  // Check if we have a valid OpenGL context
-  // If not, skip OpenGL cleanup and just reset the pointers
-  // Qt will handle OpenGL resource cleanup when the context is destroyed
+
   QOpenGLContext *context = QOpenGLContext::currentContext();
   const bool hasValidContext = (context != nullptr);
-  
+
   if (!hasValidContext) {
     qInfo() << "No valid OpenGL context, skipping OpenGL cleanup";
   }
-  
-  // Shutdown renderer and all OpenGL-dependent resources
-  // Only call shutdown if we have a valid context
+
   if (m_renderer && hasValidContext) {
     m_renderer->shutdown();
     qInfo() << "Renderer shut down";
   }
-  
-  // Clear render passes that reference renderer resources
+
   m_passes.clear();
-  
-  // Reset all renderer-dependent unique_ptrs
-  // These will call destructors which may try to access OpenGL
-  // If no valid context, the destructors should be defensive
+
   m_ground.reset();
   m_terrain.reset();
   m_biome.reset();
@@ -332,11 +324,10 @@ void GameEngine::cleanupOpenGLResources() {
   m_plant.reset();
   m_pine.reset();
   m_firecamp.reset();
-  
-  // Reset renderer and resources
+
   m_renderer.reset();
   m_resources.reset();
-  
+
   qInfo() << "OpenGL resources cleaned up";
 }
 

+ 4 - 4
main.cpp

@@ -283,7 +283,7 @@ auto main(int argc, char *argv[]) -> int {
   engine = std::make_unique<QQmlApplicationEngine>();
   qInfo() << "Adding context properties...";
   engine->rootContext()->setContextProperty("language_manager",
-                                           language_manager.get());
+                                            language_manager.get());
   engine->rootContext()->setContextProperty("game", game_engine.get());
   qInfo() << "Adding import path...";
   engine->addImportPath("qrc:/StandardOfIron/ui/qml");
@@ -370,16 +370,16 @@ auto main(int argc, char *argv[]) -> int {
 
   // Explicitly destroy in correct order to prevent segfault
   qInfo() << "Shutting down...";
-  
+
   // Destroy QML engine first (destroys OpenGL context)
   engine.reset();
   qInfo() << "QML engine destroyed";
-  
+
   // Then destroy game engine
   // OpenGL cleanup in destructors will be skipped if no valid context
   game_engine.reset();
   qInfo() << "GameEngine destroyed";
-  
+
   // Finally destroy language manager
   language_manager.reset();
   qInfo() << "LanguageManager destroyed";

+ 4 - 4
render/draw_queue.h

@@ -23,7 +23,6 @@ class Shader;
 
 namespace Render::GL {
 
-// Sort key bit shift constants
 constexpr int k_sort_key_bucket_shift = 56;
 
 struct MeshCmd {
@@ -223,7 +222,8 @@ private:
       int histogram[BUCKETS] = {0};
 
       for (std::size_t i = 0; i < count; ++i) {
-        auto const bucket = static_cast<uint8_t>(m_sortKeys[i] >> k_sort_key_bucket_shift);
+        auto const bucket =
+            static_cast<uint8_t>(m_sortKeys[i] >> k_sort_key_bucket_shift);
         ++histogram[bucket];
       }
 
@@ -234,8 +234,8 @@ private:
       }
 
       for (std::size_t i = 0; i < count; ++i) {
-        auto const bucket =
-            static_cast<uint8_t>(m_sortKeys[m_sortIndices[i]] >> k_sort_key_bucket_shift);
+        auto const bucket = static_cast<uint8_t>(m_sortKeys[m_sortIndices[i]] >>
+                                                 k_sort_key_bucket_shift);
         m_tempIndices[offsets[bucket]++] = m_sortIndices[i];
       }
     }

+ 4 - 2
render/entity/archer_renderer.cpp

@@ -462,7 +462,8 @@ public:
     constexpr int k_shoulder_pteruge_count = 8;
     constexpr float k_shoulder_pteruge_divisor = 8.0F;
     for (int i = 0; i < k_shoulder_pteruge_count; ++i) {
-      float const angle = (i / k_shoulder_pteruge_divisor) * 2.0F * std::numbers::pi_v<float>;
+      float const angle =
+          (i / k_shoulder_pteruge_divisor) * 2.0F * std::numbers::pi_v<float>;
       draw_pteruge(angle, shoulder_pteruge_y, 0.14F);
     }
 
@@ -470,7 +471,8 @@ public:
     constexpr int k_waist_pteruge_count = 10;
     constexpr float k_waist_pteruge_divisor = 10.0F;
     for (int i = 0; i < k_waist_pteruge_count; ++i) {
-      float const angle = (i / k_waist_pteruge_divisor) * 2.0F * std::numbers::pi_v<float>;
+      float const angle =
+          (i / k_waist_pteruge_divisor) * 2.0F * std::numbers::pi_v<float>;
       draw_pteruge(angle, waist_pteruge_y, 0.18F);
     }
 

+ 1 - 3
render/entity/horse_renderer.cpp

@@ -28,15 +28,13 @@ namespace {
 
 constexpr float kPi = std::numbers::pi_v<float>;
 
-// Hash function bit shift constants
 constexpr int k_hash_shift_16 = 16;
 constexpr int k_hash_shift_15 = 15;
 constexpr uint32_t k_hash_mult_1 = 0x7Feb352dU;
 constexpr uint32_t k_hash_mult_2 = 0x846ca68bU;
 constexpr uint32_t k_hash_mask_24bit = 0xFFFFFF;
-constexpr float k_hash_divisor = 16777216.0F; // 0x1000000
+constexpr float k_hash_divisor = 16777216.0F;
 
-// Color conversion constants
 constexpr float k_rgb_max = 255.0F;
 constexpr int k_rgb_shift_red = 16;
 constexpr int k_rgb_shift_green = 8;

+ 6 - 4
render/entity/knight_renderer.cpp

@@ -697,7 +697,8 @@ private:
 
     constexpr int k_ring_segments = 12;
     for (int i = 0; i < k_ring_segments; ++i) {
-      float const a0 = (float)i / k_ring_segments * 2.0F * std::numbers::pi_v<float>;
+      float const a0 =
+          (float)i / k_ring_segments * 2.0F * std::numbers::pi_v<float>;
       float const a1 =
           (float)(i + 1) / k_ring_segments * 2.0F * std::numbers::pi_v<float>;
       QVector3D const p0(center.x() + radius * std::cos(a0),
@@ -750,9 +751,10 @@ private:
                                  const QVector3D &color) {
       constexpr int k_rotated_ring_segments = 16;
       for (int i = 0; i < k_rotated_ring_segments; ++i) {
-        float const a0 = (float)i / k_rotated_ring_segments * 2.0F * std::numbers::pi_v<float>;
-        float const a1 =
-            (float)(i + 1) / k_rotated_ring_segments * 2.0F * std::numbers::pi_v<float>;
+        float const a0 = (float)i / k_rotated_ring_segments * 2.0F *
+                         std::numbers::pi_v<float>;
+        float const a1 = (float)(i + 1) / k_rotated_ring_segments * 2.0F *
+                         std::numbers::pi_v<float>;
 
         QVector3D const v0 =
             QVector3D(radius * std::cos(a0), radius * std::sin(a0), 0.0F);

+ 8 - 5
render/geom/arrow.cpp

@@ -38,8 +38,9 @@ static auto createArrowMesh() -> GL::Mesh * {
       float y = std::sin(a) * shaft_radius;
       QVector3D n(x, y, 0.0F);
       n.normalize();
-      verts.push_back(
-          {{x, y, z}, {n.x(), n.y(), n.z()}, {float(i) / k_arrow_radial_segments, z}});
+      verts.push_back({{x, y, z},
+                       {n.x(), n.y(), n.z()},
+                       {float(i) / k_arrow_radial_segments, z}});
     }
   }
 
@@ -64,8 +65,9 @@ static auto createArrowMesh() -> GL::Mesh * {
     float y = std::sin(a) * shaft_radius * 1.4F;
     QVector3D n(x, y, 0.2F);
     n.normalize();
-    verts.push_back(
-        {{x, y, tip_startZ}, {n.x(), n.y(), n.z()}, {float(i) / k_arrow_radial_segments, 0.0F}});
+    verts.push_back({{x, y, tip_startZ},
+                     {n.x(), n.y(), n.z()},
+                     {float(i) / k_arrow_radial_segments, 0.0F}});
   }
 
   int apex_index = verts.size();
@@ -123,7 +125,8 @@ void renderArrows(Renderer *renderer, ResourceManager *resources,
     constexpr float k_arc_center_offset = 0.5F;
     float const vy = (arrow.end.y() - arrow.start.y()) / dist;
     float const pitch_deg =
-        -std::atan2(vy - (k_arc_height_multiplier * arrow.arcHeight * (arrow.t - k_arc_center_offset) / dist),
+        -std::atan2(vy - (k_arc_height_multiplier * arrow.arcHeight *
+                          (arrow.t - k_arc_center_offset) / dist),
                     1.0F) *
         k_rad_to_deg;
     model.rotate(pitch_deg, QVector3D(1, 0, 0));

+ 12 - 7
render/geom/patrol_flags.cpp

@@ -11,7 +11,6 @@
 
 namespace Render::GL {
 
-// Grid precision for position hashing
 constexpr float k_position_grid_precision = 10.0F;
 constexpr int k_position_hash_shift = 32;
 
@@ -36,10 +35,13 @@ void renderPatrolFlags(Renderer *renderer, ResourceManager *resources,
     renderer->mesh(resources->unit(), flag.finial, flag.pennantColor,
                    resources->white(), 0.8F);
 
-    auto const grid_x = static_cast<int32_t>(preview_waypoint->x() * k_position_grid_precision);
-    auto const grid_z = static_cast<int32_t>(preview_waypoint->z() * k_position_grid_precision);
+    auto const grid_x =
+        static_cast<int32_t>(preview_waypoint->x() * k_position_grid_precision);
+    auto const grid_z =
+        static_cast<int32_t>(preview_waypoint->z() * k_position_grid_precision);
     uint64_t const pos_hash =
-        (static_cast<uint64_t>(grid_x) << k_position_hash_shift) | static_cast<uint64_t>(grid_z);
+        (static_cast<uint64_t>(grid_x) << k_position_hash_shift) |
+        static_cast<uint64_t>(grid_z);
     rendered_positions.insert(pos_hash);
   }
 
@@ -59,10 +61,13 @@ void renderPatrolFlags(Renderer *renderer, ResourceManager *resources,
 
     for (const auto &waypoint : patrol->waypoints) {
 
-      auto const grid_x = static_cast<int32_t>(waypoint.first * k_position_grid_precision);
-      auto const grid_z = static_cast<int32_t>(waypoint.second * k_position_grid_precision);
+      auto const grid_x =
+          static_cast<int32_t>(waypoint.first * k_position_grid_precision);
+      auto const grid_z =
+          static_cast<int32_t>(waypoint.second * k_position_grid_precision);
       uint64_t const pos_hash =
-          (static_cast<uint64_t>(grid_x) << k_position_hash_shift) | static_cast<uint64_t>(grid_z);
+          (static_cast<uint64_t>(grid_x) << k_position_hash_shift) |
+          static_cast<uint64_t>(grid_z);
 
       if (!rendered_positions.insert(pos_hash).second) {
         continue;

+ 4 - 6
render/gl/backend.cpp

@@ -18,12 +18,12 @@
 #include "ground/stone_gpu.h"
 #include "mesh.h"
 #include "render_constants.h"
-#include <QOpenGLContext>
 #include "shader.h"
 #include "state_scopes.h"
 #include "texture.h"
 #include <GL/gl.h>
 #include <QDebug>
+#include <QOpenGLContext>
 #include <cmath>
 #include <cstddef>
 #include <memory>
@@ -47,11 +47,9 @@ const QVector3D k_grid_line_color(0.22F, 0.25F, 0.22F);
 Backend::Backend() = default;
 
 Backend::~Backend() {
-  // Manually destroy pipelines before base class destructor runs
-  // This prevents access to base class OpenGL functions after context is destroyed
+
   if (QOpenGLContext::currentContext() == nullptr) {
-    // No valid context - manually release the unique_ptrs without calling their destructors
-    // This is safe because the OS will reclaim all OpenGL resources when process exits
+
     (void)m_cylinderPipeline.release();
     (void)m_vegetationPipeline.release();
     (void)m_terrainPipeline.release();
@@ -59,7 +57,7 @@ Backend::~Backend() {
     (void)m_waterPipeline.release();
     (void)m_effectsPipeline.release();
   } else {
-    // Valid context - normal cleanup
+
     m_cylinderPipeline.reset();
     m_vegetationPipeline.reset();
     m_terrainPipeline.reset();

+ 4 - 6
render/gl/backend/cylinder_pipeline.cpp

@@ -171,10 +171,9 @@ void CylinderPipeline::initializeCylinderPipeline() {
 }
 
 void CylinderPipeline::shutdownCylinderPipeline() {
-  // Check if we have a valid OpenGL context before cleanup
-  // If not, skip OpenGL calls - resources will be freed by Qt/OS
+
   if (QOpenGLContext::currentContext() == nullptr) {
-    // No valid context, just reset state without OpenGL calls
+
     m_cylinderVao = 0;
     m_cylinderVertexBuffer = 0;
     m_cylinderIndexBuffer = 0;
@@ -338,10 +337,9 @@ void CylinderPipeline::initializeFogPipeline() {
 }
 
 void CylinderPipeline::shutdownFogPipeline() {
-  // Check if we have a valid OpenGL context before cleanup
-  // If not, skip OpenGL calls - resources will be freed by Qt/OS
+
   if (QOpenGLContext::currentContext() == nullptr) {
-    // No valid context, just reset state without OpenGL calls
+
     m_fogVao = 0;
     m_fogVertexBuffer = 0;
     m_fogIndexBuffer = 0;

+ 4 - 4
render/gl/backend/vegetation_pipeline.cpp

@@ -188,7 +188,7 @@ void VegetationPipeline::initializeStonePipeline() {
 }
 
 void VegetationPipeline::shutdownStonePipeline() {
-  // Check if we have a valid OpenGL context before cleanup
+
   if (QOpenGLContext::currentContext() == nullptr) {
     m_stoneVao = 0;
     m_stoneVertexBuffer = 0;
@@ -292,7 +292,7 @@ void VegetationPipeline::initializePlantPipeline() {
 }
 
 void VegetationPipeline::shutdownPlantPipeline() {
-  // Check if we have a valid OpenGL context before cleanup
+
   if (QOpenGLContext::currentContext() == nullptr) {
     m_plantVao = 0;
     m_plantVertexBuffer = 0;
@@ -451,7 +451,7 @@ void VegetationPipeline::initializePinePipeline() {
 }
 
 void VegetationPipeline::shutdownPinePipeline() {
-  // Check if we have a valid OpenGL context before cleanup
+
   if (QOpenGLContext::currentContext() == nullptr) {
     m_pineVao = 0;
     m_pineVertexBuffer = 0;
@@ -556,7 +556,7 @@ void VegetationPipeline::initializeFireCampPipeline() {
 }
 
 void VegetationPipeline::shutdownFireCampPipeline() {
-  // Check if we have a valid OpenGL context before cleanup
+
   if (QOpenGLContext::currentContext() == nullptr) {
     m_firecampVao = 0;
     m_firecampVertexBuffer = 0;

+ 9 - 10
render/gl/camera.cpp

@@ -27,17 +27,14 @@ constexpr float k_min_margin_percent = 0.03F;
 constexpr float k_max_margin_percent = 0.10F;
 constexpr float k_boundary_smoothness = 0.3F;
 
-// Camera height reference values
 constexpr float k_reference_height = 50.0F;
 constexpr float k_height_factor_min = 0.5F;
 constexpr float k_height_factor_max = 2.0F;
 
-// Pitch angle constants
 constexpr float k_max_pitch_angle = 90.0F;
 constexpr float k_pitch_factor_min = 0.5F;
 constexpr float k_pitch_factor_max = 1.5F;
 
-// Zoom and scale constants
 constexpr float k_max_ortho_scale = 20.0F;
 constexpr float k_min_ortho_scale = 0.05F;
 constexpr float k_zoom_delta_multiplier = 0.1F;
@@ -45,12 +42,10 @@ constexpr float k_zoom_distance_delta = 0.15F;
 constexpr float k_zoom_factor_min = 0.1F;
 constexpr float k_zoom_factor_max = 10.0F;
 
-// NDC and screen space constants
 constexpr double k_ndc_scale = 2.0;
 constexpr double k_ndc_offset = 1.0;
 constexpr double k_ndc_half = 0.5;
 
-// Boundary adjustment smoothness
 constexpr float k_boundary_panning_smoothness = 0.7F;
 
 inline auto finite(const QVector3D &v) -> bool {
@@ -109,8 +104,9 @@ inline void clampOrthoBox(float &left, float &right, float &bottom,
 inline auto calculateDynamicMargin(float baseMargin, float camera_height,
                                    float pitch_deg) -> float {
 
-  float const height_factor = std::clamp(camera_height / k_reference_height,
-                                         k_height_factor_min, k_height_factor_max);
+  float const height_factor =
+      std::clamp(camera_height / k_reference_height, k_height_factor_min,
+                 k_height_factor_max);
 
   float const pitch_factor =
       std::clamp(1.0F - std::abs(pitch_deg) / k_max_pitch_angle,
@@ -474,7 +470,8 @@ auto Camera::worldToScreen(const QVector3D &world, qreal screenW, qreal screenH,
   }
 
   qreal const sx = (ndc.x() * k_ndc_half + k_ndc_half) * screenW;
-  qreal const sy = (k_ndc_offset - (ndc.y() * k_ndc_half + k_ndc_half)) * screenH;
+  qreal const sy =
+      (k_ndc_offset - (ndc.y() * k_ndc_half + k_ndc_half)) * screenH;
   outScreen = QPointF(sx, sy);
   return qIsFinite(sx) && qIsFinite(sy);
 }
@@ -689,11 +686,13 @@ void Camera::applySoftBoundaries(bool isPanning) {
 
   if (!position_adjustment.isNull()) {
     m_position +=
-        position_adjustment * (isPanning ? k_boundary_panning_smoothness : k_boundary_smoothness);
+        position_adjustment *
+        (isPanning ? k_boundary_panning_smoothness : k_boundary_smoothness);
   }
 
   if (!target_adjustment.isNull()) {
-    m_target += target_adjustment * (isPanning ? k_boundary_panning_smoothness : k_boundary_smoothness);
+    m_target += target_adjustment * (isPanning ? k_boundary_panning_smoothness
+                                               : k_boundary_smoothness);
 
     if (target_to_posDist > k_tiny) {
       QVector3D const dir = target_to_pos.normalized();

+ 0 - 1
render/gl/camera.h

@@ -6,7 +6,6 @@
 
 namespace Render::GL {
 
-// Camera default values
 namespace CameraDefaults {
 inline constexpr float k_default_rts_distance = 10.0F;
 inline constexpr float k_default_rts_angle = 45.0F;

+ 1 - 2
render/gl/persistent_buffer.h

@@ -88,9 +88,8 @@ public:
       return;
     }
 
-    // Check if we have a valid OpenGL context before cleanup
     if (QOpenGLContext::currentContext() == nullptr) {
-      // No valid context, just reset state without OpenGL calls
+
       m_buffer = 0;
       m_mappedPtr = nullptr;
       m_capacity = 0;

+ 2 - 1
render/gl/persistent_buffer_example.cpp

@@ -7,7 +7,8 @@ PersistentRingBuffer<CylinderInstanceGpu> m_cylinderPersistentBuffer;
 void Backend::initializeCylinderPipeline() {
   constexpr std::size_t k_initial_persistent_capacity = 10000;
   constexpr int k_buffers_in_flight = 3;
-  if (m_cylinderPersistentBuffer.initialize(k_initial_persistent_capacity, k_buffers_in_flight)) {
+  if (m_cylinderPersistentBuffer.initialize(k_initial_persistent_capacity,
+                                            k_buffers_in_flight)) {
   } else {
     qWarning()
         << "Failed to init persistent buffer, falling back to old method";

+ 4 - 3
render/ground/bridge_renderer.cpp

@@ -153,7 +153,8 @@ void BridgeRenderer::buildMeshes() {
       add_vertex(parapet_right_bottom, right_normal, tex_u1, texV);
 
       if (i < length_segments) {
-        auto const base_idx = static_cast<unsigned int>(i * k_vertices_per_bridge_segment);
+        auto const base_idx =
+            static_cast<unsigned int>(i * k_vertices_per_bridge_segment);
         unsigned int const next_idx = base_idx + k_vertices_per_bridge_segment;
 
         push_quad(base_idx + 0, base_idx + 1, next_idx + 1, next_idx + 0);
@@ -172,8 +173,8 @@ void BridgeRenderer::buildMeshes() {
 
     if (!vertices.empty()) {
       unsigned int const start_idx = 0;
-      auto const end_idx =
-          static_cast<unsigned int>(length_segments * k_vertices_per_bridge_segment);
+      auto const end_idx = static_cast<unsigned int>(
+          length_segments * k_vertices_per_bridge_segment);
 
       QVector3D const forward_normal = dir;
 

+ 6 - 6
render/ground/river_renderer.cpp

@@ -82,12 +82,12 @@ void RiverRenderer::buildMeshes() {
       constexpr float k_edge_noise_freq_2 = 5.0F;
       constexpr float k_edge_noise_freq_3 = 10.0F;
 
-      float const edge_noise1 =
-          noise(center_pos.x() * k_edge_noise_freq_1, center_pos.z() * k_edge_noise_freq_1);
-      float const edge_noise2 =
-          noise(center_pos.x() * k_edge_noise_freq_2, center_pos.z() * k_edge_noise_freq_2);
-      float const edge_noise3 =
-          noise(center_pos.x() * k_edge_noise_freq_3, center_pos.z() * k_edge_noise_freq_3);
+      float const edge_noise1 = noise(center_pos.x() * k_edge_noise_freq_1,
+                                      center_pos.z() * k_edge_noise_freq_1);
+      float const edge_noise2 = noise(center_pos.x() * k_edge_noise_freq_2,
+                                      center_pos.z() * k_edge_noise_freq_2);
+      float const edge_noise3 = noise(center_pos.x() * k_edge_noise_freq_3,
+                                      center_pos.z() * k_edge_noise_freq_3);
 
       float combined_noise =
           edge_noise1 * 0.5F + edge_noise2 * 0.3F + edge_noise3 * 0.2F;

+ 2 - 1
render/ground/riverbank_asset_renderer.cpp

@@ -168,7 +168,8 @@ void RiverbankAssetRenderer::generateAssetInstances() {
     int const num_steps = static_cast<int>(length / 0.8F) + 1;
 
     constexpr uint32_t k_rng_segment_multiplier = 1000;
-    uint32_t rng = m_noiseSeed + static_cast<uint32_t>(seg_idx * k_rng_segment_multiplier);
+    uint32_t rng =
+        m_noiseSeed + static_cast<uint32_t>(seg_idx * k_rng_segment_multiplier);
 
     for (int i = 0; i < num_steps; ++i) {
       float const t = static_cast<float>(i) /

+ 6 - 6
render/ground/riverbank_renderer.cpp

@@ -122,12 +122,12 @@ void RiverbankRenderer::buildMeshes() {
       constexpr float k_edge_noise_freq_2 = 5.0F;
       constexpr float k_edge_noise_freq_3 = 10.0F;
 
-      float const edge_noise1 =
-          noise(center_pos.x() * k_edge_noise_freq_1, center_pos.z() * k_edge_noise_freq_1);
-      float const edge_noise2 =
-          noise(center_pos.x() * k_edge_noise_freq_2, center_pos.z() * k_edge_noise_freq_2);
-      float const edge_noise3 =
-          noise(center_pos.x() * k_edge_noise_freq_3, center_pos.z() * k_edge_noise_freq_3);
+      float const edge_noise1 = noise(center_pos.x() * k_edge_noise_freq_1,
+                                      center_pos.z() * k_edge_noise_freq_1);
+      float const edge_noise2 = noise(center_pos.x() * k_edge_noise_freq_2,
+                                      center_pos.z() * k_edge_noise_freq_2);
+      float const edge_noise3 = noise(center_pos.x() * k_edge_noise_freq_3,
+                                      center_pos.z() * k_edge_noise_freq_3);
 
       float combined_noise =
           edge_noise1 * 0.5F + edge_noise2 * 0.3F + edge_noise3 * 0.2F;

+ 11 - 7
render/ground/terrain_renderer.cpp

@@ -354,13 +354,16 @@ void TerrainRenderer::buildMeshes() {
       constexpr int k_flip_shift = 7;
       constexpr int k_tint_shift = 12;
       constexpr int k_tint_variant_count = 7;
-      
+
       float const rotation_step =
-          static_cast<float>((variant_seed >> k_rotation_shift) & k_rotation_mask) * k_rotation_step_degrees;
+          static_cast<float>((variant_seed >> k_rotation_shift) &
+                             k_rotation_mask) *
+          k_rotation_step_degrees;
       bool const flip = ((variant_seed >> k_flip_shift) & 1U) != 0U;
-      static const float tint_variants[k_tint_variant_count] = {0.9F,  0.94F, 0.97F, 1.0F,
-                                             1.03F, 1.06F, 1.1F};
-      float const tint = tint_variants[(variant_seed >> k_tint_shift) % k_tint_variant_count];
+      static const float tint_variants[k_tint_variant_count] = {
+          0.9F, 0.94F, 0.97F, 1.0F, 1.03F, 1.06F, 1.1F};
+      float const tint =
+          tint_variants[(variant_seed >> k_tint_shift) % k_tint_variant_count];
 
       for (auto &section : sections) {
         section.rotationDeg = rotation_step;
@@ -659,8 +662,9 @@ void TerrainRenderer::buildMeshes() {
         const uint32_t noise_key_b =
             hash_coords(chunk.minX, chunk.minZ, m_noiseSeed ^ 0x68E31DA4U);
         constexpr float k_noise_offset_scale = 256.0F;
-        params.noiseOffset = QVector2D(hash_to_01(noise_key_a) * k_noise_offset_scale,
-                                       hash_to_01(noise_key_b) * k_noise_offset_scale);
+        params.noiseOffset =
+            QVector2D(hash_to_01(noise_key_a) * k_noise_offset_scale,
+                      hash_to_01(noise_key_b) * k_noise_offset_scale);
 
         float base_amp =
             m_biomeSettings.heightNoiseAmplitude *