From 1f6fc02c24e4e90f4fd398251df3ba782689dbe6 Mon Sep 17 00:00:00 2001 From: GoaLitiuM Date: Sun, 2 May 2021 18:50:37 +0300 Subject: [PATCH] Add physics queries for convex meshes --- Source/Engine/Physics/Physics.Queries.cpp | 103 +++++++++++++++++++++ Source/Engine/Physics/Physics.h | 105 +++++++++++++++++++--- 2 files changed, 197 insertions(+), 11 deletions(-) diff --git a/Source/Engine/Physics/Physics.Queries.cpp b/Source/Engine/Physics/Physics.Queries.cpp index 27171414b..d32a4affc 100644 --- a/Source/Engine/Physics/Physics.Queries.cpp +++ b/Source/Engine/Physics/Physics.Queries.cpp @@ -2,6 +2,7 @@ #include "Physics.h" #include "Utilities.h" +#include "CollisionData.h" #include "Actors/PhysicsColliderActor.h" #include #include @@ -403,6 +404,57 @@ bool Physics::CapsuleCastAll(const Vector3& center, const float radius, const fl return true; } +bool Physics::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers) +{ + CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false) + + // Prepare data + SCENE_QUERY_SETUP_SWEEP_1(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale))); + + // Perform sweep test + return GetScene()->sweep(geometry, pose, C2P(direction), maxDistance, buffer, hitFlags, filterData, GetQueryFilterCallback()); +} + +bool Physics::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers) +{ + CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false) + + // Prepare data + SCENE_QUERY_SETUP_SWEEP_1(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale))); + + // 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::ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, Array& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers) +{ + CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false) + + // Prepare data + SCENE_QUERY_SETUP_SWEEP(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale))); + + // 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 @@ -436,6 +488,19 @@ bool Physics::CheckCapsule(const Vector3& center, const float radius, const floa return GetScene()->overlap(geometry, pose, buffer, filterData, GetQueryFilterCallback()); } +bool Physics::CheckConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Quaternion& rotation, uint32 layerMask, bool hitTriggers) +{ + CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false) + + // Prepare data + SCENE_QUERY_SETUP_OVERLAP_1(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale))); + + // 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 @@ -487,6 +552,25 @@ bool Physics::OverlapCapsule(const Vector3& center, const float radius, const fl return true; } +bool Physics::OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, Array& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers) +{ + CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false) + + // Prepare data + SCENE_QUERY_SETUP_OVERLAP(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale))); + + // 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 @@ -537,3 +621,22 @@ bool Physics::OverlapCapsule(const Vector3& center, const float radius, const fl return true; } + +bool Physics::OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, Array& results, const Quaternion& rotation, uint32 layerMask, bool hitTriggers) +{ + CHECK_RETURN(convexMesh && convexMesh->GetOptions().Type == CollisionDataType::ConvexMesh, false) + + // Prepare data + SCENE_QUERY_SETUP_OVERLAP(); + const PxTransform pose(C2P(center), C2P(rotation)); + const PxConvexMeshGeometry geometry(convexMesh->GetConvex(), PxMeshScale(C2P(scale))); + + // 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 8aac37a2e..55ff70f31 100644 --- a/Source/Engine/Physics/Physics.h +++ b/Source/Engine/Physics/Physics.h @@ -11,6 +11,7 @@ class PhysicsColliderActor; class Joint; class Collider; +class CollisionData; /// /// Raycast hit result data. @@ -271,10 +272,10 @@ public: /// /// Performs a sweep test against objects in the scene using a capsule geometry. /// - /// The box center. + /// The capsule 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 normalized direction in which cast a capsule. /// The capsule rotation. /// The maximum distance the ray should check for collisions. /// The layer mask used to filter the results. @@ -285,10 +286,10 @@ public: /// /// Performs a sweep test against objects in the scene using a capsule geometry. /// - /// The box center. + /// The capsule 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 normalized direction in which cast a capsule. /// The result hit information. Valid only when method returns true. /// The capsule rotation. /// The maximum distance the ray should check for collisions. @@ -300,10 +301,10 @@ public: /// /// Performs a sweep test against objects in the scene using a capsule geometry. /// - /// The box center. + /// The capsule 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 normalized direction in which cast a capsule. /// The result hits. Valid only when method returns true. /// The capsule rotation. /// The maximum distance the ray should check for collisions. @@ -312,6 +313,50 @@ public: /// True if capsule hits an matching object, otherwise false. API_FUNCTION() static bool CapsuleCastAll(const Vector3& center, float radius, 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); + /// + /// Performs a sweep test against objects in the scene using a convex mesh. + /// + /// The convex mesh center. + /// Collision data of the convex mesh. + /// The scale of the convex mesh. + /// The normalized direction in which cast a convex mesh. + /// The convex mesh 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 convex mesh hits an matching object, otherwise false. + API_FUNCTION() static bool ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, 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 convex mesh. + /// + /// The convex mesh center. + /// Collision data of the convex mesh. + /// The scale of the convex mesh. + /// The normalized direction in which cast a convex mesh. + /// The result hit information. Valid only when method returns true. + /// The convex mesh 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 convex mesh hits an matching object, otherwise false. + API_FUNCTION() static bool ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, 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 convex mesh. + /// + /// The convex mesh center. + /// Collision data of the convex mesh. + /// The scale of the convex mesh. + /// The normalized direction in which cast a convex mesh. + /// The result hits. Valid only when method returns true. + /// The convex mesh 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 convex mesh hits an matching object, otherwise false. + API_FUNCTION() static bool ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, 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. /// @@ -345,6 +390,18 @@ public: /// True if capsule overlaps any matching object, otherwise false. API_FUNCTION() static bool CheckCapsule(const Vector3& center, float radius, float height, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Checks whether the given convex mesh overlaps with other colliders or not. + /// + /// The convex mesh center. + /// Collision data of the convex mesh. + /// The scale of the convex mesh. + /// The convex mesh rotation. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if convex mesh overlaps any matching object, otherwise false. + API_FUNCTION() static bool CheckConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// /// Finds all colliders touching or inside of the given box. /// @@ -369,18 +426,31 @@ public: 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. + /// Finds all colliders touching or inside of the given capsule. /// - /// The sphere center. + /// The capsule 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 result colliders that overlap with the given capsule. Valid only when method returns true. /// The capsule rotation. /// 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, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Finds all colliders touching or inside of the given convex mesh. + /// + /// The convex mesh center. + /// Collision data of the convex mesh. + /// The scale of the convex mesh. + /// The result colliders that overlap with the given convex mesh. Valid only when method returns true. + /// The convex mesh rotation. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if convex mesh overlaps any matching object, otherwise false. + API_FUNCTION() static bool OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, API_PARAM(Out) Array& results, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// /// Finds all colliders touching or inside of the given box. /// @@ -405,18 +475,31 @@ public: 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. + /// Finds all colliders touching or inside of the given capsule. /// /// The capsule 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 result colliders that overlap with the given capsule. Valid only when method returns true. /// The capsule rotation. /// 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, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + /// + /// Finds all colliders touching or inside of the given convex mesh. + /// + /// The convex mesh center. + /// Collision data of the convex mesh. + /// The scale of the convex mesh. + /// The result colliders that overlap with the given convex mesh. Valid only when method returns true. + /// The convex mesh rotation. + /// The layer mask used to filter the results. + /// If set to true triggers will be hit, otherwise will skip them. + /// True if convex mesh overlaps any matching object, otherwise false. + API_FUNCTION() static bool OverlapConvex(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, API_PARAM(Out) Array& results, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); + public: ///