// Converts Screen X Y coordinates into Ray in the world space
procedure TKMViewport.ScreenToWorld(X, Y: Integer; out ray: TKMVertex3Ray);
var
m: TMatrix4;
vEye, vDst: TKMVertex4;
begin
// Берем точки ближней и дальней плоскости видимой области (фрустума)
// Вычисляем положение курсора в координатах от -1 до +1 по XY и 0..1 по Z
vEye := TKMVertex4.New(X / fFrameWidth * 2 - 1, 1 - Y / fFrameHeight * 2, 0, 1);
vDst := TKMVertex4.New(X / fFrameWidth * 2 - 1, 1 - Y / fFrameHeight * 2, 1, 1);
// Будем умножать на инвертированные матрицы Проекции и Вида
m := fMatViewProj.Inverse;
vEye := vEye * m;
vDst := vDst * m;
// Итого получаем луч в мировом пространстве
ray.Start := TKMVertex3.New(vEye.X, vEye.Y, vEye.Z) / vEye.W;
ray.Endpoint := TKMVertex3.New(vDst.X, vDst.Y, vDst.Z) / vDst.W;
end;
例如,像这样(见评论):
接下来如何处理光束取决于您。它通常用于命中测试。