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);
}
这样才可跟据平滑组导出直实的顶点法线~
3ds max 中平滑组顶点法线的导出
最新推荐文章于 2021-06-17 15:05:18 发布