SimShapeFilterTest.cpp 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Tests/General/SimShapeFilterTest.h>
  6. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  7. #include <Jolt/Physics/Collision/Shape/SphereShape.h>
  8. #include <Jolt/Physics/Collision/Shape/CapsuleShape.h>
  9. #include <Jolt/Physics/Collision/Shape/StaticCompoundShape.h>
  10. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  11. #include <Jolt/Physics/SoftBody/SoftBodyCreationSettings.h>
  12. #include <Utils/SoftBodyCreator.h>
  13. #include <Layers.h>
  14. JPH_IMPLEMENT_RTTI_VIRTUAL(SimShapeFilterTest)
  15. {
  16. JPH_ADD_BASE_CLASS(SimShapeFilterTest, Test)
  17. }
  18. SimShapeFilterTest::~SimShapeFilterTest()
  19. {
  20. // Unregister shape filter
  21. mPhysicsSystem->SetSimShapeFilter(nullptr);
  22. }
  23. void SimShapeFilterTest::Initialize()
  24. {
  25. // Register shape filter
  26. mPhysicsSystem->SetSimShapeFilter(&mShapeFilter);
  27. // Floor
  28. CreateFloor();
  29. // Platform
  30. mShapeFilter.mPlatformID = mBodyInterface->CreateAndAddBody(BodyCreationSettings(new BoxShape(Vec3(5.0f, 0.5f, 5.0f)), RVec3(0, 7.5f, 0), Quat::sRotation(Vec3::sAxisX(), 0.25f * JPH_PI), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
  31. // Compound shape
  32. Ref<Shape> capsule = new CapsuleShape(2, 0.1f);
  33. capsule->SetUserData(1); // Don't want the capsule to collide with the platform
  34. Ref<Shape> sphere = new SphereShape(0.5f);
  35. sphere->SetUserData(1); // Don't want the sphere to collide with the platform
  36. Ref<Shape> box = new BoxShape(Vec3::sReplicate(0.5f));
  37. Ref<StaticCompoundShapeSettings> compound = new StaticCompoundShapeSettings;
  38. compound->AddShape(Vec3::sZero(), Quat::sIdentity(), capsule);
  39. compound->AddShape(Vec3(0, -2, 0), Quat::sIdentity(), sphere);
  40. compound->AddShape(Vec3(0, 2, 0), Quat::sIdentity(), box);
  41. // Create compound above the platform
  42. BodyCreationSettings compound_body(compound, RVec3(0, 15, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  43. mShapeFilter.mCompoundID[0] = mBodyInterface->CreateAndAddBody(compound_body, EActivation::Activate);
  44. // Create cloth that's fixated at the corners
  45. SoftBodyCreationSettings cloth(SoftBodyCreator::CreateClothWithFixatedCorners(20, 20, 0.2f), RVec3(10, 10.0f, 0), Quat::sIdentity(), Layers::MOVING);
  46. mShapeFilter.mClothID = mBodyInterface->CreateAndAddSoftBody(cloth, EActivation::Activate);
  47. // Create compound above the cloth
  48. compound_body.mPosition = RVec3(10, 15, 0);
  49. mShapeFilter.mCompoundID[1] = mBodyInterface->CreateAndAddBody(compound_body, EActivation::Activate);
  50. }
  51. bool SimShapeFilterTest::Filter::ShouldCollide(const Body &inBody1, const Shape *inShape1, const SubShapeID &inSubShapeIDOfShape1, const Body &inBody2, const Shape *inShape2, const SubShapeID &inSubShapeIDOfShape2) const
  52. {
  53. // If the platform/cloth is colliding with the compound, filter out collisions where the shape has user data 1
  54. if (inBody1.GetID() == mPlatformID || inBody1.GetID() == mClothID)
  55. {
  56. for (int i = 0; i < 2; ++i)
  57. if (inBody2.GetID() == mCompoundID[i])
  58. return inShape2->GetUserData() != 1;
  59. }
  60. else if (inBody2.GetID() == mPlatformID || inBody2.GetID() == mClothID)
  61. {
  62. for (int i = 0; i < 2; ++i)
  63. if (inBody1.GetID() == mCompoundID[i])
  64. return inShape1->GetUserData() != 1;
  65. }
  66. return true;
  67. }