QuantizedValuesTests.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzNetworking/Utilities/QuantizedValues.h>
  9. #include <AzNetworking/Serialization/NetworkInputSerializer.h>
  10. #include <AzNetworking/Serialization/NetworkOutputSerializer.h>
  11. #include <AzCore/std/limits.h>
  12. #include <AzCore/UnitTest/TestTypes.h>
  13. namespace UnitTest
  14. {
  15. template <uint32_t NUM_ELEMENTS>
  16. struct ValueFromFloat {};
  17. template <>
  18. struct ValueFromFloat<1>
  19. {
  20. using ValueType = float;
  21. static float Construct(float value)
  22. {
  23. return value;
  24. }
  25. static void CheckEqual(ValueType a, ValueType b)
  26. {
  27. EXPECT_FLOAT_EQ(a, b);
  28. }
  29. };
  30. template <>
  31. struct ValueFromFloat<2>
  32. {
  33. using ValueType = AZ::Vector2;
  34. static AZ::Vector2 Construct(float value)
  35. {
  36. return AZ::Vector2(value, value);
  37. }
  38. static void CheckEqual(ValueType a, ValueType b)
  39. {
  40. EXPECT_TRUE(a.IsClose(b, 0.01f));
  41. }
  42. };
  43. template <>
  44. struct ValueFromFloat<3>
  45. {
  46. using ValueType = AZ::Vector3;
  47. static AZ::Vector3 Construct(float value)
  48. {
  49. return AZ::Vector3(value, value, value);
  50. }
  51. static void CheckEqual(ValueType a, ValueType b)
  52. {
  53. EXPECT_TRUE(a.IsClose(b, 0.01f));
  54. }
  55. };
  56. template <>
  57. struct ValueFromFloat<4>
  58. {
  59. using ValueType = AZ::Quaternion;
  60. static AZ::Quaternion Construct(float value)
  61. {
  62. return AZ::Quaternion(value, value, value, value);
  63. }
  64. static void CheckEqual(ValueType a, ValueType b)
  65. {
  66. EXPECT_TRUE(a.IsClose(b, 0.01f));
  67. }
  68. };
  69. template <uint32_t NUM_ELEMENTS, uint32_t NUM_BYTES>
  70. void TestQuantizedValuesHelper01()
  71. {
  72. AzNetworking::QuantizedValues<NUM_ELEMENTS, NUM_BYTES, 0, 1> testIn(ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f)), testOut; // Transmits float values between 0 and 1 using NUM_BYTES
  73. AZStd::array<uint8_t, 1024> buffer;
  74. AzNetworking::NetworkInputSerializer inputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  75. AzNetworking::NetworkOutputSerializer outputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  76. EXPECT_EQ(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f));
  77. testIn.Serialize(inputSerializer);
  78. EXPECT_EQ(inputSerializer.GetSize(), NUM_BYTES * NUM_ELEMENTS);
  79. testOut.Serialize(outputSerializer);
  80. EXPECT_EQ(testIn, testOut);
  81. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(1.0f);
  82. EXPECT_EQ(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(1.0f));
  83. testIn.Serialize(inputSerializer);
  84. EXPECT_NE(testIn, testOut);
  85. EXPECT_NE(testIn.GetQuantizedIntegralValues()[0], testOut.GetQuantizedIntegralValues()[0]);
  86. testOut.Serialize(outputSerializer);
  87. EXPECT_EQ(testIn, testOut);
  88. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(0.5f);
  89. EXPECT_EQ(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(0.5f));
  90. testIn.Serialize(inputSerializer);
  91. testOut.Serialize(outputSerializer);
  92. EXPECT_EQ(testIn, testOut);
  93. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-1.0f);
  94. EXPECT_NE(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-1.0f));
  95. EXPECT_EQ(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f));
  96. testIn.Serialize(inputSerializer);
  97. testOut.Serialize(outputSerializer);
  98. EXPECT_EQ(testIn, testOut);
  99. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(2.0f);
  100. EXPECT_NE(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(2.0f));
  101. EXPECT_EQ(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(1.0f));
  102. testIn.Serialize(inputSerializer);
  103. testOut.Serialize(outputSerializer);
  104. EXPECT_EQ(testIn, testOut);
  105. }
  106. template <uint32_t NUM_ELEMENTS, uint32_t NUM_BYTES>
  107. void TestQuantizedValuesHelper11()
  108. {
  109. AzNetworking::QuantizedValues<NUM_ELEMENTS, NUM_BYTES, -1, 1> testIn, testOut; // Transmits float values between -1.0 and 1.0 using NUM_BYTES
  110. AZStd::array<uint8_t, 1024> buffer;
  111. AzNetworking::NetworkInputSerializer inputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  112. AzNetworking::NetworkOutputSerializer outputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  113. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-1.0f);
  114. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-1.0f));
  115. testIn.Serialize(inputSerializer);
  116. EXPECT_EQ(inputSerializer.GetSize(), NUM_BYTES * NUM_ELEMENTS);
  117. testOut.Serialize(outputSerializer);
  118. EXPECT_EQ(testIn, testOut);
  119. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(1.0f);
  120. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(1.0f));
  121. testIn.Serialize(inputSerializer);
  122. testOut.Serialize(outputSerializer);
  123. EXPECT_EQ(testIn, testOut);
  124. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f);
  125. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f));
  126. testIn.Serialize(inputSerializer);
  127. testOut.Serialize(outputSerializer);
  128. EXPECT_EQ(testIn, testOut);
  129. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-2.0f);
  130. EXPECT_NE(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-2.0f));
  131. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-1.0f));
  132. testIn.Serialize(inputSerializer);
  133. testOut.Serialize(outputSerializer);
  134. EXPECT_EQ(testIn, testOut);
  135. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(2.0f);
  136. EXPECT_NE(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(2.0f));
  137. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(1.0f));
  138. testIn.Serialize(inputSerializer);
  139. testOut.Serialize(outputSerializer);
  140. EXPECT_EQ(testIn, testOut);
  141. }
  142. template <uint32_t NUM_ELEMENTS, uint32_t NUM_BYTES>
  143. void TestQuantizedValuesHelper16k()
  144. {
  145. AzNetworking::QuantizedValues<NUM_ELEMENTS, NUM_BYTES, -16384, 16384> testIn, testOut; // Transmits float values between -1.0 and 1.0 using NUM_BYTES
  146. AZStd::array<uint8_t, 1024> buffer;
  147. AzNetworking::NetworkInputSerializer inputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  148. AzNetworking::NetworkOutputSerializer outputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  149. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-2000.0f);
  150. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-2000.0f));
  151. testIn.Serialize(inputSerializer);
  152. EXPECT_EQ(inputSerializer.GetSize(), NUM_BYTES * NUM_ELEMENTS);
  153. testOut.Serialize(outputSerializer);
  154. EXPECT_EQ(testIn, testOut);
  155. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(2000.0f);
  156. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(2000.0f));
  157. testIn.Serialize(inputSerializer);
  158. testOut.Serialize(outputSerializer);
  159. EXPECT_EQ(testIn, testOut);
  160. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f);
  161. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f));
  162. testIn.Serialize(inputSerializer);
  163. testOut.Serialize(outputSerializer);
  164. EXPECT_EQ(testIn, testOut);
  165. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-16385.0f);
  166. EXPECT_NE(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-16385.0f));
  167. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-16384.0f));
  168. testIn.Serialize(inputSerializer);
  169. testOut.Serialize(outputSerializer);
  170. EXPECT_EQ(testIn, testOut);
  171. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(16385.0f);
  172. EXPECT_NE(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(16385.0f));
  173. EXPECT_EQ(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(16384.0f));
  174. testIn.Serialize(inputSerializer);
  175. testOut.Serialize(outputSerializer);
  176. EXPECT_EQ(testIn, testOut);
  177. }
  178. template <uint32_t NUM_ELEMENTS, uint32_t NUM_BYTES>
  179. void TestQuantizedValuesHelper24bitRange()
  180. {
  181. // This gives us a hash sensitivity of around 1/128th of a unit, and will detect errors within a range of -16,777,216 to +16,777,216
  182. static constexpr int32_t FloatHashMinValue = (AZStd::numeric_limits<int>::min() >> 7);
  183. static constexpr int32_t FloatHashMaxValue = (AZStd::numeric_limits<int>::max() >> 7);
  184. AzNetworking::QuantizedValues<NUM_ELEMENTS, NUM_BYTES, FloatHashMinValue, FloatHashMaxValue> testIn, testOut;
  185. AZStd::array<uint8_t, 1024> buffer;
  186. AzNetworking::NetworkInputSerializer inputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  187. AzNetworking::NetworkOutputSerializer outputSerializer(buffer.data(), static_cast<uint32_t>(buffer.size()));
  188. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-20000.0f);
  189. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-20000.0f));
  190. testIn.Serialize(inputSerializer);
  191. EXPECT_EQ(inputSerializer.GetSize(), NUM_BYTES * NUM_ELEMENTS);
  192. testOut.Serialize(outputSerializer);
  193. EXPECT_EQ(testIn, testOut);
  194. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(20000.0f);
  195. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(20000.0f));
  196. testIn.Serialize(inputSerializer);
  197. testOut.Serialize(outputSerializer);
  198. EXPECT_EQ(testIn, testOut);
  199. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f);
  200. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(0.0f));
  201. testIn.Serialize(inputSerializer);
  202. testOut.Serialize(outputSerializer);
  203. EXPECT_EQ(testIn, testOut);
  204. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(-163850.0f);
  205. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(-163850.0f));
  206. testIn.Serialize(inputSerializer);
  207. testOut.Serialize(outputSerializer);
  208. EXPECT_EQ(testIn, testOut);
  209. testIn = ValueFromFloat<NUM_ELEMENTS>::Construct(163850.0f);
  210. ValueFromFloat<NUM_ELEMENTS>::CheckEqual(static_cast<typename ValueFromFloat<NUM_ELEMENTS>::ValueType>(testIn), ValueFromFloat<NUM_ELEMENTS>::Construct(163850.0f));
  211. testIn.Serialize(inputSerializer);
  212. testOut.Serialize(outputSerializer);
  213. EXPECT_EQ(testIn, testOut);
  214. }
  215. TEST(QuantizedValues, Test1Elements1Bytes)
  216. {
  217. TestQuantizedValuesHelper01<1, 1>();
  218. TestQuantizedValuesHelper11<1, 1>();
  219. }
  220. TEST(QuantizedValues, Test2Elements1Bytes)
  221. {
  222. TestQuantizedValuesHelper01<2, 1>();
  223. TestQuantizedValuesHelper11<2, 1>();
  224. }
  225. TEST(QuantizedValues, Test3Elements1Bytes)
  226. {
  227. TestQuantizedValuesHelper01<3, 1>();
  228. TestQuantizedValuesHelper11<3, 1>();
  229. }
  230. TEST(QuantizedValues, Test4Elements1Bytes)
  231. {
  232. TestQuantizedValuesHelper01<4, 1>();
  233. TestQuantizedValuesHelper11<4, 1>();
  234. }
  235. TEST(QuantizedValues, Test1Elements2Bytes)
  236. {
  237. TestQuantizedValuesHelper01<1, 2>();
  238. TestQuantizedValuesHelper11<1, 2>();
  239. }
  240. TEST(QuantizedValues, Test2Elements2Bytes)
  241. {
  242. TestQuantizedValuesHelper01<2, 2>();
  243. TestQuantizedValuesHelper11<2, 2>();
  244. }
  245. TEST(QuantizedValues, Test3Elements2Bytes)
  246. {
  247. TestQuantizedValuesHelper01<3, 2>();
  248. TestQuantizedValuesHelper11<3, 2>();
  249. }
  250. TEST(QuantizedValues, Test4Elements2Bytes)
  251. {
  252. TestQuantizedValuesHelper01<4, 2>();
  253. TestQuantizedValuesHelper11<4, 2>();
  254. }
  255. TEST(QuantizedValues, Test1Elements3Bytes)
  256. {
  257. TestQuantizedValuesHelper01 <1, 3>();
  258. TestQuantizedValuesHelper11 <1, 3>();
  259. TestQuantizedValuesHelper16k<1, 3>();
  260. }
  261. TEST(QuantizedValues, Test2Elements3Bytes)
  262. {
  263. TestQuantizedValuesHelper01 <2, 3>();
  264. TestQuantizedValuesHelper11 <2, 3>();
  265. TestQuantizedValuesHelper16k<2, 3>();
  266. }
  267. TEST(QuantizedValues, Test3Elements3Bytes)
  268. {
  269. TestQuantizedValuesHelper01 <3, 3>();
  270. TestQuantizedValuesHelper11 <3, 3>();
  271. TestQuantizedValuesHelper16k<3, 3>();
  272. }
  273. TEST(QuantizedValues, Test4Elements3Bytes)
  274. {
  275. TestQuantizedValuesHelper01 <4, 3>();
  276. TestQuantizedValuesHelper11 <4, 3>();
  277. TestQuantizedValuesHelper16k<4, 3>();
  278. }
  279. TEST(QuantizedValues, Test1Elements4Bytes)
  280. {
  281. TestQuantizedValuesHelper01 <1, 4>();
  282. TestQuantizedValuesHelper11 <1, 4>();
  283. TestQuantizedValuesHelper16k<1, 4>();
  284. }
  285. TEST(QuantizedValues, Test2Elements4Bytes)
  286. {
  287. TestQuantizedValuesHelper01 <2, 4>();
  288. TestQuantizedValuesHelper11 <2, 4>();
  289. TestQuantizedValuesHelper16k<2, 4>();
  290. TestQuantizedValuesHelper24bitRange<2, 4>();
  291. }
  292. TEST(QuantizedValues, Test3Elements4Bytes)
  293. {
  294. TestQuantizedValuesHelper01 <3, 4>();
  295. TestQuantizedValuesHelper11 <3, 4>();
  296. TestQuantizedValuesHelper16k<3, 4>();
  297. TestQuantizedValuesHelper24bitRange<3, 4>();
  298. }
  299. TEST(QuantizedValues, Test4Elements4Bytes)
  300. {
  301. TestQuantizedValuesHelper01 <4, 4>();
  302. TestQuantizedValuesHelper11 <4, 4>();
  303. TestQuantizedValuesHelper16k<4, 4>();
  304. TestQuantizedValuesHelper24bitRange<4, 4>();
  305. }
  306. }