Przeglądaj źródła

Showing test descriptions in the samples application (#1568)

This should make it easier to see what a particular test is for.
Jorrit Rouwe 4 miesięcy temu
rodzic
commit
883cc1f053
100 zmienionych plików z 650 dodań i 163 usunięć
  1. 14 1
      Samples/SamplesApp.cpp
  2. 1 0
      Samples/SamplesApp.h
  3. 6 1
      Samples/Tests/BroadPhase/BroadPhaseCastRayTest.h
  4. 6 1
      Samples/Tests/BroadPhase/BroadPhaseInsertionTest.h
  5. 6 1
      Samples/Tests/Character/CharacterPlanetTest.h
  6. 8 3
      Samples/Tests/Character/CharacterSpaceShipTest.h
  7. 7 1
      Samples/Tests/Character/CharacterTest.h
  8. 4 4
      Samples/Tests/Character/CharacterVirtualTest.cpp
  9. 6 1
      Samples/Tests/Character/CharacterVirtualTest.h
  10. 7 1
      Samples/Tests/Constraints/ConstraintPriorityTest.h
  11. 6 0
      Samples/Tests/Constraints/ConstraintSingularityTest.h
  12. 7 1
      Samples/Tests/Constraints/ConstraintVsCOMChangeTest.h
  13. 7 3
      Samples/Tests/General/ActivateDuringUpdateTest.h
  14. 6 1
      Samples/Tests/General/ActiveEdgesTest.h
  15. 15 27
      Samples/Tests/General/AllowedDOFsTest.cpp
  16. 7 2
      Samples/Tests/General/AllowedDOFsTest.h
  17. 6 1
      Samples/Tests/General/BigVsSmallTest.h
  18. 6 1
      Samples/Tests/General/CenterOfMassTest.h
  19. 8 3
      Samples/Tests/General/ChangeMotionQualityTest.cpp
  20. 7 1
      Samples/Tests/General/ChangeMotionQualityTest.h
  21. 11 3
      Samples/Tests/General/ChangeMotionTypeTest.cpp
  22. 6 1
      Samples/Tests/General/ChangeMotionTypeTest.h
  23. 7 2
      Samples/Tests/General/ChangeObjectLayerTest.h
  24. 6 1
      Samples/Tests/General/ChangeShapeTest.h
  25. 9 1
      Samples/Tests/General/ContactListenerTest.h
  26. 6 1
      Samples/Tests/General/ContactManifoldTest.h
  27. 6 1
      Samples/Tests/General/ConveyorBeltTest.h
  28. 2 0
      Samples/Tests/General/DampingTest.cpp
  29. 6 1
      Samples/Tests/General/DampingTest.h
  30. 7 1
      Samples/Tests/General/DynamicMeshTest.h
  31. 17 8
      Samples/Tests/General/EnhancedInternalEdgeRemovalTest.cpp
  32. 6 1
      Samples/Tests/General/EnhancedInternalEdgeRemovalTest.h
  33. 7 1
      Samples/Tests/General/FrictionPerTriangleTest.h
  34. 2 0
      Samples/Tests/General/FrictionTest.cpp
  35. 6 1
      Samples/Tests/General/FrictionTest.h
  36. 6 1
      Samples/Tests/General/FunnelTest.h
  37. 1 0
      Samples/Tests/General/GravityFactorTest.cpp
  38. 6 1
      Samples/Tests/General/GravityFactorTest.h
  39. 4 2
      Samples/Tests/General/GyroscopicForceTest.cpp
  40. 7 1
      Samples/Tests/General/GyroscopicForceTest.h
  41. 4 2
      Samples/Tests/General/HeavyOnLightTest.cpp
  42. 7 1
      Samples/Tests/General/HeavyOnLightTest.h
  43. 6 1
      Samples/Tests/General/HighSpeedTest.h
  44. 6 1
      Samples/Tests/General/IslandTest.h
  45. 6 1
      Samples/Tests/General/KinematicTest.h
  46. 6 1
      Samples/Tests/General/LoadSaveBinaryTest.h
  47. 6 1
      Samples/Tests/General/LoadSaveSceneTest.h
  48. 7 1
      Samples/Tests/General/ManifoldReductionTest.h
  49. 15 13
      Samples/Tests/General/ModifyMassTest.cpp
  50. 10 2
      Samples/Tests/General/ModifyMassTest.h
  51. 6 1
      Samples/Tests/General/MultithreadedTest.h
  52. 7 1
      Samples/Tests/General/PyramidTest.h
  53. 4 2
      Samples/Tests/General/RestitutionTest.cpp
  54. 6 1
      Samples/Tests/General/RestitutionTest.h
  55. 4 0
      Samples/Tests/General/SensorTest.cpp
  56. 6 1
      Samples/Tests/General/SensorTest.h
  57. 6 1
      Samples/Tests/General/ShapeFilterTest.h
  58. 8 3
      Samples/Tests/General/SimCollideBodyVsBodyTest.h
  59. 7 1
      Samples/Tests/General/SimShapeFilterTest.h
  60. 6 1
      Samples/Tests/General/SimpleTest.h
  61. 6 1
      Samples/Tests/General/StackTest.h
  62. 6 1
      Samples/Tests/General/TwoDFunnelTest.h
  63. 6 1
      Samples/Tests/General/WallTest.h
  64. 7 1
      Samples/Tests/Rig/BigWorldTest.h
  65. 6 1
      Samples/Tests/Rig/CreateRigTest.h
  66. 6 1
      Samples/Tests/Rig/KinematicRigTest.h
  67. 6 1
      Samples/Tests/Rig/LoadRigTest.h
  68. 6 1
      Samples/Tests/Rig/LoadSaveBinaryRigTest.h
  69. 6 1
      Samples/Tests/Rig/LoadSaveRigTest.h
  70. 6 1
      Samples/Tests/Rig/PoweredRigTest.h
  71. 6 1
      Samples/Tests/Rig/RigPileTest.h
  72. 6 1
      Samples/Tests/Rig/SkeletonMapperTest.h
  73. 6 1
      Samples/Tests/ScaledShapes/DynamicScaledShape.h
  74. 6 1
      Samples/Tests/Shapes/DeformedHeightFieldShapeTest.h
  75. 6 1
      Samples/Tests/Shapes/MeshShapeUserDataTest.h
  76. 6 1
      Samples/Tests/SoftBody/SoftBodyBendConstraintTest.h
  77. 10 3
      Samples/Tests/SoftBody/SoftBodyContactListenerTest.cpp
  78. 8 1
      Samples/Tests/SoftBody/SoftBodyContactListenerTest.h
  79. 6 1
      Samples/Tests/SoftBody/SoftBodyCustomUpdateTest.h
  80. 6 1
      Samples/Tests/SoftBody/SoftBodyForceTest.h
  81. 4 2
      Samples/Tests/SoftBody/SoftBodyFrictionTest.cpp
  82. 6 1
      Samples/Tests/SoftBody/SoftBodyFrictionTest.h
  83. 4 2
      Samples/Tests/SoftBody/SoftBodyGravityFactorTest.cpp
  84. 6 1
      Samples/Tests/SoftBody/SoftBodyGravityFactorTest.h
  85. 6 1
      Samples/Tests/SoftBody/SoftBodyKinematicTest.h
  86. 6 1
      Samples/Tests/SoftBody/SoftBodyLRAConstraintTest.h
  87. 2 1
      Samples/Tests/SoftBody/SoftBodyPressureTest.cpp
  88. 6 1
      Samples/Tests/SoftBody/SoftBodyPressureTest.h
  89. 4 2
      Samples/Tests/SoftBody/SoftBodyRestitutionTest.cpp
  90. 6 1
      Samples/Tests/SoftBody/SoftBodyRestitutionTest.h
  91. 6 1
      Samples/Tests/SoftBody/SoftBodySensorTest.h
  92. 6 1
      Samples/Tests/SoftBody/SoftBodyShapesTest.h
  93. 6 1
      Samples/Tests/SoftBody/SoftBodySkinnedConstraintTest.h
  94. 6 1
      Samples/Tests/SoftBody/SoftBodyStressTest.h
  95. 2 1
      Samples/Tests/SoftBody/SoftBodyUpdatePositionTest.cpp
  96. 8 3
      Samples/Tests/SoftBody/SoftBodyUpdatePositionTest.h
  97. 6 1
      Samples/Tests/SoftBody/SoftBodyVertexRadiusTest.h
  98. 6 1
      Samples/Tests/SoftBody/SoftBodyVsFastMovingTest.h
  99. 14 0
      Samples/Tests/Test.cpp
  100. 12 0
      Samples/Tests/Test.h

+ 14 - 1
Samples/SamplesApp.cpp

@@ -749,6 +749,9 @@ void SamplesApp::StartTest(const RTTI *inRTTI)
 
 	// Check if test has settings menu
 	mTestSettingsButton->SetDisabled(!mTest->HasSettingsMenu());
+
+	// We're immediately doing a step, we want to display the description for the first 2 steps
+	mShowDescription = 2;
 }
 
 void SamplesApp::RunAllTests()
@@ -2033,7 +2036,11 @@ bool SamplesApp::UpdateFrame(float inDeltaTime)
 	}
 
 	// Get the status string
-	mStatusString = mTest->GetStatusString();
+	const char *description = mShowDescription > 0? mTest->GetDescription() : nullptr;
+	if (description != nullptr)
+		mStatusString = String(description) + "\n" + mTest->GetStatusString();
+	else
+		mStatusString = mTest->GetStatusString();
 
 	// Select the next test if automatic testing times out
 	if (!CheckNextTest())
@@ -2319,6 +2326,8 @@ void SamplesApp::DrawPhysics()
 		mDebugRenderer->DrawWireBox(mPhysicsSystem->GetBounds(), Color::sGreen);
 #endif // JPH_DEBUG_RENDERER
 
+	mTest->DrawBodyLabels();
+
 	// This map collects the shapes that we used this frame
 	ShapeToGeometryMap shape_to_geometry;
 
@@ -2511,6 +2520,10 @@ void SamplesApp::StepPhysics(JobSystem *inJobSystem)
 		JPH_PROFILE("PostPhysicsUpdate");
 		mTest->PostPhysicsUpdate(delta_time);
 	}
+
+	// Decrement number of frames to show the description
+	if (mShowDescription > 0)
+		--mShowDescription;
 }
 
 void SamplesApp::SaveState(StateRecorderImpl &inStream)

+ 1 - 0
Samples/SamplesApp.h

@@ -118,6 +118,7 @@ private:
 	const RTTI *			mTestClass = nullptr;										// RTTI information for the test we're currently running
 	Test *					mTest = nullptr;											// The test we're currently running
 	UITextButton *			mTestSettingsButton = nullptr;								// Button that activates the menu that the test uses to configure additional settings
+	int						mShowDescription = 0;										// If > 0, render the description of the test
 
 	// Automatic cycling through tests
 	Array<const RTTI *>		mTestsToRun;												// The list of tests that are still waiting to be run

+ 6 - 1
Samples/Tests/BroadPhase/BroadPhaseCastRayTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/BroadPhase/BroadPhaseTest.h>
 
-// Simple test that casts a ray through the broadphase
 class BroadPhaseCastRayTest : public BroadPhaseTest
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, BroadPhaseCastRayTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Simple test that casts a ray through the broadphase.";
+	}
+
 	// Initialize the test
 	virtual void	Initialize() override;
 

+ 6 - 1
Samples/Tests/BroadPhase/BroadPhaseInsertionTest.h

@@ -7,12 +7,17 @@
 #include <Tests/BroadPhase/BroadPhaseTest.h>
 #include <random>
 
-// Test that adds/removes objects to/from the broadphase and casts a ray through the boxes to see if the collision results are correct
 class BroadPhaseInsertionTest : public BroadPhaseTest
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, BroadPhaseInsertionTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Test that adds/removes objects to/from the broadphase and casts a ray through the boxes to see if the collision results are correct.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 6 - 1
Samples/Tests/Character/CharacterPlanetTest.h

@@ -8,12 +8,17 @@
 #include <Jolt/Physics/Character/CharacterVirtual.h>
 #include <Jolt/Physics/PhysicsStepListener.h>
 
-// Demonstrates how to do custom gravity to simulate a character walking on a planet
 class CharacterPlanetTest : public Test, public PhysicsStepListener, public CharacterContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, CharacterPlanetTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Demonstrates how to do custom gravity to simulate a character walking on a planet.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 8 - 3
Samples/Tests/Character/CharacterSpaceShipTest.h

@@ -7,14 +7,19 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Character/CharacterVirtual.h>
 
-// A test that demonstrates how a character may walk around a fast moving/accelerating sci-fi space ship that is equipped with inertial dampeners.
-// Note that this is 'game physics' and not real physics, inertial dampeners only exist in the movies.
-// You can walk off the ship and remain attached to the ship. A proper implementation would detect this and detach the character.
 class CharacterSpaceShipTest : public Test, public CharacterContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, CharacterSpaceShipTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return	"Demonstrates how a character may walk around a fast moving/accelerating sci-fi space ship that is equipped with inertial dampeners.\n"
+				"Note that this is 'game physics' and not real physics, inertial dampeners only exist in the movies.\n"
+				"You can walk off the ship and remain attached to the ship. A proper implementation would detect this and detach the character.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 7 - 1
Samples/Tests/Character/CharacterTest.h

@@ -6,12 +6,18 @@
 
 #include <Tests/Character/CharacterBaseTest.h>
 
-// Simple test that test the Character class. Allows the user to move around with the arrow keys and jump with the J button.
 class CharacterTest : public CharacterBaseTest, public ContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, CharacterTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return	"Shows the Character class. Move around with the arrow keys, Shift for crouch and Ctrl for jump.\n"
+				"Note that most games should use CharacterVirtual instead of the Character class.";
+	}
+
 	// Destructor
 	virtual					~CharacterTest() override;
 

+ 4 - 4
Samples/Tests/Character/CharacterVirtualTest.cpp

@@ -43,6 +43,10 @@ void CharacterVirtualTest::Initialize()
 	// Install contact listener for all characters
 	for (CharacterVirtual *character : mCharacterVsCharacterCollision.mCharacters)
 		character->SetListener(this);
+
+	// Draw labels on ramp blocks
+	for (size_t i = 0; i < mRampBlocks.size(); ++i)
+		SetBodyLabel(mRampBlocks[i], StringFormat("PushesPlayer: %s\nPushable: %s", (i & 1) != 0? "True" : "False", (i & 2) != 0? "True" : "False"));
 }
 
 void CharacterVirtualTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
@@ -107,10 +111,6 @@ void CharacterVirtualTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
 
 	// Draw state of character
 	DrawCharacterState(mCharacter, world_transform, velocity);
-
-	// Draw labels on ramp blocks
-	for (size_t i = 0; i < mRampBlocks.size(); ++i)
-		mDebugRenderer->DrawText3D(mBodyInterface->GetPosition(mRampBlocks[i]), StringFormat("PushesPlayer: %s\nPushable: %s", (i & 1) != 0? "True" : "False", (i & 2) != 0? "True" : "False"), Color::sWhite, 0.25f);
 }
 
 void CharacterVirtualTest::HandleInput(Vec3Arg inMovementDirection, bool inJump, bool inSwitchStance, float inDeltaTime)

+ 6 - 1
Samples/Tests/Character/CharacterVirtualTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Character/CharacterBaseTest.h>
 
-// Simple test that test the CharacterVirtual class. Allows the user to move around with the arrow keys and jump with the J button.
 class CharacterVirtualTest : public CharacterBaseTest, public CharacterContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, CharacterVirtualTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows the CharacterVirtual class. Move around with the arrow keys, Shift for crouch and Ctrl for jump.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 7 - 1
Samples/Tests/Constraints/ConstraintPriorityTest.h

@@ -7,12 +7,18 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Constraints/FixedConstraint.h>
 
-// Tests constraint priority system to demonstrate that the order of solving can have an effect on the stiffness of the system
 class ConstraintPriorityTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ConstraintPriorityTest)
 
+	// Description of the test
+	virtual const char *		GetDescription() const override
+	{
+		return	"Tests constraint priority system to demonstrate that the order of solving can have an effect on the simulation.\n"
+				"Solving the root first will make the system stiffer.";
+	}
+
 	// See: Test
 	virtual void				Initialize() override;
 	virtual void				PostPhysicsUpdate(float inDeltaTime) override;

+ 6 - 0
Samples/Tests/Constraints/ConstraintSingularityTest.h

@@ -11,6 +11,12 @@ class ConstraintSingularityTest : public Test
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ConstraintSingularityTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Starts constraints in a configuration where there are multiple directions to move in to satisfy the constraint.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 7 - 1
Samples/Tests/Constraints/ConstraintVsCOMChangeTest.h

@@ -6,12 +6,18 @@
 
 #include <Tests/Test.h>
 
-// This test demonstrates how to notify a constraint that the center of mass of a body changed (constraints store their attachment points in center of mass space).
 class ConstraintVsCOMChangeTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ConstraintVsCOMChangeTest)
 
+	// Description of the test
+	virtual const char *		GetDescription() const override
+	{
+		return	"This test demonstrates how to notify a constraint that the center of mass of a body changed.\n"
+				"Constraints store their attachment points in center of mass space.";
+	}
+
 	// See: Test
 	virtual void				Initialize() override;
 	virtual void				PrePhysicsUpdate(const PreUpdateParams& inParams) override;

+ 7 - 3
Samples/Tests/General/ActivateDuringUpdateTest.h

@@ -6,14 +6,18 @@
 
 #include <Tests/Test.h>
 
-// This test tests a body that activates during the simulation step to check if it does collision detection with any other bodies during that step
-// To do so it uses 3 boxes that all initially collide. The left most box is the only one awake and has a high velocity.
-// The second box should not pass through the third box.
 class ActivateDuringUpdateTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ActivateDuringUpdateTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return	"Three initially colliding boxes where only 1 is awake and has a high velocity.\n"
+				"The 2nd and 3rd box should wake up at the same time and not pass through each other.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/ActiveEdgesTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test checks if coplanar triangles are properly merged for the simulation in order to avoid collisions with invisible edges.
 class ActiveEdgesTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ActiveEdgesTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Boxes sliding over the ramps should not collide with internal triangle edges of the ramp (aka ghost collisions).";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 15 - 27
Samples/Tests/General/AllowedDOFsTest.cpp

@@ -42,33 +42,21 @@ void AllowedDOFsTest::Initialize()
 		dcs.mMinDistance = 0.0f;
 		dcs.mMaxDistance = sqrt(3.0f) * 5.0f + 1.0f;
 		mPhysicsSystem->AddConstraint(mBodyInterface->CreateConstraint(&dcs, BodyID(), id));
-	}
-}
 
-void AllowedDOFsTest::PostPhysicsUpdate(float inDeltaTime)
-{
-	// Draw degrees of freedom
-	for (BodyID id : mBodies)
-	{
-		BodyLockRead body_lock(mPhysicsSystem->GetBodyLockInterface(), id);
-		if (body_lock.Succeeded())
-		{
-			const Body &body = body_lock.GetBody();
-			String allowed_dofs_str = "";
-			EAllowedDOFs allowed_dofs = body.GetMotionProperties()->GetAllowedDOFs();
-			if ((allowed_dofs & EAllowedDOFs::TranslationX) == EAllowedDOFs::TranslationX)
-				allowed_dofs_str += "X ";
-			if ((allowed_dofs & EAllowedDOFs::TranslationY) == EAllowedDOFs::TranslationY)
-				allowed_dofs_str += "Y ";
-			if ((allowed_dofs & EAllowedDOFs::TranslationZ) == EAllowedDOFs::TranslationZ)
-				allowed_dofs_str += "Z ";
-			if ((allowed_dofs & EAllowedDOFs::RotationX) == EAllowedDOFs::RotationX)
-				allowed_dofs_str += "RX ";
-			if ((allowed_dofs & EAllowedDOFs::RotationY) == EAllowedDOFs::RotationY)
-				allowed_dofs_str += "RY ";
-			if ((allowed_dofs & EAllowedDOFs::RotationZ) == EAllowedDOFs::RotationZ)
-				allowed_dofs_str += "RZ ";
-			DebugRenderer::sInstance->DrawText3D(body.GetPosition(), allowed_dofs_str, Color::sWhite);
-		}
+		// Draw degrees of freedom
+		String allowed_dofs_str = "";
+		if ((EAllowedDOFs(allowed_dofs) & EAllowedDOFs::TranslationX) == EAllowedDOFs::TranslationX)
+			allowed_dofs_str += "X ";
+		if ((EAllowedDOFs(allowed_dofs) & EAllowedDOFs::TranslationY) == EAllowedDOFs::TranslationY)
+			allowed_dofs_str += "Y ";
+		if ((EAllowedDOFs(allowed_dofs) & EAllowedDOFs::TranslationZ) == EAllowedDOFs::TranslationZ)
+			allowed_dofs_str += "Z ";
+		if ((EAllowedDOFs(allowed_dofs) & EAllowedDOFs::RotationX) == EAllowedDOFs::RotationX)
+			allowed_dofs_str += "RX ";
+		if ((EAllowedDOFs(allowed_dofs) & EAllowedDOFs::RotationY) == EAllowedDOFs::RotationY)
+			allowed_dofs_str += "RY ";
+		if ((EAllowedDOFs(allowed_dofs) & EAllowedDOFs::RotationZ) == EAllowedDOFs::RotationZ)
+			allowed_dofs_str += "RZ ";
+		SetBodyLabel(id, allowed_dofs_str);
 	}
 }

+ 7 - 2
Samples/Tests/General/AllowedDOFsTest.h

@@ -6,15 +6,20 @@
 
 #include <Tests/Test.h>
 
-// This test tests all permutations of allowed degrees of freedom (see EAllowedDOFs)
 class AllowedDOFsTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, AllowedDOFsTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Shows all permutations of allowed degrees of freedom for a body (see EAllowedDOFs).\n"
+				"The boxes are constrained to the world using a distance constraint, press C to show it.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
-	virtual void		PostPhysicsUpdate(float inDeltaTime) override;
 
 private:
 	BodyIDVector		mBodies;

+ 6 - 1
Samples/Tests/General/BigVsSmallTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// Tests a small box falling on a big triangle to test for numerical precision errors.
 class BigVsSmallTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, BigVsSmallTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "A small box falling on a big triangle to test for numerical precision errors.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/CenterOfMassTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// Test that spawns various shapes with the center of mass not in the center of the object
 class CenterOfMassTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, CenterOfMassTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Spawns various shapes with the center of mass not in the center of the object.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 8 - 3
Samples/Tests/General/ChangeMotionQualityTest.cpp

@@ -40,20 +40,25 @@ void ChangeMotionQualityTest::Initialize()
 	settings.SetShape(new SphereShape(1.0f));
 	settings.mPosition = RVec3(0, 0.5f, 0);
 	settings.mMotionType = EMotionType::Dynamic;
-	settings.mMotionQuality = EMotionQuality::LinearCast;
 	settings.mLinearVelocity = Vec3(-240, 0, -120);
 	settings.mFriction = 0.0f;
 	settings.mRestitution = 1.0f;
 	settings.mObjectLayer = Layers::MOVING;
 	mBody = mBodyInterface->CreateBody(settings);
 	mBodyInterface->AddBody(mBody->GetID(), EActivation::Activate);
+
+	UpdateMotionQuality();
 }
 
 void ChangeMotionQualityTest::UpdateMotionQuality()
 {
+	static EMotionQuality qualities[] = { EMotionQuality::LinearCast, EMotionQuality::Discrete };
+	static const char *labels[] = { "LinearCast", "Discrete" };
+
 	// Calculate desired motion quality
-	EMotionQuality motion_quality = (int(mTime) & 1) == 0? EMotionQuality::LinearCast : EMotionQuality::Discrete;
-	mBodyInterface->SetMotionQuality(mBody->GetID(), motion_quality);
+	int idx = int(mTime) & 1;
+	mBodyInterface->SetMotionQuality(mBody->GetID(), qualities[idx]);
+	SetBodyLabel(mBody->GetID(), labels[idx]);
 }
 
 void ChangeMotionQualityTest::PrePhysicsUpdate(const PreUpdateParams &inParams)

+ 7 - 1
Samples/Tests/General/ChangeMotionQualityTest.h

@@ -7,12 +7,18 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/Body.h>
 
-// This test will switch a body's motion quality between discrete and linear
 class ChangeMotionQualityTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ChangeMotionQualityTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Switches a body's motion quality from linear to discrete.\n"
+				"After the switch, the high speed body passes through the wall.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 11 - 3
Samples/Tests/General/ChangeMotionTypeTest.cpp

@@ -24,22 +24,30 @@ void ChangeMotionTypeTest::Initialize()
 	BodyCreationSettings settings;
 	settings.SetShape(new BoxShape(Vec3(0.5f, 1.0f, 2.0f)));
 	settings.mPosition = RVec3(0, 10, 0);
-	settings.mMotionType = EMotionType::Dynamic;
+	settings.mMotionType = EMotionType::Static;
 	settings.mObjectLayer = Layers::MOVING; // Put in moving layer, this will result in some overhead when the body is static
 	settings.mAllowDynamicOrKinematic = true;
 	mBody = mBodyInterface->CreateBody(settings);
 	mBodyInterface->AddBody(mBody->GetID(), EActivation::Activate);
+
+	UpdateMotionType();
 }
 
 void ChangeMotionTypeTest::UpdateMotionType()
 {
-	// Calculate desired motion type
 	static const EMotionType cycle[] = { EMotionType::Dynamic, EMotionType::Kinematic, EMotionType::Static, EMotionType::Kinematic, EMotionType::Dynamic, EMotionType::Static };
-	EMotionType motion_type = cycle[int(mTime) % size(cycle)];
+	static const char *label[] = { "Dynamic", "Kinematic", "Static", "Kinematic", "Dynamic", "Static" };
+
+	// Calculate desired motion type
+	int idx = int(mTime) % size(cycle);
+	EMotionType motion_type = cycle[idx];
 
 	// Update motion type and reactivate the body
 	if (motion_type != mBody->GetMotionType())
+	{
 		mBodyInterface->SetMotionType(mBody->GetID(), motion_type, EActivation::Activate);
+		SetBodyLabel(mBody->GetID(), label[idx]);
+	}
 }
 
 void ChangeMotionTypeTest::PrePhysicsUpdate(const PreUpdateParams &inParams)

+ 6 - 1
Samples/Tests/General/ChangeMotionTypeTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/Body.h>
 
-// This test will switch a body between static, kinematic and dynamic
 class ChangeMotionTypeTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ChangeMotionTypeTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Switches a body's motion type between static, kinematic and dynamic.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 7 - 2
Samples/Tests/General/ChangeObjectLayerTest.h

@@ -7,13 +7,18 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/BodyID.h>
 
-// This test will demonstrates how to use layers to disable collisions between other objects and how to change them on the fly.
-// The bodies will switch between the MOVING layer and the DEBRIS layer (debris only collides with static).
 class ChangeObjectLayerTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ChangeObjectLayerTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return	"Demonstrates how to use layers to disable collisions with other objects and how to change layers on the fly.\n"
+				"The small cubes will switch between the MOVING layer and the DEBRIS layer (debris only collides with the static floor).";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 6 - 1
Samples/Tests/General/ChangeShapeTest.h

@@ -8,12 +8,17 @@
 #include <Jolt/Physics/Body/BodyID.h>
 #include <Jolt/Physics/Collision/Shape/Shape.h>
 
-// This test will make a dynamic body cycle through various shapes
 class ChangeShapeTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ChangeShapeTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Demonstrates how to dynamically update the shape of a body.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 9 - 1
Samples/Tests/General/ContactListenerTest.h

@@ -7,12 +7,20 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Collision/ContactListener.h>
 
-// Tests the contact listener callbacks
 class ContactListenerTest : public Test, public ContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ContactListenerTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return	"Demonstrates how to listen for contact events.\n"
+				"Leftmost box ignores contacts with the 2nd box and overrides the restitution to 1 for non-persisted contacts.\n"
+				"Rightmost box contains an inner and an outer shape, the outer shape acts as a sensor.\n"
+				"The TTY will output estimated post collision velocities.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 	virtual void			PostPhysicsUpdate(float inDeltaTime) override;

+ 6 - 1
Samples/Tests/General/ContactManifoldTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test spawns objects at an angle of each other to test if the contact manifold is calculated correctly
 class ContactManifoldTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ContactManifoldTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Spawns objects at an angle to test if the contact manifold is calculated correctly.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/ConveyorBeltTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows how to create a conveyor belt
 class ConveyorBeltTest : public Test, public ContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ConveyorBeltTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Demonstrates how to use a contact listener to implement a conveyor belt.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 

+ 2 - 0
Samples/Tests/General/DampingTest.cpp

@@ -29,6 +29,7 @@ void DampingTest::Initialize()
 		body.GetMotionProperties()->SetLinearDamping(0.1f * i);
 		body.SetLinearVelocity(Vec3(0, 0, 10));
 		mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
+		SetBodyLabel(body.GetID(), StringFormat("Linear damping: %.1f", double(body.GetMotionProperties()->GetLinearDamping())));
 	}
 
 	for (int i = 0; i <= 10; ++i)
@@ -38,5 +39,6 @@ void DampingTest::Initialize()
 		body.GetMotionProperties()->SetAngularDamping(0.1f * i);
 		body.SetAngularVelocity(Vec3(0, 10, 0));
 		mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
+		SetBodyLabel(body.GetID(), StringFormat("Angular damping: %.1f", double(body.GetMotionProperties()->GetAngularDamping())));
 	}
 }

+ 6 - 1
Samples/Tests/General/DampingTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests various values for linear and angular damping
 class DampingTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, DampingTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Tests various values for linear and angular damping.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 7 - 1
Samples/Tests/General/DynamicMeshTest.h

@@ -6,12 +6,18 @@
 
 #include <Tests/Test.h>
 
-// This test drops a mesh shape on a box
 class DynamicMeshTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, DynamicMeshTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Drops a dynamic body with a mesh shape on a pile of boxes.\n"
+				"Note that mesh vs mesh collisions are currently not supported.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 17 - 8
Samples/Tests/General/EnhancedInternalEdgeRemovalTest.cpp

@@ -22,20 +22,23 @@ void EnhancedInternalEdgeRemovalTest::CreateSlidingObjects(RVec3Arg inStart)
 {
 	// Slide the shapes over the grid of boxes
 	RVec3 pos = inStart - RVec3(0, 0, 12.0_r);
+	static const char *labels[] = { "Normal", "Enhanced edge removal" };
 	for (int enhanced_removal = 0; enhanced_removal < 2; ++enhanced_removal)
 	{
 		// A box
 		BodyCreationSettings box_bcs(new BoxShape(Vec3::sReplicate(2.0f)), pos, Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
 		box_bcs.mLinearVelocity = Vec3(20, 0, 0);
 		box_bcs.mEnhancedInternalEdgeRemoval = enhanced_removal == 1;
-		mBodyInterface->CreateAndAddBody(box_bcs, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddBody(box_bcs, EActivation::Activate);
+		SetBodyLabel(id, labels[enhanced_removal]);
 		pos += RVec3(0, 0, 5.0_r);
 
 		// A sphere
 		BodyCreationSettings sphere_bcs(new SphereShape(2.0f), pos, Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
 		sphere_bcs.mLinearVelocity = Vec3(20, 0, 0);
 		sphere_bcs.mEnhancedInternalEdgeRemoval = enhanced_removal == 1;
-		mBodyInterface->CreateAndAddBody(sphere_bcs, EActivation::Activate);
+		id = mBodyInterface->CreateAndAddBody(sphere_bcs, EActivation::Activate);
+		SetBodyLabel(id, labels[enhanced_removal]);
 		pos += RVec3(0, 0, 5.0_r);
 
 		// Compound
@@ -49,7 +52,8 @@ void EnhancedInternalEdgeRemovalTest::CreateSlidingObjects(RVec3Arg inStart)
 		BodyCreationSettings compound_bcs(&compound, pos, Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
 		compound_bcs.mLinearVelocity = Vec3(20, 0, 0);
 		compound_bcs.mEnhancedInternalEdgeRemoval = enhanced_removal == 1;
-		mBodyInterface->CreateAndAddBody(compound_bcs, EActivation::Activate);
+		id = mBodyInterface->CreateAndAddBody(compound_bcs, EActivation::Activate);
+		SetBodyLabel(id, labels[enhanced_removal]);
 		pos += RVec3(0, 0, 7.0_r);
 	}
 }
@@ -65,7 +69,8 @@ void EnhancedInternalEdgeRemovalTest::Initialize()
 		for (int x = -10; x < 10; ++x)
 			for (int z = -10; z < 10; ++z)
 				compound_settings.AddShape(Vec3(size * x, 0, size * z), Quat::sIdentity(), box_shape);
-		mBodyInterface->CreateAndAddBody(BodyCreationSettings(&compound_settings, RVec3(0, -1, -40), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
+		BodyID id = mBodyInterface->CreateAndAddBody(BodyCreationSettings(&compound_settings, RVec3(0, -1, -40), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
+		SetBodyLabel(id, "Dense grid of boxes");
 
 		CreateSlidingObjects(RVec3(-18, 1.9_r, -40.0_r));
 	}
@@ -95,7 +100,8 @@ void EnhancedInternalEdgeRemovalTest::Initialize()
 		MeshShapeSettings mesh_settings(triangles);
 		mesh_settings.mActiveEdgeCosThresholdAngle = -1.0f; // Turn off regular active edge determination so that we only rely on the mEnhancedInternalEdgeRemoval flag
 		mesh_settings.SetEmbedded();
-		mBodyInterface->CreateAndAddBody(BodyCreationSettings(&mesh_settings, RVec3::sZero(), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
+		BodyID id = mBodyInterface->CreateAndAddBody(BodyCreationSettings(&mesh_settings, RVec3::sZero(), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
+		SetBodyLabel(id, "Dense triangle mesh");
 
 		CreateSlidingObjects(RVec3(-18, 1.9_r, 0));
 	}
@@ -144,7 +150,8 @@ void EnhancedInternalEdgeRemovalTest::Initialize()
 		plane_mesh.SetEmbedded();
 		BodyCreationSettings level_plane(&plane_mesh, RVec3(-10, 0, 50), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING);
 		level_plane.mFriction = 1;
-		mBodyInterface->CreateAndAddBody(level_plane, EActivation::DontActivate);
+		BodyID id = mBodyInterface->CreateAndAddBody(level_plane, EActivation::DontActivate);
+		SetBodyLabel(id, "Dense triangle mesh");
 
 		// Roll a ball over it
 		BodyCreationSettings level_ball(new SphereShape(0.5f), RVec3(-10, 1, 41), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
@@ -157,7 +164,8 @@ void EnhancedInternalEdgeRemovalTest::Initialize()
 		// Create a sloped plane
 		BodyCreationSettings slope_plane(&plane_mesh, RVec3(10, 0, 50), Quat::sRotation(Vec3::sAxisX(), DegreesToRadians(45)), EMotionType::Static, Layers::NON_MOVING);
 		slope_plane.mFriction = 1;
-		mBodyInterface->CreateAndAddBody(slope_plane, EActivation::DontActivate);
+		id = mBodyInterface->CreateAndAddBody(slope_plane, EActivation::DontActivate);
+		SetBodyLabel(id, "Dense triangle mesh");
 
 		// Roll a ball over it
 		BodyCreationSettings slope_ball(new SphereShape(0.5f), RVec3(10, 8, 44), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
@@ -211,7 +219,8 @@ void EnhancedInternalEdgeRemovalTest::Initialize()
 		MeshShapeSettings mesh_settings(triangles);
 		mesh_settings.mActiveEdgeCosThresholdAngle = -1.0f; // Turn off regular active edge determination so that we only rely on the mEnhancedInternalEdgeRemoval flag
 		mesh_settings.SetEmbedded();
-		mBodyInterface->CreateAndAddBody(BodyCreationSettings(&mesh_settings, RVec3(0, 0, 80), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
+		BodyID id = mBodyInterface->CreateAndAddBody(BodyCreationSettings(&mesh_settings, RVec3(0, 0, 80), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING), EActivation::DontActivate);
+		SetBodyLabel(id, "Dense triangle mesh");
 
 		BodyCreationSettings box_bcs(new BoxShape(Vec3::sReplicate(1.0f)), RVec3(-24, 0.9_r, 80), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
 		box_bcs.mLinearVelocity = Vec3(20, 0, 0);

+ 6 - 1
Samples/Tests/General/EnhancedInternalEdgeRemovalTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-/// Demonstrates the enhanced internal edge removal mode by sliding two shapes over a mesh that has only active edges
 class EnhancedInternalEdgeRemovalTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, EnhancedInternalEdgeRemovalTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows bodies using enhanced edge removal vs bodies that don't.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 7 - 1
Samples/Tests/General/FrictionPerTriangleTest.h

@@ -8,12 +8,18 @@
 #include <Jolt/Physics/Collision/ContactListener.h>
 #include <Jolt/Physics/Collision/PhysicsMaterialSimple.h>
 
-/// This test demonstrates how you can use a contact listener and your own material definition to get friction and restitution per triangle or sub shape of a compound shape
 class FrictionPerTriangleTest : public Test, public ContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, FrictionPerTriangleTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Demonstrates how you can use a contact listener and your own material definition to get friction and restitution per triangle or per sub shape of a compound shape.\n"
+				"Friction increases while going down the slope. Box should eventually stop.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 

+ 2 - 0
Samples/Tests/General/FrictionTest.cpp

@@ -31,6 +31,7 @@ void FrictionTest::Initialize()
 		Body &body = *mBodyInterface->CreateBody(BodyCreationSettings(box, RVec3(-50.0f + i * 10.0f, 55.0f, -50.0f), Quat::sRotation(Vec3::sAxisX(), 0.25f * JPH_PI), EMotionType::Dynamic, Layers::MOVING));
 		body.SetFriction(0.1f * i);
 		mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
+		SetBodyLabel(body.GetID(), StringFormat("Friction: %.1f", double(body.GetFriction())));
 	}
 
 	for (int i = 0; i <= 10; ++i)
@@ -38,5 +39,6 @@ void FrictionTest::Initialize()
 		Body &body = *mBodyInterface->CreateBody(BodyCreationSettings(sphere, RVec3(-50.0f + i * 10.0f, 47.0f, -40.0f), Quat::sRotation(Vec3::sAxisX(), 0.25f * JPH_PI), EMotionType::Dynamic, Layers::MOVING));
 		body.SetFriction(0.1f * i);
 		mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
+		SetBodyLabel(body.GetID(), StringFormat("Friction: %.1f", double(body.GetFriction())));
 	}
 }

+ 6 - 1
Samples/Tests/General/FrictionTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests various values for friction
 class FrictionTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, FrictionTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Bodies with varying friction.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/FunnelTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test spawns a lot of objects and drops them into a funnel to check for performance / stability issues
 class FunnelTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, FunnelTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Spawns a lot of objects and drops them into a funnel to check for performance / stability issues.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 	virtual void		GetInitialCamera(CameraState &ioState) const override;

+ 1 - 0
Samples/Tests/General/GravityFactorTest.cpp

@@ -27,5 +27,6 @@ void GravityFactorTest::Initialize()
 		Body &body = *mBodyInterface->CreateBody(BodyCreationSettings(box, RVec3(-50.0f + i * 10.0f, 25.0f, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
 		body.GetMotionProperties()->SetGravityFactor(0.1f * i);
 		mBodyInterface->AddBody(body.GetID(), EActivation::Activate);
+		SetBodyLabel(body.GetID(), StringFormat("Gravity: %.1f", double(body.GetMotionProperties()->GetGravityFactor())));
 	}
 }

+ 6 - 1
Samples/Tests/General/GravityFactorTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests various gravity factors
 class GravityFactorTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, GravityFactorTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Bodies with varying gravity factor.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 4 - 2
Samples/Tests/General/GyroscopicForceTest.cpp

@@ -31,10 +31,12 @@ void GyroscopicForceTest::Initialize()
 	bcs.mAngularDamping = 0.0f;
 	bcs.mAngularVelocity = Vec3(10, 1, 0);
 	bcs.mGravityFactor = 0.0f;
-	mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
+	BodyID id = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
+	SetBodyLabel(id, "Gyroscopic force off");
 
 	// One body with gyroscopic force
 	bcs.mPosition += RVec3(10, 0, 0);
 	bcs.mApplyGyroscopicForce = true;
-	mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
+	id = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
+	SetBodyLabel(id, "Gyroscopic force on");
 }

+ 7 - 1
Samples/Tests/General/GyroscopicForceTest.h

@@ -7,12 +7,18 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/BodyActivationListener.h>
 
-// This shows how to enable gyrosopic forces to create the Dzhanibekov effect (see: https://en.wikipedia.org/wiki/Tennis_racket_theorem)
 class GyroscopicForceTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, GyroscopicForceTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		// See: https://en.wikipedia.org/wiki/Tennis_racket_theorem
+		return "Shows how to enable gyroscopic forces to create the Dzhanibekov effect.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 4 - 2
Samples/Tests/General/HeavyOnLightTest.cpp

@@ -24,11 +24,13 @@ void HeavyOnLightTest::Initialize()
 
 	for (int i = 1; i <= 10; ++i)
 	{
-		mBodyInterface->CreateAndAddBody(BodyCreationSettings(box, RVec3(-75.0f + i * 15.0f, 10.0f, 0.0f), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING), EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddBody(BodyCreationSettings(box, RVec3(-75.0f + i * 15.0f, 10.0f, 0.0f), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING), EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Mass: %g", double(box->GetMassProperties().mMass)));
 
 		Ref<BoxShape> box2 = new BoxShape(Vec3::sReplicate(5));
 		box2->SetDensity(5000.0f * i);
 
-		mBodyInterface->CreateAndAddBody(BodyCreationSettings(box2, RVec3(-75.0f + i * 15.0f, 30.0f, 0.0f), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING), EActivation::Activate);
+		id = mBodyInterface->CreateAndAddBody(BodyCreationSettings(box2, RVec3(-75.0f + i * 15.0f, 30.0f, 0.0f), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING), EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Mass: %g", double(box2->GetMassProperties().mMass)));
 	}
 }

+ 7 - 1
Samples/Tests/General/HeavyOnLightTest.h

@@ -6,12 +6,18 @@
 
 #include <Tests/Test.h>
 
-// This test spawns a number of heavy boxes (with increasing weight) on smaller boxes to see how the simulation handles this
 class HeavyOnLightTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, HeavyOnLightTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"This test spawns a number of heavy boxes (with increasing weight) on light boxes.\n"
+				"Shows that iterative solvers have issues with large mass differences.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/HighSpeedTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test spawns a number of high speed objects to check that they don't tunnel through geometry
 class HighSpeedTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, HighSpeedTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Spawns a number of high speed objects to check that they don't tunnel through geometry.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 

+ 6 - 1
Samples/Tests/General/IslandTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test creates a number of disjoint piles of blocks to see if the islands are properly determined and that the simulation spreads them out over multiple CPUs
 class IslandTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, IslandTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Creates a number of disjoint piles of blocks to see if the islands are properly determined and that the simulation spreads them out over multiple CPUs.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/KinematicTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/Body.h>
 
-// This test tests kinematic objects against a pile of dynamic boxes
 class KinematicTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, KinematicTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Tests kinematic objects against a pile of dynamic boxes.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 6 - 1
Samples/Tests/General/LoadSaveBinaryTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests the binary serialization system by creating a number of shapes, storing them, loading them and then simulating them
 class LoadSaveBinaryTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, LoadSaveBinaryTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Tests the binary serialization system by creating a number of shapes, storing them, loading them and then simulating them.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/LoadSaveSceneTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/PhysicsScene.h>
 
-// This test tests the serialization system by creating a number of shapes, storing them, loading them and then simulating them
 class LoadSaveSceneTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, LoadSaveSceneTest)
 
+	// Description of the test
+	virtual const char *		GetDescription() const override
+	{
+		return "Tests the object stream serialization system by creating a number of shapes, storing them, loading them and then simulating them.";
+	}
+
 	// See: Test
 	virtual void				Initialize() override;
 

+ 7 - 1
Samples/Tests/General/ManifoldReductionTest.h

@@ -6,12 +6,18 @@
 
 #include <Tests/Test.h>
 
-// This test shows how many coplanar triangles are reduced to a single contact manifold
 class ManifoldReductionTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ManifoldReductionTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"This test shows how many coplanar triangles are reduced to a single contact manifold.\n"
+				"The static geometry in this test consists of a high density triangle grid.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 15 - 13
Samples/Tests/General/ModifyMassTest.cpp

@@ -26,6 +26,19 @@ void ModifyMassTest::ResetBodies(int inCycle)
 	mBodyInterface->SetUserData(mBodies[1], (inCycle << 1) + 1);
 }
 
+void ModifyMassTest::UpdateLabels()
+{
+	for (BodyID id : mBodies)
+	{
+		BodyLockRead body_lock(mPhysicsSystem->GetBodyLockInterface(), id);
+		if (body_lock.Succeeded())
+		{
+			const Body &body = body_lock.GetBody();
+			SetBodyLabel(id, StringFormat("Inv mass scale: %.1f\nVelocity X: %.1f", (double)sGetInvMassScale(body), (double)body.GetLinearVelocity().GetX()));
+		}
+	}
+}
+
 void ModifyMassTest::Initialize()
 {
 	// Floor
@@ -37,6 +50,7 @@ void ModifyMassTest::Initialize()
 	mBodies[0] = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
 	mBodies[1] = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
 	ResetBodies(0);
+	UpdateLabels();
 }
 
 void ModifyMassTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
@@ -48,20 +62,8 @@ void ModifyMassTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
 	int new_cycle = (int)(mTime / cTimeBetweenTests);
 	if (old_cycle != new_cycle)
 		ResetBodies(new_cycle);
-}
 
-void ModifyMassTest::PostPhysicsUpdate(float inDeltaTime)
-{
-	// Draw the mass scale
-	for (BodyID id : mBodies)
-	{
-		BodyLockRead body_lock(mPhysicsSystem->GetBodyLockInterface(), id);
-		if (body_lock.Succeeded())
-		{
-			const Body &body = body_lock.GetBody();
-			DebugRenderer::sInstance->DrawText3D(body.GetPosition(), StringFormat("Inv mass scale: %.1f\nVelocity X: %.1f", (double)sGetInvMassScale(body), (double)body.GetLinearVelocity().GetX()), Color::sWhite);
-		}
-	}
+	UpdateLabels();
 }
 
 float ModifyMassTest::sGetInvMassScale(const Body &inBody)

+ 10 - 2
Samples/Tests/General/ModifyMassTest.h

@@ -7,16 +7,21 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Collision/ContactListener.h>
 
-// Tests modifying mass from a contact listener
 class ModifyMassTest : public Test, public ContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ModifyMassTest)
 
+	// Description of the test
+	virtual const char *		GetDescription() const override
+	{
+		return	"Uses a contact listener to modify the mass of bodies per contacting body pair.\n"
+				"Can be used to e.g. make a dynamic body respond normally to one body and appear to have infinite mass for another.";
+	}
+
 	// See: Test
 	virtual void				Initialize() override;
 	virtual void				PrePhysicsUpdate(const PreUpdateParams &inParams) override;
-	virtual void				PostPhysicsUpdate(float inDeltaTime) override;
 	virtual void				SaveState(StateRecorder &inStream) const override;
 	virtual void				RestoreState(StateRecorder &inStream) override;
 
@@ -34,6 +39,9 @@ private:
 	// Reset the bodies to their initial states
 	void						ResetBodies(int inCycle);
 
+	// Update the labels on the bodies
+	void						UpdateLabels();
+
 	float						mTime = 0.0f;
 
 	BodyID						mBodies[2];

+ 6 - 1
Samples/Tests/General/MultithreadedTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test spawns boxes and ragdolls and performs ray cast tests from threads / jobs to see if the simulation is thread safe.
 class MultithreadedTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, MultithreadedTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "This test spawns boxes and ragdolls and performs ray cast tests from threads / jobs to see if the simulation is thread safe.";
+	}
+
 	// Destructor
 	virtual					~MultithreadedTest() override;
 

+ 7 - 1
Samples/Tests/General/PyramidTest.h

@@ -6,12 +6,18 @@
 
 #include <Tests/Test.h>
 
-// This test tests a large pyramid of boxes to check stacking and performance behavior.
 class PyramidTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, PyramidTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Tests a large pyramid of boxes to check stacking and performance behavior.\n"
+				"The large island splitter should ensure that contacts are solved on multiple CPUs in parallel.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 4 - 2
Samples/Tests/General/RestitutionTest.cpp

@@ -29,7 +29,8 @@ void RestitutionTest::Initialize()
 		BodyCreationSettings settings(sphere, RVec3(-50.0f + i * 10.0f, 20.0f, -20.0f), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
 		settings.mRestitution = 0.1f * i;
 		settings.mLinearDamping = 0.0f;
-		mBodyInterface->CreateAndAddBody(settings, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddBody(settings, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Restitution: %.1f", double(settings.mRestitution)));
 	}
 
 	for (int i = 0; i <= 10; ++i)
@@ -37,6 +38,7 @@ void RestitutionTest::Initialize()
 		BodyCreationSettings settings(box, RVec3(-50.0f + i * 10.0f, 20.0f, 20.0f), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
 		settings.mRestitution = 0.1f * i;
 		settings.mLinearDamping = 0.0f;
-		mBodyInterface->CreateAndAddBody(settings, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddBody(settings, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Restitution: %.1f", double(settings.mRestitution)));
 	}
 }

+ 6 - 1
Samples/Tests/General/RestitutionTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests various different restitution values
 class RestitutionTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, RestitutionTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Bodies with varying restitutions.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 4 - 0
Samples/Tests/General/SensorTest.cpp

@@ -37,6 +37,7 @@ void SensorTest::Initialize()
 		BodyCreationSettings sensor_settings(new SphereShape(10.0f), RVec3(0, 10, 0), Quat::sIdentity(), EMotionType::Static, Layers::SENSOR);
 		sensor_settings.mIsSensor = true;
 		mSensorID[StaticAttractor] = mBodyInterface->CreateAndAddBody(sensor_settings, EActivation::DontActivate);
+		SetBodyLabel(mSensorID[StaticAttractor], "Static sensor that attracts dynamic bodies");
 	}
 
 	{
@@ -44,6 +45,7 @@ void SensorTest::Initialize()
 		BodyCreationSettings sensor_settings(new BoxShape(Vec3::sReplicate(5.0f)), RVec3(-10, 5.1f, 0), Quat::sIdentity(), EMotionType::Static, Layers::SENSOR);
 		sensor_settings.mIsSensor = true;
 		mSensorID[StaticSensor] = mBodyInterface->CreateAndAddBody(sensor_settings, EActivation::DontActivate);
+		SetBodyLabel(mSensorID[StaticSensor], "Static sensor that detects active dynamic bodies");
 	}
 
 	{
@@ -51,6 +53,7 @@ void SensorTest::Initialize()
 		BodyCreationSettings sensor_settings(new BoxShape(Vec3::sReplicate(5.0f)), RVec3(10, 5.1f, 0), Quat::sIdentity(), EMotionType::Kinematic, Layers::SENSOR);
 		sensor_settings.mIsSensor = true;
 		mSensorID[KinematicSensor] = mBodyInterface->CreateAndAddBody(sensor_settings, EActivation::Activate);
+		SetBodyLabel(mSensorID[KinematicSensor], "Kinematic sensor that also detects sleeping bodies");
 	}
 
 	{
@@ -59,6 +62,7 @@ void SensorTest::Initialize()
 		sensor_settings.mIsSensor = true;
 		sensor_settings.mCollideKinematicVsNonDynamic = true;
 		mSensorID[SensorDetectingStatic] = mBodyInterface->CreateAndAddBody(sensor_settings, EActivation::Activate);
+		SetBodyLabel(mSensorID[SensorDetectingStatic], "Kinematic sensor that also detects sleeping and static bodies");
 	}
 
 	// Dynamic bodies

+ 6 - 1
Samples/Tests/General/SensorTest.h

@@ -7,7 +7,6 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// Test that contains a sensor that will apply forces to bodies inside the sensor
 class SensorTest : public Test, public ContactListener
 {
 public:
@@ -15,6 +14,12 @@ public:
 
 	virtual				~SensorTest() override;
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Different types of sensors. See the description of each sensor.";
+	}
+
 	// Number used to scale the terrain and camera movement to the scene
 	virtual float		GetWorldScale() const override		{ return 0.2f; }
 

+ 6 - 1
Samples/Tests/General/ShapeFilterTest.h

@@ -2,12 +2,17 @@
 
 #include <Tests/Test.h>
 
-/// This test demonstrates how to use the ShapeFilter to filter out shapes during a collision query.
 class ShapeFilterTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, ShapeFilterTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Demonstrates how to use a shape filter to filter out shapes during a collision query.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PostPhysicsUpdate(float inDeltaTime) override;

+ 8 - 3
Samples/Tests/General/SimCollideBodyVsBodyTest.h

@@ -6,14 +6,19 @@
 
 #include <Tests/Test.h>
 
-// Test that overrides the collide body vs body function on the simulation to reduce the number of contact points generated
-// between sensors and other objects in the simulation. This can be useful to improve performance if you don't need to know
-// about all contact points and are only interested in an overlap/no-overlap result.
 class SimCollideBodyVsBodyTest : public Test, public ContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SimCollideBodyVsBodyTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Overrides the collide body vs body function on the simulation to reduce the number of contact points generated between sensors and other objects in the simulation.\n"
+				"This can be useful to improve performance if you don't need to know about all contact points and are only interested in an overlap/no-overlap result.\n"
+				"The static world consists of a single compound shape with many pyramid sub shapes.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 	virtual void		PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 7 - 1
Samples/Tests/General/SimShapeFilterTest.h

@@ -7,12 +7,18 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Collision/SimShapeFilter.h>
 
-// This test shows how to use a shape filter during the simulation to disable contacts between certain sub shapes
 class SimShapeFilterTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SimShapeFilterTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Shows how to use a shape filter during the simulation to disable contacts between certain sub shapes.\n"
+				"The rod and sphere of the dynamic bodies only collide with the floor.";
+	}
+
 	// Destructor
 	virtual				~SimShapeFilterTest() override;
 

+ 6 - 1
Samples/Tests/General/SimpleTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/BodyActivationListener.h>
 
-// This is a very basic test that just drops a few objects on the floor
 class SimpleTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SimpleTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Very basic test that just drops a few objects on the floor.";
+	}
+
 	// Destructor
 	virtual				~SimpleTest() override;
 

+ 6 - 1
Samples/Tests/General/StackTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test stacks a number of boxes to see if the simulation is stable
 class StackTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, StackTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Stacks a number of boxes to see if the simulation is stable.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/TwoDFunnelTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This is a test that shows how to create a 2D simulation
 class TwoDFunnelTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, TwoDFunnelTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows how to create a 2D simulation.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/General/WallTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests a large pile of boxes to check stacking and performance behavior.
 class WallTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, WallTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"Tests a large pile of boxes to check stacking and performance behavior.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 7 - 1
Samples/Tests/Rig/BigWorldTest.h

@@ -7,12 +7,18 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test tests the performance of a pile of ragdolls on a terrain at various distances from the origin.
 class BigWorldTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, BigWorldTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return	"Tests the stability of a pile of ragdolls on a terrain at various distances from the origin.\n"
+				"Renders far away ragdoll piles at the origin in wireframe.";
+	}
+
 	// Destructor
 	virtual					~BigWorldTest() override;
 

+ 6 - 1
Samples/Tests/Rig/CreateRigTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test demonstrates how to create a ragdoll from code
 class CreateRigTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, CreateRigTest)
 
+	// Description of the test
+	virtual const char *			GetDescription() const override
+	{
+		return "Demonstrates how to create a ragdoll from code.";
+	}
+
 	// Destructor
 	virtual							~CreateRigTest() override;
 

+ 6 - 1
Samples/Tests/Rig/KinematicRigTest.h

@@ -11,12 +11,17 @@
 #include <Utils/RagdollLoader.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test tests a kinematic ragdoll moving towards a wall of boxes
 class KinematicRigTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, KinematicRigTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Tests a kinematic ragdoll moving towards a wall of boxes.";
+	}
+
 	// Destructor
 	virtual					~KinematicRigTest() override;
 

+ 6 - 1
Samples/Tests/Rig/LoadRigTest.h

@@ -8,12 +8,17 @@
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 #include <Utils/RagdollLoader.h>
 
-// This test loads a ragdoll from disc and simulates it
 class LoadRigTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, LoadRigTest)
 
+	// Description of the test
+	virtual const char *			GetDescription() const override
+	{
+		return "Loads a ragdoll from disc and simulates it.";
+	}
+
 	// Destructor
 	virtual							~LoadRigTest() override;
 

+ 6 - 1
Samples/Tests/Rig/LoadSaveBinaryRigTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test loads a ragdoll from disc, writes it to a binary stream, loads it again and simulates it
 class LoadSaveBinaryRigTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, LoadSaveBinaryRigTest)
 
+	// Description of the test
+	virtual const char *			GetDescription() const override
+	{
+		return "Loads a ragdoll from disc, writes it to a binary stream, loads it again and simulates it.";
+	}
+
 	// Destructor
 	virtual							~LoadSaveBinaryRigTest() override;
 

+ 6 - 1
Samples/Tests/Rig/LoadSaveRigTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test loads a ragdoll from disc, writes it to an object stream, loads it again and simulates it
 class LoadSaveRigTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, LoadSaveRigTest)
 
+	// Description of the test
+	virtual const char *			GetDescription() const override
+	{
+		return "Loads a ragdoll from disc, writes it to an object stream, loads it again and simulates it.";
+	}
+
 	// Destructor
 	virtual							~LoadSaveRigTest() override;
 

+ 6 - 1
Samples/Tests/Rig/PoweredRigTest.h

@@ -10,12 +10,17 @@
 #include <Jolt/Skeleton/SkeletonPose.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test demonstrates powered constraints. It can either show a ragdoll in a static pose or in an animated pose (e.g. walk).
 class PoweredRigTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, PoweredRigTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Demonstrates how to use motors to drive a ragdoll to a pose.";
+	}
+
 	// Destructor
 	virtual					~PoweredRigTest() override;
 

+ 6 - 1
Samples/Tests/Rig/RigPileTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test tests the performance of a pile of ragdolls on a terrain.
 class RigPileTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, RigPileTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Tests the performance of a pile of ragdolls on a terrain.";
+	}
+
 	// Destructor
 	virtual					~RigPileTest() override;
 

+ 6 - 1
Samples/Tests/Rig/SkeletonMapperTest.h

@@ -12,12 +12,17 @@
 #include <Utils/RagdollLoader.h>
 #include <Jolt/Physics/Ragdoll/Ragdoll.h>
 
-// This test takes shows how you can map a high detail animation skeleton on a low detail physics skeleton and back
 class SkeletonMapperTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SkeletonMapperTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows how you can map a high detail animation skeleton on a low detail physics skeleton and back.";
+	}
+
 	// Destructor
 	virtual					~SkeletonMapperTest() override;
 

+ 6 - 1
Samples/Tests/ScaledShapes/DynamicScaledShape.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// Demonstrates how you can scale a shape dynamically while a body is being simulated
 class DynamicScaledShape : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, DynamicScaledShape)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Demonstrates how you can scale a shape dynamically while a body is being simulated.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 6 - 1
Samples/Tests/Shapes/DeformedHeightFieldShapeTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Collision/Shape/HeightFieldShape.h>
 
-// This test shows how to deform a height field shape after it has been created
 class DeformedHeightFieldShapeTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, DeformedHeightFieldShapeTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows how to deform a height field shape after it has been created.";
+	}
+
 	// Initialize the test
 	virtual void			Initialize() override;
 

+ 6 - 1
Samples/Tests/Shapes/MeshShapeUserDataTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// Shows how to store per triangle user data in a mesh shape and how to retrieve it
 class MeshShapeUserDataTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, MeshShapeUserDataTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows how to store per triangle user data in a mesh shape and how to retrieve it.";
+	}
+
 	// See: Test
 	virtual void	Initialize() override;
 	virtual void	PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyBendConstraintTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows the effect of bend constraints in a soft body.
 class SoftBodyBendConstraintTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyBendConstraintTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows the effect of bend constraint type in a soft body.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 	virtual void			PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 10 - 3
Samples/Tests/SoftBody/SoftBodyContactListenerTest.cpp

@@ -30,6 +30,13 @@ void SoftBodyContactListenerTest::Initialize()
 	StartCycle();
 }
 
+void SoftBodyContactListenerTest::UpdateLabel()
+{
+	// Draw current state
+	const char *cycle_names[] = { "Accept contact", "Sphere 10x mass", "Cloth 10x mass", "Sphere infinite mass", "Cloth infinite mass", "Sensor contact", "Reject contact", "Kinematic Sphere", "Kinematic Sphere, cloth infinite mass", "Kinematic sphere, sensor contact", "Kinematic Sphere, reject contact" };
+	SetBodyLabel(mOtherBodyID, cycle_names[mCycle]);
+}
+
 void SoftBodyContactListenerTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
 {
 	mTime += inParams.mDeltaTime;
@@ -49,9 +56,7 @@ void SoftBodyContactListenerTest::PrePhysicsUpdate(const PreUpdateParams &inPara
 		StartCycle();
 	}
 
-	// Draw current state
-	const char *cycle_names[] = { "Accept contact", "Sphere 10x mass", "Cloth 10x mass", "Sphere infinite mass", "Cloth infinite mass", "Sensor contact", "Reject contact", "Kinematic Sphere", "Kinematic Sphere, cloth infinite mass", "Kinematic sphere, sensor contact", "Kinematic Sphere, reject contact" };
-	mDebugRenderer->DrawText3D(mBodyInterface->GetPosition(mOtherBodyID), cycle_names[mCycle], Color::sWhite, 1.0f);
+	UpdateLabel();
 }
 
 void SoftBodyContactListenerTest::StartCycle()
@@ -75,6 +80,8 @@ void SoftBodyContactListenerTest::StartCycle()
 	if (kinematic)
 		bcs.mLinearVelocity = Vec3(0, -2.5f, 0);
 	mOtherBodyID = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
+
+	UpdateLabel();
 }
 
 SoftBodyValidateResult SoftBodyContactListenerTest::OnSoftBodyContactValidate(const Body &inSoftBody, const Body &inOtherBody, SoftBodyContactSettings &ioSettings)

+ 8 - 1
Samples/Tests/SoftBody/SoftBodyContactListenerTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/SoftBody/SoftBodyContactListener.h>
 
-// This test shows how to use contact listeners for soft bodies
 class SoftBodyContactListenerTest : public Test, public SoftBodyContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyContactListenerTest)
 
+	// Description of the test
+	virtual const char *			GetDescription() const override
+	{
+		return "Shows how to use contact listeners for soft bodies to affect the simulation.";
+	}
+
 	// See: Test
 	virtual void					Initialize() override;
 	virtual void					PrePhysicsUpdate(const PreUpdateParams &inParams) override;
@@ -26,6 +31,8 @@ public:
 	virtual void					OnSoftBodyContactAdded(const Body &inSoftBody, const SoftBodyManifold &inManifold) override;
 
 private:
+	void							UpdateLabel();
+
 	void							StartCycle();
 
 	float							mTime = 0.0f;

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyCustomUpdateTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows how you can update a soft body outside of the main physics simulation step
 class SoftBodyCustomUpdateTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyCustomUpdateTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows how you can update a soft body outside of the main physics simulation step.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 	virtual void		PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyForceTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows how to apply a global force to a soft body
 class SoftBodyForceTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyForceTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows how to apply a global force to a soft body.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 	virtual void		PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 4 - 2
Samples/Tests/SoftBody/SoftBodyFrictionTest.cpp

@@ -31,7 +31,8 @@ void SoftBodyFrictionTest::Initialize()
 	{
 		sphere.mPosition = RVec3(-50.0f + i * 10.0f, 1.0f, 0);
 		sphere.mFriction = 0.1f * i;
-		mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Friction: %.1f", double(sphere.mFriction)));
 	}
 
 	Ref<SoftBodySharedSettings> cube_settings = SoftBodySharedSettings::sCreateCube(5, 0.5f);
@@ -43,6 +44,7 @@ void SoftBodyFrictionTest::Initialize()
 	{
 		cube.mPosition = RVec3(-50.0f + i * 10.0f, 1.0f, -5.0f);
 		cube.mFriction = 0.1f * i;
-		mBodyInterface->CreateAndAddSoftBody(cube, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(cube, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Friction: %.1f", double(cube.mFriction)));
 	}
 }

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyFrictionTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests soft bodies with various values for friction
 class SoftBodyFrictionTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyFrictionTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Tests soft bodies with various values for friction. Note that this has very little effect.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 4 - 2
Samples/Tests/SoftBody/SoftBodyGravityFactorTest.cpp

@@ -27,7 +27,8 @@ void SoftBodyGravityFactorTest::Initialize()
 	{
 		sphere.mPosition = RVec3(-50.0f + i * 10.0f, 10.0f, 0);
 		sphere.mGravityFactor = 0.1f * i;
-		mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("GravityFactor: %.1f", double(sphere.mGravityFactor)));
 	}
 
 	SoftBodyCreationSettings cube(SoftBodySharedSettings::sCreateCube(5, 0.5f), RVec3::sZero(), Quat::sIdentity(), Layers::MOVING);
@@ -36,6 +37,7 @@ void SoftBodyGravityFactorTest::Initialize()
 	{
 		cube.mPosition = RVec3(-50.0f + i * 10.0f, 10.0f, -5.0f);
 		cube.mGravityFactor = 0.1f * i;
-		mBodyInterface->CreateAndAddSoftBody(cube, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(cube, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("GravityFactor: %.1f", double(cube.mGravityFactor)));
 	}
 }

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyGravityFactorTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests soft bodies with various gravity factor values
 class SoftBodyGravityFactorTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyGravityFactorTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows soft bodies with various gravity factor values.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyKinematicTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests soft bodies with kinematic vertices
 class SoftBodyKinematicTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyKinematicTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows how to make a soft body vertex kinematic and control it.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 	virtual void		PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyLRAConstraintTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows the effect of LRA constraints in a soft body which can help reduce stretch of the cloth. The left cloth uses no LRA constraints and the right one does.
 class SoftBodyLRAConstraintTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyLRAConstraintTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows the effect of Long Range Attachment (LRA) constraints in a soft body which can help reduce cloth stretching.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 	virtual void			PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 2 - 1
Samples/Tests/SoftBody/SoftBodyPressureTest.cpp

@@ -26,6 +26,7 @@ void SoftBodyPressureTest::Initialize()
 	{
 		sphere.mPosition = RVec3(-50.0f + i * 10.0f, 10.0f, 0);
 		sphere.mPressure = 1000.0f * i;
-		mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Pressure: %g", double(sphere.mPressure)));
 	}
 }

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyPressureTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests soft bodies with various values for pressure
 class SoftBodyPressureTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyPressureTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Tests soft bodies with various values for internal pressure.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 4 - 2
Samples/Tests/SoftBody/SoftBodyRestitutionTest.cpp

@@ -28,7 +28,8 @@ void SoftBodyRestitutionTest::Initialize()
 	{
 		sphere.mPosition = RVec3(-50.0f + i * 10.0f, 10.0f, 0);
 		sphere.mRestitution = 0.1f * i;
-		mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Restitution: %.1f", double(sphere.mRestitution)));
 	}
 
 	SoftBodyCreationSettings cube(SoftBodySharedSettings::sCreateCube(5, 0.5f), RVec3::sZero(), Quat::sIdentity(), Layers::MOVING);
@@ -37,6 +38,7 @@ void SoftBodyRestitutionTest::Initialize()
 	{
 		cube.mPosition = RVec3(-50.0f + i * 10.0f, 10.0f, -5.0f);
 		cube.mRestitution = 0.1f * i;
-		mBodyInterface->CreateAndAddSoftBody(cube, EActivation::Activate);
+		BodyID id = mBodyInterface->CreateAndAddSoftBody(cube, EActivation::Activate);
+		SetBodyLabel(id, StringFormat("Restitution: %.1f", double(cube.mRestitution)));
 	}
 }

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyRestitutionTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test tests soft bodies with various values for restitution
 class SoftBodyRestitutionTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyRestitutionTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Tests soft bodies with various values for restitution. Note that this has very little effect.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/SoftBody/SoftBodySensorTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/SoftBody/SoftBodyContactListener.h>
 
-// This test shows interaction between a soft body and a sensor
 class SoftBodySensorTest : public Test, public SoftBodyContactListener
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodySensorTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows interaction between a soft body and a sensor.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyShapesTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows interaction between various collision shapes and soft bodies
 class SoftBodyShapesTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyShapesTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows interaction between various collision shapes and soft bodies.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/SoftBody/SoftBodySkinnedConstraintTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/Body/Body.h>
 
-// This test shows how to skin a soft body to a skeleton and control the animation.
 class SoftBodySkinnedConstraintTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodySkinnedConstraintTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows how to attach a soft body to a skinned mesh and control the animation.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 	virtual void			PrePhysicsUpdate(const PreUpdateParams &inParams) override;

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyStressTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test stresses the soft body system by creating a large number of soft bodies / a soft body with many vertices
 class SoftBodyStressTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyStressTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Stresses the soft body system by creating a large number of soft bodies / a soft body with many vertices.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 

+ 2 - 1
Samples/Tests/SoftBody/SoftBodyUpdatePositionTest.cpp

@@ -28,6 +28,7 @@ void SoftBodyUpdatePositionTest::Initialize()
 			sphere.mPosition = RVec3(update_position * 10.0f, 10.0f, make_rotation_identity * 10.0f);
 			sphere.mUpdatePosition = update_position != 0;
 			sphere.mMakeRotationIdentity = make_rotation_identity != 0;
-			mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+			BodyID id = mBodyInterface->CreateAndAddSoftBody(sphere, EActivation::Activate);
+			SetBodyLabel(id, StringFormat("UpdatePosition: %s\nMakeRotationIdentity: %s", update_position != 0? "On" : "Off", make_rotation_identity != 0? "On" : "Off"));
 		}
 }

+ 8 - 3
Samples/Tests/SoftBody/SoftBodyUpdatePositionTest.h

@@ -6,14 +6,19 @@
 
 #include <Tests/Test.h>
 
-// This test tests soft bodies with and without 'update position' and 'make rotation identity'
-// If you turn on 'Draw World Transforms' you will see that 2 cubes will stay at their initial position.
-// If you turn on 'Draw Bounding Boxes' then you will see that the cubes that didn't have 'make rotation identity' will have a bigger bounding box.
 class SoftBodyUpdatePositionTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyUpdatePositionTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return	"This test tests soft bodies with and without 'update position' and 'make rotation identity'.\n"
+				"The labels of the bodies that don't update their position will stay in place.\n"
+				"If you turn on 'Draw Bounding Boxes' then you will see that the cubes that with 'make rotation identity' have a smaller bounding box.\n";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyVertexRadiusTest.h

@@ -7,12 +7,17 @@
 #include <Tests/Test.h>
 #include <Jolt/Physics/SoftBody/SoftBodySharedSettings.h>
 
-// This test shows how you can use the vertex radius of a soft body to prevent z-fighting while rendering it
 class SoftBodyVertexRadiusTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyVertexRadiusTest)
 
+	// Description of the test
+	virtual const char *	GetDescription() const override
+	{
+		return "Shows how you can use the vertex radius of a soft body to prevent z-fighting while rendering it.";
+	}
+
 	// See: Test
 	virtual void			Initialize() override;
 

+ 6 - 1
Samples/Tests/SoftBody/SoftBodyVsFastMovingTest.h

@@ -6,12 +6,17 @@
 
 #include <Tests/Test.h>
 
-// This test shows interaction between a fast moving (CCD) object and a soft body
 class SoftBodyVsFastMovingTest : public Test
 {
 public:
 	JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, SoftBodyVsFastMovingTest)
 
+	// Description of the test
+	virtual const char *GetDescription() const override
+	{
+		return "Shows interaction between a fast moving (CCD) object and a soft body.";
+	}
+
 	// See: Test
 	virtual void		Initialize() override;
 };

+ 14 - 0
Samples/Tests/Test.cpp

@@ -11,6 +11,7 @@
 #include <Jolt/Physics/Collision/Shape/HeightFieldShape.h>
 #include <Jolt/Physics/Body/BodyCreationSettings.h>
 #include <Layers.h>
+#include <Renderer/DebugRendererImp.h>
 
 JPH_IMPLEMENT_RTTI_ABSTRACT(Test)
 {
@@ -170,3 +171,16 @@ Body &Test::CreateHeightFieldTerrain()
 	mBodyInterface->AddBody(floor.GetID(), EActivation::DontActivate);
 	return floor;
 }
+
+void Test::DrawBodyLabels()
+{
+	for (const BodyLabels::value_type &l : mBodyLabels)
+	{
+		BodyLockRead body_lock(mPhysicsSystem->GetBodyLockInterface(), l.first);
+		if (body_lock.Succeeded())
+		{
+			const Body &body = body_lock.GetBody();
+			mDebugRenderer->DrawText3D(body.GetPosition(), l.second, Color::sWhite, GetWorldScale() * 0.5f);
+		}
+	}
+}

+ 12 - 0
Samples/Tests/Test.h

@@ -39,6 +39,9 @@ public:
 	// Set the temp allocator
 	void			SetTempAllocator(TempAllocator *inTempAllocator)			{ mTempAllocator = inTempAllocator; }
 
+	// Description of the test
+	virtual const char *GetDescription() const									{ return nullptr; }
+
 	// Initialize the test
 	virtual void	Initialize()												{ }
 
@@ -107,6 +110,9 @@ public:
 	// Return a string that is displayed in the top left corner of the screen
 	virtual String	GetStatusString() const										{ return String(); }
 
+	// Draw the body labels
+	void			DrawBodyLabels();
+
 protected:
 	// Utility function to create a static floor body
 	Body &			CreateFloor(float inSize = 200.0f);
@@ -118,6 +124,9 @@ protected:
 	Body &			CreateMeshTerrain();
 	Body &			CreateHeightFieldTerrain();
 
+	// Add a label to a body
+	void			SetBodyLabel(const BodyID &inBodyID, const String &inLabel)	{ mBodyLabels[inBodyID] = inLabel; }
+
 	JobSystem *		mJobSystem = nullptr;
 	PhysicsSystem *	mPhysicsSystem = nullptr;
 	BodyInterface *	mBodyInterface = nullptr;
@@ -126,4 +135,7 @@ protected:
 
 private:
 	bool			mNeedsRestart = false;
+
+	using BodyLabels = unordered_map<BodyID, String>;
+	BodyLabels		mBodyLabels;
 };

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików