Code:
procedure TNXGL.GetMouseRay(const mx, my: single; const p, normal: PVector;
rayMove: single);
var viewport: TGLVectori4;
modelM,projM: TGLMatrixd4;
x1,y1,z1,x2,y2,z2: double;
n: TVector;
begin
glGetIntegerv(GL_VIEWPORT,@viewPort);
glGetDoublev(GL_PROJECTION_MATRIX,@projM);
glGetDoublev(GL_MODELVIEW_MATRIX,@modelM);
{$HINTS OFF} // hints about x1..z2 not initialized
gluUnProject(mx,my,modelM[2,3],modelM,projM,viewport,x1,y1,z1);
gluUnProject(mx,my,modelM[2,3]-1,modelM,projM,viewport,x2,y2,z2);
{$HINTS ON}
n.x:=x1-x2; n.y:=y1-y2; n.z:=z1-z2; n:=Norm(n);
if p<>nil then begin
p^.x:=x1+n.x*rayMove;
p^.y:=y1+n.y*rayMove;
p^.z:=z1+n.z*rayMove;
end;
if normal<>nil then normal^:=n;
end;
// Result >= 0 if intersection happens
function RayPlaneIntersect(const rayOrigin, rayDirection,
planeOrigin, planeNormal: TVector; intersection: PVector): single;
var d,numer,denom: single;
begin
d:=planeNormal.x*planeOrigin.x+planeNormal.y*planeOrigin.y+planeNormal.z*planeOrigin.z;
numer:=-planeNormal.x*rayOrigin.x-planeNormal.y*rayOrigin.y-planeNormal.z*rayOrigin.z+d;
denom:=planeNormal.x*rayDirection.x+planeNormal.y*rayDirection.y+planeNormal.z*rayDirection.z;
if denom=0 then begin
result:=-1; exit;
end;
result:=numer/denom;
if intersection<>nil then begin
intersection^.x:=rayOrigin.x+result*rayDirection.x;
intersection^.y:=rayOrigin.y+result*rayDirection.y;
intersection^.z:=rayOrigin.z+result*rayDirection.z;
end;
end;
function TNXGL.MouseRayAtPlane(const mx,my: single; const planePos,planeNormal: TVector): TVector;
var rayOrigin, rayDirection: TVector;
begin
GetMouseRay(mx,my,@rayOrigin,@rayDirection);
rayPlaneIntersect(rayOrigin,rayDirection,planePos,planeNormal,@result);
end;
Bookmarks