Spinning Topp Logo BlackTopp Studios
inc
point2pointconstraint.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 _physicspoint2pointconstraint_cpp
41 #define _physicspoint2pointconstraint_cpp
42 
43 #include "Physics/point2pointconstraint.h"
44 #include "Physics/physicsmanager.h"
45 #include "Physics/rigidproxy.h"
46 
47 #include "stringtool.h"
48 #include "serialization.h"
49 
50 #include <btBulletDynamicsCommon.h>
51 
52 namespace Mezzanine
53 {
54  namespace Physics
55  {
56  ////////////////////////////////////////////////////////////////////////////////
57  // Point2PointConstraint Methods
58 
59  Point2PointConstraint::Point2PointConstraint(const UInt32 ID, RigidProxy* ProxyA, RigidProxy* ProxyB, const Vector3& PivotA, const Vector3& PivotB, PhysicsManager* Creator) :
60  Constraint(ID,ProxyA,ProxyB,Creator),
61  Point2Point(NULL)
62  { this->CreateConstraint(ProxyA,ProxyB,PivotA,PivotB); }
63 
65  Constraint(ID,ProxyA,Creator),
66  Point2Point(NULL)
67  { this->CreateConstraint(ProxyA,NULL,PivotA,Vector3()); }
68 
70  Constraint(0,NULL,Creator),
71  Point2Point(NULL)
72  { this->ProtoDeSerialize(SelfRoot); }
73 
75  { this->DestroyConstraint(); }
76 
77  void Point2PointConstraint::CreateConstraint(RigidProxy* RigidA, RigidProxy* RigidB, const Vector3& PivotA, const Vector3& PivotB)
78  {
79  if( this->Point2Point == NULL ) {
80  if( RigidA && RigidB ) {
81  this->Point2Point = new btPoint2PointConstraint(*(RigidA->_GetPhysicsObject()),*(RigidB->_GetPhysicsObject()),PivotA.GetBulletVector3(),PivotB.GetBulletVector3());
82  }else if( RigidA ) {
83  this->Point2Point = new btPoint2PointConstraint(*(RigidA->_GetPhysicsObject()),PivotA.GetBulletVector3());
84  }
85  }
86  }
87 
89  {
90  this->EnableConstraint(false);
91  if( this->Point2Point != NULL ) {
92  delete this->Point2Point;
93  this->Point2Point = NULL;
94  }
95  this->ProxA = NULL;
96  this->ProxB = NULL;
97  }
98 
99  ////////////////////////////////////////////////////////////////////////////////
100  // Position and Orientation
101 
103  { this->Point2Point->setPivotA(PivotA.GetBulletVector3()); }
104 
106  { this->Point2Point->setPivotB(PivotB.GetBulletVector3()); }
107 
109  { return Vector3(this->Point2Point->getPivotInA()); }
110 
112  { return Vector3(this->Point2Point->getPivotInB()); }
113 
114  ////////////////////////////////////////////////////////////////////////////////
115  // Specific Physics Settings
116 
118  { this->Point2Point->m_setting.m_impulseClamp = Clamping; }
119 
121  { return this->Point2Point->m_setting.m_impulseClamp; }
122 
124  { this->Point2Point->m_setting.m_damping = Damping; }
125 
127  { return this->Point2Point->m_setting.m_damping; }
128 
130  { this->Point2Point->m_setting.m_tau = TAU; }
131 
133  { return this->Point2Point->m_setting.m_tau; }
134 
135  ///////////////////////////////////////////////////////////////////////////////
136  // Parameter Configuration
137 
139  {
140  Constraint::ParamList Results;
141  if( -1 == Axis ) {
142  Results.push_back(Con_ERP);
143  Results.push_back(Con_Stop_ERP);
144  Results.push_back(Con_CFM);
145  Results.push_back(Con_Stop_CFM);
146  }
147  return Results;
148  }
149 
151  {
152  Constraint::AxisList Results;
153  Results.push_back(-1);
154  return Results;
155  }
156 
158  {
159  Constraint::AxisList Results;
160  return Results;
161  }
162 
164  {
165  //return this->Point2Point->hasParamBeenSet(Param,Axis);
166  // the logic here should match the logic in the source at http://bulletphysics.com/Bullet/BulletFull/btPoint2PointConstraint_8cpp_source.html#l00202
167  if( -1 != Axis ) {
168  return false;
169  }
170 
171  return ( ( Con_ERP == Param || Con_Stop_ERP == Param ) && this->Point2Point->getFlags() & BT_P2P_FLAGS_ERP ) || //If we are checking erp OR we are checking stoperp AND the erp Flag is set OR
172  ( ( Con_CFM == Param || Con_Stop_CFM == Param ) && this->Point2Point->getFlags() & BT_P2P_FLAGS_CFM ); // we are checking cfm OR we are checking stopcfm AND the cfm Flag is set
173  }
174 
175  ///////////////////////////////////////////////////////////////////////////////
176  // Serialization
177 
179  {
180  XML::Node InitDataNode = SelfRoot.AppendChild( Point2PointConstraint::GetSerializableName() + "InitData" );
181 
182  if( InitDataNode.AppendAttribute("Version").SetValue("1") &&
183  ( this->ProxA != NULL ? InitDataNode.AppendAttribute("ProxyA-ID").SetValue( this->ProxA->GetProxyID() ) : false ) &&
184  ( this->ProxB != NULL ? InitDataNode.AppendAttribute("ProxyB-ID").SetValue( this->ProxB->GetProxyID() ) : false ) )
185  {
186  if( this->ProxA != NULL ) {
187  XML::Node PivotANode = InitDataNode.AppendChild("PivotA");
188  this->GetPivotA().ProtoSerialize( PivotANode );
189  }
190  if( this->ProxB != NULL ) {
191  XML::Node PivotBNode = InitDataNode.AppendChild("PivotB");
192  this->GetPivotB().ProtoSerialize( PivotBNode );
193  }
194 
195  return;
196  }else{
197  SerializeError("Create XML Attribute Values",Point2PointConstraint::GetSerializableName() + "InitData",true);
198  }
199  }
200 
202  {
203  this->Constraint::ProtoSerializeProperties(SelfRoot);
204 
205  XML::Node PropertiesNode = SelfRoot.AppendChild( Point2PointConstraint::GetSerializableName() + "Properties" );
206 
207  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
208  PropertiesNode.AppendAttribute("ImpulseClamping").SetValue( this->GetImpulseClamping() ) &&
209  PropertiesNode.AppendAttribute("Damping").SetValue( this->GetDamping() ) &&
210  PropertiesNode.AppendAttribute("TAU").SetValue( this->GetTAU() ) )
211  {
212  return;
213  }else{
214  SerializeError("Create XML Attribute Values",Point2PointConstraint::GetSerializableName() + "Properties",true);
215  }
216  }
217 
219  {
220  this->DestroyConstraint();
221 
222  XML::Attribute CurrAttrib;
223  XML::Node InitDataNode = SelfRoot.GetChild( Point2PointConstraint::GetSerializableName() + "InitData" );
224 
225  if( !InitDataNode.Empty() ) {
226  if(InitDataNode.GetAttribute("Version").AsInt() == 1) {
227  Vector3 PivotA;
228  Vector3 PivotB;
229 
230  CurrAttrib = InitDataNode.GetAttribute("ProxyA-ID");
231  if( !CurrAttrib.Empty() )
232  this->ProxA = static_cast<RigidProxy*>( this->Manager->GetProxyByID( CurrAttrib.AsUint() ) );
233 
234  CurrAttrib = InitDataNode.GetAttribute("ProxyB-ID");
235  if( !CurrAttrib.Empty() )
236  this->ProxB = static_cast<RigidProxy*>( this->Manager->GetProxyByID( CurrAttrib.AsUint() ) );
237 
238  XML::Node PivotANode = InitDataNode.GetChild("PivotA").GetFirstChild();
239  if( !PivotANode.Empty() ) {
240  PivotA.ProtoDeSerialize(PivotANode);
241  }
242 
243  XML::Node PivotBNode = InitDataNode.GetChild("PivotB").GetFirstChild();
244  if( !PivotBNode.Empty() ) {
245  PivotB.ProtoDeSerialize(PivotBNode);
246  }
247 
248  this->CreateConstraint(this->ProxA,this->ProxB,PivotA,PivotB);
249  }else{
250  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + ( Point2PointConstraint::GetSerializableName() + "InitData" ) + ": Not Version 1.");
251  }
252  }else{
253  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,Point2PointConstraint::GetSerializableName() + "InitData" + " was not found in the provided XML node, which was expected.");
254  }
255  }
256 
258  {
260 
261  XML::Attribute CurrAttrib;
262  XML::Node PropertiesNode = SelfRoot.GetChild( Point2PointConstraint::GetSerializableName() + "Properties" );
263 
264  if( !PropertiesNode.Empty() ) {
265  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
266  CurrAttrib = PropertiesNode.GetAttribute("ImpulseClamping");
267  if( !CurrAttrib.Empty() )
268  this->SetImpulseClamping( CurrAttrib.AsReal() );
269 
270  CurrAttrib = PropertiesNode.GetAttribute("Damping");
271  if( !CurrAttrib.Empty() )
272  this->SetDamping( CurrAttrib.AsReal() );
273 
274  CurrAttrib = PropertiesNode.GetAttribute("TAU");
275  if( !CurrAttrib.Empty() )
276  this->SetTAU( CurrAttrib.AsReal() );
277  }else{
278  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + ( Point2PointConstraint::GetSerializableName() + "Properties" ) + ": Not Version 1.");
279  }
280  }else{
281  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,Point2PointConstraint::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
282  }
283  }
284 
287 
289  { return "Point2PointConstraint"; }
290 
291  ////////////////////////////////////////////////////////////////////////////////
292  // Internal
293 
294  btTypedConstraint* Point2PointConstraint::_GetConstraintBase() const
295  { return this->Point2Point; }
296  }//Physics
297 }//Mezzanine
298 
299 
300 ///////////////////////////////////////////////////////////////////////////////
301 // Class External << Operators for streaming or assignment
302 
303 std::ostream& operator << (std::ostream& stream, const Mezzanine::Physics::Point2PointConstraint& x)
304 {
305  Mezzanine::Serialize(stream,x);
306  return stream;
307 }
308 
309 std::istream& operator >> (std::istream& stream, Mezzanine::Physics::Point2PointConstraint& x)
310  { return Mezzanine::DeSerialize(stream, x); }
311 
313  { x.ProtoDeSerialize(OneNode); }
314 
315 #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
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
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
virtual Constraint::AxisList GetValidLinearAxes() const
Get a sorted (low to high) list of all axis that operate linearly (that lock sliding/translation) ...
virtual void SetTAU(const Real TAU)
This may be a scalar for how strongly Angular momentum affects linear momemtum.
virtual Constraint::AxisList GetValidAngularAxes() const
Get A list sorted (low to high) of all axis that operate Angularly (that lock sliding/translation) ...
virtual Boole HasParamBeenSet(ConstraintParam Param, int Axis) const
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
static String GetSerializableName()
Get the name of the the XML tag the class will leave behind as its instances are serialized.
virtual void ProtoDeSerializeInitData(const XML::Node &SelfRoot)
Take the data stored in an XML Node and initializes a new internal object with it.
virtual UInt32 GetProxyID() const
Gets the unique ID of this proxy.
Definition: worldproxy.cpp:78
Thrown when the requested identity could not be found.
Definition: exception.h:94
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
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...
virtual void SetPivotA(const Vector3 &PivotA)
Set offset of the first proxy.
virtual Vector3 GetPivotB() const
Get offset of the second proxy.
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
CollidableProxy * GetProxyByID(const UInt32 ID) const
Gets the CollidableProxy via its ID.
virtual void SetPivotB(const Vector3 &PivotB)
Set offset of the second proxy.
virtual void EnableConstraint(const Boole Enable)
Enables or disables this constraint.
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.
bool Empty() const
Is this storing anything at all?
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
virtual Real GetTAU() const
Retrieve the Tau Setting.
virtual Real GetDamping() const
Get the current Damping.
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
The interface for serialization.
Tries to make a point relative to each of two actors match in 3d space, without regard to rotation...
bool SetValue(const Char8 *rhs)
Set the value of this.
virtual void SetImpulseClamping(const Real Clamping)
Set the current impulse clamping on the constraint.
virtual void CreateConstraint(RigidProxy *RigidA, RigidProxy *RigidB, const Vector3 &PivotA, const Vector3 &PivotB)
Creates the internal constraint.
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
btVector3 GetBulletVector3() const
Gets a Bullet vector3.
Definition: vector3.cpp:555
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
unsigned int AsUint(unsigned int def=0) const
Attempts to convert the value of the attribute to an unsigned int and returns the results...
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
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 DestroyConstraint()
Destroys the internal constraint.
virtual btRigidBody * _GetPhysicsObject() const
Accessor for the internal rigid body physics proxy.
Definition: rigidproxy.cpp:406
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 Real GetImpulseClamping() const
get the current impulse clamping value.
virtual void SetDamping(const Real Damping)
Set a resistive force against the constraint, not too dissimilar to from hinge friction or Air resist...
std::istream & DeSerialize(std::istream &Stream, T &Converted)
Deserialize the next xml tag in the stream into a specific in memory class instance.
virtual btTypedConstraint * _GetConstraintBase() const
Get the Bullet constraint that this class encapsulates.
This is a proxy from which rigid body proxys are handled.
Definition: rigidproxy.h:102
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
btPoint2PointConstraint * Point2Point
The internal constraint that this class encapsulates.
virtual Vector3 GetPivotA() const
Get offset of the first proxy.
void ProtoDeSerialize(const XML::Node &OneNode)
Take the data stored in an XML and overwrite this instance of this object with it.
Definition: vector3.cpp:614
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
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
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 void ProtoSerializeInitData(XML::Node &SelfRoot) const
Convert the data needed to initialize this class to an XML::Node ready for serialization.
Point2PointConstraint(const UInt32 ID, RigidProxy *ProxyA, RigidProxy *ProxyB, const Vector3 &PivotA, const Vector3 &PivotB, PhysicsManager *Creator)
Double body constructor. Binds the two bodies.
virtual ~Point2PointConstraint()
Class destructor.
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 String GetDerivedSerializableName() const
Gets the most derived serializable name of this Constraint.
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 Constraint::ParamList GetValidParamsOnAxis(int Axis) const
Get a sorted (low to high) list of Parameters that are valid on this Axis.
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
Definition: vector3.cpp:588
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.