// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Math/Vector3.h" #include "Engine/Core/Math/Quaternion.h" #include "Engine/Scripting/ScriptingObject.h" #include "Types.h" struct ActionData; struct RayCastHit; class PhysicsSettings; class PhysicsColliderActor; class Joint; class Collider; class CollisionData; #if WITH_VEHICLE class WheeledVehicle; #endif /// /// Physical simulation scene. /// API_CLASS() class FLAXENGINE_API PhysicsScene : public ScriptingObject { DECLARE_SCRIPTING_TYPE(PhysicsScene); private: String _name; bool _autoSimulation = true; bool _isDuringSimulation = false; Vector3 _origin = Vector3::Zero; void* _scene = nullptr; public: ~PhysicsScene(); /// /// Gets the name of the scene. /// API_PROPERTY() String GetName() const; /// /// Gets the native physics system scene object. /// FORCE_INLINE void* GetPhysicsScene() const { return _scene; } /// /// Gets the automatic simulation feature that perform physics simulation after on fixed update by auto, otherwise user should do it. /// API_PROPERTY() bool GetAutoSimulation() const; /// /// Sets the automatic simulation feature that perform physics simulation after on fixed update by auto, otherwise user should do it. /// API_PROPERTY() void SetAutoSimulation(bool value); /// /// Gets the current gravity force. /// API_PROPERTY() Vector3 GetGravity() const; /// /// Sets the current gravity force. /// API_PROPERTY() void SetGravity(const Vector3& value); /// /// Gets the CCD feature enable flag. /// API_PROPERTY() bool GetEnableCCD() const; /// /// Sets the CCD feature enable flag. /// API_PROPERTY() void SetEnableCCD(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(float value); /// /// Gets the current scene origin that defines the center of the simulation (in world). Can be used to run physics simulation relative to the camera. /// API_PROPERTY() FORCE_INLINE Vector3 GetOrigin() const { return _origin; } /// /// Sets the current scene origin that defines the center of the simulation (in world). Can be used to run physics simulation relative to the camera. /// API_PROPERTY() void SetOrigin(const Vector3& value); #if COMPILE_WITH_PROFILER /// /// Gets the physics simulation statistics for the scene. /// API_PROPERTY() PhysicsStatistics GetStatistics() const; #endif public: /// /// Initializes the scene. /// /// The name. /// The physics settings. /// True if failed, otherwise false. bool Init(const StringView& name, const PhysicsSettings& settings); /// /// 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. /// API_PROPERTY() bool IsDuringSimulation() const; /// /// Called to collect physic simulation results and apply them as well as fire collision events. /// API_FUNCTION() void CollectResults(); public: /// /// Performs a line between two points in the scene. /// /// The start position of the line. /// The end position of the line. /// 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 LineCast(const Vector3& start, const Vector3& end, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// Performs a line between two points in the scene. /// /// The start position of the line. /// The end position of the line. /// The result hit information. 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 ray hits an matching object, otherwise false. API_FUNCTION() bool LineCast(const Vector3& start, const Vector3& end, API_PARAM(Out) RayCastHit& hitInfo, uint32 layerMask = MAX_uint32, bool hitTriggers = true); // /// Performs a line between two points in the scene, returns all hitpoints infos. /// /// The origin of the ray. /// The normalized direction of the ray. /// The result hits. 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 ray hits an matching object, otherwise false. API_FUNCTION() bool LineCastAll(const Vector3& start, const Vector3& end, API_PARAM(Out) Array& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true); /// /// 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); };