Przeglądaj źródła

Merge pull request #368 from djeada/copilot/reduce-magic-numbers-render-dir

Reduce magic numbers in render/ directory
Adam Djellouli 1 miesiąc temu
rodzic
commit
f7459c1189

+ 5 - 2
render/draw_queue.h

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

+ 11 - 7
render/entity/archer_renderer.cpp

@@ -459,14 +459,18 @@ public:
     };
 
     float const shoulder_pteruge_y = y_top_cover - 0.02F;
-    for (int i = 0; i < 8; ++i) {
-      float const angle = (i / 8.0F) * 2.0F * std::numbers::pi_v<float>;
+    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>;
       draw_pteruge(angle, shoulder_pteruge_y, 0.14F);
     }
 
     float const waist_pteruge_y = waist_y - 0.04F;
-    for (int i = 0; i < 10; ++i) {
-      float const angle = (i / 10.0F) * 2.0F * std::numbers::pi_v<float>;
+    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>;
       draw_pteruge(angle, waist_pteruge_y, 0.18F);
     }
 
@@ -565,7 +569,7 @@ private:
         clampf(pose.hand_r.y(), extras.bowBotY + 0.05F, extras.bowTopY - 0.05F),
         clampf(pose.hand_r.z(), bow_plane_z - 0.30F, bow_plane_z + 0.30F));
 
-    const int segs = 22;
+    constexpr int k_bowstring_segments = 22;
     auto q_bezier = [](const QVector3D &a, const QVector3D &c,
                        const QVector3D &b, float t) {
       float const u = 1.0F - t;
@@ -580,8 +584,8 @@ private:
                          bow_plane_z + extras.bowDepth * 0.6F);
 
     QVector3D prev = bot_end;
-    for (int i = 1; i <= segs; ++i) {
-      float const t = float(i) / float(segs);
+    for (int i = 1; i <= k_bowstring_segments; ++i) {
+      float const t = float(i) / float(k_bowstring_segments);
       QVector3D const cur = q_bezier(bot_end, ctrl, top_end, t);
       out.mesh(getUnitCylinder(),
                cylinderBetween(ctx.model, prev, cur, extras.bowRodR),

+ 3 - 3
render/entity/arrow_vfx_renderer.cpp

@@ -328,7 +328,7 @@ static inline void drawBowAndArrow(const DrawContext &p, ISubmitter &out,
                  clampf(P.hand_r.y(), P.bowBotY + 0.05F, P.bowTopY - 0.05F),
                  clampf(P.hand_r.z(), grip.z() - 0.30F, grip.z() + 0.30F));
 
-  const int segs = 22;
+  constexpr int k_bow_curve_segments = 22;
   auto q_bezier = [](const QVector3D &a, const QVector3D &c, const QVector3D &b,
                      float t) {
     float u = 1.0F - t;
@@ -336,8 +336,8 @@ static inline void drawBowAndArrow(const DrawContext &p, ISubmitter &out,
   };
   QVector3D ctrl = nock + forward * P.bowDepth;
   QVector3D prev = bot_end;
-  for (int i = 1; i <= segs; ++i) {
-    float t = float(i) / float(segs);
+  for (int i = 1; i <= k_bow_curve_segments; ++i) {
+    float t = float(i) / float(k_bow_curve_segments);
     QVector3D cur = q_bezier(bot_end, ctrl, top_end, t);
     out.mesh(getUnitCylinder(), cylinderBetween(p.model, prev, cur, P.bowRodR),
              C.wood, nullptr, 1.0F);

+ 33 - 18
render/entity/horse_renderer.cpp

@@ -28,13 +28,26 @@ 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
+
+// Color conversion constants
+constexpr float k_rgb_max = 255.0F;
+constexpr int k_rgb_shift_red = 16;
+constexpr int k_rgb_shift_green = 8;
+
 inline auto hash01(uint32_t x) -> float {
-  x ^= x >> 16;
-  x *= 0x7Feb352dU;
-  x ^= x >> 15;
-  x *= 0x846ca68bU;
-  x ^= x >> 16;
-  return (x & 0xFFFFFF) / float(0x1000000);
+  x ^= x >> k_hash_shift_16;
+  x *= k_hash_mult_1;
+  x ^= x >> k_hash_shift_15;
+  x *= k_hash_mult_2;
+  x ^= x >> k_hash_shift_16;
+  return (x & k_hash_mask_24bit) / k_hash_divisor;
 }
 
 inline auto randBetween(uint32_t seed, uint32_t salt, float minV,
@@ -107,16 +120,16 @@ inline auto bezier(const QVector3D &p0, const QVector3D &p1,
 }
 
 inline auto colorHash(const QVector3D &c) -> uint32_t {
-  auto const r = uint32_t(saturate(c.x()) * 255.0F);
-  auto const g = uint32_t(saturate(c.y()) * 255.0F);
-  auto const b = uint32_t(saturate(c.z()) * 255.0F);
-  uint32_t v = (r << 16) | (g << 8) | b;
-
-  v ^= v >> 16;
-  v *= 0x7Feb352dU;
-  v ^= v >> 15;
-  v *= 0x846ca68bU;
-  v ^= v >> 16;
+  auto const r = uint32_t(saturate(c.x()) * k_rgb_max);
+  auto const g = uint32_t(saturate(c.y()) * k_rgb_max);
+  auto const b = uint32_t(saturate(c.z()) * k_rgb_max);
+  uint32_t v = (r << k_rgb_shift_red) | (g << k_rgb_shift_green) | b;
+
+  v ^= v >> k_hash_shift_16;
+  v *= k_hash_mult_1;
+  v ^= v >> k_hash_shift_15;
+  v *= k_hash_mult_2;
+  v ^= v >> k_hash_shift_16;
   return v;
 }
 
@@ -593,8 +606,10 @@ void HorseRenderer::render(const DrawContext &ctx, const AnimationInputs &anim,
 
   QVector3D const mane_root =
       neck_top + QVector3D(0.0F, d.headHeight * 0.20F, -d.headLength * 0.20F);
-  for (int i = 0; i < 12; ++i) {
-    float const t = i / 11.0F;
+  constexpr int k_mane_segments = 12;
+  constexpr float k_mane_segment_divisor = 11.0F;
+  for (int i = 0; i < k_mane_segments; ++i) {
+    float const t = i / k_mane_segment_divisor;
     QVector3D seg_start = lerp(mane_root, neck_base, t);
     seg_start.setY(seg_start.y() + (0.07F - t * 0.05F));
     float const sway =

+ 12 - 12
render/entity/knight_renderer.cpp

@@ -695,11 +695,11 @@ private:
                              float radius, float thickness,
                              const QVector3D &color, ISubmitter &out) {
 
-    const int segments = 12;
-    for (int i = 0; i < segments; ++i) {
-      float const a0 = (float)i / segments * 2.0F * std::numbers::pi_v<float>;
+    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 a1 =
-          (float)(i + 1) / segments * 2.0F * std::numbers::pi_v<float>;
+          (float)(i + 1) / k_ring_segments * 2.0F * std::numbers::pi_v<float>;
       QVector3D const p0(center.x() + radius * std::cos(a0),
                          center.y() + radius * std::sin(a0), center.z());
       QVector3D const p1(center.x() + radius * std::cos(a1),
@@ -716,9 +716,9 @@ private:
     const float scale_factor = 2.5F;
     const float R = extras.shieldRadius * scale_factor;
 
-    const float yaw_deg = -70.0F;
+    constexpr float k_shield_yaw_degrees = -70.0F;
     QMatrix4x4 rot;
-    rot.rotate(yaw_deg, 0.0F, 1.0F, 0.0F);
+    rot.rotate(k_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
 
     const QVector3D n = rot.map(QVector3D(0.0F, 0.0F, 1.0F));
     const QVector3D axis_x = rot.map(QVector3D(1.0F, 0.0F, 0.0F));
@@ -733,7 +733,7 @@ private:
     {
       QMatrix4x4 m = ctx.model;
       m.translate(shield_center + n * plate_half);
-      m.rotate(yaw_deg, 0.0F, 1.0F, 0.0F);
+      m.rotate(k_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
       m.scale(R, R, plate_full);
       out.mesh(getUnitCylinder(), m, extras.shieldColor, nullptr, 1.0F);
     }
@@ -741,18 +741,18 @@ private:
     {
       QMatrix4x4 m = ctx.model;
       m.translate(shield_center - n * plate_half);
-      m.rotate(yaw_deg, 0.0F, 1.0F, 0.0F);
+      m.rotate(k_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
       m.scale(R * 0.985F, R * 0.985F, plate_full);
       out.mesh(getUnitCylinder(), m, v.palette.leather * 0.8F, nullptr, 1.0F);
     }
 
     auto draw_ring_rotated = [&](float radius, float thickness,
                                  const QVector3D &color) {
-      const int segments = 16;
-      for (int i = 0; i < segments; ++i) {
-        float const a0 = (float)i / segments * 2.0F * std::numbers::pi_v<float>;
+      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) / segments * 2.0F * std::numbers::pi_v<float>;
+            (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);

+ 4 - 4
render/entity/mounted_knight_renderer.cpp

@@ -689,9 +689,9 @@ private:
     const float scale_factor = 2.0F;
     const float R = 0.15F * scale_factor;
 
-    const float yaw_deg = -70.0F;
+    constexpr float k_mounted_shield_yaw_degrees = -70.0F;
     QMatrix4x4 rot;
-    rot.rotate(yaw_deg, 0.0F, 1.0F, 0.0F);
+    rot.rotate(k_mounted_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
 
     const QVector3D n = rot.map(QVector3D(0.0F, 0.0F, 1.0F));
     const QVector3D axis_x = rot.map(QVector3D(1.0F, 0.0F, 0.0F));
@@ -706,7 +706,7 @@ private:
     {
       QMatrix4x4 m = ctx.model;
       m.translate(shield_center + n * plate_half);
-      m.rotate(yaw_deg, 0.0F, 1.0F, 0.0F);
+      m.rotate(k_mounted_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
       m.scale(R, R, plate_full);
       out.mesh(getUnitCylinder(), m, v.palette.cloth * 1.15F, nullptr, 1.0F);
     }
@@ -714,7 +714,7 @@ private:
     {
       QMatrix4x4 m = ctx.model;
       m.translate(shield_center - n * plate_half);
-      m.rotate(yaw_deg, 0.0F, 1.0F, 0.0F);
+      m.rotate(k_mounted_shield_yaw_degrees, 0.0F, 1.0F, 0.0F);
       m.scale(R * 0.985F, R * 0.985F, plate_full);
       out.mesh(getUnitCylinder(), m, v.palette.leather * 0.8F, nullptr, 1.0F);
     }

+ 19 - 17
render/geom/arrow.cpp

@@ -22,7 +22,7 @@ static auto createArrowMesh() -> GL::Mesh * {
   std::vector<GL::Vertex> verts;
   std::vector<unsigned int> idx;
 
-  const int radial = 12;
+  constexpr int k_arrow_radial_segments = 12;
   const float shaft_radius = 0.05F;
   const float shaft_len = 0.85F;
   const float tip_len = 0.15F;
@@ -32,23 +32,23 @@ static auto createArrowMesh() -> GL::Mesh * {
   int const base_index = 0;
   for (int ring = 0; ring < 2; ++ring) {
     float z = (ring == 0) ? 0.0F : shaft_len;
-    for (int i = 0; i < radial; ++i) {
-      float const a = (float(i) / radial) * 6.2831853F;
+    for (int i = 0; i < k_arrow_radial_segments; ++i) {
+      float const a = (float(i) / k_arrow_radial_segments) * 6.2831853F;
       float x = std::cos(a) * shaft_radius;
       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) / radial, z}});
+          {{x, y, z}, {n.x(), n.y(), n.z()}, {float(i) / k_arrow_radial_segments, z}});
     }
   }
 
-  for (int i = 0; i < radial; ++i) {
-    int const next = (i + 1) % radial;
+  for (int i = 0; i < k_arrow_radial_segments; ++i) {
+    int const next = (i + 1) % k_arrow_radial_segments;
     int a = base_index + i;
     int b = base_index + next;
-    int c = base_index + radial + next;
-    int d = base_index + radial + i;
+    int c = base_index + k_arrow_radial_segments + next;
+    int d = base_index + k_arrow_radial_segments + i;
     idx.push_back(a);
     idx.push_back(b);
     idx.push_back(c);
@@ -58,20 +58,20 @@ static auto createArrowMesh() -> GL::Mesh * {
   }
 
   int const ring_start = verts.size();
-  for (int i = 0; i < radial; ++i) {
-    float const a = (float(i) / radial) * 6.2831853F;
+  for (int i = 0; i < k_arrow_radial_segments; ++i) {
+    float const a = (float(i) / k_arrow_radial_segments) * 6.2831853F;
     float x = std::cos(a) * shaft_radius * 1.4F;
     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) / radial, 0.0F}});
+        {{x, y, tip_startZ}, {n.x(), n.y(), n.z()}, {float(i) / k_arrow_radial_segments, 0.0F}});
   }
 
   int apex_index = verts.size();
   verts.push_back({{0.0F, 0.0F, tip_end_z}, {0.0F, 0.0F, 1.0F}, {0.5F, 1.0F}});
-  for (int i = 0; i < radial; ++i) {
-    int const next = (i + 1) % radial;
+  for (int i = 0; i < k_arrow_radial_segments; ++i) {
+    int const next = (i + 1) % k_arrow_radial_segments;
     idx.push_back(ring_start + i);
     idx.push_back(apex_index);
     idx.push_back(ring_start + next);
@@ -114,16 +114,18 @@ void renderArrows(Renderer *renderer, ResourceManager *resources,
     QMatrix4x4 model;
     model.translate(pos.x(), pos.y(), pos.z());
 
+    constexpr float k_rad_to_deg = 180.0F / std::numbers::pi_v<float>;
     QVector3D const dir = delta.normalized();
-    float const yaw_deg =
-        std::atan2(dir.x(), dir.z()) * 180.0F / std::numbers::pi_v<float>;
+    float const yaw_deg = std::atan2(dir.x(), dir.z()) * k_rad_to_deg;
     model.rotate(yaw_deg, QVector3D(0, 1, 0));
 
+    constexpr float k_arc_height_multiplier = 8.0F;
+    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 - (8.0F * arrow.arcHeight * (arrow.t - 0.5F) / dist),
+        -std::atan2(vy - (k_arc_height_multiplier * arrow.arcHeight * (arrow.t - k_arc_center_offset) / dist),
                     1.0F) *
-        180.0F / std::numbers::pi_v<float>;
+        k_rad_to_deg;
     model.rotate(pitch_deg, QVector3D(1, 0, 0));
 
     constexpr float arrow_z_scale = 0.40F;

+ 10 - 6
render/geom/patrol_flags.cpp

@@ -11,6 +11,10 @@
 
 namespace Render::GL {
 
+// Grid precision for position hashing
+constexpr float k_position_grid_precision = 10.0F;
+constexpr int k_position_hash_shift = 32;
+
 void renderPatrolFlags(Renderer *renderer, ResourceManager *resources,
                        Engine::Core::World &world,
                        const std::optional<QVector3D> &preview_waypoint) {
@@ -32,10 +36,10 @@ 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() * 10.0F);
-    auto const grid_z = static_cast<int32_t>(preview_waypoint->z() * 10.0F);
+    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) << 32) | 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);
   }
 
@@ -55,10 +59,10 @@ void renderPatrolFlags(Renderer *renderer, ResourceManager *resources,
 
     for (const auto &waypoint : patrol->waypoints) {
 
-      auto const grid_x = static_cast<int32_t>(waypoint.first * 10.0F);
-      auto const grid_z = static_cast<int32_t>(waypoint.second * 10.0F);
+      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) << 32) | 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 - 4
render/geom/selection_disc.cpp

@@ -13,17 +13,17 @@ static auto createDiscMesh() -> Render::GL::Mesh * {
   using namespace Render::GL;
   std::vector<Vertex> verts;
   std::vector<unsigned int> idx;
-  const int seg = 72;
+  constexpr int k_disc_segments = 72;
 
   verts.push_back({{0.0F, 0.0F, 0.0F}, {0.0F, 1.0F, 0.0F}, {0.5F, 0.5F}});
-  for (int i = 0; i <= seg; ++i) {
-    float const a = (i / float(seg)) * 6.2831853F;
+  for (int i = 0; i <= k_disc_segments; ++i) {
+    float const a = (i / float(k_disc_segments)) * 6.2831853F;
     float x = std::cos(a);
     float z = std::sin(a);
     verts.push_back(
         {{x, 0.0F, z}, {0.0F, 1.0F, 0.0F}, {0.5F + 0.5F * x, 0.5F + 0.5F * z}});
   }
-  for (int i = 1; i <= seg; ++i) {
+  for (int i = 1; i <= k_disc_segments; ++i) {
     idx.push_back(0);
     idx.push_back(i);
     idx.push_back(i + 1);

+ 4 - 4
render/geom/selection_ring.cpp

@@ -15,12 +15,12 @@ static auto createRingMesh() -> Render::GL::Mesh * {
   using namespace Render::GL;
   std::vector<Vertex> verts;
   std::vector<unsigned int> idx;
-  const int seg = 48;
+  constexpr int k_ring_segments = 48;
   const float inner = 0.94F;
   const float outer = 1.0F;
-  for (int i = 0; i < seg; ++i) {
-    float const a0 = (i / float(seg)) * 6.2831853F;
-    float const a1 = ((i + 1) / float(seg)) * 6.2831853F;
+  for (int i = 0; i < k_ring_segments; ++i) {
+    float const a0 = (i / float(k_ring_segments)) * 6.2831853F;
+    float const a1 = ((i + 1) / float(k_ring_segments)) * 6.2831853F;
     QVector3D const n(0, 1, 0);
     QVector3D const v0i(inner * std::cos(a0), 0.0F, inner * std::sin(a0));
     QVector3D const v0o(outer * std::cos(a0), 0.0F, outer * std::sin(a0));

+ 3 - 2
render/geom/transforms.cpp

@@ -11,6 +11,7 @@ const QVector3D k_yaxis(0, 1, 0);
 const float k_rad_to_deg = 57.2957795131F;
 const float k_epsilon = 1e-6F;
 const float k_epsilonSq = k_epsilon * k_epsilon;
+constexpr float k_flip_rotation_degrees = 180.0F;
 } // namespace
 
 auto cylinderBetween(const QVector3D &a, const QVector3D &b,
@@ -44,7 +45,7 @@ auto cylinderBetween(const QVector3D &a, const QVector3D &b,
     if (axis_len_sq < k_epsilonSq) {
 
       if (dot < 0.0F) {
-        M.rotate(180.0F, 1.0F, 0.0F, 0.0F);
+        M.rotate(k_flip_rotation_degrees, 1.0F, 0.0F, 0.0F);
       }
     } else {
 
@@ -104,7 +105,7 @@ auto cylinderBetween(const QMatrix4x4 &parent, const QVector3D &a,
     if (axis_len_sq < k_epsilonSq) {
 
       if (dot < 0.0F) {
-        M.rotate(180.0F, 1.0F, 0.0F, 0.0F);
+        M.rotate(k_flip_rotation_degrees, 1.0F, 0.0F, 0.0F);
       }
     } else {
 

+ 3 - 3
render/gl/backend/cylinder_pipeline.cpp

@@ -114,8 +114,8 @@ void CylinderPipeline::initializeCylinderPipeline() {
                         GL_FALSE, sizeof(Vertex),
                         reinterpret_cast<void *>(offsetof(Vertex, tex_coord)));
 
-  const std::size_t persistent_capacity = 10000;
-  if (m_cylinderPersistentBuffer.initialize(persistent_capacity,
+  constexpr std::size_t k_cylinder_persistent_capacity = 10000;
+  if (m_cylinderPersistentBuffer.initialize(k_cylinder_persistent_capacity,
                                             BufferCapacity::BuffersInFlight)) {
     m_usePersistentBuffers = true;
     glBindBuffer(GL_ARRAY_BUFFER, m_cylinderPersistentBuffer.buffer());
@@ -165,7 +165,7 @@ void CylinderPipeline::initializeCylinderPipeline() {
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
   m_cylinderScratch.reserve(m_usePersistentBuffers
-                                ? persistent_capacity
+                                ? k_cylinder_persistent_capacity
                                 : m_cylinderInstanceCapacity);
 }
 

+ 6 - 3
render/gl/backend/vegetation_pipeline.cpp

@@ -164,7 +164,8 @@ void VegetationPipeline::initializeStonePipeline() {
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_stoneIndexBuffer);
   glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(stone_indices), stone_indices,
                GL_STATIC_DRAW);
-  m_stoneIndexCount = 36;
+  constexpr int k_stone_index_count = 36;
+  m_stoneIndexCount = k_stone_index_count;
 
   glEnableVertexAttribArray(Position);
   glVertexAttribPointer(
@@ -455,10 +456,12 @@ void VegetationPipeline::initializeFireCampPipeline() {
     QVector2D tex_coord;
   };
 
+  constexpr std::size_t k_firecamp_vertex_reserve = 12;
+  constexpr std::size_t k_firecamp_index_reserve = 18;
   std::vector<FireCampVertex> vertices;
-  vertices.reserve(12);
+  vertices.reserve(k_firecamp_vertex_reserve);
   std::vector<unsigned short> indices;
-  indices.reserve(18);
+  indices.reserve(k_firecamp_index_reserve);
 
   auto append_plane = [&](float planeIndex) {
     auto const base = static_cast<unsigned short>(vertices.size());

+ 45 - 17
render/gl/camera.cpp

@@ -27,6 +27,32 @@ 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;
+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 {
   return qIsFinite(v.x()) && qIsFinite(v.y()) && qIsFinite(v.z());
 }
@@ -83,10 +109,12 @@ 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 / 50.0F, 0.5F, 2.0F);
+  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) / 90.0F, 0.5F, 1.5F);
+      std::clamp(1.0F - std::abs(pitch_deg) / k_max_pitch_angle,
+                 k_pitch_factor_min, k_pitch_factor_max);
 
   return baseMargin * height_factor * pitch_factor;
 }
@@ -225,12 +253,12 @@ void Camera::zoom(float delta) {
   if (m_isPerspective) {
     m_fov = qBound(k_min_fov, m_fov - delta, k_max_fov);
   } else {
-    float scale = 1.0F + delta * 0.1F;
-    if (!finite(scale) || scale <= 0.05F) {
-      scale = 0.05F;
+    float scale = 1.0F + delta * k_zoom_delta_multiplier;
+    if (!finite(scale) || scale <= k_min_ortho_scale) {
+      scale = k_min_ortho_scale;
     }
-    if (scale > 20.0F) {
-      scale = 20.0F;
+    if (scale > k_max_ortho_scale) {
+      scale = k_max_ortho_scale;
     }
     m_orthoLeft *= scale;
     m_orthoRight *= scale;
@@ -251,11 +279,11 @@ void Camera::zoomDistance(float delta) {
     r = k_tiny;
   }
 
-  float factor = 1.0F - delta * 0.15F;
+  float factor = 1.0F - delta * k_zoom_distance_delta;
   if (!finite(factor)) {
     factor = 1.0F;
   }
-  factor = std::clamp(factor, 0.1F, 10.0F);
+  factor = std::clamp(factor, k_zoom_factor_min, k_zoom_factor_max);
 
   float const newR = std::clamp(r * factor, k_min_dist, k_max_dist);
   QVector3D const dir = safeNormalize(offset, QVector3D(0, 0, 1));
@@ -382,8 +410,8 @@ auto Camera::screenToGround(qreal sx, qreal sy, qreal screenW, qreal screenH,
     return false;
   }
 
-  double const x = (2.0 * sx / screenW) - 1.0;
-  double const y = 1.0 - (2.0 * sy / screenH);
+  double const x = (k_ndc_scale * sx / screenW) - k_ndc_offset;
+  double const y = k_ndc_offset - (k_ndc_scale * sy / screenH);
 
   bool ok = false;
   QMatrix4x4 const inv_vp =
@@ -445,8 +473,8 @@ auto Camera::worldToScreen(const QVector3D &world, qreal screenW, qreal screenH,
     return false;
   }
 
-  qreal const sx = (ndc.x() * 0.5 + 0.5) * screenW;
-  qreal const sy = (1.0 - (ndc.y() * 0.5 + 0.5)) * 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;
   outScreen = QPointF(sx, sy);
   return qIsFinite(sx) && qIsFinite(sy);
 }
@@ -601,10 +629,10 @@ void Camera::applySoftBoundaries(bool isPanning) {
   float const map_depth = map_max_z - map_min_z;
   float const base_margin_x =
       map_width * std::lerp(k_min_margin_percent, k_max_margin_percent,
-                            std::min(camera_height / 50.0F, 1.0F));
+                            std::min(camera_height / k_reference_height, 1.0F));
   float const base_margin_z =
       map_depth * std::lerp(k_min_margin_percent, k_max_margin_percent,
-                            std::min(camera_height / 50.0F, 1.0F));
+                            std::min(camera_height / k_reference_height, 1.0F));
 
   float const margin_x =
       calculateDynamicMargin(base_margin_x, camera_height, pitch_deg);
@@ -661,11 +689,11 @@ void Camera::applySoftBoundaries(bool isPanning) {
 
   if (!position_adjustment.isNull()) {
     m_position +=
-        position_adjustment * (isPanning ? 0.7F : k_boundary_smoothness);
+        position_adjustment * (isPanning ? k_boundary_panning_smoothness : k_boundary_smoothness);
   }
 
   if (!target_adjustment.isNull()) {
-    m_target += target_adjustment * (isPanning ? 0.7F : 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();

+ 26 - 11
render/gl/camera.h

@@ -6,6 +6,18 @@
 
 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;
+inline constexpr float k_default_rts_yaw = 45.0F;
+inline constexpr float k_default_fov = 45.0F;
+inline constexpr float k_default_aspect_ratio = 16.0F / 9.0F;
+inline constexpr float k_default_far_plane = 200.0F;
+inline constexpr float k_default_ortho_size = 10.0F;
+inline constexpr float k_default_pitch_min = -85.0F;
+} // namespace CameraDefaults
+
 class Camera {
   friend void solveConstraints(Render::GL::Camera *self, bool allowTargetShift);
 
@@ -50,9 +62,12 @@ public:
   void captureFollowOffset() { m_followOffset = m_position - m_target; }
   void updateFollow(const QVector3D &targetCenter);
 
-  void setRTSView(const QVector3D &center, float distance = 10.0F,
-                  float angle = 45.0F, float yaw_deg = 45.0F);
-  void setTopDownView(const QVector3D &center, float distance = 10.0F);
+  void setRTSView(const QVector3D &center,
+                  float distance = CameraDefaults::k_default_rts_distance,
+                  float angle = CameraDefaults::k_default_rts_angle,
+                  float yaw_deg = CameraDefaults::k_default_rts_yaw);
+  void setTopDownView(const QVector3D &center,
+                      float distance = CameraDefaults::k_default_rts_distance);
   void applySoftBoundaries(bool isPanning = false);
 
   [[nodiscard]] auto getViewMatrix() const -> QMatrix4x4;
@@ -89,16 +104,16 @@ private:
   QVector3D m_lastPosition;
 
   bool m_isPerspective = true;
-  float m_fov = 45.0F;
-  float m_aspect = 16.0F / 9.0F;
+  float m_fov = CameraDefaults::k_default_fov;
+  float m_aspect = CameraDefaults::k_default_aspect_ratio;
 
   float m_near_plane = 1.0F;
-  float m_far_plane = 200.0F;
+  float m_far_plane = CameraDefaults::k_default_far_plane;
 
-  float m_orthoLeft = -10.0F;
-  float m_orthoRight = 10.0F;
-  float m_orthoBottom = -10.0F;
-  float m_orthoTop = 10.0F;
+  float m_orthoLeft = -CameraDefaults::k_default_ortho_size;
+  float m_orthoRight = CameraDefaults::k_default_ortho_size;
+  float m_orthoBottom = -CameraDefaults::k_default_ortho_size;
+  float m_orthoTop = CameraDefaults::k_default_ortho_size;
 
   bool m_followEnabled = false;
   QVector3D m_followOffset{0, 0, 0};
@@ -107,7 +122,7 @@ private:
   float m_ground_y = 0.0F;
   float m_min_height = 0.5F;
 
-  float m_pitchMinDeg = -85.0F;
+  float m_pitchMinDeg = CameraDefaults::k_default_pitch_min;
   float m_pitchMaxDeg = -5.0F;
 
   bool m_orbitPending = false;

+ 3 - 3
render/gl/persistent_buffer_example.cpp

@@ -5,9 +5,9 @@
 PersistentRingBuffer<CylinderInstanceGpu> m_cylinderPersistentBuffer;
 
 void Backend::initializeCylinderPipeline() {
-
-  const std::size_t initialCapacity = 10000;
-  if (m_cylinderPersistentBuffer.initialize(initialCapacity, 3)) {
+  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)) {
   } else {
     qWarning()
         << "Failed to init persistent buffer, falling back to old method";

+ 4 - 4
render/ground/bridge_renderer.cpp

@@ -56,7 +56,7 @@ void BridgeRenderer::buildMeshes() {
     std::vector<Vertex> vertices;
     std::vector<unsigned int> indices;
 
-    const int verts_per_segment = 12;
+    constexpr int k_vertices_per_bridge_segment = 12;
     const float deck_thickness = std::clamp(bridge.width * 0.25F, 0.35F, 0.8F);
     const float parapet_height = std::clamp(bridge.width * 0.25F, 0.25F, 0.55F);
     const float parapet_offset = half_width * 1.05F;
@@ -153,8 +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 * verts_per_segment);
-        unsigned int const next_idx = base_idx + verts_per_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);
 
@@ -173,7 +173,7 @@ void BridgeRenderer::buildMeshes() {
     if (!vertices.empty()) {
       unsigned int const start_idx = 0;
       auto const end_idx =
-          static_cast<unsigned int>(length_segments * verts_per_segment);
+          static_cast<unsigned int>(length_segments * k_vertices_per_bridge_segment);
 
       QVector3D const forward_normal = dir;
 

+ 6 - 6
render/ground/river_renderer.cpp

@@ -78,16 +78,16 @@ void RiverRenderer::buildMeshes() {
           static_cast<float>(i) / static_cast<float>(length_steps - 1);
       QVector3D center_pos = segment.start + dir * (length * t);
 
-      float const noise_freq1 = 2.0F;
-      float const noise_freq2 = 5.0F;
-      float const noise_freq3 = 10.0F;
+      constexpr float k_edge_noise_freq_1 = 2.0F;
+      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() * noise_freq1, center_pos.z() * noise_freq1);
+          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() * noise_freq2, center_pos.z() * noise_freq2);
+          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() * noise_freq3, center_pos.z() * noise_freq3);
+          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

@@ -167,7 +167,8 @@ void RiverbankAssetRenderer::generateAssetInstances() {
 
     int const num_steps = static_cast<int>(length / 0.8F) + 1;
 
-    uint32_t rng = m_noiseSeed + static_cast<uint32_t>(seg_idx * 1000);
+    constexpr uint32_t k_rng_segment_multiplier = 1000;
+    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

@@ -118,16 +118,16 @@ void RiverbankRenderer::buildMeshes() {
           static_cast<float>(i) / static_cast<float>(length_steps - 1);
       QVector3D center_pos = segment.start + dir * (length * t);
 
-      float const noise_freq1 = 2.0F;
-      float const noise_freq2 = 5.0F;
-      float const noise_freq3 = 10.0F;
+      constexpr float k_edge_noise_freq_1 = 2.0F;
+      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() * noise_freq1, center_pos.z() * noise_freq1);
+          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() * noise_freq2, center_pos.z() * noise_freq2);
+          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() * noise_freq3, center_pos.z() * noise_freq3);
+          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;

+ 14 - 6
render/ground/terrain_renderer.cpp

@@ -348,12 +348,19 @@ void TerrainRenderer::buildMeshes() {
 
       uint32_t const chunk_seed = hash_coords(chunk_x, chunk_z, m_noiseSeed);
       uint32_t const variant_seed = chunk_seed ^ k_golden_ratio;
+      constexpr int k_rotation_shift = 5;
+      constexpr int k_rotation_mask = 3;
+      constexpr float k_rotation_step_degrees = 90.0F;
+      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 >> 5) & 3) * 90.0F;
-      bool const flip = ((variant_seed >> 7) & 1U) != 0U;
-      static const float tint_variants[7] = {0.9F,  0.94F, 0.97F, 1.0F,
+          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 >> 12) % 7];
+      float const tint = tint_variants[(variant_seed >> k_tint_shift) % k_tint_variant_count];
 
       for (auto &section : sections) {
         section.rotationDeg = rotation_step;
@@ -651,8 +658,9 @@ void TerrainRenderer::buildMeshes() {
             hash_coords(chunk.minX, chunk.minZ, m_noiseSeed ^ 0xB5297A4DU);
         const uint32_t noise_key_b =
             hash_coords(chunk.minX, chunk.minZ, m_noiseSeed ^ 0x68E31DA4U);
-        params.noiseOffset = QVector2D(hash_to_01(noise_key_a) * 256.0F,
-                                       hash_to_01(noise_key_b) * 256.0F);
+        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);
 
         float base_amp =
             m_biomeSettings.heightNoiseAmplitude *

+ 3 - 3
render/humanoid_base.cpp

@@ -397,13 +397,13 @@ void HumanoidRendererBase::drawCommonBody(const DrawContext &ctx,
   const float heel_back_frac = 0.15F;
   const float ball_frac = 0.72F;
   const float toe_up_frac = 0.06F;
-  const float yaw_out_deg = 12.0F;
+  constexpr float k_foot_yaw_out_degrees = 12.0F;
   const float ankle_fwd_frac = 0.10F;
   const float ankle_up_frac = 0.50F;
   const float toe_splay_frac = 0.06F;
 
-  const QVector3D fwdL = rotY(FWD, -yaw_out_deg * DEG);
-  const QVector3D fwdR = rotY(FWD, +yaw_out_deg * DEG);
+  const QVector3D fwdL = rotY(FWD, -k_foot_yaw_out_degrees * DEG);
+  const QVector3D fwdR = rotY(FWD, +k_foot_yaw_out_degrees * DEG);
   const QVector3D right_l = rightOf(fwdL);
   const QVector3D right_r = rightOf(fwdR);
 

+ 2 - 1
render/scene_renderer.cpp

@@ -453,7 +453,8 @@ void Renderer::renderWorld(Engine::Core::World *world) {
         contact_base.translate(transform->position.x,
                                transform->position.y + 0.03F,
                                transform->position.z);
-        contact_base.rotate(-90.0F, 1.0F, 0.0F, 0.0F);
+        constexpr float k_contact_shadow_rotation = -90.0F;
+        contact_base.rotate(k_contact_shadow_rotation, 1.0F, 0.0F, 0.0F);
         float const footprint =
             std::max({transform->scale.x, transform->scale.z, 0.6F});