LoggingCharacterContactListener.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Physics/Character/CharacterVirtual.h>
  6. // Character contact listener that just logs the calls made to it for later validation
  7. class LoggingCharacterContactListener : public CharacterContactListener
  8. {
  9. public:
  10. // Contact callback type
  11. enum class EType
  12. {
  13. ValidateBody,
  14. ValidateCharacter,
  15. AddBody,
  16. AddCharacter,
  17. };
  18. // Entry written when a contact callback happens
  19. struct LogEntry
  20. {
  21. EType mType;
  22. const CharacterVirtual * mCharacter;
  23. BodyID mBody2;
  24. const CharacterVirtual * mCharacter2;
  25. SubShapeID mSubShapeID2;
  26. };
  27. virtual bool OnContactValidate(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2) override
  28. {
  29. mLog.push_back({ EType::ValidateBody, inCharacter, inBodyID2, nullptr, inSubShapeID2 });
  30. return true;
  31. }
  32. virtual bool OnCharacterContactValidate(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2) override
  33. {
  34. mLog.push_back({ EType::ValidateCharacter, inCharacter, BodyID(), inOtherCharacter, inSubShapeID2 });
  35. return true;
  36. }
  37. virtual void OnContactAdded(const CharacterVirtual *inCharacter, const BodyID &inBodyID2, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) override
  38. {
  39. mLog.push_back({ EType::AddBody, inCharacter, inBodyID2, nullptr, inSubShapeID2 });
  40. }
  41. virtual void OnCharacterContactAdded(const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2, RVec3Arg inContactPosition, Vec3Arg inContactNormal, CharacterContactSettings &ioSettings) override
  42. {
  43. mLog.push_back({ EType::AddCharacter, inCharacter, BodyID(), inOtherCharacter, inSubShapeID2 });
  44. }
  45. void Clear()
  46. {
  47. mLog.clear();
  48. }
  49. size_t GetEntryCount() const
  50. {
  51. return mLog.size();
  52. }
  53. const LogEntry & GetEntry(size_t inIdx) const
  54. {
  55. return mLog[inIdx];
  56. }
  57. // Find first event with a particular type and involving a particular character vs body
  58. int Find(EType inType, const CharacterVirtual *inCharacter, const BodyID &inBody2) const
  59. {
  60. for (size_t i = 0; i < mLog.size(); ++i)
  61. {
  62. const LogEntry &e = mLog[i];
  63. if (e.mType == inType && e.mCharacter == inCharacter && e.mBody2 == inBody2 && e.mCharacter2 == nullptr)
  64. return int(i);
  65. }
  66. return -1;
  67. }
  68. // Check if event with a particular type and involving a particular character vs body
  69. bool Contains(EType inType, const CharacterVirtual *inCharacter, const BodyID &inBody2) const
  70. {
  71. return Find(inType, inCharacter, inBody2) >= 0;
  72. }
  73. // Find first event with a particular type and involving a particular character vs character
  74. int Find(EType inType, const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter) const
  75. {
  76. for (size_t i = 0; i < mLog.size(); ++i)
  77. {
  78. const LogEntry &e = mLog[i];
  79. if (e.mType == inType && e.mCharacter == inCharacter && e.mBody2.IsInvalid() && e.mCharacter2 == inOtherCharacter)
  80. return int(i);
  81. }
  82. return -1;
  83. }
  84. // Check if event with a particular type and involving a particular character vs character
  85. bool Contains(EType inType, const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter) const
  86. {
  87. return Find(inType, inCharacter, inOtherCharacter) >= 0;
  88. }
  89. // Find first event with a particular type and involving a particular character vs body and sub shape ID
  90. int Find(EType inType, const CharacterVirtual *inCharacter, const BodyID &inBody2, const SubShapeID &inSubShapeID2) const
  91. {
  92. for (size_t i = 0; i < mLog.size(); ++i)
  93. {
  94. const LogEntry &e = mLog[i];
  95. if (e.mType == inType && e.mCharacter == inCharacter && e.mBody2 == inBody2 && e.mCharacter2 == nullptr && e.mSubShapeID2 == inSubShapeID2)
  96. return int(i);
  97. }
  98. return -1;
  99. }
  100. // Check if a particular type and involving a particular character vs body and sub shape ID exists
  101. bool Contains(EType inType, const CharacterVirtual *inCharacter, const BodyID &inBody2, const SubShapeID &inSubShapeID2) const
  102. {
  103. return Find(inType, inCharacter, inBody2, inSubShapeID2) >= 0;
  104. }
  105. // Find first event with a particular type and involving a particular character vs character and sub shape ID
  106. int Find(EType inType, const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2) const
  107. {
  108. for (size_t i = 0; i < mLog.size(); ++i)
  109. {
  110. const LogEntry &e = mLog[i];
  111. if (e.mType == inType && e.mCharacter == inCharacter && e.mBody2.IsInvalid() && e.mCharacter2 == inOtherCharacter && e.mSubShapeID2 == inSubShapeID2)
  112. return int(i);
  113. }
  114. return -1;
  115. }
  116. // Check if a particular type and involving a particular character vs character and sub shape ID exists
  117. bool Contains(EType inType, const CharacterVirtual *inCharacter, const CharacterVirtual *inOtherCharacter, const SubShapeID &inSubShapeID2) const
  118. {
  119. return Find(inType, inCharacter, inOtherCharacter, inSubShapeID2) >= 0;
  120. }
  121. private:
  122. Array<LogEntry> mLog;
  123. };