Spinning Topp Logo BlackTopp Studios
inc
constraint.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 _physicsconstraint_cpp
41 #define _physicsconstraint_cpp
42 
43 #include "Physics/constraint.h"
44 #include "Physics/physicsenumerations.h"
45 #include "Physics/physicsmanager.h"
46 #include "Physics/rigidproxy.h"
47 
48 #include "actormanager.h"
49 #include "entresol.h"
50 
51 #include "stringtool.h"
52 #include "exception.h"
53 #include "serialization.h"
54 
55 #include <btBulletDynamicsCommon.h>
56 #include <BulletSoftBody/btSoftRigidDynamicsWorld.h>
57 
58 /// @cond DontDocumentInternal
59 
60 namespace Mezzanine
61 {
62  namespace Physics
63  {
64  /////////////////////////////////////////
65  // Functions
66 
68  {
69  switch (Param)
70  {
71  case Con_ERP: return String("Con_ERP");
72  case Con_Stop_ERP: return String("Con_Stop_ERP");
73  case Con_CFM: return String("Con_CFM");
74  case Con_Stop_CFM: return String("Con_Stop_CFM");
75  default: { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid Constraint Paramater to a String."); }
76  }
77  }
78 
80  {
81  if(5>Param.size())
82  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Too Short."); }
83 
84  switch(Param.at(4))
85  {
86  case 'E':
88  { return Con_ERP; }
89  else
90  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_ERP but isn't."); }
91  case 'C':
93  { return Con_CFM; }
94  else
95  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_CFM but isn't."); }
96  case 'S':
97  switch(Param.at(9))
98  {
99  case 'E':
100  if(ConstraintParamAsString(Con_Stop_ERP)==Param)
101  { return Con_Stop_ERP; }
102  else
103  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_Stop_ERP but isn't."); }
104  case 'C':
105  if(ConstraintParamAsString(Con_Stop_CFM)==Param)
106  { return Con_Stop_CFM; }
107  else
108  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_Stop_CFM but isn't."); }
109  case 'S':
110 
111  default:
112  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appeared to be Con_Stop_Something, but wasn't."); }
113  }
114  default:
115  { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Invalid Name."); }
116  }
117  }
118 
119  int char4ToAxis(char it)
120  {
121  switch(it)
122  {
123  case '-': return -1; break;
124  case '0': return 0; break;
125  case '1': return 1; break;
126  case '2': return 2; break;
127  case '3': return 3; break;
128  case '4': return 4; break;
129  case '5': return 5; break;
130  default: { MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"Cannot convert invalid axis name."); }
131  }
132  }
133 
134  /////////////////////////////////////////
135  // Constraint Functions
136 
137  ////////////////////////////////////////////////////////////////////////////////
138  // Constraint Protected Methods
139 
140  Constraint::Constraint(const UInt32 ID, PhysicsManager* Creator) :
141  ProxA(NULL),
142  ProxB(NULL),
143  Manager(Creator),
144  ConstraintID(ID),
145  AllowCollisions(true),
146  Enabled(false)
147  { }
148 
149  Constraint::Constraint(const UInt32 ID, RigidProxy* Prox1, PhysicsManager* Creator) :
150  ProxA(Prox1),
151  ProxB(NULL),
152  Manager(Creator),
153  ConstraintID(ID),
154  AllowCollisions(true),
155  Enabled(false)
156  {
157  if( this->ProxA ) {
158  this->ProxA->SetActivationState(Physics::AS_DisableDeactivation);
159  }
160  }
161 
162  Constraint::Constraint(const UInt32 ID, RigidProxy* Prox1, RigidProxy* Prox2, PhysicsManager* Creator) :
163  ProxA(Prox1),
164  ProxB(Prox2),
165  Manager(Creator),
166  ConstraintID(ID),
167  AllowCollisions(true),
168  Enabled(false)
169  {
170  if( this->ProxA ) {
171  this->ProxA->SetActivationState(Physics::AS_DisableDeactivation);
172  }
173  if( this->ProxB ) {
174  this->ProxB->SetActivationState(Physics::AS_DisableDeactivation);
175  }
176  }
177 
179  { }
180 
181  ////////////////////////////////////////////////////////////////////////////////
182  // Utility
183 
185  { return this->ConstraintID; }
186 
187  void Constraint::EnableConstraint(const Boole Enable)
188  {
189  if( Enable != this->Enabled ) {
190  if( Enable ) {
191  this->Manager->_GetPhysicsWorldPointer()->addConstraint(this->_GetConstraintBase(),!this->AllowCollisions);
192  }else{
193  this->Manager->_GetPhysicsWorldPointer()->removeConstraint(this->_GetConstraintBase());
194  }
195  this->Enabled = Enable;
196  }
197  }
198 
200  { return this->Enabled; }
201 
202  void Constraint::SetAllowCollisions(const Boole Allow)
203  { this->AllowCollisions = Allow; }
204 
206  { return this->AllowCollisions; }
207 
208  RigidProxy* Constraint::GetProxyA() const
209  { return this->ProxA; }
210 
211  RigidProxy* Constraint::GetProxyB() const
212  { return this->ProxB; }
213 
214  ///////////////////////////////////////////////////////////////////////////////
215  // Constraint Parameters
216 
218  {
219  AxisList Ang = this->GetValidAngularAxes();
220  AxisList Lin = this->GetValidLinearAxes();
221  Lin.insert(Lin.end(),Ang.begin(),Ang.end()); // just kinda stick the two together and return that, no checking is performed for uniqueness.
222  std::sort(Lin.begin(),Lin.end()); // Usually the Linear axis are 0,1,2 and the angular are 3,4,5 so hopefully, this will hardly ever need to do work.
223  return Lin;
224  }
225 
227  {
228  ParamList Supported = GetValidParamsOnAxis(Axis);
229  if( size_t(ConstraintParamCount) == Supported.size() ) { // no need to check deeper, because everything is supported
230  return true;
231  }else{
232  if( Supported.size() ) {
233  return ( std::find(Supported.begin(),Supported.end(),Param) != Supported.end() ); // should return true if found
234  }else{
235  return false; // size is 0 of course it is not supported
236  }
237  }
238  }
239 
241  {
242  AxisList AllAxis = this->GetValidAxes();
243  ParamList Results;
244  if( AllAxis.size() ) { //If we have no Axis, the we have no valid Parameters.
245  Results = this->GetValidParamsOnAxis( *(AllAxis.begin()) ); // Let's start off with whatever the first Axis Support, then we will trim from here.
246 
247  if( AllAxis.size() > 1 ) { //if the constraint only support one axis then we already have our answer, and we don't want to run of the end of the Paramlist
248  for( AxisList::iterator AxisIter = AllAxis.begin() + 1 ; AllAxis.end() != AxisIter; ++AxisIter ) //For each axis after the first
249  {
250  for( int ParamID = Results.size() ; ParamID <= 0 ; --ParamID ) // We start at the back and work by index because reverse erase does no accept rever iterators, and
251  {
252  if( !this->IsParamValidOnAxis(Results.at(ParamID),*AxisIter) ) { // if an Item is erase near the beginning, it changes all the items after, making forward iteration logic that
253  Results.erase( Results.begin()+ParamID ); // erases needlessly complicated, and potentially expensive depending on the Vector implementation
254  }
255  }
256  }
257  }
258  }
259  sort(Results.begin(),Results.end());
260  return Results;
261  }
262 
263  void Constraint::SetParam(ConstraintParam Param, Real Value, int Axis)
264  { this->_GetConstraintBase()->setParam(Param, Value, Axis); }
265 
266  Real Constraint::GetParam(ConstraintParam Param, int Axis) const
267  { return this->_GetConstraintBase()->getParam(Param, Axis); }
268 
269  ///////////////////////////////////////////////////////////////////////////////
270  // Serialization
271 
272  void Constraint::ProtoSerialize(XML::Node& ParentNode) const
273  {
274  XML::Node SelfRoot = ParentNode.AppendChild(this->GetDerivedSerializableName());
275 
276  this->ProtoSerializeInitData(SelfRoot);
277  this->ProtoSerializeProperties(SelfRoot);
278  this->ProtoSerializeGlobalOverrides(SelfRoot);
279  }
280 
281  void Constraint::ProtoSerializeProperties(XML::Node& SelfRoot) const
282  {
283  XML::Node PropertiesNode = SelfRoot.AppendChild( Constraint::GetSerializableName() + "Properties" );
284 
285  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
286  PropertiesNode.AppendAttribute("ID").SetValue( this->ConstraintID ) &&
287  PropertiesNode.AppendAttribute("Enabled").SetValue( this->IsConstraintEnabled() ) &&
288  PropertiesNode.AppendAttribute("AllowCollisions").SetValue( this->GetAllowCollisions() ) )
289  {
290  return;
291  }else{
292  SerializeError("Create XML Attribute Values",Constraint::GetSerializableName() + "Properties",true);
293  }
294  }
295 
296  void Constraint::ProtoSerializeGlobalOverrides(XML::Node& SelfRoot) const
297  {
298  XML::Node GlobalOverridesNode = SelfRoot.AppendChild( Constraint::GetSerializableName() + "GlobalOverrides" );
299 
300  String CurrentAxisName;
301  AxisList AllAxis = this->GetValidAxes();
302  for( AxisList::iterator AxisIter = AllAxis.begin() ; AllAxis.end() != AxisIter ; ++AxisIter )
303  {
304  XML::Node OverrideNode = GlobalOverridesNode.AppendChild("ParamOverride");
305 
306  ParamList AxisParams = this->GetValidParamsOnAxis(*AxisIter);
307  for( ParamList::iterator ParamIter = AxisParams.begin() ; AxisParams.end() != ParamIter; ++ParamIter )
308  {
309  if( this->HasParamBeenSet(*ParamIter,*AxisIter) ) {
310  if( OverrideNode.AppendAttribute("Version").SetValue("1") &&
311  OverrideNode.AppendAttribute("Axis").SetValue( *AxisIter ) &&
312  OverrideNode.AppendAttribute("Param").SetValue( ConstraintParamAsString(*ParamIter) ) &&
313  OverrideNode.AppendAttribute("Value").SetValue( this->GetParam(*ParamIter,*AxisIter) ) )
314  {
315  continue;
316  }else{
317  SerializeError(String("Create ") + ConstraintParamAsString(*ParamIter) + " Attribute in " + CurrentAxisName + " Node.",this->GetSerializableName());
318  }
319  }// If the parameter has already been set
320  }// For each param
321  }// For each axis
322  }
323 
324  void Constraint::ProtoDeSerialize(const XML::Node& SelfRoot)
325  {
326  this->ProtoDeSerializeInitData(SelfRoot);
327  this->ProtoDeSerializeProperties(SelfRoot);
328  this->ProtoDeSerializeGlobalOverrides(SelfRoot);
329  }
330 
331  void Constraint::ProtoDeSerializeProperties(const XML::Node& SelfRoot)
332  {
333  XML::Attribute CurrAttrib;
334  XML::Node PropertiesNode = SelfRoot.GetChild( Constraint::GetSerializableName() + "Properties" );
335 
336  if( !PropertiesNode.Empty() ) {
337  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
338  CurrAttrib = PropertiesNode.GetAttribute("ID");
339  if( !CurrAttrib.Empty() )
340  this->ConstraintID = static_cast<UInt32>( CurrAttrib.AsUint() );
341 
342  CurrAttrib = PropertiesNode.GetAttribute("AllowCollisions");
343  if( !CurrAttrib.Empty() )
344  this->SetAllowCollisions( CurrAttrib.AsBool(true) );
345 
346  CurrAttrib = PropertiesNode.GetAttribute("Enabled");
347  if( !CurrAttrib.Empty() )
348  this->EnableConstraint( CurrAttrib.AsBool(false) );
349  }else{
350  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + ( Constraint::GetSerializableName() + "Properties" ) + ": Not Version 1.");
351  }
352  }else{
353  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,Constraint::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
354  }
355  }
356 
357  void Constraint::ProtoDeSerializeGlobalOverrides(const XML::Node& SelfRoot)
358  {
359  XML::Attribute CurrAttrib;
360  XML::Node OverridesNode = SelfRoot.GetChild( Constraint::GetSerializableName() + "GlobalOverrides" );
361 
362  if( !OverridesNode.Empty() ) {
363  if( OverridesNode.GetAttribute("Version").AsInt() == 1 ) {
364  for( XML::NodeIterator OverrideNodeIt = OverridesNode.begin() ; OverrideNodeIt != OverridesNode.end() ; ++OverrideNodeIt )
365  {
366  if( (*OverrideNodeIt).GetAttribute("Version").AsInt() == 1 ) {
367  Integer Axis = -99; // Known invalid axis just about everywhere
368  Integer Param = 0; // Known invalid param
369  Real OverrideValue = 0.0;
370 
371  CurrAttrib = (*OverrideNodeIt).GetAttribute("Axis");
372  if( !CurrAttrib.Empty() )
373  Axis = CurrAttrib.AsInt();
374 
375  CurrAttrib = (*OverrideNodeIt).GetAttribute("Param");
376  if( !CurrAttrib.Empty() )
377  Param = CurrAttrib.AsUint();
378 
379  CurrAttrib = (*OverrideNodeIt).GetAttribute("Value");
380  if( !CurrAttrib.Empty() )
381  OverrideValue = CurrAttrib.AsReal();
382 
383  if( this->IsParamValidOnAxis(static_cast<ConstraintParam>(Param),Axis) ) {
384  this->SetParam(static_cast<ConstraintParam>(Param),OverrideValue,Axis);
385  }
386  }else{
387  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + String("ParamOverride") + ": Not Version 1.");
388  }
389  }
390  }else{
391  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + ( Constraint::GetSerializableName() + "GlobalOverrides" ) + ": Not Version 1.");
392  }
393  }
394  }
395 
397  { return "Constraint"; }
398 
399  ///////////////////////////////////////////////////////////////////////////////
400  // Internal Methods
401  }//Physics
402 }//Mezzanine
403 
404 std::ostream& MEZZ_LIB operator<< (std::ostream& Stream, const Mezzanine::Physics::Constraint* Con)
405 {
406  Mezzanine::Serialize(Stream,*Con);
407  return Stream;
408 }
409 
410 std::istream& MEZZ_LIB operator>> (std::istream& Stream, Mezzanine::Physics::Constraint* Con)
411 {
412  return Mezzanine::DeSerialize(Stream,*Con);
413 }
414 
416 {
417  Con->ProtoSerialize(OneNode);
418 }
419 
421 {
422  Con->ProtoDeSerialize(OneNode);
423 }
424 
425 /// @endcond
426 
427 #endif
std::ostream & operator<<(std::ostream &stream, const Mezzanine::LinearInterpolator< T > &Lint)
Used to Serialize an Mezzanine::LinearInterpolator to a human readable stream.
Definition: interpolator.h:433
Constraint(const UInt32 ID, PhysicsManager *Creator)
Zero body constructor.
virtual Boole GetAllowCollisions() const
Gets whether or not collisions can/will occur between the two constrained bodies. ...
virtual Boole IsConstraintEnabled() const
Gets whether or not this constraint is enabled.
std::vector< int > AxisList
Used to Store lists of Int Axis for return types.
Definition: constraint.h:124
ConstraintParam StringAsConstraintParam(String Param)
Convert A string that might be ConstraintParam to one.
virtual ~Constraint()
Class destructor.
CFM values adds some small value to the main diagonal on the constraint matrix to prevent degenerate ...
Definition: constraint.h:65
const int ConstraintParamCount
How many ConstraintParam Exist.
Definition: constraint.h:82
virtual ParamList GetValidParamsOnAxis(int Axis) const =0
Get a sorted (low to high) list of Parameters that are valid on this Axis.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
virtual Real GetParam(ConstraintParam Param, int Axis=-1) const
Gets value of constraint parameters.
virtual void SetActivationState(const Physics::ActivationState State, Boole Force=false)
Sets the activation state of the world object.
static String GetSerializableName()
Get the name of the the XML tag the class will leave behind as its instances are serialized.
UInt32 ConstraintID
The unique ID used to identify this constraint.
Definition: constraint.h:139
virtual void SetParam(ConstraintParam Param, Real Value, int Axis=-1)
Provides override of constraint parameters.
virtual void ProtoDeSerializeGlobalOverrides(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the global overrides of this object with it...
Thrown when the requested identity could not be found.
Definition: exception.h:94
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
std::ostream & Serialize(std::ostream &Stream, const T &Converted, const String &Indent=String(""))
Convert any class that supports serialization or has a serializer to a string of chars in a stream...
int Integer
A datatype used to represent any integer close to.
Definition: datatypes.h:154
Boole Enabled
Whether or not the constraint is currently taking effect.
Definition: constraint.h:145
virtual void SetAllowCollisions(const Boole Allow)
Sets whether collisions between the two constrained bodies should occur.
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
virtual void ProtoSerialize(XML::Node &ParentNode) const
Convert this class to an XML::Node ready for serialization.
virtual void EnableConstraint(const Boole Enable)
Enables or disables this constraint.
String ConstraintParamAsString(ConstraintParam Param)
Get a Constraint Parameter as a String.
PhysicsManager * Manager
This is a pointer to the physics manager that created and owns this constraint.
Definition: constraint.h:136
This is the base class for all constraints supported.
Definition: constraint.h:116
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
This implements the exception hiearchy for Mezzanine.
virtual Boole IsParamValidOnAxis(ConstraintParam Param, int Axis) const
Is a certain Parameter valid on a certain axis.
virtual void ProtoDeSerializeInitData(const XML::Node &SelfRoot)=0
Take the data stored in an XML Node and initializes a new internal object with it.
int char4ToAxis(char it)
used to help convert string to the axis they indicate
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
The interface for serialization.
virtual btTypedConstraint * _GetConstraintBase() const =0
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...
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
virtual RigidProxy * GetProxyB() const
Gets the second Proxy this constraint applies to.
ConstraintParam
Used by constraints for setting some parameters.
Definition: constraint.h:61
virtual void ProtoSerializeInitData(XML::Node &SelfRoot) const =0
Convert the data needed to initialize this class to an XML::Node ready for serialization.
btSoftRigidDynamicsWorld * _GetPhysicsWorldPointer()
This returns a pointer to the bullet physics world. This is for internal use only.
virtual AxisList GetValidAngularAxes() const =0
Get A list sorted (low to high) of all axis that operate Angularly (that lock sliding/translation) ...
std::istream & DeSerialize(std::istream &Stream, T &Converted)
Deserialize the next xml tag in the stream into a specific in memory class instance.
std::vector< ConstraintParam > ParamList
Used to Store lists of param for return types.
Definition: constraint.h:120
virtual AxisList GetValidLinearAxes() const =0
Get a sorted (low to high) list of all axis that operate linearly (that lock sliding/translation) ...
Thrown when parameters are checked at runtime and found invalid.
Definition: exception.h:108
RigidProxy * ProxA
The first Collidable this constraint applies to.
Definition: constraint.h:130
virtual Boole HasParamBeenSet(ConstraintParam Param, int Axis) const =0
Has the given Param on the Given Axis been set yet.
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
virtual ParamList GetValidParams() const
Get A sorted (low to high) list of Parameters that are valid on all Axis.
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
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Boole AllowCollisions
Whether or not collisions will be allowed to occure between the constrained bodies.
Definition: constraint.h:142
std::istream & operator>>(std::istream &stream, Mezzanine::LinearInterpolator< T > &Lint)
Used to de-serialize an Mezzanine::LinearInterpolator from a stream.
Definition: interpolator.h:448
virtual UInt32 GetConstraintID() const
Gets the unique ID of this constraint.
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.
virtual void ProtoSerializeGlobalOverrides(XML::Node &SelfRoot) const
Convert the global overrides of this class to an XML::Node ready for serialization.
virtual String GetDerivedSerializableName() const =0
Gets the most derived serializable name of this Constraint.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
virtual RigidProxy * GetProxyA() const
Gets the first Proxy this constraint applies to.
virtual AxisList GetValidAxes() const
Get a sorted (low to high) list of All Valid Axis.