MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
hingeconstraint.h
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _physicshingeconstraint_h
41 #define _physicshingeconstraint_h
42 
43 #include "Physics/dualtransformconstraint.h"
44 
45 class btHingeConstraint;
46 
47 namespace Mezzanine
48 {
49  namespace Physics
50  {
51  ///////////////////////////////////////////////////////////////////////////////
52  /// @class HingeConstraint
53  /// @headerfile constraint.h
54  /// @brief This is a constraint to be used to restrict the movement between two objects to angular rotation on a single axis.
55  /// @details As the name suggests, this constraint essentially works like a door Hinge.
56  ///////////////////////////////////////
58  {
59  protected:
60  /// @brief Bullet constraint that this class encapsulates.
61  btHingeConstraint* Hinge;
62  public:
63  ////////////////////////////////////////////////////////////////////////////////
64  // HingeConstraint Construction and Destruction
65 
66  /// @brief Creates a Hinge constraint that will connect two proxies together by their offsets.
67  /// @param ProxyA The first proxy to apply this constraint to.
68  /// @param ProxyB The second proxy to apply this constraint to.
69  /// @param PivotA The location in ProxyA's local space to apply the constraint to.
70  /// @param PivotB The location in ProxyB's local space to apply the constraint to.
71  /// @param AxisInA The axis(for ProxyA) on which the hinge is to act. For example, a door hinge would be (0.0,1.0,0.0), aka the positive Y axis.
72  /// @param AxisInB The axis(for ProxyB) on which the hinge is to act. For example, a door hinge would be (0.0,1.0,0.0), aka the positive Y axis.
73  /// @param UseReferenceFrameA By default, this constraint uses ProxyB's local space as the reference for certain values, such as the rotational limits. This simply controls whether or not it should use ProxyA's local space instead.
74  HingeConstraint(RigidProxy* ProxyA, RigidProxy* ProxyB, const Vector3& PivotInA, const Vector3& PivotInB, const Vector3& AxisInA, const Vector3& AxisInB, bool UseReferenceFrameA=false);
75  /// @brief Creates a Hinge constraint that will attach an proxy to a point in world space.
76  /// @param ProxyA The proxy to apply this constraint to.
77  /// @param PivotInA The point in the objects(ProxyA) local space where the constraint is to be attached to world space.
78  /// @param AxisInA The axis(for ProxyA) on which the hinge is to act. For example, a door hinge would be (0.0,1.0,0.0), aka the positive Y axis.
79  /// @param UseReferenceFrameA By default, this constraint uses ProxyB's local space as the reference for certain values, such as the rotational limits. This simply controls whether or not it should use ProxyA's local space instead.
80  HingeConstraint(RigidProxy* ProxyA, const Vector3& PivotInA, const Vector3& AxisInA, bool UseReferenceFrameA=false);
81  /// @brief Create a Hinge with components of a tranform
82  /// @param ProxyA The first proxy to apply this constraint to.
83  /// @param ProxyB The second proxy to apply this constraint to.
84  /// @param VectorA The location component of Transform A
85  /// @param VectorB The location component of Transform B
86  /// @param QuaternionA The rotation component of Transform A
87  /// @param QuaternionB The rotation component of Transform B
88  /// @param UseReferenceFrameA By default, this constraint uses ProxyB's local space as the reference for certain values, such as the rotational limits. This simply controls whether or not it should use ProxyAs local space instead.
89  HingeConstraint(RigidProxy* ProxyA, RigidProxy* ProxyB, const Vector3& VectorA, const Vector3& VectorB, const Quaternion& QuaternionA, const Quaternion& QuaternionB, bool UseReferenceFrameA=false);
90  /// @brief Create a Hinge with components of a tranform
91  /// @param ProxyA The first proxy to apply this constraint to.
92  /// @param ProxyB The second proxy to apply this constraint to.
93  /// @param TransformA The location component of Transform A
94  /// @param TransformB The location component of Transform B
95  /// @param UseReferenceFrameA By default, this constraint uses ProxyBs local space as the reference for certain values, such as the rotational limits. This simply controls whether or not it should use ProxyAs local space instead.
96  HingeConstraint(RigidProxy* ProxyA, RigidProxy* ProxyB, const Transform& TransformA, const Transform& TransformB, bool UseReferenceFrameA=false);
97  /// @brief Class destructor.
98  virtual ~HingeConstraint();
99 
100  ////////////////////////////////////////////////////////////////////////////////
101  // HingeConstraint Position and Orientation
102 
103  /// @brief Set The relative location of the hinge pivot from ActorA's Center of gravity.
104  /// @param Location The New value for PivotA
105  /// @details Ultimately this information winds up being stored in the TransformA. This implements
106  /// a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
107  virtual void SetPivotALocation(const Vector3& Location);
108  /// @brief Set The relative location of the hinge pivot from ActorB's Center of gravity.
109  /// @param Location The New value for PivotB
110  /// @details Ultimately this information winds up being stored in the TransformB. This implements
111  /// a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
112  virtual void SetPivotBLocation(const Vector3& Location);
113  /// @brief Get the location of the hinge pivot relative to ActorA's Center of gravity
114  /// @return A Vector3 with the pivot location.
115  /// @details This implements a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
116  virtual Vector3 GetPivotALocation() const;
117  /// @brief Get the location of the hinge pivot relative to ActorB's Center of gravity
118  /// @return A Vector3 with the pivot location.
119  /// @details This implements a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
120  virtual Vector3 GetPivotBLocation() const;
121 
122  /// @brief Set The relative rotation of ActorA
123  /// @param Rotation The new rotation amount for A
124  /// @details Ultimately this information winds up being stored in the TransformA. This implements
125  /// a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
126  virtual void SetAPivotRotation(const Quaternion& Rotation);
127  /// @brief Set The relative rotation of ActorB
128  /// @param otation The new rotation amount for B
129  /// @details Ultimately this information winds up being stored in the TransformB. This implements
130  /// a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
131  virtual void SetBPivotRotation(const Quaternion& Rotation);
132  /// @brief Get the relative rotation for ActorA
133  /// @return A Quaternion that has the rotation
134  /// @details This implements a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
135  virtual Quaternion GetAPivotRotation() const;
136  /// @brief Get the relative rotation for ActorB
137  /// @return A Quaternion that has the rotation
138  /// @details This implements a more Hinge specific version of the logic than DualTransformConstraint for efficiency reasons.
139  virtual Quaternion GetBPivotRotation() const;
140 
141  /// @copydoc DualTransformConstraint::SetTransformA
142  virtual void SetPivotATransform(const Transform& TranA);
143  /// @copydoc DualTransformConstraint::SetTransformB
144  virtual void SetPivotBTransform(const Transform& TranB);
145  /// @copydoc DualTransformConstraint::GetTransformA
146  virtual Transform GetPivotATransform() const;
147  /// @copydoc DualTransformConstraint::GetTransformB
148  virtual Transform GetPivotBTransform() const;
149 
150  ////////////////////////////////////////////////////////////////////////////////
151  // HingeConstraint Angular Motor
152 
153  /// @brief Enables(or Disables) the motor on the hinge and sets it's parameters.
154  /// @param EnableMotor Sets whether or not the motor on this constraint is enabled.
155  /// @param TargetVelocity The desired velocity of rotation the motor will have. This may or may not be achieved based on obstructions in the simulation.
156  /// @param MaxMotorImpulse The maximum amount of force the motor is to apply to try and reach it's target velocity.
157  virtual void EnableMotor(bool EnableMotor, Real TargetVelocity, Real MaxMotorImpulse);
158  /// @brief Enables(or Disables) the motor on the hinge.
159  /// @warning Be sure to set values for the Motor max impulse and/or velocity before enabling the motor, or else you may get a crash.
160  /// @param EnableMotor Sets whether or not the motor on this constraint is enabled.
161  virtual void EnableMotor(bool EnableMotor);
162  /// @brief Is this motor on this hinge enabled?
163  /// @return True if it is, false otherwise.
164  virtual bool GetMotorEnabled() const;
165  /// @brief Sets the maximum amount of force the motor is to apply.
166  /// @param MaxMotorImpulse The maximum amount of force the motor is to apply to try and reach it's target velocity.
167  virtual void SetMaxMotorImpulse(Real MaxMotorImpulse);
168  /// @brief Retrieve the maximimum value that the acceleration of the motor can be increased.
169  /// @return A real containing the maximum impulse.
170  virtual Real GetMaxMotorImpulse() const;
171  /// @brief Sets a Target Velocity, indirectly using the angle stored in a quaternion.
172  /// @details Is implemented in terms of SetMotorTarget(Real, Real);
173  /// @param QuatAInB The angle a quaternion relative to the two objects in the constraint.
174  /// @param Dt The Desired Time steps that the target rotational velocity should be reached in.
175  virtual void SetMotorTarget(const Quaternion& QuatAInB, Real Dt);
176  /// @brief Set the Rotational velocity in a more direct fashion
177  /// @param TargetAngle The desired angle in radians.
178  /// @param Dt The Desired Time steps that the target rotational velocity should be reached in.
179  virtual void SetMotorTarget(Real TargetAngle, Real Dt);
180  /// @brief Desired angular velocity of the motor
181  /// @param TargetVelocity The Desired velocity
182  /// @warning Causes segfaults in some tests.
183  virtual void SetMotorTargetVelocity(Real TargetVelocity);
184  /// @brief Get the Target Velocity.
185  /// @return the target valocity as a real.
186  virtual Real GetMotorTargetVelocity() const;
187 
188  ////////////////////////////////////////////////////////////////////////////////
189  // HingeConstraint Limits
190 
191  /// @brief Sets the angle limits of the constraint in radians.
192  /// @param Low The minimum angle limit for the constraint in radians.
193  /// @param High The maximum angle limit for the constraint in radians.
194  /// @param Softness Not currently used internally.
195  /// @param BiasFactor Multiplier for the constraint error, constraint appears more "soft" when closer to zero.
196  /// @param RelaxationFactor The amount of bounce to apply when the constraint reaches it's limit. Range: 0.0-1.0.
197  virtual void SetLimit(Real Low, Real High, Real Softness=0.9, Real BiasFactor=0.3, Real RelaxationFactor=1.0);
198  /// @brief Return the Lower Limit of the hinge
199  /// @return A real containing the Lower Limit
200  virtual Real GetLimitLow() const;
201  /// @brief Return the Upper Limit of the hinge
202  /// @return A real containing the Higher Limit
203  virtual Real GetLimitHigh() const;
204  /// @brief Return the Softness of the hinge
205  /// @return A real containing the Softness
206  virtual Real GetLimitSoftness() const;
207  /// @brief Return the bias factor of the hinge (Not entirely certain hat this on is)
208  /// @return A real containing the bias Factor
209  virtual Real GetLimitBiasFactor() const;
210  /// @brief Return the Relaxation Factor of the hinge
211  /// @return A real containing the Relaxation Factor
212  virtual Real GetLimitRelaxationFactor() const;
213 
214  ////////////////////////////////////////////////////////////////////////////////
215  // HingeConstraint Details
216 
217  /// @brief Sets the axis on which this constraint acts.
218  /// @param AxisInA A vector3 representing the axis to be used with this constraint.
219  virtual void SetAxis(const Vector3& AxisInA);
220  /// @brief Gets the current angle of the hinge.
221  /// @return Gets the amount of rotation this hinge is off from it's origin in radians.
222  virtual Real GetHingeAngle();
223  /// @copydoc Constraint::ValidParamOnAxis(int) const
224  virtual Constraint::ParamList ValidParamOnAxis(int Axis) const;
225  /// @copydoc Constraint::ValidLinearAxis() const
226  virtual Constraint::AxisList ValidLinearAxis() const;
227  /// @copydoc Constraint::ValidAngularAxis() const
228  virtual Constraint::AxisList ValidAngularAxis() const;
229  /// @copydoc Constraint::ValidAngularAxis(ConstraintParam,int) const
230  virtual bool HasParamBeenSet(ConstraintParam Param, int Axis) const;
231  /// @brief Retrieve the stored value from the physics subsystem(bullet)
232  /// @return a True or false.
233  virtual bool GetUseFrameOffset() const;
234  /// @brief Set the stored value for UseFrameOffset on this hinge in the physics subsystem(bullet)
235  /// @param FrameOffset The new desired value.
236  virtual void SetUseFrameOffset(bool FrameOffset);
237  /// @brief Is this Using Reference Frame A
238  /// @return A the value UseReferenceFrameA is set to internally.
239  virtual bool GetUseReferenceFrameA() const;
240  /// @brief Change whether this is Using Reference Frame A or not
241  /// @param UseReferenceFrameA Whether certain math be performed from the perspective of Actor A or Actor B (we think this is the case, but we have not test thoroughly)
242  virtual void SetUseReferenceFrameA(bool UseReferenceFrameA=false);
243 
244  /// @copydoc Constraint::GetConstraintBase() const
245  virtual btTypedConstraint* GetConstraintBase() const;
246 
247  ////////////////////////////////////////////////////////////////////////////////
248  // HingeConstraint Serialization
249 
250  /// @brief Convert this class to an XML::Node ready for serialization
251  /// @param CurrentRoot The point in the XML hierarchy that all this vectorw should be appended to.
252  virtual void ProtoSerialize(XML::Node& CurrentRoot) const;
253  /// @brief Take the data stored in an XML and overwrite this instance of this object with it
254  /// @param OneNode and XML::Node containing the data.
255  /// @warning A precondition of using this is that all of the actors intended for use must already be Deserialized.
256  virtual void ProtoDeSerialize(const XML::Node& OneNode);
257  /// @brief Get the name of the the XML tag this class will leave behind as its instances are serialized.
258  /// @return A string containing "HingeConstraint"
259  static String SerializableName();
260  };//HingeConstraint
261  }//Physics
262 }//Mezzanine
263 
264 ///////////////////////////////////////////////////////////////////////////////
265 // Class External << Operators for streaming or assignment
266 
267 /// @copydoc operator << (std::ostream& stream, const Mezzanine::Physics::Constraint& x)
268 std::ostream& MEZZ_LIB operator << (std::ostream& stream, const Mezzanine::Physics::HingeConstraint& x);
269 /// @copydoc operator >> (std::istream& stream, Mezzanine::Physics::Constraint& x)
270 std::istream& MEZZ_LIB operator >> (std::istream& stream, Mezzanine::Physics::HingeConstraint& x);
271 /// @copydoc operator >> (const Mezzanine::XML::Node& OneNode, Mezzanine::Physics::Constraint& x)
272 void operator >> (const Mezzanine::XML::Node& OneNode, Mezzanine::Physics::HingeConstraint& x);
273 
274 #endif