1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #ifndef B2_MOTOR_JOINT_H
24 #define B2_MOTOR_JOINT_H
25 
26 #include "b2_api.h"
27 #include "b2_joint.h"
28 
29 /// Motor joint definition.
30 struct B2_API b2MotorJointDef : public b2JointDef
31 {
b2MotorJointDefb2MotorJointDef32 	b2MotorJointDef()
33 	{
34 		type = e_motorJoint;
35 		linearOffset.SetZero();
36 		angularOffset = 0.0f;
37 		maxForce = 1.0f;
38 		maxTorque = 1.0f;
39 		correctionFactor = 0.3f;
40 	}
41 
42 	/// Initialize the bodies and offsets using the current transforms.
43 	void Initialize(b2Body* bodyA, b2Body* bodyB);
44 
45 	/// Position of bodyB minus the position of bodyA, in bodyA's frame, in meters.
46 	b2Vec2 linearOffset;
47 
48 	/// The bodyB angle minus bodyA angle in radians.
49 	float angularOffset;
50 
51 	/// The maximum motor force in N.
52 	float maxForce;
53 
54 	/// The maximum motor torque in N-m.
55 	float maxTorque;
56 
57 	/// Position correction factor in the range [0,1].
58 	float correctionFactor;
59 };
60 
61 /// A motor joint is used to control the relative motion
62 /// between two bodies. A typical usage is to control the movement
63 /// of a dynamic body with respect to the ground.
64 class B2_API b2MotorJoint : public b2Joint
65 {
66 public:
67 	b2Vec2 GetAnchorA() const override;
68 	b2Vec2 GetAnchorB() const override;
69 
70 	b2Vec2 GetReactionForce(float inv_dt) const override;
71 	float GetReactionTorque(float inv_dt) const override;
72 
73 	/// Set/get the target linear offset, in frame A, in meters.
74 	void SetLinearOffset(const b2Vec2& linearOffset);
75 	const b2Vec2& GetLinearOffset() const;
76 
77 	/// Set/get the target angular offset, in radians.
78 	void SetAngularOffset(float angularOffset);
79 	float GetAngularOffset() const;
80 
81 	/// Set the maximum friction force in N.
82 	void SetMaxForce(float force);
83 
84 	/// Get the maximum friction force in N.
85 	float GetMaxForce() const;
86 
87 	/// Set the maximum friction torque in N*m.
88 	void SetMaxTorque(float torque);
89 
90 	/// Get the maximum friction torque in N*m.
91 	float GetMaxTorque() const;
92 
93 	/// Set the position correction factor in the range [0,1].
94 	void SetCorrectionFactor(float factor);
95 
96 	/// Get the position correction factor in the range [0,1].
97 	float GetCorrectionFactor() const;
98 
99 	/// Dump to b2Log
100 	void Dump() override;
101 
102 protected:
103 
104 	friend class b2Joint;
105 
106 	b2MotorJoint(const b2MotorJointDef* def);
107 
108 	void InitVelocityConstraints(const b2SolverData& data) override;
109 	void SolveVelocityConstraints(const b2SolverData& data) override;
110 	bool SolvePositionConstraints(const b2SolverData& data) override;
111 
112 	// Solver shared
113 	b2Vec2 m_linearOffset;
114 	float m_angularOffset;
115 	b2Vec2 m_linearImpulse;
116 	float m_angularImpulse;
117 	float m_maxForce;
118 	float m_maxTorque;
119 	float m_correctionFactor;
120 
121 	// Solver temp
122 	int32 m_indexA;
123 	int32 m_indexB;
124 	b2Vec2 m_rA;
125 	b2Vec2 m_rB;
126 	b2Vec2 m_localCenterA;
127 	b2Vec2 m_localCenterB;
128 	b2Vec2 m_linearError;
129 	float m_angularError;
130 	float m_invMassA;
131 	float m_invMassB;
132 	float m_invIA;
133 	float m_invIB;
134 	b2Mat22 m_linearMass;
135 	float m_angularMass;
136 };
137 
138 #endif
139