Pull to refresh

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

Reading time 6 min
Views 13K


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

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

http://ewclid.headfire.ru/

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

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



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


На данный момент прототип обладает следующими возможностями:
  • Создание сцены ведется на языке PHP. Cоответственно доступны все возможности языка (переменные, массивы, циклы, условия, вспомогательные функции). Можно создавать 3D-сцены, используя примитивы (точка, отрезок, вектор, параллелепипед он-же плоскость, сфера, конус, цилиндр).
  • Объекты могут быть разных цветов (рекомендуется использовать серый, красный, синий, зеленый, желтый). Кроме того может быть назначена произвольная прозрачность (от полностью непрозрачного до полностью прозрачного).
  • Можно размещать и вращать в пространстве как сами примитивы, так и рабочую систему координат (удобно, когда все построение нужно сделать под нужным углом и в нужной точке)
  • Можно добавить несложную анимацию. Пока доступно только отобразить объект, скрыть объект, вывести текстовый комментарий, сделать паузу, чтобы сцена какое-то время отображалась зрителю.
  • Все, что создается можно просматривать в нескольких режимах. (См.ниже)
  • Сценой можно управлять с помощью мыши. Сцену можно вращать, приближать-удалять, указывать новый центр вращения. В стерео-режимах на мышь реагирует только сцена для левого глаза (в режиме Перекрестного взгляда она находится справа!).

Режимы просмотра 3d-сцен:
  • Моно-режим – одно окно.
  • Перекрестный взгляд – для левого глаза сцена справа, для правого – слева.
  • Режим Стерео ТВ – режим Side-By-Side. Правый глаз справа, левый глаз слева. Оба изображения сжаты по горизонтали в два раза.
  • Все режимы имеют возможность разворачиваться на полный экран (в режиме Стерео-ТВ без этого ничего не получится)
  • Существует Исходный код, где каждый может посмотреть, какими командами строилась сцена


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


На сценах в качестве фона может присутствовать объемная чертежная доска. На доске располагается лист бумаги формата 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 в строке адреса после идентификатора публикации.

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


Многие возможности остались за рамками прототипа, хотя намерения их реализовать были.
  • Хотелось бы больше примитивов (очень не хватает кусков – дуг, секторов, многоугольных плоскостей).
  • Конечно же, сплайн-поверхности и сплайн-кривые.
  • Очень хотелось реализовать объемные подписи, чтобы прямо в объеме подписывать примитивы. К сожалению не хватило ума. В WebGL-библиотеке возможность есть, но кое-что не заработало так как мне хотелось.
  • Хотелось бы несложную геометрическую арифметику, чтобы находить точки пересечения примитивов.
  • Более широкие возможности анимации. Плавные движения и трансформации. (Главное при этом не усложнить все настолько, что трудно будет этим пользоваться).


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


Под капотом: в качестве CMS – Drupal 6, в качестве WebGL-библиотеки – x3dom (читается как xFreedom). И то и другое было немного доработано. Что было сделано:
  • Доработана библиотека x3dom. Смысл доработки – сделать синхронизацию двух видов для использования в стереорежиме. Кроме того в режиме Стерео-ТВ нужно было сжимать вид по горизонтали.
  • Был создан модуль к Drupal для реализации API. Был создан фильтр Drupal для распознавания 3D-кода.Немного доработана тема оформления Drupal для вывода экранов.
  • Был создан несложный JavaScript-код для управления анимацией. Еще некоторое количество обвязки из PHP и JavaScript, чтобы все вместе заработало.


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

Articles