MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rigiddebris.cpp
Go to the documentation of this file.
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 _rigiddebris_cpp
41 #define _rigiddebris_cpp
42 
43 /// @file
44 /// @brief This file contains the implementation for the debris class that does not deform.
45 
46 #include "rigiddebris.h"
47 
48 #include "Graphics/scenemanager.h"
49 #include "Graphics/entityproxy.h"
50 
51 #include "Physics/physicsmanager.h"
52 #include "Physics/rigidproxy.h"
53 
54 #include "entresol.h"
55 #include "exception.h"
56 #include "stringtool.h"
57 #include "serialization.h"
58 
59 namespace Mezzanine
60 {
61  ///////////////////////////////////////////////////////////////////////////////
62  // RigidDebris Methods
63 
65  Debris(TheWorld),
66  EntProx(NULL),
67  RigProx(NULL)
68  { }
69 
70  RigidDebris::RigidDebris(const String& Name, const Real Mass, World* TheWorld) :
71  Debris(Name,TheWorld),
72  EntProx(NULL),
73  RigProx(NULL)
74  { this->CreateRigidDebris(Mass); }
75 
76  RigidDebris::RigidDebris(const XML::Node& SelfRoot, World* TheWorld) :
77  Debris(TheWorld),
78  EntProx(NULL),
79  RigProx(NULL)
80  { this->ProtoDeSerialize(SelfRoot); }
81 
83  { this->DestroyRigidDebris(); }
84 
86  {
88  if( SceneMan ) {
89  this->EntProx = SceneMan->CreateEntityProxy();
90  this->EntProx->_Bind( this );
91  }
92 
94  if( PhysMan ) {
95  this->RigProx = PhysMan->CreateRigidProxy(Mass);
96  this->RigProx->_Bind( this );
97  }
98 
99  if( this->EntProx && this->RigProx ) {
100  this->RigProx->AddSyncObject( this->EntProx );
101  }
102  }
103 
105  {
106  this->RemoveFromWorld();
107  if( this->EntProx ) {
109  if( SceneMan ) {
110  SceneMan->DestroyProxy( this->EntProx );
111  this->EntProx = NULL;
112  }
113  }
114 
115  if( this->RigProx ) {
117  if( PhysMan ) {
118  PhysMan->DestroyProxy( this->RigProx );
119  this->RigProx = NULL;
120  }
121  }
122  }
123 
124  ///////////////////////////////////////////////////////////////////////////////
125  // Utility and Configuration
126 
127  WorldObjectType RigidDebris::GetType() const
128  { return Mezzanine::WO_DebrisRigid; }
129 
131  { return this->EntProx; }
132 
134  { return this->RigProx; }
135 
136  Boolean RigidDebris::IsInWorld() const
137  { return this->RigProx->IsInWorld(); }
138 
139  Boolean RigidDebris::IsStatic() const
140  { return this->RigProx->IsStatic(); }
141 
142  Boolean RigidDebris::IsKinematic() const
143  { return this->RigProx->IsKinematic(); }
144 
146  {
147  Proxies.push_back( this->EntProx );
148  Proxies.push_back( this->RigProx );
149  }
150 
151  void RigidDebris::GetProxies(const UInt32 Types, ProxyContainer& Proxies)
152  {
153  if( Types & Mezzanine::PT_Graphics_EntityProxy ) {
154  Proxies.push_back( this->EntProx );
155  }
156  if( Types & Mezzanine::PT_Physics_RigidProxy ) {
157  Proxies.push_back( this->RigProx );
158  }
159  }
160 
161  ///////////////////////////////////////////////////////////////////////////////
162  // Working with the World
163 
165  {
166  if( this->EntProx )
167  this->EntProx->AddToWorld();
168 
169  if( this->RigProx )
170  this->RigProx->AddToWorld();
171  }
172 
174  {
175  if( this->EntProx )
176  this->EntProx->RemoveFromWorld();
177 
178  if( this->RigProx )
179  this->RigProx->RemoveFromWorld();
180  }
181 
182  ///////////////////////////////////////////////////////////////////////////////
183  // Transform Methods
184 
186  {
187  this->RigProx->SetLocation(Loc);
188  this->EntProx->SetLocation(Loc);
189  }
190 
191  void RigidDebris::SetLocation(const Real X, const Real Y, const Real Z)
192  {
193  this->RigProx->SetLocation(X,Y,Z);
194  this->EntProx->SetLocation(X,Y,Z);
195  }
196 
198  {
199  return this->RigProx->GetLocation();
200  }
201 
203  {
204  this->RigProx->SetOrientation(Ori);
205  this->EntProx->SetOrientation(Ori);
206  }
207 
208  void RigidDebris::SetOrientation(const Real X, const Real Y, const Real Z, const Real W)
209  {
210  this->RigProx->SetOrientation(X,Y,Z,W);
211  this->EntProx->SetOrientation(X,Y,Z,W);
212  }
213 
215  {
216  return this->RigProx->GetOrientation();
217  }
218 
220  {
221  this->RigProx->SetScale(Sc);
222  this->EntProx->SetScale(Sc);
223  }
224 
225  void RigidDebris::SetScale(const Real X, const Real Y, const Real Z)
226  {
227  this->RigProx->SetScale(X,Y,Z);
228  this->EntProx->SetScale(X,Y,Z);
229  }
230 
232  {
233  return this->RigProx->GetScale();
234  }
235 
236  void RigidDebris::Translate(const Vector3& Trans)
237  {
238  this->RigProx->Translate(Trans);
239  this->EntProx->Translate(Trans);
240  }
241 
242  void RigidDebris::Translate(const Real X, const Real Y, const Real Z)
243  {
244  this->RigProx->Translate(X,Y,Z);
245  this->EntProx->Translate(X,Y,Z);
246  }
247 
248  void RigidDebris::Yaw(const Real Angle)
249  {
250  this->RigProx->Yaw(Angle);
251  this->EntProx->Yaw(Angle);
252  }
253 
254  void RigidDebris::Pitch(const Real Angle)
255  {
256  this->RigProx->Pitch(Angle);
257  this->EntProx->Pitch(Angle);
258  }
259 
260  void RigidDebris::Roll(const Real Angle)
261  {
262  this->RigProx->Roll(Angle);
263  this->EntProx->Roll(Angle);
264  }
265 
266  void RigidDebris::Rotate(const Vector3& Axis, const Real Angle)
267  {
268  this->RigProx->Rotate(Axis,Angle);
269  this->EntProx->Rotate(Axis,Angle);
270  }
271 
272  void RigidDebris::Rotate(const Quaternion& Rotation)
273  {
274  this->RigProx->Rotate(Rotation);
275  this->EntProx->Rotate(Rotation);
276  }
277 
278  void RigidDebris::Scale(const Vector3& Scale)
279  {
280  this->RigProx->Scale(Scale);
281  this->EntProx->Scale(Scale);
282  }
283 
284  void RigidDebris::Scale(const Real X, const Real Y, const Real Z)
285  {
286  this->RigProx->Scale(X,Y,Z);
287  this->EntProx->Scale(X,Y,Z);
288  }
289 
290  ///////////////////////////////////////////////////////////////////////////////
291  // Serialization
292 
294  {
295  this->Debris::ProtoSerializeProperties(SelfRoot);
296  }
297 
299  {
300  // No base implementations to call
301  XML::Node ProxiesNode = SelfRoot.AppendChild( RigidDebris::GetSerializableName() + "Proxies" );
302 
303  if( ProxiesNode.AppendAttribute("Version").SetValue("1") )
304  {
305  XML::Node EntProxNode = ProxiesNode.AppendChild("EntProx");
306  this->EntProx->ProtoSerialize( EntProxNode );
307  XML::Node RigProxNode = ProxiesNode.AppendChild("RigProx");
308  this->RigProx->ProtoSerialize( RigProxNode );
309 
310  return;
311  }else{
312  SerializeError("Create XML Attribute Values",RigidDebris::GetSerializableName() + "Proxies",true);
313  }
314  }
315 
317  {
318  this->Debris::ProtoDeSerializeProperties(SelfRoot);
319  }
320 
322  {
323  this->DestroyRigidDebris();
324  // No base implementations to call
325  //XML::Attribute CurrAttrib;
326  XML::Node ProxiesNode = SelfRoot.GetChild( RigidDebris::GetSerializableName() + "Proxies" );
327 
328  if( !ProxiesNode.Empty() ) {
329  if(ProxiesNode.GetAttribute("Version").AsInt() == 1) {
330  /// @todo I don't think an exception is appropriate for the failure of the worldmanager validity checks,
331  /// however a warning should be written to the log if that happens. This should be updated to do that once
332  /// logging refactors are done.
333 
334  XML::Node EntProxNode = ProxiesNode.GetChild("EntProx").GetFirstChild();
335  if( !EntProxNode.Empty() ) {
337  if( SceneMan ) {
338  this->EntProx = SceneMan->CreateEntityProxy( EntProxNode );
339  this->EntProx->_Bind( this );
340  }
341  }
342 
343  XML::Node RigProxNode = ProxiesNode.GetChild("RigProx").GetFirstChild();
344  if( !RigProxNode.Empty() ) {
346  if( PhysMan ) {
347  this->RigProx = PhysMan->CreateRigidProxy(RigProxNode);
348  this->RigProx->_Bind( this );
349  }
350  }
351 
352  if( this->EntProx && this->RigProx ) {
353  this->RigProx->AddSyncObject( this->EntProx );
354  }
355  }else{
356  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (RigidDebris::GetSerializableName() + "Proxies" ) + ": Not Version 1.");
357  }
358  }else{
359  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,RigidDebris::GetSerializableName() + "Proxies" + " was not found in the provided XML node, which was expected.");
360  }
361  }
362 
365 
367  { return "RigidDebris"; }
368 
369  ///////////////////////////////////////////////////////////////////////////////
370  // Internal Methods
371 
373  {
374  // Do nothing
375  }
376 
378  {
379  if( ToBeDestroyed == NULL )
380  return;
381 
382  if( this->EntProx == ToBeDestroyed ) {
383  if( this->RigProx ) {
384  this->RigProx->RemoveSyncObject( this->EntProx );
385  }
386 
387  this->EntProx = NULL;
388  }
389 
390  if( this->RigProx == ToBeDestroyed ) {
391  this->RigProx = NULL;
392  }
393  }
394 
395  ///////////////////////////////////////////////////////////////////////////////
396  // RigidDebrisFactory Methods
397 
399  { }
400 
402  { }
403 
406 
408  { return new RigidDebris(Name,Mass,TheWorld); }
409 
411  { return static_cast<RigidDebris*>( this->CreateDebris(XMLNode,TheWorld) ); }
412 
413  Debris* RigidDebrisFactory::CreateDebris(const String& Name, World* TheWorld, const NameValuePairMap& Params)
414  {
415  Real Mass = 0;
416  NameValuePairMap::const_iterator ParamIt = Params.find( "Mass" );
417  if( ParamIt != Params.end() )
418  Mass = StringTools::ConvertToReal( (*ParamIt).second );
419 
420  return new RigidDebris(Name,Mass,TheWorld);
421  }
422 
424  { return new RigidDebris(XMLNode,TheWorld); }
425 
427  { delete ToBeDestroyed; }
428 }//Mezzanine
429 
430 #endif