|
|
〓三维顶点与纹理坐标的映射问题〓
大家新年好!
最近在研究纹理坐标系和lightmap坐标系与顶点之间的映射关系
首要问题应该是先求平面(通常是三角形所在平面)的坐标基(Axis Base)
我首先想到的是求camera坐标系类似的方法(左手系:up*normal=right,normal*right=up,通常up先取(0,+-1,0),除非normal的y分量最大,否则up取成其他,如(0,0,+-1)))。
但总感觉这个方法不太好。
在查看quake3源码的时候发现一个方法,但看了半天没太看明白:
(注:quake3是右手笛卡尔坐标系,即z垂直向上,y指向屏幕里)
//typedef float vec_t;
//typedef vec_t vec3_t[3]; //[0]即x, [1]即y, [2]即z
// NOTE : ComputeAxisBase here and in editor code must always BE THE SAME !
// WARNING : special case behaviour of atan2(y,x) <-> atan(y/x) might not be the same everywhere when x == 0
// rotation by (0,RotY,RotZ) assigns X to normal
void ComputeAxisBase(vec3_t normal,vec3_t texX,vec3_t texY)
{
vec_t RotY,RotZ;
// compute the two rotations around Y and Z to rotate X to normal
RotY = -atan2(normal[2], sqrt(normal[1]*normal[1] + normal[0]*normal[0]));
RotZ = atan2(normal[1], normal[0]);
// rotate (0,1,0) and (0,0,1) to compute texX and texY
texX[0]= -sin(RotZ);
texX[1]= cos(RotZ);
texX[2]= 0;
// the texY vector is along -Z ( T texture coorinates axis )
texY[0]= -sin(RotY)*cos(RotZ);
texY[1]= -sin(RotY)*sin(RotZ);
texY[2]= -cos(RotY);
}
Q1:我大概看出来是通过旋转轴的方式在求,但画个图发现不对啊~~~~~
然后就是求平面的顶点坐标对应的纹理坐标:
//dv->xyz即顶点的三维坐标, s->texMat即纹理坐标变换矩阵
ComputeAxisBase( 顶点所在平面的法线, texX, texY );
x = DotProduct( dv->xyz, texX );
y = DotProduct( dv->xyz, texY );
dv->st[0] = s->texMat[0][0]*x + s->texMat[0][1]*y + s->texMat[0][2]; //即纹理的u或s值
dv->st[1] = s->texMat[1][0]*x + s->texMat[1][1]*y + s->texMat[1][2]; //即纹理的v或t值
Q2:这里的点积DotProduct是做什么的?为什么这样做就把三维顶点变换到平面坐标轴上了呢?
Q3: 请问还有其他方法求吗?
您的任何建议和想法对我都有用。
多谢了!
|
|