MeshShapeUserDataTest.cpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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/Shapes/MeshShapeUserDataTest.h>
  6. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  7. #include <Jolt/Physics/Collision/Shape/MeshShape.h>
  8. #include <Jolt/Physics/Collision/Shape/StaticCompoundShape.h>
  9. #include <Jolt/Physics/Collision/RayCast.h>
  10. #include <Jolt/Physics/Collision/CastResult.h>
  11. #include <Jolt/Geometry/Triangle.h>
  12. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  13. #include <Layers.h>
  14. #include <Renderer/DebugRendererImp.h>
  15. JPH_IMPLEMENT_RTTI_VIRTUAL(MeshShapeUserDataTest)
  16. {
  17. JPH_ADD_BASE_CLASS(MeshShapeUserDataTest, Test)
  18. }
  19. void MeshShapeUserDataTest::Initialize()
  20. {
  21. std::default_random_engine random;
  22. // Create regular grid of triangles
  23. uint32 user_data = 0;
  24. TriangleList triangles[2];
  25. for (int x = -10; x < 10; ++x)
  26. for (int z = -10; z < 10; ++z)
  27. {
  28. float x1 = 10.0f * x;
  29. float z1 = 10.0f * z;
  30. float x2 = x1 + 10.0f;
  31. float z2 = z1 + 10.0f;
  32. Float3 v1 = Float3(x1, 0, z1);
  33. Float3 v2 = Float3(x2, 0, z1);
  34. Float3 v3 = Float3(x1, 0, z2);
  35. Float3 v4 = Float3(x2, 0, z2);
  36. triangles[random() & 1].push_back(Triangle(v1, v3, v4, 0, user_data++));
  37. triangles[random() & 1].push_back(Triangle(v1, v4, v2, 0, user_data++));
  38. }
  39. // Create a compound with 2 meshes
  40. StaticCompoundShapeSettings compound_settings;
  41. compound_settings.SetEmbedded();
  42. for (TriangleList &t : triangles)
  43. {
  44. // Shuffle the triangles
  45. std::shuffle(t.begin(), t.end(), random);
  46. // Create mesh
  47. MeshShapeSettings mesh_settings(t);
  48. mesh_settings.mPerTriangleUserData = true;
  49. compound_settings.AddShape(Vec3::sZero(), Quat::sIdentity(), mesh_settings.Create().Get());
  50. }
  51. // Create body
  52. mBodyInterface->CreateAndAddBody(BodyCreationSettings(&compound_settings, RVec3::sZero(), Quat::sRotation(Vec3::sAxisX(), 0.25f * JPH_PI), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
  53. // 1 body with zero friction
  54. BodyCreationSettings bcs(new BoxShape(Vec3::sReplicate(2.0f)), RVec3(0, 55.0f, -50.0f), Quat::sRotation(Vec3::sAxisX(), 0.25f * JPH_PI), EMotionType::Dynamic, Layers::MOVING);
  55. bcs.mFriction = 0.0f;
  56. bcs.mEnhancedInternalEdgeRemoval = true; // Needed because the 2 meshes have a lot of active edges
  57. mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
  58. }
  59. void MeshShapeUserDataTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
  60. {
  61. // Cast a ray
  62. RayCastResult hit;
  63. RRayCast ray(inParams.mCameraState.mPos, inParams.mCameraState.mForward * 100.0f);
  64. mPhysicsSystem->GetNarrowPhaseQuery().CastRay(ray, hit);
  65. // Get body (if there was a hit)
  66. BodyLockRead lock(mPhysicsSystem->GetBodyLockInterface(), hit.mBodyID);
  67. if (lock.SucceededAndIsInBroadPhase())
  68. {
  69. // Get the leaf shape (mesh shape in this case)
  70. SubShapeID remainder;
  71. const Shape *shape = lock.GetBody().GetShape()->GetLeafShape(hit.mSubShapeID2, remainder);
  72. JPH_ASSERT(shape->GetType() == EShapeType::Mesh);
  73. // Get user data from the triangle that was hit
  74. uint32 user_data = static_cast<const MeshShape *>(shape)->GetTriangleUserData(remainder);
  75. // Draw it on screen
  76. RVec3 hit_pos = ray.GetPointOnRay(hit.mFraction);
  77. mDebugRenderer->DrawText3D(hit_pos, StringFormat("UserData: %d", user_data).c_str());
  78. }
  79. }