Spinning Topp Logo BlackTopp Studios
inc
conetwistconstraint.cpp
1 // © Copyright 2010 - 2016 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 _physicsconetwistconstraint_cpp
41 #define _physicsconetwistconstraint_cpp
42 
43 #include "Physics/conetwistconstraint.h"
44 #include "Physics/rigidproxy.h"
45 
46 #include "stringtool.h"
47 #include "serialization.h"
48 
49 #include <btBulletDynamicsCommon.h>
50 
51 namespace Mezzanine
52 {
53  namespace Physics
54  {
55  /////////////////////////////////////////
56  // ConeTwist Constraint Functions
57 
58  ConeTwistConstraint::ConeTwistConstraint(const UInt32 ID, RigidProxy* ProxyA, RigidProxy* ProxyB, const Transform& TransA, const Transform& TransB, PhysicsManager* Creator) :
59  DualTransformConstraint(ID,ProxyA,ProxyB,Creator),
60  ConeTwist(NULL)
61  { this->CreateConstraint(ProxyA,ProxyB,TransA,TransB); }
62 
64  DualTransformConstraint(ID,ProxyA,Creator),
65  ConeTwist(NULL)
66  { this->CreateConstraint(ProxyA,NULL,TransA,Transform()); }
67 
69  DualTransformConstraint(0,NULL,Creator),
70  ConeTwist(NULL)
71  { this->ProtoDeSerialize(SelfRoot); }
72 
74  { this->DestroyConstraint(); }
75 
76  void ConeTwistConstraint::CreateConstraint(RigidProxy* RigidA, RigidProxy* RigidB, const Transform& TransA, const Transform& TransB)
77  {
78  if( this->ConeTwist == NULL ) {
79  if( RigidA && RigidB ) {
80  this->ConeTwist = new btConeTwistConstraint(*(RigidA->_GetPhysicsObject()),*(RigidB->_GetPhysicsObject()),TransA.GetBulletTransform(),TransB.GetBulletTransform());
81  }else if( RigidA ) {
82  this->ConeTwist = new btConeTwistConstraint(*(RigidA->_GetPhysicsObject()),TransA.GetBulletTransform());
83  }
84  }
85  }
86 
88  {
89  this->EnableConstraint(false);
90  if( this->ConeTwist != NULL ) {
91  delete this->ConeTwist;
92  this->ConeTwist = NULL;
93  }
94  this->ProxA = NULL;
95  this->ProxB = NULL;
96  }
97 
98  ///////////////////////////////////////////////////////////////////////////////
99  // Utility Methods
100 
102  { return this->ConeTwist->isPastSwingLimit(); }
103 
105  { return this->ConeTwist->getTwistAngle(); }
106 
108  {
109  btTransform BTrans = this->ConeTwist->getBFrame();
110  this->ConeTwist->setFrames(TransA.GetBulletTransform(),BTrans);
111  }
112 
114  {
115  btTransform ATrans = this->ConeTwist->getAFrame();
116  this->ConeTwist->setFrames(ATrans,TransB.GetBulletTransform());
117  }
118 
120  { return Transform( this->ConeTwist->getAFrame() ); }
121 
123  { return Transform( this->ConeTwist->getBFrame() ); }
124 
125  ///////////////////////////////////////////////////////////////////////////////
126  // Configuration Methods
127 
129  { this->ConeTwist->enableMotor(Enable); }
130 
132  { return this->ConeTwist->isMotorEnabled(); }
133 
134  void ConeTwistConstraint::SetAngularOnly(const Boole AngularOnly)
135  { this->ConeTwist->setAngularOnly(AngularOnly); }
136 
137  Boole ConeTwistConstraint::GetAngularOnly() const
138  { return this->ConeTwist->getAngularOnly(); }
139 
140  void ConeTwistConstraint::SetLimit(const Integer LimitIndex, const Real LimitValue)
141  { this->ConeTwist->setLimit(LimitIndex, LimitValue); }
142 
143  void ConeTwistConstraint::SetLimits(const Real SwingSpan1, const Real SwingSpan2, const Real TwistSpan, const Real Softness, const Real BiasFactor, const Real RelaxationFactor)
144  { this->ConeTwist->setLimit(SwingSpan1, SwingSpan2, TwistSpan, Softness, BiasFactor, RelaxationFactor); }
145 
147  { return this->ConeTwist->getLimit(LimitIndex); }
148 
150  { return this->ConeTwist->getSwingSpan1(); }
151 
153  { return this->ConeTwist->getSwingSpan2(); }
154 
156  { return this->ConeTwist->getTwistAngle(); }
157 
159  { return this->ConeTwist->getLimitSoftness(); }
160 
162  { return this->ConeTwist->getBiasFactor(); }
163 
165  { return this->ConeTwist->getRelaxationFactor(); }
166 
167  void ConeTwistConstraint::SetDamping(const Real Damping)
168  { this->ConeTwist->setDamping(Damping); }
169 
170  Real ConeTwistConstraint::GetDamping() const
171  { return this->ConeTwist->getDamping(); }
172 
173  void ConeTwistConstraint::SetMaxMotorImpulse(const Real MaxMotorImpulse)
174  { this->ConeTwist->setMaxMotorImpulse(MaxMotorImpulse); }
175 
176  void ConeTwistConstraint::SetMaxMotorImpulseNormalized(const Real MaxMotorImpulse)
177  { this->ConeTwist->setMaxMotorImpulseNormalized(MaxMotorImpulse); }
178 
179  Boole ConeTwistConstraint::IsMaxMotorImpulseNormalized() const
180  { return this->ConeTwist->isMaxMotorImpulseNormalized(); }
181 
182  Real ConeTwistConstraint::GetMaxMotorImpulse() const
183  { return this->ConeTwist->getMaxMotorImpulse(); }
184 
185  void ConeTwistConstraint::SetFixThresh(const Real FixThresh)
186  { this->ConeTwist->setFixThresh(FixThresh); }
187 
188  Real ConeTwistConstraint::GetFixThresh() const
189  { return this->ConeTwist->getFixThresh(); }
190 
191  void ConeTwistConstraint::SetMotorTarget(const Quaternion& Quat)
192  { this->ConeTwist->setMotorTarget( Quat.GetBulletQuaternion() ); }
193 
194  void ConeTwistConstraint::SetMotorTargetInConstraintSpace(const Quaternion& Quat)
195  { this->ConeTwist->setMotorTargetInConstraintSpace( Quat.GetBulletQuaternion() ); }
196 
198  { return Quaternion( this->ConeTwist->getMotorTarget() ); }
199 
200  ///////////////////////////////////////////////////////////////////////////////
201  // Constraint Parameters
202 
204  {
205  Constraint::ParamList Results;
206  // All params are valid on each of the 6 axes
207  if( Axis >= 0 && Axis < 6 ) {
208  Results.push_back(Con_ERP);
209  Results.push_back(Con_Stop_ERP);
210  Results.push_back(Con_CFM);
211  Results.push_back(Con_Stop_CFM);
212  }
213  return Results;
214  }
215 
217  {
218  Constraint::AxisList Results;
219  Results.push_back(0);
220  Results.push_back(1);
221  Results.push_back(2);
222  return Results;
223  }
224 
226  {
227  Constraint::AxisList Results;
228  Results.push_back(3);
229  Results.push_back(4);
230  Results.push_back(5);
231  return Results;
232  }
233 
235  {
236  if( Param == Physics::Con_ERP || Param == Physics::Con_Stop_ERP ) {
237  if( Axis >= 0 && Axis < 3 ) {
238  return ( this->ConeTwist->getFlags() & BT_CONETWIST_FLAGS_LIN_ERP );
239  }else if( Axis >= 3 && Axis < 6 ) {
240  // This internally correlates to the biasfactor
241  return true;
242  }
243  }else if( Param == Physics::Con_CFM || Param == Physics::Con_Stop_CFM ) {
244  if( Axis >= 0 && Axis < 3 ) {
245  return ( this->ConeTwist->getFlags() & BT_CONETWIST_FLAGS_LIN_CFM );
246  }else if( Axis >= 3 && Axis < 6 ) {
247  return ( this->ConeTwist->getFlags() & BT_CONETWIST_FLAGS_ANG_CFM );
248  }
249  }
250  return false;
251  }
252 
253  ///////////////////////////////////////////////////////////////////////////////
254  // Serialization
255 
257  {
258  this->Constraint::ProtoSerializeProperties(SelfRoot);
259 
260  XML::Node PropertiesNode = SelfRoot.AppendChild( ConeTwistConstraint::GetSerializableName() + "Properties" );
261 
262  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
263  PropertiesNode.AppendAttribute("MotorEnabled").SetValue( this->IsMotorEnabled() ) &&
264  PropertiesNode.AppendAttribute("AngularOnly").SetValue( this->GetAngularOnly() ) &&
265  PropertiesNode.AppendAttribute("Damping").SetValue( this->GetDamping() ) &&
266  PropertiesNode.AppendAttribute("MaxMotorImpulse").SetValue( this->GetMaxMotorImpulse() ) &&
267  PropertiesNode.AppendAttribute("FixThreshold").SetValue( this->GetFixThresh() ) &&
268  PropertiesNode.AppendAttribute("SwingSpan1").SetValue( this->GetSwingSpan1() ) &&
269  PropertiesNode.AppendAttribute("SwingSpan2").SetValue( this->GetSwingSpan2() ) &&
270  PropertiesNode.AppendAttribute("TwistSpan").SetValue( this->GetTwistSpan() ) &&
271  PropertiesNode.AppendAttribute("LimitSoftness").SetValue( this->GetLimitSoftness() ) &&
272  PropertiesNode.AppendAttribute("BiasFactor").SetValue( this->GetBiasFactor() ) &&
273  PropertiesNode.AppendAttribute("RelaxationFactor").SetValue( this->GetRelaxationFactor() ) )
274  {
275  XML::Node MotorTargetNode = PropertiesNode.AppendChild("MotorTarget");
276  this->GetMotorTarget().ProtoSerialize( MotorTargetNode );
277 
278  return;
279  }else{
280  SerializeError("Create XML Attribute Values",ConeTwistConstraint::GetSerializableName() + "Properties",true);
281  }
282  }
283 
285  {
287 
288  XML::Attribute CurrAttrib;
289  XML::Node PropertiesNode = SelfRoot.GetChild( ConeTwistConstraint::GetSerializableName() + "Properties" );
290 
291  if( !PropertiesNode.Empty() ) {
292  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
293  Real ConeSwingSpan1 = 0.0;
294  Real ConeSwingSpan2 = 0.0;
295  Real ConeTwistSpan = 0.0;
296  Real ConeLimitSoftness = 1.0;
297  Real ConeBiasFactor = 0.3;
298  Real ConeRelaxationFactor = 1.0;
299 
300  CurrAttrib = PropertiesNode.GetAttribute("MotorEnabled");
301  if( !CurrAttrib.Empty() )
302  this->EnableMotor( CurrAttrib.AsBool() );
303 
304  CurrAttrib = PropertiesNode.GetAttribute("AngularOnly");
305  if( !CurrAttrib.Empty() )
306  this->SetAngularOnly( CurrAttrib.AsBool() );
307 
308  CurrAttrib = PropertiesNode.GetAttribute("Damping");
309  if( !CurrAttrib.Empty() )
310  this->SetDamping( CurrAttrib.AsReal() );
311 
312  CurrAttrib = PropertiesNode.GetAttribute("MaxMotorImpulse");
313  if( !CurrAttrib.Empty() )
314  this->SetMaxMotorImpulse( CurrAttrib.AsReal() );
315 
316  CurrAttrib = PropertiesNode.GetAttribute("FixThreshold");
317  if( !CurrAttrib.Empty() )
318  this->SetFixThresh( CurrAttrib.AsReal() );
319 
320  CurrAttrib = PropertiesNode.GetAttribute("SwingSpan1");
321  if( !CurrAttrib.Empty() )
322  ConeSwingSpan1 = CurrAttrib.AsReal();
323 
324  CurrAttrib = PropertiesNode.GetAttribute("SwingSpan2");
325  if( !CurrAttrib.Empty() )
326  ConeSwingSpan2 = CurrAttrib.AsReal();
327 
328  CurrAttrib = PropertiesNode.GetAttribute("TwistSpan");
329  if( !CurrAttrib.Empty() )
330  ConeTwistSpan = CurrAttrib.AsReal();
331 
332  CurrAttrib = PropertiesNode.GetAttribute("LimitSoftness");
333  if( !CurrAttrib.Empty() )
334  ConeLimitSoftness = CurrAttrib.AsReal();
335 
336  CurrAttrib = PropertiesNode.GetAttribute("BiasFactor");
337  if( !CurrAttrib.Empty() )
338  ConeBiasFactor = CurrAttrib.AsReal();
339 
340  CurrAttrib = PropertiesNode.GetAttribute("RelaxationFactor");
341  if( !CurrAttrib.Empty() )
342  ConeRelaxationFactor = CurrAttrib.AsReal();
343 
344  this->SetLimits(ConeSwingSpan1,ConeSwingSpan2,ConeTwistSpan,ConeLimitSoftness,ConeBiasFactor,ConeRelaxationFactor);
345 
346  XML::Node MotorTargetNode = PropertiesNode.GetChild("MotorTarget").GetFirstChild();
347  if( !MotorTargetNode.Empty() ) {
348  Quaternion MotorTarget(MotorTargetNode);
349  this->SetMotorTarget(MotorTarget);
350  }
351  }else{
352  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + ( ConeTwistConstraint::GetSerializableName() + "Properties" ) + ": Not Version 1.");
353  }
354  }else{
355  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,ConeTwistConstraint::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
356  }
357  }
358 
361 
363  { return "ConeTwistConstraint"; }
364 
365  ///////////////////////////////////////////////////////////////////////////////
366  // Internal
367 
368  btTypedConstraint* ConeTwistConstraint::_GetConstraintBase() const
369  { return this->ConeTwist; }
370  }//Physics
371 }//Mezzanine
372 
373 #endif
std::vector< int > AxisList
Used to Store lists of Int Axis for return types.
Definition: constraint.h:124
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
CFM values adds some small value to the main diagonal on the constraint matrix to prevent degenerate ...
Definition: constraint.h:65
virtual ~ConeTwistConstraint()
Class destructor.
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
virtual Real GetTwistSpan() const
Gets the currently set value for the constraint Twist span on the X axis.
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
All constraints that track rotation and location of the Pivot relative to each Actor inherit from thi...
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
ConeTwistConstraint(const UInt32 ID, RigidProxy *ProxyA, RigidProxy *ProxyB, const Transform &TransA, const Transform &TransB, PhysicsManager *Creator)
Class constructor.
bool AsBool(bool def=false) const
Attempts to convert the value of the attribute to a float and returns the results.
virtual AxisList GetValidAngularAxes() const
Get A list sorted (low to high) of all axis that operate Angularly (that lock sliding/translation) ...
virtual Boole IsMotorEnabled() const
Gets whether or not the motor is enabled.
virtual Real GetSwingSpan2() const
Gets the currently set value for the constraint Swing span on the Z axis.
virtual Real GetBiasFactor() const
Gets the strength of the force enforcing the twist limits.
Thrown when the requested identity could not be found.
Definition: exception.h:94
virtual Real GetLimit(const Integer LimitIndex) const
Gets a constraint limit based on Index.
static String GetSerializableName()
Get the name of the the XML tag the class will leave behind as its instances are serialized.
Node GetFirstChild() const
Get the first child Node of this Node.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
int Integer
A datatype used to represent any integer close to.
Definition: datatypes.h:154
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
virtual void SetLimits(const Real SwingSpan1, const Real SwingSpan2, const Real TwistSpan, const Real Softness=1.0, const Real BiasFactor=0.3, const Real RelaxationFactor=1.0)
Sets all constraint limits.
virtual void EnableConstraint(const Boole Enable)
Enables or disables this constraint.
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
bool Empty() const
Is this storing anything at all?
virtual ParamList GetValidParamsOnAxis(int Axis) const
Get a sorted (low to high) list of Parameters that are valid on this Axis.
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
The interface for serialization.
bool SetValue(const Char8 *rhs)
Set the value of this.
btTransform GetBulletTransform() const
Gets a Bullet Transform.
Definition: transform.cpp:71
virtual btTypedConstraint * _GetConstraintBase() const
Get the Bullet constraint that this class encapsulates.
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
btConeTwistConstraint * ConeTwist
The internal constraint that this class encapsulates.
virtual Real GetRelaxationFactor() const
Gets the strength of the force enforcing the swing limits.
virtual Transform GetPivotBTransform() const
Gets the current Rotation and Location of ProxyB.
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
bool Empty() const
Is this storing anything at all?
virtual void SetPivotBTransform(const Transform &TransB)
Sets the Position and Rotation for the second body using a Transform.
virtual void EnableMotor(const Boole Enable)
Enables (or disables) the motor of this constraint.
virtual btRigidBody * _GetPhysicsObject() const
Accessor for the internal rigid body physics proxy.
Definition: rigidproxy.cpp:406
virtual Boole HasParamBeenSet(ConstraintParam Param, int Axis) const
Has the given Param on the Given Axis been set yet.
Real AsReal(Real def=0) const
Attempts to convert the value of the attribute to a Real and returns the results. ...
ConstraintParam
Used by constraints for setting some parameters.
Definition: constraint.h:61
virtual void DestroyConstraint()
Destroys the internal constraint.
virtual void SetLimit(const Integer LimitIndex, const Real LimitValue)
Sets a constraint limit based on Index.
This is a proxy from which rigid body proxys are handled.
Definition: rigidproxy.h:102
Stores information about relative location and rotation in 3d space.
Definition: transform.h:62
std::vector< ConstraintParam > ParamList
Used to Store lists of param for return types.
Definition: constraint.h:120
This is simply a place for storing all the Physics Related functions.
RigidProxy * ProxA
The first Collidable this constraint applies to.
Definition: constraint.h:130
virtual AxisList GetValidLinearAxes() const
Get a sorted (low to high) list of all axis that operate linearly (that lock sliding/translation) ...
virtual void ProtoDeSerialize(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite this object with it.
RigidProxy * ProxB
The second Collidable this constraint applies to.
Definition: constraint.h:133
virtual String GetDerivedSerializableName() const
Gets the most derived serializable name of this Constraint.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
virtual Transform GetPivotATransform() const
Gets the current Rotation and Location of ProxyA.
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
Definition: quaternion.cpp:502
Real GetTwistAngle() const
Gets the current angle of thw twist applied to the constraint.
This is used to store information about rotation in 3d space.
Definition: quaternion.h:68
ERP values adjust how fast the errors in the constraints are reduced.
Definition: constraint.h:63
void SerializeError(const String &FailedTo, const String &ClassName, Boole SOrD)
Simply does some string concatenation, then throws an Exception.
Node AppendChild(NodeType Type=NodeElement)
Creates a Node and makes it a child of this one.
virtual Real GetSwingSpan1() const
Gets the currently set value for the constraint Swing span on the Y axis.
virtual void SetPivotATransform(const Transform &TransA)
Sets the Position and Rotation for the first body using a Transform.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
Attribute GetAttribute(const Char8 *Name) const
Attempt to get an Attribute on this Node with a given name.
virtual Real GetLimitSoftness() const
Gets the % portion of the swing limit in which to start enforcing the limit.
virtual void CreateConstraint(RigidProxy *RigidA, RigidProxy *RigidB, const Transform &TransA, const Transform &TransB)
Creates the internal constraint.
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.
Boole IsPassedSwingLimit() const
Gets whether or not the child object is outside the set limits for the constraint.