OGRE  1.8
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-2013 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 
37 namespace Ogre
38 {
39 
49  {
50  public:
52  virtual ~TangentSpaceCalc();
53 
54  typedef std::pair<size_t, size_t> VertexSplit;
55 
57  struct IndexRemap
58  {
60  size_t indexSet;
62  size_t faceIndex;
65 
66  IndexRemap() {} // to keep container happy
67  IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {}
68  };
72 
74 
76  struct Result
77  {
86  };
87 
89  void clear();
90 
92  void setVertexData(VertexData* v_in);
93 
98 
111  void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; }
112 
114  bool getStoreParityInW() const { return mStoreParityInW; }
115 
130  void setSplitMirrored(bool split) { mSplitMirrored = split; }
131 
135  bool getSplitMirrored() const { return mSplitMirrored; }
136 
151  void setSplitRotated(bool split) { mSplitRotated = split; }
155  bool getSplitRotated() const { return mSplitRotated; }
156 
179  Result build(VertexElementSemantic targetSemantic = VES_TANGENT,
180  unsigned short sourceTexCoordSet = 0, unsigned short index = 1);
181 
182 
183  protected:
184 
193 
194 
195  struct VertexInfo
196  {
202  // Which way the tangent space is oriented (+1 / -1) (set on first time found)
203  int parity;
204  // What index the opposite parity vertex copy is at (0 if not created yet)
206 
207  VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO),
208  parity(0), oppositeParityIndex(0) {}
209  };
212 
213  void extendBuffers(VertexSplits& splits);
214  void insertTangents(Result& res,
215  VertexElementSemantic targetSemantic,
216  unsigned short sourceTexCoordSet, unsigned short index);
217 
218  void populateVertexArray(unsigned short sourceTexCoordSet);
219  void processFaces(Result& result);
221  void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN);
222  Real calculateAngleWeight(size_t v0, size_t v1, size_t v2);
223  int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n);
224  void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd,
225  const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result);
226  void normaliseVertices();
227  void remapIndexes(Result& res);
228  template <typename T>
229  void remapIndexes(T* ibuf, size_t indexSet, Result& res)
230  {
231  for (IndexRemapList::iterator i = res.indexesRemapped.begin();
232  i != res.indexesRemapped.end(); ++i)
233  {
234  IndexRemap& remap = *i;
235 
236  // Note that because this is a vertex split situation, and vertex
237  // split is only for some faces, it's not a case of replacing all
238  // instances of vertex index A with vertex index B
239  // It actually matters which triangle we're talking about, so drive
240  // the update from the face index
241 
242  if (remap.indexSet == indexSet)
243  {
244  T* pBuf;
245  pBuf = ibuf + remap.faceIndex * 3;
246 
247  for (int v = 0; v < 3; ++v, ++pBuf)
248  {
249  if (*pBuf == remap.splitVertex.first)
250  {
251  *pBuf = (T)remap.splitVertex.second;
252  }
253  }
254  }
255 
256 
257  }
258  }
259 
260 
261  };
265 }
266 
267 
268 
269 #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:233
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.