Итоги 2013 года

Завершился 2013 год, в течение которого я всеми силами старался выкроить свободное время для работы над Atrium и сопутствующими инструментами. Подведу итоги: что было сделано, какие в прошедшем году произошли важные релизы и достижения.

  • Сециально для Atrium был разработан игровой физический движок dmech с поддержкой нескольких видов геометрических тел и сочленений. Он еще далек от совершенства, но уже пригоден для использования в простых задачах игровой динамики;
  • Было выпущено 6 номеров электронно-познавательного журнала «FPS» (№№ 22, 23, 24, 25, 26, 27). Кстати, в феврале 2014 года журналу исполняется 6 лет!
  • Состоялось серьезное обновление dlib: в частности, пакетов dlib.math и dlib.image. Библиотека обогатилась новой функциональностью, переехала на GitHub и обзавелась поддержкой DUB;
  • Вышла Cook2, экспериментальная ветка программы сборки проектов Cook со значительными изменениями и улучшениями;
  • Вышла альфа-версия Arrow — тетрисоподобной игры-головоломки с оригинальной механикой.

Огромное спасибо всем, кто так или иначе помогал мне в течение года:

  • Андрею Пенечко (MrSmith33) — за багрепорты и багфиксы в dlib;
  • Наталии Чумаковой (d_o_r_i_a_n_a) — за помощь по матчасти и тестирование всех программ на Windows 7, а также за сотрудничество по журналу;
  • Александру Санникову (Suslik) — за советы и помощь по физике.

    Редактор уровней для Atrium

    После долгого перерыва я вновь возвращаюсь к работе над Atrium. Будущей игре нужны инструменты для подготовки контента, и я решил начать с редактора уровней. Конечно, в качестве редактора уровней можно было использовать один из существующих 3D-пакетов — например, Blender — но я отказался от этой идеи по следующим соображениям:

    • Blender «заточен» под моделирование, а не сборку сцен из готовых моделей. Нет встроенной системы ассетов, библиотеки материалов и т.д.;
    • В существующих программах нет возможности создавать новые классы объектов с нестандартными свойствами и функциональностью, специализированные для конкретного игрового движка;
    • Нет полноценного WYSIWYG, в то время как в собственном редакторе уровней используется графический движок от своей же игры, и картинка в редакторе совпадает с картинкой в игре;
    • Собственный редактор можно распространять параллельно с игрой, на тех же лицензионных условиях, а сторонний инструмент — не всегда.

    Для разработки редактора я, как обычно, использую D и OpenGL, а в качестве тулкита — GTK+ (через биндинг GtkD). Планируется выпустить версии для Linux и Windows.

    Журнал «FPS» №27

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

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

    > Подборка новостей по Blender
    > Тон Розендаль о будущем интерфейса Blender
    > GIMP: цветокоррекция на Python
    > От мольберта — к дисплею. Заметки о цифровой живописи
    > Физический движок своими руками. Часть IV
    > Математика в dlib
    > Ranges: диапазоны в D
    > Игровые новости из мира Linux
    > Право на творчество

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

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

    Архив номеров журнала здесь.

    Cook2

    В связи с выходом DMD 2.064 с поддержкой пакетного импортирования, была создана новая нестабильная ветка проекта Cook (инкрементальной системы сборки для программ на D).
    В Cook2 планируется внесение серьезных изменений без сохранения обратной совместимости: в частности, переписан код обработки опций командной строки (он теперь использует std.getopt), а также удалена устаревшая и ненужная функциональность.
    Поддержка пакетных модулей (package.d) уже обеспечена — кроме того, появилась поддержка выборочных и именованных импортов (например, import foo = bar.Foo и import std.stdio: writefln).

    Репозиторий проекта:
    https://github.com/gecko0307/cook2

    Обновление dlib.image

    В dlib.image появилась возможность отслеживать прогресс во время работы фильтров. Для этого используется многопоточность – необходимо создать класс-враппер, наследующий от FilteringThread. Прогресс (от 0 до 1) считывается из свойства progress для SuperImage. В данном примере показано, как использовать эту функциональность для вывода прогресса свертки в консоль:

    import std.stdio;
    import dlib.image.image;
    import dlib.image.io.png;
    import dlib.image.filters.convolution;
    import dlib.image.fthread;
    
    class ConvolutionThread: FilteringThread
    {
        float[] kernel;
        
        this(SuperImage img, float[] k)
        {
            super(img);
            kernel = k;
        }
        
        override void run()
        {
            output = image.convolve(kernel);
        }
        
        override void onRunning()
        {
            writef("Convolving %s%%", cast(uint)(image.progress * 100));
            write("r");
            stdout.flush();
        }
        
        override void onFinished()
        {
            writeln();
        }
    }
    
    void main()
    {
        auto img = loadPNG("test.png");
        img = (new ConvolutionThread(img, Kernel.Emboss)).filtered;
        img.savePNG("output.png");
    }

    Пример работы с Yahoo! Finance на D

    Пример работы с сетевым API Yahoo! Finance: запрос котировок ценных бумаг. Демонстрирует некоторые распространенные идиомы Phobos – например, форматированный ввод, объекты времени и даты. Использует минималистичный HTTP-клиент DHTTPClient. На ввод программа принимает тикер (биржевое обозначение акции) – например, MGNT.ME для акций “Магнит”. Выводит стоимость, дату и время последней сделки.

    module main;
    
    import std.stdio;
    import std.string;
    import std.uri;
    import std.format;
    import std.datetime;
    
    import dhttpclient;
    
    struct Quote
    {
        string symbol;     // s
        string name;       // n
        double lastTrade;  // l1
        string currency;   // c4
        DateTime datetime; // d1 t1
    }
    
    Quote getQuote(string sym)
    {   
        const request = "snl1c4d1t1";
    
        const url = 
            "http://finance.yahoo.com/d/quotes.csv?e=.csv"
          ~ "&f=" ~ request
          ~ "&s=" ~ sym.encode;
        
        auto http = new HTTPClient();
        auto data = http.get(url).chomp;
    
        Quote q;
    
        with (q)
        {
            uint year, month, day;
            string time;
    
            formattedRead(data, 
                ""%s","%s",%s,"%s","%s/%s/%s","%s"", 
                &symbol, &name,
                &lastTrade, &currency,
                &month, &day, &year, &time);
    
            uint hour, minute;
            formattedRead(time, "%s:%s", &hour, &minute);
            if (time[$-2..$] == "pm")
                hour += 12;
    
            datetime = DateTime(year, month, day, hour, minute);
        }
    
        return q;
    }
    
    void main(string[] args)
    {
        string s = "AAPL"; // Apple Inc.
        
        if (args.length > 1)
            s = args[1];
    
        auto q = getQuote(s);
    
        writefln("Symbol: %s", q.symbol);
        writefln("Name: %s", q.name);
        writefln("Last trade: %s %s (%s)", 
            q.lastTrade, 
            q.currency, 
            q.datetime);
    }

    Рефакторинг матриц в dlib

    На днях состоялось грандиозное обновление пакета линейной алгебры dlib.math. Изменения коснулись, главным образом, реализации матриц. Если раньше матрицы 2×2, 3×3 и 4×4 имели каждая отдельную независимую реализацию, то теперь все они являются частными случаями обобщенной квадратной матрицы Matrix!(T,N) (где T – тип элементов, N – размерность). Она содержит все необходимые общие методы для матриц любого размера (нахождение определителя, нахождение обратной матрицы, нахождение матрицы миноров и алгебраических дополнений и т.д.), оптимизированные, где это возможно, для размерностей 2, 3 и 4. Таким образом, нынешние специализации Matrix2x2f, Matrix3x3f и Matrix4x4f практически идентичны их прежним аналогам.

    Новая реализация создана с учетом обратной совместимости, но все-таки есть несколько критичных изменений:

    1. Больше нет шаблонов Matrix2x2!(T), Matrix3x3!(T), Matrix4x4!(T). Используйте вместо них Matrix!(T,2), Matrix!(T,3) и Matrix!(T,4). При этом псевдонимы на специализации типа Matrix2x2f и Matrix4x4d сохранены;

    2. Нет доступа к элементам матриц 4×4 через поля m*, t* и h*. Возможен только доступ через поля a*. Это справедливо для матриц любого размера:

    a11 a12 a13 a14 .. a1N
    a21 a22 a23 a24 .. a2N
    a31 a32 a33 a34 .. a3N
    a41 a42 a43 a44 .. a4N
     :   :   :   :  .
    aN1 aN2 aN3 aN4  ' aNN

    2. Все аффинные преобразования (функции rotationMatrix, translationMatrix и др.) и утилитарные функции для матриц вынесены в отдельный модуль dlib.math.affine. Там же находятся функции right, up, forward, translation, scaling, которые раньше были опрелены как методы в Matrix4x4!(T). Благодаря UFCS, их и теперь можно использовать как методы – однако все они теперь представляют собой свойства только для чтения. Пока они определены только для Matrix!(T,4), но в будущем функции базиса (right, up, forwartd) будут доступны и для Matrix!(T,3).

    3. В целях обратной совместимости сохраняются модули dlib.math.matrix2x2, dlib.math.matrix3x3, dlib.math.matrix4x4, но они помечены как deprecated. Вместо них импортируйте dlib.math.matrix (и dlib.math.affine, если вам нужны аффинные преобразования)

    2. Не рекомендуется использовать identityMatrix3x3!(T) и identityMatrix4x4!(T). Единичные матрицы создаются при помощи статического метода identity: например, Matrix3x3f.identity.

    3. Не рекомендуется трансформировать векторы методом transform. Вместо этого лучше использовать умножение вектора на матрицу: Vector3f(1, 2, 3) * myMatrix.

    4. Любые матрицы можно создавать при помощи функции-фабрики matrixf, которая автоматически определяет размерность на основе входных данных:

    auto m1 = matrixf(
        8, 3, 2, 0,
        4, 0, 2, 0,
        1, 3, 3, 0,
        0, 0, 3, 1
    );

    Это выражение создаст матрицу типа Matrix!(float,4) и присвоит ее переменной m1.

    Убедительная просьба всем пользователям dlib сообщить мне (в Issues в репозитории на GitHub, либо на почту – gecko0307@gmail.com), если будут обнаружены какие-то несостыковки и баги, связанные с данным рефакторингом матриц.

    WolframAlpha

    Совершенно случайно набрел на интереснейший сервис — http://www.wolframalpha.com. Это гибрид поисковика, базы знаний и вычислительной системы, понимающий запросы на литературном английском.

    В первую очередь меня, конечно, заинтересовали его математические возможности. WolframAlpha может служить как простой калькулятор арифметических выражений

    32*56-756

    …и конвертер величин:

    100 kilograms in pounds

    Если вам нужна система линейной алгебры, а Matlab/Octave под рукой нет, то сервис поможет и здесь. Например, можно решать уравнения:

    solve x^2+2x-1=0

    Или рисовать графики функций:

    plot f(x)=x^2

    Поддерживаются операции с матрицами:

    matrix inverse {{8, 3, 2, 0},{4, 0, 2, 0},{1, 3, 3, 0},{0, 0, 3, 1}} decimal

    Также у WolframAlpha можно спрашивать какие-нибудь научные факты, например, возраст Вселенной:

    universe age in years

    Или статистические данные, например, крупнейшие города США:

    biggest cities of usa

    Сервис умеет показывать погоду в указанном городе или регионе:

    weather in moscow

    Я еще не успел ознакомиться со всеми возможностями этой замечательной системы — уверен, там есть еще много интересного.

    Журнал «FPS» №26

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

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

    > Tube Open Movie. Интервью с Бассамом Курдали
    > Обзор дополнений Blender, выпуск 5
    > GIMP: ломо-эффект как в Instagram
    > Физический движок своими руками, часть III
    > Making-of: логическая мини-игра Arrow
    > Генерация случайных уровней
    > Осваиваемся в SDL2
    > Пишем плагин для DeleD на D
    > Как я стал D-шником или Путь художника в IT
    > Игровые новости из мира СПО и Linux
    > «Корпорация зла». Почему у Microsoft нет будущего

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

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

    Архив номеров журнала здесь.