From e7edb9d38cc324436e028213e96af460b69d5d17 Mon Sep 17 00:00:00 2001 From: GoaLitiuM Date: Mon, 5 Apr 2021 19:36:36 +0300 Subject: [PATCH] Add sweep and overlap physics queries for capsule shapes --- Source/Engine/Physics/Physics.Queries.cpp | 90 +++++++++++++++++++++++ Source/Engine/Physics/Physics.h | 79 ++++++++++++++++++++ 2 files changed, 169 insertions(+) diff --git a/Source/Engine/Physics/Physics.Queries.cpp b/Source/Engine/Physics/Physics.Queries.cpp index 15630e7ff..6cf3c786d 100644 --- a/Source/Engine/Physics/Physics.Queries.cpp +++ b/Source/Engine/Physics/Physics.Queries.cpp @@ -358,6 +358,51 @@ bool Physics::SphereCastAll(const Vector3& center, const float radius, const Vec return true; } +bool Physics::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers) +{ + // Prepare data + SCENE_QUERY_SETUP_SWEEP_1(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxCapsuleGeometry geometry(radius, height * 0.5f); + + // Perform sweep test + return GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()); +} + +bool Physics::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers) +{ + // Prepare data + SCENE_QUERY_SETUP_SWEEP_1(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxCapsuleGeometry geometry(radius, height * 0.5f); + + // Perform sweep test + if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback())) + return false; + + // Collect results + SCENE_QUERY_COLLECT_SINGLE(); + + return true; +} + +bool Physics::CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, Array& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers) +{ + // Prepare data + SCENE_QUERY_SETUP_SWEEP(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxCapsuleGeometry geometry(radius, height * 0.5f); + + // Perform sweep test + if (!GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback())) + return false; + + // Collect results + SCENE_QUERY_COLLECT_ALL(); + + return true; +} + bool Physics::CheckBox(const Vector3& center, const Vector3& halfExtents, const Quaternion& rotation, uint32 layerMask, bool hitTriggers) { // Prepare data @@ -380,6 +425,17 @@ bool Physics::CheckSphere(const Vector3& center, const float radius, uint32 laye return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()); } +bool Physics::CheckCapsule(const Vector3& center, const float radius, const float height, uint32 layerMask, bool hitTriggers) +{ + // Prepare data + SCENE_QUERY_SETUP_OVERLAP_1(); + const PxTransform pose(C2P(center)); + const PxCapsuleGeometry geometry(radius, height * 0.5f); + + // Perform overlap test + return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()); +} + bool Physics::OverlapBox(const Vector3& center, const Vector3& halfExtents, Array& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers) { // Prepare data @@ -414,6 +470,23 @@ bool Physics::OverlapSphere(const Vector3& center, const float radius, Array& results, uint32 layerMask, bool hitTriggers) +{ + // Prepare data + SCENE_QUERY_SETUP_OVERLAP(); + const PxTransform pose(C2P(center)); + const PxCapsuleGeometry geometry(radius, height * 0.5f); + + // Perform overlap test + if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback())) + return false; + + // Collect results + SCENE_QUERY_COLLECT_OVERLAP_COLLIDER(); + + return true; +} + bool Physics::OverlapBox(const Vector3& center, const Vector3& halfExtents, Array& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers) { // Prepare data @@ -447,3 +520,20 @@ bool Physics::OverlapSphere(const Vector3& center, const float radius, Array& results, uint32 layerMask, bool hitTriggers) +{ + // Prepare data + SCENE_QUERY_SETUP_OVERLAP(); + const PxTransform pose(C2P(center)); + const PxCapsuleGeometry geometry(radius, height * 0.5f); + + // Perform overlap test + if (!GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback())) + return false; + + // Collect results + SCENE_QUERY_COLLECT_OVERLAP(); + + return true; +} diff --git a/Source/Engine/Physics/Physics.h b/Source/Engine/Physics/Physics.h index 05b64cb0f..275ae9cb9 100644 --- a/Source/Engine/Physics/Physics.h +++ b/Source/Engine/Physics/Physics.h @@ -276,6 +276,50 @@ public: /// True if sphere hits an matching object, otherwise false. API_FUNCTION() static bool SphereCastAll(const Vector3& center, float radius, const Vector3& direction, API_PARAM(Out) Array& results, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Performs a sweep test against objects in the scene using a capsule geometry. + /// + /// The box center. + /// The radius of the capsule. + /// The height of the capsule, excluding the top and bottom spheres. + /// The normalized direction in which cast a box. + /// The capsule rotation. + /// The maximum distance the ray should check for collisions. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if capsule hits an matching object, otherwise false. + API_FUNCTION() static bool CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + + /// + /// Performs a sweep test against objects in the scene using a capsule geometry. + /// + /// The box center. + /// The radius of the capsule. + /// The height of the capsule, excluding the top and bottom spheres. + /// The normalized direction in which cast a box. + /// The result hit information. Valid only when method returns true. + /// The capsule rotation. + /// The maximum distance the ray should check for collisions. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if capsule hits an matching object, otherwise false. + API_FUNCTION() static bool CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, API_PARAM(Out) RayCastHit& hitInfo, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + + /// + /// Performs a sweep test against objects in the scene using a capsule geometry. + /// + /// The box center. + /// The radius of the capsule. + /// The height of the capsule, excluding the top and bottom spheres. + /// The normalized direction in which cast a box. + /// The result hits. Valid only when method returns true. + /// The capsule rotation. + /// The maximum distance the ray should check for collisions. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if capsule hits an matching object, otherwise false. + API_FUNCTION() static bool CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, API_PARAM(Out) Array& results, const Quaternion& rotation = Quaternion::Identity, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// /// Checks whether the given box overlaps with other colliders or not. /// @@ -297,6 +341,17 @@ public: /// True if sphere overlaps any matching object, otherwise false. API_FUNCTION() static bool CheckSphere(const Vector3& center, float radius, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Checks whether the given capsule overlaps with other colliders or not. + /// + /// The sphere center. + /// The radius of the capsule. + /// The height of the capsule, excluding the top and bottom spheres. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if capsule overlaps any matching object, otherwise false. + API_FUNCTION() static bool CheckCapsule(const Vector3& center, float radius, float height, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// /// Finds all colliders touching or inside of the given box. /// @@ -320,6 +375,18 @@ public: /// True if sphere overlaps any matching object, otherwise false. API_FUNCTION() static bool OverlapSphere(const Vector3& center, float radius, API_PARAM(Out) Array& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Finds all colliders touching or inside of the given sphere. + /// + /// The sphere center. + /// The radius of the capsule. + /// The height of the capsule, excluding the top and bottom spheres. + /// The result colliders that overlap with the given sphere. Valid only when method returns true. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if capsule overlaps any matching object, otherwise false. + API_FUNCTION() static bool OverlapCapsule(const Vector3& center, float radius, float height, API_PARAM(Out) Array& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// /// Finds all colliders touching or inside of the given box. /// @@ -343,6 +410,18 @@ public: /// True if sphere overlaps any matching object, otherwise false. API_FUNCTION() static bool OverlapSphere(const Vector3& center, float radius, API_PARAM(Out) Array& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Finds all colliders touching or inside of the given sphere. + /// + /// The sphere center. + /// The radius of the capsule. + /// The height of the capsule, excluding the top and bottom spheres. + /// The result colliders that overlap with the given sphere. Valid only when method returns true. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if capsule overlaps any matching object, otherwise false. + API_FUNCTION() static bool OverlapCapsule(const Vector3& center, float radius, float height, API_PARAM(Out) Array& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + public: ///