MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
generic6dofconstraint.cpp
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 _physicsgeneric6dofconstraint_cpp
41 #define _physicsgeneric6dofconstraint_cpp
42 
43 #include "Physics/generic6dofconstraint.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  // Generic6Dof Constraint Functions
57 
59  { }
60 
61  btTypedConstraint* Generic6DofConstraint::GetConstraintBase() const
62  { return this->Generic6dof; }
63 
64  ////////////////////////////////////////////////////////////////////////////////
65  // Generic6DofConstraint Construction and Destruction
66 
68  const Vector3& VectorB, const Quaternion& QuaternionA, const Quaternion& QuaternionB, bool UseLinearReferenceA)
69  {
70  this->SetBodies(ProxyA,ProxyB);
71  Transform TransformA(VectorA, QuaternionA);
72  Transform TransformB(VectorB, QuaternionB);
73  this->Generic6dof = new btGeneric6DofConstraint(*(ProxA->_GetPhysicsObject()), *(ProxB->_GetPhysicsObject()), TransformA.GetBulletTransform(), TransformB.GetBulletTransform(), UseLinearReferenceA);
74  }
75 
76  Generic6DofConstraint::Generic6DofConstraint(RigidProxy* ProxyA, RigidProxy* ProxyB, const Transform& TransformA, const Transform& TransformB, bool UseLinearReferenceA)
77  {
78  this->SetBodies(ProxyA,ProxyB);
79  this->Generic6dof = new btGeneric6DofConstraint(*(ProxA->_GetPhysicsObject()), *(ProxB->_GetPhysicsObject()), TransformA.GetBulletTransform(), TransformB.GetBulletTransform(), UseLinearReferenceA);
80  }
81 
82  Generic6DofConstraint::Generic6DofConstraint(RigidProxy* ProxyB, const Vector3& VectorB, const Quaternion& QuaternionB, bool UseLinearReferenceB)
83  {
84  this->SetBodies(ProxyB);
85 
86  btTransform transa(QuaternionB.GetBulletQuaternion(), VectorB.GetBulletVector3());
87  this->Generic6dof = new btGeneric6DofConstraint(*(ProxA->_GetPhysicsObject()), transa, UseLinearReferenceB);
88  }
89 
90  Generic6DofConstraint::Generic6DofConstraint(RigidProxy* ProxyB, const Transform& TransformB, bool UseLinearReferenceB)
91  {
92  this->SetBodies(ProxyB);
93 
94  this->Generic6dof = new btGeneric6DofConstraint(*(ProxA->_GetPhysicsObject()), TransformB.GetBulletTransform(), UseLinearReferenceB);
95  }
96 
98  {
99  if(this->Generic6dof)
100  delete this->Generic6dof;
101  }
102 
103  ////////////////////////////////////////////////////////////////////////////////
104  // Generic6DofConstraint Location and Rotation
105 
107  { this->Generic6dof->getFrameOffsetA() = TranA.GetBulletTransform(); }
108 
110  { this->Generic6dof->getFrameOffsetB() = TranB.GetBulletTransform(); }
111 
113  { return this->Generic6dof->getFrameOffsetA(); }
114 
116  { return this->Generic6dof->getFrameOffsetB(); }
117 
118 
120  { this->Generic6dof->getFrameOffsetA().setOrigin(Location.GetBulletVector3()); }
121 
123  { this->Generic6dof->getFrameOffsetB().setOrigin(Location.GetBulletVector3()); }
124 
126  { return Vector3(this->Generic6dof->getFrameOffsetA().getOrigin()); }
127 
129  { return Vector3(this->Generic6dof->getFrameOffsetB().getOrigin()); }
130 
131 
133  { this->Generic6dof->getFrameOffsetA().setRotation(Rotation.GetBulletQuaternion()); }
134 
136  { this->Generic6dof->getFrameOffsetA().setRotation(Rotation.GetBulletQuaternion()); }
137 
139  { return Quaternion(this->Generic6dof->getFrameOffsetA().getRotation()); }
140 
142  { return Quaternion(this->Generic6dof->getFrameOffsetB().getRotation()); }
143 
144  ////////////////////////////////////////////////////////////////////////////////
145  // Generic6DofConstraint Basic Limit Accessors
146 
147  void Generic6DofConstraint::SetLimit(int Axis, Real Lower, Real Upper)
148  { this->Generic6dof->setLimit(Axis, Lower, Upper); }
149 
151  { this->Generic6dof->setLinearUpperLimit(Limit.GetBulletVector3()); }
152 
154  { this->Generic6dof->setLinearLowerLimit(Limit.GetBulletVector3()); }
155 
157  { return Vector3(this->Generic6dof->getTranslationalLimitMotor()->m_upperLimit); }
158 
160  { return Vector3(this->Generic6dof->getTranslationalLimitMotor()->m_lowerLimit); }
161 
163  { this->Generic6dof->setAngularUpperLimit(Limit.GetBulletVector3()); }
164 
166  { this->Generic6dof->setAngularLowerLimit(Limit.GetBulletVector3()); }
167 
170 
173 
175  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(RotationalAxis))->m_loLimit; }
176 
178  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(RotationalAxis))->m_hiLimit; }
179 
180  ////////////////////////////////////////////////////////////////////////////////
181  // Generic6DofConstraint Angular Limit and Motor Details
182 
185 
187  { this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_maxLimitForce = MaxLimitForce; }
188 
191 
193  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_maxLimitForce; }
194 
195 
198 
200  { this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_targetVelocity = Velocity; }
201 
204 
206  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_targetVelocity; }
207 
208 
211 
213  { this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_maxMotorForce = Force; }
214 
217 
219  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_maxMotorForce; }
220 
221 
224 
226  { this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_damping = Damping; }
227 
230 
232  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_damping; }
233 
234 
237 
239  { this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_bounce = Restistution; }
240 
243 
245  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_bounce; }
246 
247 
250 
252  { this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_enableMotor = Enabled; }
253 
256 
258  { return this->Generic6dof->getRotationalLimitMotor(AxisToAngularAxis(Axis))->m_enableMotor; }
259 
260  ////////////////////////////////////////////////////////////////////////////////
261  // Generic6DofConstraint Linear Limit and Motor Details
262 
264  { this->Generic6dof->getTranslationalLimitMotor()->m_limitSoftness = Softness; }
265 
267  { return this->Generic6dof->getTranslationalLimitMotor()->m_limitSoftness; }
268 
270  { this->Generic6dof->getTranslationalLimitMotor()->m_damping = Damping; }
271 
273  { return this->Generic6dof->getTranslationalLimitMotor()->m_damping; }
274 
276  { this->Generic6dof->getTranslationalLimitMotor()->m_restitution = Restitution; }
277 
279  { return this->Generic6dof->getTranslationalLimitMotor()->m_restitution; }
280 
281 
284 
286  { this->Generic6dof->getTranslationalLimitMotor()->m_maxMotorForce[Axis] = Force; }
287 
290 
292  { return this->Generic6dof->getTranslationalLimitMotor()->m_maxMotorForce[Axis]; }
293 
296 
298  { this->Generic6dof->getTranslationalLimitMotor()->m_targetVelocity[Axis] = Velocity; }
299 
302 
304  { return this->Generic6dof->getTranslationalLimitMotor()->m_targetVelocity[Axis]; }
305 
306 
308  { this->SetLinearMotorEnabledOnAxis(Enableds.X,LinearX); this->SetLinearMotorEnabledOnAxis(Enableds.Y,LinearY); this->SetLinearMotorEnabledOnAxis(Enableds.Z,LinearZ); }
309 
311  { this->Generic6dof->getTranslationalLimitMotor()->m_enableMotor[Axis] = Enabled; }
312 
315 
317  { return this->Generic6dof->getTranslationalLimitMotor()->m_enableMotor[Axis]; }
318 
319 
320 
321  ////////////////////////////////////////////////////////////////////////////////
322  // Generic6DofConstraint Axis, Params and other Details
323 
325  {
326  Constraint::ParamList Results;
327  if(0<=Axis && 5>=Axis)
328  {
329  Results.push_back(Con_Stop_ERP);
330  Results.push_back(Con_CFM);
331  Results.push_back(Con_Stop_CFM);
332  }
333  return Results;
334  }
335 
337  {
338  Constraint::AxisList Results;
339  Results.push_back(0);
340  Results.push_back(1);
341  Results.push_back(2);
342  return Results;
343  }
344 
346  {
347  Constraint::AxisList Results;
348  Results.push_back(3);
349  Results.push_back(4);
350  Results.push_back(5);
351  return Results;
352  }
353 
355  {
356  // the logic here should match the logic in the source at http://bulletphysics.com/Bullet/BulletFull/btGeneric6DofConstraint_8cpp_source.html#l00964
357  if(0>Axis || 5<Axis)
358  { return false; }
359  return ( Con_Stop_ERP==Param && this->Generic6dof->getFlags() & (BT_6DOF_FLAGS_ERP_STOP << (Axis * BT_6DOF_FLAGS_AXIS_SHIFT)) ) || //if we are checking the stop_erp AND the stop_erp bit is set for the correct axis
360  ( Con_Stop_CFM==Param && this->Generic6dof->getFlags() & (BT_6DOF_FLAGS_CFM_STOP << (Axis * BT_6DOF_FLAGS_AXIS_SHIFT)) ) || //if we are checking the stop_cfm AND the stop_cfm bit is set
361  ( Con_CFM==Param && this->Generic6dof->getFlags() & (BT_6DOF_FLAGS_CFM_NORM << (Axis * BT_6DOF_FLAGS_AXIS_SHIFT)) ) ; //if we are checking the cfm AND the cfm bit is set
362  }
363 
365  { return this->Generic6dof->getUseFrameOffset(); }
366 
368  { this->Generic6dof->setUseFrameOffset(FrameOffset); }
369 
370  ///////////////////////////////////////////////////////////////////////////////
371  // Generic6DofConstraint Serialization
372 
374  {
375 
376  XML::Node G6dofNode = CurrentRoot.AppendChild(this->Generic6DofConstraint::SerializableName()); // The base node all the base constraint stuff will go in
377  if (!G6dofNode)
378  { SerializeError("Create G6dofNode", SerializableName()); }
379 
380 
381  XML::Node LinLimUpp = G6dofNode.AppendChild("LinearLimitUpper"); // Basic Limit Stuff
382  if (!LinLimUpp)
383  { SerializeError("Create LinLimUpp", SerializableName()); }
384  this->GetLinearLimitUpper().ProtoSerialize(LinLimUpp);
385 
386  XML::Node LinLimLow = G6dofNode.AppendChild("LinearLimitLower");
387  if (!LinLimLow)
388  { SerializeError("Create LinLimLow", SerializableName()); }
389  this->GetLinearLimitLower().ProtoSerialize(LinLimLow);
390 
391  XML::Node AngLimUpp = G6dofNode.AppendChild("AngularLimitUpper");
392  if (!AngLimUpp)
393  { SerializeError("Create AngLimUpp", SerializableName()); }
394  this->GetAngularLimitUpper().ProtoSerialize(AngLimUpp);
395 
396  XML::Node AngLimLow = G6dofNode.AppendChild("AngularLimitLower");
397  if (!AngLimLow)
398  { SerializeError("Create AngLimLow", SerializableName()); }
399  this->GetAngularLimitLower().ProtoSerialize(AngLimLow);
400 
401 
402  XML::Node AngularLimitMaxForce = G6dofNode.AppendChild("AngularLimitMaxForce"); // Angular Limit and Motor Details
403  if (!AngularLimitMaxForce)
404  { SerializeError("Create AngularLimitMaxForce", SerializableName()); }
405  this->GetAngularLimitMaxForce().ProtoSerialize(AngularLimitMaxForce);
406 
407  XML::Node AngularMotorTargetVelocity = G6dofNode.AppendChild("AngularMotorTargetVelocity");
408  if (!AngularMotorTargetVelocity)
409  { SerializeError("Create AngularMotorTargetVelocity", SerializableName()); }
410  this->GetAngularMotorTargetVelocity().ProtoSerialize(AngularMotorTargetVelocity);
411 
412  XML::Node AngularMotorMaxForce = G6dofNode.AppendChild("AngularMotorMaxForce");
413  if (!AngularMotorMaxForce)
414  { SerializeError("Create AngularMotorMaxForce", SerializableName()); }
415  this->GetAngularMotorMaxForce().ProtoSerialize(AngularMotorMaxForce);
416 
417  XML::Node AngularMotorDamping = G6dofNode.AppendChild("AngularMotorDamping");
418  if (!AngularMotorDamping)
419  { SerializeError("Create AngularMotorDamping", SerializableName()); }
420  this->GetAngularMotorDamping().ProtoSerialize(AngularMotorDamping);
421 
422  XML::Node AngularMotorRestitution = G6dofNode.AppendChild("AngularMotorRestitution");
423  if (!AngularMotorRestitution)
424  { SerializeError("Create AngularMotorRestitution", SerializableName()); }
425  this->GetAngularMotorRestitution().ProtoSerialize(AngularMotorRestitution);
426 
427  XML::Node AngularMotorEnabled = G6dofNode.AppendChild("AngularMotorEnabled");
428  if (!AngularMotorEnabled)
429  { SerializeError("Create AngularMotorEnabled", SerializableName()); }
430  this->GetAngularMotorEnabled().ProtoSerialize(AngularMotorEnabled);
431 
432 
433  XML::Node LinearMotorMaxForce = G6dofNode.AppendChild("LinearMotorMaxForce"); // Linear limit and motor details
434  if (!LinearMotorMaxForce)
435  { SerializeError("Create LinearMotorMaxForce", SerializableName()); }
436  this->GetLinearMotorMaxForce().ProtoSerialize(LinearMotorMaxForce);
437 
438  XML::Node LinearMotorTargetVelocity = G6dofNode.AppendChild("LinearMotorTargetVelocity");
439  if (!LinearMotorTargetVelocity)
440  { SerializeError("Create LinearMotorTargetVelocity", SerializableName()); }
441  this->GetLinearMotorTargetVelocity().ProtoSerialize(LinearMotorTargetVelocity);
442 
443  XML::Node LinearMotorEnabled = G6dofNode.AppendChild("LinearMotorEnabled");
444  if (!LinearMotorEnabled)
445  { SerializeError("Create LinearMotorEnabled", SerializableName()); }
446  this->GetLinearMotorEnabled().ProtoSerialize(LinearMotorEnabled);
447 
448  Mezzanine::XML::Attribute Version = G6dofNode.AppendAttribute("Version"); // Version
449  if (!Version)
450  { SerializeError("Create Version", SerializableName()); }
451  Version.SetValue(1);
452 
453  Mezzanine::XML::Attribute LinearLimitSoftness = G6dofNode.AppendAttribute("LinearLimitSoftness"); // Linear Attributes.
454  if (!LinearLimitSoftness)
455  { SerializeError("Create LinearLimitSoftness", SerializableName()); }
456  LinearLimitSoftness.SetValue(this->GetLinearLimitSoftness());
457 
458  Mezzanine::XML::Attribute LinearLimitDamping = G6dofNode.AppendAttribute("LinearLimitDamping");
459  if (!LinearLimitDamping)
460  { SerializeError("Create LinearLimitDamping", SerializableName()); }
461  LinearLimitDamping.SetValue(this->GetLinearLimitDamping());
462 
463  Mezzanine::XML::Attribute LinearLimitRestitution = G6dofNode.AppendAttribute("LinearLimitRestitution");
464  if (!LinearLimitRestitution)
465  { SerializeError("Create LinearLimitRestitution", SerializableName()); }
466  LinearLimitRestitution.SetValue(this->GetLinearLimitRestitution());
467 
469  }
470 
472  {
474  {
475  if(OneNode.GetAttribute("Version").AsInt() == 1)
476  {
477  XML::Node DualTranny = OneNode.GetChild("DualTransformConstraint");
478  if(!DualTranny)
479  { DeSerializeError("locate DualTransforn node",SerializableName()); }
481 
482  this->SetLinearLimitSoftness(OneNode.GetAttribute("LinearLimitSoftness").AsReal());
483  this->SetLinearLimitDamping(OneNode.GetAttribute("LinearLimitDamping").AsReal());
484  this->SetLinearLimitRestitution(OneNode.GetAttribute("LinearLimitRestitution").AsReal());
485 
486  Vector3 vec;
487 
488  XML::Node LinearLimitUpper = OneNode.GetChild("LinearLimitUpper");
489  if(!LinearLimitUpper || !LinearLimitUpper.GetFirstChild())
490  { DeSerializeError("locate LinearLimitUpper node",SerializableName()); }
491  vec.ProtoDeSerialize(LinearLimitUpper.GetFirstChild());
492  this->SetLinearLimitUpper(vec);
493 
494  XML::Node LinearLimitLower = OneNode.GetChild("LinearLimitLower");
495  if(!LinearLimitLower || !LinearLimitLower.GetFirstChild())
496  { DeSerializeError("locate LinearLimitLower node",SerializableName()); }
497  vec.ProtoDeSerialize(LinearLimitLower.GetFirstChild());
498  this->SetLinearLimitLower(vec);
499 
500  XML::Node AngularLimitUpper = OneNode.GetChild("AngularLimitUpper");
501  if(!AngularLimitUpper || !AngularLimitUpper.GetFirstChild())
502  { DeSerializeError("locate AngularLimitUpper node",SerializableName()); }
503  vec.ProtoDeSerialize(AngularLimitUpper.GetFirstChild());
504  this->SetAngularLimitUpper(vec);
505 
506  XML::Node AngularLimitLower = OneNode.GetChild("AngularLimitLower");
507  if(!AngularLimitLower || !AngularLimitLower.GetFirstChild())
508  { DeSerializeError("locate AngularLimitLower node",SerializableName()); }
509  vec.ProtoDeSerialize(AngularLimitLower.GetFirstChild());
510  this->SetAngularLimitLower(vec);
511 
512  XML::Node AngularLimitMaxForce = OneNode.GetChild("AngularLimitMaxForce");
513  if(!AngularLimitMaxForce || !AngularLimitMaxForce.GetFirstChild())
514  { DeSerializeError("locate AngularLimitMaxForce node",SerializableName()); }
515  vec.ProtoDeSerialize(AngularLimitMaxForce.GetFirstChild());
516  this->SetAngularLimitMaxForce(vec);
517 
518  XML::Node AngularMotorTargetVelocity = OneNode.GetChild("AngularMotorTargetVelocity");
519  if(!AngularMotorTargetVelocity || !AngularMotorTargetVelocity.GetFirstChild())
520  { DeSerializeError("locate AngularMotorTargetVelocity node",SerializableName()); }
521  vec.ProtoDeSerialize(AngularMotorTargetVelocity.GetFirstChild());
523 
524  XML::Node AngularMotorMaxForce = OneNode.GetChild("AngularMotorMaxForce");
525  if(!AngularMotorMaxForce || !AngularMotorMaxForce.GetFirstChild())
526  { DeSerializeError("locate AngularMotorMaxForce node",SerializableName()); }
527  vec.ProtoDeSerialize(AngularMotorMaxForce.GetFirstChild());
528  this->SetAngularMotorMaxForce(vec);
529 
530  XML::Node AngularMotorDamping = OneNode.GetChild("AngularMotorDamping");
531  if(!AngularMotorDamping || !AngularMotorDamping.GetFirstChild())
532  { DeSerializeError("locate AngularMotorDamping node",SerializableName()); }
533  vec.ProtoDeSerialize(AngularMotorDamping.GetFirstChild());
534  this->SetAngularMotorDamping(vec);
535 
536  XML::Node AngularMotorRestitution = OneNode.GetChild("AngularMotorRestitution");
537  if(!AngularMotorRestitution || !AngularMotorRestitution.GetFirstChild())
538  { DeSerializeError("locate AngularMotorRestitution node",SerializableName()); }
539  vec.ProtoDeSerialize(AngularMotorRestitution.GetFirstChild());
540  this->SetAngularMotorRestitution(vec);
541 
542  XML::Node AngularMotorEnabled = OneNode.GetChild("AngularMotorEnabled");
543  if(!AngularMotorEnabled || !AngularMotorEnabled.GetFirstChild())
544  { DeSerializeError("locate AngularMotorEnabled node",SerializableName()); }
545  vec.ProtoDeSerialize(AngularMotorEnabled.GetFirstChild());
546  this->SetAngularMotorEnabled(vec);
547 
548  XML::Node LinearMotorMaxForce = OneNode.GetChild("LinearMotorMaxForce");
549  if(!LinearMotorMaxForce || !LinearMotorMaxForce.GetFirstChild())
550  { DeSerializeError("locate LinearMotorMaxForce node",SerializableName()); }
551  vec.ProtoDeSerialize(LinearMotorMaxForce.GetFirstChild());
552  this->SetLinearMotorMaxForce(vec);
553 
554  XML::Node LinearMotorTargetVelocity = OneNode.GetChild("LinearMotorTargetVelocity");
555  if(!LinearMotorTargetVelocity || !LinearMotorTargetVelocity.GetFirstChild())
556  { DeSerializeError("locate LinearMotorTargetVelocity node",SerializableName()); }
557  vec.ProtoDeSerialize(LinearMotorTargetVelocity.GetFirstChild());
558  this->SetLinearMotorTargetVelocity(vec);
559 
560  XML::Node LinearMotorEnabled = OneNode.GetChild("LinearMotorEnabled");
561  if(!LinearMotorEnabled || !LinearMotorEnabled.GetFirstChild())
562  { DeSerializeError("locate LinearMotorEnabled node",SerializableName()); }
563  vec.ProtoDeSerialize(LinearMotorEnabled.GetFirstChild());
564  this->SetLinearMotorEnabled(vec);
565  }else{
566  DeSerializeError("find usable serialization version",SerializableName());
567  }
568  }else{
569  DeSerializeError(String("find correct class to deserialize, found a ")+OneNode.Name(),SerializableName());
570  }
571  }
572 
574  { return String("Generic6DofConstraint"); }
575  }//Physics
576 }//Mezzanine
577 
578 ///////////////////////////////////////////////////////////////////////////////
579 // Class External << Operators for streaming or assignment
580 
581 std::ostream& operator << (std::ostream& stream, const Mezzanine::Physics::Generic6DofConstraint& x)
582 {
583  Mezzanine::Serialize(stream,x);
584  return stream;
585 }
586 
587 std::istream& operator >> (std::istream& stream, Mezzanine::Physics::Generic6DofConstraint& x)
588  { return Mezzanine::DeSerialize(stream, x); }
589 
590 void operator >> (const Mezzanine::XML::Node& OneNode, Mezzanine::Physics::Generic6DofConstraint& x)
591  { x.ProtoDeSerialize(OneNode); }
592 
593 #endif