Spinning Topp Logo BlackTopp Studios
inc
submesh.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 #ifndef _graphicssubmesh_cpp
42 #define _graphicssubmesh_cpp
43 
44 #include "Graphics/submesh.h"
45 
46 #include <Ogre.h>
47 
48 namespace Mezzanine
49 {
50  namespace Graphics
51  {
52  SubMesh::SubMesh(Ogre::SubMesh* Internal) :
53  InternalSubMesh(Internal)
54  { }
55 
57  {
58  // Let Ogre Manage submeshes on it's own.
59  }
60 
61  ///////////////////////////////////////////////////////////////////////////////
62  // Utility Methods
63 
64  void SubMesh::SetMaterialName(const String& MatName)
65  { this->InternalSubMesh->setMaterialName(MatName); }
66 
68  { return this->InternalSubMesh->getMaterialName(); }
69 
71  { return this->InternalSubMesh->useSharedVertices; }
72 
74  {
75  Ogre::VertexData* VertData = ( this->InternalSubMesh->useSharedVertices ? this->InternalSubMesh->parent->sharedVertexData : this->InternalSubMesh->vertexData );
76  return VertData->vertexCount;
77  }
78 
80  {
81  return this->InternalSubMesh->indexData->indexCount;
82  }
83 
84  ///////////////////////////////////////////////////////////////////////////////
85  // SubMesh Information Methods
86 
87  void SubMesh::GetInfo(MeshInfo& ToFill) const
88  {
89  // Get the simple stuff first
90  Ogre::RenderOperation Render;
91  this->InternalSubMesh->_getRenderOperation(Render);
92  ToFill.OperationType = Render.operationType;
93 
94  ToFill.MaterialName = this->InternalSubMesh->getMaterialName();
95 
96  /// @todo Should probably be replaced with something that calls our material manager.
97  Ogre::MaterialManager* MatMan = Ogre::MaterialManager::getSingletonPtr();
98  if( MatMan != NULL ) {
99  Ogre::ResourcePtr Mat = MatMan->getByName( this->InternalSubMesh->getMaterialName() );
100  ToFill.MaterialGroup = Mat->getOrigin();
101  }
102 
103  this->AppendVertexInfo(ToFill.Vertices);
104  }
105 
107  {
108  Ogre::VertexData* VertData = ( this->InternalSubMesh->useSharedVertices ? this->InternalSubMesh->parent->sharedVertexData : this->InternalSubMesh->vertexData );
109  ToFill.VertexCount += VertData->vertexCount;
110  ToFill.IndexCount += this->InternalSubMesh->indexData->indexCount;
111 
112  this->AppendVertexPositionInfo(ToFill.Positions);
113  this->AppendVertexNormalInfo(ToFill.Normals);
114  this->AppendVertexTexCoordInfo(ToFill.UVs);
115  this->AppendVertexTangentInfo(ToFill.Tangents);
116  this->AppendIndexInfo(ToFill.Indices);
117  }
118 
120  {
121  Whole VertexOffset = ToFill.size();
122  Whole NewSize = VertexOffset + this->GetVertexCount();
123 
124  Ogre::VertexData* VertData = ( this->InternalSubMesh->useSharedVertices ? this->InternalSubMesh->parent->sharedVertexData : this->InternalSubMesh->vertexData );
125  const Ogre::VertexElement* PositionElem = VertData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
126  if( PositionElem != NULL ) {
127  ToFill.resize(NewSize);
128  Ogre::HardwareVertexBufferSharedPtr vBuffer = VertData->vertexBufferBinding->getBuffer(PositionElem->getSource());
129 
130  float* pReal = NULL;
131  unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
132  for( size_t j = VertexOffset ; j < NewSize ; j++, vertex += vBuffer->getVertexSize() )
133  {
134  PositionElem->baseVertexPointerToElement(vertex, &pReal);
135  ToFill[j].X = *pReal++;
136  ToFill[j].Y = *pReal++;
137  ToFill[j].Z = *pReal++;
138  }
139  vBuffer->unlock();
140  }
141  }
142 
144  {
145  Whole VertexOffset = ToFill.size();
146  Whole NewSize = VertexOffset + this->GetVertexCount();
147 
148  Ogre::VertexData* VertData = ( this->InternalSubMesh->useSharedVertices ? this->InternalSubMesh->parent->sharedVertexData : this->InternalSubMesh->vertexData );
149  const Ogre::VertexElement* TexCoordElem = VertData->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
150  if( TexCoordElem != NULL ) {
151  ToFill.resize(NewSize);
152  Ogre::HardwareVertexBufferSharedPtr vBuffer = VertData->vertexBufferBinding->getBuffer(TexCoordElem->getSource());
153 
154  float* pReal = NULL;
155  unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
156  for( size_t j = VertexOffset ; j < NewSize ; j++, vertex += vBuffer->getVertexSize() )
157  {
158  TexCoordElem->baseVertexPointerToElement(vertex, &pReal);
159  ToFill[j].X = *pReal++;
160  ToFill[j].Y = *pReal++;
161  }
162  vBuffer->unlock();
163  }
164  }
165 
167  {
168  Whole VertexOffset = ToFill.size();
169  Whole NewSize = VertexOffset + this->GetVertexCount();
170 
171  Ogre::VertexData* VertData = ( this->InternalSubMesh->useSharedVertices ? this->InternalSubMesh->parent->sharedVertexData : this->InternalSubMesh->vertexData );
172  const Ogre::VertexElement* NormalElem = VertData->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL);
173  if( NormalElem != NULL ) {
174  ToFill.resize(NewSize);
175  Ogre::HardwareVertexBufferSharedPtr vBuffer = VertData->vertexBufferBinding->getBuffer(NormalElem->getSource());
176 
177  float* pReal = NULL;
178  unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
179  for( size_t j = VertexOffset ; j < NewSize ; j++, vertex += vBuffer->getVertexSize() )
180  {
181  NormalElem->baseVertexPointerToElement(vertex, &pReal);
182  ToFill[j].X = *pReal++;
183  ToFill[j].Y = *pReal++;
184  ToFill[j].Z = *pReal++;
185  }
186  vBuffer->unlock();
187  }
188  }
189 
191  {
192  Whole VertexOffset = ToFill.size();
193  Whole NewSize = VertexOffset + this->GetVertexCount();
194 
195  Ogre::VertexData* VertData = ( this->InternalSubMesh->useSharedVertices ? this->InternalSubMesh->parent->sharedVertexData : this->InternalSubMesh->vertexData );
196  const Ogre::VertexElement* TangentElem = VertData->vertexDeclaration->findElementBySemantic(Ogre::VES_TANGENT);
197  if( TangentElem != NULL ) {
198  ToFill.resize(NewSize);
199  Ogre::HardwareVertexBufferSharedPtr vBuffer = VertData->vertexBufferBinding->getBuffer(TangentElem->getSource());
200 
201  float* pReal = NULL;
202  unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
203  for( size_t j = VertexOffset ; j < NewSize ; j++, vertex += vBuffer->getVertexSize() )
204  {
205  TangentElem->baseVertexPointerToElement(vertex, &pReal);
206  ToFill[j].X = *pReal++;
207  ToFill[j].Y = *pReal++;
208  ToFill[j].Z = *pReal++;
209  }
210  vBuffer->unlock();
211  }
212  }
213 
214  void SubMesh::AppendIndexInfo(IntVec& ToFill) const
215  {
216  Whole IndexOffset = ToFill.size();
217  Whole NewSize = IndexOffset + this->GetVertexCount();
218 
219  Ogre::HardwareIndexBufferSharedPtr iBuffer = this->InternalSubMesh->indexData->indexBuffer;
220  Boole use32bitindexes = ( iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT );
221  ToFill.resize(NewSize);
222 
223  long* pLong = static_cast<long*>( iBuffer->lock( Ogre::HardwareBuffer::HBL_READ_ONLY ) );
224  if( use32bitindexes ) {
225  for( size_t CurrIndex = IndexOffset ; CurrIndex < NewSize ; ++CurrIndex )
226  { ToFill[CurrIndex] = pLong[CurrIndex]; }
227  }else{
228  short* pShort = reinterpret_cast<short*>(pLong);
229  for( size_t CurrIndex = IndexOffset ; CurrIndex < NewSize ; ++CurrIndex )
230  { ToFill[CurrIndex] = static_cast<unsigned long>( pShort[CurrIndex] ); }
231  }
232  iBuffer->unlock();
233  }
234 
235  ///////////////////////////////////////////////////////////////////////////////
236  // Internal Methods
237 
238  Ogre::SubMesh* SubMesh::_GetInternalSubMesh() const
239  { return this->InternalSubMesh; }
240  }//Graphics
241 }//Mezzanine
242 
243 #endif
VertexInfo Vertices
A collection of containers storing the various properties of a Vertex.
Definition: meshinfo.h:108
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
A convenience class for the storage of Vertex data in a Mesh/SubMesh.
Definition: meshinfo.h:62
Ogre::SubMesh * InternalSubMesh
A pointer to the internal SubMesh this is based on.
Definition: submesh.h:66
~SubMesh()
Class Destructor.
Definition: submesh.cpp:56
void AppendIndexInfo(IntVec &ToFill) const
Gets the Index information of this SubMesh and appends it to the container provided.
Definition: submesh.cpp:214
IntVec Indices
A container of Indexes used to assemble the Vertices for rendering.
Definition: meshinfo.h:79
String MaterialName
The name of the material used to render the Mesh/SubMesh.
Definition: meshinfo.h:103
const String & GetMaterialName() const
Gets the name of the Material being used by this SubMesh.
Definition: submesh.cpp:67
String MaterialGroup
The resource group in which the named Material can be found.
Definition: meshinfo.h:105
Whole GetVertexCount() const
Gets the number of Vertices in this SubMesh.
Definition: submesh.cpp:73
Boole UsesSharedVertices() const
Gets whether or not this SubMesh shares a Vertex Buffer with other SubMeshes.
Definition: submesh.cpp:70
void AppendVertexPositionInfo(Vector3Vec &ToFill) const
Gets the vertex position information of this SubMesh and appends it to the container provided...
Definition: submesh.cpp:119
Vector3Vec Tangents
A container storing the tangent of each vertex.
Definition: meshinfo.h:76
Whole VertexCount
The number of Vertices in the Mesh/SubMesh.
Definition: meshinfo.h:65
SubMesh(Ogre::SubMesh *Internal)
Internal Constructor.
Definition: submesh.cpp:52
void SetMaterialName(const String &MatName)
Sets the name of the Material to be used by this SubMesh.
Definition: submesh.cpp:64
std::vector< Vector2 > Vector2Vec
Convenience type for a container of Vector2s.
Definition: meshinfo.h:54
Vector2Vec UVs
A container storing the texture coordinates of each vertex.
Definition: meshinfo.h:72
A convenience class for the storage of rendering data in a Mesh/SubMesh.
Definition: meshinfo.h:97
void AppendVertexTexCoordInfo(Vector2Vec &ToFill) const
Gets the vertex texture coordinate information of this SubMesh and appends it to the container provid...
Definition: submesh.cpp:143
Vector3Vec Normals
A container storing the normal of each vertex.
Definition: meshinfo.h:74
std::vector< Integer > IntVec
Convenience type for a container of Integers.
Definition: meshinfo.h:56
void GetInfo(MeshInfo &ToFill) const
Gets the information used to render this SubMesh.
Definition: submesh.cpp:87
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Whole IndexCount
The number of Indexes in the Mesh/SubMesh.
Definition: meshinfo.h:67
std::vector< Vector3 > Vector3Vec
Convenience type for a container of Vector3s.
Definition: meshinfo.h:52
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
Whole OperationType
Used Internally. Describes how the Vertex data should be treated when rendering.
Definition: meshinfo.h:100
Vector3Vec Positions
A container storing the position of each vertex.
Definition: meshinfo.h:70
void AppendVertexTangentInfo(Vector3Vec &ToFill) const
Gets the vertex tangent information of this SubMesh and appends it to the container provided...
Definition: submesh.cpp:190
void AppendVertexInfo(VertexInfo &ToFill) const
Gets the vertex information of this SubMesh and appends it to the VertexInfo provided.
Definition: submesh.cpp:106
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
Ogre::SubMesh * _GetInternalSubMesh() const
Gets the internal SubMesh pointer.
Definition: submesh.cpp:238
Whole GetIndexCount() const
Gets the number of Indices in this SubMesh.
Definition: submesh.cpp:79
void AppendVertexNormalInfo(Vector3Vec &ToFill) const
Gets the vertex normal information of this SubMesh and appends it to the container provided...
Definition: submesh.cpp:166