Spinning Topp Logo BlackTopp Studios
inc
linegroup.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 _LINEGROUP_cpp
41 #define _LINEGROUP_cpp
42 
43 #include "linegroup.h"
44 #include "Graphics/scenemanager.h"
45 #include "entresol.h"
46 #include "world.h"
47 
48 #include <Ogre.h>
49 #include <vector>
50 
51 namespace Mezzanine
52 {
53 
54 ///////////////////////////////////////////////////////////////////////////////
55 // Mezzanine::Internal::Line3D
56 ///////////////////////////////////////
57 
58  //We need to decalare an internal class to make this work.
59  namespace Internal
60  {
61  /// @internal
62  /// @brief A small declaration of what our vertexs look like for when we write to the buffers.
63  struct LineVertex
64  {
65  /// @internal
66  /// @brief Vertex position.
68  /// @internal
69  /// @brief Vertex colour.
71 
72  /// @internal
73  /// @brief Class constructor.
74  /// @param Pos The position to be assigned to this vertex.
75  /// @param Col The colour of this vertex.
76  LineVertex(const Vector3& Pos, const ColourValue& Col)
77  : Position(Pos), Colour(Col) { }
78  /// @internal
79  /// @brief Class destructor.
81  };//LineVertex
82 
83  /// @internal
84  /// @brief Does the bulk of the work that that the Mezzanine::LineGroup performs
85  /// @details Mezzanine::LineGroup is a simple wrapper around this to perform precise
86  /// low level interactions with Ogre, the rendering subsystem. This uses too much stuff
87  /// from ogre to use publicly. so we need to hide it here in the Mezzanine::internal namespace.
88  class Line3D : public Ogre::SimpleRenderable
89  {
90  protected:
91  /// @internal
92  /// @brief Gets how rotated this is currently
93  /// @details Returns a quaternion with the rotation
94  /// @return Is a Ogre::Quaternion which stores the rotation information of this Line3D
95  const Ogre::Quaternion getWorldOrientation(void) const;
96  /// @internal
97  /// @brief Get the position of this Line3d
98  /// @return This returns a Ogre::Vector3 with the Position relative to the world Origin
99  const Ogre::Vector3 getWorldPosition(void) const;
100  /// @internal
101  /// @brief Resizes the Vertex Buffer.
102  /// @note The Vertex Buffer will not shrink, only grow. Passing in a smaller size will do nothing.
103  /// @param RequestedSize The new size for the existing buffer.
104  void ResizeVertexBuffer(const Whole RequestedSize);
105 
106  /// @internal
107  /// @brief This is a vector which stores the point data
108  std::vector<LineVertex> Points;
109  /// @internal
110  /// @brief Internal pointer to the vertex buffer for this object.
111  Ogre::HardwareVertexBufferSharedPtr VertexBuffer;
112  /// @internal
113  /// @brief Pointer to the node that will be used exclusively for this renderable.
114  Ogre::SceneNode* SelfNode;
115  /// @brief Parent World to locate SceneManager
117  public:
118  /// @internal
119  /// @brief Default Constructor
120  Line3D(World * ParentWorld);
121  /// @internal
122  /// @brief Destructor
123  ~Line3D();
124 
125  /// @internal
126  /// @brief This adds a point to the list of what should be rendered.
127  /// @param NewPoint The point to be added.
128  void AddPoint(const Vector3& NewPoint, const ColourValue& Colour);
129  /// @internal
130  /// @brief Access a specific point by index
131  /// @param index The index.
132  /// @details This really does just access the underlying vector.
133  /// @return This Returns the specific Vector3 requested.
134  const Vector3& GetPoint(const Whole Index) const;
135  /// @internal
136  /// @brief How many points are in this Line3D.
137  /// @return This returns the amount of points stored in this class.
138  Whole GetNumPoints() const;
139  /// @internal
140  /// @brief This changes a specific point.
141  /// @details This replaces a point specified by index with a new point.
142  /// @param Index The index of the point to replace.
143  /// @param NewValue A point to replace the existing point with.
144  void UpdatePoint(const Whole Index, const Vector3& NewValue);
145  /// @brief Clears all data pertaining to points in this line group.
146  void ClearPoints();
147 
148  /// @internal
149  /// @brief This adds Two points to the list.
150  /// @param Start The first point to be added.
151  /// @param End The second point to be added.
152  /// @param Colour The colour of the line being added.
153  void DrawLine(const Vector3& Start, const Vector3& End, const ColourValue& Colour);
154  /// @internal
155  /// @brief Updates the internal buffers as necessary for rendering.
156  void DrawLines();
157 
158  /// @internal
159  /// @brief Not Used
160  /// @param Cam Not Used
161  /// @return This returns a Real.
162  Real getSquaredViewDepth(const Ogre::Camera* Cam) const;
163  /// @internal
164  /// @brief How big would a circle need to be to encapsulate this
165  /// @details This returns the radius the a circle would need to have to surround this line group.
166  /// @return This returns a real number which indicates the radius.
167  Real getBoundingRadius(void) const;
168 
169  /// @internal
170  /// @brief Retrieves the scene node that will be used to attach this object to the scenegraph.
171  /// @return Returns a pointer to this LineDatas scenenode.
172  Ogre::SceneNode* GetNode() const;
173  };//Line3D
174 
175  Line3D::Line3D(World * ParentWorldArg)
176  : ParentWorld(ParentWorldArg)
177  {
178  mRenderOp.vertexData = new Ogre::VertexData();
179  this->SelfNode = static_cast<Graphics::SceneManager*>( this->ParentWorld->GetManager(ManagerBase::MT_SceneManager) )->_GetGraphicsWorldPointer()->getRootSceneNode()->createChildSceneNode();
180 
181  // Initialization stuff
182  mRenderOp.indexData = 0;
183  mRenderOp.vertexData->vertexCount = 1024;
184  mRenderOp.vertexData->vertexStart = 0;
185  mRenderOp.operationType = Ogre::RenderOperation::OT_LINE_LIST;
186  mRenderOp.useIndexes = false;
187 
188  Ogre::VertexDeclaration* VDecl = mRenderOp.vertexData->vertexDeclaration;
189  Ogre::VertexBufferBinding* VBind = mRenderOp.vertexData->vertexBufferBinding;
190 
191  size_t Offset = 0;
192  // Position.
193  VDecl->addElement(0,0,Ogre::VET_FLOAT3,Ogre::VES_POSITION);
194  Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
195 
196  // Colour
197  VDecl->addElement(0,Offset,Ogre::VET_FLOAT4,Ogre::VES_DIFFUSE);
198  Offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT4);
199 
200  this->VertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
201  VDecl->getVertexSize(0),
202  mRenderOp.vertexData->vertexCount,
203  Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
204  false);
205 
206  VBind->setBinding(0,this->VertexBuffer);
207 
208  this->setMaterial("BaseWhiteNoLighting");
209  }
210 
212  {
213  static_cast<Graphics::SceneManager*>( this->ParentWorld->GetManager(ManagerBase::MT_SceneManager) )->_GetGraphicsWorldPointer()->destroySceneNode(this->SelfNode);
214  delete mRenderOp.vertexData;
215  }
216 
217  const Ogre::Quaternion Line3D::getWorldOrientation() const
218  { return this->SelfNode->_getDerivedOrientation(); }
219 
220  const Ogre::Vector3 Line3D::getWorldPosition() const
221  { return this->SelfNode->_getDerivedPosition(); }
222 
223  void Line3D::ResizeVertexBuffer(const Whole RequestedSize)
224  {
225  if(RequestedSize > this->VertexBuffer->getNumVertices() ) {
226  // Update only by powers of 2
227  Whole NewVertexBufferSize = 1;
228  while(NewVertexBufferSize < RequestedSize)
229  NewVertexBufferSize <<= 1;
230 
231  this->VertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer(
232  this->mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
233  NewVertexBufferSize,
234  Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
235  false);
236 
237  this->mRenderOp.vertexData->vertexStart = 0;
238  this->mRenderOp.vertexData->vertexBufferBinding->setBinding(0,this->VertexBuffer);
239  }
240  }
241 
242  void Line3D::AddPoint(const Vector3& NewPoint, const ColourValue& Colour)
243  {
244  this->Points.push_back( LineVertex(NewPoint,Colour) );
245  }
246 
247  const Vector3& Line3D::GetPoint(const Whole Index) const
248  {
249  assert(Index < this->Points.size() && "Point index is out of bounds!!");
250 
251  return this->Points[Index].Position;
252  }
253 
255  {
256  return this->Points.size();
257  }
258 
259  void Line3D::UpdatePoint(const Whole Index, const Vector3& NewValue)
260  {
261  assert(Index < this->Points.size() && "Point index is out of bounds!!");
262 
263  this->Points[Index].Position = NewValue;
264  }
265 
267  {
268  this->Points.clear();
269  }
270 
271  void Line3D::DrawLine(const Vector3& Start, const Vector3& End, const ColourValue& Colour)
272  {
273  this->Points.push_back( LineVertex(Start,Colour) );
274  this->Points.push_back( LineVertex(End,Colour) );
275  }
276 
278  {
279  // Drawing stuff
280  Whole NumPoints = this->Points.size();
281  if( NumPoints > 0 ) {
282  this->ResizeVertexBuffer(NumPoints);
283  /*if( mRenderOp.vertexData->vertexCount < NumPoints ) {
284  Whole NewVertexBufferSize = 1;
285  while(NewVertexBufferSize < NumPoints)
286  NewVertexBufferSize <<= 1;
287 
288  this->VertexBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
289  mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
290  NewVertexBufferSize,
291  Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
292  false);
293 
294  mRenderOp.vertexData->vertexStart = 0;
295  mRenderOp.vertexData->vertexBufferBinding->setBinding(0,this->VertexBuffer);
296  }// */
297 
298  Vector3 vaabMin = this->Points[0].Position;
299  Vector3 vaabMax = this->Points[0].Position;
300 
301  Real* prPos = static_cast<Real*>(this->VertexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
302  for( Whole Index = 0 ; Index < NumPoints ; ++Index )
303  {
304  const LineVertex& CurrVertex = this->Points.at(Index);
305 
306  // Position assignment
307  *prPos++ = CurrVertex.Position.X;
308  *prPos++ = CurrVertex.Position.Y;
309  *prPos++ = CurrVertex.Position.Z;
310 
311  // Colour assignment
312  *prPos++ = CurrVertex.Colour.RedChannel;
313  *prPos++ = CurrVertex.Colour.GreenChannel;
314  *prPos++ = CurrVertex.Colour.BlueChannel;
315  *prPos++ = CurrVertex.Colour.AlphaChannel;
316 
317  // Bounds checking
318  if(CurrVertex.Position.X < vaabMin.X)
319  vaabMin.X = CurrVertex.Position.X;
320  if(CurrVertex.Position.Y < vaabMin.Y)
321  vaabMin.Y = CurrVertex.Position.Y;
322  if(CurrVertex.Position.Z < vaabMin.Z)
323  vaabMin.Z = CurrVertex.Position.Z;
324 
325  if(CurrVertex.Position.X > vaabMax.X)
326  vaabMax.X = CurrVertex.Position.X;
327  if(CurrVertex.Position.Y > vaabMax.Y)
328  vaabMax.Y = CurrVertex.Position.Y;
329  if(CurrVertex.Position.Z > vaabMax.Z)
330  vaabMax.Z = CurrVertex.Position.Z;
331  }
332  this->VertexBuffer->unlock();
333  this->mRenderOp.vertexData->vertexCount = NumPoints;
334 
335  mBox.setExtents(vaabMin.GetOgreVector3(), vaabMax.GetOgreVector3());
336  }
337  }
338 
339  Real Line3D::getSquaredViewDepth(const Ogre::Camera* Cam) const
340  {
341  Ogre::Vector3 vMin, vMax, vMid, vDist;
342  vMin = mBox.getMinimum();
343  vMax = mBox.getMaximum();
344  vMid = ((vMin - vMax) * 0.5) + vMin;
345  vDist = Cam->getDerivedPosition() - vMid;
346 
347  return vDist.squaredLength();
348  }
349 
351  { return Ogre::Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength())); }
352 
353  Ogre::SceneNode* Line3D::GetNode() const
354  { return this->SelfNode; }
355  }// /internal
356 
357 
358  ///////////////////////////////////////////////////////////////////////////////
359  // Mezzanine::LineGroup
360 
362  : ParentWorld(ParentWorld)
363  {
364  this->LineData = new Internal::Line3D(this->ParentWorld);
365  }
366 
368  {
369  this->RemoveFromWorld();
370  delete this->LineData;
371  }
372 
373  void LineGroup::AddPoint(const Vector3& NewPoint, const ColourValue& Colour)
374  { this->LineData->AddPoint(NewPoint,Colour); }
375 
376  const Vector3 LineGroup::GetPoint(const Whole Index) const
377  { return Vector3(this->LineData->GetPoint(Index)); }
378 
380  { return this->LineData->GetNumPoints(); }
381 
382  void LineGroup::UpdatePoint(const Whole Index, const Vector3& NewValue)
383  { return this->LineData->UpdatePoint(Index,NewValue); }
384 
386  { this->LineData->ClearPoints(); }
387 
388  void LineGroup::DrawLine(const Vector3& Start, const Vector3& End, const ColourValue& Colour)
389  { this->LineData->DrawLine(Start,End,Colour); }
390 
392  { this->LineData->DrawLines(); }
393 
395  {
396  if( this->LineData->isAttached() == false )
397  this->LineData->GetNode()->attachObject(this->LineData);
398  }
399 
401  {
402  if( this->LineData->isAttached() == true )
403  this->LineData->GetNode()->detachObject(this->LineData);
404  }
405 
407  {
408  return this->LineData->getBoundingRadius();
409  }
410 }
411 
412 #endif
ColourValue Colour
Vertex colour.
Definition: linegroup.cpp:70
void DrawLine(const Vector3 &Start, const Vector3 &End, const ColourValue &Colour)
This adds Two points to the list.
Definition: linegroup.cpp:388
WorldManager * GetManager(const Whole ManagerToGet)
This is will find the manager of a given type.
Definition: world.cpp:324
const Ogre::Quaternion getWorldOrientation(void) const
Gets how rotated this is currently.
Definition: linegroup.cpp:217
This class contains utilities and functions to allow the manipulation of the Graphical scene...
Definition: scenemanager.h:85
Real X
Coordinate on the X vector.
Definition: vector3.h:85
Real Z
Coordinate on the Z vector.
Definition: vector3.h:89
void UpdatePoint(const Whole Index, const Vector3 &NewValue)
This changes a specific point.
Definition: linegroup.cpp:259
Ogre::SceneNode * SelfNode
Pointer to the node that will be used exclusively for this renderable.
Definition: linegroup.cpp:114
void AddToWorld()
Configures this LineGroup to render in the scene.
Definition: linegroup.cpp:394
const Ogre::Vector3 getWorldPosition(void) const
Get the position of this Line3d.
Definition: linegroup.cpp:220
Ogre::SceneNode * GetNode() const
Retrieves the scene node that will be used to attach this object to the scenegraph.
Definition: linegroup.cpp:353
void DrawLines()
Updates the internal buffers as necessary for rendering.
Definition: linegroup.cpp:277
void AddPoint(const Vector3 &NewPoint, const ColourValue &Colour)
This add Either a start pointing, or a line segment to the next point.
Definition: linegroup.cpp:373
Real getBoundingRadius(void) const
How big would a circle need to be to encapsulate this.
Definition: linegroup.cpp:350
void DrawLines()
Updates the render buffers with the needed data to draw the lines in this LineGroup.
Definition: linegroup.cpp:391
This is a simple class for holding 4 reals representing the colour any give object or lightsource can...
Definition: colourvalue.h:64
Whole GetNumPoints() const
How many points are in this Line3D.
Definition: linegroup.cpp:254
~LineGroup()
Default Destructor.
Definition: linegroup.cpp:367
void ClearLines()
Clears all data pertaining to points in this line group.
Definition: linegroup.cpp:385
const Vector3 & GetPoint(const Whole Index) const
Access a specific point by index.
Definition: linegroup.cpp:247
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
void RemoveFromWorld()
Unhooks this LineGroup from the scene, stopping it from rendering.
Definition: linegroup.cpp:400
LineGroup(World *ParentWorld)
Basic Constructor.
Definition: linegroup.cpp:361
Real GreenChannel
Value from 0.0 to 1.0 representing the amount of green present in the colour. 1.0 if very green...
Definition: colourvalue.h:73
const Vector3 GetPoint(const Whole Index) const
Access points by order they were added.
Definition: linegroup.cpp:376
void ClearPoints()
Clears all data pertaining to points in this line group.
Definition: linegroup.cpp:266
Real AlphaChannel
Value from 0.0 to 1.0 representing the transparency of the colours. 1.0 is opaque and 0...
Definition: colourvalue.h:79
void AddPoint(const Vector3 &NewPoint, const ColourValue &Colour)
This adds a point to the list of what should be rendered.
Definition: linegroup.cpp:242
Ogre::Vector3 GetOgreVector3() const
Gets a Ogre vector3.
Definition: vector3.cpp:572
Real Y
Coordinate on the Y vector.
Definition: vector3.h:87
Real GetBoundingRadius() const
How big would a circle need to be to encapsulate this.
Definition: linegroup.cpp:406
~LineVertex()
Class destructor.
Definition: linegroup.cpp:80
Line3D(World *ParentWorld)
Default Constructor.
Definition: linegroup.cpp:175
Real getSquaredViewDepth(const Ogre::Camera *Cam) const
Not Used.
Definition: linegroup.cpp:339
void UpdatePoint(const Whole Index, const Vector3 &NewValue)
This changes a specific point.
Definition: linegroup.cpp:382
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
void ResizeVertexBuffer(const Whole RequestedSize)
Resizes the Vertex Buffer.
Definition: linegroup.cpp:223
Vector3 Position
Vertex position.
Definition: linegroup.cpp:67
World * ParentWorld
Parent World to locate SceneManager.
Definition: linegroup.cpp:116
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
This class represents a world for objects to interact within.
Definition: world.h:74
Real BlueChannel
Value from 0.0 to 1.0 representing the amount of blue present in the colour. 1.0 if very blue...
Definition: colourvalue.h:76
void DrawLine(const Vector3 &Start, const Vector3 &End, const ColourValue &Colour)
This adds Two points to the list.
Definition: linegroup.cpp:271
LineVertex(const Vector3 &Pos, const ColourValue &Col)
Class constructor.
Definition: linegroup.cpp:76
Does the bulk of the work that that the Mezzanine::LineGroup performs.
Definition: linegroup.cpp:88
Real RedChannel
Value from 0.0 to 1.0 representing the amount of red present in the colour. 1.0 if very red...
Definition: colourvalue.h:70
Ogre::HardwareVertexBufferSharedPtr VertexBuffer
Internal pointer to the vertex buffer for this object.
Definition: linegroup.cpp:111
std::vector< LineVertex > Points
This is a vector which stores the point data.
Definition: linegroup.cpp:108
Whole GetNumPoints() const
Get the amount of points used to define Line Segments.
Definition: linegroup.cpp:379
A small declaration of what our vertexs look like for when we write to the buffers.
Definition: linegroup.cpp:63