Spinning Topp Logo BlackTopp Studios
inc
compoundcollisionshape.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 _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::GetSerializableName());
154  if (!CollisionNode) { SerializeError("create CollisionNode",this->CompoundCollisionShape::GetSerializableName());}
155 
156  XML::Attribute Version = CollisionNode.AppendAttribute("Version");
157  if (Version)
158  { Version.SetValue(1); }
159  else
160  { SerializeError("Create Version Attribute", GetSerializableName()); }
161 
162  this->CollisionShape::ProtoSerialize(CollisionNode);
163 
164  XML::Node ChildShapesNode = CollisionNode.AppendChild("Shapes");
165  if (!ChildShapesNode) { SerializeError("create ChildShapesNode",this->CompoundCollisionShape::GetSerializableName());}
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::GetSerializableName());}
172  XML::Attribute OneName = OneChildShapeNode.AppendAttribute("Name");
173  if(!OneName) { SerializeError("create Name Attribute on OneChildShapeNode",this->CompoundCollisionShape::GetSerializableName());}
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",GetSerializableName()); }
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::GetSerializableName());}
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::GetSerializableName()); }
204  CollisionShape* CurrentShape = CollisionShapeManager::GetSingletonPtr()->GetShape(OneName.AsString());
205  if(!CurrentShape) { DeSerializeError("find correct shape in CollisionShape Manager",this->CompoundCollisionShape::GetSerializableName()); }
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",GetSerializableName());
216  }
217  }else{
218  DeSerializeError(String("find correct class to deserialize, found a ")+OneNode.Name(),GetSerializableName());
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 
234  { x.ProtoDeSerialize(OneNode); }
235 
236 #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
This is the base class for all collision shapes.
virtual void ProtoDeSerialize(const XML::Node &OneNode)
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
virtual void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
CompoundCollisionShape(const String &Name)
Class Constructor.
CollisionShape * CreateShape(CollisionShape::ShapeType ShapeToCreate, const String &Name_, btCollisionShape *ShapeToModel)
Create A shape of a type and optionally model it after an example.
String ConvertToString(const Vector2 &ToConvert)
Converts a Vector2 into a string.
Definition: stringtool.cpp:291
virtual Whole GetNumChildren() const
Gets the number of children belonging to this compound shape.
Node GetFirstChild() const
Get the first child Node of this Node.
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...
const Char8 * AsString(const Char8 *def="") const
Attempts to convert the value of the attribute to a String and returns the results.
std::vector< CollisionShape * > ChildShapes
Storage for Child shapes.
virtual void ProtoSerialize(XML::Node &CurrentRoot) const
virtual btCollisionShape * _GetInternalShape() const
Gets the internal shape pointer this collision shape is based on.
virtual CollisionShape * GetChild(Whole Index) const
Get a specific child.
Node GetNextSibling() const
Attempt to retrieve the next sibling of this Node.
Indicates the class is a CompoundCollisionShape.
btQuaternion GetBulletQuaternion(Boole normalize=false) const
Gets a Bullet quaternion.
Definition: quaternion.cpp:243
virtual btCompoundShape * GetBulletCompoundShape() const
bool SetValue(const Char8 *rhs)
Set the value of this.
btTransform GetBulletTransform() const
Gets a Bullet Transform.
Definition: transform.cpp:71
static CollisionShapeManager * GetSingletonPtr()
Fetches a pointer to the singleton.
Definition: singleton.h:97
virtual void AddChildShape(CollisionShape *Child, const Vector3 &ChildLocation, const Quaternion &ChildRotation)
Adds a shape to this compound shape.
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
static String GetSerializableName()
Get the name of the the XML tag this class will leave behind as its instances are serialized...
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
virtual CollisionShape::ShapeType GetType() const
Gets the type of Collision shape this is.
ShapeType
This enum describes what kind of shape you are currently working with.
std::istream & DeSerialize(std::istream &Stream, T &Converted)
Deserialize the next xml tag in the stream into a specific in memory class instance.
virtual void ProtoDeSerialize(const XML::Node &OneNode)
Take the data stored in an XML and overwrite this instance of this object with it.
Stores information about relative location and rotation in 3d space.
Definition: transform.h:62
void DeSerializeError(const String &FailedTo, const String &ClassName, Boole SOrD)
Simply does some string concatenation, then throws an Exception.
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
virtual void RemoveChildShape(CollisionShape *Child)
Removes a Child shape from this compound shape.
String Name
Storage for the name of this class instance.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
std::istream & operator>>(std::istream &stream, Mezzanine::LinearInterpolator< T > &Lint)
Used to de-serialize an Mezzanine::LinearInterpolator from a stream.
Definition: interpolator.h:448
btCollisionShape * ShapeBase
A pointer to the bullet collision this uses.
const Char8 * Name() const
ptrdiff_tGet the name of this Node.
CollisionShape::ShapeType InternalShapeTypeToShapeType(int InternalShapeType)
Convert from a Internal Collision Shape to a CollisionShape::ShapeType.
This is used to store information about rotation in 3d space.
Definition: quaternion.h:68
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.
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.
A collision shape composed of many other collision shapes placed and oriented in local space...
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.
virtual const String & GetName() const
Gets the name of this shape.