Spinning Topp Logo BlackTopp Studios
inc
lathe.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 _graphicsprocedurallathe_cpp
68 #define _graphicsprocedurallathe_cpp
69 
70 #include "Graphics/Procedural/Mesh/lathe.h"
71 
72 //#include "Graphics/Procedural/proceduraldatatypes.h"
73 #include "Graphics/Procedural/shape.h"
74 #include "Graphics/Procedural/multishape.h"
75 #include "Graphics/Procedural/triangulator.h"
76 
77 #include "MathTools/constants.h"
78 
79 namespace Mezzanine
80 {
81  namespace Graphics
82  {
83  namespace Procedural
84  {
86  ShapeToLathe(NULL),
87  MultiShapeToLathe(NULL),
88  NumSegments(16),
89  AngleBegin(0),
90  AngleEnd(MathTools::GetTwoPi()),
91  Closed(true),
92  Capped(true)
93  { }
94 
95  Lathe::Lathe(Shape* ToLathe, const Whole Segments) :
96  ShapeToLathe(ToLathe),
97  MultiShapeToLathe(NULL),
98  NumSegments(Segments > 2 ? Segments : 3),
99  AngleBegin(0),
100  AngleEnd(MathTools::GetTwoPi()),
101  Closed(true),
102  Capped(true)
103  { }
104 
105  Lathe::Lathe(MultiShape* ToLathe, const Whole Segments) :
106  ShapeToLathe(NULL),
107  MultiShapeToLathe(ToLathe),
108  NumSegments(Segments > 2 ? Segments : 3),
109  AngleBegin(0),
110  AngleEnd(MathTools::GetTwoPi()),
111  Closed(true),
112  Capped(true)
113  { }
114 
116  { }
117 
119  {
120  IndexContainer Indexes;
121  Point2DContainer Points;
122 
123  Buffer.RebaseOffset();
124 
125  Triangulator Tri;
126  Shape ShapeCopy;
127  MultiShape MultishapeCopy;
128 
129  if( this->ShapeToLathe ) {
130  ShapeCopy = *this->ShapeToLathe;
131  ShapeCopy.Close();
132  Tri.SetShapeToTriangulate(&ShapeCopy);
133  }else{
134  MultishapeCopy = *this->MultiShapeToLathe;
135  MultishapeCopy.Close();
137  }
138  Tri.Triangulate(Indexes,Points);
139  Buffer.EstimateIndexCount(2*Indexes.size());
140  Buffer.EstimateVertexCount(2*Points.size());
141 
142  // begin cap
143  Buffer.RebaseOffset();
144  Quaternion Quat;
146  for( Whole CurrPoint = 0 ; CurrPoint < Points.size() ; ++CurrPoint )
147  {
148  Vector2 Point2D = Points[CurrPoint];
149  Vector3 Point3D(Point2D.X,Point2D.Y,0);
150  Vector3 Normal = Vector3::Unit_Z();
151 
152  this->AddPoint(Buffer, Quat * Point3D, Quat * Normal, Point2D);
153  }
154 
155  for( Whole CurrIndex = 0 ; CurrIndex < Indexes.size() / 3 ; ++CurrIndex )
156  {
157  Buffer.AddIndex( Indexes[CurrIndex*3] );
158  Buffer.AddIndex( Indexes[CurrIndex*3+1] );
159  Buffer.AddIndex( Indexes[CurrIndex*3+2] );
160  }
161  // end cap
162  Buffer.RebaseOffset();
164  for( Whole CurrPoint = 0 ; CurrPoint < Points.size() ; ++CurrPoint )
165  {
166  Vector2 Point2D = Points[CurrPoint];
167  Vector3 Point3D(Point2D.X,Point2D.Y,0);
168  Vector3 Normal = Vector3::Neg_Unit_Z();
169 
170  this->AddPoint(Buffer, Quat * Point3D, Quat * Normal, Point2D);
171  }
172 
173  for( Whole CurrIndex = 0 ; CurrIndex < Indexes.size() / 3 ; ++CurrIndex )
174  {
175  Buffer.AddIndex( Indexes[CurrIndex*3] );
176  Buffer.AddIndex( Indexes[CurrIndex*3+2] );
177  Buffer.AddIndex( Indexes[CurrIndex*3+1] );
178  }
179  }
180 
181  void Lathe::GenerateBody(TriangleBuffer& Buffer, const Shape* ToLathe) const
182  {
183  if( ToLathe == NULL ) {
184  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Invalid shape detected when performing a Lathe.");
185  }
186  Integer NumShapeSegments = ToLathe->GetSegCount();
187  if( this->NumSegments < 3 ) {
188  MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"The number of segments when Lathe'ing a shape cannot be less than 3.");
189  }
190  Integer Offset = 0;
191 
192  //Integer NumLatheSegments = this->Closed ? this->NumSegments + 1 : this->NumSegments;
193  Integer NumLatheSegments = this->NumSegments + 1;
194  Buffer.RebaseOffset();
195  Buffer.EstimateIndexCount( NumLatheSegments * NumShapeSegments * 6 );
196  Buffer.EstimateVertexCount( ( NumShapeSegments + 1 ) * ( NumLatheSegments + 1 ) );
197 
198  Real TempEnd = this->AngleEnd;
199  if( this->AngleBegin > this->AngleEnd ) {
200  TempEnd += MathTools::GetTwoPi();
201  }
202 
203  for( Integer LatheSegIndex = 0 ; LatheSegIndex < NumLatheSegments ; ++LatheSegIndex )
204  {
205  Real Angle = 0;
206  if( this->Closed ) {
207  Angle = LatheSegIndex / static_cast<Real>( this->NumSegments ) * MathTools::GetTwoPi();
208  }else{
209  Angle = this->AngleBegin + LatheSegIndex / static_cast<Real>( this->NumSegments ) * ( TempEnd - this->AngleBegin );
210  }
211  Quaternion Quat;
212  Quat.SetFromAxisAngle(Angle,Vector3::Unit_Y());
213 
214  for( Integer ShapeSegIndex = 0 ; ShapeSegIndex <= NumShapeSegments ; ++ShapeSegIndex )
215  {
216  const Vector2& SegStart = ToLathe->GetPoint(ShapeSegIndex);
217  const Vector2& SegDirection = ToLathe->GetAvgDirection(ShapeSegIndex);
218  Vector2 SegNormal = SegDirection.Perpendicular();
219  Vector3 VertPos(SegStart.X,SegStart.Y,0);
220  Vector3 Normal3D(SegNormal.X,SegNormal.Y,0);
221  Normal3D.Normalize();
222  if( ToLathe->GetOutSide() == Procedural::SS_Right ) {
223  Normal3D = -Normal3D;
224  }
225 
226  this->AddPoint(Buffer, Quat * VertPos, Quat * Normal3D, Vector2( LatheSegIndex / static_cast<Real>( this->NumSegments ), ShapeSegIndex / static_cast<Real>( NumShapeSegments ) ) );
227 
228  if( ShapeSegIndex < NumShapeSegments && LatheSegIndex < NumLatheSegments - 1 ) {
229  if( ToLathe->GetOutSide() == Procedural::SS_Right ) {
230  Buffer.AddTriangle(Offset + NumShapeSegments + 2, Offset, Offset + NumShapeSegments + 1);
231  Buffer.AddTriangle(Offset + NumShapeSegments + 2, Offset + 1, Offset);
232  }else{
233  Buffer.AddTriangle(Offset + NumShapeSegments + 2, Offset + NumShapeSegments + 1, Offset);
234  Buffer.AddTriangle(Offset + NumShapeSegments + 2, Offset, Offset + 1);
235  }
236  }
237  Offset++;
238  }
239  }
240  }
241 
242  ///////////////////////////////////////////////////////////////////////////////
243  // Utility
244 
246  {
247  if( this->ShapeToLathe == NULL && this->MultiShapeToLathe == NULL ) {
248  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"A shape or multishape must be defined in order to perform a lathe.");
249  }
250 
251  // Triangulate the begin and end caps
252  if( !this->Closed && this->Capped ) {
253  this->GenerateCaps(Buffer);
254  }
255 
256  // Extrudes the body
257  if( this->ShapeToLathe ) {
258  this->GenerateBody(Buffer,this->ShapeToLathe);
259  }else{
260  for( Whole Index = 0 ; Index < this->MultiShapeToLathe->GetNumShapes() ; ++Index )
261  {
262  this->GenerateBody(Buffer,&this->MultiShapeToLathe->GetShape(Index));
263  }
264  }
265  }
266 
267  ///////////////////////////////////////////////////////////////////////////////
268  // Configuration
269 
271  {
272  this->ShapeToLathe = ToLathe;
273  this->MultiShapeToLathe = NULL;
274  return *this;
275  }
276 
278  {
279  this->ShapeToLathe = NULL;
280  this->MultiShapeToLathe = ToLathe;
281  return *this;
282  }
283 
285  {
286  if( Segments < 3 ) {
287  MEZZ_EXCEPTION(ExceptionBase::PARAMETERS_EXCEPTION,"The number of segments when Lathe'ing a shape cannot be less than 3.");
288  }
289  this->NumSegments = Segments;
290  return *this;
291  }
292 
294  {
295  this->AngleBegin = Begin;
296  this->Closed = false;
297  return *this;
298  }
299 
301  {
302  this->AngleEnd = End;
303  this->Closed = false;
304  return *this;
305  }
306 
307  Lathe& Lathe::SetClosed(const Boole ShapeClosed)
308  {
309  this->Closed = ShapeClosed;
310  return *this;
311  }
312 
313  Lathe& Lathe::SetCapped(const Boole ShapeCapped)
314  {
315  this->Capped = ShapeCapped;
316  return *this;
317  }
318  }//Procedural
319  }//Graphics
320 }//Mezzanine
321 
322 #endif
323 
Boole Closed
Whether or not the Lathe is configured to rotate a full 360 degrees.
Definition: lathe.h:106
Real AngleBegin
The angle at which the rotation will start.
Definition: lathe.h:100
Vector2 Perpendicular() const
Generates a Vector2 that is perpendicular to this vector.
Definition: vector2.cpp:263
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
const Vector2 & GetPoint(const Integer Index) const
Gets a point by index which can be out of bounds and will wrap.
Definition: shape.cpp:694
virtual ~Lathe()
Class destructor.
Definition: lathe.cpp:115
A convenience buffer that stores vertices and indices of a mesh to be generated.
Procedural::ShapeSide GetOutSide() const
Gets which side is the OutSide of this shape.
Definition: shape.cpp:833
void SetFromAxisAngle(const Real &Angle, const Vector3 &Axis)
Generates and sets the values of this quaternion to describe a rotation from an axis and angle on tha...
Definition: quaternion.cpp:115
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
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
MultiShape & Close()
Closes each shape in this MultiShape.
Definition: multishape.cpp:278
Triangulator & SetShapeToTriangulate(const Shape *TriShape)
Sets shape to triangulate.
void GenerateCaps(TriangleBuffer &Buffer) const
Creates the caps at the ends of the rotated shape.
Definition: lathe.cpp:118
Vector2 GetAvgDirection(const Whole Index) const
Gets the averaged direction from the specified point to both the next and previous points in the sequ...
Definition: shape.cpp:795
Lathe & SetAngleEnd(const Real End)
Sets the endng angle for the rotation.
Definition: lathe.cpp:300
Whole NumSegments
The number of segments to have when rotating the shape to produce the Mesh. Large number of segments ...
Definition: lathe.h:97
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
std::vector< Integer > IndexContainer
A container of Integers used to represent the indicies of a shape.
std::vector< Vector2 > Point2DContainer
Basic container type for the storage of 2D points.
Real Y
Coordinate on the Y vector.
Definition: vector2.h:69
Shape & Close()
Makes this a closed shape, connecting the last point to the first point.
Definition: shape.cpp:623
Lathe & SetMultiShapeToLathe(MultiShape *ToLathe)
Sets the MultiShape to to be Lathe'd.
Definition: lathe.cpp:277
Real X
Coordinate on the X vector.
Definition: vector2.h:67
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
static Vector3 Unit_Y()
Gets a vector representing the Y unit of a Vector3.
Definition: vector3.cpp:134
Vector3 & Normalize()
This will change this point into it's own normal relative to the origin.
Definition: vector3.cpp:352
Whole GetSegCount() const
Gets the number of segments in this shape.
Definition: shape.cpp:472
TriangleBuffer & AddTriangle(const Integer Index1, const Integer Index2, const Integer Index3)
Adds a triangle to the index buffer.
Lathe & SetNumSegments(const Whole Segments)
Sets the number of segments in the rotation to generate. the number of segments is being set to a num...
Definition: lathe.cpp:284
Lathe & SetAngleBegin(const Real Begin)
Sets the starting angle for the rotation.
Definition: lathe.cpp:293
Lathe & SetShapeToLathe(Shape *ToLathe)
Sets the Shape to to be Lathe'd.
Definition: lathe.cpp:270
Lathe & SetClosed(const Boole ShapeClosed)
Sets whether or not the start and end segments should be connected.
Definition: lathe.cpp:307
A generator class that implements the Delaunay Triangulation algorithm.
Definition: triangulator.h:252
Thrown when the available information should have worked but failed for unknown reasons.
Definition: exception.h:113
void AddPoint(TriangleBuffer &Buffer, const Vector3 &Loc, const Vector3 &Norm, const Vector2 &UV) const
Adds a new point to a triangle buffer, using the format defined for that MeshGenerator.
Thrown when parameters are checked at runtime and found invalid.
Definition: exception.h:108
MultiShape * MultiShapeToLathe
A pointer to the MultiShape that will be used to generate a Mesh.
Definition: lathe.h:94
void Triangulate(IndexContainer &Indexes, Point2DContainer &Vertices) const
Executes the Constrained Delaunay Triangulation algorithm. INVALID_STATE_EXCEPTION will be thrown if ...
Whole GetNumShapes() const
Gets the number of shapes in this MultiShape.
Definition: multishape.cpp:317
Lathe & SetCapped(const Boole ShapeCapped)
Sets whether or not the outside ends of the rotated shape should be enclosed.
Definition: lathe.cpp:313
static Vector3 Unit_Z()
Gets a vector representing the Z unit of a Vector3.
Definition: vector3.cpp:137
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
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
Triangulator & SetMultiShapeToTriangulate(const MultiShape *TriMultiShape)
Sets multi shape to triangulate.
virtual void AddToTriangleBuffer(TriangleBuffer &Buffer) const
Adds the vertices and indices as configured in this generator to a triangle buffer.
Definition: lathe.cpp:245
Lathe()
Class constructor.
Definition: lathe.cpp:85
This is used to store information about rotation in 3d space.
Definition: quaternion.h:68
Boole Capped
Whether or not the ends should be capped if the shape isn't rotated a full 360 degrees.
Definition: lathe.h:109
A collection of interconnected 2D points used to express an arbitrary 2D shape.
Definition: shape.h:95
Shape & GetShape(const Whole Index)
Gets a shape by index.
Definition: multishape.cpp:311
Real AngleEnd
The angle at which the rotation will end.
Definition: lathe.h:103
A grouping of individual 2D shapes used to express more elaborate shapes.
Definition: multishape.h:87
Shape * ShapeToLathe
A pointer to the Shape that will be used to generate a Mesh.
Definition: lathe.h:91
static Vector3 Neg_Unit_Z()
Gets a vector representing the negative Z unit of a Vector3.
Definition: vector3.cpp:146
A generator that produces a Mesh by rotating a 2D shape around the Y axis.
Definition: lathe.h:86
void GenerateBody(TriangleBuffer &Buffer, const Shape *ToLathe) const
Creates the main body of the lathe'd shape.
Definition: lathe.cpp:181