Меня понятное дело это не устраивает ...
И я пытаюсь юзать gluLookAt
Например как то так...
В OpenGL неудобная камера. Понятно что Вам хочется разобраться. Лично мне пришлось нарисовать и прорешать задачу проектирования. А вот для задачи стерео зрения надо действовать на результат. Вы должны реализовать свой класс камеры.
Чтобы у неё была позиция в 3-д мири и все объекты вы размещаете так же в абсолютных координатах мира.
Как в OGRE3D
radius:=0.3;
centerX:=0; centery:=0; centerZ:=0;
// rx:= 0; ry:= 0;
rx := View[0,0]; //элемент матрицы явно реагирующий на вращение вокруг оси Y
ry := View[0,1];//элемент матрицы явно реагирующий на вращение вокруг оси X
eyeX := centerX + radius*cos(ry)*sin(rx);
eyeY := centerY + radius*sin(ry)*sin(rx);
eyeZ := centerZ + radius*cos(rx);
Тут чушь написана. Вам следует прочитать про матрицу вращений
https://wiki.sources.ru/doku.php?id=art ... 1%82%D0%B0Для трекинга я реализовал так.
- Код: Выделить всё
// создание матрицы вращения вокруг оси z
//стр 291-292 Ф.Хилл OpenGL. Программирование компьютерной графики(2002)
function buildRotatematrixZ(Angle:Real):TMatrix44;
var c,s:Real;
begin
c:=Cos(Angle); S:=Sin(Angle);
Result[0,0]:=c; Result[0,1]:=-s; Result[0,2]:=0; Result[0,3]:=0;
Result[1,0]:=s; Result[1,1]:=c; Result[1,2]:=0; Result[1,3]:=0;
Result[2,0]:=0; Result[2,1]:=0; Result[2,2]:=1; Result[2,3]:=0;
Result[3,0]:=0; Result[3,1]:=0; Result[3,2]:=0; Result[3,3]:=1;
end;
// создание матрицы вращения вокруг оси x
//стр 291-292 Ф.Хилл OpenGL. Программирование компьютерной графики(2002)
function buildRotatematrixX(Angle:Real):TMatrix44;
var c,s:Real;
begin
c:=Cos(Angle); S:=Sin(Angle);
Result[0,0]:=1; Result[0,1]:=0; Result[0,2]:=0; Result[0,3]:=0;
Result[1,0]:=0; Result[1,1]:=c; Result[1,2]:=-s; Result[1,3]:=0;
Result[2,0]:=0; Result[2,1]:=s; Result[2,2]:=c; Result[2,3]:=0;
Result[3,0]:=0; Result[3,1]:=0; Result[3,2]:=0; Result[3,3]:=1;
end;
// создание матрицы вращения вокруг оси y
//стр 291-292 Ф.Хилл OpenGL. Программирование компьютерной графики(2002)
function buildRotatematrixY(Angle:Real):TMatrix44;
var c,s:Real;
begin
c:=Cos(Angle); S:=Sin(Angle);
Result[0,0]:=c; Result[0,1]:=0; Result[0,2]:=-s; Result[0,3]:=0;
Result[1,0]:=0; Result[1,1]:=1; Result[1,2]:=0; Result[1,3]:=0;
Result[2,0]:=s; Result[2,1]:=0; Result[2,2]:=c; Result[2,3]:=0;
Result[3,0]:=0; Result[3,1]:=0; Result[3,2]:=0; Result[3,3]:=1;
end;
// https://wiki.sources.ru/doku.php?id=articles:%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D0%B0_%D0%BF%D0%BE%D0%B2%D0%BE%D1%80%D0%BE%D1%82%D0%B0
function buildWordView(Yaw,Pitch,Roll:Real; T:TPoint3D):TMatrix44;
var RotR, RotP, RotY:TMatrix44;
begin
Result:=IdentityMatrix44;
RotR:=buildRotatematrixZ(Roll); // Меняем Y, Z
RotP:=buildRotatematrixX(Pitch);
RotY:=buildRotatematrixY(Yaw);
Result:=MatrixMulMatrix(RotY,Result);
Result:=MatrixMulMatrix(RotP,Result);
Result:=MatrixMulMatrix(RotR,Result);
Result[0,3]:=T.x;
Result[1,3]:=T.y;
Result[2,3]:=T.z;
Result[3,3]:=1;
end;
Что-то я запутался ... Изображение
Это матрица для glMultMatrixd...
С первыми тремя векторами более менее понятно, но что за "трансформация"?
Это не трансформация. Это структуру упаковали в матрицу. Абсолютно бесполезная вещь.
- Код: Выделить всё
// Создаёт структуру камеры
// Yaw,Pitch,Roll - в градусах
// NearPlan - размер передней плоскости на которую идёт проекция
// В чем-то схож с размером матрицы
function Cam(Yaw,Pitch,Roll:Real; T:TPoint3D; Fov, NearPlane,k,a:Real):TCam;
begin
Result.Yaw:=Rad(Yaw);
Result.Pitch:=Rad(Pitch);
Result.Roll:=Rad(Roll);
Result.T:=T;
Result.D:=NearPlane*FovToFocal(Rad(Fov)); // Примечание для метода оптимизации необходимо для нормировки
Result.k:=k*0.000001;
Result.a:=a;
Result.NearPlane:=NearPlane;
end;
// Целевая функция переводит точки 3-х мерного пространства в 2-х мерные точки камеры.
// Yaw,Pitch,Roll и T положение камеры в мировых координатах
// D,k,a внутренние параметры камеры.
function F(v:TPoint3D; Cam:TCam):TPoint2D; overload;
var WordView,Perspective, Project:TMatrix44;
V4:TPoint4D;
begin
v4:=Point4D(v);
WordView:=buildWordView(Cam.Yaw,Cam.Pitch,Cam.Roll,Neg(Cam.T));
Perspective:=buildPerspectiveMatrix(Cam.D);
Project:=MatrixMulMatrix(Perspective,WordView);
Result:=S(L(P(v4,Project),Cam.k),Cam.a);
end;
Добавлено спустя 7 минут 24 секунды:Калибровка камеры.
Задача калибровки выяснить параметры камеры. У нас есть шахматная доска и есть камера.
Она снимает шахматную и на экране мы видим рисунок с некоторыми искажениями.
1)Параллельные прямые собираются в точку, а иногда и в три точки. Горизонтальные вертикальные и перпендикулярные каждые линии собираются в свою точку.
2)Квадраты становятся пухлыми округлыми. А плоская доска похожа на подушку или бочку.
3)А если присмотреться, то прямые линии становятся кривыми.
4)А если в кадр попадает девушка, то у ней моментально прибавляются килограммы.
5)Даже неподвижные объекты выглядывают друг из-за друга стараясь попасть в кадр.
6)Ах да и основное чуть не забыли центр доски не по центру кадра.
Задача калибровки устранить все эти искажения. Для чего нам надо разработать модель камеры.
Внешние параметры камеры. Это положение камеры в пространстве мира-сцены.
Положение камеры 3 параметра Cam.T=(x,y,z) и 3 угла Эйлера Cam.YPR=(Yaw,Pitch,Roll)
Еще не стоит забывать что у доски тоже самое.
Положение доски 3 параметра Board.T=(x,y,z) и 3 угла Эйлера Board.YPR=(Yaw,Pitch,Roll)
Они кодируют смещение точек на фото. А так же вращение относительно точки на экране.
*Оставшиеся углы* кодируют сжатие и растяжение по горизонтали и вертикали.
Внутренние параметры.
У камеры есть фокусное расстояние cam.D. Оно связано с углом обзора. И при этом создаёт перспективу.
Есть матрица камеры но она может быть установлена неровно относительно линзы.
Из за чего нарушается соотношение сторон пикселей. cam.Aspect (Выше было cam.a)
В потогонных трубах стоит пара линз которая должна скомпенсировать перспективное искажение.
Однако оптическая система линз не идеальна и создаёт геометрическое искажение по краям картинки более узкая, а по серёдке более. Будем называть это дисторсией линз.
Даже система из единичной линзой не идеальна и с фронтальной и тыльной стороны имеют разный радиус кривизны. Будем использовать приближение первого порядка.
Тут k- это коэффициент определяющий геометрические искажения линзы.
- Код: Выделить всё
// Оператор геометрических искажений от линзы.
function L(x,k,r:Real):Real; Overload;
begin
if ((1+k*r*r)=0) then result:=MaxInt
else
result:=x/(1+k*r*r);
end;
function L(v:TPoint2DReal; k3:Real):TPoint2DReal; Overload;
var r:Real;
begin
r:=Hypot(v.x,v.y); // расстояние от 0 до точки, Hypot точнее чем sqrt.
Result.x:=L(v.x,k3,r);
Result.y:=L(v.y,k3,r);
end;