minimap_utils_test.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "map/minimap/minimap_utils.h"
  2. #include <cmath>
  3. #include <gtest/gtest.h>
  4. using namespace Game::Map::Minimap;
  5. class MinimapUtilsTest : public ::testing::Test {
  6. protected:
  7. static constexpr float EPSILON = 0.001F;
  8. static constexpr float TILE_SIZE = 2.0F;
  9. void ExpectNearPair(const std::pair<float, float> &actual,
  10. const std::pair<float, float> &expected) {
  11. EXPECT_NEAR(actual.first, expected.first, EPSILON);
  12. EXPECT_NEAR(actual.second, expected.second, EPSILON);
  13. }
  14. };
  15. TEST_F(MinimapUtilsTest, PixelToWorldInversesWorldToPixel) {
  16. const float world_width = 100.0F; // Grid dimensions
  17. const float world_height = 100.0F;
  18. const float img_width = 256.0F;
  19. const float img_height = 256.0F;
  20. // Test various world coordinates (in actual world space)
  21. std::vector<std::pair<float, float>> test_coords = {
  22. {0.0F, 0.0F}, // Center
  23. {20.0F, 0.0F}, // Right (10 grid units * 2.0 tile_size)
  24. {-20.0F, 0.0F}, // Left
  25. {0.0F, 20.0F}, // Forward
  26. {0.0F, -20.0F}, // Back
  27. {40.0F, 40.0F}, // Diagonal
  28. {-30.0F, 60.0F}, // Mixed
  29. };
  30. for (const auto &[world_x, world_z] : test_coords) {
  31. // Convert world to grid for world_to_pixel
  32. const float grid_x = world_x / TILE_SIZE;
  33. const float grid_z = world_z / TILE_SIZE;
  34. // Convert grid to pixel
  35. auto [px, py] = world_to_pixel(grid_x, grid_z, world_width, world_height,
  36. img_width, img_height);
  37. // Convert back to world
  38. auto [result_x, result_z] = pixel_to_world(
  39. px, py, world_width, world_height, img_width, img_height, TILE_SIZE);
  40. // Should get back the original coordinates
  41. ExpectNearPair({result_x, result_z}, {world_x, world_z});
  42. }
  43. }
  44. TEST_F(MinimapUtilsTest, CenterPixelMapsToCenterWorld) {
  45. const float world_width = 100.0F;
  46. const float world_height = 100.0F;
  47. const float img_width = 256.0F;
  48. const float img_height = 256.0F;
  49. // Center of the image should map to (0, 0) world
  50. const float center_px = img_width / 2.0F;
  51. const float center_py = img_height / 2.0F;
  52. auto [world_x, world_z] =
  53. pixel_to_world(center_px, center_py, world_width, world_height, img_width,
  54. img_height, TILE_SIZE);
  55. ExpectNearPair({world_x, world_z}, {0.0F, 0.0F});
  56. }
  57. TEST_F(MinimapUtilsTest, CornerPixelsMapToExpectedWorldCoords) {
  58. const float world_width = 100.0F;
  59. const float world_height = 100.0F;
  60. const float img_width = 256.0F;
  61. const float img_height = 256.0F;
  62. // Top-left corner (0, 0) in pixels
  63. auto [tl_x, tl_z] = pixel_to_world(0.0F, 0.0F, world_width, world_height,
  64. img_width, img_height, TILE_SIZE);
  65. // Bottom-right corner in pixels
  66. auto [br_x, br_z] =
  67. pixel_to_world(img_width, img_height, world_width, world_height,
  68. img_width, img_height, TILE_SIZE);
  69. // The corners should be at the world bounds (with rotation applied)
  70. // Due to the rotation, we can't simply check against world_width/2
  71. // But the distance from center should be consistent
  72. const float tl_dist = std::sqrt(tl_x * tl_x + tl_z * tl_z);
  73. const float br_dist = std::sqrt(br_x * br_x + br_z * br_z);
  74. // Both corners should be approximately the same distance from center
  75. EXPECT_NEAR(tl_dist, br_dist, EPSILON);
  76. }
  77. TEST_F(MinimapUtilsTest, SquareMapSymmetry) {
  78. const float world_width = 100.0F;
  79. const float world_height = 100.0F;
  80. const float img_width = 256.0F;
  81. const float img_height = 256.0F;
  82. // For a square map, symmetric pixels should map to symmetric world coords
  83. const float quarter_x = img_width / 4.0F;
  84. const float quarter_y = img_height / 4.0F;
  85. const float three_quarter_x = 3.0F * img_width / 4.0F;
  86. const float three_quarter_y = 3.0F * img_height / 4.0F;
  87. auto [w1_x, w1_z] =
  88. pixel_to_world(quarter_x, quarter_y, world_width, world_height, img_width,
  89. img_height, TILE_SIZE);
  90. auto [w2_x, w2_z] =
  91. pixel_to_world(three_quarter_x, three_quarter_y, world_width,
  92. world_height, img_width, img_height, TILE_SIZE);
  93. // Due to rotation, the relationship is more complex, but we can verify
  94. // the conversion is consistent by checking the round-trip
  95. const float g1_x = w1_x / TILE_SIZE;
  96. const float g1_z = w1_z / TILE_SIZE;
  97. auto [p1_x, p1_y] = world_to_pixel(g1_x, g1_z, world_width, world_height,
  98. img_width, img_height);
  99. ExpectNearPair({p1_x, p1_y}, {quarter_x, quarter_y});
  100. const float g2_x = w2_x / TILE_SIZE;
  101. const float g2_z = w2_z / TILE_SIZE;
  102. auto [p2_x, p2_y] = world_to_pixel(g2_x, g2_z, world_width, world_height,
  103. img_width, img_height);
  104. ExpectNearPair({p2_x, p2_y}, {three_quarter_x, three_quarter_y});
  105. }
  106. TEST_F(MinimapUtilsTest, TileSizeScaling) {
  107. const float world_width = 50.0F; // 50 grid cells
  108. const float world_height = 50.0F;
  109. const float img_width = 128.0F;
  110. const float img_height = 128.0F;
  111. const float tile_size = 3.0F; // 3 world units per grid cell
  112. // Test a specific grid position
  113. const float grid_x = 10.0F; // 10 cells from center
  114. const float grid_z = 10.0F;
  115. const float expected_world_x = grid_x * tile_size; // 30 world units
  116. const float expected_world_z = grid_z * tile_size; // 30 world units
  117. // Convert grid to pixel
  118. auto [px, py] = world_to_pixel(grid_x, grid_z, world_width, world_height,
  119. img_width, img_height);
  120. // Convert pixel back to world with tile_size
  121. auto [world_x, world_z] = pixel_to_world(px, py, world_width, world_height,
  122. img_width, img_height, tile_size);
  123. // Should match expected world coordinates
  124. ExpectNearPair({world_x, world_z}, {expected_world_x, expected_world_z});
  125. }