MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
compoundcollisionshape.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 _physicscompoundcollisionshape_cpp
41 #define _physicscompoundcollisionshape_cpp
42 
43 #include "Physics/compoundcollisionshape.h"
44 #include "collisionshapemanager.h"
45 #include "stringtool.h"
46 
47 #include <btBulletDynamicsCommon.h>
48 
49 namespace Mezzanine
50 {
51  namespace Physics
52  {
53  /////////////////////////////////////////
54  // CompoundCollisionShape Functions
55 
57  {
58  this->Name = Name;
59  ShapeBase = new btCompoundShape(false);
60  }
61 
62  CompoundCollisionShape::CompoundCollisionShape(const String& Name, btCompoundShape* BulletShape)
63  {
64  this->Name = Name;
65  ShapeBase = BulletShape;
66 
67  Whole NumChildren = GetBulletCompoundShape()->getNumChildShapes();
68  for( Whole X = 0 ; X < NumChildren ; X++ )
69  {
70  btCollisionShape* CurrChild = GetBulletCompoundShape()->getChildShape(X);
71  CollisionShape* CreatedShape = CreateShape(InternalShapeTypeToShapeType(CurrChild->getShapeType()), this->Name+"Child"+StringTools::ConvertToString(X), CurrChild);
72  ChildShapes.push_back(CreatedShape);
73  CollisionShapeManager::GetSingletonPtr()->StoreShape(CreatedShape);
74  }
75  }
76 
78  {
79  /*for( Whole X = 0 ; X < ChildShapes.size() ; X++ )
80  {
81  //GetBulletCompoundShape()->removeChildShapeByIndex(X);
82  delete ChildShapes[X];
83  }
84  ChildShapes.clear();*/
85  delete GetBulletCompoundShape();
86  }
87 
88  void CompoundCollisionShape::AddChildShape(CollisionShape* Child, const Vector3& ChildLocation, const Quaternion& ChildRotation)
89  {
90  btTransform ChildTrans(ChildRotation.GetBulletQuaternion(),ChildLocation.GetBulletVector3());
91  GetBulletCompoundShape()->addChildShape(ChildTrans,Child->_GetInternalShape());
92  ChildShapes.push_back(Child);
93  CollisionShapeManager::GetSingletonPtr()->StoreShape(Child);
94  }
95 
97  {
98  btTransform ChildTrans;
99  ChildTrans.setIdentity();
100  ChildTrans.setOrigin(ChildLocation.GetBulletVector3());
101  GetBulletCompoundShape()->addChildShape(ChildTrans,Child->_GetInternalShape());
102  ChildShapes.push_back(Child);
103  CollisionShapeManager::GetSingletonPtr()->StoreShape(Child);
104  }
105 
107  {
108  GetBulletCompoundShape()->addChildShape(ChildLocation.GetBulletTransform(),Child->_GetInternalShape());
109  ChildShapes.push_back(Child);
110  CollisionShapeManager::GetSingletonPtr()->StoreShape(Child);
111  }
112 
114  {
115  return ChildShapes.size();
116  }
117 
119  {
120  return ChildShapes.at(Index);
121  }
122 
124  {
125  for( std::vector<CollisionShape*>::iterator CSit = ChildShapes.begin() ; CSit != ChildShapes.end() ; CSit++ )
126  {
127  if(Child == (*CSit))
128  {
129  ChildShapes.erase(CSit);
130  GetBulletCompoundShape()->removeChildShape(Child->_GetInternalShape());
131  return;
132  }
133  }
134  }
135 
137  {
138  std::vector<CollisionShape*>::iterator CSit = ChildShapes.begin() + ChildIndex;
139  ChildShapes.erase(CSit);
140  GetBulletCompoundShape()->removeChildShapeByIndex(ChildIndex);
141  }
142 
144  {
146  }
147 
149  { return static_cast<btCompoundShape*>(ShapeBase); }
150 
152  {
153  XML::Node CollisionNode = CurrentRoot.AppendChild(this->CompoundCollisionShape::SerializableName());
154  if (!CollisionNode) { SerializeError("create CollisionNode",this->CompoundCollisionShape::SerializableName());}
155 
156  XML::Attribute Version = CollisionNode.AppendAttribute("Version");
157  if (Version)
158  { Version.SetValue(1); }
159  else
160  { SerializeError("Create Version Attribute", SerializableName()); }
161 
162  this->CollisionShape::ProtoSerialize(CollisionNode);
163 
164  XML::Node ChildShapesNode = CollisionNode.AppendChild("Shapes");
165  if (!ChildShapesNode) { SerializeError("create ChildShapesNode",this->CompoundCollisionShape::SerializableName());}
166  for( Whole X = 0 ; X < ChildShapes.size() ; X++ )
167  {
168  //if() //the shape is in the manager
169  //{
170  XML::Node OneChildShapeNode = ChildShapesNode.AppendChild("ChildShapeFromManager");
171  if(!OneChildShapeNode) { SerializeError("create ChildShapeFromManager Node",this->CompoundCollisionShape::SerializableName());}
172  XML::Attribute OneName = OneChildShapeNode.AppendAttribute("Name");
173  if(!OneName) { SerializeError("create Name Attribute on OneChildShapeNode",this->CompoundCollisionShape::SerializableName());}
174  OneName.SetValue(ChildShapes[X]->GetName());
175  //}else{
176  // ChildShapes[X].ProtoSerialize(ChildShapesNode);
177  //}
178  }
179 
180  }
181 
183  {
185  {
186  if(OneNode.GetAttribute("Version").AsInt() == 1)
187  {
188  XML::Node CollisionNode = OneNode.GetChild("CollisionShape");
189  if(!CollisionNode)
190  { DeSerializeError("locate CollisionShape node",SerializableName()); }
191  this->CollisionShape::ProtoDeSerialize(CollisionNode);
192 
193  ChildShapes.clear(); // this will leak if any childshapes are not in the CollisionManager.
194  XML::Node ChildShapesNode = OneNode.GetChild("Shapes");
195  if(!ChildShapesNode) { DeSerializeError("Find Shapes Node",this->CompoundCollisionShape::SerializableName());}
196 
197  XML::Node ChildNode = ChildShapesNode.GetFirstChild();
198  while(ChildNode)
199  {
200  if(String(ChildNode.Name())=="ChildShapeFromManager")
201  {
202  XML::Attribute OneName = ChildNode.GetAttribute("Name");
203  if(!OneName) { DeSerializeError("find Name Attribute on ChildShapeFromManager Node",this->CompoundCollisionShape::SerializableName()); }
204  CollisionShape* CurrentShape = CollisionShapeManager::GetSingletonPtr()->GetShape(OneName.AsString());
205  if(!CurrentShape) { DeSerializeError("find correct shape in CollisionShape Manager",this->CompoundCollisionShape::SerializableName()); }
206  ChildShapes.push_back(CurrentShape);
207  }else{
208  CollisionShape* CurrentShape = CreateShape(ChildNode);
209  ChildShapes.push_back(CurrentShape);
210  }
211  ChildNode=ChildNode.GetNextSibling();
212  }
213 
214  }else{
215  DeSerializeError("find usable serialization version",SerializableName());
216  }
217  }else{
218  DeSerializeError(String("find correct class to deserialize, found a ")+OneNode.Name(),SerializableName());
219  }
220  }
221 
223  { return String("CompoundCollisionShape"); }
224  }//Physics
225 }//Mezzanine
226 
227 std::ostream& operator << (std::ostream& stream, const Mezzanine::Physics::CompoundCollisionShape& ShapeToSerialize)
228  { Mezzanine::Serialize(stream, ShapeToSerialize); return stream; }
229 
230 std::istream& operator >> (std::istream& stream, Mezzanine::Physics::CompoundCollisionShape& x)
231  { return Mezzanine::DeSerialize(stream, x); }
232 
233 void operator >> (const Mezzanine::XML::Node& OneNode, Mezzanine::Physics::CompoundCollisionShape& x)
234  { x.ProtoDeSerialize(OneNode); }
235 
236 #endif