1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Physics/BsJoint.h"
7
8namespace bs
9{
10 class PhysicsScene;
11 /** @addtogroup Physics
12 * @{
13 */
14
15 struct HINGE_JOINT_DESC;
16
17 /** Flags that control hinge joint options. */
18 enum class BS_SCRIPT_EXPORT(m:Physics) HingeJointFlag
19 {
20 Limit = 0x1, /**< Joint limit is enabled. */
21 Drive = 0x2 /**< Joint drive is enabled. */
22 };
23
24 /** Properties of a drive that drives the joint's angular velocity towards a paricular value. */
25 struct BS_SCRIPT_EXPORT(m:Physics,pl:true) HingeJointDrive
26 {
27 /** Target speed of the joint. */
28 float speed = 0.0f;
29
30 /** Maximum torque the drive is allowed to apply .*/
31 float forceLimit = FLT_MAX;
32
33 /** Scales the velocity of the first body, and its response to drive torque is scaled down. */
34 float gearRatio = 1.0f;
35
36 /**
37 * If the joint is moving faster than the drive's target speed, the drive will try to break. If you don't want
38 * the breaking to happen set this to true.
39 */
40 bool freeSpin = false;
41
42 bool operator==(const HingeJointDrive& other) const
43 {
44 return speed == other.speed && forceLimit == other.forceLimit && gearRatio == other.gearRatio &&
45 freeSpin && other.freeSpin;
46 }
47 };
48
49 /**
50 * Hinge joint removes all but a single rotation degree of freedom from its two attached bodies (for example a door
51 * hinge).
52 */
53 class BS_CORE_EXPORT HingeJoint : public Joint
54 {
55 public:
56 HingeJoint(const HINGE_JOINT_DESC& desc) { }
57 virtual ~HingeJoint() = default;
58
59 /** Returns the current angle between the two attached bodes. */
60 virtual Radian getAngle() const = 0;
61
62 /** Returns the current angular speed of the joint. */
63 virtual float getSpeed() const = 0;
64
65 /** @copydoc setLimit() */
66 virtual LimitAngularRange getLimit() const = 0;
67
68 /**
69 * Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the
70 * limit flag on the joint in order for this to be recognized.
71 *
72 * @see LimitAngularRange
73 */
74 virtual void setLimit(const LimitAngularRange& limit) = 0;
75
76 /** @copydoc setDrive() */
77 virtual HingeJointDrive getDrive() const = 0;
78
79 /**
80 * Determines the drive properties of the joint. It drives the joint's angular velocity towards a particular value.
81 * You must enable the drive flag on the joint in order for the drive to be active.
82 *
83 * @see HingeJoint::Drive
84 */
85 virtual void setDrive(const HingeJointDrive& drive) = 0;
86
87 /** Enables or disables a flag that controls joint behaviour. */
88 virtual void setFlag(HingeJointFlag flag, bool enabled) = 0;
89
90 /** Checks is the specified option enabled. */
91 virtual bool hasFlag(HingeJointFlag flag) const = 0;
92
93 /**
94 * Creates a new hinge joint.
95 *
96 * @param[in] scene Scene to which to add the joint.
97 * @param[in] desc Settings describing the joint.
98 */
99 static SPtr<HingeJoint> create(PhysicsScene& scene, const HINGE_JOINT_DESC& desc);
100 };
101
102 /** Structure used for initializing a new HingeJoint. */
103 struct HINGE_JOINT_DESC : JOINT_DESC
104 {
105 HingeJointDrive drive;
106 LimitAngularRange limit;
107 HingeJointFlag flag = (HingeJointFlag)0;
108 };
109
110 /** @} */
111}