diff --git a/include/NovelRT/NovelRT.h b/include/NovelRT/NovelRT.h index f73ace5e3..30bc428aa 100644 --- a/include/NovelRT/NovelRT.h +++ b/include/NovelRT/NovelRT.h @@ -94,6 +94,9 @@ // Persistence types #include + // Physics types + #include + //Misc types #include #include diff --git a/include/NovelRT/Physics/2D/BodyDefinition2D.hpp b/include/NovelRT/Physics/2D/BodyDefinition2D.hpp new file mode 100644 index 000000000..aa4c39302 --- /dev/null +++ b/include/NovelRT/Physics/2D/BodyDefinition2D.hpp @@ -0,0 +1,30 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct BodyDefinition2D final + { + std::optional OnCollisionEnter; + std::optional OnCollisionExit; + std::optional OnTriggerEnter; + std::optional OnTriggerExit; + NovelRT::Maths::GeoVector2F Position; + NovelRT::Maths::GeoVector2F LinearVelocity; + NovelRT::Maths::GeoVector2F AngularVelocity; + NovelRT::Maths::GeoVector2F Gravity; + float RotationAngle; + float LinearDamping; + float AngularDamping; + RigidBodyFlags2D Flags; + }; +} + +// TODO: when implementing box2d, instead of relying on gravity scale, set it to 1 or 0 (depending on +// BodyFlags::UseWorldGravity) and apply a constant force during the world step. \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/BoxCollisionFixture2D.hpp b/include/NovelRT/Physics/2D/BoxCollisionFixture2D.hpp new file mode 100644 index 000000000..d13e379c9 --- /dev/null +++ b/include/NovelRT/Physics/2D/BoxCollisionFixture2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class BoxCollisionFixture2D : public CollisionFixture2D + { + public: + [[nodiscard]] virtual NovelRT::Maths::GeoVector2F GetHalfSize() = 0; + + virtual void SetHalfSize(NovelRT::Maths::GeoVector2F halfSize) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/BoxCollisionFixtureDefinition2D.hpp b/include/NovelRT/Physics/2D/BoxCollisionFixtureDefinition2D.hpp new file mode 100644 index 000000000..ac2f9f0b3 --- /dev/null +++ b/include/NovelRT/Physics/2D/BoxCollisionFixtureDefinition2D.hpp @@ -0,0 +1,15 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct BoxCollisionFixtureDefinition2D final : public CollisionFixtureDefinition2D + { + NovelRT::Maths::GeoVector2F HalfSize; + + ~BoxCollisionFixtureDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CapsuleCollisionFixture2D.hpp b/include/NovelRT/Physics/2D/CapsuleCollisionFixture2D.hpp new file mode 100644 index 000000000..752143a23 --- /dev/null +++ b/include/NovelRT/Physics/2D/CapsuleCollisionFixture2D.hpp @@ -0,0 +1,20 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class CapsuleCollisionFixture2D : public CollisionFixture2D + { + public: + [[nodiscard]] virtual float GetHeight() = 0; + + [[nodiscard]] virtual float GetRadius() = 0; + + virtual void SetHeight(float height) = 0; + + virtual void SetRadius(float radius) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CapsuleCollisionFixtureDefinition2D.hpp b/include/NovelRT/Physics/2D/CapsuleCollisionFixtureDefinition2D.hpp new file mode 100644 index 000000000..4ee0e5a66 --- /dev/null +++ b/include/NovelRT/Physics/2D/CapsuleCollisionFixtureDefinition2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct CapsuleCollisionFixtureDefinition2D final : public CollisionFixtureDefinition2D + { + float Height; + float Radius; + + ~CapsuleCollisionFixtureDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CircleCollisionFixture2D.hpp b/include/NovelRT/Physics/2D/CircleCollisionFixture2D.hpp new file mode 100644 index 000000000..17aedb825 --- /dev/null +++ b/include/NovelRT/Physics/2D/CircleCollisionFixture2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class CircleCollisionFixture2D : public CollisionFixture2D + { + [[nodiscard]] virtual float GetRadius() = 0; + + virtual void SetRadius() = 0; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CircleCollisionFixtureDefinition2D.hpp b/include/NovelRT/Physics/2D/CircleCollisionFixtureDefinition2D.hpp new file mode 100644 index 000000000..67c588c4b --- /dev/null +++ b/include/NovelRT/Physics/2D/CircleCollisionFixtureDefinition2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct CircleCollisionFixtureDefinition2D final : public CollisionFixtureDefinition2D + { + float Radius; + + ~CircleCollisionFixtureDefinition2D() = default; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CollisionCallbackArgument2D.hpp b/include/NovelRT/Physics/2D/CollisionCallbackArgument2D.hpp new file mode 100644 index 000000000..d84a6ef4c --- /dev/null +++ b/include/NovelRT/Physics/2D/CollisionCallbackArgument2D.hpp @@ -0,0 +1,15 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct CollisionCallBackArgument2D final + { + const RigidBody2D* const RigidBody; + const CollisionFixture2D* const CollisionFixture; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CollisionFixture2D.hpp b/include/NovelRT/Physics/2D/CollisionFixture2D.hpp new file mode 100644 index 000000000..f79355c1c --- /dev/null +++ b/include/NovelRT/Physics/2D/CollisionFixture2D.hpp @@ -0,0 +1,37 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class CollisionFixture2D + { + public: + [[nodiscard]] virtual NovelRT::Maths::GeoVector2F GetOffset() = 0; + + [[nodiscard]] virtual float GetFriction() = 0; + + [[nodiscard]] virtual float GetRestitution() = 0; + + [[nodiscard]] virtual float GetRestitutionThreshold() = 0; + + [[nodiscard]] virtual float GetDensity() = 0; + + [[nodiscard]] virtual bool IsSensor() = 0; + + virtual void SetOffset(NovelRT::Maths::GeoVector2F offset) = 0; + + virtual void SetFriction(float friction) = 0; + + virtual void SetRestitution(float restitution) = 0; + + virtual void SetRestitutionThreshold(float restitutionThreshold) = 0; + + virtual void SetDensity(float density) = 0; + + virtual void SetIsSensor(bool isSensor) = 0; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/CollisionFixtureDefinition2D.hpp b/include/NovelRT/Physics/2D/CollisionFixtureDefinition2D.hpp new file mode 100644 index 000000000..e6d63721b --- /dev/null +++ b/include/NovelRT/Physics/2D/CollisionFixtureDefinition2D.hpp @@ -0,0 +1,21 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct CollisionFixtureDefinition2D + { + NovelRT::Maths::GeoVector2F Offset; + float Friction; + float Restitution; + float RestitutionThreshold; + float Density; + bool IsSensor; + + virtual ~CollisionFixtureDefinition2D() = 0; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/DistanceJoint2D.hpp b/include/NovelRT/Physics/2D/DistanceJoint2D.hpp new file mode 100644 index 000000000..c69ccfb97 --- /dev/null +++ b/include/NovelRT/Physics/2D/DistanceJoint2D.hpp @@ -0,0 +1,45 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + /** + * @brief + * A joint that keeps the anchors of the attached bodies within a certain range of distance. + */ + class DistanceJoint2D : public Joint2D + { + protected: + float _minLength; + float _maxLength; + float _restLength; + + public: + [[nodiscard]] inline float GetMinLength() const noexcept + { + return _minLength; + } + + [[nodiscard]] inline float GetMaxLength() const noexcept + { + return _minLength; + } + + [[nodiscard]] inline float GetRestLength() const noexcept + { + return _minLength; + } + + virtual void SetMinLength(float minLength) = 0; + + virtual void SetMaxLength(float maxLength) = 0; + + virtual void SetRestLength(float restLength) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/DistanceJointDefinition2D.hpp b/include/NovelRT/Physics/2D/DistanceJointDefinition2D.hpp new file mode 100644 index 000000000..0b602a236 --- /dev/null +++ b/include/NovelRT/Physics/2D/DistanceJointDefinition2D.hpp @@ -0,0 +1,20 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct DistanceJointDefinition2D final : public JointDefinition2D + { + float MinLength; + float MaxLength; + float RestLength; + + ~DistanceJointDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/EdgeCollisionFixture2D.hpp b/include/NovelRT/Physics/2D/EdgeCollisionFixture2D.hpp new file mode 100644 index 000000000..e3a49ea49 --- /dev/null +++ b/include/NovelRT/Physics/2D/EdgeCollisionFixture2D.hpp @@ -0,0 +1,17 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class EdgeCollisionFixture2D : public CollisionFixture2D + { + public: + [[nodiscard]] virtual NovelRT::Utilities::Misc::Span GetVertices() = 0; + + virtual void SetVertices(NovelRT::Utilities::Misc::Span vertices) = 0; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/EdgeCollisionFixtureDefinition2D.hpp b/include/NovelRT/Physics/2D/EdgeCollisionFixtureDefinition2D.hpp new file mode 100644 index 000000000..d2263ae91 --- /dev/null +++ b/include/NovelRT/Physics/2D/EdgeCollisionFixtureDefinition2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct EdgeCollisionFixtureDefinition2D final : public CollisionFixtureDefinition2D + { + std::vector Vertices; + + ~EdgeCollisionFixtureDefinition2D() = default; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/FixedDistanceJoint2D.hpp b/include/NovelRT/Physics/2D/FixedDistanceJoint2D.hpp new file mode 100644 index 000000000..28f6fc774 --- /dev/null +++ b/include/NovelRT/Physics/2D/FixedDistanceJoint2D.hpp @@ -0,0 +1,37 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + /** + * @brief + * A joint that keeps the anchors of the attached bodies at a set distance. + */ + class FixedDistanceJoint2D : public Joint2D + { + protected: + float _restLength; + bool _isOnlyMaxLengthEnforced; + + public: + [[nodiscard]] inline float GetRestLength() const noexcept + { + return _restLength; + } + + [[nodiscard]] inline bool GetIsOnlyMaxLengthEnforced() const noexcept + { + return _isOnlyMaxLengthEnforced; + } + + virtual void SetRestLength(float restLength) = 0; + + virtual void SetIsOnlyMaxLengthEnforced(bool isOnlyMaxLengthEnforced) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/FixedDistanceJointDefinition2D.hpp b/include/NovelRT/Physics/2D/FixedDistanceJointDefinition2D.hpp new file mode 100644 index 000000000..1a9ef2b41 --- /dev/null +++ b/include/NovelRT/Physics/2D/FixedDistanceJointDefinition2D.hpp @@ -0,0 +1,19 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct FixedJointDefinition2D final : public JointDefinition2D + { + float RestLength; + bool IsOnlyMaxLengthEnforced; + + ~FixedJointDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/GearJoint2D.hpp b/include/NovelRT/Physics/2D/GearJoint2D.hpp new file mode 100644 index 000000000..4434daad5 --- /dev/null +++ b/include/NovelRT/Physics/2D/GearJoint2D.hpp @@ -0,0 +1,41 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class GearJoint2D : public Joint2D + { + protected: + Joint2D* _primaryJoint; + Joint2D* _secondaryJoint; + float _ratio; + + public: + [[nodiscard]] inline Joint2D* GetPrimaryJoint() + { + return _primaryJoint; + } + + [[nodiscard]] inline Joint2D* GetSecondaryJoint() + { + return _secondaryJoint; + } + + [[nodiscard]] inline float GetRatio() + { + return _ratio; + } + + virtual void SetPrimaryJoint(Joint2D* primaryJoint) = 0; + + virtual void SetSecondaryJoint(Joint2D* secondaryJoint) = 0; + + virtual void SetRatio(float ratio) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/GearJointDefinition2D.hpp b/include/NovelRT/Physics/2D/GearJointDefinition2D.hpp new file mode 100644 index 000000000..b2ca4cfde --- /dev/null +++ b/include/NovelRT/Physics/2D/GearJointDefinition2D.hpp @@ -0,0 +1,20 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct GearJointDefinition2D final : public JointDefinition2D + { + Joint2D* PrimaryJoint; + Joint2D* SecondaryJoint; + float Ratio; + + ~GearJointDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/HingeJoint2D.hpp b/include/NovelRT/Physics/2D/HingeJoint2D.hpp new file mode 100644 index 000000000..0c164a731 --- /dev/null +++ b/include/NovelRT/Physics/2D/HingeJoint2D.hpp @@ -0,0 +1,57 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class HingeJoint2D : public Joint2D + { + protected: + float _lowerAngleLimit; + float _upperAngleLimit; + float _motorSpeed; + float _maxMotorTorque; + bool _isMotorUsed; + + public: + [[nodiscard]] inline float GetLowerAngleLimit() const noexcept + { + return _lowerAngleLimit; + } + + [[nodiscard]] inline float GetUpperAngleLimit() const noexcept + { + return _upperAngleLimit; + } + + [[nodiscard]] inline float GetMotorSpeed() const noexcept + { + return _motorSpeed; + } + + [[nodiscard]] inline float GetMaxMotorTorque() const noexcept + { + return _maxMotorTorque; + } + + [[nodiscard]] inline bool GetIsMotorUsed() const noexcept + { + return _isMotorUsed; + } + + virtual void SetLowerAngleLimit(float lowerAngleLimit) = 0; + + virtual void SetUpperAngleLimit(float upperAngleLimit) = 0; + + virtual void SetMotorSpeed(float motorSpeed) = 0; + + virtual void SetMaxMotorTorque(float maxMotorTorque) = 0; + + virtual void SetIsMotorUsed(bool isMotorUsed) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/HingeJointDefinition2D.hpp b/include/NovelRT/Physics/2D/HingeJointDefinition2D.hpp new file mode 100644 index 000000000..4f3374749 --- /dev/null +++ b/include/NovelRT/Physics/2D/HingeJointDefinition2D.hpp @@ -0,0 +1,32 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct HingeJointDefinition2D final : public JointDefinition2D + { + /** + * @brief + * The lower angle limit in radians. + */ + float LowerAngleLimit; + + /** + * @brief + * The upper angle limit in radians. + */ + float UpperAngleLimit; + + float MotorSpeed; + float MaxMotorTorque; + bool IsMotorUsed; + + ~HingeJointDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/Joint2D.hpp b/include/NovelRT/Physics/2D/Joint2D.hpp new file mode 100644 index 000000000..ecbaaf9e4 --- /dev/null +++ b/include/NovelRT/Physics/2D/Joint2D.hpp @@ -0,0 +1,76 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + // TODO: validate if the current approach for the getters in joints is viable. + // Will most likely have to do that with an actual implementation. + + class Joint2D + { + protected: + RigidBody2D* _primaryBody; + RigidBody2D* _secondaryBody; + NovelRT::Maths::GeoVector2F _primaryAnchorOffset; + NovelRT::Maths::GeoVector2F _secondaryAnchorOffset; + float _breakForce; + float _breakTorque; + bool _collideConnectedBodies; + + public: + [[nodiscard]] inline RigidBody2D* GetPrimaryBody() const noexcept + { + return _primaryBody; + } + + [[nodiscard]] inline RigidBody2D* GetSecondaryBody() const noexcept + { + return _secondaryBody; + } + + [[nodiscard]] inline NovelRT::Maths::GeoVector2F GetPrimaryAnchorOffset() const noexcept + { + return _primaryAnchorOffset; + } + + [[nodiscard]] inline NovelRT::Maths::GeoVector2F GetSecondaryAnchorOffset() const noexcept + { + return _secondaryAnchorOffset; + } + + [[nodiscard]] inline float GetBreakForce() const noexcept + { + return _breakForce; + } + + [[nodiscard]] inline float GetBreakTorque() const noexcept + { + return _breakTorque; + } + + [[nodiscard]] inline bool GetCollideConnectedBodies() const noexcept + { + return _collideConnectedBodies; + } + + virtual void SetPrimaryBody(RigidBody2D* body) = 0; + + virtual void SetSecondaryBody(RigidBody2D* body) = 0; + + virtual void SetPrimaryAnchorOffset(NovelRT::Maths::GeoVector2F offset) = 0; + + virtual void SetSecondaryAnchorOffset(NovelRT::Maths::GeoVector2F offset) = 0; + + virtual void SetBreakForce(float required) = 0; + + virtual void SetBreakTorque(float required) = 0; + + virtual void SetCollideConnectedBodies(bool shouldCollide) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/JointDefinition2D.hpp b/include/NovelRT/Physics/2D/JointDefinition2D.hpp new file mode 100644 index 000000000..a2a9d65d3 --- /dev/null +++ b/include/NovelRT/Physics/2D/JointDefinition2D.hpp @@ -0,0 +1,23 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct JointDefinition2D + { + RigidBody2D* PrimaryBody; + RigidBody2D* SecondaryBody; + NovelRT::Maths::GeoVector2F PrimaryBodyOffset; + NovelRT::Maths::GeoVector2F SecondaryBodyOffset; + float BreakForce; + bool CollideConnectedBodies; + + virtual ~JointDefinition2D() = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/OverlapHit2D.hpp b/include/NovelRT/Physics/2D/OverlapHit2D.hpp new file mode 100644 index 000000000..73a430fb8 --- /dev/null +++ b/include/NovelRT/Physics/2D/OverlapHit2D.hpp @@ -0,0 +1,17 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct OverlapHit2D final + { + RigidBody2D* RigidBody; + CollisionFixture2D* CollisionFixture; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/Physics.2D.hpp b/include/NovelRT/Physics/2D/Physics.2D.hpp new file mode 100644 index 000000000..10fb1ea63 --- /dev/null +++ b/include/NovelRT/Physics/2D/Physics.2D.hpp @@ -0,0 +1,97 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +/** + * @brief + * The plugin API for simulated physics in a two dimensional space. + */ +namespace NovelRT::Physics::Physics2D +{ + class PhysicsProvider2D; + class PhysicsWorld2D; + struct RayCastHit2D; + struct OverlapHit2D; + struct CollisionCallbackArgument2D; + struct TriggerCallbackArgument2D; + class RigidBody2D; + struct BodyDefinition2D; + enum struct RigidBodyFlags2D : std::int8_t; + class CollisionFixture2D; + class BoxCollisionFixture2D; + class CircleCollisionFixture2D; + class CapsuleCollisionFixture2D; + class EdgeCollisionFixture2D; + class PolygonCollisionFixture2D; + struct CollisionFixtureDefinition2D; + struct BoxCollisionFixtureDefinition2D; + struct CircleCollisionFixtureDefinition2D; + struct CapsuleCollisionFixtureDefinition2D; + struct EdgeCollisionFixtureDefinition2D; + struct PolygonCollisionFixtureDefinition2D; + class Joint2D; + class DistanceJoint2D; + class GearJoint2D; + class FixedDistanceJoint2D; + class HingeJoint2D; + class SlidingJoint2D; + class SpringJoint2D; + struct JointDefinition2D; + struct DistanceJointDefinition2D; + struct GearJointDefinition2D; + struct FixedDistanceJointDefinition2D; + struct HingeJointDefinition2D; + struct SlidingJointDefinition2D; + struct SpringJointDefinition2D; + + // TODO: figure out what arguments should be passed + typedef void (*OnCollisionEnterCallbackDelegate2D)(CollisionCallbackArgument2D collisionEnterArgument); + typedef void (*OnCollisionExitCallbackDelegate2D)(CollisionCallbackArgument2D collisionExitArgument); + typedef void (*OnTriggerEnterCallbackDelegate2D)(TriggerCallbackArgument2D triggerEnterArgument); + typedef void (*OnTriggerExitCallbackDelegate2D)(TriggerCallbackArgument2D triggerExitArgument); +} + +// clang-format off + +#include "PhysicsProvider2D.hpp" +#include "RigidBodyFlags2D.hpp" +#include "RigidBody2D.hpp" +#include "PhysicsWorld2D.hpp" +#include "OverlapHit2D.hpp" +#include "RayCastHit2D.hpp" +#include "CollisionCallbackArgument2D.hpp" +#include "TriggerCallbackArgument2D.hpp" +#include "BodyDefinition2D.hpp" +#include "CollisionFixture2D.hpp" +#include "BoxCollisionFixture2D.hpp" +#include "CircleCollisionFixture2D.hpp" +#include "CapsuleCollisionFixture2D.hpp" +#include "EdgeCollisionFixture2D.hpp" +#include "PolygonCollisionFixture2D.hpp" +#include "CollisionFixtureDefinition2D.hpp" +#include "BoxCollisionFixtureDefinition2D.hpp" +#include "CircleCollisionFixtureDefinition2D.hpp" +#include "CapsuleCollisionFixtureDefinition2D.hpp" +#include "EdgeCollisionFixtureDefinition2D.hpp" +#include "PolygonCollisionFixtureDefinition2D.hpp" +#include "Joint2D.hpp" +#include "DistanceJoint2D.hpp" +#include "FixedDistanceJoint2D.hpp" +#include "GearJoint2D.hpp" +#include "HingeJoint2D.hpp" +#include "SlidingJoint2D.hpp" +#include "SpringJoint2D.hpp" +#include "JointDefinition2D.hpp" +#include "DistanceJointDefinition2D.hpp" +#include "FixedDistanceJointDefinition2D.hpp" +#include "HingeJointDefinition2D.hpp" +#include "GearJointDefinition2D.hpp" +#include "SlidingJointDefinition2D.hpp" +#include "SpringJointDefinition2D.hpp" + +// clang-format on \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/PhysicsProvider2D.hpp b/include/NovelRT/Physics/2D/PhysicsProvider2D.hpp new file mode 100644 index 000000000..a5a60f24d --- /dev/null +++ b/include/NovelRT/Physics/2D/PhysicsProvider2D.hpp @@ -0,0 +1,31 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class PhysicsProvider2D : public PhysicsProvider + { + public: + [[nodiscard]] bool Supports2D() const noexcept final + { + return true; + } + + /** + * @brief + * Creates an instance of a 2 dimensional physics world. + * + * @details + * + * + * @return std::unique_ptr The instance of a 2 dimensional physics world. + */ + [[nodiscard]] virtual std::unique_ptr CreateWorld() = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/PhysicsWorld2D.hpp b/include/NovelRT/Physics/2D/PhysicsWorld2D.hpp new file mode 100644 index 000000000..bc0116c19 --- /dev/null +++ b/include/NovelRT/Physics/2D/PhysicsWorld2D.hpp @@ -0,0 +1,172 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + /** + * @brief + * A 2D space for physics simulations. + */ + class PhysicsWorld2D + { + public: + /** + * @brief + * Simulates how the physics objects have moved over the given period. + * + * @param timeStep The time passed since the last step. + */ + virtual void Step(float timeStep) = 0; + + /** + * @brief + * Adds a RigidBody2D to be simulated to the world. + * + * @details + * + * + * @param bodyDefinition + * @return RigidBody2D* A pointer to the RigidBody2D that has been added to this world instance. + */ + [[nodiscard]] virtual RigidBody2D* AddRigidBody(const BodyDefinition2D& bodyDefinition) = 0; + + /** + * @brief Removes a RigidBody2D from the world to stop simulating it. + * + * @param rigidBody The RigidBody2D to be removed from this world instance. + */ + virtual void RemoveRigidBody(RigidBody2D* rigidBody) = 0; + + [[nodiscard]] virtual DistanceJoint2D* AddDistanceJoint(const DistanceJointDefinition2D& jointDefinition) = 0; + + [[nodiscard]] virtual FixedDistanceJoint2D* AddFixedJoint( + const FixedDistanceJointDefinition2D& jointDefiniton) = 0; + + [[nodiscard]] virtual GearJoint2D* AddGearJoint2D(const GearJointDefinition2D& jointDefinition) = 0; + + [[nodiscard]] virtual HingeJoint2D* AddHingeJoint(const HingeJointDefinition2D& jointDefinition) = 0; + + [[nodiscard]] virtual SpringJoint2D* AddSpringJoint(const SpringJointDefinition2D& jointDefinition) = 0; + + virtual void RemoveJoint(Joint2D* joint) = 0; + + /** + * @brief + * Gets the current gravity that gets applied to this world. + * + * @details + * + * + * @return NovelRT::Maths::GeoVector2F The gravity that gets applied to this world + */ + [[nodiscard]] virtual NovelRT::Maths::GeoVector2F GetGravity() = 0; + + /** + * @brief + * Gets the current gravity that gets applied to this world. + * + * @param gravity + */ + virtual void SetGravity(NovelRT::Maths::GeoVector2F gravity) = 0; + + [[nodiscard]] virtual BoxCollisionFixture2D* CreateSharedBoxFixture( + BoxCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual CapsuleCollisionFixture2D* CreateSharedBoxFixture( + CapsuleCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual CircleCollisionFixture2D* CreateSharedBoxFixture( + CircleCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual EdgeCollisionFixture2D* CreateSharedBoxFixture( + EdgeCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual PolygonCollisionFixture2D* CreateSharedBoxFixture( + PolygonCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + virtual void RemoveSharedFixture(CollisionFixture2D* fixture) = 0; + + [[nodiscard]] virtual std::optional RayCast(NovelRT::Maths::GeoVector2F origin, + NovelRT::Maths::GeoVector2F direction, + float length) const = 0; + + [[nodiscard]] virtual std::optional RayCast(NovelRT::Maths::GeoVector2F pointOne, + NovelRT::Maths::GeoVector2F pointTwo) const = 0; + + [[nodiscard]] virtual size_t RayCast(NovelRT::Maths::GeoVector2F origin, + NovelRT::Maths::GeoVector2F direction, + float length, + NovelRT::Utilities::Misc::Span buffer) const = 0; + + [[nodiscard]] virtual size_t RayCast(NovelRT::Maths::GeoVector2F pointOne, + NovelRT::Maths::GeoVector2F pointTwo, + NovelRT::Utilities::Misc::Span buffer) const = 0; + + [[nodiscard]] virtual std::vector RayCastAll(NovelRT::Maths::GeoVector2F origin, + NovelRT::Maths::GeoVector2F direction, + float length) const = 0; + + [[nodiscard]] virtual std::vector RayCastAll(NovelRT::Maths::GeoVector2F pointOne, + NovelRT::Maths::GeoVector2F pointTwo) const = 0; + + [[nodiscard]] virtual size_t RayCastAll(NovelRT::Maths::GeoVector2F origin, + NovelRT::Maths::GeoVector2F direction, + float length, + std::vector buffer) const = 0; + + [[nodiscard]] virtual size_t RayCastAll(NovelRT::Maths::GeoVector2F pointOne, + NovelRT::Maths::GeoVector2F pointTwo, + std::vector buffer) const = 0; + + [[nodiscard]] virtual bool RayCastHasHit(NovelRT::Maths::GeoVector2F origin, + NovelRT::Maths::GeoVector2F direction, + float length) const = 0; + + [[nodiscard]] virtual bool RayCastHasHit(NovelRT::Maths::GeoVector2F pointOne, + NovelRT::Maths::GeoVector2F pointTwo) const = 0; + + [[nodiscard]] virtual std::optional BoxOverlap(NovelRT::Maths::GeoVector2F position, + NovelRT::Maths::GeoVector2F halfExtend, + float rotation) const = 0; + + [[nodiscard]] virtual size_t BoxOverlap(NovelRT::Maths::GeoVector2F position, + NovelRT::Maths::GeoVector2F halfExtend, + float rotation, + NovelRT::Utilities::Misc::Span buffer) const = 0; + + [[nodiscard]] virtual std::vector BoxOverlapAll(NovelRT::Maths::GeoVector2F position, + NovelRT::Maths::GeoVector2F halfExtend, + float rotation) const = 0; + + [[nodiscard]] virtual size_t BoxOverlapAll(NovelRT::Maths::GeoVector2F position, + NovelRT::Maths::GeoVector2F halfExtend, + float rotation, + std::vector buffer) const = 0; + + [[nodiscard]] virtual bool BoxHasOverlap(NovelRT::Maths::GeoVector2F position, + NovelRT::Maths::GeoVector2F halfExtend, + float rotation) const = 0; + + [[nodiscard]] virtual std::optional CircleOverlap(NovelRT::Maths::GeoVector2F position, + float radius) const = 0; + + [[nodiscard]] virtual size_t CircleOverlap(NovelRT::Maths::GeoVector2F position, + float radius, + NovelRT::Utilities::Misc::Span buffer) const = 0; + + [[nodiscard]] virtual std::vector CircleOverlapAll(NovelRT::Maths::GeoVector2F position, + float radius) const = 0; + + [[nodiscard]] virtual size_t CircleOverlapAll(NovelRT::Maths::GeoVector2F position, + float radius, + std::vector buffer) const = 0; + + [[nodiscard]] virtual bool CircleHasOverlap(NovelRT::Maths::GeoVector2F position, float radius) const = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/PolygonCollisionFixture2D.hpp b/include/NovelRT/Physics/2D/PolygonCollisionFixture2D.hpp new file mode 100644 index 000000000..bfe298239 --- /dev/null +++ b/include/NovelRT/Physics/2D/PolygonCollisionFixture2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class PolygonCollisionFixture2D : public CollisionFixture2D + { + [[nodiscard]] virtual NovelRT::Utilities::Misc::Span GetVertices() = 0; + + virtual void SetVertices(NovelRT::Utilities::Misc::Span vertices) = 0; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/PolygonCollisionFixtureDefinition2D.hpp b/include/NovelRT/Physics/2D/PolygonCollisionFixtureDefinition2D.hpp new file mode 100644 index 000000000..37a6969c2 --- /dev/null +++ b/include/NovelRT/Physics/2D/PolygonCollisionFixtureDefinition2D.hpp @@ -0,0 +1,16 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct PolygonCollisionFixtureDefinition2D final : public CollisionFixtureDefinition2D + { + std::vector Vertices; + + ~PolygonCollisionFixtureDefinition2D() = default; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/RayCastHit2D.hpp b/include/NovelRT/Physics/2D/RayCastHit2D.hpp new file mode 100644 index 000000000..8714323ae --- /dev/null +++ b/include/NovelRT/Physics/2D/RayCastHit2D.hpp @@ -0,0 +1,19 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct RayCastHit2D final + { + RigidBody2D* RigidBody; + CollisionFixture2D* CollisionFixture; + NovelRT::Maths::GeoVector2F Point; + float DistanceFromOrigin; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/RigidBody2D.hpp b/include/NovelRT/Physics/2D/RigidBody2D.hpp new file mode 100644 index 000000000..a79833f7a --- /dev/null +++ b/include/NovelRT/Physics/2D/RigidBody2D.hpp @@ -0,0 +1,153 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class RigidBody2D + { + protected: + NovelRT::Maths::GeoVector2F _position; + NovelRT::Maths::GeoVector2F _linearVelocity; + NovelRT::Maths::GeoVector2F _angularVelocity; + NovelRT::Maths::GeoVector2F _gravity; + float _rotationAngle; + float _linearDamping; + float _angularDamping; + RigidBodyFlags2D _flags; + NovelRT::Physics::RigidBodyCallbackFlags _callbackFlags; + + public: + [[nodiscard]] inline NovelRT::Maths::GeoVector2F GetPosition() const noexcept + { + return _position; + } + + [[nodiscard]] inline NovelRT::Maths::GeoVector2F GetLinearVelocity() const noexcept + { + return _linearVelocity; + } + + [[nodiscard]] inline NovelRT::Maths::GeoVector2F GetAngularVelocity() const noexcept + { + return _angularVelocity; + } + + [[nodiscard]] inline NovelRT::Maths::GeoVector2F GetOwnGravity() const noexcept + { + return _gravity; + } + + [[nodiscard]] inline float GetRotationAngle() const noexcept + { + return _rotationAngle; + } + + [[nodiscard]] inline float GetLinearDamping() const noexcept + { + return _linearDamping; + } + + [[nodiscard]] inline float GetAngularDamping() const noexcept + { + return _angularDamping; + } + + [[nodiscard]] inline RigidBodyFlags2D GetBodyFlags() const noexcept + { + return _flags; + } + + [[nodiscard]] inline bool IsAllowedToSleep() const noexcept + { + return (_flags & RigidBodyFlags2D::AllowSleep) == RigidBodyFlags2D::AllowSleep; + } + + [[nodiscard]] inline bool IsAwakeOnStartUp() const noexcept + { + return (_flags & RigidBodyFlags2D::FixedRotation) == RigidBodyFlags2D::FixedRotation; + } + + [[nodiscard]] inline bool IsUsingConstantCollisionDetection() const noexcept + { + return (_flags & RigidBodyFlags2D::UseConstantCollisionDetection) == + RigidBodyFlags2D::UseConstantCollisionDetection; + } + + [[nodiscard]] inline bool IsEnabled() const noexcept + { + return (_flags & RigidBodyFlags2D::Enabled) == RigidBodyFlags2D::Enabled; + } + + [[nodiscard]] inline bool IsApplyingWorldGravity() const noexcept + { + return (_flags & RigidBodyFlags2D::UseWorldGravity) == RigidBodyFlags2D::UseWorldGravity; + } + + virtual void SetPosition(NovelRT::Maths::GeoVector2F position) = 0; + + virtual void SetLinearVelocity(NovelRT::Maths::GeoVector2F linearVelocity) = 0; + + virtual void SetAngularVelocity(NovelRT::Maths::GeoVector2F angularVelocity) = 0; + + virtual void SetOwnGravity(NovelRT::Maths::GeoVector2F gravity) = 0; + + virtual void SetRotationAngle(float angle) = 0; + + virtual void SetLinearDamping(float linearDamping) = 0; + + virtual void SetAngularDamping(float angularDamping) = 0; + + virtual void SetBodyFlags(RigidBodyFlags2D flags) = 0; + + inline void SetAllowedToSleep(bool isAllowedToSleep) + { + SetBodyFlags((_flags & ~RigidBodyFlags2D::AllowSleep) | + (isAllowedToSleep ? RigidBodyFlags2D::AllowSleep : static_cast(0))); + } + + inline void SetUsingConstantCollisionDetection(bool isUsingConstantCollisionDetection) + { + SetBodyFlags((_flags & ~RigidBodyFlags2D::UseConstantCollisionDetection) | + (isUsingConstantCollisionDetection ? RigidBodyFlags2D::UseConstantCollisionDetection + : static_cast(0))); + } + + inline void SetEnabled(bool isEnabled) + { + SetBodyFlags((_flags & ~RigidBodyFlags2D::Enabled) | + (isEnabled ? RigidBodyFlags2D::Enabled : static_cast(0))); + } + + inline void SetApplyingWorldGravity(bool isApplyingWorldGravity) + { + SetBodyFlags( + (_flags & ~RigidBodyFlags2D::UseWorldGravity) | + (isApplyingWorldGravity ? RigidBodyFlags2D::UseWorldGravity : static_cast(0))); + } + + [[nodiscard]] virtual BoxCollisionFixture2D* AddBoxFixture( + BoxCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual CapsuleCollisionFixture2D* AddBoxFixture( + CapsuleCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual CircleCollisionFixture2D* AddBoxFixture( + CircleCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual EdgeCollisionFixture2D* AddBoxFixture( + EdgeCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + [[nodiscard]] virtual PolygonCollisionFixture2D* AddBoxFixture( + PolygonCollisionFixtureDefinition2D& fixtureDefinition) = 0; + + virtual void RemoveFixture(const CollisionFixture2D* fixture) = 0; + + virtual void RemoveSharedFixture(const CollisionFixture2D* fixture) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/RigidBodyFlags2D.hpp b/include/NovelRT/Physics/2D/RigidBodyFlags2D.hpp new file mode 100644 index 000000000..36fe44cea --- /dev/null +++ b/include/NovelRT/Physics/2D/RigidBodyFlags2D.hpp @@ -0,0 +1,21 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + enum class RigidBodyFlags2D : std::int8_t + { + AllowSleep = 1 << 0, + Awake = 1 << 1, + FixedRotation = 1 << 2, + UseConstantCollisionDetection = 1 << 3, + Enabled = 1 << 4, + UseWorldGravity = 1 << 5 + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/SlidingJoint2D.hpp b/include/NovelRT/Physics/2D/SlidingJoint2D.hpp new file mode 100644 index 000000000..35467a783 --- /dev/null +++ b/include/NovelRT/Physics/2D/SlidingJoint2D.hpp @@ -0,0 +1,81 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + /** + * @brief + * A joint whose movement is restricted to a single axis, often called a prismatic joint. + * + * @details + * A sliding joint can move along a single axis, rather than rotating around it. It can be useful for situations, + * like sliding doors. + */ + class SlidingJoint2D : public Joint2D + { + protected: + float _motorSpeed; + float _maximumMotorForce; + float _lowerTranslationLimit; + float _upperTranslationLimit; + float _breakTorque; + bool _useTranslationLimits; + bool _useMotor; + + public: + [[nodiscard]] inline float GetMotorSpeed() const noexcept + { + return _motorSpeed; + } + + [[nodiscard]] inline float GetMaximumMotorForce() const noexcept + { + return _maximumMotorForce; + } + + [[nodiscard]] inline float GetLowerTranslationLimit() const noexcept + { + return _lowerTranslationLimit; + } + + [[nodiscard]] inline float GetUpperTranslationLimit() const noexcept + { + return _upperTranslationLimit; + } + + [[nodiscard]] inline float GetBreakTorque() const noexcept + { + return _breakTorque; + } + + [[nodiscard]] inline bool GetAreTranslationLimitsUsed() const noexcept + { + return _useTranslationLimits; + } + + [[nodiscard]] inline bool GetIsMotorUsed() const noexcept + { + return _useMotor; + } + + virtual void SetMotorSpeed(float motorSpeed) = 0; + + virtual void SetMaximumMotorForce(float maximumMotorForce) = 0; + + virtual void SetLowerTranslationLimit(float lowerTranslationLimit) = 0; + + virtual void SetUpperTranslationLimit(float upperTranslationLimit) = 0; + + virtual void SetBreakTorque(float breakTorque) = 0; + + virtual void SetAreTranslationLimitsUsed(bool useTranslationLimits) = 0; + + virtual void SetIsMotorUsed(bool useMotor) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/SlidingJointDefinition2D.hpp b/include/NovelRT/Physics/2D/SlidingJointDefinition2D.hpp new file mode 100644 index 000000000..7f1b5696b --- /dev/null +++ b/include/NovelRT/Physics/2D/SlidingJointDefinition2D.hpp @@ -0,0 +1,24 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct SlidingJointDefinition2D final : public JointDefinition2D + { + float MotorSpeed; + float MaximumMotorForce; + float LowerTranslationLimit; + float UpperTranslationLimit; + float BreakTorque; + bool UseTranslationLimits; + bool UseMotor; + + ~SlidingJointDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/SpringJoint2D.hpp b/include/NovelRT/Physics/2D/SpringJoint2D.hpp new file mode 100644 index 000000000..d8cf643f7 --- /dev/null +++ b/include/NovelRT/Physics/2D/SpringJoint2D.hpp @@ -0,0 +1,57 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + class SpringJoint2D : public Joint2D + { + protected: + float _minimumLength; + float _maximumLength; + float _restLength; + float _stiffness; + float _damping; + + public: + [[nodiscard]] inline float GetMinimumLength() const noexcept + { + return _minimumLength; + } + + [[nodiscard]] inline float GetMaximumLength() const noexcept + { + return _maximumLength; + } + + [[nodiscard]] inline float GetRestLength() const noexcept + { + return _restLength; + } + + [[nodiscard]] inline float GetStiffness() const noexcept + { + return _stiffness; + } + + [[nodiscard]] inline float GetDamping() const noexcept + { + return _damping; + } + + virtual void SetMinimumLength(float minimumLength) = 0; + + virtual void SetMaximumLength(float maximumLength) = 0; + + virtual void SetRestLength(float restLength) = 0; + + virtual void SetStiffness(float stiffness) = 0; + + virtual void SetDamping(float damping) = 0; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/SpringJointDefinition2D.hpp b/include/NovelRT/Physics/2D/SpringJointDefinition2D.hpp new file mode 100644 index 000000000..c2936df56 --- /dev/null +++ b/include/NovelRT/Physics/2D/SpringJointDefinition2D.hpp @@ -0,0 +1,22 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct SpringJointDefinition2D final : public JointDefinition2D + { + float MinimumLength; + float MaximumLength; + float RestLength; + float Stiffness; + float Damping; + + ~SpringJointDefinition2D() = default; + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/2D/TriggerCallbackArgument2D.hpp b/include/NovelRT/Physics/2D/TriggerCallbackArgument2D.hpp new file mode 100644 index 000000000..545743bc4 --- /dev/null +++ b/include/NovelRT/Physics/2D/TriggerCallbackArgument2D.hpp @@ -0,0 +1,15 @@ +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics::Physics2D +{ + struct TriggerCallBackArgument2D final + { + const RigidBody2D* const RigidBody; + const CollisionFixture2D* const CollisionFixture; + }; + +} // namespace NovelRT::Physics::Physics2D \ No newline at end of file diff --git a/include/NovelRT/Physics/BodyType.hpp b/include/NovelRT/Physics/BodyType.hpp new file mode 100644 index 000000000..12e84fa99 --- /dev/null +++ b/include/NovelRT/Physics/BodyType.hpp @@ -0,0 +1,36 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics +{ + /** + * @brief + * The type associated with a rigidbody. + */ + enum class BodyType + { + /** + * @brief + * A rigibody that is not meant to move, for example: scenery. + */ + Static, + + /** + * @brief + * A rigidbody that gets moved around programmatically, for example: player characters. + */ + Kinematic, + + /** + * @brief + * A rigidbody that gets fully simulated by the physics system. + */ + Dynamic + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/Physics.hpp b/include/NovelRT/Physics/Physics.hpp new file mode 100644 index 000000000..0a8d4b103 --- /dev/null +++ b/include/NovelRT/Physics/Physics.hpp @@ -0,0 +1,35 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once +#define NOVELRT_PHYSICS_HPP + +// TODO: replace *.h with *.hpp when they get renamed. + +// physics dependencies +#include "NovelRT/Maths/Maths.h" +#include "NovelRT/Utilities/Misc.h" +#include +#include +#include +#include + +/** + * @brief + * The plugin API for simulated physics. + */ +namespace NovelRT::Physics +{ + enum class BodyType; + class PhysicsProvider; + enum class RigidBodyCallbackFlags : std::int8_t; +} + +// clang-format off + +#include "BodyType.hpp" +#include "RigidBodyCallbackFlags.hpp" +#include "PhysicsProvider.hpp" +#include "2D/Physics.2D.hpp" + +// clang-format on \ No newline at end of file diff --git a/include/NovelRT/Physics/PhysicsProvider.hpp b/include/NovelRT/Physics/PhysicsProvider.hpp new file mode 100644 index 000000000..552bb3536 --- /dev/null +++ b/include/NovelRT/Physics/PhysicsProvider.hpp @@ -0,0 +1,42 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics +{ + class PhysicsProvider : public std::enable_shared_from_this + { + private: + PhysicsProvider() = default; + + public: + /** + * @brief + * Determines if the physics provider supports 2D physics simulations. + * + * @retval true if the physics provider supports 2D physics simulations. + * @retval false if the physics provider does not support 2D physics simulations. + */ + [[nodiscard]] virtual bool Supports2D() const noexcept + { + return false; + } + + /** + * @brief + * Determines if the physics provider supports 3D physics simulations. + * + * @retval true if the physics provider supports 3D physics simulations. + * @retval false if the physics provider does not support 3D physics simulations. + */ + [[nodiscard]] virtual bool Supports3D() const noexcept + { + return false; + } + }; +} \ No newline at end of file diff --git a/include/NovelRT/Physics/RigidBodyCallbackFlags.hpp b/include/NovelRT/Physics/RigidBodyCallbackFlags.hpp new file mode 100644 index 000000000..d971e52bc --- /dev/null +++ b/include/NovelRT/Physics/RigidBodyCallbackFlags.hpp @@ -0,0 +1,21 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#pragma once + +#ifndef NOVELRT_PHYSICS_HPP +#error NovelRT does not support including types explicitly by default. Please include Physics.h instead for the Physics namespace subset. +#endif + +namespace NovelRT::Physics +{ + enum class RigidBodyCallbackFlags : std::int8_t + { + HasCollisionEnterCallback = 1 << 0, + HasCollisionExitCallback = 1 << 1, + HasCollisionStayCallback = 1 << 2, + HasTriggerEnterCallback = 1 << 3, + HasTriggerExitCallback = 1 << 4, + HasTriggerStayCallback = 1 << 5, + }; +} \ No newline at end of file