воскресенье, 25 августа 2013 г.

Улучшения в dmech

Ведется работа по улучшению физического движка dmech:
  • производительность повышена на 50%;
  • повышена стабильность симуляции;
  • улучшена система проверки столкновений - добавлен генератор contact manifold'ов;
  • реализовано двухосевое трение в солвере контактов.
Демка для Linux (1,84 МБ)
Исходники (0,3 МБ)

Периодически будут появляться новые демки - следите за изменениями в публичной папке на DropBox.

В скором времени изменения будут доступны на GitHub.

пятница, 16 августа 2013 г.

Arrow

Arrow - мини-игра наподобие "Тетриса", которую я от нечего делать написал за ту неделю, когда у меня не было доступа в Интернет. Это, фактически, клон java-игры GuruGuru, предустановленной на мой телефон (Pantech PG-1500). Она отличается от классического "Тетриса" оригинальной механикой: вместо простых блоков здесь блоки-стрелки. Вы должны выстраивать линии из стрелок, указывающих в одном направлении. Есть четыре однонаправленные стрелки (вверх, вниз, вправо, влево), две двунаправленные (горзонтальная и вертикальная) и одна четырехнаправленная. Как только выстроена линия в 3 и больше стрелок, она исчезает, а все соседние с ней стрелки поворачиваются на 90 градусов. Есть также "бетонный" блок без направления, который исчезает только вследствие исчезновения его соседа.

В игре пока нет уровней, системы подсчета очков или каких-либо иных целей - просто бесконечный игровой процесс. Если экран заполнится блоками доверху, игра заканчивается. В оригинальной GuruGuru был интересный режим "битвы" с искусственным интеллектом - побеждал тот, кто дольше продержится, не заполнив свой экран. Не исключено, что когда-нибудь нечто подобное будет реализовано и в Arrow.

Игра написана на D, с использованием моего "традиционного" инструментария: OpenGL, SDL, FreeType, Derelict, dlib.

Сборка для Windows (0,93 МБ)
Исходники доступны на GitHub: https://github.com/gecko0307/arrow

суббота, 3 августа 2013 г.

Журнал "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);
}