3ds max 中平滑组顶点法线的导出

长平狐 发布于 2012/11/19 15:12
阅读 107
收藏 0

                3ds max中导出顶点的法线看似很容易,直接通过mesh->getNormal(i);可以获取,但实际上这样获取的法线不一定对。

实际在3ds max中会常常使用平滑组来对面法线进行指定。这样的结果是一个顶点可能处于多个平滑组中。或者说,一个顶点有N个法线对应。

所以,务必将这种情况修改为一个顶点与一个法线对应。

我的做法是:

           遍历每一个面中的三个顶点。取出法线,并将对应的法线放入对应顶点信息结构的法线容器中。如果已经有相同法线。则直接返回顶点信息结构的新增顶点索引容器中对应的索引做为面顶点索引。否则以新增顶点索引做为面顶点索引。

for(int v = 0 ; v < 3 ; v++)
{
GetVertexNormalUsingSmoothGroup(norm,*mesh,i,mesh->faces[i].v[v]);
norm = norm * NrmMat ;
norm.Normalize();
tFace.mNormal = norm;

                                                       SVertex*tpVertex = &(pMeshNode->m_SubMeshVec.back().m_VertexVec[mesh->faces[i].v[v]]);

if(true == tpVertex->mNormalVec.empty())
{
tpVertex->mNPosX = norm.x ;
tpVertex->mNPosY = norm.z ;
tpVertex->mNPosZ = norm.y ;


tpVertex->mNormalVec.push_back(norm);
tpVertex->mVertexVec.push_back(mesh->faces[i].v[v]);
}
else
{


//法线VEC
vector<Point3>::iterator Iter;
bool tFind = false;
int tVertexIndex = 0;
for(Iter = tpVertex->mNormalVec.begin() ; Iter != tpVertex->mNormalVec.end(); Iter++)
{
if(norm == (*Iter))
{
tFind = true;

if(0 == v)
{
tFace.mVertexIndex1 = tpVertex->mVertexVec[tVertexIndex];
}
else if(1 == v)
{
tFace.mVertexIndex2 = tpVertex->mVertexVec[tVertexIndex];
}
else if(2 == v)
{
tFace.mVertexIndex3 = tpVertex->mVertexVec[tVertexIndex];
}
break;
}
tVertexIndex++;
}
if(false == tFind)
{
tpVertex->mNormalVec.push_back(norm);


SVertex tNewVertex = *tpVertex;
tNewVertex.mNPosX = norm.x ;
tNewVertex.mNPosY = norm.z ;
tNewVertex.mNPosZ = norm.y ;


int tVertexIndex = pMeshNode->m_SubMeshVec.back().m_VertexVec.size();
tpVertex->mVertexVec.push_back(tVertexIndex);
pMeshNode->m_SubMeshVec.back().m_VertexVec.push_back(tNewVertex);


if(0 == v)
{
tFace.mVertexIndex1 = tVertexIndex ;
}
else if(1 == v)
{
tFace.mVertexIndex2 = tVertexIndex ;
}
else if(2 == v)
{
tFace.mVertexIndex3 = tVertexIndex ;
}


}
}



GetVertexNormalUsingSmoothGroup函数:

GetVertexNormalUsingSmoothGroup(Point3& VN, Mesh& mesh, int faceId, int vertexId) 

   // get the "rendered" vertex 
   RVertex *pRVertex = mesh.getRVertPtr(vertexId); 


   // get the face 
   const Face& Face = mesh.faces[faceId]; 


   // get the smoothing group of the face 
   const DWORD smGroup = Face.smGroup; 


   // get the number of normals 
   const int normalCount = pRVertex->rFlags & NORCT_MASK; 


   // check if the normal is specified ... 
   if(pRVertex->rFlags & SPECIFIED_NORMAL) 
   { 
      VN = pRVertex->rn.getNormal(); 
      return; 
   } 
   // ... otherwise, check for a smoothing group 
   else if((normalCount > 0) && (smGroup != 0)) 
   { 
      // If there is only one vertex is found in the rn member. 
      if(normalCount == 1) 
      { 
         VN = pRVertex->rn.getNormal(); 
         return; 
      } 
      else 
      { 
         for(int normalId = 0; normalId < normalCount; normalId++) 
         { 
            if(pRVertex->ern[normalId].getSmGroup() & smGroup) 
            { 
               VN = pRVertex->ern[normalId].getNormal(); 
               return; 
            } 
         } 
      } 
   } 


   // if all failed, return the face normal 
   VN = mesh.getFaceNormal(faceId); 


  
这样才可跟据平滑组导出直实的顶点法线~



原文链接:http://blog.csdn.net/honghaier/article/details/6690725
加载中
返回顶部
顶部