MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
constraint.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 _physicsconstraint_cpp
41 #define _physicsconstraint_cpp
42 
43 #include "Physics/constraint.h"
44 #include "Physics/physicsenumerations.h"
45 #include "Physics/rigidproxy.h"
46 
47 #include "actormanager.h"
48 #include "entresol.h"
49 
50 #include "stringtool.h"
51 #include "serialization.h"
52 
53 #include <btBulletDynamicsCommon.h>
54 
55 /// @cond DontDocumentInternal
56 
57 namespace Mezzanine
58 {
59  namespace Physics
60  {
61  /////////////////////////////////////////
62  // Functions
63 
65  {
66  switch (Param)
67  {
68  case Con_ERP: return String("Con_ERP");
69  case Con_Stop_ERP: return String("Con_Stop_ERP");
70  case Con_CFM: return String("Con_CFM");
71  case Con_Stop_CFM: return String("Con_Stop_CFM");
72  default: { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid Constraint Paramater to a String."); }
73  }
74  }
75 
77  {
78  if(5>Param.size())
79  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Too Short."); }
80 
81  switch(Param.at(4))
82  {
83  case 'E':
85  { return Con_ERP; }
86  else
87  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_ERP but isn't."); }
88  case 'C':
90  { return Con_CFM; }
91  else
92  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_CFM but isn't."); }
93  case 'S':
94  switch(Param.at(9))
95  {
96  case 'E':
97  if(ConstraintParamAsString(Con_Stop_ERP)==Param)
98  { return Con_Stop_ERP; }
99  else
100  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_Stop_ERP but isn't."); }
101  case 'C':
102  if(ConstraintParamAsString(Con_Stop_CFM)==Param)
103  { return Con_Stop_CFM; }
104  else
105  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appears to be Con_Stop_CFM but isn't."); }
106  case 'S':
107 
108  default:
109  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Appeared to be Con_Stop_Something, but wasn't."); }
110  }
111  default:
112  { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Attempted to convert invalid String to Constraint Paramater: Invalid Name."); }
113  }
114  }
115 
116  int char4ToAxis(char it)
117  {
118  switch(it)
119  {
120  case '-': return -1; break;
121  case '0': return 0; break;
122  case '1': return 1; break;
123  case '2': return 2; break;
124  case '3': return 3; break;
125  case '4': return 4; break;
126  case '5': return 5; break;
127  default: { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Cannot convert invalid axis name."); }
128  }
129  }
130 
131  /////////////////////////////////////////
132  // Constraint Functions
133 
134  ////////////////////////////////////////////////////////////////////////////////
135  // Constraint Protected Methods
136 
138  { }
139 
140  void Constraint::SetBodies(RigidProxy* Prox1, RigidProxy* Prox2)
141  {
142  this->ProxA = Prox1;
143  this->ProxB = Prox2;
144  this->ProxA->SetActivationState(Mezzanine::Physics::AS_DisableDeactivation);
145  this->ProxB->SetActivationState(Mezzanine::Physics::AS_DisableDeactivation);
146  }
147 
148  void Constraint::SetBodies(RigidProxy* Prox1)
149  {
150  this->ProxA = Prox1;
151  this->ProxB = NULL;
152  this->ProxA->SetActivationState(Mezzanine::Physics::AS_DisableDeactivation);
153  }
154 
155  ////////////////////////////////////////////////////////////////////////////////
156  // Constraint Core Functionality
157 
159  { }
160 
161  RigidProxy* Constraint::GetProxyA() const
162  { return ProxA; }
163 
164  RigidProxy* Constraint::GetProxyB() const
165  { return ProxB; }
166 
167  ///////////////////////////////////////////////////////////////////////////////
168  // Constraint Parameters
169 
170  void Constraint::SetParam(ConstraintParam Param, Real Value, int Axis)
171  { this->GetConstraintBase()->setParam(Param, Value, Axis); }
172 
173  Real Constraint::GetParam(ConstraintParam Param, int Axis) const
174  { return this->GetConstraintBase()->getParam(Param, Axis); }
175 
176  ///////////////////////////////////////////////////////////////////////////////
177  // Constraint Serialization
178 
179  void Constraint::ProtoSerialize(XML::Node& CurrentRoot) const
180  {
181  XML::Node ConstraintNode = CurrentRoot.AppendChild(SerializableName()); // The base node all the base constraint stuff will go in
182  if (!ConstraintNode)
183  { SerializeError("Create ConstraintNode", SerializableName()); }
184 
185  XML::Attribute Version = ConstraintNode.AppendAttribute("Version");
186  XML::Attribute ActorNameA = ConstraintNode.AppendAttribute("ActorNameA");
187  XML::Attribute ActorNameB = ConstraintNode.AppendAttribute("ActorNameB");
188 
189  if (Version && ActorNameA && ActorNameB)
190  {
191  Version.SetValue(1);
192  /*ActorNameA.SetValue( this->GetActorA()->GetName() );
193  ActorNameB.SetValue( this->GetActorB()->GetName() );//*/
194  }else{
195  SerializeError("Create Attributes on ConstraintNode", SerializableName());
196  }
197 
198  String CurrentAxisName;
199  AxisList AllAxis = this->ValidAxis();
200  for(AxisList::iterator AxisIter=AllAxis.begin(); AllAxis.end()!=AxisIter; ++AxisIter)
201  {
202  XML::Node OneAxisNode;
203  CurrentAxisName = String("Axis")+StringTools::ConvertToString(*AxisIter); // Should result in "Axis-1", "Axis0", "Axis1" ...
204  ParamList AxisParams = ValidParamOnAxis(*AxisIter);
205  for(ParamList::iterator ParamIter=AxisParams.begin(); AxisParams.end()!=ParamIter; ++ParamIter)
206  {
207  if(HasParamBeenSet(*ParamIter,*AxisIter)) // No need to create a node if no attributes exist for it, so we will create one for the first attribute that does exist and
208  { // reuse it until we move onto the next Axis
209  if (!OneAxisNode)
210  {
211  OneAxisNode = ConstraintNode.AppendChild(CurrentAxisName);
212  if (!OneAxisNode)
213  { SerializeError( String("Create ") + CurrentAxisName + " Node", SerializableName()); }
214  }
215 
216  XML::Attribute CurrenParamAttribute = OneAxisNode.AppendAttribute( ConstraintParamAsString(*ParamIter) );
217  if (!CurrenParamAttribute)
218  { SerializeError(String("Create ") + ConstraintParamAsString(*ParamIter) + " Attribute in " + CurrentAxisName + " Node", SerializableName()); }
219  CurrenParamAttribute.SetValue( this->GetParam(*ParamIter,*AxisIter));
220  }
221  }
222  }
223  }
224 
225  void Constraint::ProtoDeSerialize(const XML::Node& OneNode)
226  {
227  if ( Mezzanine::String(OneNode.Name())==this->Constraint::SerializableName() )
228  {
229  if(OneNode.GetAttribute("Version").AsInt() == 1)
230  {
231  /*String ActorNameA(OneNode.GetAttribute("ActorNameA").AsString()); // get Actors from the XML
232  String ActorNameB(OneNode.GetAttribute("ActorNameB").AsString());
233  if (""!=ActorNameA) //Figure out if the actors are fine
234  {
235  ActorRigid* FutureA = dynamic_cast<ActorRigid*>(Entresol::GetSingletonPtr()->GetActorManager()->GetActor(ActorNameA)); // get ActorA from the Actormanager
236  if (0==FutureA)
237  { DeSerializeError("find an ActorRigid named "+ActorNameA+" in the ActorManager", SerializableName()); }
238 
239  if (""!=ActorNameB)
240  {
241  ActorRigid* FutureB = dynamic_cast<ActorRigid*>(Entresol::GetSingletonPtr()->GetActorManager()->GetActor(ActorNameB)); // get ActorB from the Actormanager
242  if (0==FutureB)
243  { DeSerializeError("find an ActorRigid named "+ActorNameB+" in the ActorManager", SerializableName()); }
244  this->SetBodies(FutureA,FutureB);
245  }else{
246  this->SetBodies(FutureA);
247  }
248  }else{
249  DeSerializeError("retrieve ActorNameA",SerializableName());
250  }//*/
251 
252  XML::Node TheAxis = OneNode.GetFirstChild();
253  while(TheAxis)
254  {
255  String EnemyName(TheAxis.Name()); //WWII country are we dealing with.
256  if(4>EnemyName.size()) //No country on the axis side WWII had fewer than 4 letters in its name. if USA somehow lands on this list it is an error
257  { DeSerializeError("find valid axis name, name is too short",SerializableName()); }
258  int AxisValue;
259 
260  AxisValue=char4ToAxis(EnemyName[4]);
261 
262  XML::Attribute AxisAttribute = TheAxis.GetFirstAttribute();
263  while(AxisAttribute)
264  {
265  this->SetParam(StringAsConstraintParam(AxisAttribute.Name()),AxisAttribute.AsReal(),AxisValue);
266  AxisAttribute = AxisAttribute.GetNextAttribute();
267  }
268 
269  TheAxis = TheAxis.GetNextSibling();
270  }// /While(TheAxis)
271 
272  }else{
273  DeSerializeError("Incompatible XML Version for "+SerializableName(),SerializableName());
274  }
275  }else{
276  DeSerializeError(String("find correct class to deserialize, found a ")+OneNode.Name()+",",SerializableName());
277  }
278  }
279 
281  { return String("Constraint"); }
282  }//Physics
283 }//Mezzanine
284 
285 ///////////////////////////////////////////////////////////////////////////////
286 // Class External << Operators for streaming or assignment
287 std::ostream& operator << (std::ostream& stream, const Mezzanine::Physics::Constraint& x)
288 {
289  Mezzanine::Serialize(stream,x);
290  return stream;
291 }
292 
293 std::istream& operator >> (std::istream& stream, Mezzanine::Physics::Constraint& x)
294  { return Mezzanine::DeSerialize(stream, x); }
295 
296 void operator >> (const Mezzanine::XML::Node& OneNode, Mezzanine::Physics::Constraint& x)
297  { x.ProtoDeSerialize(OneNode); }
298 
299 /// @endcond
300 
301 #endif