我有一个项目,我必须读取OBJ文件并使用GLUT显示模型。即时通讯阅读和显示模型正常,但我不能正常工作正常。我已经将所有面部保存在具有x,y,z的3个vtx [](=点)数组的Faces []数组中,并且还使用x,y,z坐标保存了法线。我计算了2个矢量,它们对应于每个面的3个顶点中的每一个,我得到它们的交叉积,我将它标准化,然后将它的x,y,z坐标添加到Normal参数(这样如果有多个对于每个顶点,我们为它们添加一个类似于所有法向量的平均值的东西)并且我再次标准化。当我打印出一些Normal坐标以查看发生了什么时,它打印出0,0,(奇怪的东西)为x,y,z。无论如何这里是代码。
for (int i = 0 ; i<triangle_index; i++)
{
float ux,uy,uz,vx,vy,vz,nn,nx,ny,nz;
//get vectors from first vertex of face
ux= Faces[triangle_index].vtx[1].x - Faces[triangle_index].vtx[0].x ;
uy= Faces[triangle_index].vtx[1].y - Faces[triangle_index].vtx[0].y ;
uz= Faces[triangle_index].vtx[1].z - Faces[triangle_index].vtx[0].z ;
vx= Faces[triangle_index].vtx[2].x - Faces[triangle_index].vtx[0].x ;
vy= Faces[triangle_index].vtx[2].y - Faces[triangle_index].vtx[0].y ;
vz= Faces[triangle_index].vtx[2].z - Faces[triangle_index].vtx[0].z ;
//CrossProduct
nx = (uy*vz) - (vy*uz);
ny = (vx*uz) - (ux*vz);
nz = (ux*vy) - (uy*vx);
//Length
nn = sqrt((nx*nx)+(ny*ny)+(nz*nz));
//Normalize
nx = nx/nn;
ny = ny/nn;
nz = nz/nn;
//Save to Vertex.Normal (plus any previous data)
Faces[triangle_index].vtx[0].norm.x =(Faces[triangle_index].vtx[0].norm.x + nx);
Faces[triangle_index].vtx[0].norm.y =(Faces[triangle_index].vtx[0].norm.y + ny);
Faces[triangle_index].vtx[0].norm.z =(Faces[triangle_index].vtx[0].norm.z + nz);
//get length again
nn = sqrt((Faces[triangle_index].vtx[0].norm.x*Faces[triangle_index].vtx[0].norm.x)+(Faces[triangle_index].vtx[0].norm.y*Faces[triangle_index].vtx[0].norm.y)+(Faces[triangle_index].vtx[0].norm.z*Faces[triangle_index].vtx[0].norm.z));
//Normalize again
Faces[triangle_index].vtx[0].norm.x =(Faces[triangle_index].vtx[0].norm.x)/nn;
Faces[triangle_index].vtx[0].norm.y =(Faces[triangle_index].vtx[0].norm.y)/nn;
Faces[triangle_index].vtx[0].norm.z =(Faces[triangle_index].vtx[0].norm.z)/nn;
//---------------Same For Second Vertex of the Same Face---------------------------/
ux= Faces[triangle_index].vtx[2].x - Faces[triangle_index].vtx[1].x ;
uy= Faces[triangle_index].vtx[2].y - Faces[triangle_index].vtx[1].y ;
uz= Faces[triangle_index].vtx[2].z - Faces[triangle_index].vtx[1].z ;
vx= Faces[triangle_index].vtx[0].x - Faces[triangle_index].vtx[1].x ;
vy= Faces[triangle_index].vtx[0].y - Faces[triangle_index].vtx[1].y ;
vz= Faces[triangle_index].vtx[0].z - Faces[triangle_index].vtx[1].z ;
nx = (uy*vz) - (vy*uz);
ny = (vx*uz) - (ux*vz);
nz = (ux*vy) - (uy*vx);
nn = sqrt((nx*nx)+(ny*ny)+(nz*nz));
nx = nx/nn;
ny = ny/nn;
nz = nz/nn;
Faces[triangle_index].vtx[1].norm.x =(Faces[triangle_index].vtx[1].norm.x + nx);
Faces[triangle_index].vtx[1].norm.y =(Faces[triangle_index].vtx[1].norm.y + ny);
Faces[triangle_index].vtx[1].norm.z =(Faces[triangle_index].vtx[1].norm.z + nz);
nn =sqrt((Faces[triangle_index].vtx[1].norm.x*Faces[triangle_index].vtx[1].norm.x)+(Faces[triangle_index].vtx[1].norm.y*Faces[triangle_index].vtx[1].norm.y)+(Faces[triangle_index].vtx[1].norm.z*Faces[triangle_index].vtx[1].norm.z));
Faces[triangle_index].vtx[1].norm.x =(Faces[triangle_index].vtx[1].norm.x)/nn;
Faces[triangle_index].vtx[1].norm.y =(Faces[triangle_index].vtx[1].norm.y)/nn;
Faces[triangle_index].vtx[1].norm.z =(Faces[triangle_index].vtx[1].norm.z)/nn;
//------------------Again for number three--------------------------------
ux= Faces[triangle_index].vtx[0].x - Faces[triangle_index].vtx[2].x ;
uy= Faces[triangle_index].vtx[0].y - Faces[triangle_index].vtx[2].y ;
uz= Faces[triangle_index].vtx[0].z - Faces[triangle_index].vtx[2].z ;
vx= Faces[triangle_index].vtx[1].x - Faces[triangle_index].vtx[2].x ;
vy= Faces[triangle_index].vtx[1].y - Faces[triangle_index].vtx[2].y ;
vz= Faces[triangle_index].vtx[1].z - Faces[triangle_index].vtx[2].z ;
nx = (uy*vz) - (vy*uz);
ny = (vx*uz) - (ux*vz);
nz = (ux*vy) - (uy*vx);
nn = sqrt((nx*nx)+(ny*ny)+(nz*nz));
nx = nx/nn;
ny = ny/nn;
nz = nz/nn;
Faces[triangle_index].vtx[2].norm.x =(Faces[triangle_index].vtx[2].norm.x + nx);
Faces[triangle_index].vtx[2].norm.y =(Faces[triangle_index].vtx[2].norm.y + ny);
Faces[triangle_index].vtx[2].norm.z =(Faces[triangle_index].vtx[2].norm.z + nz);
nn = sqrt((Faces[triangle_index].vtx[2].norm.x*Faces[triangle_index].vtx[2].norm.x)+(Faces[triangle_index].vtx[2].norm.y*Faces[triangle_index].vtx[2].norm.y)+(Faces[triangle_index].vtx[2].norm.z*Faces[triangle_index].vtx[2].norm.z));
Faces[triangle_index].vtx[2].norm.x =(Faces[triangle_index].vtx[2].norm.x)/nn;
Faces[triangle_index].vtx[2].norm.y =(Faces[triangle_index].vtx[2].norm.y)/nn;
Faces[triangle_index].vtx[2].norm.z =(Faces[triangle_index].vtx[2].norm.z)/nn;
}
如果我添加此循环只是为了看看在计算法线之后发生了什么
for (int i =0 ; i<100;i++)
cout << "n "<< Faces[i].vtx[0].norm.x<< " "<< Faces[i].vtx[0].norm.x <<" "<< Faces[i].vtx[0].norm.x <<"\n";
我为norm.x,y,z得到全零。 任何人都可以看到代码有什么问题吗?
答案 0 :(得分:1)
您在任何地方使用triangle_index
进行数组索引:
ux= Faces[triangle_index].vtx[1].x - Faces[triangle_index].vtx[0].x ;
uy= Faces[triangle_index].vtx[1].y - Faces[triangle_index].vtx[0].y ;
uz= Faces[triangle_index].vtx[1].z - Faces[triangle_index].vtx[0].z ;
我认为您想要使用循环索引:
ux= Faces[i].vtx[1].x - Faces[i].vtx[0].x ;
uy= Faces[i].vtx[1].y - Faces[i].vtx[0].y ;
uz= Faces[i].vtx[1].z - Faces[i].vtx[0].z ;
你需要在整个循环中解决这个问题。
此外,为了正确平均顶点处的法线,您应该只在这个循环中累积它们,并在新的第二个循环中重新规范化它们。也就是说,将这两个步骤分为两个步骤:
Faces[i].vtx[0].norm.x += nx;
Faces[i].vtx[0].norm.y += ny;
Faces[i].vtx[0].norm.z += nz;
和
nn = sqrt( (Faces[i].vtx[0].norm.x*Faces[i].vtx[0].norm.x)
+ (Faces[i].vtx[0].norm.y*Faces[i].vtx[0].norm.y)
+ (Faces[i].vtx[0].norm.z*Faces[i].vtx[0].norm.z) );
Faces[i].vtx[0].norm.x /= nn;
Faces[i].vtx[0].norm.y /= nn;
Faces[i].vtx[0].norm.z /= nn;
这样,与该顶点重合的每个三角形都具有相同的权重。
答案 1 :(得分:0)
您的代码可能完全有效,问题在于您的法线方向。如果在同一平面上有两个三角形在一个点相交,那么在顶点处计算的法线可能是相反的方向(比如,如果这些点在XY平面中,则可以有一个法线[0 0 1]并且其他[0 0 -1]),取决于顶点的顺序。
当你添加这两个向量时,你可能会得到一个长度为零的向量,这会在规范化过程中给你带来麻烦。
我会检查向量的长度,并可能选择“主导方向”来防止这个问题。或者总是指定三角形的值“其质心最接近顶点”,或“具有最低X,Y值的质心”等等。