Spinning Topp Logo BlackTopp Studios
inc
areaeffect.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 _areaeffect_cpp
41 #define _areaeffect_cpp
42 
43 #include "areaeffect.h"
44 
45 #include "Physics/physicsmanager.h"
46 #include "Physics/collisionshape.h"
47 #include "Physics/collisionshapemanager.h"
48 #include "Physics/ghostproxy.h"
49 
50 #include "Graphics/mesh.h"
51 #include "Graphics/meshmanager.h"
52 #include "Graphics/entityproxy.h"
54 #include "Graphics/scenemanager.h"
55 
56 #include "serialization.h"
57 #include "exception.h"
58 #include "entresol.h"
59 #include "world.h"
60 
61 #include <algorithm>
62 
63 #ifdef GetObject
64 #undef GetObject
65 #endif
66 
67 namespace Mezzanine
68 {
70  WorldObject(TheWorld),
71  Ghost(NULL)
72  { this->CreateAreaEffect(NULL); }
73 
74  AreaEffect::AreaEffect(const String& Name, World* TheWorld) :
75  WorldObject(Name,TheWorld),
76  Ghost(NULL)
77  { this->CreateAreaEffect(NULL); }
78 
79  AreaEffect::AreaEffect(const String& Name, Physics::CollisionShape* Shape, World* TheWorld) :
80  WorldObject(Name,TheWorld),
81  Ghost(NULL)
82  { this->CreateAreaEffect(Shape); }
83 
85  { this->DestroyAreaEffect(); }
86 
88  {
89  Physics::PhysicsManager* PhysMan = static_cast<Physics::PhysicsManager*>( this->ParentWorld->GetManager(ManagerBase::MT_PhysicsManager) );
90  if( PhysMan != NULL ) {
91  if( Shape == NULL ) {
92  this->Ghost = PhysMan->CreateGhostProxy();
93  }else{
94  this->Ghost = PhysMan->CreateGhostProxy(Shape,false);
95  }
96 
97  UInt16 ColGroup = Physics::CF_SensorFilter;
98  UInt16 ColMask = Physics::CF_AllFilter & ~(Physics::CF_SensorFilter | Physics::CF_StaticFilter);
99  this->Ghost->SetCollisionGroupAndMask(ColGroup,ColMask);
100  this->Ghost->_Bind(this);
101  }
102  }
103 
105  {
106  this->RemoveFromWorld();
107  Physics::PhysicsManager* PhysMan = static_cast<Physics::PhysicsManager*>( this->ParentWorld->GetManager(ManagerBase::MT_PhysicsManager) );
108  if( this->Ghost != NULL && PhysMan != NULL ) {
109  PhysMan->DestroyProxy( this->Ghost );
110  this->Ghost = NULL;
111  }
112  }
113 
114  ///////////////////////////////////////////////////////////////////////////////
115  // Utility
116 
118  { return Mezzanine::WO_AreaEffectUnknown; }
119 
121  { return this->Ghost; }
122 
124  { return this->Ghost->IsInWorld(); }
125 
127  { return this->Ghost->IsStatic(); }
128 
130  { return this->Ghost->IsKinematic(); }
131 
132  void AreaEffect::GetProxies(ProxyContainer& Proxies)
133  {
134  Proxies.push_back( this->Ghost );
135  }
136 
137  void AreaEffect::GetProxies(const UInt32 Types, ProxyContainer& Proxies)
138  {
139  if( Types & Mezzanine::PT_Physics_GhostProxy ) {
140  Proxies.push_back( this->Ghost );
141  }
142  }
143 
144  ///////////////////////////////////////////////////////////////////////////////
145  // Working with the World
146 
148  {
149  if( this->Ghost )
150  this->Ghost->AddToWorld();
151  }
152 
154  {
155  if( this->Ghost )
156  this->Ghost->RemoveFromWorld();
157  }
158 
159  ///////////////////////////////////////////////////////////////////////////////
160  // Overlapping Object Management
161 
163  { return this->OverlappingObjects.size(); }
164 
166  { return this->AddedObjects.size(); }
167 
169  { return this->RemovedObjects.size(); }
170 
172  { return this->OverlappingObjects; }
173 
175  { return this->AddedObjects; }
176 
178  { return this->RemovedObjects; }
179 
180  ///////////////////////////////////////////////////////////////////////////////
181  // AreaEffect Properties
182 
183  ///////////////////////////////////////////////////////////////////////////////
184  // Transform Methods
185 
187  {
188  this->Ghost->SetLocation(Loc);
189  }
190 
191  void AreaEffect::SetLocation(const Real X, const Real Y, const Real Z)
192  {
193  this->Ghost->SetLocation(X,Y,Z);
194  }
195 
197  {
198  return this->Ghost->GetLocation();
199  }
200 
202  {
203  this->Ghost->SetOrientation(Ori);
204  }
205 
206  void AreaEffect::SetOrientation(const Real X, const Real Y, const Real Z, const Real W)
207  {
208  this->Ghost->SetOrientation(X,Y,Z,W);
209  }
210 
212  {
213  return this->Ghost->GetOrientation();
214  }
215 
217  {
218  this->Ghost->SetScale(Sc);
219  }
220 
221  void AreaEffect::SetScale(const Real X, const Real Y, const Real Z)
222  {
223  this->Ghost->SetScale(X,Y,Z);
224  }
225 
227  {
228  return this->Ghost->GetScale();
229  }
230 
231  void AreaEffect::Translate(const Vector3& Trans)
232  {
233  this->Ghost->Translate(Trans);
234  }
235 
236  void AreaEffect::Translate(const Real X, const Real Y, const Real Z)
237  {
238  this->Ghost->Translate(X,Y,Z);
239  }
240 
241  void AreaEffect::Yaw(const Real Angle)
242  {
243  this->Ghost->Yaw(Angle);
244  }
245 
246  void AreaEffect::Pitch(const Real Angle)
247  {
248  this->Ghost->Pitch(Angle);
249  }
250 
251  void AreaEffect::Roll(const Real Angle)
252  {
253  this->Ghost->Roll(Angle);
254  }
255 
256  void AreaEffect::Rotate(const Vector3& Axis, const Real Angle)
257  {
258  this->Ghost->Rotate(Axis,Angle);
259  }
260 
261  void AreaEffect::Rotate(const Quaternion& Rotation)
262  {
263  this->Ghost->Rotate(Rotation);
264  }
265 
266  void AreaEffect::Scale(const Vector3& Scale)
267  {
268  this->Ghost->Scale(Scale);
269  }
270 
271  void AreaEffect::Scale(const Real X, const Real Y, const Real Z)
272  {
273  this->Ghost->Scale(X,Y,Z);
274  }
275 
276  ///////////////////////////////////////////////////////////////////////////////
277  // Serialization
278 
280  {
282  }
283 
285  {
286  // No base implementations to call
287  XML::Node ProxiesNode = SelfRoot.AppendChild( AreaEffect::GetSerializableName() + "Proxies" );
288 
289  if( ProxiesNode.AppendAttribute("Version").SetValue("1") )
290  {
291  XML::Node GhostProxNode = ProxiesNode.AppendChild("Ghost");
292  this->Ghost->ProtoSerialize( GhostProxNode );
293 
294  return;
295  }else{
296  SerializeError("Create XML Attribute Values",AreaEffect::GetSerializableName() + "Proxies",true);
297  }
298  }
299 
301  {
303  }
304 
306  {
307  this->DestroyAreaEffect();
308  // No base implementations to call
309  //XML::Attribute CurrAttrib;
310  XML::Node ProxiesNode = SelfRoot.GetChild( AreaEffect::GetSerializableName() + "Proxies" );
311 
312  if( !ProxiesNode.Empty() ) {
313  if(ProxiesNode.GetAttribute("Version").AsInt() == 1) {
314  /// @todo I don't think an exception is appropriate for the failure of the worldmanager validity checks,
315  /// however a warning should be written to the log if that happens. This should be updated to do that once
316  /// logging refactors are done.
317 
318  XML::Node GhostProxNode = ProxiesNode.GetChild("Ghost").GetFirstChild();
319  if( !GhostProxNode.Empty() ) {
320  Physics::PhysicsManager* PhysMan = static_cast<Physics::PhysicsManager*>( this->ParentWorld->GetManager(ManagerBase::MT_PhysicsManager) );
321  if( PhysMan ) {
322  this->Ghost = PhysMan->CreateGhostProxy(GhostProxNode);
323  this->Ghost->_Bind( this );
324  }
325  }
326  }else{
327  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (AreaEffect::GetSerializableName() + "Proxies" ) + ": Not Version 1.");
328  }
329  }else{
330  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,AreaEffect::GetSerializableName() + "Proxies" + " was not found in the provided XML node, which was expected.");
331  }
332  }
333 
335  { return AreaEffect::GetSerializableName(); }
336 
338  { return "AreaEffect"; }
339 
340  ///////////////////////////////////////////////////////////////////////////////
341  // Internal Methods
342 
344  {
345  this->AddedObjects.clear();
346  this->RemovedObjects.clear();
347 
348  ObjectContainer PrevOverlapping;
349  PrevOverlapping.swap( this->OverlappingObjects );
350 
351  const UInt32 NumProxies = this->Ghost->GetNumShapeOverlappingProxies();
352  for( UInt32 ProxIndex = 0 ; ProxIndex < NumProxies ; ++ProxIndex )
353  {
354  Physics::CollidableProxy* CurrProxy = this->Ghost->GetShapeOverlappingProxy( ProxIndex );
355  if( CurrProxy != NULL ) {
356  WorldObject* CurrObject = CurrProxy->GetParentObject();
357  if( CurrObject != NULL ) {
358  // We need to check for unique world objects just in case a world object contains multiple collidable proxies
359  ObjectIterator UniqueCheck = std::find( this->OverlappingObjects.begin(), this->OverlappingObjects.end(), CurrObject );
360  if( UniqueCheck == this->OverlappingObjects.end() ) {
361  // We've established that this object is unique, so lets try to remove it from our temporary vector
362  ObjectIterator PrevCheck = std::find( PrevOverlapping.begin(), PrevOverlapping.end(), CurrObject );
363  if( PrevCheck == PrevOverlapping.end() ) {
364  // If we've failed to find it, then it's new
365  this->OverlappingObjects.push_back( CurrObject );
366  this->AddedObjects.push_back( CurrObject );
367  }else{
368  // If it was in the previous frame it isn't new, but it may be removed
369  this->OverlappingObjects.push_back( CurrObject );
370  PrevOverlapping.erase( PrevCheck );
371  }
372  }
373  }
374  }
375  }
376 
377  // If we have anything left over in our prev-overlapping, it's not inside this anymore so put them in the removed vector
378  if( !PrevOverlapping.empty() ) {
379  this->RemovedObjects.swap( PrevOverlapping );
380  }
381  }
382 
384  {
385  if( ToBeDestroyed == NULL )
386  return;
387 
388  if( this->Ghost == ToBeDestroyed ) {
389  this->Ghost = NULL;
390  }
391  }
392 }
393 
394 #endif
This is the base class for all collision shapes.
virtual void Yaw(const Real Angle)
Rotate the object around the Y axis.
virtual void AddToWorld()
Performs all the necessary task to ensure this object is connected to it's respective world and ready...
Definition: ghostproxy.cpp:103
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
WorldManager * GetManager(const Whole ManagerToGet)
This is will find the manager of a given type.
Definition: world.cpp:324
ObjectContainer & GetOverlappingObjects()
Gets the list of objects within this field.
Definition: areaeffect.cpp:171
virtual void Pitch(const Real Angle)
Rotate the object around the X axis.
virtual void SetLocation(const Vector3 &Loc)
Sets the location of this object in parent space.
Definition: areaeffect.cpp:186
virtual void AddToWorld()
Adds the object to the World.
Definition: areaeffect.cpp:147
virtual void Rotate(const Vector3 &Axis, const Real Angle)
Rotates the object from it's existing rotation.
Definition: areaeffect.cpp:256
ObjectContainer & GetRemovedObjects()
Gets the list of objects that have been removed from the list since the last simulation step...
Definition: areaeffect.cpp:177
ObjectContainer AddedObjects
Container of actors that have been added since last frame.
Definition: areaeffect.h:80
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
std::vector< WorldObject * > ObjectContainer
Basic container type for Object storage by this class.
Definition: areaeffect.h:69
virtual void Rotate(const Vector3 &Axis, const Real Angle)
Rotates the object from it's existing rotation.
virtual void Translate(const Vector3 &Trans)
Moves this object from it's current location.
Definition: areaeffect.cpp:231
virtual UInt32 GetNumShapeOverlappingProxies() const
Gets the number of proxies overlapping with the actual collision shape of this ghost.
Definition: ghostproxy.cpp:164
virtual void Yaw(const Real Angle)
Rotate the object around the Y axis.
Definition: areaeffect.cpp:241
UInt32 GetNumRemovedObjects() const
Gets the number of objects removed from this AE since the last update.
Definition: areaeffect.cpp:168
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
This is the proxy object for ghost objects with no contact response.
Definition: ghostproxy.h:55
ObjectContainer::iterator ObjectIterator
Iterator type for Object instances stored by this class.
Definition: areaeffect.h:71
Thrown when the requested identity could not be found.
Definition: exception.h:94
Node GetFirstChild() const
Get the first child Node of this Node.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
virtual Vector3 GetLocation() const
Gets this objects current location.
World * ParentWorld
This is the world this object belongs to and will be inserted in/removed from.
Definition: worldobject.h:84
virtual void ProtoDeSerializeProxies(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the proxies of this object with it...
Definition: areaeffect.cpp:305
virtual CollidableProxy * GetShapeOverlappingProxy(const UInt32 Index)
Gets a proxy overlapping with the collision shape of this ghost.
Definition: ghostproxy.cpp:131
virtual void SetScale(const Vector3 &Sc)
Sets the scaling to be applied to this object.
Definition: areaeffect.cpp:216
ObjectContainer & GetAddedObjects()
Gets the list of objects that have been added to the list since the last simulation step...
Definition: areaeffect.cpp:174
virtual Boole IsKinematic() const
Is the object kinematic.
virtual void ProtoSerializeProxies(XML::Node &SelfRoot) const
Convert the proxies of this class to an XML::Node ready for serialization.
Definition: areaeffect.cpp:284
ObjectContainer OverlappingObjects
Container for actors within the field area.
Definition: areaeffect.h:77
GhostProxy * CreateGhostProxy()
Creates a new GhostProxy.
bool Empty() const
Is this storing anything at all?
virtual void SetLocation(const Vector3 &Loc)
Sets the location of this object in parent space.
virtual Boole IsInWorld() const
Gets whether or not this object is currently in the world.
Definition: areaeffect.cpp:123
This implements the exception hiearchy for Mezzanine.
virtual void Pitch(const Real Angle)
Rotate the object around the X axis.
Definition: areaeffect.cpp:246
virtual void Roll(const Real Angle)
Rotate the object around the Z axis.
virtual void ProtoSerialize(XML::Node &ParentNode) const
Convert this class to an XML::Node ready for serialization.
Definition: worldproxy.cpp:84
virtual void Scale(const Vector3 &Scale)
Scales the object from it's current size.
Definition: areaeffect.cpp:266
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
The interface for serialization.
bool SetValue(const Char8 *rhs)
Set the value of this.
This is the base class from which classes that are insertable into the physical world.
Definition: worldobject.h:60
virtual Boole IsStatic() const
Checks of the object is static.
Definition: areaeffect.cpp:126
uint16_t UInt16
An 16-bit unsigned integer.
Definition: datatypes.h:122
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Definition: areaeffect.cpp:279
virtual WorldObjectType GetType() const
Gets the type of the object instance.
Definition: areaeffect.cpp:117
virtual Vector3 GetScale() const
Gets the scaling currently being applied to this object.
virtual void SetOrientation(const Quaternion &Ori)
Sets the orientation of this object in parent space.
virtual Vector3 GetScale() const
Gets the scaling currently being applied to this object.
Definition: areaeffect.cpp:226
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Definition: worldobject.cpp:87
AreaEffect(World *TheWorld)
Blank constructor.
Definition: areaeffect.cpp:69
virtual void CreateAreaEffect(Physics::CollisionShape *Shape)
Common constructor method for AreaEffect base class.
Definition: areaeffect.cpp:87
virtual Boole IsStatic() const
Is the object static.
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
virtual Boole IsKinematic() const
Checks of the object is kinematic.
Definition: areaeffect.cpp:129
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
This is the base class for proxy objects belonging to the various 3D subsystems.
Definition: worldproxy.h:53
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
Definition: areaeffect.cpp:300
This file contains the declaration for the World proxy wrapping basic entity(mesh) functionality...
virtual void SetScale(const Vector3 &Sc)
Sets the scaling to be applied to this object.
virtual void _NotifyProxyDestroyed(WorldProxy *ToBeDestroyed)
Notifies that a proxy belonging to this WorldObject is being forcibly destroyed, and it needs to upda...
Definition: areaeffect.cpp:383
void _Bind(WorldObject *NewParent)
Binds this proxy to a WorldObject.
Definition: worldproxy.cpp:174
virtual void DestroyAreaEffect()
Common destructor method for AreaEffect base class.
Definition: areaeffect.cpp:104
static String GetSerializableName()
Get the name of the the XML tag the proxy class will leave behind as its instances are serialized...
Definition: areaeffect.cpp:337
Physics::GhostProxy * Ghost
A pointer to the ghost powering this AE field.
Definition: areaeffect.h:89
virtual Quaternion GetOrientation() const
Gets this objects current orientation.
virtual String GetDerivedSerializableName() const
Gets the most derived serializable name of this WorldObject.
Definition: areaeffect.cpp:334
This is a proxy from which physics objects that can collide with each other are handled.
virtual void RemoveFromWorld()
Unhooks this proxy from it's respective world.
Definition: ghostproxy.cpp:110
This is simply a place for storing all the Physics Related functions.
virtual void Roll(const Real Angle)
Rotate the object around the Z axis.
Definition: areaeffect.cpp:251
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
virtual void Translate(const Vector3 &Trans)
Moves this object from it's current location.
WorldObjectType
Used by various classes to help identify what class an object is.
Definition: enumerations.h:147
virtual void RemoveFromWorld()
Removes the object from the World.
Definition: areaeffect.cpp:153
UInt32 GetNumOverlappingObjects() const
Gets the number of objects currently overlapping with this AE.
Definition: areaeffect.cpp:162
virtual void Scale(const Vector3 &Scale)
Scales the object from it's current size.
virtual Quaternion GetOrientation() const
Gets this objects current orientation.
Definition: areaeffect.cpp:211
virtual void GetProxies(ProxyContainer &Proxies)
Populates a container with all of the WorldProxies being used by this WorldObject.
Definition: areaeffect.cpp:132
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
This file contains the declaration for the World proxy wrapping particle functionality.
void DestroyProxy(CollidableProxy *ToBeDestroyed)
Deletes a CollidableProxy.
This class represents a world for objects to interact within.
Definition: world.h:74
virtual Boole IsInWorld() const
Gets whether or not this object is inside of it's world.
virtual WorldObject * GetParentObject() const
Gets a pointer to the parent object controlling this proxy.
Definition: worldproxy.cpp:75
virtual Vector3 GetLocation() const
Gets this objects current location.
Definition: areaeffect.cpp:196
UInt32 GetNumAddedObjects() const
Gets the number of objects added to this AE since the last update.
Definition: areaeffect.cpp:165
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.
ObjectContainer RemovedObjects
Container of actors that have been removed since last frame.
Definition: areaeffect.h:83
virtual Physics::GhostProxy * GetGhostProxy() const
Gets a pointer to the physics portion of this AreaEffect.
Definition: areaeffect.cpp:120
virtual void SetCollisionGroupAndMask(const Int16 Group, const Int16 Mask)
Set the collision group and mask for the proxy to determine what it should collide with...
virtual void _Update()
Utility function for altering or checking the World Object every frame.
Definition: areaeffect.cpp:343
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.
virtual ~AreaEffect()
Class destructor.
Definition: areaeffect.cpp:84
virtual void SetOrientation(const Quaternion &Ori)
Sets the orientation of this object in parent space.
Definition: areaeffect.cpp:201
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.