// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Math/Vector2.h" #include "Engine/Core/Math/Vector3.h" #include "Engine/Core/Math/Quaternion.h" #include "Engine/Scripting/ScriptingType.h" #include "Types.h" class PhysicsColliderActor; class Joint; class Collider; /// /// Raycast hit result data. /// API_STRUCT() struct RayCastHit { DECLARE_SCRIPTING_TYPE_NO_SPAWN(RayCastHit); /// /// The collider that was hit. /// API_FIELD() PhysicsColliderActor* Collider; /// /// The normal of the surface the ray hit. /// API_FIELD() Vector3 Normal; /// /// The distance from the ray's origin to the hit location. /// API_FIELD() float Distance; /// /// The point in the world space where ray hit the collider. /// API_FIELD() Vector3 Point; /// /// The barycentric coordinates of hit point, for triangle mesh and height field. /// API_FIELD() Vector2 UV; public: /// /// Gathers the data from the specified hit (PhysX). /// /// The hit. void Gather(const PxRaycastHit& hit); /// /// Gathers the data from the specified hit (PhysX). /// /// The hit. void Gather(const PxSweepHit& hit); }; /// /// Physics simulation system. /// API_CLASS(Static) class FLAXENGINE_API Physics { DECLARE_SCRIPTING_TYPE_NO_SPAWN(Physics); /// /// Gets the master physics object. /// static PxPhysics* GetPhysics(); #if COMPILE_WITH_PHYSICS_COOKING /// /// Gets physics cooking object /// static PxCooking* GetCooking(); #endif /// /// Gets PhysX scene object /// static PxScene* GetScene(); /// /// Gets PhysX characters controller manager object /// static PxControllerManager* GetControllerManager(); /// /// Gets the physics tolerances scale. /// static PxTolerancesScale* GetTolerancesScale(); /// /// Gets the default query filter callback used for the scene queries. /// static PxQueryFilterCallback* GetQueryFilterCallback(); /// /// Gets the default query filter callback used for the character controller collisions detection. /// static PxQueryFilterCallback* GetCharacterQueryFilterCallback(); /// /// Gets the default physical material. /// static PxMaterial* GetDefaultMaterial(); public: /// /// The automatic simulation feature. True if perform physics simulation after on fixed update by auto, otherwise user should do it. /// API_FIELD() static bool AutoSimulation; /// /// Gets the current gravity force. /// API_PROPERTY() static Vector3 GetGravity(); /// /// Sets the current gravity force. /// API_PROPERTY() static void SetGravity(const Vector3& value); /// /// Gets the CCD feature enable flag. /// API_PROPERTY() static bool GetEnableCCD(); /// /// Sets the CCD feature enable flag. /// API_PROPERTY() static void SetEnableCCD(bool value); /// /// Gets the minimum relative velocity required for an object to bounce. /// API_PROPERTY() static float GetBounceThresholdVelocity(); /// /// Sets the minimum relative velocity required for an object to bounce. /// API_PROPERTY() static void SetBounceThresholdVelocity(float value); /// /// The collision layers masks. Used to define layer-based collision detection. /// static uint32 LayerMasks[32]; public: /// /// Performs a raycast against objects in the scene. /// /// The origin of the ray. /// The normalized direction of the ray. /// 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 ray hits an matching object, otherwise false. API_FUNCTION() static bool RayCast(const Vector3& origin, const Vector3& direction, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Performs a raycast against objects in the scene, returns results in a RayCastHit structure. /// /// The origin of the ray. /// The normalized direction of the ray. /// The result hit information. Valid only when method returns true. /// 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 ray hits an matching object, otherwise false. API_FUNCTION() static bool RayCast(const Vector3& origin, const Vector3& direction, API_PARAM(Out) RayCastHit& hitInfo, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Performs a raycast against objects in the scene, returns results in a RayCastHit structure. /// /// The origin of the ray. /// The normalized direction of the ray. /// The result hits. Valid only when method returns true. /// 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 ray hits an matching object, otherwise false. API_FUNCTION() static bool RayCastAll(const Vector3& origin, 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 box geometry. /// /// The box center. /// The half size of the box in each direction. /// The normalized direction in which cast a box. /// The box 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 box hits an matching object, otherwise false. API_FUNCTION() static bool BoxCast(const Vector3& center, const Vector3& halfExtents, 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 box geometry. /// /// The box center. /// The half size of the box in each direction. /// The normalized direction in which cast a box. /// The result hit information. Valid only when method returns true. /// The box 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 box hits an matching object, otherwise false. API_FUNCTION() static bool BoxCast(const Vector3& center, const Vector3& halfExtents, 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 box geometry. /// /// The box center. /// The half size of the box in each direction. /// The normalized direction in which cast a box. /// The result hits. Valid only when method returns true. /// The box 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 box hits an matching object, otherwise false. API_FUNCTION() static bool BoxCastAll(const Vector3& center, const Vector3& halfExtents, 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 sphere geometry. /// /// The sphere center. /// The radius of the sphere. /// The normalized direction in which cast a sphere. /// 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 sphere hits an matching object, otherwise false. API_FUNCTION() static bool SphereCast(const Vector3& center, float radius, const Vector3& direction, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Performs a sweep test against objects in the scene using a sphere geometry. /// /// The sphere center. /// The radius of the sphere. /// The normalized direction in which cast a sphere. /// The result hit information. Valid only when method returns true. /// 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 sphere hits an matching object, otherwise false. API_FUNCTION() static bool SphereCast(const Vector3& center, float radius, const Vector3& direction, API_PARAM(Out) RayCastHit& hitInfo, float maxDistance = MAX_float, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Performs a sweep test against objects in the scene using a sphere geometry. /// /// The sphere center. /// The radius of the sphere. /// The normalized direction in which cast a sphere. /// The result hits. Valid only when method returns true. /// 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 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, float radius, 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, float radius, 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, 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); /// /// Checks whether the given box overlaps with other colliders or not. /// /// The box center. /// The half size of the box in each direction. /// The box rotation. /// The layer mask used to filter the results. /// If set to true triggers will be hit, otherwise will skip them. /// True if box overlaps any matching object, otherwise false. API_FUNCTION() static bool CheckBox(const Vector3& center, const Vector3& halfExtents, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Checks whether the given sphere overlaps with other colliders or not. /// /// The sphere center. /// The radius of the sphere. /// The layer mask used to filter the results. /// If set to true triggers will be hit, otherwise will skip them. /// 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 capsule center. /// The radius of the capsule. /// The height of the capsule, excluding the top and bottom spheres. /// 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 CheckCapsule(const Vector3& center, float radius, float height, const Quaternion& rotation = Quaternion::Identity, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Finds all colliders touching or inside of the given box. /// /// The box center. /// The half size of the box in each direction. /// The box rotation. /// The result colliders that overlap with the given box. 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 box overlaps any matching object, otherwise false. API_FUNCTION() static bool OverlapBox(const Vector3& center, const Vector3& halfExtents, 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 sphere. /// /// The sphere center. /// The radius of the sphere. /// 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 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 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 box. /// /// The box center. /// The half size of the box in each direction. /// The box rotation. /// The result colliders that overlap with the given box. 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 box overlaps any matching object, otherwise false. API_FUNCTION() static bool OverlapBox(const Vector3& center, const Vector3& halfExtents, 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 sphere. /// /// The sphere center. /// The radius of the sphere. /// 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 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 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 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); public: /// /// Called during main engine loop to start physic simulation. Use CollectResults after. /// /// The delta time (in seconds). API_FUNCTION() static void Simulate(float dt); /// /// Called during main engine loop to collect physic simulation results and apply them as well as fire collision events. /// API_FUNCTION() static void CollectResults(); /// /// Checks if physical simulation is running /// /// True if simulation is active, otherwise false API_PROPERTY() static bool IsDuringSimulation(); public: /// /// Flushes the async requests to add/remove actors, remove materials, etc.. /// static void FlushRequests(); /// /// Removes the material (using safe async request). /// /// The material. static void RemoveMaterial(PxMaterial* material); /// /// Removes the physX object via calling release() on it (using safe async request). /// /// The obj. static void RemoveObject(PxBase* obj); /// /// Adds the actor (using safe async request). /// /// The actor. static void AddActor(PxActor* actor); /// /// Adds the actor (using safe async request). /// /// The actor. /// If set to true will put actor to sleep after spawning. static void AddActor(PxRigidDynamic* actor, bool putToSleep = false); /// /// Removes the actor (using safe async request). /// /// The actor. static void RemoveActor(PxActor* actor); /// /// Marks that collider has been removed (all collision events should be cleared to prevent leaks of using removed object). /// /// The collider. static void RemoveCollider(PhysicsColliderActor* collider); /// /// Marks that joint has been removed (all collision events should be cleared to prevent leaks of using removed object). /// /// The joint. static void RemoveJoint(Joint* joint); };