Возможно вы искали: 'Warbands: Rise of Baro...'

May 09 2025 14:44:34
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 95949629
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18338
• Обзор The Walking ... 18776
• Обзор DMC: Devil M... 19857
• Обзор на игру Valk... 15861
• Обзор на игру Stars! 17745
• Обзор на Far Cry 3 17926
• Обзор на Resident ... 16005
• Обзор на Chivalry:... 17487
• Обзор на игру Kerb... 17962
• Обзор игры 007: Fr... 16592
Превью о играх
• Превью к игре Comp... 17938
• Превью о игре Mage... 14442
• Превью Incredible ... 14699
• Превью Firefall 13453
• Превью Dead Space 3 16318
• Превью о игре SimC... 14705
• Превью к игре Fuse 15422
• Превью Red Orche... 15526
• Превью Gothic 3 16327
• Превью Black & W... 17336
Главная » Статьи » Панель инструментов » ЛКИ-Creator 3D: Взаимодействие с объектами

ЛКИ-Creator 3D: Взаимодействие с объектами

Законы существуют, чтобы их нарушать, однако тот, кто ради временного жертвует вечным, теряет и временное, и вечное.

«Атхарва Веда»


Организация законов управления и взаимодействия — вот о чем пойдет речь в этой статье.

В предыдущих номерах мы с вами создали наш трехмерный мир и заселили его объектами. Мы также научились управлять их перемещениями по отдельности с помощью клавиатуры. Для управления кнопками и другими текстовыми элементами мы также используем мышь. Однако остался открытым важный вопрос — как задать физические законы нашего мира, ведь без этого он весьма далек даже от подобия реальности. Кроме того, хотелось бы иметь возможность управлять объектами посредством такого удобного инструмента, как мышь, как мы это уже делаем с текстовыми элементами. Как скоро увидим, эти задачи связаны и имеют общие методы решения.

Ну, а материалы наших прошлых занятий, а также руководство по двумерному пакету ЛКИ-Creator 2D и микроучебник языка Delphi вы можете найти на нашем диске в разделе «Своими руками».

Перед началом работы нам, как обычно, потребуется переустановить пакет ЛКИ-Creator 3D. Как это делается — описано в предыдущих статьях.

Управление объектами с помощью мыши (Picking)

Предположим, мы хотим щелкнуть левой клавишей по дельфинчику из примера Dolphin и в ответ получить от него некую реакцию: всплеск пузырьков, изменение положения в пространстве и т.п. Нам очевидно, что щелкаем именно по дельфину. Но как выделить нужный объект, имея на руках лишь координаты курсора мыши, тем более — в масштабе окна, а не нашего трехмерного мира? Для этого существует технология, называемая picking (выбор).

Она реализована в стандартном методе ЛКИ-Creator 3D, но, поскольку бывают жизненные ситуации, когда метод выбора объекта нужно переопределить, — разберемся, как работает picking.

Итак...

Что мы знаем

Мы знаем, что нужный нам объект спроектирован на некоторую площадь, окружающую точку, указанную мышью. А на самом деле он спроектирован на окрестность точки p, которая соответствует точке s, выделенной мышью на экране. То есть мы имеем дело с объектом в трехмерном пространстве и его проекцией.

Итак, при щелчке должен быть выбран объект, который пересекает луч, проходящий через точку p, и, соответственно, проекция этого объекта включает точку p. Для того чтобы провести луч, нужно две точки, поэтому в качестве начала луча выберем местоположение камеры — точку с проекцией в центре координат. Соответственно, нужно построить луч для выбора объектов (picking ray), а затем перебрать объекты игрового мира и проверить каждый на пересечение с лучом. Сразу следует отметить, что перебор может занять очень много времени и ресурсов, если объектов много. В этом случае можно рекомендовать разбить игровое пространство на домены, проверить, в какой домен попадает луч, и перебирать объекты только из данного домена.

В итоге получаем следующие шаги алгоритма выбора нужного объекта (picking algorithm).

Зная координаты оконной точки щелчка мыши s, вычисляем соответствующую точку p в области проекции окна. Вычисляем луч, проходящий через точку p и позицию камеры в начале координат. Трансформируем луч в игровое пространство. Находим объект, который пересекает луч. Это и будет нужный нам объект.

Пройдем этот алгоритм по шагам.

Вычисление луча
px := 0;
py := 0;

m_pd3dDevice.GetViewport(vp);
m_pd3dDevice.GetTransform(D3DTS_PROJECTION, proj);

px := ((( 2.0*x) / vp.dwWidth) – 1.0) / proj._11;
py := (((-2.0*y) / vp.dwHeight) + 1.0) / proj._22;

ray.dvPos.x := 0.0;
ray.dvPos.y := 0.0;
ray.dvPos.z := 0.0;

ray.dvDir.x := px;
ray.dvDir.y := py;
ray.dvDir.z := 1.0;

Вычисление луча

Для вычисления луча воспользуемся параметрическим уравнением прямой p(t) = p0 + tu, где p0 — точка, откуда начинается луч, а u — вектор, указывающий направление луча. Точка начала луча совпадает с положением камеры в начале координат, поэтому p0 = (0, 0, 0). Если точка p находится на плоскости проекции и луч проходит через нее, то вектор направления u вычисляется так: u = p – p0 = (px, py, 1) – (0, 0, 0) = p. То есть тут идет чистая векторная и матричная математика в пространстве. Приходится приводить некоторые выкладки, без них никак. Вообще работа в трехмерном пространстве несколько сложнее, чем в 2D.

Таким образом можно получить нужный луч, используя координаты x и y точки щелчка мышью в пространстве окна монитора.


Трансформация луча
D3DXVec3TransformCoord(
  TD3DXVector3(ray.dvPos),
  TD3DXVector3(ray.dvPos),
  T
);

D3DXVec3TransformNormal(
  TD3DXVector3(ray.dvDir),
  TD3DXVector3(ray.dvDir),
  T
);

Трансформация луча

Луч, который мы вычислили, принадлежит пространству обзора. Однако для определения существования пересечения с объектом и объект, и луч должны находиться в одном пространстве координат. Естественно, трансформировать луч в объектное пространство намного проще и быстрее, чем тащить все объекты игрового мира в пространство луча. Чтобы трансформировать луч r(t) = p0 + tu, нужно трансформировать точку p0 и направление луча — вектор u — с помощью матрицы трансформации.

Небольшое пояснение. D3DXVec3TransformCoord — это функция для трансформации точек, а D3DXVec3TransformNormal — векторов.

Проверка пересечения луча с объектом

Чтобы найти объект, который пересекает луч, нужно последовательно перебрать все полигоны, из которых состоит поверхность объекта, и проверить, есть ли точка пересечения какого-либо полигона и луча. Этот метод дает правильный результат, но он требует много ресурсов, особенно если полигонов много. На практике применяют другие методы: построение ограничивающих объемов (Bounding Volume). Самые распространенные ограничивающие объемы — это сфера (Bounding Sphere) и коробка (Bounding Box), которая бывает следующих видов: коробка со сторонами, параллельными осям координат в мировой системе (Axis-Aligned Bounding Box (AABB)), и произвольно ориентированная коробка (Oriented Bounding Box (OBB)). К сожалению, приходится вводить много новых понятий, но без этого практически никак. Ничего, скоро все закончится.

Так вот, методы, которые применяются для picking, практически без изменений могут быть применены и к определению правил взаимодействия объектов в игровом пространстве (Collision Detection).

Для простоты мы будем пользоваться ограничивающей сферой. Для вычисления этого вида ограничивающего объема для объекта в библиотеке DirectX существует функция D3DXComputeBoundingSphere. Можно также вычислить ограничивающую сферу и самому.

Для сферы определяющими параметрами являются радиус (pRadius) и положение центра (pCenter). Для их вычисления необходимо найти максимальную и минимальную по координатам точки объекта, то есть его вершины (Vertex).


Построение ограничивающего объема (сферы) для объекта
p := World.Objects.Mesh.Vertices;
D3DX8.D3DXComputeBoundingSphere(
p,
World.Objects.Mesh.NumVertices,
D3DFVF_RESERVED0,
BSphere._center,
BSphere._radius);

Найдем объект, который пересекает луч. Это и будет нужный нам объект.

Для этого проверим, существует ли точка пересечения сферы и луча. Радиус r и центр сферы c заданы, поэтому используем следующее уравнение: длина вектора p – c должна быть равна радиусу сферы r, если точка p принадлежит сфере.

Чтобы определить, как и где луч p(t) = p0 + tu пересекает сферу, мы подставим уравнение луча в уравнение сферы и найдем решение и параметр t, который определит точки пересечения.

Подставим p(t) = p0 + tu в |p(t) – c| – r = 0, получим |p0 + tu – c| – r = 0 и в итоге

Ax2 + Bx + C = 0,

где

A = u · u, B = 2(u · (p0 – c)) è C = (p0 – c) · (p0 – c) – r2.


Проверка пересечения луча с объектом
// v := ray.dvPos – sphere._center;
D3DXVec3Subtract(v,
TD3DXVector3(sphere._center),
TD3DXVector3(ray.dvPos)
);

// вычисляем параметры квадратичного уравнения
b := 2.0 * D3DXVec3Dot(TD3DXVector3(ray.dvDir), v);
c := D3DXVec3Dot(v, v) – (sphere._radius * sphere._radius);

// находим дискриминант
discriminant := (b * b) – (4.0 * c);
if discriminant < 0.0 then Result := false;
discriminant := sqrt(discriminant);

// находим два корня уравнения
s0 := (-b + discriminant) / 2.0;
s1 := (-b – discriminant) / 2.0;

// нас интересует только случай, когда оба корня больше или равны 0, тогда наш луч пересекает ограничивающую сферу
if (s0 >= 0.0) and (s1 >= 0.0) then Result := true;
Result := false;

Если качественно оценивать решения t1 и t0 этого уравнения, то можно выделить несколько общих случаев.

Луч не пересекает сферу; и t0, и t1 — мнимые корни уравнения. Луч находится перед сферой; и t0, и t1 меньше 0. Луч внутри сферы; один из корней больше 0, а другой — меньше. Положительный по знаку корень дает точку пересечения луча и сферы. Луч пересекает сферу; и t0, и t1 больше 0. Луч касается сферы, t0 = t1 и больше 0.
Выбор объекта по щелчку мыши
// пробегаем по всем объектам игрового мира
for i:=0 to World.NObj-1 do begin

p := World.Objects.Mesh.Vertices;

// вычисляем ограничивающую сферу
D3DX8.D3DXComputeBoundingSphere(
p,
World.Objects.Mesh.NumVertices,
D3DFVF_RESERVED0,
BSphere._center,
BSphere._radius);



// проводим проверку на пересечение луча и сферы
if raySphereIntersectionTest(ray, BSphere) then begin
World.IntersectActionExecute(World.Objects.Id);
break;
end;
end;

Для того чтобы привязать picking к щелчку мыши, мы вставим процедуру проверки пересечения в обработчик щелчков мыши TLKI3dForm.MouseProcess.


В итоге для примера с дельфином мы получим следующую картину - щелчок мыши по дельфинчику вызывает всплеск частиц, как и при задании соответствующей команды с клавиатуры.

Реализация метода в ЛКИ-Creator

У всех игровых объектов есть свойство IsPickingEnabled, определяющее, можно ли выбирать объект мышью. Например, если у вас в игре есть звезды, планеты, ракеты и вражеские корабли, но стрелять можно только по последним — у всех остальных это свойство надо установить в false, а у кораблей — в true. Рекомендуется всегда отключать picking у «лишних» объектов во избежание неточностей и траты лишних ресурсов.

То же свойство есть и у формы: оно должно быть установлено в true, если вы хотите, чтобы picking в принципе работал.

Далее, чтобы ввести у себя поддержку picking’а, вам осталось сделать только одно: переопределить метод TLKI3dGameWorld.IntersectActionExecute(ObjId : integer). Этот метод отвечает за действия, которые совершает игровой мир в момент щелчка мышью по какому-то объекту. Параметр — идентификационный номер этого объекта.

В этом методе вы можете описать все что угодно: движение, стрельбу, лечение и так далее, в зависимости от положения объекта, статуса игрока и так далее.

Для того чтобы организовать свой метод picking, необходимо переопределить методы CalcPickingRay, TransformRay, raySphereIntersectionTest, LKI3dPicking для TLKI3dForm и ComputeBoundingSphere для TLKI3dGameObject.

Проверка столкновений объектов

Что такое Collision Detection и зачем оно нужно?

Перед человеком, решившим заняться трехмерной графикой, очень скоро (обычно сразу же после появления на экране первой созданной самостоятельно сцены) встает вопрос, похожий на эти: «А как сделать так, чтобы машинки сталкивались?», или «Как сделать, чтобы человек не проходил сквозь стены и мебель?», или «Как сделать, чтобы мячик скакал по комнате?».

Вот как раз определением факта столкновения объектов (а в идеале еще и определением точек контакта объектов при столкновении) и занимается Collision Detection. Для двумерного игрового мира мы уже умеем это делать. В 3D все похоже, но несколько сложнее. Предположим, у нас есть два объекта — корабль и ракета. Их поверхности в 3D мире состоят из связанных полигонов. Наиболее распространенный класс полигонов — треугольник, но есть и другие. Нужно перебрать все полигоны одного объекта и проверить, существует ли пересечение их с полигонами другого объекта. Хотя на самом деле довольно часто для уменьшения расчетов вместо самих объектов используют так называемые Bounding Volumes, такие как Bounding Sphere, Bounding Box или объект с минимальным уровнем детализации (в виде выпуклого многогранника). Это нам известно из предыдущей главы про picking.

Конечно, от этого страдает точность, что проявляется как столкновение объектов, которые визуально все еще находятся друг от друга на некотором расстоянии или, напротив, уже давно должны были столкнуться, но ради скорости чем-то приходится жертвовать.

Есть и такая возможность: сперва определить столкновение Bounding Volumes, а если оно имело место — то проверить более точно уже по граням, было ли столкновение. Это быстрее, чем сразу проверять грани: тогда детальная обработка понадобится только для тех объектов, которые достаточно близко друг к другу.

Тут, правда, тоже есть хитрость: а вдруг один объект целиком попал внутрь другого? Тогда их границы не пересекутся. Но этими тонкостями мы займемся позже.

Что такое Bounding Volume?

Bounding Volume — это ограниченная область в пространстве. Для целей Collision Detection подразумевается, что эта область «твердая», т.е. сквозь нее не могут проходить другие объекты.

Bounding Volume может иметь любую форму (чаще всего выпуклую), но поскольку определение столкновения сложных объектов — процесс достаточно непростой, который к тому же может занимать довольно много времени, часто сложные объекты заменяются на более простые Bounding Volumes — сферы (Bounding Sphere), параллелепипеды (Bounding Box) или выпуклые многогранники (Convex Polyhedron).

При этом получается, что объект как бы окружен непроницаемой оболочкой, которая более или менее повторяет его контуры.


скриншот 3D grathic, 9KB
Bounding Sphere

Bounding Sphere — это Bounding Volume в виде сферы.

Использование Bounding Sphere — это простой, быстрый и самый грубый (если, конечно, объект сам по себе не является сферой) способ узнать, столкнулись объекты или нет.

скриншот 3D grathic, 10KB
Bounding Box

Bounding Box — это Bounding Volume в виде прямоугольного параллелепипеда.

Обычно параллелепипед более точно, чем сфера, повторяет форму объектов, к тому же проверка на столкновения с помощью Bounding Box-ов все еще достаточно простая и быстрая, поэтому они наиболее часто используются для проверки на столкновения. Существует два варианта Bounding Box-ов: AABB и OBB.

скриншот 3D grathic, 10KB
Axis-Aligned BBox

AABB (Axis-Aligned Bounding Box) — это Bounding Box со сторонами, параллельными осям координат в мировой системе.

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

скриншот 3D grathic, 14KB
Oriented BBox

OBB (Oriented Bounding Box) — это произвольно ориентированный Bounding Box.

В отличие от AABB, OBB вращается вместе с объектом и не меняет своих размеров. Проверка на столкновения с помощью OBB несколько сложнее и медленнее, чем с помощью AABB, но чаще она более предпочтительна.

Как определить факт столкновения поверхностей объектов?

Мы выберем сферу в качестве ограничивающего объема для объектов нашего игрового мира. Тогда проверка столкновения объектов переходит в проверку пересечения двух сфер.


Проверка столкновения двух ограничивающих объемов (сфер)
function
TLKI3dForm.CheckSphereIntersect( XCenter1 : single;
YCenter1 : single;
ZCenter1 : single;
Radius1 : single;
XCenter2 : single;
YCenter2 : single;
ZCenter2 : single;
Radius2 : single
) : boolean;

var
XDiff,
YDiff,
ZDiff,
Distance : single;

begin

// вычисляем расстояние между центрами сфер
XDiff := abs(XCenter2-XCenter1);
YDiff := abs(YCenter2-YCenter1);
ZDiff := abs(ZCenter2-ZCenter1);
Distance := sqrt(XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff);

// если сферы пересекаются…
if(Distance <= (Radius1+Radius2)) then Result := true

// а нет – так нет
else Result := false;
end;

Функция возвращает ложь, если два объекта, представленные своими ограничивающими сферами, не пересекаются, иначе — истину. Для проверки факта столкновения сфер вычисляем расстояние между их центрами, и если оно меньше или равно сумме радиусов сфер, то сферы пересекаются.


Это интересно: для оптимизации выполнения проверки на столкновение сфер можно исключить использование функции вычисления квадратного корня sqrt.


Оптимизация
Distance :=
XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff;
RadiusDistance := (Radius1+Radius2)*(Radius1+Radius2)*3;
 
// Пересекаются
If (Distance <= RadiusDistance) then result := true ;
Result := FALSE;
// Не пересекаются

Представление объектов ограничивающими сферами дает выигрыш по скорости и по простоте проверок столкновений, но существенно проигрывает другим методам по точности. Особенно это заметно для тех объектов игрового мира, которые имеют сильно выдающиеся в стороны фрагменты поверхности тела, например, сильно хвостатых монстров или космических вертопланов.


* * *

За это занятие мы освоили некоторые механизмы взаимодействия объектов в трехмерном пространстве и методы управления, которые может применять пользователь к объектам. До встречи через месяц!

956 Прочтений •  [ЛКИ-Creator 3D: Взаимодействие с объектами] [15.08.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• ЛКИ-Creator 3D: Взаимодействие с об... Ukraine Vova 15.08.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2024

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка