00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2012 Torus Knot Software Ltd 00008 00009 Permission is hereby granted, free of charge, to any person obtaining a copy 00010 of this software and associated documentation files (the "Software"), to deal 00011 in the Software without restriction, including without limitation the rights 00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 copies of the Software, and to permit persons to whom the Software is 00014 furnished to do so, subject to the following conditions: 00015 00016 The above copyright notice and this permission notice shall be included in 00017 all copies or substantial portions of the Software. 00018 00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 THE SOFTWARE. 00026 ----------------------------------------------------------------------------- 00027 */ 00028 #ifndef _OgreTangentSpaceCalc_H_ 00029 #define _OgreTangentSpaceCalc_H_ 00030 00031 #include "OgrePrerequisites.h" 00032 #include "OgreRenderOperation.h" 00033 #include "OgreVector2.h" 00034 #include "OgreVector3.h" 00035 #include "OgreVertexIndexData.h" 00036 00037 namespace Ogre 00038 { 00039 00048 class _OgreExport TangentSpaceCalc 00049 { 00050 public: 00051 TangentSpaceCalc(); 00052 virtual ~TangentSpaceCalc(); 00053 00054 typedef std::pair<size_t, size_t> VertexSplit; 00055 00057 struct IndexRemap 00058 { 00060 size_t indexSet; 00062 size_t faceIndex; 00064 VertexSplit splitVertex; 00065 00066 IndexRemap() {} // to keep container happy 00067 IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {} 00068 }; 00071 typedef list<IndexRemap>::type IndexRemapList; 00072 00073 typedef list<VertexSplit>::type VertexSplits; 00074 00076 struct Result 00077 { 00082 VertexSplits vertexSplits; 00085 IndexRemapList indexesRemapped; 00086 }; 00087 00089 void clear(); 00090 00092 void setVertexData(VertexData* v_in); 00093 00097 void addIndexData(IndexData* i_in, RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST); 00098 00111 void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; } 00112 00114 bool getStoreParityInW() const { return mStoreParityInW; } 00115 00130 void setSplitMirrored(bool split) { mSplitMirrored = split; } 00131 00135 bool getSplitMirrored() const { return mSplitMirrored; } 00136 00151 void setSplitRotated(bool split) { mSplitRotated = split; } 00155 bool getSplitRotated() const { return mSplitRotated; } 00156 00179 Result build(VertexElementSemantic targetSemantic = VES_TANGENT, 00180 unsigned short sourceTexCoordSet = 0, unsigned short index = 1); 00181 00182 00183 protected: 00184 00185 VertexData* mVData; 00186 typedef vector<IndexData*>::type IndexDataList; 00187 typedef vector<RenderOperation::OperationType>::type OpTypeList; 00188 IndexDataList mIDataList; 00189 OpTypeList mOpTypes; 00190 bool mSplitMirrored; 00191 bool mSplitRotated; 00192 bool mStoreParityInW; 00193 00194 00195 struct VertexInfo 00196 { 00197 Vector3 pos; 00198 Vector3 norm; 00199 Vector2 uv; 00200 Vector3 tangent; 00201 Vector3 binormal; 00202 // Which way the tangent space is oriented (+1 / -1) (set on first time found) 00203 int parity; 00204 // What index the opposite parity vertex copy is at (0 if not created yet) 00205 size_t oppositeParityIndex; 00206 00207 VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO), 00208 parity(0), oppositeParityIndex(0) {} 00209 }; 00210 typedef vector<VertexInfo>::type VertexInfoArray; 00211 VertexInfoArray mVertexArray; 00212 00213 void extendBuffers(VertexSplits& splits); 00214 void insertTangents(Result& res, 00215 VertexElementSemantic targetSemantic, 00216 unsigned short sourceTexCoordSet, unsigned short index); 00217 00218 void populateVertexArray(unsigned short sourceTexCoordSet); 00219 void processFaces(Result& result); 00221 void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN); 00222 Real calculateAngleWeight(size_t v0, size_t v1, size_t v2); 00223 int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n); 00224 void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd, 00225 const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result); 00226 void normaliseVertices(); 00227 void remapIndexes(Result& res); 00228 template <typename T> 00229 void remapIndexes(T* ibuf, size_t indexSet, Result& res) 00230 { 00231 for (IndexRemapList::iterator i = res.indexesRemapped.begin(); 00232 i != res.indexesRemapped.end(); ++i) 00233 { 00234 IndexRemap& remap = *i; 00235 00236 // Note that because this is a vertex split situation, and vertex 00237 // split is only for some faces, it's not a case of replacing all 00238 // instances of vertex index A with vertex index B 00239 // It actually matters which triangle we're talking about, so drive 00240 // the update from the face index 00241 00242 if (remap.indexSet == indexSet) 00243 { 00244 T* pBuf; 00245 pBuf = ibuf + remap.faceIndex * 3; 00246 00247 for (int v = 0; v < 3; ++v, ++pBuf) 00248 { 00249 if (*pBuf == remap.splitVertex.first) 00250 { 00251 *pBuf = (T)remap.splitVertex.second; 00252 } 00253 } 00254 } 00255 00256 00257 } 00258 } 00259 00260 00261 }; 00265 } 00266 00267 00268 00269 #endif
Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri May 25 23:36:28 2012