...

суббота, 18 января 2014 г.

Создание 3D-иллюстраций — прототип системы


Привет, Хабр! В институте на моей специальности был курс 'Начертательная геометрия'. Дисциплина мне понравилась с самого начала. А когда к концу курса я узнал, какие страшные штуки можно вытворять, имея за душой всего линейку и циркуль, начертательная геометрия навсегда покорила мое сердце. С тех пор меня не покидала навязчивая идея сделать что-нибудь на компьютере в духе объемных чертежных построений.


Не так давно, я с удивлением обнаружил, что даже мой ноутбук (далеко не самый новый и мощный) поддерживает стандарт WebGL. Стало понятно, что подходящий момент пришел. В результате некоторых усилий получился прототип системы создания и публикации 3D-иллюстраций.


http://ift.tt/1bcqFAv


Интересная возможность, которую удалось реализовать — просмотр иллюстраций на 3D-телевизорах в стереорежиме без каких-либо драйверов и плагинов. Вывод осуществляется прямо из браузера в формате Side-By-Side. В общем-то ради этого все и затевалось.


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


Возможности прототипа




На данный момент протоип обладает следующими возможностями:


  • Создание сцены ведется на языке PHP. Cоответственно доступны все возможности языка (переменные, массивы, циклы, условия, вспомогательные функции). Можно создавать 3D-сцены, используя примитивы (точка, отрезок, вектор, параллелепипед он-же плоскость, сфера, конус, цилиндр).

  • Объекты могут быть разных цветов (рекомендуется использовать серый, красный, синий, зеленый, желтый). Кроме того может быть назначена произвольная прозрачность (от полностью непрозрачного до полностью прозрачного).

  • Можно размещать и вращать в пространстве как сами примитивы, так и рабочую систему координат (удобно, когда все построение нужно сделать под нужным углом и в нужной точке)

  • Можно добавить несложную анимацию. Пока доступно только отобразить объект, скрыть объект, вывести текстовый комментарий, сделать паузу, чтобы сцена какое-то время отображалась зрителю.

  • Все, что создается можно просматривать в нескольких режимах. (См.ниже)

  • Сценой можно управлять с помощью мыши. Сцену можно вращать, приближать-удалять, указывать новый центр вращения. В стерео-режимах на мышь реагирует только сцена для левого глаза (в режиме Перекрестного взгляда она находится справа!).




Режимы просмотра 3d-сцен:


  • Моно-режим – одно окно.

  • Перекрестный взгляд – для левого глаза сцена справа, для правого – слева.

  • Режим Стерео ТВ – режим Side-By-Side. Правый глаз справа, левый глаз слева. Оба изображения сжаты по горизонтали в два раза.

  • Все режимы имеют возможность разворачиваться на полный экран (в режиме Стерео-ТВ без этого ничего не получится)

  • Существует режим для крутых парней – называется Исходный код (чтобы строить чертеж в уме по PHP коду– без компьютера)


Про чертежную доску и нездоровый педантизм




На сценах в качестве фона может присутствовать объемная чертежная доска. На доске располагается лист бумаги формата A0. Старался сделать, чтобы дерево было похоже на дерево, а бумага — на бумагу. Если присмотрется, то можно увидеть по четырем углам канцелярские кнопки. Надеюсь, Хабр простит мне эти нехитрые конструкторские радости.


Думаю, доска полезна – она задает систему координат, дает ощущение пространства и масштаба. Чертежи на ее фоне смотрятся лучше. По умолчанию центр координат совпадает с центром листа. Размеры задаются в миллиметрах (размеры листа соответственно 841×1189). Если Вы будете строить, задавая Z=0, то построения будут проходить в плоскости бумаги. Ну а кто наберется смелости и выйдет в объем – должен задействовать Z-значения, отличные от нуля.


Еще хочется сказать, что примитивы, не имеющие толщины – такие, как точка, вектор, отрезок – все равно реализованы как объемные тела – мне кажется это более зрелищно.


Демо-иллюстрации




Чтобы показать возможности системы было создано несколько демо-сцен. На главной странице сами иллюстрации не отображаются, чтобы их увидеть нужно войти в публикацию.

Demo 1. Примитивы.


Demo 2. Составные объекты.


Demo 3. Объект в формате x3d.


Demo 4. Анимация. Построение тетраэдра. (Анимация включается в левом верхнем углу сцены).


Привожу исходный код Demo3, чтобы было ясно, как примерно производятся построения.



function zzCustomLamp($place, $color) {
zzSetCoord($place);
zzLamp('', array(0,0,0));
for ($i=1; $i<=6; $i++) {
zzSetStyle($color, $i/7);
zzCircle('', array(0,0,$i*40), 50+$i*10);
}
}

zzDesk();
zzCustomLamp(array(-200,-200,0),'red');
zzCustomLamp(array(-200,200,0),'green');
zzCustomLamp(array(200,-200,0),'blue');
zzCustomLamp(array(200,200,0),'gray');


Испытания на 3D-телевизоре




Режим Стерео ТВ был испытан на телевизоре Phillips с пассивными очками. Компьютер подключался через HDMI. Стереоэффект присутствовал. При вращении сцены некоторые объекты кокетливо вылезали из экрана. Был замечен один недостаток — в стереорежиме неудобно управлять сайтом, поэтому часто приходилось переходить в режим 2D. Вообще пытался испытавать сайт на всех компьютерах, до которых смог дотянуться. Тестировал в браузерах Firefox и Chrome. Вроде работает. Но конечно лучшие результаты и плавность движений достигается на игровых комптьютерах с сильной видеокартой.

Инструкции для желающих почертить




Следующая информация – для тех, кто хочет почертить самостоятельно. Нужно войти в систему под логином editor (пароль совпадает с логином). Далее выбрать – Создать публикацию, 3D-сцена. В окошке создания материала можно набирать команды. Самое первое, что нужно – отделить PHP код от основного содержания строкой ###3D###. Дальше набрать zzDesk(); — если хотите вывести чертежную доску. А дальше – вводить команды.

Одной из целей проекта было максимально упростить язык построения сцен. Думаю, что структура команд была мне навеяна старой доброй графической библиотекой Турбо-Паскаля. Ниже привожу полный перечень доступных на текущий момент команд.



// ###3D### - строка отделяющая PHP-код

$place=array( $x, $y, $z )
$size=array( $dx, $dy , $dz )
$rotation = array ( $axis_x, $axis_y, $axis_z, $angle)

// $angle задается в ГРАДУСАХ, прошу прощение у любителей математики.

$color = ‘gray’ ‘red’ ‘green’ ‘blue’ ‘yellow’
$transparent = 0..1 (прозрачность – 1 – полностью прозрачный).
$emissive = true – объект подсвечен изнутри

$id = ‘circle01’ - идентификатор объекта
// задается при создании примитива,
// используется при дальнейшей анимации

$id_comment = ‘com01’ - идентификатор коментария
// любой тег в тексте публикации может быть помечен
// атрибутом id, и затем содержимое тега
// можно вывести как комментарий в построении

// настройка параметров черчения
function zzSetHide(); // объекты будут создаваться невидимыми (для будущей анимации)
function zzSetShow(); // объекты будут создаваться видимыми
function zzSetStyle($color, {$transparent}, {$emissive} ); // задание цвета и прозрачности
function zzSetCoord($center, {$rotation} ); // перемещение локальной системы координат

// черчение примитивов
function zzDesk(); // чертежная доска
function zzPoint($id, $place) ; // точка
function zzLine($id, $pBegin, $pEnd); // отрезок
function zzVector($id, $pBegin, $pEnd); // вектор (со стрелкой на конце)
function zzCircle($id, $place, $radius, {$rotation} ) ; // окружность
function zzBox($id, $place, $size, {$rotation} ) ; // параллелипипед (при желании плоскость)
function zzSphere($id, $place, $radius) ; // сфера
function zzCone($id, $place, $radius, $height, {$rotation} ); // конус
function zzCylinder($id, $place, $radius, $height, {$rotation} ) ; // цилиндр
function zzLamp($id, $place) ; // лампа, формат x3d (играет роль teapot – ну вы поняли)

// анимация
function zzStepHide($id); //скрыть объект
function zzStepShow($id); //показать объект
function zzStepComment($comment_id); // вывести комментарий
function zzStepCommentHide($comment_id); // скрыть панель комментариев (иногда полезно)
function zzStepPause(); //показать сцену пользователю (сейчас настроено 2 сек)



Если вдруг Вам выведется пустая сцена, или совсем пустое окно браузера – значит что-то не в порядке в коде. Прошу меня извинить, система обработки ошибок в зачаточном состоянии. Лечится либо кнопкой назад, либо набором edit в строке адреса после идентификатора публикации.


Что не удалось реализовать в прототипе




Многие возможности остались за рамками прототипа, хотя намерения их реализовать были.


  • Хотелось бы больше примитивов (очень не хватает кусков – дуг, секторов, многоугольных плоскостей).

  • Конечно же, сплайн-поверхности и сплайн-кривые.

  • Очень хотелось реализовать объемные подписи, чтобы прямо в объеме подписывать примитивы. К сожалению не хватило ума. В WebGL-библиотеке возможность есть, но кое-что не заработало так как мне хотелось.

  • Хотелось бы несложную геометрическую арифметику, чтобы находить точки пересечения примитивов.

  • Более широкие возможности анимации. Плавные движения и трансформации. (Главное при этом не усложнить все настолько, что трудно будет этим пользоваться).


Заглянем под капот




Под капотом: в качестве CMS – рабочая лошадка Drupal 6, в качестве WebGL-библиотеки – x3dom (читается как xFreedom). И то и другое пришлось немного допилить напильником. Что было конкретно сделано:


  • Самое главное — доработана библиотека x3dom. Смысл доработки – сделать синхронизацию двух видов для использования в стереорежиме. Пришлось лезть в сердце библиотеки и руками по локоть в крови управлять матрицами трансформации. Кроме того в режиме Стерео-ТВ нужно было сжимать вид по горизонтали. Надежды почти не было… Но пациент выжил. Что и обеспечило работоспособность прототипа.

  • Был создан модуль к Drupal для реализации API. Был создан фильтр Drupal для распознавания 3D-кода.Немного допилена тема оформления Drupal для вывода экранов.

  • Был создан несложный JavaScript-код для управления анимацией. Еще некоторое количество обвязки из PHP и JavaScript, чтобы все вместе заработало.


Что дальше?




Хочу совершенствовать систему и добавлять различные 3D-сцены из различных областей знания. Конечно, многие вещи хотелось бы сделать изящнее. Например, мне приходится строить сцену для двух видов по отдельности. Возможностью расшарить объекты между двумя видами воспользоваться мне не удалось. Если Хабр подскажет мне какие-нибудь библиотеки и варианты более коротких путей буду очень признателен.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий