DynamicScaledShape.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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/ScaledShapes/DynamicScaledShape.h>
  6. #include <Jolt/Physics/Collision/Shape/SphereShape.h>
  7. #include <Jolt/Physics/Collision/Shape/ScaledShape.h>
  8. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  9. #include <Layers.h>
  10. JPH_IMPLEMENT_RTTI_VIRTUAL(DynamicScaledShape)
  11. {
  12. JPH_ADD_BASE_CLASS(DynamicScaledShape, Test)
  13. }
  14. void DynamicScaledShape::Initialize()
  15. {
  16. // Floor
  17. CreateHeightFieldTerrain();
  18. // Create scaled sphere
  19. RefConst<Shape> scaled_sphere_shape = new ScaledShape(new SphereShape(2.0f), Vec3::sOne());
  20. mBodyID = mBodyInterface->CreateAndAddBody(BodyCreationSettings(scaled_sphere_shape, RVec3(0, 10, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING), EActivation::Activate);
  21. }
  22. void DynamicScaledShape::PrePhysicsUpdate(const PreUpdateParams &inParams)
  23. {
  24. // Update time
  25. mTime += inParams.mDeltaTime;
  26. BodyLockWrite lock(mPhysicsSystem->GetBodyLockInterface(), mBodyID);
  27. if (lock.Succeeded())
  28. {
  29. Body &body = lock.GetBody();
  30. // Fetch the inner shape
  31. // Note that we know here that the inner shape is the original shape, but if you're scaling a CompoundShape non-uniformly the inner shape
  32. // may be a new compound shape with the scale baked into the children. In this case you need to keep track of your original shape yourself.
  33. JPH_ASSERT(body.GetShape()->GetSubType() == EShapeSubType::Scaled);
  34. const ScaledShape *scaled_shape = static_cast<const ScaledShape *>(body.GetShape());
  35. const Shape *non_scaled_shape = scaled_shape->GetInnerShape();
  36. // Rescale the sphere
  37. float new_scale = 1.0f + 0.5f * Sin(mTime);
  38. Shape::ShapeResult new_shape = non_scaled_shape->ScaleShape(Vec3::sReplicate(new_scale));
  39. JPH_ASSERT(new_shape.IsValid()); // We're uniformly scaling a sphere, this should always succeed
  40. // Note: Using non-locking interface here because we already have the lock
  41. // Also note that scaling shapes may cause simulation issues as the bodies can get stuck when they get bigger.
  42. // Recalculating mass every frame can also be an expensive operation.
  43. mPhysicsSystem->GetBodyInterfaceNoLock().SetShape(body.GetID(), new_shape.Get(), true, EActivation::Activate);
  44. }
  45. }
  46. void DynamicScaledShape::SaveState(StateRecorder &inStream) const
  47. {
  48. inStream.Write(mTime);
  49. }
  50. void DynamicScaledShape::RestoreState(StateRecorder &inStream)
  51. {
  52. inStream.Read(mTime);
  53. }