Spinning Topp Logo BlackTopp Studios
inc
cameracontroller.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 _cameracontroller_cpp
41 #define _cameracontroller_cpp
42 
43 #include "cameracontroller.h"
44 
45 #include "enumerations.h"
46 #include "ray.h"
47 #include "rayquerytool.h"
48 #include "worldmanager.h"
49 #include "worldobject.h"
50 
51 #include "Graphics/cameraproxy.h"
52 #include "MathTools/mathtools.h"
53 
54 namespace Mezzanine
55 {
57  Controlled(NULL),
58  YawLimits(NULL),
59  PitchLimits(NULL),
60  RollLimits(NULL),
61  HoverHeight(2),
62  YawRad(0),
63  PitchRad(0),
64  RollRad(0),
65  CurrentMMode(CCM_Fly)
66  { }
67 
69  Controlled(ToBeControlled),
70  YawLimits(NULL),
71  PitchLimits(NULL),
72  RollLimits(NULL),
73  HoverHeight(2),
74  YawRad(0),
75  PitchRad(0),
76  RollRad(0),
77  CurrentMMode(CCM_Fly)
78  { }
79 
81  {
82  this->RemoveYawLimits();
83  this->RemovePitchLimits();
84  this->RemoveRollLimits();
85  }
86 
88  {
89  Real Pi = MathTools::GetPi();
90  if( Angle > Pi ) {
91  Angle = -Pi + (Angle - Pi);
92  }else if( Angle < -Pi ) {
93  Angle = Pi + (Angle + Pi);
94  }
95  }
96 
98  {
99  if( this->YawLimits ) {
100  if( YawRad > this->YawLimits->Upper )
101  YawRad = this->YawLimits->Upper;
102  if( YawRad < this->YawLimits->Lower )
103  YawRad = this->YawLimits->Lower;
104  }
105  if( this->PitchLimits ) {
106  if( PitchRad > this->PitchLimits->Upper )
107  PitchRad = this->PitchLimits->Upper;
108  if( PitchRad < this->PitchLimits->Lower )
109  PitchRad = this->PitchLimits->Lower;
110  }
111  if( this->YawLimits ) {
112  if( RollRad > this->RollLimits->Upper )
113  RollRad = this->RollLimits->Upper;
114  if( RollRad < this->RollLimits->Lower )
115  RollRad = this->RollLimits->Lower;
116  }
117  }
118 
120  {
121  this->CheckAngleLimits();
122  this->CheckAngleRollover(this->YawRad);
123  this->CheckAngleRollover(this->PitchRad);
124  this->CheckAngleRollover(this->RollRad);
125  }
126 
128  {
129  Vector3 Loc(this->Controlled->GetLocation());
130  Real Dist = this->FindDistanceToGround();
131  if( 0 == Dist )
132  return;
133  Real DeltaDist = Dist - this->HoverHeight;
134  Loc.Y -= DeltaDist;
135  this->Controlled->SetLocation(Loc);
136  }
137 
139  {
140  Vector3 Loc( this->Controlled->GetLocation() );
141  Vector3 Dest( Vector3::Neg_Unit_Y() );
142  Ray GroundRay(Loc,Dest);
143  UInt32 flags = Mezzanine::WO_MeshTerrain | Mezzanine::WO_HeightfieldTerrain | Mezzanine::WO_VectorFieldTerrain | Mezzanine::WO_VoxelTerrain;
144  if( !RayCaster.GetFirstObjectOnRayByPolygon(GroundRay,flags) )
145  { return 0; }
147  return Distance;
148  }
149 
150  ///////////////////////////////////////////////////////////////////////////////
151  // Utility
152 
154  {
155  this->Controlled = ToBeControlled;
156  this->RayCaster.SetWorld( this->Controlled->GetCreator()->GetWorld() );
157  }
158 
160  { return this->Controlled; }
161 
162  ///////////////////////////////////////////////////////////////////////////////
163  // CameraController Properties
164 
166  { this->CurrentMMode = MoveMode; }
167 
169  { return this->CurrentMMode; }
170 
172  { this->HoverHeight = Hover; }
173 
175  { return this->HoverHeight; }
176 
177  void CameraController::SetYawLimits(const Real& UpperLimit, const Real& LowerLimit)
178  {
179  if(!this->YawLimits)
180  this->YawLimits = new AngleLimits();
181  this->YawLimits->Upper = UpperLimit;
182  this->YawLimits->Lower = LowerLimit;
183  }
184 
186  {
187  if(this->YawLimits) {
188  delete this->YawLimits;
189  this->YawLimits = NULL;
190  }
191  }
192 
193  void CameraController::SetPitchLimits(const Real& UpperLimit, const Real& LowerLimit)
194  {
195  if(!this->PitchLimits)
196  this->PitchLimits = new AngleLimits();
197  this->PitchLimits->Upper = UpperLimit;
198  this->PitchLimits->Lower = LowerLimit;
199  }
200 
202  {
203  if(this->PitchLimits) {
204  delete this->PitchLimits;
205  this->PitchLimits = NULL;
206  }
207  }
208 
209  void CameraController::SetRollLimits(const Real& UpperLimit, const Real& LowerLimit)
210  {
211  if(!this->RollLimits)
212  this->RollLimits = new AngleLimits();
213  this->RollLimits->Upper = UpperLimit;
214  this->RollLimits->Lower = LowerLimit;
215  }
216 
218  {
219  if(this->RollLimits) {
220  delete this->RollLimits;
221  this->RollLimits = NULL;
222  }
223  }
224 
225  ///////////////////////////////////////////////////////////////////////////////
226  // Transform Methods
227 
229  {
230  Vector3 Move(0,0,-Units);
231  this->Controlled->MoveRelative(Move);
232  if(CCM_Walk == this->CurrentMMode)
233  this->CheckHeight();
234  }
235 
237  {
238  Vector3 Move(0,0,Units);
239  this->Controlled->MoveRelative(Move);
240  if(CCM_Walk == this->CurrentMMode)
241  this->CheckHeight();
242  }
243 
245  {
246  Vector3 Move(-Units,0,0);
247  this->Controlled->MoveRelative(Move);
248  if(CCM_Walk == CurrentMMode)
249  CheckHeight();
250  }
251 
253  {
254  Vector3 Move(Units,0,0);
255  this->Controlled->MoveRelative(Move);
256  if(CCM_Walk == this->CurrentMMode)
257  this->CheckHeight();
258  }
259 
260  void CameraController::Rotate(Real Yaw, Real Pitch, Real Roll)
261  {
262  this->YawRad += Yaw;
263  this->PitchRad += Pitch;
264  this->RollRad += Roll;
265  this->CheckAllAngles();
266  Quaternion YawQuat, PitchQuat, RollQuat;
267 
268  if(0 == this->YawRad)
269  YawQuat = Quaternion(0,0,0,1);
270  else
271  YawQuat = Quaternion(-YawRad,Vector3::Unit_Y());
272 
273  if(0 == this->PitchRad)
274  PitchQuat = Quaternion(0,0,0,1);
275  else
276  PitchQuat = Quaternion(-PitchRad,Vector3::Unit_X());
277 
278  if(0 == this->RollRad)
279  RollQuat = Quaternion(0,0,0,1);
280  else
281  RollQuat = Quaternion(-RollRad,Vector3::Unit_Z());
282 
283  Quaternion CamRot = YawQuat * PitchQuat * RollQuat;
284  this->Controlled->SetOrientation(CamRot);
285  }
286 
288  {
289  Quaternion CamRot(this->Controlled->GetOrientation());
290  CamRot = CamRot *
291  Quaternion(-Yaw,Vector3::Unit_Y()) *
292  Quaternion(-Pitch,Vector3::Unit_X()) *
293  Quaternion(-Roll,Vector3::Unit_Z());
294  this->Controlled->SetOrientation(CamRot);// */
295  }
296 }
297 
298 #endif
void CheckAllAngles()
Calls CheckAngleLimits() and CheckAngleRollover(Real).
Real Lower
The lower limit for rotation, in radians.
Real FindDistanceToGround()
Performs a raycast to get the distance to any terrain beneath the camera.
virtual void SetOrientation(const Quaternion &Ori)
Sets the orientation of this object in parent space.
virtual Vector3 GetLocation() const
Gets this objects current location.
Real HoverHeight
The height at which the camera is to remain above the terrain.
MovementMode
Possible options for determining how the camera should move relative to the world.
AngleLimits * RollLimits
A pointer to the angle limits for rotations on the Z axis.
Graphics::CameraProxy * GetControlledCamera() const
Gets the camera this controller is controlling.
Real YawRad
The current rotation of the camera on the Y axis.
virtual WorldManager * GetCreator() const
Gets a pointer to this proxies creator.
Any global enumerations shared between multiple classes is to be declared here.
CameraController()
Blank constructor.
Real RollRad
The current rotation of the camera on the Z axis.
void SetControlledCamera(Graphics::CameraProxy *ToBeControlled)
Sets the camera being controlled by this controller.
void SetYawLimits(const Real &UpperLimit, const Real &LowerLimit)
Sets rotational limits on the Y axis.
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
void CheckHeight()
Ensures the camera position is at the desired height above any world terrain.
virtual World * GetWorld() const
Gets the world this manager belongs to.
void MoveBackward(Real Units)
Moves the camera backward.
Real Upper
The upper limit for rotation, in radians.
virtual Vector3 GetLocation() const =0
Gets this objects current location.
virtual Quaternion GetOrientation() const
Gets this objects current orientation.
void CheckAngleRollover(Real Angle)
Wraps an angle value if it goes outside the range of [-pi,+pi].
This file contains the declaration for the World proxy wrapping camera functionality.
void RemoveYawLimits()
Clears any set limits on yaw(Y axis) rotation.
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
void Rotate(Real Yaw, Real Pitch, Real Roll)
Rotates the camera.
MovementMode GetMovementMode() const
Gets the currently set movement mode.
static Vector3 Unit_Y()
Gets a vector representing the Y unit of a Vector3.
Definition: vector3.cpp:134
~CameraController()
Class destructor.
WorldObject * LastQueryResultsObjectPtr() const
It is common to ray query for WorldObjects, if so the results can be retrieved with this...
void RemoveRollLimits()
Clears any set limits on roll(Z axis) rotation.
void StrafeRight(Real Units)
Moves the camera to the right.
MovementMode CurrentMMode
The mode with which the camera should move around the scene.
void SetRollLimits(const Real &UpperLimit, const Real &LowerLimit)
Sets rotational limits on the Z axis.
AngleLimits * YawLimits
A pointer to the angle limits for rotations on the Y axis.
static Vector3 Unit_X()
Gets a vector representing the X unit of a Vector3.
Definition: vector3.cpp:131
This is the proxy class for placing and manipulating a camera in the scene.
Definition: cameraproxy.h:65
CCM_Walk: This forces the camera to be only a certain distance above the terrain. ...
void SetWorld(World *QueryWorld)
Sets the World in which the ray query is to be performed.
void MoveForward(Real Units)
Moves the camera forward.
static Vector3 Unit_Z()
Gets a vector representing the Z unit of a Vector3.
Definition: vector3.cpp:137
void SetPitchLimits(const Real &UpperLimit, const Real &LowerLimit)
Sets rotational limits on the X axis.
Real GetHoverHeight() const
Gets the distance the camera hovers over terrain while in CCM_Walk mode.
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
void SetHoverHeight(const Real &Hover)
Sets the hover distance for the camera while it's moving.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Real PitchRad
The current rotation of the camera on the X axis.
void CheckAngleLimits()
Clamps all current rotation values to their set limits.
void SetMovementMode(const MovementMode &MoveMode)
Sets the movement mode for this camera/controller.
virtual void SetLocation(const Vector3 &Loc)
Sets the location of this object in parent space.
RayQueryTool RayCaster
A ray casting tool used to determine surrounding geometry to limit movement.
Vector3 LastQueryResultsOffset() const
Get an offset from the last query. Depending on the last query, this could be an Offset from a variet...
This is used to store information about rotation in 3d space.
Definition: quaternion.h:68
AngleLimits * PitchLimits
A pointer to the angle limits for rotations on the X axis.
Boundaries for rotation on one axis.
void Rotate6DOF(Real Yaw, Real Pitch, Real Roll)
Rotates the camera.
void RemovePitchLimits()
Clears any set limits on pitch(X axis) rotation.
Boole GetFirstObjectOnRayByPolygon(Ray ObjectRay, Whole ObjectFlags)
This will find the first Object to intesect the Given ray.
virtual void MoveRelative(const Vector3 &ToMove)
Moves the camera through local space.
void StrafeLeft(Real Units)
Moves the camera to the left.
This represents a line placed in 3D space and is used with spacial queries.
Definition: ray.h:67
static Vector3 Neg_Unit_Y()
Gets a vector representing the negative Y unit of a Vector3.
Definition: vector3.cpp:143
Graphics::CameraProxy * Controlled
A pointer to the Camera being controlled.