rider_proportions_test.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include "render/entity/registry.h"
  2. #include "render/humanoid/rig.h"
  3. #include <QVector3D>
  4. #include <cmath>
  5. #include <gtest/gtest.h>
  6. using namespace Render::GL;
  7. // Mock renderer classes for testing proportions
  8. namespace TestMocks {
  9. class RomanHorseSwordsmanRenderer : public HumanoidRendererBase {
  10. public:
  11. auto get_proportion_scaling() const -> QVector3D override {
  12. return {0.92F, 0.88F, 0.96F};
  13. }
  14. };
  15. class CarthageHorseSwordsmanRenderer : public HumanoidRendererBase {
  16. public:
  17. auto get_proportion_scaling() const -> QVector3D override {
  18. return {0.92F, 0.88F, 0.96F};
  19. }
  20. };
  21. } // namespace TestMocks
  22. class RiderProportionsTest : public ::testing::Test {
  23. protected:
  24. // Helper to check if a value is within a reasonable range
  25. bool inRange(float value, float min, float max) {
  26. return value >= min && value <= max;
  27. }
  28. // Helper to check approximate equality
  29. bool approxEqual(float a, float b, float epsilon = 0.01F) {
  30. return std::abs(a - b) < epsilon;
  31. }
  32. };
  33. TEST_F(RiderProportionsTest, KingdomRiderHasRealisticProportions) { SUCCEED(); }
  34. TEST_F(RiderProportionsTest, RomanRiderHasRealisticProportions) {
  35. TestMocks::RomanHorseSwordsmanRenderer renderer;
  36. QVector3D const proportions = renderer.get_proportion_scaling();
  37. // Expectations for realistic mounted proportions
  38. EXPECT_TRUE(inRange(proportions.x(), 0.9F, 1.1F))
  39. << "Width scale " << proportions.x() << " is outside realistic range";
  40. EXPECT_TRUE(inRange(proportions.y(), 0.85F, 0.98F))
  41. << "Height scale " << proportions.y() << " is outside realistic range";
  42. EXPECT_TRUE(inRange(proportions.z(), 0.9F, 1.1F))
  43. << "Depth scale " << proportions.z() << " is outside realistic range";
  44. }
  45. TEST_F(RiderProportionsTest, CarthageRiderHasRealisticProportions) {
  46. TestMocks::CarthageHorseSwordsmanRenderer renderer;
  47. QVector3D const proportions = renderer.get_proportion_scaling();
  48. // Same expectations as other nations
  49. EXPECT_TRUE(inRange(proportions.x(), 0.9F, 1.1F))
  50. << "Width scale " << proportions.x() << " is outside realistic range";
  51. EXPECT_TRUE(inRange(proportions.y(), 0.85F, 0.98F))
  52. << "Height scale " << proportions.y() << " is outside realistic range";
  53. EXPECT_TRUE(inRange(proportions.z(), 0.9F, 1.1F))
  54. << "Depth scale " << proportions.z() << " is outside realistic range";
  55. }
  56. TEST_F(RiderProportionsTest, AllNationsHaveConsistentProportions) {
  57. TestMocks::RomanHorseSwordsmanRenderer roman_renderer;
  58. TestMocks::CarthageHorseSwordsmanRenderer carthage_renderer;
  59. QVector3D const roman_props = roman_renderer.get_proportion_scaling();
  60. QVector3D const carthage_props = carthage_renderer.get_proportion_scaling();
  61. // All nations should have similar proportions (within 10%)
  62. EXPECT_TRUE(approxEqual(roman_props.x(), carthage_props.x(), 0.1F))
  63. << "Roman and Carthage width scales differ too much";
  64. EXPECT_TRUE(approxEqual(roman_props.y(), carthage_props.y(), 0.1F))
  65. << "Roman and Carthage height scales differ too much";
  66. EXPECT_TRUE(approxEqual(roman_props.z(), carthage_props.z(), 0.1F))
  67. << "Roman and Carthage depth scales differ too much";
  68. }
  69. TEST_F(RiderProportionsTest, ProportionsPreventOverlyElongatedLimbs) {
  70. TestMocks::RomanHorseSwordsmanRenderer renderer;
  71. QVector3D const proportions = renderer.get_proportion_scaling();
  72. // Width and height should be reasonably balanced
  73. // Aspect ratio should not be extreme (no dimension more than 2x another)
  74. float const width_height_ratio = proportions.x() / proportions.y();
  75. EXPECT_TRUE(inRange(width_height_ratio, 0.5F, 2.0F))
  76. << "Width/height ratio " << width_height_ratio << " is too extreme";
  77. float const depth_height_ratio = proportions.z() / proportions.y();
  78. EXPECT_TRUE(inRange(depth_height_ratio, 0.5F, 2.0F))
  79. << "Depth/height ratio " << depth_height_ratio << " is too extreme";
  80. // Height should not be drastically different from width/depth
  81. // This prevents the "stretched stick figure" appearance
  82. float const avg_lateral = (proportions.x() + proportions.z()) / 2.0F;
  83. float const height_vs_lateral = proportions.y() / avg_lateral;
  84. EXPECT_TRUE(inRange(height_vs_lateral, 0.7F, 1.3F))
  85. << "Height vs lateral proportion ratio " << height_vs_lateral
  86. << " is unbalanced";
  87. }