DeterminismLog.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // SPDX-FileCopyrightText: 2022 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. //#define JPH_ENABLE_DETERMINISM_LOG
  5. #ifdef JPH_ENABLE_DETERMINISM_LOG
  6. #include <Jolt/Physics/Body/BodyID.h>
  7. #include <Jolt/Physics/Collision/Shape/SubShapeID.h>
  8. #include <iomanip>
  9. #include <fstream>
  10. JPH_NAMESPACE_BEGIN
  11. /// A simple class that logs the state of the simulation. The resulting text file can be used to diff between platforms and find issues in determinism.
  12. class DeterminismLog
  13. {
  14. private:
  15. JPH_INLINE uint32 Convert(float inValue) const
  16. {
  17. return *(uint32 *)&inValue;
  18. }
  19. public:
  20. DeterminismLog()
  21. {
  22. mLog.open("detlog.txt", ios::out | ios::trunc | ios::binary); // Binary because we don't want a difference between Unix and Windows line endings.
  23. mLog.fill('0');
  24. }
  25. DeterminismLog & operator << (char inValue)
  26. {
  27. mLog << inValue;
  28. return *this;
  29. }
  30. DeterminismLog & operator << (const char *inValue)
  31. {
  32. mLog << dec << inValue;
  33. return *this;
  34. }
  35. DeterminismLog & operator << (const string &inValue)
  36. {
  37. mLog << dec << inValue;
  38. return *this;
  39. }
  40. DeterminismLog & operator << (const BodyID &inValue)
  41. {
  42. mLog << hex << setw(8) << inValue.GetIndexAndSequenceNumber();
  43. return *this;
  44. }
  45. DeterminismLog & operator << (const SubShapeID &inValue)
  46. {
  47. mLog << hex << setw(8) << inValue.GetValue();
  48. return *this;
  49. }
  50. DeterminismLog & operator << (float inValue)
  51. {
  52. mLog << hex << setw(8) << Convert(inValue);
  53. return *this;
  54. }
  55. DeterminismLog & operator << (int inValue)
  56. {
  57. mLog << inValue;
  58. return *this;
  59. }
  60. DeterminismLog & operator << (uint32 inValue)
  61. {
  62. mLog << hex << setw(8) << inValue;
  63. return *this;
  64. }
  65. DeterminismLog & operator << (uint64 inValue)
  66. {
  67. mLog << hex << setw(16) << inValue;
  68. return *this;
  69. }
  70. DeterminismLog & operator << (Vec3Arg inValue)
  71. {
  72. mLog << hex << setw(8) << Convert(inValue.GetX()) << " " << setw(8) << Convert(inValue.GetY()) << " " << setw(8) << Convert(inValue.GetZ());
  73. return *this;
  74. }
  75. DeterminismLog & operator << (Vec4Arg inValue)
  76. {
  77. mLog << hex << setw(8) << Convert(inValue.GetX()) << " " << setw(8) << Convert(inValue.GetY()) << " " << setw(8) << Convert(inValue.GetZ()) << " " << setw(8) << Convert(inValue.GetW());
  78. return *this;
  79. }
  80. DeterminismLog & operator << (const Float3 &inValue)
  81. {
  82. mLog << hex << setw(8) << Convert(inValue.x) << " " << setw(8) << Convert(inValue.y) << " " << setw(8) << Convert(inValue.z);
  83. return *this;
  84. }
  85. DeterminismLog & operator << (Mat44Arg inValue)
  86. {
  87. *this << inValue.GetColumn4(0) << " " << inValue.GetColumn4(1) << " " << inValue.GetColumn4(2) << " " << inValue.GetColumn4(3);
  88. return *this;
  89. }
  90. DeterminismLog & operator << (QuatArg inValue)
  91. {
  92. *this << inValue.GetXYZW();
  93. return *this;
  94. }
  95. // Singleton instance
  96. static DeterminismLog sLog;
  97. private:
  98. ofstream mLog;
  99. };
  100. /// Will log something to the determinism log, usage: JPH_DET_LOG("label " << value);
  101. #define JPH_DET_LOG(...) DeterminismLog::sLog << __VA_ARGS__ << '\n'
  102. JPH_NAMESPACE_END
  103. #else
  104. JPH_SUPPRESS_WARNING_PUSH
  105. JPH_SUPPRESS_WARNINGS
  106. /// By default we log nothing
  107. #define JPH_DET_LOG(...)
  108. JPH_SUPPRESS_WARNING_POP
  109. #endif // JPH_ENABLE_DETERMINISM_LOG