📄 nvmeshmender.h
字号:
#ifndef _NVMeshMender_H_#define _NVMeshMender_H_/*********************************************************************NVMH2****Copyright (C) 1999, 2000, 2001, 2002 NVIDIA CorporationThis file is provided without support, instruction, or implied warranty of anykind. NVIDIA makes no guarantee of its fitness for a particular purpose and isnot liable under any circumstances for any damages or loss whatsoever arisingfrom the use or inability to use this file or items derived from it.Questions to sim.dietrich@nvidia.comComments: This tool is designed to help condition meshes for use in vertex & pixel shaders. It can generate normals, texture coordinates, and perhaps most importantly, texture space basis matrices. It also can fix common texuring problems that come up when bump mapping, including Texture Mirroring - When two one halves of a character use the same part of a texture. Cylindrical TexGen - When the rendering relies on cylindrical wrapping, texture space computation won't work right. Stretched Basis - When two adjacend faces use wildly different texture mappings, causing stretching that can ruin per-pixel lighting. Here is an example usage scenario : Say you have positions & indices & normals, and want textures, and tangents, and binormals. and assume that positions, indices, and normals are in STL arrays: vpos, triIndices and vnor respectively. std::vector<float> vpos; std::vector<int> triIndices; std::vector<float> vnor; ... NVMeshMender aMender; std::vector<NVMeshMender::VertexAttribute> inputAtts; // What you have std::vector<NVMeshMender::VertexAttribute> outputAtts; // What you want. NVMeshMender::VertexAttribute posAtt; posAtt.Name_ = "position"; posAtt.floatVector_ = vpos; NVMeshMender::VertexAttribute triIndAtt; triIndAtt.Name_ = "indices"; triIndAtt.intVector_ = triIndices; NVMeshMender::VertexAttribute norAtt; norAtt.Name_ = "normal"; norAtt.floatVector_ = vnor; std::vector<float> texCoords; NVMeshMender::VertexAttribute texCoordAtt; texCoordAtt.Name_ = "tex0"; texCoordAtt.floatVector_;// = texCoords; NVMeshMender::VertexAttribute tgtSpaceAtt; tgtSpaceAtt.Name_ = "tangent"; NVMeshMender::VertexAttribute binormalAtt; binormalAtt.Name_ = "binormal"; inputAtts.push_back(posAtt); inputAtts.push_back(triIndAtt); inputAtts.push_back(norAtt); outputAtts.push_back(posAtt); outputAtts.push_back(triIndAtt); outputAtts.push_back(norAtt); outputAtts.push_back(texCoordAtt); outputAtts.push_back(tgtSpaceAtt); outputAtts.push_back(binormalAtt); // All inputs except for indices are assumed to be sets of 3 floats // "indices" are assumed to be unsigned ints // "tex0" is used for the tangent space calculation // "tex0" is the only coordinate set generated, and the texture matrix applies only to it // All unknown attribute types, including "tex1", "tex2", "random_attribute", "weights", "bones", etc. // are simply passed through. They will be duplicated as needed just like positions, normals, etc. bool bSuccess = aMender.Munge( inputAtts, // these are my positions & indices outputAtts, // these are the outputs I requested, plus extra stuff generated on my behalf 3.141592654f / 2.5f, // tangent space smooth angle NULL, // no Texture matrix applied to my tex0 coords FixTangents, // fix degenerate bases & texture mirroring FixCylindricalTexGen // handle cylidrically mapped textures via vertex duplication WeightNormalsByFaceSize // weight vertex normals by the triangle's size ); if ( !bSuccess ) return false; vpos = outputAtts[0].floatVector_; // Note that there may be more vertices than you sent in. vnor = outputAtts[2].floatVector_; std::vector<float> texCoords = outputAtts[3].floatVector_; // texcoords std::vector<float> vtgt = outputAtts[4].floatVector_; // tgts triIndices = outputAtts[1].intVector_; // new indices. std::vector<float> vbin = outputAtts[5].floatVector_; // binormals. // Now the outputAtts may contain more vertex then you sent in ! // This is because in handling tangent space smoothing, and solving texture mirroring & // cylindrical texture wrapping problems, we partially duplicate vertices. // All attributes are duplicated, even unknowns. // You may also get things you didn't ask for. For instance, if you ask for tangent space, // in other words, you ask for "tangent" or "binormal", you will get "normal", "tex0", // "tangent" and "binormal". You can then ignore things in the output vector that you don't want. // If you ask for FixCylindricalTexGen, it will fix any absolute change in texture coordinates > 0.5 // across a single edge. Therefore, if you pass in a single quad or cube, it won't work. Any more // complicated or tessellated mesh should work fine.******************************************************************************/#include <vector>#include <string>class NVMeshMender{ private : mutable std::vector< std::string > LastErrors_; struct Edge { unsigned int v0; unsigned int v1; unsigned int face; unsigned int face2; bool operator==( const Edge& rhs ) const { return ( ( v0 == rhs.v0 ) && ( v1 == rhs.v1 ) ); } bool operator<( const Edge& rhs ) const { if ( v0 < rhs.v0 ) { return true; } if ( v0 > rhs.v0 ) { return false; } return ( v1 < rhs.v1 ); } }; public : void SetLastError( const std::string& rhs ) const { LastErrors_.push_back( rhs ); } std::string GetLastError() const { std::string aString; if ( LastErrors_.size() > 0 ) { aString = LastErrors_.back(); } return aString; } struct VertexAttribute { std::string Name_; typedef std::vector< int > IntVector; IntVector intVector_; typedef std::vector< float > FloatVector; FloatVector floatVector_; VertexAttribute& operator=( const VertexAttribute& rhs ) { Name_ = rhs.Name_; intVector_ = rhs.intVector_; floatVector_ = rhs.floatVector_; return *this; } VertexAttribute( const char* pName = "" ) : Name_(pName) {;} VertexAttribute( const VertexAttribute& rhs ) { *this = rhs; } bool operator==( const VertexAttribute& rhs ) { return ( Name_ == rhs.Name_ ); } bool operator<( const VertexAttribute& rhs ) { return ( Name_ < rhs.Name_ ); } }; typedef std::vector< VertexAttribute > VAVector; enum Option { FixTangents, DontFixTangents, FixCylindricalTexGen, DontFixCylindricalTexGen, WeightNormalsByFaceSize, DontWeightNormalsByFaceSize }; bool Munge( const NVMeshMender::VAVector& input, NVMeshMender::VAVector& output, const float bSmoothCreaseAngleRadians = 3.141592654f / 3.0f, const float* pTextureMatrix = 0, const Option _FixTangents = FixTangents, const Option _FixCylindricalTexGen = FixCylindricalTexGen, const Option _WeightNormalsByFaceSize = WeightNormalsByFaceSize ); bool MungeD3DX( const NVMeshMender::VAVector& input, NVMeshMender::VAVector& output, const float bSmoothCreaseAngleRadians = 3.141592654f / 3.0f, const float* pTextureMatrix = 0, const Option _FixTangents = FixTangents, const Option _FixCylindricalTexGen = FixCylindricalTexGen, const Option _WeightNormalsByFaceSize = WeightNormalsByFaceSize );};#endif //_NVMeshMender_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -