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



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

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

http://ewclid.headfire.ru/

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

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



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


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

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


Про чертежную доску


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



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

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

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


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

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


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


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


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


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

###3D###
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 в строке адреса после идентификатора публикации.

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


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


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


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


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