Spinning Topp Logo BlackTopp Studios
inc
axisalignedbox.cpp
Go to the documentation of this file.
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 _axisalignedbox_cpp
41 #define _axisalignedbox_cpp
42 
43 /// @file
44 /// @brief This file contains the implementation for the AxisAlignedBox class for representing AABB's of objects in the world.
45 
46 #include "axisalignedbox.h"
47 #include "MathTools/mathtools.h"
48 #include "plane.h"
49 #include "ray.h"
50 #include "exception.h"
51 #include "serialization.h"
52 
53 #include <Ogre.h>
54 
55 #include <algorithm>
56 
57 namespace Mezzanine
58 {
60  { }
61 
63  MinExt(Other.MinExt),
64  MaxExt(Other.MaxExt)
65  { }
66 
68  MinExt(Min),
69  MaxExt(Max)
70  { }
71 
72  AxisAlignedBox::AxisAlignedBox(const Ogre::AxisAlignedBox& InternalAABB)
73  { this->ExtractOgreAABB(InternalAABB); }
74 
76  { }
77 
78  ///////////////////////////////////////////////////////////////////////////////
79  // Utility
80 
82  {
83  return ( this->MinExt.X >= this->MaxExt.X &&
84  this->MinExt.Y >= this->MaxExt.Y &&
85  this->MinExt.Z >= this->MaxExt.Z );
86  }
87 
89  {
90  Vector3 Diff = this->MaxExt - this->MinExt;
91  return ( MathTools::Abs(Diff.X) * MathTools::Abs(Diff.Y) * MathTools::Abs(Diff.Z) );
92  }
93 
95  {
96  Vector3 NewMin = this->MinExt, NewMax = this->MaxExt;
97  NewMin.Ceil(Other.MinExt);
98  NewMax.Floor(Other.MaxExt);
99 
100  if( NewMin.X < NewMax.X && NewMin.Y < NewMax.Y && NewMin.Z < NewMax.Z ) {
101  return AxisAlignedBox(NewMin,NewMax);
102  }else{
103  return AxisAlignedBox();
104  }
105  }
106 
107  void AxisAlignedBox::Expand(const Vector3& Point)
108  {
109  this->MinExt.Floor(Point);
110  this->MaxExt.Ceil(Point);
111  }
112 
114  {
115  this->MinExt.Floor(Other.MinExt);
116  this->MaxExt.Ceil(Other.MaxExt);
117  }
118 
119  Boole AxisAlignedBox::IsInside(const Vector3& ToCheck) const
120  { return MathTools::IsInside(*this,ToCheck); }
121 
123  { return MathTools::Overlap(*this,ToCheck); }
124 
126  { return MathTools::Overlap(*this,ToCheck); }
127 
129  { return MathTools::Overlap(*this,ToCheck); }
130 
132  { return MathTools::Intersects(*this,ToCheck); }
133 
134  ///////////////////////////////////////////////////////////////////////////////
135  // Extents query
136 
137  void AxisAlignedBox::SetExtents(const Vector3& Min, const Vector3& Max)
138  { this->MinExt = Min; this->MaxExt = Max; }
139 
141  { return ( this->MaxExt - this->MinExt ); }
142 
144  { return ( this->GetSize() * 0.5 ); }
145 
147  { return ( this->MaxExt + this->MinExt ) * 0.5; }
148 
150  {
151  return Vector3( ( XEx == AE_Min ? this->MinExt.X : this->MaxExt.X ),
152  ( YEx == AE_Min ? this->MinExt.Y : this->MaxExt.Y ),
153  ( ZEx == AE_Min ? this->MinExt.Z : this->MaxExt.Z ) );
154  }
155 
156  Real AxisAlignedBox::GetSideExtent(AxisAlignedBox::Side WhichSideExtent) const
157  {
158  switch(WhichSideExtent)
159  {
160  case SideMinX: return this->MinExt.X;
161  case SideMinY: return this->MinExt.Y;
162  case SideMinZ: return this->MinExt.Z;
163  case SideMaxX: return this->MaxExt.X;
164  case SideMaxY: return this->MaxExt.Y;
165  case SideMaxZ: return this->MaxExt.Z;
166  }
167  }
168 
170  {
171  Real Extent = GetSideExtent(WhichSidePlane); /// @todo This plane stuff is farfrom optimal,
172  Real SideMultiplier = (Extent>=0) ? 1 : -1;
173  switch(WhichSidePlane)
174  {
175  case SideMinX: case SideMaxX: return Plane(Vector3::Unit_X()*SideMultiplier, Extent);
176  case SideMinY: case SideMaxY: return Plane(Vector3::Unit_Y()*SideMultiplier, Extent);
177  case SideMinZ: case SideMaxZ: return Plane(Vector3::Unit_Z()*SideMultiplier, Extent);
178  }
179 
180  }
181 
182  ///////////////////////////////////////////////////////////////////////////////
183  // Conversion Methods
184 
185  void AxisAlignedBox::ExtractOgreAABB(const Ogre::AxisAlignedBox& InternalAABB)
186  { this->MinExt.ExtractOgreVector3( InternalAABB.getMinimum() ); this->MaxExt.ExtractOgreVector3( InternalAABB.getMaximum() ); }
187 
188  Ogre::AxisAlignedBox AxisAlignedBox::GetOgreAABB() const
189  { return Ogre::AxisAlignedBox(this->MinExt.GetOgreVector3(),this->MaxExt.GetOgreVector3()); }
190 
191  ///////////////////////////////////////////////////////////////////////////////
192  // Serialization
193 
195  {
196  XML::Node SelfRoot = ParentNode.AppendChild( AxisAlignedBox::GetSerializableName() );
197 
198  if( SelfRoot.AppendAttribute("Version").SetValue("1") )
199  {
200  XML::Node MinimumNode = SelfRoot.AppendChild("MinExt");
201  this->MinExt.ProtoSerialize( MinimumNode );
202 
203  XML::Node MaximumNode = SelfRoot.AppendChild("MaxExt");
204  this->MaxExt.ProtoSerialize( MaximumNode );
205 
206  return;
207  }else{
208  SerializeError("Create XML Attribute Values",AxisAlignedBox::GetSerializableName(),true);
209  }
210  }
211 
213  {
214  if( String(SelfRoot.Name()) == AxisAlignedBox::GetSerializableName() ) {
215  if(SelfRoot.GetAttribute("Version").AsInt() == 1) {
216  // Get the properties that need their own nodes
217  XML::Node MinimumNode = SelfRoot.GetChild("MinExt").GetFirstChild();
218  if( !MinimumNode.Empty() )
219  this->MinExt.ProtoDeSerialize(MinimumNode);
220 
221  XML::Node MaximumNode = SelfRoot.GetChild("MaxExt").GetFirstChild();
222  if( !MaximumNode.Empty() )
223  this->MaxExt.ProtoDeSerialize(MaximumNode);
224  }else{
225  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + AxisAlignedBox::GetSerializableName() + ": Not Version 1.");
226  }
227  }else{
228  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,AxisAlignedBox::GetSerializableName() + " was not found in the provided XML node, which was expected.");
229  }
230  }
231 
233  {
234  return "AxisAlignedBox";
235  }
236 
237  ///////////////////////////////////////////////////////////////////////////////
238  // Operators
239 
241  { this->MinExt = Other.MinExt; this->MaxExt = Other.MaxExt; }
242 
243  void AxisAlignedBox::operator=(const Ogre::AxisAlignedBox& InternalAABB)
244  { this->ExtractOgreAABB(InternalAABB); }
245 
247  { return ( this->GetVolume() > Other.GetVolume() ); }
248 
250  { return ( this->GetVolume() < Other.GetVolume() ); }
251 
253  { return ( this->GetVolume() >= Other.GetVolume() ); }
254 
256  { return ( this->GetVolume() <= Other.GetVolume() ); }
257 
259  { return ( this->MinExt == Other.MinExt && this->MaxExt == Other.MaxExt ); }
260 
262  { return ( this->MinExt != Other.MinExt || this->MaxExt != Other.MaxExt ); }
263 }//Mezzanine
264 
265 #endif
This is a generic sphere class used for spacial queries.
Definition: sphere.h:62
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
AxisExtent
This enum is used to help make querys for data on the AABB.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
Boole IsInside(const Vector3 &ToCheck) const
Checks to see if a point is inside this AABB.
Ogre::AxisAlignedBox GetOgreAABB() const
Gets an Ogre::AxisAlignedBox that contains this Spheres information.
Real X
Coordinate on the X vector.
Definition: vector3.h:85
Real Z
Coordinate on the Z vector.
Definition: vector3.h:89
~AxisAlignedBox()
Class destructor.
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
Boole IsZero() const
Gets whether or not this AABB has no size.
void ProtoDeSerialize(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite this object with it.
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
Boole IsOverlapping(const Sphere &ToCheck) const
Checks to see if a sphere overlaps with this AABB.
Side
Used to uniquely identify sides of an axis aligned box.
bool Empty() const
Is this storing anything at all?
This is used to represent a flat infinite slice of the game world.
Definition: plane.h:65
This implements the exception hiearchy for Mezzanine.
void Expand(const Vector3 &Point)
Expands the size of this AABB to encompass it's current bounds plus a point in 3D space...
Vector3 GetCorner(const AxisExtent XEx, const AxisExtent YEx, const AxisExtent ZEx) const
Gets the location of the specified corner.
This file contains the AxisAlignedBox class for representing AABB's of objects in the world...
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.
Vector3 & Floor(const Vector3 &Other)
Sets each member of this Vector3 to the lower value between the two vector3s.
Definition: vector3.cpp:544
Boole operator<=(const AxisAlignedBox &Other) const
Less-than or equals-to operator.
Plane GetSidePlane(Side WhichSidePlane) const
Get a plane corresponding to a side of the box.
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
static Vector3 Unit_Y()
Gets a vector representing the Y unit of a Vector3.
Definition: vector3.cpp:134
Vector3 & Ceil(const Vector3 &Other)
Sets each member of this Vector3 to the higher value between the two vector3s.
Definition: vector3.cpp:536
void ExtractOgreVector3(const Ogre::Vector3 &temp)
Copies an existing Ogre vector3.
Definition: vector3.cpp:581
Ogre::Vector3 GetOgreVector3() const
Gets a Ogre vector3.
Definition: vector3.cpp:572
Real Y
Coordinate on the Y vector.
Definition: vector3.h:87
AxisAlignedBox()
Blank constructor.
static String GetSerializableName()
Get the name of the the XML tag this class will leave behind as its instances are serialized...
Boole operator>=(const AxisAlignedBox &Other) const
Less-than operator.
Real GetVolume() const
Gets the total volume of this AABB.
void SetExtents(const Vector3 &Min, const Vector3 &Max)
Sets the minimum and maximum extents of this AABB.
static Vector3 Unit_X()
Gets a vector representing the X unit of a Vector3.
Definition: vector3.cpp:131
Boole operator!=(const AxisAlignedBox &Other) const
Inequality operator.
void ProtoDeSerialize(const XML::Node &OneNode)
Take the data stored in an XML and overwrite this instance of this object with it.
Definition: vector3.cpp:614
Vector3 GetHalfSize() const
Gets half the size of this AABB.
static Vector3 Unit_Z()
Gets a vector representing the Z unit of a Vector3.
Definition: vector3.cpp:137
AxisAlignedBox GetOverlap(const AxisAlignedBox &Other) const
Gets an AABB that has the dimensions of the overlap between this AABB and another AABB...
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
Vector3 MinExt
The minimum extents on each axis in world space.
Vector3 GetCenter() const
Gets the center of this AABB.
Boole operator==(const AxisAlignedBox &Other) const
Equality operator.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
std::pair< Boole, Ray > RayTestResult
This is a type used for the return of a ray intersection test.
void ExtractOgreAABB(const Ogre::AxisAlignedBox &InternalAABB)
Changes this AxisAlignedBox to match the Ogre AxisAlignedBox.
void operator=(const AxisAlignedBox &Other)
Assignment operator.
Boole operator<(const AxisAlignedBox &Other) const
Greater-than or equals-to operator.
const Char8 * Name() const
ptrdiff_tGet the name of this Node.
Boole operator>(const AxisAlignedBox &Other) const
Greater-than operator.
void SerializeError(const String &FailedTo, const String &ClassName, Boole SOrD)
Simply does some string concatenation, then throws an Exception.
RayTestResult Intersects(const Ray &ToCheck) const
Checks to see if a ray intersects this AABB.
Node AppendChild(NodeType Type=NodeElement)
Creates a Node and makes it a child of this one.
void ProtoSerialize(XML::Node &ParentNode) const
Convert this class to an XML::Node ready for serialization.
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.
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
Definition: vector3.cpp:588
Vector3 MaxExt
The maximum extents on each axis in world space.
This represents a line placed in 3D space and is used with spacial queries.
Definition: ray.h:67
Vector3 GetSize() const
Gets the size of this AABB.
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.
This is a utility class used to represent the Axis-Aligned Bounding Boxes of objects in various subsy...