#pragma once
#include "Engine/Scripting/ScriptingObject.h"
#include "Engine/Scripting/ScriptingType.h"
#include "Engine/Core/Math/Vector3.h"
#include "Engine/Core/Math/Quaternion.h"
#include "Types.h"
#if WITH_VEHICLE
class WheeledVehicle;
#endif
struct ActionData;
struct RayCastHit;
class FixedStepper;
class PhysicsSettings;
class PhysicsColliderActor;
class PhysicsScenePhysX;
class Joint;
class Collider;
class CollisionData;
///
/// Isolated physics scene.
///
API_CLASS(NoSpawn) class FLAXENGINE_API PhysicsScene : public PersistentScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(PhysicsScene);
explicit PhysicsScene(const String& name, const PhysicsSettings& settings);
~PhysicsScene();
///
/// Gets the name of the scene.
///
API_PROPERTY() String GetName() const;
public:
String ToString() const override
{
return GetName();
}
PxScene* GetScene();
///
/// The automatic simulation feature. True if perform physics simulation after on fixed update by auto, otherwise user should do it.
///
API_PROPERTY() bool GetAutoSimulation();
API_PROPERTY() void SetAutoSimulation(bool value);
///
/// Sets the current gravity force.
///
API_PROPERTY() void SetGravity(const Vector3& value);
///
/// Gets the current gravity force.
///
API_PROPERTY() Vector3 GetGravity();
///
/// Gets the CCD feature enable flag.
///
API_PROPERTY() bool GetEnableCCD();
///
/// Sets the CCD feature enable flag.
///
API_PROPERTY() void SetEnableCCD(const bool value);
///
/// Gets the minimum relative velocity required for an object to bounce.
///
API_PROPERTY() float GetBounceThresholdVelocity();
///
/// Sets the minimum relative velocity required for an object to bounce.
///
API_PROPERTY() void SetBounceThresholdVelocity(const float value);
///
/// Called during main engine loop to start physic simulation. Use CollectResults after.
///
/// The delta time (in seconds).
API_FUNCTION() void Simulate(float dt);
///
/// Checks if physical simulation is running
///
/// True if simulation is active, otherwise false
API_PROPERTY() bool IsDuringSimulation();
///
/// Called to collect physic simulation results and apply them as well as fire collision events.
///
API_FUNCTION() void CollectResults();
///
/// Flushes the async requests to add/remove actors, remove materials, etc..
///
void FlushRequests();
///
/// Removes the material (using safe async request).
///
/// The material.
void RemoveMaterial(PxMaterial* material);
///
/// Removes the physX object via calling release() on it (using safe async request).
///
/// The obj.
void RemoveObject(PxBase* obj);
///
/// Adds the actor (using safe async request).
///
/// The actor.
void AddActor(PxActor* actor);
///
/// Adds the actor (using safe async request).
///
/// The actor.
/// If set to true will put actor to sleep after spawning.
void AddActor(PxRigidDynamic* actor, bool putToSleep = false);
///
/// Removes the actor (using safe async request).
///
/// The actor.
void RemoveActor(PxActor* actor);
///
/// Removes the actor from the underlying physics scene without destroying it.
///
void UnlinkActor(PxActor* actor);
///
/// Marks that collider has been removed (all collision events should be cleared to prevent leaks of using removed object).
///
/// The collider.
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.
void RemoveJoint(Joint* joint);
///
/// Gets PhysX characters controller manager object
///
PxControllerManager* GetControllerManager();
public:
///
/// Gets the default query filter callback used for the scene queries.
///
PxQueryFilterCallback* GetQueryFilterCallback();
///
/// Gets the default query filter callback used for the character controller collisions detection.
///
PxQueryFilterCallback* GetCharacterQueryFilterCallback();
///
/// Gets the default controller filter callback used for the character controller collisions detection.
///
static PxControllerFilterCallback* GetCharacterControllerFilterCallback();
///
/// 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() 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() 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() 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() 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() 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() 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() 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() 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() 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 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 capsule.
/// 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() 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 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 capsule.
/// 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() 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 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 capsule.
/// 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() 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() 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() 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() 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.
///
/// 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() 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() 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() 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() 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.
///
/// 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() 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() 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 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 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() 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() 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.
///
/// 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() 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() 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 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 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() 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() 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:
#if WITH_VEHICLE
void AddWheeledVehicle(WheeledVehicle* vehicle);
void RemoveWheeledVehicle(WheeledVehicle* vehicle);
#endif
private:
String mName;
bool mAutoSimulation = true;
void* mScratchMemory = nullptr;
FixedStepper* mStepper = nullptr;
float mLastDeltaTime = 0.0f;
bool mIsDuringSimulation = false;
PhysicsScenePhysX* mPhysxImpl;
};