JoltPhysics3D: Rework RigidBody wrapper
- Add a clear way to setup dynamic/kinematic or static bodies - Body registration to the world is batched (all bodies created before a physics step are added together, which is what Jolt is optimized for) - Added support for empty shapes (= rigid bodies without collision) using a very small shape and tagging the body as sensor
This commit is contained in:
committed by
Jérôme Leclercq
parent
67b1710adb
commit
d610baf920
@@ -21,6 +21,12 @@ namespace Nz
|
||||
|
||||
Max = TranslatedRotatedDecoration
|
||||
};
|
||||
|
||||
enum class JoltMotionQuality
|
||||
{
|
||||
Discrete,
|
||||
LinearCast
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NAZARA_JOLTPHYSICS3D_ENUMS_HPP
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
|
||||
namespace JPH
|
||||
{
|
||||
class BodyID;
|
||||
class PhysicsSystem;
|
||||
class Shape;
|
||||
}
|
||||
|
||||
namespace Nz
|
||||
@@ -31,6 +33,7 @@ namespace Nz
|
||||
class NAZARA_JOLTPHYSICS3D_API JoltPhysWorld3D
|
||||
{
|
||||
friend JoltCharacter;
|
||||
friend JoltRigidBody3D;
|
||||
|
||||
public:
|
||||
struct RaycastHit;
|
||||
@@ -47,10 +50,13 @@ namespace Nz
|
||||
Time GetStepSize() const;
|
||||
|
||||
inline bool IsBodyActive(UInt32 bodyIndex) const;
|
||||
inline bool IsBodyRegistered(UInt32 bodyIndex) const;
|
||||
|
||||
bool RaycastQuery(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const RaycastHit& hitInfo)>& callback);
|
||||
bool RaycastQueryFirst(const Vector3f& from, const Vector3f& to, const FunctionRef<void(const RaycastHit& hitInfo)>& callback);
|
||||
|
||||
void RefreshBodies();
|
||||
|
||||
void SetGravity(const Vector3f& gravity);
|
||||
void SetMaxStepCount(std::size_t maxStepCount);
|
||||
void SetStepSize(Time stepSize);
|
||||
@@ -77,13 +83,19 @@ namespace Nz
|
||||
|
||||
struct JoltWorld;
|
||||
|
||||
const JPH::Shape* GetNullShape() const;
|
||||
|
||||
void OnPreStep(float deltatime);
|
||||
|
||||
void RegisterBody(const JPH::BodyID& bodyID, bool activate, bool removeFromDeactivationList);
|
||||
inline void RegisterCharacter(JoltCharacter* character);
|
||||
|
||||
void UnregisterBody(const JPH::BodyID& bodyID, bool destroy, bool removeFromRegisterList);
|
||||
inline void UnregisterCharacter(JoltCharacter* character);
|
||||
|
||||
std::size_t m_maxStepCount;
|
||||
std::unique_ptr<std::atomic_uint64_t[]> m_activeBodies;
|
||||
std::unique_ptr<std::uint64_t[]> m_registeredBodies;
|
||||
std::unique_ptr<JoltWorld> m_world;
|
||||
std::vector<JoltCharacter*> m_characters;
|
||||
Vector3f m_gravity;
|
||||
|
||||
@@ -14,6 +14,14 @@ namespace Nz
|
||||
return m_activeBodies[blockIndex] & (UInt64(1u) << localIndex);
|
||||
}
|
||||
|
||||
inline bool JoltPhysWorld3D::IsBodyRegistered(UInt32 bodyIndex) const
|
||||
{
|
||||
UInt32 blockIndex = bodyIndex / 64;
|
||||
UInt32 localIndex = bodyIndex % 64;
|
||||
|
||||
return m_registeredBodies[blockIndex] & (UInt64(1u) << localIndex);
|
||||
}
|
||||
|
||||
inline void JoltPhysWorld3D::RegisterCharacter(JoltCharacter* character)
|
||||
{
|
||||
auto it = std::lower_bound(m_characters.begin(), m_characters.end(), character);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
namespace JPH
|
||||
{
|
||||
class Body;
|
||||
class BodyCreationSettings;
|
||||
}
|
||||
|
||||
namespace Nz
|
||||
@@ -28,8 +29,11 @@ namespace Nz
|
||||
class NAZARA_JOLTPHYSICS3D_API JoltRigidBody3D
|
||||
{
|
||||
public:
|
||||
JoltRigidBody3D(JoltPhysWorld3D* world, const Matrix4f& mat = Matrix4f::Identity());
|
||||
JoltRigidBody3D(JoltPhysWorld3D* world, std::shared_ptr<JoltCollider3D> geom, const Matrix4f& mat = Matrix4f::Identity());
|
||||
struct DynamicSettings;
|
||||
struct StaticSettings;
|
||||
|
||||
JoltRigidBody3D(JoltPhysWorld3D& world, const DynamicSettings& settings);
|
||||
JoltRigidBody3D(JoltPhysWorld3D& world, const StaticSettings& settings);
|
||||
JoltRigidBody3D(const JoltRigidBody3D& object) = delete;
|
||||
JoltRigidBody3D(JoltRigidBody3D&& object) noexcept;
|
||||
~JoltRigidBody3D();
|
||||
@@ -38,7 +42,9 @@ namespace Nz
|
||||
void AddForce(const Vector3f& force, const Vector3f& point, CoordSys coordSys = CoordSys::Global);
|
||||
void AddTorque(const Vector3f& torque, CoordSys coordSys = CoordSys::Global);
|
||||
|
||||
inline void DisableSimulation();
|
||||
inline void DisableSleeping();
|
||||
void EnableSimulation(bool enable);
|
||||
void EnableSleeping(bool enable);
|
||||
|
||||
void FallAsleep();
|
||||
@@ -53,16 +59,16 @@ namespace Nz
|
||||
float GetLinearDamping() const;
|
||||
Vector3f GetLinearVelocity() const;
|
||||
float GetMass() const;
|
||||
Vector3f GetMassCenter(CoordSys coordSys = CoordSys::Local) const;
|
||||
Matrix4f GetMatrix() const;
|
||||
Vector3f GetPosition() const;
|
||||
std::pair<Vector3f, Quaternionf> GetPositionAndRotation() const;
|
||||
Quaternionf GetRotation() const;
|
||||
inline JoltPhysWorld3D* GetWorld() const;
|
||||
inline JoltPhysWorld3D& GetWorld() const;
|
||||
|
||||
bool IsSimulationEnabled() const;
|
||||
inline bool IsSimulationEnabled() const;
|
||||
bool IsSleeping() const;
|
||||
bool IsSleepingEnabled() const;
|
||||
bool IsStatic() const;
|
||||
|
||||
void SetAngularDamping(float angularDamping);
|
||||
void SetAngularVelocity(const Vector3f& angularVelocity);
|
||||
@@ -70,7 +76,6 @@ namespace Nz
|
||||
void SetLinearDamping(float damping);
|
||||
void SetLinearVelocity(const Vector3f& velocity);
|
||||
void SetMass(float mass, bool recomputeInertia = true);
|
||||
void SetMassCenter(const Vector3f& center);
|
||||
void SetPosition(const Vector3f& position);
|
||||
void SetRotation(const Quaternionf& rotation);
|
||||
|
||||
@@ -86,14 +91,53 @@ namespace Nz
|
||||
JoltRigidBody3D& operator=(const JoltRigidBody3D& object) = delete;
|
||||
JoltRigidBody3D& operator=(JoltRigidBody3D&& object) noexcept;
|
||||
|
||||
struct CommonSettings
|
||||
{
|
||||
std::shared_ptr<JoltCollider3D> geom;
|
||||
Quaternionf rotation = Quaternionf::Identity();
|
||||
Vector3f position = Vector3f::Zero();
|
||||
bool initiallySleeping = false;
|
||||
bool isSimulationEnabled = true;
|
||||
bool isTrigger = false;
|
||||
};
|
||||
|
||||
struct DynamicSettings : CommonSettings
|
||||
{
|
||||
// Default values from Jolt
|
||||
JoltMotionQuality motionQuality = JoltMotionQuality::Discrete;
|
||||
Vector3f angularVelocity = Vector3f::Zero();
|
||||
Vector3f linearVelocity = Vector3f::Zero();
|
||||
bool allowSleeping = true;
|
||||
float angularDamping = 0.05f;
|
||||
float friction = 0.2f;
|
||||
float gravityFactor = 1.f;
|
||||
float linearDamping = 0.05f;
|
||||
float mass = 1.f;
|
||||
float maxAngularVelocity = 0.25f * Pi<float> * 60.f;
|
||||
float maxLinearVelocity = 500.f;
|
||||
float restitution = 0.f;
|
||||
};
|
||||
|
||||
struct StaticSettings : CommonSettings
|
||||
{
|
||||
};
|
||||
|
||||
protected:
|
||||
void Destroy();
|
||||
void Destroy(bool worldDestruction = false);
|
||||
|
||||
private:
|
||||
void BuildSettings(const CommonSettings& settings, JPH::BodyCreationSettings& creationSettings);
|
||||
void BuildSettings(const DynamicSettings& settings, JPH::BodyCreationSettings& creationSettings);
|
||||
void BuildSettings(const StaticSettings& settings, JPH::BodyCreationSettings& creationSettings);
|
||||
|
||||
bool ShouldActivate() const;
|
||||
|
||||
std::shared_ptr<JoltCollider3D> m_geom;
|
||||
JPH::Body* m_body;
|
||||
JoltPhysWorld3D* m_world;
|
||||
UInt32 m_bodyIndex;
|
||||
bool m_isSimulationEnabled;
|
||||
bool m_isTrigger;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void JoltRigidBody3D::DisableSimulation()
|
||||
{
|
||||
return EnableSimulation(false);
|
||||
}
|
||||
|
||||
inline void JoltRigidBody3D::DisableSleeping()
|
||||
{
|
||||
return EnableSleeping(false);
|
||||
@@ -31,9 +36,14 @@ namespace Nz
|
||||
return m_geom;
|
||||
}
|
||||
|
||||
inline JoltPhysWorld3D* JoltRigidBody3D::GetWorld() const
|
||||
inline JoltPhysWorld3D& JoltRigidBody3D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
return *m_world;
|
||||
}
|
||||
|
||||
inline bool JoltRigidBody3D::IsSimulationEnabled() const
|
||||
{
|
||||
return m_isSimulationEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Nz
|
||||
template<typename... Args>
|
||||
JoltRigidBody3DComponent JoltPhysics3DSystem::CreateRigidBody(Args&&... args)
|
||||
{
|
||||
return JoltRigidBody3DComponent(&m_physWorld, std::forward<Args>(args)...);
|
||||
return JoltRigidBody3DComponent(m_physWorld, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline JoltPhysWorld3D& JoltPhysics3DSystem::GetPhysWorld()
|
||||
|
||||
Reference in New Issue
Block a user