如果一个顶点的法线共享多个三角形,我们还需要对此法线进行均值计算,如下伪代码
void CalculationNormalVector()
{
for(int i=0;i<m_Vertices.size();i+=3)
{
Vector3D normal=CrossProduct(
(m_Vertices[i+1].m_Position-m_Vertices[i].m_Position),//A2-A1的点值
(m_Vertices[i+2].m_Position-m_Vertices[i+1].m_Position)//A3-A2的点值
);//计算两边的叉乘
m_Vertices[i].m_NormalVector=normal;//保存法线变量
m_Vertices[i+1].m_NormalVector=normal;
m_Vertices[i+2].m_NormalVector=normal;
}
bool* flag=new bool[m_Vertices.size()];//申请一个标志位
memset(flag,false,sizeof(bool)*m_Vertices.size());//全部清空
for(int i=0;i<m_Vertices.size();i++)
{
if(!flag[i])
{
vector<Vertex*> pointers;
int n=0;
Vector3D sum={0,0,0};
for(int j=i;j<m_Vertices.size();j++)
{
if(m_Vertices[i].m_Position==m_Vertices[j].m_Position)
{//如果两个点有重合
n+=1;
sum=sum+m_Vertices[j].m_NormalVector;//法线向量总和相加
flag[j]=true;
pointers.push_back(&m_Vertices[j]);//保存需要处理的顶点数据
}
}
Vector3D ans=sum/n;
for(auto p:pointers)
{
p->m_NormalVector=ans;//最后将所有需要均值的顶点法线都设置为均值
}
}
}
delete[] flag;
}