Spinning Topp Logo BlackTopp Studios
inc
trianglebuffer.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 /*
41  -----------------------------------------------------------------------------
42  This source file is part of ogre-procedural
43 
44  For the latest info, see http://code.google.com/p/ogre-procedural/
45 
46  Copyright (c) 2010-2013 Michael Broutin
47 
48  Permission is hereby granted, free of charge, to any person obtaining a copy
49  of this software and associated documentation files (the "Software"), to deal
50  in the Software without restriction, including without limitation the rights
51  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
52  copies of the Software, and to permit persons to whom the Software is
53  furnished to do so, subject to the following conditions:
54 
55  The above copyright notice and this permission notice shall be included in
56  all copies or substantial portions of the Software.
57 
58  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64  THE SOFTWARE.
65  -----------------------------------------------------------------------------
66  */
67 #ifndef _graphicsproceduraltrianglebuffer_cpp
68 #define _graphicsproceduraltrianglebuffer_cpp
69 
70 #include "Graphics/Procedural/Mesh/trianglebuffer.h"
71 
72 #include "Graphics/meshmanager.h"
73 
74 #include "Ogre.h"
75 
76 namespace Mezzanine
77 {
78  namespace Graphics
79  {
80  namespace Procedural
81  {
83  CurrentVertex(NULL),
84  EstimatedVertexCount(0),
85  EstimatedIndexCount(0),
86  GlobalOffset(0)
87  { }
88 
90  { }
91 
92  ///////////////////////////////////////////////////////////////////////////////
93  // Utility
94 
96  {
97  this->RebaseOffset();
98  for( ConstIndexIterator IndIt = Other.Indices.begin() ; IndIt != Other.Indices.end() ; ++IndIt )
99  { this->Indices.push_back( this->GlobalOffset + (*IndIt) ); }
100 
101  for( ConstVertexIterator VertIt = Other.Vertices.begin() ; VertIt != Other.Vertices.end() ; ++VertIt )
102  { this->Vertices.push_back( *VertIt ); }
103  }
104 
105  void TriangleBuffer::AppendBufferAsSection(const TriangleBuffer& Other, const String& MatName, const String& MatGroup, const Whole RenderOp)
106  {
107  this->BeginSection(MatName,MatGroup,RenderOp);
108  this->AppendBuffer(Other);
109  this->EndSection();
110  }
111 
112  Mesh* TriangleBuffer::GenerateMesh(const String& MeshName, const String& MeshGroup, const String& MatName, const String& MatGroup) const
113  {
114  Ogre::ManualObject* TempMan = new Ogre::ManualObject("TempMan");
115 
116  #if OGRE_VERSION >= ((2 << 16) | (0 << 8) | 0)
117  Ogre::Vector3 aabb_min = Ogre::Vector3::ZERO;
118  Ogre::Vector3 aabb_max = Ogre::Vector3::ZERO;
119  #endif
120  if( this->IsUsingSections() ) {
121  for( ConstSectionIterator SectIt = this->Sections.begin() ; SectIt != this->Sections.end() ; ++SectIt )
122  {
123  TempMan->begin( (*SectIt).MaterialName, Ogre::RenderOperation::OT_TRIANGLE_LIST, (*SectIt).MaterialGroup );
124  const ConstVertexIterator VertEndIt = this->Vertices.begin() + (*SectIt).LastVertex;
125  for( ConstVertexIterator VertIt = this->Vertices.begin() + (*SectIt).FirstVertex ; VertIt != VertEndIt ; ++VertIt )
126  {
127  TempMan->position( VertIt->Position.GetOgreVector3() );
128  TempMan->textureCoord( VertIt->UV.GetOgreVector2() );
129  TempMan->normal( VertIt->Normal.GetOgreVector3() );
130  #if OGRE_VERSION >= ((2 << 16) | (0 << 8) | 0)
131  if( VertIt->Position.X < aabb_min.X ) aabb_min.X = it->Position.X;
132  if( VertIt->Position.Y < aabb_min.Y ) aabb_min.Y = it->Position.Y;
133  if( VertIt->Position.Z < aabb_min.Z ) aabb_min.Z = it->Position.Z;
134  if( VertIt->Position.X > aabb_max.X ) aabb_max.X = it->Position.X;
135  if( VertIt->Position.Y > aabb_max.Y ) aabb_max.Y = it->Position.Y;
136  if( VertIt->Position.Z > aabb_max.Z ) aabb_max.z = it->Position.Z;
137  #endif
138  }
139  const ConstIndexIterator IndicEndIt = this->Indices.begin() + (*SectIt).LastIndex;
140  for( ConstIndexIterator IndicIt = this->Indices.begin() + (*SectIt).FirstIndex ; IndicIt != IndicEndIt ; ++IndicIt )
141  { TempMan->index( *IndicIt ); }
142  TempMan->end();
143  }
144  }else{
145  TempMan->begin(MatName,Ogre::RenderOperation::OT_TRIANGLE_LIST,MatGroup);
146  for( ConstVertexIterator VertIt = this->Vertices.begin() ; VertIt != this->Vertices.end() ; ++VertIt )
147  {
148  TempMan->position( VertIt->Position.GetOgreVector3() );
149  TempMan->textureCoord( VertIt->UV.GetOgreVector2() );
150  TempMan->normal( VertIt->Normal.GetOgreVector3() );
151  #if OGRE_VERSION >= ((2 << 16) | (0 << 8) | 0)
152  if( VertIt->Position.X < aabb_min.X ) aabb_min.X = it->Position.X;
153  if( VertIt->Position.Y < aabb_min.Y ) aabb_min.Y = it->Position.Y;
154  if( VertIt->Position.Z < aabb_min.Z ) aabb_min.Z = it->Position.Z;
155  if( VertIt->Position.X > aabb_max.X ) aabb_max.X = it->Position.X;
156  if( VertIt->Position.Y > aabb_max.Y ) aabb_max.Y = it->Position.Y;
157  if( VertIt->Position.Z > aabb_max.Z ) aabb_max.z = it->Position.Z;
158  #endif
159  }
160  for( ConstIndexIterator IndIt = this->Indices.begin() ; IndIt != this->Indices.end() ; ++IndIt )
161  { TempMan->index( *IndIt ); }
162  TempMan->end();
163  }
164  #if OGRE_VERSION >= ((2 << 16) | (0 << 8) | 0)
165  TempMan->setLocalAabb( Ogre::Aabb::newFromExtents(aabb_min,aabb_max) );
166  #endif
167  Mesh* NewMesh = MeshManager::GetSingletonPtr()->_WrapInternalMesh( TempMan->convertToMesh(MeshName,MeshGroup) );
168  delete TempMan;
169  return NewMesh;
170  }
171 
173  {
174  this->EstimatedVertexCount += VertexCount;
175  this->Vertices.reserve( this->EstimatedVertexCount );
176  }
177 
179  {
180  this->EstimatedIndexCount += IndexCount;
181  this->Indices.reserve( this->EstimatedIndexCount );
182  }
183 
185  { this->GlobalOffset = Vertices.size(); }
186 
188  { return this->Sections; }
189 
191  { return this->Sections; }
192 
194  { return this->Vertices; }
195 
197  { return this->Vertices; }
198 
200  { return this->Indices; }
201 
203  { return this->Indices; }
204 
205  ///////////////////////////////////////////////////////////////////////////////
206  // Section Utility
207 
208  void TriangleBuffer::BeginSection(const String& MatName, const String& MatGroup, const Whole RenderOp)
209  {
210  // Close any sections we may be working on.
211  this->EndSection();
212  // If this check succeeds then we have no sections and are starting a new one with data that needs to be in a section.
213  if( this->Sections.empty() && !this->Vertices.empty() ) {
214  this->CurrentSection.FirstIndex = 0;
215  this->CurrentSection.FirstVertex = 0;
217  this->CurrentSection.LastIndex = this->Indices.size() - 1;
218  this->CurrentSection.LastVertex = this->Vertices.size() - 1;
219 
220  this->Sections.push_back( this->CurrentSection );
221  this->CurrentSection.Clear();
222  }
223 
224  this->RebaseOffset();
225  this->CurrentSection.FirstIndex = this->Indices.size();
226  this->CurrentSection.FirstVertex = this->Vertices.size();
227  this->CurrentSection.RenderOp = RenderOp;
228  this->CurrentSection.MaterialName = MatName;
229  this->CurrentSection.MaterialGroup = MatGroup;
230  }
231 
233  {
234  if( this->IsWorkingOnSection() ) {
235  this->CurrentSection.LastIndex = this->Indices.size() - 1;
236  this->CurrentSection.LastVertex = this->Vertices.size() - 1;
237 
238  this->Sections.push_back( this->CurrentSection );
239  this->CurrentSection.Clear();
240  }
241  }
242 
244  { return ( !this->Sections.empty() || this->IsWorkingOnSection() ); }
245 
247  { return ( this->CurrentSection.FirstVertex != 0 && this->CurrentSection.FirstIndex != 0 ); }
248 
249  ///////////////////////////////////////////////////////////////////////////////
250  // Vertex Management
251 
253  {
254  this->Vertices.push_back(Vert);
255  this->CurrentVertex = &this->Vertices.back();
256  return *this;
257  }
258 
259  TriangleBuffer& TriangleBuffer::AddVertex(const Vector3& Loc, const Vector3& Norm, const Vector2& UV)
260  {
261  Vertex Vert;
262  Vert.Position = Loc;
263  Vert.Normal = Norm;
264  Vert.UV = UV;
265  this->Vertices.push_back(Vert);
266  this->CurrentVertex = &this->Vertices.back();
267  return *this;
268  }
269 
271  {
272  Vertex Vert;
273  Vert.Position = Loc;
274  this->Vertices.push_back(Vert);
275  this->CurrentVertex = &this->Vertices.back();
276  return *this;
277  }
278 
280  {
281  Vertex Vert;
282  Vert.Position.SetValues(X,Y,Z);
283  this->Vertices.push_back(Vert);
284  this->CurrentVertex = &this->Vertices.back();
285  return *this;
286  }
287 
289  {
290  this->CurrentVertex->Normal = Norm;
291  return *this;
292  }
293 
295  {
296  this->CurrentVertex->UV.SetValues(U,V);
297  return *this;
298  }
299 
301  {
302  this->CurrentVertex->UV = UV;
303  return *this;
304  }
305 
307  {
308  for( VertexIterator VertIt = this->Vertices.begin() ; VertIt != this->Vertices.end() ; ++VertIt )
309  {
310  VertIt->Position = Mat * VertIt->Position;
311  VertIt->Normal = Mat * VertIt->Normal;
312  VertIt->Normal.Normalize();
313  }
314  return *this;
315  }
316 
318  {
319  for( VertexIterator VertIt = this->Vertices.begin() ; VertIt != this->Vertices.end() ; ++VertIt )
320  {
321  VertIt->Position = VertIt->Position + Trans;
322  }
323  return *this;
324  }
325 
327  {
328  return this->TranslateVertices( Vector3(X,Y,Z) );
329  }
330 
332  {
333  for( VertexIterator VertIt = this->Vertices.begin() ; VertIt != this->Vertices.end() ; ++VertIt )
334  {
335  VertIt->Position = Rot * VertIt->Position;
336  VertIt->Normal = Rot * VertIt->Normal;
337  VertIt->Normal.Normalize();
338  }
339  return *this;
340  }
341 
343  {
344  for( VertexIterator VertIt = this->Vertices.begin() ; VertIt != this->Vertices.end() ; ++VertIt )
345  {
346  VertIt->Position = Scale * VertIt->Position;
347  }
348  return *this;
349  }
350 
352  {
353  return this->ScaleVertices( Vector3(X,Y,Z) );
354  }
355 
357  {
358  for( VertexIterator VertIt = this->Vertices.begin() ; VertIt != this->Vertices.end() ; ++VertIt )
359  {
360  VertIt->Normal = -(VertIt->Normal);
361  }
362  for( Whole Index = 0 ; Index < this->Indices.size() ; ++Index )
363  {
364  if( Index % 3 == 1 ) {
365  std::swap(this->Indices[Index],this->Indices[Index - 1]);
366  }
367  }
368  return *this;
369  }
370 
371  ///////////////////////////////////////////////////////////////////////////////
372  // Index Management
373 
375  {
376  this->Indices.push_back( this->GlobalOffset + Index );
377  return *this;
378  }
379 
380  TriangleBuffer& TriangleBuffer::AddTriangle(const Integer Index1, const Integer Index2, const Integer Index3)
381  {
382  this->Indices.push_back( this->GlobalOffset + Index1 );
383  this->Indices.push_back( this->GlobalOffset + Index2 );
384  this->Indices.push_back( this->GlobalOffset + Index3 );
385  return *this;
386  }
387  }//Procedural
388  }//Graphics
389 }//Mezzanine
390 
391 #endif
IndexContainer::const_iterator ConstIndexIterator
Const Iterator type for a IndexContainer.
std::vector< Vertex > VertexContainer
Basic container type for Vertex storage.
IndexContainer & GetIndices()
Gets a modifiable reference to Indices.
Whole LastIndex
The end indicy of this section in the parent buffer.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
IndexContainer Indices
Container storing all of the Indices in this buffer.
VertexContainer::iterator VertexIterator
Iterator type for Vertex instances in a VertexContainer.
BufferSection CurrentSection
Temporary storage for the current section being worked on.
A convenience buffer that stores vertices and indices of a mesh to be generated.
TriangleBuffer & SetTextureCoord(const Real U, const Real V)
Sets the texture coordinates of the current vertex.
This class is used to check and modify the properties of a graphics mesh.
Definition: mesh.h:63
TriangleBuffer & RotateVertices(const Quaternion &Rot)
Applies the rotation immediately to all the points contained in this triangle buffer.
TriangleBuffer & ApplyTransform(const Matrix4x4 &Mat)
Applies a matrix to transform all vertices inside this triangle buffer.
void EstimateIndexCount(const Whole IndexCount)
Gives an estimation of the number of indices needed for this triangle buffer.
int Integer
A datatype used to represent any integer close to.
Definition: datatypes.h:154
A simple definition for a Vertex to be used when procedurally generating meshes.
void AppendBuffer(const TriangleBuffer &Other)
Appends the contents of another buffer to this buffer.
A 4x4 matrix math class for the representation of full transforms.
Definition: matrix4x4.h:59
TriangleBuffer & SetNormal(const Vector3 &Norm)
Sets the normal of the current vertex.
Integer EstimatedIndexCount
The user estimated Index count for this buffer.
Mesh * GenerateMesh(const String &MeshName, const String &MeshGroup, const String &MatName="", const String &MatGroup="") const
Builds a Mesh from this buffer.
Quaternion & Normalize()
Normalizes this Quaternion.
Definition: quaternion.cpp:218
void AppendBufferAsSection(const TriangleBuffer &Other, const String &MatName="", const String &MatGroup="", const Whole RenderOp=Graphics::RO_TriangleList)
Appends the contents of another buffer to this buffer as a separate section of the Mesh...
String MaterialGroup
The asset group where the material can be found.
VertexContainer & GetVertices()
Gets a modifiable reference to Vertices.
Whole LastVertex
The end vertex of this section in the parent buffer.
Vector3 Position
The position of the vertex in local space.
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
void Clear()
Clears all the data on this BufferSection back to a blank initialization.
Integer EstimatedVertexCount
The user estimated Vertex count for this buffer.
void BeginSection(const String &MatName="", const String &MatGroup="", const Whole RenderOp=Graphics::RO_TriangleList)
Gets a BufferSection that can be appended to the end of this buffer.
std::vector< BufferSection > SectionContainer
Basic container type for Section storage in this class.
std::vector< Integer > IndexContainer
A container of Integers used to represent the indicies of a shape.
VertexContainer Vertices
Container storing all of the Vertices in this buffer.
Vector2 UV
The UV coordinate for applying textures.
Whole FirstIndex
The start indicy of this section in the parent buffer.
String MaterialName
The name of the material to be used with this section.
static MeshManager * GetSingletonPtr()
Fetches a pointer to the singleton.
Definition: singleton.h:97
SectionContainer::const_iterator ConstSectionIterator
Const Iterator type for Section instances stored in this class.
TriangleBuffer & TranslateVertices(const Vector3 &Trans)
Applies the translation immediately to all the points contained in this triangle buffer.
void EstimateVertexCount(const Whole VertexCount)
Gives an estimation of the number of vertices need for this triangle buffer.
This is used to represent a point on a 2 dimentional area, such as a screen.
Definition: vector2.h:63
SectionContainer & GetSections()
Gets a modifiable reference to Sections.
TriangleBuffer & AddTriangle(const Integer Index1, const Integer Index2, const Integer Index3)
Adds a triangle to the index buffer.
Boole IsWorkingOnSection() const
Gets whether or not a section has been started and not yet closed.
void SetValues(const Real &x, const Real &y)
Sets the X and Y values of this vector2.
Definition: vector2.cpp:105
void SetValues(const Real &X, const Real &Y, const Real &Z)
Manually sets all the members of this vector3.
Definition: vector3.cpp:524
void EndSection()
Sets a BufferSection as the end section of this buffer.
Vertex * CurrentVertex
Convenience pointer to the Vertex currently being manipulated.
Integer GlobalOffset
Offset used to set where buffer/mesh appends begin.
Whole RenderOp
The render operation to be used for the section. See Graphics::RenderOperation enum for more info...
Boole IsUsingSections() const
Gets whether or not this buffer is divided into sections.
TriangleBuffer & ScaleVertices(const Vector3 &Scale)
Applies an immediate scale operation to this triangle buffer.
TriangleBuffer & AddIndex(const Integer Index)
Adds an index to the index buffer.
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
VertexContainer::const_iterator ConstVertexIterator
Const Iterator type for Vertex instances in a VertexContainer.
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
Vector3 Normal
The facing direction of the vertex in local space.
TriangleBuffer & InvertNormals()
Applies normal inversion on this triangle buffer.
This is used to store information about rotation in 3d space.
Definition: quaternion.h:68
SectionContainer Sections
Container storing all of the sections of this buffer.
Whole FirstVertex
The start vertex of this section in the parent buffer.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
Vertices form triangles. Each triangle has it's own distinct set of Vertices. Vertices are not expect...
TriangleBuffer & AddVertex(const Vertex &Vert)
Adds a premade Vertex to the buffer.