# 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
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat Apr 11 14:26:48 2009