OGRE  1.9
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
OgreTangentSpaceCalc.h
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef _OgreTangentSpaceCalc_H_
29 #define _OgreTangentSpaceCalc_H_
30 
31 #include "OgrePrerequisites.h"
32 #include "OgreRenderOperation.h"
33 #include "OgreVector2.h"
34 #include "OgreVector3.h"
35 #include "OgreVertexIndexData.h"
36 #include "OgreHeaderPrefix.h"
37 
38 namespace Ogre
39 {
40 
50  {
51  public:
53  virtual ~TangentSpaceCalc();
54 
55  typedef std::pair<size_t, size_t> VertexSplit;
56 
58  struct IndexRemap
59  {
61  size_t indexSet;
63  size_t faceIndex;
66 
67  IndexRemap() {} // to keep container happy
68  IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {}
69  };
73 
75 
77  struct Result
78  {
87  };
88 
90  void clear();
91 
93  void setVertexData(VertexData* v_in);
94 
99 
112  void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; }
113 
115  bool getStoreParityInW() const { return mStoreParityInW; }
116 
131  void setSplitMirrored(bool split) { mSplitMirrored = split; }
132 
136  bool getSplitMirrored() const { return mSplitMirrored; }
137 
152  void setSplitRotated(bool split) { mSplitRotated = split; }
156  bool getSplitRotated() const { return mSplitRotated; }
157 
180  Result build(VertexElementSemantic targetSemantic = VES_TANGENT,
181  unsigned short sourceTexCoordSet = 0, unsigned short index = 1);
182 
183 
184  protected:
185 
194 
195 
196  struct VertexInfo
197  {
203  // Which way the tangent space is oriented (+1 / -1) (set on first time found)
204  int parity;
205  // What index the opposite parity vertex copy is at (0 if not created yet)
207 
208  VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO),
209  parity(0), oppositeParityIndex(0) {}
210  };
213 
214  void extendBuffers(VertexSplits& splits);
215  void insertTangents(Result& res,
216  VertexElementSemantic targetSemantic,
217  unsigned short sourceTexCoordSet, unsigned short index);
218 
219  void populateVertexArray(unsigned short sourceTexCoordSet);
220  void processFaces(Result& result);
222  void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN);
223  Real calculateAngleWeight(size_t v0, size_t v1, size_t v2);
224  int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n);
225  void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd,
226  const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result);
227  void normaliseVertices();
228  void remapIndexes(Result& res);
229  template <typename T>
230  void remapIndexes(T* ibuf, size_t indexSet, Result& res)
231  {
232  for (IndexRemapList::iterator i = res.indexesRemapped.begin();
233  i != res.indexesRemapped.end(); ++i)
234  {
235  IndexRemap& remap = *i;
236 
237  // Note that because this is a vertex split situation, and vertex
238  // split is only for some faces, it's not a case of replacing all
239  // instances of vertex index A with vertex index B
240  // It actually matters which triangle we're talking about, so drive
241  // the update from the face index
242 
243  if (remap.indexSet == indexSet)
244  {
245  T* pBuf;
246  pBuf = ibuf + remap.faceIndex * 3;
247 
248  for (int v = 0; v < 3; ++v, ++pBuf)
249  {
250  if (*pBuf == remap.splitVertex.first)
251  {
252  *pBuf = (T)remap.splitVertex.second;
253  }
254  }
255  }
256 
257 
258  }
259  }
260 
261 
262  };
266 }
267 
268 #include "OgreHeaderSuffix.h"
269 
270 #endif
float Real
Software floating point type.
size_t indexSet
Index data set (can be >0 if more than one index data was added)
size_t faceIndex
The position in the index buffer that's affected.
#define _OgreExport
Definition: OgrePlatform.h:260
IndexRemap(size_t i, size_t f, const VertexSplit &s)
bool getStoreParityInW() const
Gets whether to store tangent space parity in the W of a 4-component tangent or not.
Tangent (X axis if normal is Z)
vector< VertexInfo >::type VertexInfoArray
IndexRemapList indexesRemapped
A list of indexes which were affected by splits.
void remapIndexes(T *ibuf, size_t indexSet, Result &res)
VertexElementSemantic
Vertex element semantics, used to identify the meaning of vertex buffer contents. ...
The result of having built a tangent space basis.
list< VertexSplit >::type VertexSplits
Information about a remapped index.
Standard 2-dimensional vector.
Definition: OgreVector2.h:51
Summary class collecting together index data source information.
Class for calculating a tangent space basis.
Standard 3-dimensional vector.
Definition: OgreVector3.h:51
void setSplitRotated(bool split)
Sets whether or not to split vertices when tangent space rotates more than 90 degrees around a vertex...
std::pair< size_t, size_t > VertexSplit
VertexSplit splitVertex
The old and new vertex index.
Summary class collecting together vertex source information.
vector< IndexData * >::type IndexDataList
bool getSplitMirrored() const
Gets whether or not to split vertices when a mirrored tangent space transition is detected...
VertexSplits vertexSplits
A list of vertex indices which were split off into new vertices because of mirroring.
A list of triangles, 3 vertices per triangle.
void setSplitMirrored(bool split)
Sets whether or not to split vertices when a mirrored tangent space transition is detected (matrix pa...
bool getSplitRotated() const
Sets whether or not to split vertices when tangent space rotates more than 90 degrees around a vertex...
OperationType
The rendering operation type to perform.
list< IndexRemap >::type IndexRemapList
List of indexes that were remapped (split vertices).
vector< RenderOperation::OperationType >::type OpTypeList
void setStoreParityInW(bool enabled)
Sets whether to store tangent space parity in the W of a 4-component tangent or not.