MaxBodiesScene.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2025 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. // Jolt includes
  6. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  7. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  8. // Local includes
  9. #include "PerformanceTestScene.h"
  10. #include "Layers.h"
  11. // A scene that creates the max number of bodies that Jolt supports and simulates them
  12. class MaxBodiesScene : public PerformanceTestScene
  13. {
  14. public:
  15. virtual const char * GetName() const override
  16. {
  17. return "MaxBodies";
  18. }
  19. virtual size_t GetTempAllocatorSizeMB() const override
  20. {
  21. return 8192;
  22. }
  23. virtual uint GetMaxBodies() const override
  24. {
  25. return PhysicsSystem::cMaxBodiesLimit;
  26. }
  27. virtual uint GetMaxBodyPairs() const override
  28. {
  29. return PhysicsSystem::cMaxBodyPairsLimit;
  30. }
  31. virtual uint GetMaxContactConstraints() const override
  32. {
  33. return PhysicsSystem::cMaxContactConstraintsLimit;
  34. }
  35. virtual void StartTest(PhysicsSystem &inPhysicsSystem, EMotionQuality inMotionQuality) override
  36. {
  37. BodyInterface &bi = inPhysicsSystem.GetBodyInterface();
  38. // Reduce the solver iteration count in the interest of performance
  39. PhysicsSettings settings = inPhysicsSystem.GetPhysicsSettings();
  40. settings.mNumVelocitySteps = 4;
  41. settings.mNumPositionSteps = 1;
  42. inPhysicsSystem.SetPhysicsSettings(settings);
  43. // Create the bodies
  44. uint num_bodies = inPhysicsSystem.GetMaxBodies();
  45. uint num_constraints = 0;
  46. BodyIDVector body_ids;
  47. body_ids.reserve(num_bodies);
  48. uint num_per_axis = uint(pow(float(num_bodies), 1.0f / 3.0f)) + 1;
  49. Vec3 half_extent = Vec3::sReplicate(0.5f);
  50. BodyCreationSettings bcs(new BoxShape(half_extent), RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  51. bcs.mOverrideMassProperties = EOverrideMassProperties::MassAndInertiaProvided;
  52. bcs.mMassPropertiesOverride.SetMassAndInertiaOfSolidBox(2.0f * half_extent, 1000.0f);
  53. for (uint z = 0; z < num_per_axis && body_ids.size() < num_bodies; ++z)
  54. for (uint y = 0; y < num_per_axis && body_ids.size() < num_bodies; ++y)
  55. for (uint x = 0; x < num_per_axis && body_ids.size() < num_bodies; ++x)
  56. {
  57. // When we reach the limit of contact constraints, start placing the boxes further apart so they don't collide
  58. bcs.mPosition = RVec3(num_constraints < PhysicsSystem::cMaxContactConstraintsLimit? Real(x) : 2.0_r * x, 2.0_r * y, 2.0_r * z);
  59. body_ids.push_back(bi.CreateBody(bcs)->GetID());
  60. // From the 2nd box onwards in a row, we will get a contact constraint
  61. if (x > 0)
  62. ++num_constraints;
  63. }
  64. // Add the bodies to the simulation
  65. BodyInterface::AddState state = bi.AddBodiesPrepare(body_ids.data(), num_bodies);
  66. bi.AddBodiesFinalize(body_ids.data(), num_bodies, state, EActivation::Activate);
  67. }
  68. };