Глава 4. Ориентация и координаты 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Глава 4. Ориентация и координаты



 

В OpenGL существуют две системы координат: глобальная и локальная. Глобальная (она же абсолютная) система координат — это система координат компонента GLSceneViewer. Локальную систему координат имеет каждый объект сцены, включая камеру, источник света и любой другой. То есть абсолютная система координат одна, а локальных — сколько объектов в сцене. В любой локальной системе координат положение объекта это всегда три нуля по всем осям (X=Y=Z=0), а в глобальной не обязательно. Объект может иметь «родителя», и тогда локальная система координат родителя (Parent) станет для него глобальной, а настоящая глобальная (абсолютная) система координат вообще перестанет к нему относиться.

В связи с этим в GLScene у каждого объекта предусмотрена пара функций:

LocalToAbsolute(V:TVector) Возвращает глобальные (абсолютные) координаты вектора, заданные в локальной системе координат вызвавшего объекта. Например, Var V:TVector3f; ... GLSphere1.Position.X:=2; v[0]:=1; r:=GLSphere1.LocalToAbsolute(v); Если запустим отладчик Delphi, увидим, что r=3 Если мы увеличим V на один, то получим r=4 и т.д.
AbsoluteToLocal(V:TVector) Наоборот, превращает абсолютные координаты в локальные.

В OpenGL (и GLScene) принята система координат, в которой ось Y направлена вверх, ось Z вперёд, а X вправо.

 
Это не значит, что мы всегда будем смотреть таким образом. Камера может перемещаться в любую точку сцены и смотреть в
 
любом направлении.

Для того, чтобы камера всегда смотрела на некоторый объект, независимо от его положения, нужно установить этот объект в свойстве TargetObject. После этого камера будет автоматически нацеливаться на объект. Понятно, что координаты камеры и объекта не должны совпадать (в этом случае камера будет просто смотреть из объекта и не видеть его - так же как человек не видит своё лицо).

Чтобы легче было понять, как объекты расположены друг относительно друга и куда они движутся можно включить отображение осей локальных координат объектов — свойство ShowAxes (X — красная ось, Y — зелёная, Z — синяя).

Свойство Position (и не только оно) задаётся типом TGLCoordinates. Он служит для удобной работы с координатами. Его можно менять с помощью значений X, Y, Z прямо в инспекторе объектов. Рассмотрим основные свойства этого типа:

X, Y, Z, W и DirectX/Y/Z/W — собственно координаты

AsVector, AsAffineVector, AsPoint2D, AsString — возвращают координаты в виде четырех-, трех-, двухкомпонентного вектров и строки соответственно. Векторы в GLScene задаются как массивы, в которых [0] — это X, [1] — Y, [2] — Z и [3] — W. Подробнее про векторы см. в Приложении I. «Типы векторов и матриц».

SetPoint — устанавливает координаты для свойства Position (оно имеет смысл точки)

SetVector — аналогично для свойств Direction, Up, Left, Scale (они имеют смысл вектора)

Также у всех объектов есть свойства, регулирующие углы поворота относительно осей: PitchAngle — текущий угол поворота относительно оси X, TurnAngle — Y, RollAngle — Z. Процедуры же Pitch, Turn, Roll поворачивают объект вокруг осей X, Y, Z. Процедура ResetAndPitchTurnRoll сбрасывает текущие значения поворотов и устанавливает новые.

Кроме того, у объектов есть свойства Direction (вектор «вперёд»), Up (вектор «вверх») и Left (вектор «влево»), полностью описывающие положение объекта в пространстве. По сути это направления координатных осей Z, Y, X локальной системы координат объекта относительно родительской. По умолчанию Up направлен по оси Y (имеет значение (0;1;0)) а вектор Direction по оси Z (0;0;1).

Рассмотрим рисунок ниже. Шар имеет Direction (0;0;1), Up (0;1;0) и является родителем для конуса. Каковы Direction и Up конуса? Синяя ось конуса, отображающая Direction, параллельна зеленой оси шара, отображающей его Up, который равен (0;1;0). Следовательно, Direction у конуса тоже (0;±1;0). Зеленая ось конуса (его Up) параллельна красной оси шара (его Left, он по определению равен векторному произведению Direction на Up и численно (1;0;0)). Значит, у конуса Up (±1;0;0).

 

 


Глава 5. Компонент GLCamera

 

Камера, пожалуй, один из главных компонентов каждого проекта. Именно она показывает нам то, что мы создали в сцене. В проектах может быть любое количество камер, но обычно требуется всего одна. Рассмотрим свойства GLCamera:

Свойство Описание
CameraStyle Базовый параметр, отвечающий за способ проецирования объектов на экран. Его эначения: csPerspective:значение по умолчанию, задаётинтуитивно понятную нам перспективную проекцию. Напомню, перспективная проекция определяет, что все объекты будут видны в усечённом конусе. csInfinitePerspective: очень похож на csPerspective. csOrthogonal:используется для создания ортогональной (изометрической) проекции в трёхмерных сценах. При нем не будет перспективных искажений объектов (например, рельсы не будут «пересекаться» вдали). csOrtho2D:используется при создании двухмерных сцен. При выборе этого значения объекты трёхмерной сцены будут видимы, только если свойство GLCamera. Position. Z будет в пределах 0,9…-1.. При нем способ отображения такой же, как и при использовании стандартного класса TCanvas. Управлять видимыми размерами объекта приближением или отдалением камеры не получится, нужно изменять его длину и ширину. csPerspectiveKeepFOV: похоже на csPerspectiveи наcsInfinitePerspective.Различие же в том, что размеры объектов будут относительно размеров экрана, а не GLViewer. Сравните:
DepthOfView Указывает, как далеко может видеть камера. Все объекты дальше этого значения не отображаются.
FocalLength Фокусное расстояние камеры.
NearPlaneBias Передняя отсекающая плоскость. Все, что ближе к камере, чем эта плоскость, не отображается.
Position Позиция камеры. Камера может размещаться в любой точке сцены.
SceneScale Определяет масштаб сцены.
TargetObject Определяет, будет ли камера свободна (nil) или будет ли она автоматически следить за каким-то объектом.

 


Глава 6. Движение

 

Реализуем простое движение камеры. Создайте проект, подобный Hello, GLScene!, и подключите модуль GLKeyboard для работы с клавиатурой. В событии OnProgress каденсера запишите следующее:

if IsKeyDown(VK_ESCAPE) then Close;

 

// Движение вперед/назад по клавишам W/S (Ц/Ы)

if IsKeyDown(ord('W')) then GLCamera1.Move(2*deltaTime);

if IsKeyDown(ord('S')) then GLCamera1.Move(-2*deltaTime);

// Движение вправо/влево по клавишам D/A (В/Ф)

if IsKeyDown(ord('D')) then GLCamera1.Slide(2*deltaTime);

if IsKeyDown(ord('A')) then GLCamera1.Slide(-2*deltaTime);

// Движение влево/вправо по клавишам Z/X (Я/Ч)

if IsKeyDown(ord('Z')) then GLCamera1.Lift(2*deltaTime);

if IsKeyDown(ord('X')) then GLCamera1 Lift(-2*deltaTime);

Запускаем проект и видим, что мы можем перемещать камеру по сцене.

Теперь добавим управление мышью. Это можно сделать двумя способами.

1) Сложный. Поместите из вкладки GLScene Utils на форму GLNavigator . У него в свойстве MovingObject выберите GLCamera1 (это объект, который будет перемещаться). Затем добавьте оттуда же GLUserInterface и установите ему свойство GLNavigator. Свойство MouseSpeed — это скорость реакции мыши, сделаем её равной 10. Во время работы программы нужно вручную активировать этот компонент, также желательно скрыть курсор мыши. Для этого добавьте в Form1.OnCreate строки

GLUserInterface1.MouseLookActive:=true;

GLSceneViewer1.Cursor:=crNone;

А в событие OnProgress Cadencer’а добавьте:

GLUserInterface1.Mouselook;

GLUserInterface1.MouseUpdate;

Всё. Запускаем проект и смотрим, что получилось.

Демка: Demos\meshes\actortwocam

Свойства компонента GLNavigator:

Свойство Описание
AngleLock, MaxAngle, MinAngle Отвечают за блокировку поворотов по вертикали. Блокирует просмотр выше MaxAngle и ниже MinAngle.
AutoUpdateObject Пока ни на что не влияет
InvertHorizontalSteeringWhenUpsideDown Когда UseVirtualUp = True и вертикальный поворот вне 90 градусов, это свойство будет make steering seem inverted, so we «invert» back to normal.
MovingObject Перемещаемый объект сцены.
UseVirtualUp MoveUpWhenMovingForward Если установлено в True, то MoveForward не будет двигать MovingObject по оси Y. Когда установлено в False, MovingObject перемещается туда, куда смотрит камера;в таком случае персонаж будет «ходить по воздуху».

 

2) Более простой. Создадим GLDummyCube и поместим в него камеру. Также объявим две глобальные переменные: xangle: single = 0 и yangle: single = 90. В OnProgress каденсера запишем:

xangle:=(Mouse.CursorPos.X-(Screen.Width div 2))*

0.1/(1+deltaTime);

yangle:=-(Mouse.CursorPos.Y-(Screen.Height div 2))*

0.1/(1+deltaTime);

GLCamera1.Turn(xangle);

GLDummyCube1.Pitch(yangle);

Нельзя вращать камеру сразу по двум осям, т. к. она перекосится, поэтому мы создали DummyCube и вращаем каждый объект только по одной оси.

 


Глава 7. Всё о GLCadencer

 

GLCadencer («каденсер») находится на вкладке GLScene. Это один из важнейших компонентов. Он автоматически вызывается после отрисовки кадра. Время, прошедшее с последнего рендинга, передаётся в событие OnProgress как параметр deltaTime.

Свойство Описание
Enabled Включен или выключен GLCadencer.
FixedDeltaTime Используется, если нужно, чтобы OnProgress вызывалось через одинаковые промежутки времени, а не как только стало возможно. Это позволяет снизить нагрузку на процессор.
MaxDeltaTime Устанавливает максимально возможное значение deltaTime. Однако не следует занижать его — оно ограничено быстродействием процессора.
MinDeltaTime Устанавливает минимальное значение deltaTime, это позволяет разгрузить процессор.
Mode cmManual — программист должен вызывать событие OnProgress вручную; cmASAP — обработчик срабатывает как можно скорее, сразу после рендеринга. Нагрузка процессора в этом режиме обычно около 100%; cmApplicationIdle — каденсер будет срабатывать, когда система простаивает, т. е. не выполняет никаких расчётов. Только один GLCadencer может работать в этом режиме.
Scene Сцена, отрисовки которой дожидается каденсер.
SleepLength После тика каденсер может «отдохнуть». В это время процнссор будет разгружен. Если -1, то каденсер работает постоянно.
TimeMultiplier На это число умножается передаваемое в OnProgress значение deltaTime.
TimeReference cmRTC (RealTimeClock) — каденсер будет привязан к обычному таймеру, отсюда ограничение по фиксации кадров (свойства MinDeltatime и MaxDeltatime) до значения 1/65 секунды;в данном режиме не учитывается FixedDeltatime, а когда MaxDeltaTime и MinDeltaTime равны 0, работает как cmPerformanceCounter; cmPerformanceCounter — высокоточный счётчик, благодаря которому можно использовать FixedDeltatime; cmExternal — режим, когда счётчик обновляется снаружи, вызовом метода Progress.

При завершении программы каденсер следует останавливать, чтобы он не вызвал OnProgress, когда часть используемых объектов уже освобождены.



Поделиться:


Последнее изменение этой страницы: 2016-04-19; просмотров: 1059; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.223.196.59 (0.012 с.)