|
|
我用skyonsky网上的文章实现射线拾取,文章如下:
源码(VC6.0 + OPENGL + WINDOWS2000,调试通过):
bool IntersectTriangle()
{
GLfloat edge1[3];
GLfloat edge2[3];
edge1[0]=V1[0]-V0[0];
edge1[1]=V1[1]-V0[1];
edge1[2]=V1[2]-V0[2];
edge2[0]=V2[0]-V0[0];
edge2[1]=V2[1]-V0[1];
edge2[2]=V2[2]-V0[2];
GLfloat dir[3];
dir[0]=g_farxyz[0]-g_nearxyz[0];
dir[1]=g_farxyz[1]-g_nearxyz[1];
dir[2]=g_farxyz[2]-g_nearxyz[2];
GLfloat w = (GLfloat)sqrt((double)pow(dir[0],2.0)+(double)pow(dir[1],2.0)+(double)pow(dir[2],2.0));
dir[0] /= w;
dir[1] /= w;
dir[2] /= w;
GLfloat pvec[3];
pvec[0]= dir[1]*edge2[2] - dir[2]*edge2[1];
pvec[1]= dir[2]*edge2[0] - dir[0]*edge2[2];
pvec[2]= dir[0]*edge2[1] - dir[1]*edge2[0];
GLfloat det ;
det = edge1[0]*pvec[0]+edge1[1]*pvec[1]+edge1[2]*pvec[2];
GLfloat tvec[3];
if( det > 0 )
{
tvec[0] = g_nearxyz[0] - V0[0];
tvec[1] = g_nearxyz[1] - V0[1];
tvec[2] = g_nearxyz[2] - V0[2];
}
else
{
tvec[0] = V0[0] - g_nearxyz[0];
tvec[1] = V0[1] - g_nearxyz[1];
tvec[2] = V0[2] - g_nearxyz[2];
det = -det ;
}
if( det < 0.0001f ) return false;
GLfloat u ;
u = tvec[0]*pvec[0]+ tvec[1]*pvec[1]+ tvec[2]*pvec[2];
if( u < 0.0f || u > det ) return false;
GLfloat qvec[3];
qvec[0]= tvec[1]*edge1[2] - tvec[2]*edge1[1];
qvec[1]= tvec[2]*edge1[0] - tvec[0]*edge1[2];
qvec[2]= tvec[0]*edge1[1] - tvec[1]*edge1[0];
GLfloat v;
v = dir[0]*qvec[0]+dir[1]*qvec[1]+dir[2]*qvec[2];
if( v < 0.0f || u + v > det ) return false;
GLfloat t = edge2[0]*qvec[0]+edge2[1]*qvec[1]+edge2[2]*qvec[2];
GLfloat fInvDet = 1.0f / det;
t *= fInvDet;
u *= fInvDet;
v *= fInvDet;
return true;
}
void pick(GLfloat xpos,GLfloat ypos)
{
xpos,ypos;
GLint viewport[4];
GLdouble mvmatrix[16],projmatrix[16];
GLint realy;
GLdouble wx,wy,wz;
glGetIntegerv(GL_VIEWPORT,viewport);
glGetDoublev(GL_MODELVIEW_MATRIX,mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX,projmatrix);
realy = viewport[3]-(GLint)ypos -1;// 左下角为坐标原点
gluUnProject((GLdouble)xpos,(GLdouble)realy,0.0,mvmatrix,projmatrix,viewport,&wx,&wy,&wz);
g_nearxyz[0] = (GLfloat)wx;
g_nearxyz[1] = (GLfloat)wy;
g_nearxyz[2] = (GLfloat)wz;////
gluUnProject((GLdouble)xpos,(GLdouble)realy,1.0,mvmatrix,projmatrix,viewport,&wx,&wy,&wz);
g_farxyz[0] = (GLfloat)wx;
g_farxyz[1] = (GLfloat)wy;
g_farxyz[2] = (GLfloat)wz;////
g_color = 0.0;
if(IntersectTriangle()) g_color=1.0;
}
GLfloat V0[3]={1.0,0.0,-1.0 };
GLfloat V1[3]={0.0,1.0,-1.0 };
GLfloat V2[3]={0.0,0.0,-2.0 };
Void DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(g_color,0.0,1.0);
glVertex3fv(V0);// 如果加了glTranslatef之类的变换函数,射线应该反向变化
glVertex3fv(V1);
glVertex3fv(V2);
glEnd();
SwapBuffers(hDC);
}
}
我的程序里面使用了glTranslate变换函数,拾取出现了变换的反向偏移,文章里面有一句提示“如果加了glTranslatef之类的变换函数,射线应该反向变化”,是不是这个问题,为什么会出现这种情况,“射线应该反向变化”应该怎么做,是什么射线反向变化,谢谢!! |
|