FrictionPerTriangleTest.cpp 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <TestFramework.h>
  4. #include <Tests/General/FrictionPerTriangleTest.h>
  5. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  6. #include <Jolt/Physics/Collision/Shape/MeshShape.h>
  7. #include <Jolt/Geometry/Triangle.h>
  8. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  9. #include <Layers.h>
  10. JPH_IMPLEMENT_RTTI_VIRTUAL(FrictionPerTriangleTest)
  11. {
  12. JPH_ADD_BASE_CLASS(FrictionPerTriangleTest, Test)
  13. }
  14. void FrictionPerTriangleTest::Initialize()
  15. {
  16. const int num_sections = 5;
  17. const float section_size = 50.0f;
  18. // Create a strip of triangles
  19. TriangleList triangles;
  20. for (int z = 0; z <= num_sections; ++z)
  21. {
  22. float z1 = section_size * (z - 0.5f * num_sections);
  23. float z2 = z1 + section_size;
  24. Float3 v1 = Float3(-100.0f, 0, z1);
  25. Float3 v2 = Float3(100.0f, 0, z1);
  26. Float3 v3 = Float3(-100.0f, 0, z2);
  27. Float3 v4 = Float3(100.0f, 0, z2);
  28. triangles.push_back(Triangle(v1, v3, v4, z));
  29. triangles.push_back(Triangle(v1, v4, v2, z));
  30. }
  31. // Create materials with increasing friction
  32. PhysicsMaterialList materials;
  33. for (uint i = 0; i <= num_sections; ++i)
  34. {
  35. float friction = float(i) / float(num_sections);
  36. materials.push_back(new MyMaterial("Friction " + ConvertToString(friction), Color::sGetDistinctColor(i), friction, 0.0f));
  37. }
  38. // A ramp
  39. mBodyInterface->CreateAndAddBody(BodyCreationSettings(new MeshShapeSettings(triangles, materials), Vec3::sZero(), Quat::sRotation(Vec3::sAxisX(), 0.2f * JPH_PI), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
  40. // A box with friction 1 that slides down the ramp
  41. Ref<BoxShape> box_shape = new BoxShape(Vec3(2.0f, 2.0f, 2.0f), cDefaultConvexRadius, new MyMaterial("Box Friction 1", Color::sYellow, 1.0f, 0.0f));
  42. mBodyInterface->CreateAndAddBody(BodyCreationSettings(box_shape, Vec3(0, 60.0f, -75.0f), Quat::sRotation(Vec3::sAxisX(), 0.2f * JPH_PI), EMotionType::Dynamic, Layers::MOVING), EActivation::Activate);
  43. }
  44. void FrictionPerTriangleTest::sGetFrictionAndRestitution(const Body &inBody, const SubShapeID &inSubShapeID, float &outFriction, float &outRestitution)
  45. {
  46. // Get the material that corresponds to the sub shape ID
  47. const PhysicsMaterial *material = inBody.GetShape()->GetMaterial(inSubShapeID);
  48. if (material == PhysicsMaterial::sDefault)
  49. {
  50. // This is the default material, use the settings from the body (note all bodies in our test have a material so this should not happen)
  51. outFriction = inBody.GetFriction();
  52. outRestitution = inBody.GetRestitution();
  53. }
  54. else
  55. {
  56. // If it's not the default material we know its a material that we created so we can cast it and get the values
  57. const MyMaterial *my_material = static_cast<const MyMaterial *>(material);
  58. outFriction = my_material->mFriction;
  59. outRestitution = my_material->mRestitution;
  60. }
  61. }
  62. void FrictionPerTriangleTest::sOverrideContactSettings(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  63. {
  64. // Get the custom friction and restitution for both bodies
  65. float friction1, friction2, restitution1, restitution2;
  66. sGetFrictionAndRestitution(inBody1, inManifold.mSubShapeID1, friction1, restitution1);
  67. sGetFrictionAndRestitution(inBody2, inManifold.mSubShapeID2, friction2, restitution2);
  68. // Use the default formulas for combining friction and restitution
  69. ioSettings.mCombinedFriction = sqrt(friction1 * friction2);
  70. ioSettings.mCombinedRestitution = max(restitution1, restitution2);
  71. }
  72. void FrictionPerTriangleTest::OnContactAdded(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  73. {
  74. sOverrideContactSettings(inBody1, inBody2, inManifold, ioSettings);
  75. }
  76. void FrictionPerTriangleTest::OnContactPersisted(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  77. {
  78. sOverrideContactSettings(inBody1, inBody2, inManifold, ioSettings);
  79. }