Skip to content

Commit

Permalink
Adds more test coverage of Contact & fixed bug found in equality support
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-langholtz committed Nov 1, 2023
1 parent 5a897b6 commit c8a5d84
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 28 deletions.
19 changes: 14 additions & 5 deletions Library/include/playrho/Contact.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,21 @@ struct ToiConf;
class Contact
{
public:
/// @brief Default contactable value.
static constexpr auto DefaultContactable = Contactable{InvalidBodyID, InvalidShapeID, 0};

/// @brief Substep type.
using substep_type = TimestepIters;

/// @brief Default constructor.
constexpr Contact() noexcept = default;

/// @brief Initializing constructor.
/// @note This need never be called directly by a user.
/// @param a The "a" contactable value.
/// @param b The "b" contactable value.
/// @post If either @p a or @p b is not the value of @c DefaultContactable then:
/// <code>IsEnabled()</code> and <code>NeedsUpdating()</code> return true,
/// else they return false.
constexpr Contact(const Contactable& a, const Contactable& b) noexcept;

/// @brief Is this contact touching?
Expand Down Expand Up @@ -290,10 +297,10 @@ class Contact
};

/// @brief Identifying info for the A-side of the 2-bodied contact.
Contactable m_contactableA{InvalidBodyID, InvalidShapeID, 0};
Contactable m_contactableA = DefaultContactable;

/// @brief Identifying info for the B-side of the 2-bodied contact.
Contactable m_contactableB{InvalidBodyID, InvalidShapeID, 0};
Contactable m_contactableB = DefaultContactable;

// initialized on construction (construction-time depedent)

Expand Down Expand Up @@ -322,7 +329,8 @@ class Contact
constexpr Contact::Contact(const Contactable& a, const Contactable& b) noexcept
: m_contactableA{a},
m_contactableB{b},
m_flags{e_enabledFlag | e_dirtyFlag}
m_flags{((a != DefaultContactable) || (b != DefaultContactable))
? FlagsType(e_enabledFlag | e_dirtyFlag): FlagsType{}}
{
}

Expand Down Expand Up @@ -516,7 +524,8 @@ constexpr void Contact::IncrementToiCount() noexcept
/// @relatedalso Contact
constexpr bool operator==(const Contact& lhs, const Contact& rhs) noexcept
{
return lhs.GetContactableA() == rhs.GetContactableB() && //
return lhs.GetContactableA() == rhs.GetContactableA() && //
lhs.GetContactableB() == rhs.GetContactableB() && //
lhs.GetFriction() == rhs.GetFriction() && //
lhs.GetRestitution() == rhs.GetRestitution() && //
lhs.GetTangentSpeed() == rhs.GetTangentSpeed() && //
Expand Down
103 changes: 80 additions & 23 deletions UnitTests/Contact.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,6 @@
using namespace playrho;
using namespace playrho::d2;

TEST(Contact, ByteSize)
{
// Check size at test runtime instead of compile-time via static_assert to avoid stopping
// builds and to report actual size rather than just reporting that expected size is wrong.
switch (sizeof(Real))
{
case 4:
EXPECT_EQ(alignof(Contact), 4u);
EXPECT_EQ(sizeof(Contact), std::size_t(36));
break;
case 8:
EXPECT_EQ(alignof(Contact), 8u);
EXPECT_EQ(sizeof(Contact), std::size_t(56));
break;
case 16:
EXPECT_EQ(sizeof(Contact), std::size_t(96));
break;
default:
FAIL();
break;
}
}

TEST(Contact, Enabled)
{
const auto bA = BodyID(0u);
Expand All @@ -63,6 +40,11 @@ TEST(Contact, Enabled)

TEST(Contact, DefaultConstruction)
{
{
const auto c = Contact();
EXPECT_EQ(c.GetContactableA(), Contact::DefaultContactable);
EXPECT_EQ(c.GetContactableB(), Contact::DefaultContactable);
}
EXPECT_EQ(GetBodyA(Contact()), InvalidBodyID);
EXPECT_EQ(GetBodyB(Contact()), InvalidBodyID);
EXPECT_EQ(GetShapeA(Contact()), InvalidShapeID);
Expand Down Expand Up @@ -218,3 +200,78 @@ TEST(Contact, GetOtherBody)
EXPECT_EQ(GetOtherBody(contact, bodyIdA), bodyIdB);
EXPECT_EQ(GetOtherBody(contact, bodyIdB), bodyIdA);
}

TEST(Contact, Equality)
{
EXPECT_TRUE(Contact() == Contact());
EXPECT_TRUE(Contact() == Contact(Contact::DefaultContactable, Contact::DefaultContactable));
{
auto c = Contact();
c.SetTouching();
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetEnabled();
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetFriction(NonNegative<Real>(2));
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetRestitution(Real(42));
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetTangentSpeed(42_mps);
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetToiCount(42u);
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetToi(std::optional<UnitIntervalFF<Real>>(0.5));
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.FlagForFiltering();
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.FlagForUpdating();
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetSensor();
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetImpenetrable();
EXPECT_FALSE(Contact() == c);
}
{
auto c = Contact();
c.SetIsActive();
EXPECT_FALSE(Contact() == c);
}
EXPECT_FALSE(Contact() ==
Contact(Contactable{BodyID(1u), ShapeID(0u), ChildCounter(0u)},
Contact::DefaultContactable));
EXPECT_FALSE(Contact() ==
Contact(Contactable{BodyID(0u), ShapeID(1u), ChildCounter(0u)},
Contact::DefaultContactable));
EXPECT_FALSE(Contact() ==
Contact(Contactable{BodyID(0u), ShapeID(0u), ChildCounter(1u)},
Contact::DefaultContactable));
}

0 comments on commit c8a5d84

Please sign in to comment.