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 Sun Sep 27 22:02:26 2009