OgreTangentSpaceCalc.h
Go to the documentation of this file.
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-2013 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 #include "OgreHeaderPrefix.h"
00037 
00038 namespace Ogre
00039 {
00040 
00049     class _OgreExport TangentSpaceCalc
00050     {
00051     public:
00052         TangentSpaceCalc();
00053         virtual ~TangentSpaceCalc();
00054 
00055         typedef std::pair<size_t, size_t> VertexSplit;
00056 
00058         struct IndexRemap
00059         {
00061             size_t indexSet;
00063             size_t faceIndex;
00065             VertexSplit splitVertex;
00066         
00067             IndexRemap() {} // to keep container happy
00068             IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {}
00069         };
00072         typedef list<IndexRemap>::type IndexRemapList;
00073 
00074         typedef list<VertexSplit>::type VertexSplits;
00075 
00077         struct Result
00078         {
00083             VertexSplits vertexSplits;
00086             IndexRemapList indexesRemapped;
00087         };
00088 
00090         void clear();
00091 
00093         void setVertexData(VertexData* v_in);
00094 
00098         void addIndexData(IndexData* i_in, RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
00099 
00112         void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; }
00113 
00115         bool getStoreParityInW() const { return mStoreParityInW; }
00116 
00131         void setSplitMirrored(bool split) { mSplitMirrored = split; }
00132         
00136         bool getSplitMirrored() const { return mSplitMirrored; }
00137 
00152         void setSplitRotated(bool split) { mSplitRotated = split; }
00156         bool getSplitRotated() const { return mSplitRotated; }
00157 
00180         Result build(VertexElementSemantic targetSemantic = VES_TANGENT,
00181             unsigned short sourceTexCoordSet = 0, unsigned short index = 1);
00182 
00183 
00184     protected:
00185 
00186         VertexData* mVData;
00187         typedef vector<IndexData*>::type IndexDataList;
00188         typedef vector<RenderOperation::OperationType>::type OpTypeList;
00189         IndexDataList mIDataList;
00190         OpTypeList mOpTypes;
00191         bool mSplitMirrored;
00192         bool mSplitRotated;
00193         bool mStoreParityInW;
00194 
00195 
00196         struct VertexInfo
00197         {
00198             Vector3 pos;
00199             Vector3 norm;
00200             Vector2 uv;
00201             Vector3 tangent;
00202             Vector3 binormal;
00203             // Which way the tangent space is oriented (+1 / -1) (set on first time found)
00204             int parity;
00205             // What index the opposite parity vertex copy is at (0 if not created yet)
00206             size_t oppositeParityIndex;
00207 
00208             VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO), 
00209                 parity(0), oppositeParityIndex(0) {}
00210         };
00211         typedef vector<VertexInfo>::type VertexInfoArray;
00212         VertexInfoArray mVertexArray;
00213 
00214         void extendBuffers(VertexSplits& splits);
00215         void insertTangents(Result& res,
00216             VertexElementSemantic targetSemantic, 
00217             unsigned short sourceTexCoordSet, unsigned short index);
00218 
00219         void populateVertexArray(unsigned short sourceTexCoordSet);
00220         void processFaces(Result& result);
00222         void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN);
00223         Real calculateAngleWeight(size_t v0, size_t v1, size_t v2);
00224         int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n);
00225         void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd, 
00226             const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result);
00227         void normaliseVertices();
00228         void remapIndexes(Result& res);
00229         template <typename T>
00230         void remapIndexes(T* ibuf, size_t indexSet, Result& res)
00231         {
00232             for (IndexRemapList::iterator i = res.indexesRemapped.begin();
00233                 i != res.indexesRemapped.end(); ++i)
00234             {
00235                 IndexRemap& remap = *i;
00236 
00237                 // Note that because this is a vertex split situation, and vertex
00238                 // split is only for some faces, it's not a case of replacing all
00239                 // instances of vertex index A with vertex index B
00240                 // It actually matters which triangle we're talking about, so drive
00241                 // the update from the face index
00242 
00243                 if (remap.indexSet == indexSet)
00244                 {
00245                     T* pBuf;
00246                     pBuf = ibuf + remap.faceIndex * 3;
00247 
00248                     for (int v = 0; v < 3; ++v, ++pBuf)
00249                     {
00250                         if (*pBuf == remap.splitVertex.first)
00251                         {
00252                             *pBuf = (T)remap.splitVertex.second;
00253                         }
00254                     }
00255                 }
00256 
00257 
00258             }
00259         }
00260         
00261 
00262     };
00266 }
00267 
00268 #include "OgreHeaderSuffix.h"
00269 
00270 #endif

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Mon Jul 27 2020 13:40:48