OGRE  1.9.0
OgreTangentSpaceCalc.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE 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
38namespace Ogre
39{
40
50 {
51 public:
54
55 typedef std::pair<size_t, size_t> VertexSplit;
56
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
94
98 void addIndexData(IndexData* i_in, RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
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
197 {
203 // Which way the tangent space is oriented (+1 / -1) (set on first time found)
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
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);
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
#define _OgreExport
Definition: OgrePlatform.h:260
Summary class collecting together index data source information.
OperationType
The rendering operation type to perform.
Class for calculating a tangent space basis.
void processFaces(Result &result)
bool getSplitRotated() const
Sets whether or not to split vertices when tangent space rotates more than 90 degrees around a vertex...
void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd, const Vector3 &faceTsU, const Vector3 &faceTsV, const Vector3 &faceNorm, Result &result)
list< IndexRemap >::type IndexRemapList
List of indexes that were remapped (split vertices).
vector< RenderOperation::OperationType >::type OpTypeList
void setSplitRotated(bool split)
Sets whether or not to split vertices when tangent space rotates more than 90 degrees around a vertex...
void setSplitMirrored(bool split)
Sets whether or not to split vertices when a mirrored tangent space transition is detected (matrix pa...
void insertTangents(Result &res, VertexElementSemantic targetSemantic, unsigned short sourceTexCoordSet, unsigned short index)
void calculateFaceTangentSpace(const size_t *vertInd, Vector3 &tsU, Vector3 &tsV, Vector3 &tsN)
Calculate face tangent space, U and V are weighted by UV area, N is normalised.
Result build(VertexElementSemantic targetSemantic=VES_TANGENT, unsigned short sourceTexCoordSet=0, unsigned short index=1)
Build a tangent space basis from the provided data.
vector< IndexData * >::type IndexDataList
void setStoreParityInW(bool enabled)
Sets whether to store tangent space parity in the W of a 4-component tangent or not.
void extendBuffers(VertexSplits &splits)
void remapIndexes(Result &res)
Real calculateAngleWeight(size_t v0, size_t v1, size_t v2)
bool getStoreParityInW() const
Gets whether to store tangent space parity in the W of a 4-component tangent or not.
void addIndexData(IndexData *i_in, RenderOperation::OperationType opType=RenderOperation::OT_TRIANGLE_LIST)
Add a set of index data that references the vertex data.
void setVertexData(VertexData *v_in)
Set the incoming vertex data (which will be modified)
void remapIndexes(T *ibuf, size_t indexSet, Result &res)
list< VertexSplit >::type VertexSplits
vector< VertexInfo >::type VertexInfoArray
std::pair< size_t, size_t > VertexSplit
int calculateParity(const Vector3 &u, const Vector3 &v, const Vector3 &n)
void clear()
Reset the calculation object.
bool getSplitMirrored() const
Gets whether or not to split vertices when a mirrored tangent space transition is detected.
void populateVertexArray(unsigned short sourceTexCoordSet)
Standard 2-dimensional vector.
Definition: OgreVector2.h:52
Standard 3-dimensional vector.
Definition: OgreVector3.h:52
Summary class collecting together vertex source information.
VertexElementSemantic
Vertex element semantics, used to identify the meaning of vertex buffer contents.
float Real
Software floating point type.
Information about a remapped index.
size_t indexSet
Index data set (can be >0 if more than one index data was added)
VertexSplit splitVertex
The old and new vertex index.
size_t faceIndex
The position in the index buffer that's affected.
IndexRemap(size_t i, size_t f, const VertexSplit &s)
The result of having built a tangent space basis.
IndexRemapList indexesRemapped
A list of indexes which were affected by splits.
VertexSplits vertexSplits
A list of vertex indices which were split off into new vertices because of mirroring.
std::list< T, A > type
std::vector< T, A > type