Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

NVMeshMender.h

Go to the documentation of this file.
00001 #ifndef _NVMeshMender_H_
00002 #define _NVMeshMender_H_
00003 
00004 /*********************************************************************NVMH2****
00005 Copyright (C) 1999, 2000, 2001, 2002 NVIDIA Corporation
00006 This file is provided without support, instruction, or implied warranty of any
00007 kind.  NVIDIA makes no guarantee of its fitness for a particular purpose and is
00008 not liable under any circumstances for any damages or loss whatsoever arising
00009 from the use or inability to use this file or items derived from it.
00010 
00011 Questions to sim.dietrich@nvidia.com
00012 
00013 Comments:
00014 
00015     This tool is designed to help condition meshes for use in vertex & pixel shaders.
00016 
00017     It can generate normals, texture coordinates, and perhaps most importantly, texture space 
00018   basis matrices.  It also can fix common texuring problems that come up when bump mapping, including
00019 
00020   Texture Mirroring -  When two one halves of a character use the same part of a texture.
00021 
00022   Cylindrical TexGen - When the rendering relies on cylindrical wrapping, texture space computation
00023                         won't work right.
00024 
00025   Stretched Basis -    When two adjacend faces use wildly different texture mappings, causing stretching
00026                         that can ruin per-pixel lighting.
00027  
00028 
00029   Here is an example usage scenario : 
00030 
00031   Say you have positions & indices & normals, and want textures, and tangents, and binormals.
00032   and assume that positions, indices, and normals are in STL arrays: vpos, triIndices and vnor respectively.
00033 
00034   std::vector<float> vpos;
00035   std::vector<int> triIndices;
00036   std::vector<float> vnor; 
00037   ...
00038 
00039   NVMeshMender aMender;
00040 
00041 
00042   std::vector<NVMeshMender::VertexAttribute> inputAtts;     // What you have
00043   std::vector<NVMeshMender::VertexAttribute> outputAtts;    // What you want.
00044 
00045   NVMeshMender::VertexAttribute posAtt;
00046   posAtt.Name_ = "position";
00047   posAtt.floatVector_ = vpos;
00048 
00049   NVMeshMender::VertexAttribute triIndAtt;
00050   triIndAtt.Name_ = "indices";
00051   triIndAtt.intVector_ = triIndices;
00052 
00053   NVMeshMender::VertexAttribute norAtt;
00054   norAtt.Name_ = "normal";
00055   norAtt.floatVector_ = vnor;
00056 
00057   std::vector<float> texCoords;
00058   NVMeshMender::VertexAttribute texCoordAtt;
00059   texCoordAtt.Name_ = "tex0";
00060   texCoordAtt.floatVector_;// = texCoords;
00061 
00062   NVMeshMender::VertexAttribute tgtSpaceAtt;
00063   tgtSpaceAtt.Name_ = "tangent";
00064 
00065   NVMeshMender::VertexAttribute binormalAtt;
00066   binormalAtt.Name_ = "binormal";
00067 
00068   inputAtts.push_back(posAtt);
00069   inputAtts.push_back(triIndAtt);
00070   inputAtts.push_back(norAtt);
00071 
00072   outputAtts.push_back(posAtt);
00073   outputAtts.push_back(triIndAtt);
00074   outputAtts.push_back(norAtt);
00075   outputAtts.push_back(texCoordAtt);
00076   outputAtts.push_back(tgtSpaceAtt);
00077   outputAtts.push_back(binormalAtt);
00078 
00079   // All inputs except for indices are assumed to be sets of 3 floats
00080 
00081   // "indices" are assumed to be unsigned ints
00082 
00083   // "tex0" is used for the tangent space calculation
00084 
00085   // "tex0" is the only coordinate set generated, and the texture matrix applies only to it
00086 
00087   //  All unknown attribute types, including "tex1", "tex2", "random_attribute", "weights", "bones", etc.
00088   // are simply passed through.  They will be duplicated as needed just like positions, normals, etc.
00089 
00090   bool bSuccess = aMender.Munge( inputAtts,              // these are my positions & indices
00091                                  outputAtts,             // these are the outputs I requested, plus extra stuff generated on my behalf
00092                                  3.141592654f / 2.5f,    // tangent space smooth angle
00093                                  NULL,                   // no Texture matrix applied to my tex0 coords
00094                                  FixTangents,            // fix degenerate bases & texture mirroring
00095                                  FixCylindricalTexGen    // handle cylidrically mapped textures via vertex duplication
00096                                  WeightNormalsByFaceSize // weight vertex normals by the triangle's size
00097                                  );
00098 
00099 
00100   if ( !bSuccess ) return false;
00101   
00102   vpos = outputAtts[0].floatVector_; // Note that there may be more vertices than you sent in.
00103   vnor = outputAtts[2].floatVector_;
00104   std::vector<float> texCoords = outputAtts[3].floatVector_; // texcoords
00105   std::vector<float> vtgt = outputAtts[4].floatVector_;      // tgts
00106   triIndices = outputAtts[1].intVector_;                     // new indices.
00107   std::vector<float> vbin = outputAtts[5].floatVector_;      // binormals.
00108 
00109   // Now the outputAtts may contain more vertex then you sent in !
00110   //  This is because in handling tangent space smoothing, and solving texture mirroring & 
00111   // cylindrical texture wrapping problems, we partially duplicate vertices.
00112 
00113   // All attributes are duplicated, even unknowns.
00114 
00115   //  You may also get things you didn't ask for.  For instance, if you ask for tangent space,
00116   // in other words, you ask for "tangent" or "binormal",  you will get "normal", "tex0", 
00117   // "tangent" and "binormal".  You can then ignore things in the output vector that you don't want.
00118 
00119   //   If you ask for FixCylindricalTexGen, it will fix any absolute change in texture coordinates > 0.5 
00120   // across a single edge.  Therefore, if you pass in a single quad or cube, it won't work.  Any more 
00121   // complicated or tessellated mesh should work fine.
00122 
00123 
00124 ******************************************************************************/
00125 
00126 #include <vector>
00127 #include <string>
00128 
00129 
00130 
00131 
00132 class NVMeshMender
00133 {
00134     private :
00135 
00136         mutable std::vector< std::string > LastErrors_;
00137 
00138 
00139         struct Edge
00140         {
00141             unsigned int v0;
00142             unsigned int v1;
00143 
00144             unsigned int face;
00145             unsigned int face2;
00146 
00147             bool operator==( const Edge& rhs ) const
00148             {
00149                 return ( ( v0 == rhs.v0 ) && ( v1 == rhs.v1 ) );
00150             }
00151 
00152             bool operator<( const Edge& rhs ) const
00153             {
00154                 if ( v0 < rhs.v0 ) 
00155                 {
00156                     return true;
00157                 }
00158 
00159                 if ( v0 > rhs.v0 )
00160                 {
00161                     return false;
00162                 }
00163 
00164                 return  ( v1 < rhs.v1 );
00165             }
00166         };
00167 
00168     public :
00169 
00170         void SetLastError( const std::string& rhs ) const
00171         {
00172             LastErrors_.push_back( rhs );
00173         }
00174 
00175         std::string GetLastError() const
00176         {
00177             std::string aString;
00178 
00179             if ( LastErrors_.size() > 0 )
00180             {
00181                 aString = LastErrors_.back();
00182             }
00183             return aString;
00184         }
00185 
00186         struct VertexAttribute
00187         {
00188             std::string  Name_;
00189 
00190             typedef std::vector< int > IntVector;
00191             IntVector intVector_;
00192 
00193 
00194             typedef std::vector< float > FloatVector;
00195             FloatVector floatVector_;
00196 
00197             VertexAttribute& operator=( const VertexAttribute& rhs )
00198             {
00199                 Name_   = rhs.Name_;
00200                 intVector_ = rhs.intVector_;
00201                 floatVector_ = rhs.floatVector_;
00202                 return *this;
00203             }
00204 
00205             VertexAttribute( const char* pName = "" ) : Name_(pName) {;}
00206 
00207             VertexAttribute( const VertexAttribute& rhs )
00208             {
00209                 *this = rhs;
00210             }
00211 
00212             bool operator==( const VertexAttribute& rhs )
00213             {
00214                 return ( Name_ == rhs.Name_ );
00215             }
00216 
00217             bool operator<( const VertexAttribute& rhs )
00218             {
00219                 return ( Name_ < rhs.Name_ );
00220             }
00221 
00222         };
00223 
00224         typedef std::vector< VertexAttribute > VAVector;
00225 
00226         enum Option
00227         {
00228             FixTangents,
00229             DontFixTangents,
00230 
00231             FixCylindricalTexGen,
00232             DontFixCylindricalTexGen,
00233 
00234             WeightNormalsByFaceSize,
00235             DontWeightNormalsByFaceSize
00236         };
00237 
00238         bool NVMeshMender::Munge( const NVMeshMender::VAVector& input, 
00239                                NVMeshMender::VAVector& output, 
00240                                const float bSmoothCreaseAngleRadians = 3.141592654f / 3.0f,
00241                                const float* pTextureMatrix = 0,
00242                                const Option _FixTangents = FixTangents,
00243                                const Option _FixCylindricalTexGen = FixCylindricalTexGen,
00244                                const Option _WeightNormalsByFaceSize = WeightNormalsByFaceSize
00245                                );
00246         bool NVMeshMender::MungeD3DX( const NVMeshMender::VAVector& input, 
00247                                NVMeshMender::VAVector& output, 
00248                                const float bSmoothCreaseAngleRadians = 3.141592654f / 3.0f,
00249                                const float* pTextureMatrix = 0,
00250                                const Option _FixTangents = FixTangents,
00251                                const Option _FixCylindricalTexGen = FixCylindricalTexGen,
00252                                const Option _WeightNormalsByFaceSize = WeightNormalsByFaceSize
00253                                );
00254 };
00255 
00256 #endif  //_NVMeshMender_H_
00257 

Generated on Thu Apr 6 15:25:39 2006 for rcssserver3d by  doxygen 1.4.4