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


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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值