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-2007 Torus Knot Software Ltd
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 
00024 You may alternatively use this source under the terms of a specific version of
00025 the OGRE Unrestricted License provided you have obtained such a license from
00026 Torus Knot Software Ltd.
00027 -----------------------------------------------------------------------------
00028 */
00029 #ifndef _OgreTangentSpaceCalc_H_
00030 #define _OgreTangentSpaceCalc_H_
00031 
00032 #include "OgrePrerequisites.h"
00033 #include "OgreRenderOperation.h"
00034 #include "OgreVector2.h"
00035 #include "OgreVector3.h"
00036 #include "OgreVertexIndexData.h"
00037 
00038 namespace Ogre
00039 {
00040 
00043     class _OgreExport TangentSpaceCalc
00044     {
00045     public:
00046         TangentSpaceCalc();
00047         virtual ~TangentSpaceCalc();
00048 
00049         typedef std::pair<size_t, size_t> VertexSplit;
00050 
00052         struct IndexRemap
00053         {
00055             size_t indexSet;
00057             size_t faceIndex;
00059             VertexSplit splitVertex;
00060 
00061             IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {}
00062         };
00065         typedef std::list<IndexRemap> IndexRemapList;
00066 
00067         typedef std::list<VertexSplit> VertexSplits;
00068 
00070         struct Result
00071         {
00076             VertexSplits vertexSplits;
00079             IndexRemapList indexesRemapped;
00080         };
00081 
00083         void clear();
00084 
00086         void setVertexData(VertexData* v_in);
00087 
00091         void addIndexData(IndexData* i_in, RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
00092 
00105         void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; }
00106 
00108         bool getStoreParityInW() const { return mStoreParityInW; }
00109 
00124         void setSplitMirrored(bool split) { mSplitMirrored = split; }
00125         
00129         bool getSplitMirrored() const { return mSplitMirrored; }
00130 
00145         void setSplitRotated(bool split) { mSplitRotated = split; }
00149         bool getSplitRotated() const { return mSplitRotated; }
00150 
00173         Result build(VertexElementSemantic targetSemantic = VES_TANGENT,
00174             unsigned short sourceTexCoordSet = 0, unsigned short index = 1);
00175 
00176 
00177     protected:
00178 
00179         VertexData* mVData;
00180         typedef std::vector<IndexData*> IndexDataList;
00181         typedef std::vector<RenderOperation::OperationType> OpTypeList;
00182         IndexDataList mIDataList;
00183         OpTypeList mOpTypes;
00184         bool mSplitMirrored;
00185         bool mSplitRotated;
00186         bool mStoreParityInW;
00187 
00188 
00189         struct VertexInfo
00190         {
00191             Vector3 pos;
00192             Vector3 norm;
00193             Vector2 uv;
00194             Vector3 tangent;
00195             Vector3 binormal;
00196             // Which way the tangent space is oriented (+1 / -1) (set on first time found)
00197             int parity;
00198             // What index the opposite parity vertex copy is at (0 if not created yet)
00199             size_t oppositeParityIndex;
00200 
00201             VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO), 
00202                 parity(0), oppositeParityIndex(0) {}
00203         };
00204         typedef std::vector<VertexInfo> VertexInfoArray;
00205         VertexInfoArray mVertexArray;
00206 
00207         void extendBuffers(VertexSplits& splits);
00208         void insertTangents(Result& res,
00209             VertexElementSemantic targetSemantic, 
00210             unsigned short sourceTexCoordSet, unsigned short index);
00211 
00212         void populateVertexArray(unsigned short sourceTexCoordSet);
00213         void processFaces(Result& result);
00215         void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN);
00216         Real calculateAngleWeight(size_t v0, size_t v1, size_t v2);
00217         int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n);
00218         void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd, 
00219             const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result);
00220         void normaliseVertices();
00221         void remapIndexes(Result& res);
00222         template <typename T>
00223         void remapIndexes(T* ibuf, size_t indexSet, Result& res)
00224         {
00225             for (IndexRemapList::iterator i = res.indexesRemapped.begin();
00226                 i != res.indexesRemapped.end(); ++i)
00227             {
00228                 IndexRemap& remap = *i;
00229 
00230                 // Note that because this is a vertex split situation, and vertex
00231                 // split is only for some faces, it's not a case of replacing all
00232                 // instances of vertex index A with vertex index B
00233                 // It actually matters which triangle we're talking about, so drive
00234                 // the update from the face index
00235 
00236                 if (remap.indexSet == indexSet)
00237                 {
00238                     T* pBuf;
00239                     pBuf = ibuf + remap.faceIndex * 3;
00240 
00241                     for (int v = 0; v < 3; ++v, ++pBuf)
00242                     {
00243                         if (*pBuf == remap.splitVertex.first)
00244                         {
00245                             *pBuf = (T)remap.splitVertex.second;
00246                         }
00247                     }
00248                 }
00249 
00250 
00251             }
00252         }
00253         
00254 
00255     };
00256 
00257 }
00258 
00259 
00260 
00261 #endif

Copyright © 2008 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:26 2009