- Новый модуль dlib.core.memory предоставляет средства для ручного выделения и высвобождения динамической памяти, независимые от сборщика мусора и основанные на malloc/free. Имеется поддержка структур, классов и массивов. При использовании классов рекомендуется использовать интерфейс ManuallyAllocatable и перегружать метод free, который ответственен за удаление объекта – в противном случае корректное удаление в некоторых случаях не гарантировано (например, при доступе через интерфейс или родительский класс).
- Началась работа по переводу всей dlib на РУП. Так, загрузчики изрбражений (PNG, JPEG, TGA, BMP) в новой версии полностью независимы от сборщика мусора. Для этого активно используется паттерн абстрактной фабрики, ответственный за создание изображений в памяти. Кстати, в загрузчике PNG значительно улучшена поддержка индексированных изображений, для них добавлена поддержка альфа-канала.
- Кроме того, на РУП переведены некоторые контейнеры из dlib.container – BST, ассоциативный массив. Реализован полностью ручной динамический массив (dlib.container.array).
- Еще одна новинка – ООП для структур (dlib.core.oop). Это экспериментальный модуль, реализующий для структур прототипный стиль ООП с поддержкой множественного наследования и параметрического полиморфизма. Полностью заменить классы он, конечно, не может, но окажется весьма полезен, если нужно создавать объекты с наследованием в стеке. В будущем планируется переписать некоторые внутренние механизмы dlib с использованием этой легковесной объектной системы.
- В пакете dlib.math появилась поддержка дуальных кватернионов. Это частный случай алгербы Клиффорда, обобщение кватернионов на поле дуальных чисел. Их можно использовать, например, для описания движения тел в кинематике – один дуальный кватернион охватывает и перенос, и вращение. Кстати, реализация обычных кватернионов через инкапсуляцию теперь совместима с векторами.
- Изменения коснулись и пакета вычислительной геометрии. Усеченная пирамида (dlib.geometry.frustum) теперь задается с нормалями ограничивающих плоскостей, указывающими наружу пирамиды. Подвергся изменению API проверки пересечения Frustum с AABB. Исправлены ошибки в реализации AABB и плоскости.
programming
Как я стал D-шником
Так совпало, что именно в это время я познакомился с движением СПО (свободного программного обеспечения), и это навсегда изменило мое отношение к компьютерам. В какой-то момент моими привычными инструментами стали исключительно свободные программы – GIMP, Blender, OpenOffice.org и т.д. Я понял, что свобода изучения, изменения и распространения программ важнее их качества – хотя это, на первый взгляд, кажется абсурдным. Так утверждает Ричард Столлман – великий человек, основатель проекта GNU, автор лицензии GPL и создатель таких программ, как компилятор GCC и текстовый редактор Emacs. Над его словами часто иронизируют – но в итоге он всегда оказывается прав.
Дело шло неплохо – пока я в один прекрасный день не установил Linux. Это прямого отношения к моему программерскому хобби не имело, но в силу обстоятельств оказало на него сильное влияние. Несколько лет я большую часть времени проводил в Linux – и, естественно, писал под него программки, изучал линуксовые инструменты для разработчиков. К Game Maker уже практически не прикасался. В какой-то момент я понял, что нет больше смысла привязывать себя к Windows – и с тех пор мой движок существует как отдельный самодостаточный проект. Правда, он до сих пор не принял устоявшейся формы. Нет ни релизов, ни версий, ни постоянного репозитория, ни даже конкретного названия – это просто движок. Периодически я выпускаю какие-то демки и мини-игры, основанные на нем. Но окончательной версии, готовой к использованию сторонними лицами, пока нет.
Мое представление о D изначально было весьма смутным: мне казалось, что это какое-то расширение С++ – наподобие того, как сам C++ является расширением C. Ознакомившись со статьей на Википедии, я почувствовал, что это именно то, что мне нужно: компиляция в машинный код, как у C++, и автоматическое управление памятью, как в Java (но надо сказать, что с Java мне на тот момент еще не приходилось работать, поэтому сравнивал я, естественно, с C++). И это не считая многочисленных полезных мелочей, которые D унаследовал от своих многочисленных предшественников – C#, Python, Haskell и др. Обрадовало то, что компилятор D компактен и легок в установке: распаковал архив в любой каталог и работай. В одном архиве – версии для Windows, Linux и FreeBSD, плюс подробная документация по языку и стандартной библиотеке.
Я пишу на D уже несколько лет и очень доволен языком. С каждым релизом он становится все лучше. Не берусь рекомендовать его тем, кто вынужден тянуть вагон legacy-кода на C++ (все-таки, полной бинарной совместимости с C++ у D нет), а также тем, кто такого багажа не имеет, но планирует на полном серьезе трудоустраиваться куда-нибудь в качестве программиста (там тоже будет legacy). Но тот, кто свободен от этого балласта – хакер, любитель, инди-разработчик – обязательно оценит язык по достоинству. Даже если у вас есть некоторое количество кода на «плюсах», без которого вы не можете жить, ничто не мешает потратить пару вечеров и портировать его на D. Сам я так и сделал – некоторые компоненты моей библиотеки dlib были портированы с C++.
Выбор объектов мышью
В играх со сложным пользовательским интерфейсом (большинство стратегий, ряд симуляторов типа 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);
}
JSPE – JavaScript Physics Engine
Чтобы иметь возможность немного отвлекаться от D и при этом делать что-то полезное, я решил начать писать двумерный физический движок на JavaScript и HTML5. Ничего серьезного не планируется – исключительно “just for fun”.
https://github.com/gecko0307/jspe
Журнал “FPS” №24
Читайте в этом номере:
> Blender: новости
> История Blender
> Проект “Лондон”. Интервью с режиссером
> Тренд года – трехмерная печать
> Физический движок своими руками. Часть 1
> Новости игровой индустрии
> История компьютерных игр
> Демосцена: алгоритм как произведение искусства
Номер доступен для онлайн-чтения и загрузки на сервисе Issuu.com, Документах Google и Dropbox.
Последние новости по проекту вы можете узнать в публичной странице журнала в социальной сети Google+: http://gplus.to/fpsmag. Добавляйте нас в круги, оставляйте свои комментарии и отписывайтесь в нашем сообществе.