JoltPhysics3D: Add raycast hit normal

This commit is contained in:
SirLynix 2023-03-30 13:23:05 +02:00 committed by Jérôme Leclercq
parent 1387ac6e35
commit d697450a60
2 changed files with 21 additions and 9 deletions

View File

@ -15,6 +15,7 @@
#include <NazaraUtils/FunctionRef.hpp>
#include <NazaraUtils/MovablePtr.hpp>
#include <atomic>
#include <optional>
#include <vector>
namespace JPH
@ -63,6 +64,7 @@ namespace Nz
{
float fraction;
JoltRigidBody3D* hitBody = nullptr;
Vector3f hitNormal;
Vector3f hitPosition;
};

View File

@ -163,7 +163,7 @@ namespace Nz
{
namespace NAZARA_ANONYMOUS_NAMESPACE
{
class CallbackHitResult : public JPH::RayCastBodyCollector
class CallbackHitResult : public JPH::CastRayCollector
{
public:
CallbackHitResult(const JPH::BodyLockInterface& bodyLockInterface, const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const JoltPhysWorld3D::RaycastHit& hitInfo)>& callback) :
@ -175,7 +175,7 @@ namespace Nz
{
}
void AddHit(const JPH::BroadPhaseCastResult& result) override
void AddHit(const JPH::RayCastResult& result) override
{
JoltPhysWorld3D::RaycastHit hitInfo;
hitInfo.fraction = result.mFraction;
@ -185,7 +185,10 @@ namespace Nz
if (!lock.Succeeded())
return; //< body was destroyed
hitInfo.hitBody = reinterpret_cast<JoltRigidBody3D*>(static_cast<std::uintptr_t>(lock.GetBody().GetUserData()));
JPH::Body& body = lock.GetBody();
hitInfo.hitBody = reinterpret_cast<JoltRigidBody3D*>(static_cast<std::uintptr_t>(body.GetUserData()));
hitInfo.hitNormal = FromJolt(body.GetWorldSpaceSurfaceNormal(result.mSubShapeID2, ToJolt(hitInfo.hitPosition)));
if (auto fractionOpt = m_callback(hitInfo))
{
@ -336,24 +339,28 @@ namespace Nz
bool JoltPhysWorld3D::RaycastQuery(const Vector3f& from, const Vector3f& to, const FunctionRef<std::optional<float>(const RaycastHit& hitInfo)>& callback)
{
JPH::RayCast rayCast;
JPH::RRayCast rayCast;
rayCast.mDirection = ToJolt(to - from);
rayCast.mOrigin = ToJolt(from);
JPH::RayCastSettings rayCastSettings;
CallbackHitResult collector(m_world->physicsSystem.GetBodyLockInterface(), from, to, callback);
m_world->physicsSystem.GetBroadPhaseQuery().CastRay(rayCast, collector);
m_world->physicsSystem.GetNarrowPhaseQuery().CastRay(rayCast, rayCastSettings, collector);
return collector.DidHit();
}
bool JoltPhysWorld3D::RaycastQueryFirst(const Vector3f& from, const Vector3f& to, const FunctionRef<void(const RaycastHit& hitInfo)>& callback)
{
JPH::RayCast rayCast;
JPH::RRayCast rayCast;
rayCast.mDirection = ToJolt(to - from);
rayCast.mOrigin = ToJolt(from);
JPH::ClosestHitCollisionCollector<JPH::RayCastBodyCollector> collector;
m_world->physicsSystem.GetBroadPhaseQuery().CastRay(rayCast, collector);
JPH::RayCastSettings rayCastSettings;
JPH::ClosestHitCollisionCollector<JPH::CastRayCollector> collector;
m_world->physicsSystem.GetNarrowPhaseQuery().CastRay(rayCast, rayCastSettings, collector);
if (!collector.HadHit())
return false;
@ -362,10 +369,13 @@ namespace Nz
if (!lock.Succeeded())
return false; //< body was destroyed before lock
JPH::Body& body = lock.GetBody();
RaycastHit hitInfo;
hitInfo.fraction = collector.mHit.GetEarlyOutFraction();
hitInfo.hitPosition = Lerp(from, to, hitInfo.fraction);
hitInfo.hitBody = reinterpret_cast<JoltRigidBody3D*>(static_cast<std::uintptr_t>(lock.GetBody().GetUserData()));
hitInfo.hitBody = reinterpret_cast<JoltRigidBody3D*>(static_cast<std::uintptr_t>(body.GetUserData()));
hitInfo.hitNormal = FromJolt(body.GetWorldSpaceSurfaceNormal(collector.mHit.mSubShapeID2, rayCast.GetPointOnRay(collector.mHit.GetEarlyOutFraction())));
return true;
}