SoftBodyTests.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include "UnitTestFramework.h"
  5. #include "PhysicsTestContext.h"
  6. #include "Layers.h"
  7. #include <Jolt/Physics/SoftBody/SoftBodySharedSettings.h>
  8. #include <Jolt/Physics/SoftBody/SoftBodyCreationSettings.h>
  9. #include <Jolt/Physics/SoftBody/SoftBodyMotionProperties.h>
  10. TEST_SUITE("SoftBodyTests")
  11. {
  12. TEST_CASE("TestBendConstraint")
  13. {
  14. // Possible values for x3
  15. const Float3 x3_values[] = {
  16. Float3(0, 0, 1), // forming flat plane
  17. Float3(0, 0, -1), // overlapping
  18. Float3(0, 1, 0), // 90 degrees concave
  19. Float3(0, -1, 0), // 90 degrees convex
  20. Float3(0, 1, 1), // 45 degrees concave
  21. Float3(0, -1, -1) // 135 degrees convex
  22. };
  23. for (const Float3 &x3 : x3_values)
  24. {
  25. PhysicsTestContext c;
  26. PhysicsSystem *s = c.GetSystem();
  27. BodyInterface &bi = s->GetBodyInterface();
  28. // Create settings
  29. Ref<SoftBodySharedSettings> shared_settings = new SoftBodySharedSettings;
  30. /* Create two triangles with a shared edge, x3 = free, the rest is locked
  31. x2
  32. e1/ \e3
  33. / \
  34. x0----x1
  35. \ e0 /
  36. e2\ /e4
  37. x3
  38. */
  39. SoftBodySharedSettings::Vertex v;
  40. v.mPosition = Float3(-1, 0, 0);
  41. v.mInvMass = 0;
  42. shared_settings->mVertices.push_back(v);
  43. v.mPosition = Float3(1, 0, 0);
  44. shared_settings->mVertices.push_back(v);
  45. v.mPosition = Float3(0, 0, -1);
  46. shared_settings->mVertices.push_back(v);
  47. v.mPosition = x3;
  48. v.mInvMass = 1;
  49. shared_settings->mVertices.push_back(v);
  50. // Create the 2 triangles
  51. shared_settings->AddFace(SoftBodySharedSettings::Face(0, 1, 2));
  52. shared_settings->AddFace(SoftBodySharedSettings::Face(0, 3, 1));
  53. // Create edge and dihedral constraints
  54. SoftBodySharedSettings::VertexAttributes va;
  55. va.mShearCompliance = FLT_MAX;
  56. va.mBendCompliance = 0;
  57. shared_settings->CreateConstraints(&va, 1, SoftBodySharedSettings::EBendType::Dihedral);
  58. // Optimize the settings
  59. shared_settings->Optimize();
  60. // Create the soft body
  61. SoftBodyCreationSettings sb_settings(shared_settings, RVec3::sZero(), Quat::sIdentity(), Layers::MOVING);
  62. sb_settings.mGravityFactor = 0.0f;
  63. sb_settings.mAllowSleeping = false;
  64. sb_settings.mUpdatePosition = false;
  65. Body &body = *bi.CreateSoftBody(sb_settings);
  66. bi.AddBody(body.GetID(), EActivation::Activate);
  67. SoftBodyMotionProperties *mp = static_cast<SoftBodyMotionProperties *>(body.GetMotionProperties());
  68. // Test 4 angles to see if there are singularities (the dot product between the triangles has the same value for 2 configurations)
  69. for (float angle : { 0.0f, 90.0f, 180.0f, 270.0f })
  70. {
  71. // Perturb x3
  72. Vec3 perturbed_x3(x3);
  73. mp->GetVertex(3).mPosition = 0.5f * (Mat44::sRotationX(DegreesToRadians(angle)) * perturbed_x3);
  74. // Simulate
  75. c.Simulate(0.25f);
  76. // Should return to the original position
  77. CHECK_APPROX_EQUAL(mp->GetVertex(3).mPosition, Vec3(x3), 1.0e-3f);
  78. }
  79. }
  80. }
  81. }