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