From 6cbfb012439b275ee335f38ed353b1b92009ff64 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Thu, 7 Dec 2023 16:45:14 +0100 Subject: [PATCH] JoltPhysics3D: Allow raycast to return hit characters (and retrieve their entities) --- .../Nazara/JoltPhysics3D/JoltAbstractBody.hpp | 32 +++++++++++++++++++ .../Nazara/JoltPhysics3D/JoltAbstractBody.inl | 12 +++++++ .../Nazara/JoltPhysics3D/JoltCharacter.hpp | 10 ++++-- .../Nazara/JoltPhysics3D/JoltCharacter.inl | 14 ++++++-- .../Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp | 4 ++- .../Nazara/JoltPhysics3D/JoltRigidBody3D.hpp | 5 +-- .../Nazara/JoltPhysics3D/JoltRigidBody3D.inl | 5 --- .../Systems/JoltPhysics3DSystem.hpp | 6 ++-- src/Nazara/JoltPhysics3D/JoltAbstractBody.cpp | 11 +++++++ src/Nazara/JoltPhysics3D/JoltCharacter.cpp | 22 ++++++++++++- src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp | 4 +-- src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp | 5 +++ 12 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 include/Nazara/JoltPhysics3D/JoltAbstractBody.hpp create mode 100644 include/Nazara/JoltPhysics3D/JoltAbstractBody.inl create mode 100644 src/Nazara/JoltPhysics3D/JoltAbstractBody.cpp diff --git a/include/Nazara/JoltPhysics3D/JoltAbstractBody.hpp b/include/Nazara/JoltPhysics3D/JoltAbstractBody.hpp new file mode 100644 index 000000000..829ad4e68 --- /dev/null +++ b/include/Nazara/JoltPhysics3D/JoltAbstractBody.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_JOLTPHYSICS3D_JOLTABSTRACTBODY_HPP +#define NAZARA_JOLTPHYSICS3D_JOLTABSTRACTBODY_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_JOLTPHYSICS3D_API JoltAbstractBody + { + public: + JoltAbstractBody() = default; + JoltAbstractBody(const JoltAbstractBody&) = delete; + JoltAbstractBody(JoltAbstractBody&&) = delete; + virtual ~JoltAbstractBody(); + + virtual UInt32 GetBodyIndex() const = 0; + + JoltAbstractBody& operator=(const JoltAbstractBody&) = delete; + JoltAbstractBody& operator=(JoltAbstractBody&&) = delete; + }; +} + +#include + +#endif // NAZARA_JOLTPHYSICS3D_JOLTABSTRACTBODY_HPP diff --git a/include/Nazara/JoltPhysics3D/JoltAbstractBody.inl b/include/Nazara/JoltPhysics3D/JoltAbstractBody.inl new file mode 100644 index 000000000..b33ed0a27 --- /dev/null +++ b/include/Nazara/JoltPhysics3D/JoltAbstractBody.inl @@ -0,0 +1,12 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ +} + +#include diff --git a/include/Nazara/JoltPhysics3D/JoltCharacter.hpp b/include/Nazara/JoltPhysics3D/JoltCharacter.hpp index cad95a7e4..d05a7b4ef 100644 --- a/include/Nazara/JoltPhysics3D/JoltCharacter.hpp +++ b/include/Nazara/JoltPhysics3D/JoltCharacter.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,7 @@ namespace Nz class JoltCollider3D; class JoltPhysWorld3D; - class NAZARA_JOLTPHYSICS3D_API JoltCharacter : public JoltPhysicsStepListener + class NAZARA_JOLTPHYSICS3D_API JoltCharacter : public JoltAbstractBody, public JoltPhysicsStepListener { friend JoltPhysWorld3D; @@ -42,11 +43,14 @@ namespace Nz inline void DisableSleeping(); void EnableSleeping(bool enable); - inline UInt32 GetBodyIndex() const; + UInt32 GetBodyIndex() const override; + inline const std::shared_ptr& GetCollider() const; Vector3f GetLinearVelocity() const; - Quaternionf GetRotation() const; + inline JoltPhysWorld3D& GetPhysWorld(); + inline const JoltPhysWorld3D& GetPhysWorld() const; Vector3f GetPosition() const; std::pair GetPositionAndRotation() const; + Quaternionf GetRotation() const; Vector3f GetUp() const; bool IsOnGround() const; diff --git a/include/Nazara/JoltPhysics3D/JoltCharacter.inl b/include/Nazara/JoltPhysics3D/JoltCharacter.inl index aaeba430a..6b998766f 100644 --- a/include/Nazara/JoltPhysics3D/JoltCharacter.inl +++ b/include/Nazara/JoltPhysics3D/JoltCharacter.inl @@ -11,9 +11,19 @@ namespace Nz return EnableSleeping(false); } - inline UInt32 JoltCharacter::GetBodyIndex() const + inline const std::shared_ptr& JoltCharacter::GetCollider() const { - return m_bodyIndex; + return m_collider; + } + + inline JoltPhysWorld3D& JoltCharacter::GetPhysWorld() + { + return *m_world; + } + + inline const JoltPhysWorld3D& JoltCharacter::GetPhysWorld() const + { + return *m_world; } inline void JoltCharacter::SetImpl(std::shared_ptr characterImpl) diff --git a/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp b/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp index e5143e037..118985eb1 100644 --- a/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp +++ b/include/Nazara/JoltPhysics3D/JoltPhysWorld3D.hpp @@ -27,8 +27,10 @@ namespace JPH namespace Nz { + class JoltAbstractBody; class JoltCharacter; class JoltCharacterImpl; + class JoltCollider3D; class JoltPhysicsStepListener; class JoltRigidBody3D; @@ -75,7 +77,7 @@ namespace Nz struct RaycastHit { float fraction; - JoltRigidBody3D* hitBody = nullptr; + JoltAbstractBody* hitBody = nullptr; Vector3f hitNormal; Vector3f hitPosition; }; diff --git a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp index 8559c3685..a194d5eb8 100644 --- a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp +++ b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ namespace Nz { class JoltPhysWorld3D; - class NAZARA_JOLTPHYSICS3D_API JoltRigidBody3D + class NAZARA_JOLTPHYSICS3D_API JoltRigidBody3D : public JoltAbstractBody { public: struct DynamicSettings; @@ -54,7 +55,7 @@ namespace Nz Vector3f GetAngularVelocity() const; inline JPH::Body* GetBody(); inline const JPH::Body* GetBody() const; - inline UInt32 GetBodyIndex() const; + UInt32 GetBodyIndex() const override; inline const std::shared_ptr& GetGeom() const; float GetLinearDamping() const; Vector3f GetLinearVelocity() const; diff --git a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl index e231de3e9..65a4b3157 100644 --- a/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl +++ b/include/Nazara/JoltPhysics3D/JoltRigidBody3D.inl @@ -36,11 +36,6 @@ namespace Nz return m_body; } - inline UInt32 JoltRigidBody3D::GetBodyIndex() const - { - return m_bodyIndex; - } - inline const std::shared_ptr& JoltRigidBody3D::GetGeom() const { return m_geom; diff --git a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp index dc43c6813..900ad1db5 100644 --- a/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp +++ b/include/Nazara/JoltPhysics3D/Systems/JoltPhysics3DSystem.hpp @@ -51,8 +51,9 @@ namespace Nz private: void OnBodyConstruct(entt::registry& registry, entt::entity entity); - void OnCharacterConstruct(entt::registry& registry, entt::entity entity); void OnBodyDestruct(entt::registry& registry, entt::entity entity); + void OnCharacterConstruct(entt::registry& registry, entt::entity entity); + void OnCharacterDestruct(entt::registry& registry, entt::entity entity); std::size_t m_stepCount; std::vector m_bodyIndicesToEntity; @@ -60,8 +61,9 @@ namespace Nz entt::observer m_characterConstructObserver; entt::observer m_rigidBodyConstructObserver; entt::scoped_connection m_bodyConstructConnection; - entt::scoped_connection m_characterConstructConnection; entt::scoped_connection m_bodyDestructConnection; + entt::scoped_connection m_characterConstructConnection; + entt::scoped_connection m_characterDestructConnection; JoltPhysWorld3D m_physWorld; }; } diff --git a/src/Nazara/JoltPhysics3D/JoltAbstractBody.cpp b/src/Nazara/JoltPhysics3D/JoltAbstractBody.cpp new file mode 100644 index 000000000..9aa8871b7 --- /dev/null +++ b/src/Nazara/JoltPhysics3D/JoltAbstractBody.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) +// This file is part of the "Nazara Engine - JoltPhysics3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + JoltAbstractBody::~JoltAbstractBody() = default; +} diff --git a/src/Nazara/JoltPhysics3D/JoltCharacter.cpp b/src/Nazara/JoltPhysics3D/JoltCharacter.cpp index fe4365e27..5d28b0a7b 100644 --- a/src/Nazara/JoltPhysics3D/JoltCharacter.cpp +++ b/src/Nazara/JoltPhysics3D/JoltCharacter.cpp @@ -29,7 +29,13 @@ namespace Nz m_bodyIndex(character.m_bodyIndex) { character.m_bodyIndex = std::numeric_limits::max(); - + + if (m_character) + { + JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterfaceNoLock(); + bodyInterface.SetUserData(m_character->GetBodyID(), SafeCast(reinterpret_cast(this))); + } + if (m_world) { m_world->UnregisterStepListener(&character); @@ -52,6 +58,11 @@ namespace Nz bodyLock.GetBody().SetAllowSleeping(enable); } + UInt32 JoltCharacter::GetBodyIndex() const + { + return m_bodyIndex; + } + Vector3f JoltCharacter::GetLinearVelocity() const { return FromJolt(m_character->GetLinearVelocity(false)); @@ -135,6 +146,12 @@ namespace Nz character.m_bodyIndex = std::numeric_limits::max(); + if (m_character) + { + JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterfaceNoLock(); + bodyInterface.SetUserData(m_character->GetBodyID(), SafeCast(reinterpret_cast(this))); + } + return *this; } @@ -157,6 +174,9 @@ namespace Nz m_bodyIndex = m_character->GetBodyID().GetIndex(); + JPH::BodyInterface& bodyInterface = m_world->GetPhysicsSystem()->GetBodyInterfaceNoLock(); + bodyInterface.SetUserData(m_character->GetBodyID(), SafeCast(reinterpret_cast(this))); + m_world->RegisterStepListener(this); } diff --git a/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp b/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp index 941b4307b..ad359c7e6 100644 --- a/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp +++ b/src/Nazara/JoltPhysics3D/JoltPhysWorld3D.cpp @@ -186,7 +186,7 @@ namespace Nz JPH::Body& body = lock.GetBody(); - hitInfo.hitBody = reinterpret_cast(static_cast(body.GetUserData())); + hitInfo.hitBody = reinterpret_cast(static_cast(body.GetUserData())); hitInfo.hitNormal = FromJolt(body.GetWorldSpaceSurfaceNormal(result.mSubShapeID2, ToJolt(hitInfo.hitPosition))); if (auto fractionOpt = m_callback(hitInfo)) @@ -387,7 +387,7 @@ namespace Nz RaycastHit hitInfo; hitInfo.fraction = collector.mHit.GetEarlyOutFraction(); hitInfo.hitPosition = Lerp(from, to, hitInfo.fraction); - hitInfo.hitBody = reinterpret_cast(static_cast(body.GetUserData())); + hitInfo.hitBody = reinterpret_cast(static_cast(body.GetUserData())); hitInfo.hitNormal = FromJolt(body.GetWorldSpaceSurfaceNormal(collector.mHit.mSubShapeID2, rayCast.GetPointOnRay(collector.mHit.GetEarlyOutFraction()))); callback(hitInfo); diff --git a/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp b/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp index ba6a19cc3..3ef4760d7 100644 --- a/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp +++ b/src/Nazara/JoltPhysics3D/JoltRigidBody3D.cpp @@ -120,6 +120,11 @@ namespace Nz return FromJolt(m_body->GetAngularVelocity()); } + UInt32 JoltRigidBody3D::GetBodyIndex() const + { + return m_bodyIndex; + } + float JoltRigidBody3D::GetLinearDamping() const { if NAZARA_UNLIKELY(IsStatic())