LCOV - code coverage report
Current view: top level - rbc/shapes - Heightmap.hpp (source / functions) Coverage Total Hit
Test: coverage_clean.info Lines: 0.0 % 12 0
Test Date: 2026-03-30 03:13:12 Functions: 0.0 % 2 0

            Line data    Source code
       1              : #pragma once
       2              : #include <cstdint>
       3              : #include <cmath>
       4              : #include <limits>
       5              : #include <math3d/math3d.hpp>
       6              : #include "rbc/AABB.hpp"
       7              : 
       8              : namespace rbc
       9              : {
      10              :     // ── HeightmapData ─────────────────────────────────────────────────────────
      11              :     // Owns (or references) a row-major grid of height samples.
      12              :     // Vertex world position at grid index (row, col):
      13              :     //   pos.x = origin.x + col * scale.x
      14              :     //   pos.y = heights[row * cols + col] * scale.y
      15              :     //   pos.z = origin.z + row * scale.z
      16              :     //
      17              :     // Two triangles per cell (row,col) → (row+1,col+1):
      18              :     //   tri0: (r,c), (r,c+1), (r+1,c)
      19              :     //   tri1: (r,c+1), (r+1,c+1), (r+1,c)
      20              :     struct HeightmapData
      21              :     {
      22              :         const float *heights; // [rows × cols] height samples (Y before scale)
      23              :         uint32_t rows;
      24              :         uint32_t cols;
      25              :         m3d::vec3 scale;        // (cell_size_x, height_scale, cell_size_z)
      26              :         m3d::vec3 origin;       // world position of the (0,0) vertex
      27              :         m3d::scalar min_height; // precomputed: min(heights)*scale.y + origin.y
      28              :         m3d::scalar max_height; // precomputed: max(heights)*scale.y + origin.y
      29              :     };
      30              : 
      31              :     // ── Heightmap shape ───────────────────────────────────────────────────────
      32              :     // Holds a POINTER — HeightmapData must outlive the Heightmap.
      33              :     // The transform tf is intentionally ignored for heightmap queries;
      34              :     // world position is baked into HeightmapData::origin.
      35              :     struct Heightmap
      36              :     {
      37              :         const HeightmapData *data; // non-owning pointer
      38              : 
      39              :         Heightmap() : data(nullptr) {}
      40              :         explicit Heightmap(const HeightmapData *data) : data(data) {}
      41              : 
      42              :         inline bool operator==(const Heightmap &o) const { return data == o.data; }
      43              :         inline bool operator!=(const Heightmap &o) const { return data != o.data; }
      44              :     };
      45              : 
      46              :     // ── Construction helper ───────────────────────────────────────────────────
      47              :     // Creates a HeightmapData on the heap and precomputes min/max height.
      48              :     // Caller owns the returned pointer and must call heightmap_data_destroy().
      49              :     inline HeightmapData *heightmap_data_create(const float *heights,
      50              :                                                 uint32_t rows,
      51              :                                                 uint32_t cols,
      52              :                                                 const m3d::vec3 &scale,
      53              :                                                 const m3d::vec3 &origin)
      54              :     {
      55              :         auto *hd = new HeightmapData;
      56              :         hd->heights = heights;
      57              :         hd->rows = rows;
      58              :         hd->cols = cols;
      59              :         hd->scale = scale;
      60              :         hd->origin = origin;
      61              : 
      62              :         float mn = std::numeric_limits<float>::max();
      63              :         float mx = std::numeric_limits<float>::lowest();
      64              :         const uint32_t n = rows * cols;
      65              :         for (uint32_t i = 0; i < n; ++i)
      66              :         {
      67              :             mn = std::min(mn, heights[i]);
      68              :             mx = std::max(mx, heights[i]);
      69              :         }
      70              :         hd->min_height = static_cast<m3d::scalar>(mn) * scale.y + origin.y;
      71              :         hd->max_height = static_cast<m3d::scalar>(mx) * scale.y + origin.y;
      72              :         return hd;
      73              :     }
      74              : 
      75              :     inline void heightmap_data_destroy(HeightmapData *hd) { delete hd; }
      76              : 
      77              :     // ── World position of a grid vertex ──────────────────────────────────────
      78              :     inline m3d::vec3 heightmap_vertex(const HeightmapData &hd, uint32_t row, uint32_t col)
      79              :     {
      80              :         return m3d::vec3(
      81              :             hd.origin.x + static_cast<m3d::scalar>(col) * hd.scale.x,
      82              :             static_cast<m3d::scalar>(hd.heights[row * hd.cols + col]) * hd.scale.y + hd.origin.y,
      83              :             hd.origin.z + static_cast<m3d::scalar>(row) * hd.scale.z);
      84              :     }
      85              : 
      86              :     // ── Support (not meaningful for GJK — use analytic collisions) ───────────
      87            0 :     inline m3d::vec3 support(const Heightmap & /*h*/, const m3d::vec3 & /*dir*/)
      88              :     {
      89            0 :         return m3d::vec3(0.0, 0.0, 0.0); // placeholder; not used directly
      90              :     }
      91              : 
      92              :     // ── AABB from precomputed min/max height ──────────────────────────────────
      93            0 :     inline AABB compute_aabb(const Heightmap &h, const m3d::tf & /*tf*/)
      94              :     {
      95            0 :         if (!h.data)
      96            0 :             return AABB{};
      97            0 :         const HeightmapData &hd = *h.data;
      98              :         return {
      99            0 :             m3d::vec3(hd.origin.x,
     100            0 :                       hd.min_height,
     101            0 :                       hd.origin.z),
     102            0 :             m3d::vec3(hd.origin.x + static_cast<m3d::scalar>(hd.cols - 1) * hd.scale.x,
     103            0 :                       hd.max_height,
     104            0 :                       hd.origin.z + static_cast<m3d::scalar>(hd.rows - 1) * hd.scale.z)};
     105              :     }
     106              : } // namespace rbc
        

Generated by: LCOV version 2.0-1