Журнал «FPS» №25

Вышел 25 номер электронного PDF-журнала «FPS», посвященного разработке игр, программированию, компьютерной графике и звуку.

Читайте в этом номере:

> SIGGRAPH 2013: новости с выставки
> VIGAMUS — музей видеоигр
> Моделирование волос в Blender
> Физический движок своими руками, часть II
> Дуальные числа и автоматическое дифференцирование
> Фильтрация изображений в dlib
> История Git
> Linux — для геймеров?
> Полезные консольные команды в Linux

Номер доступен для онлайн-чтения и загрузки на сервисе Issuu.com, Документах Google и Dropbox.

Последние новости по проекту вы можете узнать в публичной странице журнала в социальной сети Google+: http://gplus.to/fpsmag. Добавляйте нас в круги, оставляйте свои комментарии и отписывайтесь в нашем сообществе.

Выбор объектов мышью

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

Vector3f clickVector(
    Camera camera, 
    int x, 
    int y, 
    int scrw, 
    int scrh, 
    float yfov)
{
    Vector3f camPos = camera.getPosition();
    Vector3f camDir = camera.getDirectionVector();

    float aspect = cast(float)scrw / cast(float)scrh;

    float xfov = fovXfromY(yfov, aspect);

    float tfov1 = tan(yfov * PI / 360.0f); 
    float tfov2 = tan(xfov * PI / 360.0f);

    Vector3f camUp = camera.getUpVector() * tfov1;
    Vector3f camRight = camera.getRightVector() * tfov2;

    float width  = 1.0f - 2.0f * cast(float)(x) / cast(float)(scrw);
    float height = 1.0f - 2.0f * cast(float)(y) / cast(float)(scrh);

    float mx = camDir.x + camUp.x * height + camRight.x * width;
    float my = camDir.y + camUp.y * height + camRight.y * width;
    float mz = camDir.z + camUp.z * height + camRight.z * width;

    return Vector3f(mx, my, mz);
}

T fovXfromY(T) (T yfov, T aspectRatio) 
{
    yfov = degtorad(yfov);
    T xfov = 2.0 * atan(tan(yfov * 0.5) * aspectRatio);
    return radtodeg(xfov);
}

При нажатии кнопки мыши делаем следующее:

Vector3f v = -clickVector(
    camera, mouseX, mouseY, 
    windowWidth, windowHeight, 60);

v.normalize();

Vector3f rayStart = camera.getPosition;
Vector3f rayEnd = camera.getPosition + v * 1000.0f;
Ray r = Ray(rayStart, rayEnd);

Vector3f isecPoint;
float nearestDistance = float.max;
int pickIndex = -1;

foreach(i, obj; sceneObjects)
{
    auto bs = obj.boundingSphere;
    if (r.intersectSphere(bs, isecPoint))
    {
        float d = distance(isecPoint, rayStart);
        if (d < nearestDistance)
        {
            nearestDistance = d;
            pickIndex = i;
        }
    }
}

if (pickIndex >= 0)
{
    writefln("You clicked sphere %s!", pickIndex);
}

dmech

Физический движок, являющийся частью Atrium, будет разрабатываться в качестве отдельного проекта — dmech.

Исходники доступны на GitHub:
https://github.com/gecko0307/dmech

Поддержка сочленений в физическом движке

Физический движок Atrium обзавелся базовой поддержкой сочленений (или ограничений — Constraints) между телами. В данный момент реализован один тип сочленений — шарнир (BallConstraint), который удерживает два тела на определенном расстоянии друг от друга, позволяя им вращаться вокруг заданной точки.

Изменения доступны в репозитории Atrium на GitHub.
Сборка для Windows (2,63 МБ)

Кроме того, вслед за dlib, система сборки проектов Cook также переехала на GitHub. Репозиторий проекта доступен по адресу: http://github.com/gecko0307/cook.

Дуальные числа и касательная к кривой Безье

Дуальные числа, поддержка которых не так давно появилась в dlib (dlib.math.dual), обладают замечательным свойством: с их помощью можно реализовать автоматическое дифференцирование функций. Если производить вычисления не над вещественными, а над дуальными числами, то в вещественной части результата получается значение самой функции в заданной точке, а в дуальной – значение ее производной.
При этом если оформить функцию в виде шаблона, она без лишних телодвижений расширяется до множества дуальных чисел. Следующий пример показывает дифференцирование простейшей квадратичной функции:

import std.stdio;
import dlib.math.dual;

T parabola(T)(T x)
{
    return x*x;
}

void main()
{
    float x = 1.0f;

    Dualf eval = parabola(Dualf(x, 1.0f));
    float value = eval.re;
    float deriv = eval.du;
    
    writeln(deriv);
}

При запуске программа выдаст значение производной – 2 для точки 1. Правильность результата нетрудно проверить, зная формулу производной степенной функции: если f(x) = xn, то f ‘(x) = nxn-1. Следовательно, если f(x) = x2, то f ‘(x) = 2x.

Теперь начинается самое интересное. Попробуем вместо скалярных величин взять векторные и дифференцировать функцию кривой Безье (dlib.geometry.bezier) для двумерного случая:

import dlib.math.dual;
import dlib.math.vector;
import dlib.geometry.bezier;

alias DualVector2f = Vector!(Dualf, 2);

void main()
{
    float t = 0.5f;
    
    DualVector2f eval = bezierCurveFunc2D(
        DualVector2f(Dualf(0.0f), Dualf(0.0f)),
        DualVector2f(Dualf(1.0f), Dualf(1.0f)),
        DualVector2f(Dualf(2.0f), Dualf(1.0f)),
        DualVector2f(Dualf(3.0f), Dualf(0.0f)),
        Dualf(t, 1.0f));
}

Результирующий вектор eval будет содержать в вещественной части точку на кривой, а в дуальной – вектор касательной к кривой в этой точке, который нам остается только нормировать:

Vector2f point = Vector2f(eval.x.re, eval.y.re);
Vector2f tangent = Vector2f(eval.x.du, eval.y.du).normalized;

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

dlib 0.1.2

Коллекция библиотек dlib обновилась до версии 0.1.2. Были внесены несколько значительных нвовведений:

  • В dlib.image.color типы ColorRGBA и ColorRGBAf были переименованы в Color4 и Color4f соответственно. Для обеспечения обратной совместимости, старые имена сохранены в виде псевдонимов, но новый код рекомендуется писать с использованием новых имен;
  • Добавлена поддержка свертки изображений (dlib.image.filters.convolution), которая позволяет реализовать на ее основе множество различных фильтров. Есть несколько встроенных ядер 3×3: Identity, BoxBlur, GaussianBlur, Sharpen, Emboss, EdgeEmboss, EdgeDetect, Laplace;
  • Добавлена поддержка цветового пространства HSV. На его основе реализованы эффекты Chroma Key («зеленый фон») и Color Pass (выборочное обесцвечивание).
  • Исправлены баги, связанные со сборкой при помощи DUB.

Страница проекта:
https://github.com/gecko0307/dlib

Скачать dlib 0.1.2:
https://github.com/gecko0307/dlib/releases/tag/v0.1.2

JSPE — JavaScript Physics Engine

Чтобы иметь возможность немного отвлекаться от D и при этом делать что-то полезное, я решил начать писать двумерный физический движок на JavaScript и HTML5. Ничего серьезного не планируется — исключительно «just for fun».

https://github.com/gecko0307/jspe

Релиз dlib 0.1

Состоялся первый нестабильный релиз коллекции библиотек dlib.

Нововведений по сравнению с последней ревизией SVN практически нет (если не считать функцию генерации тангенс-векторов для полигональных мешей) — релиз просто ознаменовал переезд проекта на GitHub (однако старый репозиторий в обозримом будущем продолжит обновляться параллельно с новым).

Одновременно с этим был зарегистрирован пакет dlib в реестре DUB: http://code.dlang.org/packages/dlib.

Страница проекта:
https://github.com/gecko0307/dlib

Скачать dlib 0.1:
https://github.com/gecko0307/dlib/releases/tag/v0.1

Bump mapping в Atrium

В движке Atrium реализован шейдерный эффект рельефа с использованием карт нормалей (Normal mapping). Представленная демонстрация показывает эффект в действии для динамических боксов, которыми игрок может манипулировать. Планируется также поддержка Parallax mapping.

Сборка для Windows (2,68 МБ)
Сборка для Linux (3,1 МБ)

Шейдеры написаны на GLSL и требуют наличия расширения ARB_shading_language_100 (или OpenGL 2.0), но это не является критической необходимостью — игра будет работать и со старыми видеокартами без поддержки шейдеров.

Журнал «FPS» №24

Вышел 24 номер электронного PDF-журнала «FPS», посвященного разработке игр, программированию, компьютерной графике и звуку.

Читайте в этом номере:

> Авторы «FPS» — кто они?
> Blender: новости
> История Blender
> Проект «Лондон». Интервью с режиссером
> Тренд года — трехмерная печать
> Физический движок своими руками. Часть 1
> Новости игровой индустрии
> История компьютерных игр
> Демосцена: алгоритм как произведение искусства

Номер доступен для онлайн-чтения и загрузки на сервисе Issuu.com, Документах Google и Dropbox.

Последние новости по проекту вы можете узнать в публичной странице журнала в социальной сети Google+: http://gplus.to/fpsmag. Добавляйте нас в круги, оставляйте свои комментарии и отписывайтесь в нашем сообществе.