3ds max 中平滑組頂點法線的導出


                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); 


  
這樣才可跟據平滑組導出直實的頂點法線~



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com