Реальная Виртуальность

Блуждая по просторам интернета, постоянно рискуешь напороться на некий объект, способный легко уничтожить уйму столь дефицитного личного и, пока еще, столь дорогого сетевого времени. Подобные "Черные Дыры" виртуальных закоулков без сомнения известны любому пользователю, сделавшему хотя бы несколько ходок, не говоря уже о профессиональных серферах и сталкерах сети. Странные существа люди — они даже составляют специальные хит-парады, посвященные подобным местам периодического времяубийства. Да, Вы и сами хорошо знаете всяческих Рэмблеров и прочие Топ 1000. С другой стороны, еще никто не пытается создать хит-парад интернет технологий, способных качественно и масштабно уничтожать личное время. HTML, mp3 и … и запишите VRML в первую пятерку!

Справка

VRML: аббревиатура от Virtual Reality Modeling Language (по отечественному ЯМВР, Язык Моделирования Виртуальной Реальности). Стандарт языка описания трехмерных сцен, содержащих объекты, а также возможных взаимодействий между объектами и наблюдателем. Основное назначение — описание набора объектов (сцены) в системах виртуальной реальности. Основное на данный момент применение — представление статической и интерактивной информации в сети интернет, в виде виртуальной трехмерной среды содержащей различные объекты. Существует три распространенных версии языка: VRML 1.0, 2.0 и VRML 97. На данный момент самой широко поддерживаемой версией является VRML 2.0. Развитие языка координируется VRML Architecture (по другим источникам Advisory) Group (перевод — Группа Архитектуры VRML), известной под аббревиатурой VAG.

История

Все началось 27 октября 1969 года, с первого TCP пакета. Затем были "telnet 1.0.0.2" и "ftp 1.0.0.2". Еще позже появился "ftp.cc.mil" и прочие DNS. В 1989 году начал развиваться WWW. Впрочем, все это события глубоко довиртуальной эры. В январе 1994 года, Mark Pesce и Tony Parisi придумывают концепцию трехмерного HTML, своеобразного языка описания трехмерных сцен с поддержкой гиперссылок, и создают пакет программ и экспериментальный формат, названные ими Labyrinth — первый прообраз VRML. В апреле 1994 года их проект участвует в First International Conference on the World Wide Web (Первой Интернациональной Конференции по WWW), где и звучит впервые термин VRML. Кстати, тогда он расшифровывался как Virtual Reality Markup Language, и лишь позже "markup" был заменен на более научно-звучное "modeling". В июне 1994 года известный журнал WIRED создает список рассылки, посвященной проблеме создания VRML, в течение недели на него подписываются около 1000 специалистов, что в 1994 году было крайне серьезным числом. Они и определяют направление развития концепции, придавая ей, в ходе многочисленных письменных обсуждений, первые очертания. До сих пор соблюдается хорошая традиция совершенствования языка: постоянный поиск решений удовлетворяющих большинство участвующих в обсуждении добровольцев, т.е. столь любимый первым президентом нашей родины консенсус. Практически сразу решено не заниматься изобретением велосипеда, а взять за основу какой либо существующий язык описания трехмерных сцен. Коим становится разработанный в Silicon Graphics Incorporation формат файлов программной библиотеки Open Inventor. Gavin Bell, инженер SGI модифицировал формат Open Inventor, создав первый вариант языка VRML, который был анонсирован в октябре 1994 года на "Второй Всемирной Конференции по WWW" и 5 ноября превратился в официальный проект стандарта VRML 1.0. Его коллега, Paul Strauss, написал первый VRML 1.0 клиент, назвав его трудно произносимым именем QvLib. Клиент был впервые представлен для платформы SGI, в январе 1995 года.

Печальная легенда гласит, что столь неудобоваримое название программы было придумано, дабы постоянно напоминать авторам о необходимости создать, чуть позже, название гораздо более удобное и красивое. Что, в полном согласии с известной пословицей, так и не было никогда сделано. Позже исходные тексты QvLib были предоставлены всем желающим, вызвав неконтролируемое распространение VRML по аппаратным платформам, сайтам и многочисленным сознаниям людей. Вскоре Parsi создает свою собственную компанию, Intervista, и начинает разработку трехмерного … как это лучше перевести … обозревателя, основанного на VRML. Который был назван WorldView и успешно существует до сих пор. Тогда же Parsi, Pesce и один известный архитектор из Сан-Франциско осуществляют проект Virtual SOMA — VRML модель южной части пригорода, призванной стать центром мультимедиа и интернет бизнеса, первое масштабное наполовину коммерческое применение VRML технологии. В апреле 1995 года SGI анонсирует новую программу просмотра WebSpace, открывая широкую кампанию по продвижению VRML. В ней принимаю участие такие фирмы, как Netscape, DEC, Spyglass, и NEC. Начинается рекламная шумиха в компьютерной (и не очень) прессе. На конференции SIGGRAPH'95 язык VRML, несомненно, является основной темой. С этого момента следует стремительная лавина анонсов новых обозревателей, средств создания VRML сцен и просто содержащих VRML контент сайтов. В августе 1995 года Pesce анонсирует создание VAG, начинается разработка проекта стандарта VRML 2.0. Первоначальный проект забит и затоптан в ходе обсуждения, но присланы шесть новых вариантов от ведущих компьютерных фирм:

  1. Active VRML от Microsoft
  2. Dynamic Worlds от GMD сотоварищи
  3. HoloWeb от Sun
  4. Moving Worlds от Silicon Graphics сотоварищи
  5. Out of this World от Apple
  6. Reactive Virtual Environment от IBM Japan

В ходе обсуждений выявляется лидер — Moving Worlds. Вскоре, благородная Apple отказывается от своего проекта в пользу Moving Worlds, остальные гиганты продолжают настаивать на своих вариантах. Некоторое время Moving Worlds шлифуется, постепенно становясь проектом стандарта VRML 2.0. В июне 1996 представители VAG договариваются, подписывая окончательное соглашение, считать работы над VRML 2.0 завершенными. Кстати, несмотря на поиск консенсуса, работа по созданию и принятию стандарта продвигается невероятно быстро. В декабре 1996 стандарт ISO/IEC DIS 14772-1 (VRML 2.0) принят окончательно. А в октябре 1997 года был завершен проект стандарта новой, расширенной версии языка, названной, в соответствии с последними веяниями, VRML 97. Следует отметить, что VRML абсолютный рекордсмен по скорости разработки и принятия официального стандарта, среди всех компьютерных языков. Развитие VRML продолжается, хоть и не столь бурно, по сей день. За сим прошу откланяться.

Из чего сделаны мальчики?

Это я, разумеется, хватил через край. Из чего сделаны мальчики и девочки известно всем, со времен счастливого детства и ненавязчивой детской поэзии. Компьютерные же мальчики и девочки, как известно, сделаны из закрашенных треугольников. А вот из чего состоит VRML, мы сейчас попытаемся узнать. Итак, нам необходимо обеспечить выполнение двух основных действий:

  1. Описать виртуальный мир.
  2. Предъявить этот мир пользователю, позволив ему взаимодействовать с ним.

Решим эти задачи, попробовав себя в непростой роли создателей VRML. В первую очередь необходимо создать информационную структуру, описывающую мир . Чрезвычайно гибкая и удобная (для пользователя или математика, но не для реализующего ее обработку программиста) структура — граф. Т.е. набор узлов (в терминологии VRML — node) дополненный информацией о связях между ними. Узлы похожи на обычные структуры данных, они содержат поля (fields) и события (events). Cвязи между узлами реализуются с помощью полей, имеющих тип указателя (на узел). Фактически, события также представляют собою указатель на объект способный эти события генерировать, или воспринимать, что сразу разделяет их на два типа — исходящие (EventOut) и входящие (EvevnIn), соответственно.

Благодаря подобной концепции, VRML, несомненно, может считаться объектно-ориентированным языком. Все это безобразие, схематически изображенное на рисунке 1, в сумме описывает мир*, в VRML понимании этого слова. Поля Field 1 и 2 представляют собою первичные параметры (например, цвет или точка в трехмерном пространстве), Field 3 является набором указателей на другие узлы, а Event 1 событием, поступающим от двух узлов.

*С точки зрения функционального подхода правильнее говорить описание сцены или мир, но, когда мы займемся программированием на языке VRML, мы будем использовать процессуальное название программа.

Структура есть, предположим, что основные типы узлов, событий и полей также определены. Но, пока, это лишь на бумаге и в мыслях, нам же необходимо создать синтаксис языка — формальное описание возможного содержимого файла, в рамках которого наш мир будет формулироваться человеком или редактором. А затем, возможно, он будет интерпретироваться и демонстрироваться программой клиентом (так "успешно" обозванной мною обозревателем). Разумеется, обозревателя также необходимо разработать и написать, хотя, формально, рамки стандарта заканчиваются уже на этапе формулировки синтаксиса и описания функционирования определенных заранее узлов. Конкретная реализация программы, то, как она будет представлять информацию пользователю и то, как она будет обеспечивать его взаимодействие с виртуальным миром, остаются на совести разработчиков. Впрочем, этот факт совершенно не спасает от стойкого ощущения дежавю во время работы с большинством распространенных на данный момент клиентов. Достаточное ограничение в простор реализации вносят четкие правила относительно генерации событий и строго фиксированный набор параметров, определяющих визуальное (геометрия, материал и освещение) описание объектов. Подводя итоги, составим следующую табличку:

VRML технология



СтратегияОписание трехмерного виртуального мира, возможность взаимодействия с объектами.
Понятийный уровеньПонятие узла, набора, поля, события.
Событийный уровеньПравила генерации событий.
Структурный уровеньКонкретные типы полей и событий (точка, число, цвет, URL,…).
Конкретные типы узлов, их структура (источник,…).
Языковой уровеньСинтаксис описания структур ([], {}, ROUTE, DEF,…).
Синтаксис описания узлов (Field, EventIn,…).
Имена предопределенных типов полей (SFColor, SFBool,…).
Имена предопределенных типов событий (addChildren,…).
Имена предопределенных типов узлов (Anchor, Material,…).
Клиентский уровеньСреда распространения VRML описаний (файлы, HTTP,…).
Среда визуализации (OpenGL устройства, принтер,…).
Интерфейс навигации и взаимодействия (мышь, вид из глаз,…).

Типы, странные и не очень

Разберемся с первичными типами, основными строительными кирпичиками языка VRML. Все типы полей делятся на два класса, содержащие одно значение (так называемые SF типы) и наборы (MF). Для пущей простоты, имена первых всегда начинаются с букв SF, а вторых, как Вы, наверное, уже догадались, с MF. Для записи элементов набора используются квадратные скобки. Например, если у нас есть поле, набор целого типа MFInt32, под названием MyIntegerSet, мы можем описать его следующим образом:

MFInt32 MyIntegerSet

Кстати, VRML болезненно чувствителен к разнице между заглавными и строчными буквами. Поэтому, sfint32 и SFInt32 — два различных идентификатора. Это к слову, а теперь, попробуем заполнить наш набор значениями:

MyIntegerSet [ 1, 0, 0, 1 ]

В одной очень известной трехмерной игре, помнится, как раз подобной комбинацией и открывалась крайне важная дверь. Разумеется, еще мы можем оставить набор пустым или записать в него лишь одно значение:

MyIntegerSet [ ]

MyIntegerSet [ 1 ] или MyIntegerSet 0

И, даже, поступить так:

MyIntegerSet [ 0, ]

Некоторые первичные типы имеют как SF так и MF разновидность, например, если тип называется Color то соответствующие имена записываются как SFColor и MFColor,. Следующая таблица претендует на некоторую долю информативности:

Первичные типы данных

Имена типовОписаниеПример значения
SFBoolЛогический типTRUE
FALSE
SFColor
MFColor
Цвет (три плавающих числа из диапазона 0.0…1.0)0.1 1.0 0.0
[ 0.1 0.2 0.3, 0.3 0.2 0.1 ]
SFFloat
MFFloat
Плавающее число (IEEE, 32 бит, С нотация)1.1
[ 3.1415926, .01e-22, 1. ]
SFImageИзображение в виде X Y NC <данные> NC=1 — 255 градаций серого на одну точку
2 — по 255 градаций серого и прозрачности на точку.
3 — по 255 градаций RGB на одну точку.
4 — по 255 градаций RGB и прозрачности на точку.

320 200 1 0xff 0xff 0x00 0x2f… <Сер.>

20 30 2 0x1200 0x1300 0x00ff…<Сер.><Проз.>

30 20 3 0xff00ff 0x00ff00… <Кр.><Син.><Зел.>
25 25 4 0xff00ff00 0x000000ff… <Кр.><Син.><Зел.><Проз.>
SFInt32
MFInt32
Целый тип (со знаком, 32 бит, С нотация)0x33
[ 0xffabcd9, 1, 2, -555555 ]
SFNode
MFNode
Определяет ссылку на узел. В качестве значения можно использовать экземпляр узла. Anchor { … }
[ Anchor { … }, Material {…} ]
SFRotation
MFRotation
Поворот. (ось поворота и угол, X Y Z Alpha). 0 1 0.0 3.1415926
[0 1 0 1.1, 1.0 .0 .0 1.0, …]
SFString
MFString
Строка. (код UTF-8, в C нотации)."Hello, world! "
[""Sam" it's me", "www.microsoft.com"]
SFTimeВремя, секунд с 1 января 1970 года. (UNIX формат, плавающее число, 64 бит, в С нотации).1.34343454545e20
SFVec2f
MFVec2f
Двумерный вектор. (Плавающие числа 32 бита, в С нотации).0.0 1.0
[ 1.0 2.0, 1.0 0.0 ]
SFVec3f
MFVec3f
Трехмерный вектор. (Плавающие числа 32 бита, в С нотации).0.0 1.0 2.0
[1.0 1.0 2.0, 1.0 1.0 0.0 ]

Засим, первичные типы успешно закончились.

Узлы, связи и все все все…

А теперь посмотрим все остальное. Основной объект языка — узел. VRML файл (программа) состоит из некоторого количества прототипов (определений новых типов узлов), некоторого количества узлов, заполненных конкретной информацией, и не менее некоторого количества событийных связей между узлами. Все эти элементы могут быть расположены в произвольном порядке.

Экземпляры узлов описываются и заполняются так:

<Название существующего типа> {
<тип поля> <значение>

}

Где специальное слово ROUTE позволяет установить автоматическую отправку конкретного исходящего события одного узла в конкретное входящее событие другого. Также, можно создавать именованyые экземпляры узлов, с возможностью их одновременного использования в нескольких местах программы:

DEF <Имя узла> <Экземпляр узла>

Подобный именованный узел может быть далее использован с помощью другого ключевого слова:

USE <Имя узла>

Заполним, для примера, узел предопределенного типа Anchor, попутно продемонстрировав использование неразлучной парочки DEF/USE:

# Простой красный материал DEF SimplyRedMaterial Material { diffuseColor 1 0 0 } # Ссылка в виде шарика Anchor { url "http://www.microsoft.com/" children [ Shape { geometry Sphere { radius 2.0 } appearance Appearance { material USE SimplyRedMaterial } } ] }

Определяет ссылку на сайт всеми любимой компании, которая (ссылка, не компания) содержит объект, содержащий, в свою очередь, геометрическую информацию (сфера единичного радиуса) и описание материала имеющего красный цвет в рассеянном свете. Уф… Вот такая вложенная структура данных понадобилась ради одного маленького красненького шарика, неправда ли, это эффективное средство убийства времени набирающего подобные программы человека? Шутки в сторону, вернемся к примеру. Поле children является стандартным для всех узлов, содержащих подчиненные узлы (так называемые "дети") и представляет собою набор типа MFNode. Как правило, узел каким то образом влияет на всех своих детей, например, перемещая их в пространстве, масштабируя, или придавая им какие либо общие свойства. В действительности, узел типа Material имеет множество других параметров, но, в данном примере, мы полагаемся на их значения по умолчанию, определенные где-то в недрах языка. Обратите внимание на комментарий, который обозначается символом # и продолжается до конца строки включительно. Кстати, если добавить в предыдущий пример такую вот первую строчку:

#VRML V2.0 utf8

обязательную для всех VRML 2.0 программ, мы получим полноценный файл, который можно назвать "КакВамУгодно.wrl", открыть в соответствующем обозревателе и даже кликнуть (по красному шарику). До сих пор, мы имели дело с заранее определенными, в языке, типами узлов Anchor, Shape, Sphere и Material. Но, если мы того пожелаем, можно легко определить новый тип узла. Делается это следующим образом:

PROTO <Название нового типа> [
<классификатор>

] {
<Экземпляр узла на основе которого строится новый тип>
<Экземпляры других используемых узлов>
<Описание пути событий>
<Прототип>

}

Классификатор определяет каждый конкретный член нового типа узла. Возможны следующие классификаторы:

field <Тип> <Имя> <Значение>Обычное поле данных
exposedField <Тип> <Имя> <Значение>Поле данных, реагирующее на события
eventIn <Тип> <Имя>Входящее событие
eventOut <Тип> <Имя>Исходящее событие

Поле данных, реагирующее на события (exposedField) порождает исходящее событие <Имя поля>_changed, которое генерируется при изменении значения данного поля каким либо образом и входящее событие set_<Имя поля>, генерируя которое, значение поля можно менять. Разумеется, тип данных этих событий совпадает с типом обслуживаемого или поля. В квадратных скобках оператора PROTO задается интерфейс нового типа узла (доступные для использования поля и события), а в фигурных описывается его реализация. События представляют собою данные, какого либо типа, передаваемые от узла к узлу. Причем, настройка путей передачи происходит специальным ключевым словом ROUTE:

ROUTE <Имя узла>.<Имя исходящего события> TO <Имя узла>.<Имя входящего события>

Вот пример использования ROUTE — столь любимый мною красный шарик, издающий звук, когда с ним сталкивается наблюдатель: DEF SphereWithSound Collision { children [ Shape { geometry Sphere { } appearance Appearance { material USE SimplyRedMaterial } } Sound { source DEF BoomSound AudioClip { url "boom.wav" } } ] } ROUTE SphereWithSound.collideTime TO BoomSound.startTime

Подобным образом можно легко строить сложно связанные иерархии объектов, в которых изменение каких либо параметров одного узла вызывает незамедлительную реакцию всей системы. Толкнул кубик, а с ним двинулся и шарик, и все такое… Приведу небольшую VRML программу, демонстрирующую не только определение новых типов узлов, но и другие возможностями языка: #VRML V2.0 utf8 PROTO TwoColorStool [ field SFColor legColor .8 .4 .7 field SFColor seatColor .6 .6 .1 ] { Transform { children [ # Сиденье стула Transform { translation 0 0.6 0 children Shape { appearance Appearance { material Material { diffuseColor IS seatColor } } geometry Box { size 1.2 0.2 1.2 } } } # Первая нога Transform { translation -.5 0 -.5 children DEF Leg Shape { appearance Appearance { material Material { diffuseColor IS legColor } } geometry Cylinder { height 1 radius .1 } } } # Вторая нога Transform { translation .5 0 -.5 children USE Leg } # Третья Transform { translation -.5 0 .5 children USE Leg } # Последняя Transform { translation .5 0 .5 children USE Leg } ]} }

Это определение нового типа узла — двухцветной табуретки. У нее есть два поля определяющие цвет сиденья и ножек соответственно. Давайте внимательно посмотрим на использованные для ее создания узлы:

  • Transform — осуществляет геометрическое преобразование своих детей, например сдвиг, поворот или масштабирование.
  • Shape — видимый объект, состоит из описания геометрии и параметров ее отображения, таких как материал, текстура и т.д.
  • Box, Cylinder — прямоугольник и цилиндр, соответственно.

Также, нам встретился новый оператор IS:

  • <Имя поля> IS <Имя поля декларируемого типа узла>
  • <Имя события> IS <Имя события декларируемого типа узла>

Который позволяет связывать параметры и сообщения узлов, из которых состоит реализация создаваемого нами типа, с его интерфейсными параметрами и сообщениями.

Продолжим: DEF XForm Transform { children [ TwoColorStool { legColor 1 0 0 seatColor 0 0 1 } DEF Clicker TouchSensor {} DEF TimeSource TimeSensor { cycleInterval 2.0 } # Animate one full turn about Y axis: DEF Animation OrientationInterpolator { key [ 0, .33, .66, 1.0 ] keyValue [ 0 1 0 0, 0 1 0 2.1, 0 1 0 4.2, 0 1 0 0 ] } ]} ROUTE Clicker.touchTime TO TimeSource.startTime ROUTE TimeSource.fraction_changed TO Animation.set_fraction ROUTE Animation.value_changed TO XForm.rotation NavigationInfo { type "EXAMINE" }

Здесь, мы определяем новый узел XForm типа Transform, который кроме уже описанной нами табуретки (синего цвета с зелеными ножками, рисунок 2) содержит датчик прикосновений TouchSensor, порождающий событие, когда в обозревателе по нашей табуретке щелкают мышкой (т.е. касаются) и таймер TimeSensor. Таймер настроен таким образом, что постоянно генерирует событие fraction_changed значение которого пробегает значение от 0 до 1 за две секунды. Также используется узел OrientationInterpolator, интерполирующий значение типа SFRotation по таблице в зависимости от значения поля fraction. Затем соответствующим образом построено взаимодействие между датчиком прикосновений, таймером, интерполятором и трансформатором позиции табуретки (три ROUTE). В итоге мы получили объект (в нашем случае табуретку, но на ее месте может быть узел любого заранее определенного типа) способный повернуться вокруг себя за две секунды, если к нему прикоснулись. Избушка, избушка, встань к монитору… Последняя строчка переводит обозреватель перейти в режим изучения объекта, в котором наблюдатель не двигается, а просто рассматривает и трогает предмет.

Небольшое продолжение к нашему примеру демонстрирует возможность использования Java Script (если быть корректным — ECMA Script) в VRML программах:

DEF Sizer Script { eventIn SFTime startSizing eventOut SFVec3f scale field SFFloat sc 1.0 field SFBool sizeUp TRUE url "javascript: function startSizing() { if(sizeUp) sc+=0.04; else sc-=0.04; if(sc<0.8||sc>1.3) sizeUp=!sizeUp; scale[0]=sc; scale[1]=sc; scale[2]=sc; } " } DEF Ticker TimeSensor { cycleInterval 0.05 loop TRUE enabled FALSE } ROUTE Clicker.isOver TO Ticker.set_enabled ROUTE Ticker.cycleTime TO Sizer.startSizing ROUTE Sizer.scale TO XForm.scale

Вот так, с помощью предопределенного узла Script мы получаем практически безграничные возможности в определении правил, по которым будет жить наш мир. В данном примере мы заставляем нашу табуретку циклически менять размер (дышать), пока над ней находится курсор обозревателя, вне зависимости от того, прикоснулись мы к ней или нет. Для этого используется событие isOver узла TouchSenser, реагирующее на описанную выше ситуацию с мышиным курсором, таймер генерирующий 20 раз в секунду событие cycleTime и небольшой скрипт, создающий масштабирование, которое затем применяется к объекту.

Дополнения

Все, что было написано ранее, ни в коем случае не претендует на роль руководства или описания. Это лишь попытка показать, что же в действительности стоит за весьма претенциозным термином VRML. Любители формальных грамматик и полных описаний, а также просто заинтересованные читатели могут заглянуть сюда. Где можно найти исчерпывающее описание синтаксиса и концепций VRML 2.0. И множество прокомментированных примеров от SGI, послуживших отличной основой для написания приведенных выше VRML программ. Впрочем, будьте внимательны: в доступных по этому адресу примерах, к моему искреннему удивлению, практически сразу обнаружилось несколько грубых ошибок. Которые, разумеется, убили некое сверхплановое количество свободного времени, но были успешно опознаны и уничтожены. Предвидя возможные недостаток желания или нехватку сетевого времени, приведу список некоторых предопределенных узлов VRML 2.0, отметив, где и как их можно использовать:

Группировка объектов:

AnchorСсылка на URL или URN (альтернативная форма URL)
BillboardМодификатор осей координат
CollisionОбработка столкновений
GroupПростая группа
TransformРазличные преобразования систем координат

Специальные группы:

InlineВставка VRML текста из любого URL
LODУправление уровнем детализации объекта при отрисовке
SwitchУправляемый выбор одного ребенка

Общие узлы:

AudioClipАудио, MIDI или WAV
DirectionalLightНаправленный источник света
PointLightТочечный источник света
ScriptПоддержка внешних языков (ECMA Script, Java,…)
ShapeОтображаемый объект
SoundИсточник 3D звука
SpotLightИсточник света типа прожектор
WorldInfoДополнительная текстовая информация про данный мир

Генераторы событий:

CylinderSensorПреобразует движения мыши в координаты на поверхности цилиндра
PlaneSensorТо же, но в плоскости
ProximitySensorРегион в пространстве чувствительный к проникновению в него
SphereSensorПреобразует движения мыши в координаты на поверхности сферы
TimeSensorТаймер
TouchSensorДатчик прикосновений
VisibilitySensorДатчик видимости

Геометрическая информация:

BoxПрямоугольник
ConeКонус
CylinderЦилиндр
ElevationGridПоверхность вида z=f(x,y)
ExtrusionФигура образованная 2D контуром, протянутым вдоль кривой
IndexedFaceSetНабор точек и построенных по ним граней
IndexedLineSetНабор точек и построенных по ним линий
PointSetНабор точек
SphereСфера
TextТекст

Дополнительная информация:

ColorНабор цветов для каждой вершины объекта
CoordinateНабор координат
NormalНабор векторов нормалей
TextureCoordinateПривязка текстуры

Свойства внешнего вида:

AppearanceВсе в купе для отображаемого объекта
FontStyleПараметры шрифта
ImageTextureТекстура, в виде URL на изображение
MaterialМатериал
MovieTextureАнимационная текстура, URL на клип
PixelTextureТекстура, задаваемая прямо в программе
TextureTransformДополнительное преобразование текстурных координат

Интерполяторы по таблице значений:

ColorInterpolatorЦвета
CoordinateInterpolatorКоординат
NormalInterpolatorВекторов нормалей
OrientationInterpolatorОриентации (поворота)
PositionInterpolatorПозиции
ScalarInterpolatorЛюбого плавающего значения

Управление глобальными параметрами обозревателя:

BackgroundФон изображения
FogХарактеристики атмосферы
NavigationInfoРежим навигации и взаимодействия
ViewpointТочка обзора

Клиенты всегда правы

Все клиенты обладают достаточно схожим интерфейсом. Как правило, навигация осуществляется манипулятором, например мышкой, причем есть несколько легко переключаемых режимов:

  • Движение вперед-назад и повороты вправо-влево
  • Движение вверх-вниз и вправо-влево
  • Повороты вверх-вниз и вправо-влево
  • Автоматическое движение до указанного объекта
  • Переход на заранее определенную точку зрения
  • Возможность "потрогать" объект


Эти действия являются стандартными практически для любой клиентской программы. Опишу два самых успешных, распространенных и самозабвенно конкурирующих обозревателя, соответствующих стандарту VRML 2.0.

Cosmo Software — Cosmo Player:

Разработка SGI. Представляет собою plug-in для браузера, интегрируется в Netscape 3.0 и более или Microsoft Explorer 4.0 и более. Для отображения использует библиотеку OpenGL, и, следовательно, аппаратную акселерацию на любом OpenGL совместимом ускорителе. Для создания объемного звука используется DirectSound (DirectX 3.0) и выше, следовательно, также поддерживается аппаратное ускорение. Клиент соответствует стандарту VRML 2.0 и VRML 97. Поддерживает полноценные Java классы (а не только ECMA Script). Файлы VRML 1.0 автоматически конвертируются в VRML 2.0. Все передаваемые данные могут быть запакованы в GZIP архив, для уменьшения времени загрузки мира. Может быть использован любой программой, как встроенный ActiveX элемент, что позволяет программистам легко добавлять поддержку просмотра VRML в свои продукты. Содержит множество полезных мелочей, начиная с отката действий и заканчивая отладочной консолью для создающих VRML файлы разработчиков. Среди досадных ошибок — неправильная обработка параметров некоторых источников освещения, некоторые проблемы с заданием скорости перемещения из программы и поддержкой анимационных GIF изображений. В поставку входит очень миролюбивая игра "Chomp", с акулой в главной роли, полностью написанная на VRML и ECMA Script. Отличные скоростные качества. Данный клиент всячески рекомендуется мною к использованию. Поддерживаются различные платформы, в том числе: SGI, Windows (9x/NT/3.11) и Mac OS. Органы управления подробно изображены на рисунке 4, взятом из документации. Последнюю версию (Cosmo Player 2.1), море информации и отлично оформленный сайт с VRML афишками Вы найдете по адресу cosmosoftware.com

Microsoft VRML 2.0 viewer:

Разработка … понятно чья. Основан на коде упомянутого ранее WorldView. Представляет собою plug-in для браузера, интегрируется в Microsoft Explorer 3.0 и более. Для отображения использует библиотеку DirectX 3.x и выше, и, следовательно, аппаратную акселерацию на любом DirectX совместимом ускорителе. Соответствует стандарту VRML 2.0 (есть некоторые несущественные расхождения). Поддерживает полноценные Java классы (а не только ECMA Script), но только как URL, а не внутри VRML текста. Поддерживает файлы VRML 1.0. Есть некоторые проблемы с GZIP файлами, приводящие, как правило, к предупреждениям которые можно игнорировать, но иногда прекращающие загрузку миров. Есть некоторые проблемы с реализацией ProximitySensor и обработкой сообщений таймера и событий, связанных с взаимодействием, что крайне печально. Достаточно компактный и удобный интерфейс. Несколько бестолковые настройки. Производительность (немного) и визуальное качество (сильно) уступают Cosmo Player. Рекомендуется как замена Cosmo Player, в случае невозможности использовать его по какой либо причине. Более подробная и глубокая справочная информация, подробно рассмотрено большое количество неоднозначных аспектов конкретной реализации. Не может быть использован как ActiveX элемент в сторонних программах. Только Windows (9x/NT) платформа. Последнюю версию, информацию и устаревшую галерею Вы найдете по адресу www.microsoft.com/vrml/

Впрочем, полуось (IBM OS/2) также не забыта разработчиками: фирма Now Interprises разработала OS/2 VRML viewer.

Редакторы, корректоры, конверторы:

Существует огромное множество инструментария для работы с VRML. Сформулируем, в кратце, основные категории подобных продуктов:

  • Конвертеры — преобразуют файлы других трехмерных форматов в VRML.
  • Валидаторы — проверяют VRML файлы на наличие синтаксических и структурных ошибок.
  • Интерактивные редакторы — позволяют редактировать VRML миры без непосредственного программирования, как это делается в большинстве трехмерных студий.

Где красиво убить время

Обязательно загляните на сайт Российской компании ParallelGraphics

Заключение

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

P.S.

В настоящее время на рынке VRML браузеров доминируют три следующие программы:

  1. Blaxxun Contact 4.3 (www.blaxxun.com) — поддержка сплайновых поверхностей (NURBS), версии с поддержкой DirectX/OpenGL, PIII-оптимизация геометрических вычислений, клиент к многопользовательским VRML-мирам;
  2. Cortona VRML client 2.1 (www.paragraph.ru) - поддержка сплайнов и сплайновых поверхностей (NURBS), поддержка Macromediа Flash и Real Video технологий, графические API DirectX/OpenGL, звуковой EAI2, PIII-оптимизация, версия клиента для многопользовательских VRML-миров;
  3. CosmoPlayer 2.1 — DirectX/OpenGL

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




24 августа 1999 Г.

Реальная Виртуальность

Реальная Виртуальность

Блуждая по просторам интернета, постоянно рискуешь напороться на некий объект, способный легко уничтожить уйму столь дефицитного личного и, пока еще, столь дорогого сетевого времени. Подобные "Черные Дыры" виртуальных закоулков без сомнения известны любому пользователю, сделавшему хотя бы несколько ходок, не говоря уже о профессиональных серферах и сталкерах сети. Странные существа люди — они даже составляют специальные хит-парады, посвященные подобным местам периодического времяубийства. Да, Вы и сами хорошо знаете всяческих Рэмблеров и прочие Топ 1000. С другой стороны, еще никто не пытается создать хит-парад интернет технологий, способных качественно и масштабно уничтожать личное время. HTML, mp3 и … и запишите VRML в первую пятерку!

Справка

VRML: аббревиатура от Virtual Reality Modeling Language (по отечественному ЯМВР, Язык Моделирования Виртуальной Реальности). Стандарт языка описания трехмерных сцен, содержащих объекты, а также возможных взаимодействий между объектами и наблюдателем. Основное назначение — описание набора объектов (сцены) в системах виртуальной реальности. Основное на данный момент применение — представление статической и интерактивной информации в сети интернет, в виде виртуальной трехмерной среды содержащей различные объекты. Существует три распространенных версии языка: VRML 1.0, 2.0 и VRML 97. На данный момент самой широко поддерживаемой версией является VRML 2.0. Развитие языка координируется VRML Architecture (по другим источникам Advisory) Group (перевод — Группа Архитектуры VRML), известной под аббревиатурой VAG.

История

Все началось 27 октября 1969 года, с первого TCP пакета. Затем были "telnet 1.0.0.2" и "ftp 1.0.0.2". Еще позже появился "ftp.cc.mil" и прочие DNS. В 1989 году начал развиваться WWW. Впрочем, все это события глубоко довиртуальной эры. В январе 1994 года, Mark Pesce и Tony Parisi придумывают концепцию трехмерного HTML, своеобразного языка описания трехмерных сцен с поддержкой гиперссылок, и создают пакет программ и экспериментальный формат, названные ими Labyrinth — первый прообраз VRML. В апреле 1994 года их проект участвует в First International Conference on the World Wide Web (Первой Интернациональной Конференции по WWW), где и звучит впервые термин VRML. Кстати, тогда он расшифровывался как Virtual Reality Markup Language, и лишь позже "markup" был заменен на более научно-звучное "modeling". В июне 1994 года известный журнал WIRED создает список рассылки, посвященной проблеме создания VRML, в течение недели на него подписываются около 1000 специалистов, что в 1994 году было крайне серьезным числом. Они и определяют направление развития концепции, придавая ей, в ходе многочисленных письменных обсуждений, первые очертания. До сих пор соблюдается хорошая традиция совершенствования языка: постоянный поиск решений удовлетворяющих большинство участвующих в обсуждении добровольцев, т.е. столь любимый первым президентом нашей родины консенсус. Практически сразу решено не заниматься изобретением велосипеда, а взять за основу какой либо существующий язык описания трехмерных сцен. Коим становится разработанный в Silicon Graphics Incorporation формат файлов программной библиотеки Open Inventor. Gavin Bell, инженер SGI модифицировал формат Open Inventor, создав первый вариант языка VRML, который был анонсирован в октябре 1994 года на "Второй Всемирной Конференции по WWW" и 5 ноября превратился в официальный проект стандарта VRML 1.0. Его коллега, Paul Strauss, написал первый VRML 1.0 клиент, назвав его трудно произносимым именем QvLib. Клиент был впервые представлен для платформы SGI, в январе 1995 года.

Печальная легенда гласит, что столь неудобоваримое название программы было придумано, дабы постоянно напоминать авторам о необходимости создать, чуть позже, название гораздо более удобное и красивое. Что, в полном согласии с известной пословицей, так и не было никогда сделано. Позже исходные тексты QvLib были предоставлены всем желающим, вызвав неконтролируемое распространение VRML по аппаратным платформам, сайтам и многочисленным сознаниям людей. Вскоре Parsi создает свою собственную компанию, Intervista, и начинает разработку трехмерного … как это лучше перевести … обозревателя, основанного на VRML. Который был назван WorldView и успешно существует до сих пор. Тогда же Parsi, Pesce и один известный архитектор из Сан-Франциско осуществляют проект Virtual SOMA — VRML модель южной части пригорода, призванной стать центром мультимедиа и интернет бизнеса, первое масштабное наполовину коммерческое применение VRML технологии. В апреле 1995 года SGI анонсирует новую программу просмотра WebSpace, открывая широкую кампанию по продвижению VRML. В ней принимаю участие такие фирмы, как Netscape, DEC, Spyglass, и NEC. Начинается рекламная шумиха в компьютерной (и не очень) прессе. На конференции SIGGRAPH'95 язык VRML, несомненно, является основной темой. С этого момента следует стремительная лавина анонсов новых обозревателей, средств создания VRML сцен и просто содержащих VRML контент сайтов. В августе 1995 года Pesce анонсирует создание VAG, начинается разработка проекта стандарта VRML 2.0. Первоначальный проект забит и затоптан в ходе обсуждения, но присланы шесть новых вариантов от ведущих компьютерных фирм:

  1. Active VRML от Microsoft
  2. Dynamic Worlds от GMD сотоварищи
  3. HoloWeb от Sun
  4. Moving Worlds от Silicon Graphics сотоварищи
  5. Out of this World от Apple
  6. Reactive Virtual Environment от IBM Japan

В ходе обсуждений выявляется лидер — Moving Worlds. Вскоре, благородная Apple отказывается от своего проекта в пользу Moving Worlds, остальные гиганты продолжают настаивать на своих вариантах. Некоторое время Moving Worlds шлифуется, постепенно становясь проектом стандарта VRML 2.0. В июне 1996 представители VAG договариваются, подписывая окончательное соглашение, считать работы над VRML 2.0 завершенными. Кстати, несмотря на поиск консенсуса, работа по созданию и принятию стандарта продвигается невероятно быстро. В декабре 1996 стандарт ISO/IEC DIS 14772-1 (VRML 2.0) принят окончательно. А в октябре 1997 года был завершен проект стандарта новой, расширенной версии языка, названной, в соответствии с последними веяниями, VRML 97. Следует отметить, что VRML абсолютный рекордсмен по скорости разработки и принятия официального стандарта, среди всех компьютерных языков. Развитие VRML продолжается, хоть и не столь бурно, по сей день. За сим прошу откланяться.

Из чего сделаны мальчики?

Это я, разумеется, хватил через край. Из чего сделаны мальчики и девочки известно всем, со времен счастливого детства и ненавязчивой детской поэзии. Компьютерные же мальчики и девочки, как известно, сделаны из закрашенных треугольников. А вот из чего состоит VRML, мы сейчас попытаемся узнать. Итак, нам необходимо обеспечить выполнение двух основных действий:

  1. Описать виртуальный мир.
  2. Предъявить этот мир пользователю, позволив ему взаимодействовать с ним.

Решим эти задачи, попробовав себя в непростой роли создателей VRML. В первую очередь необходимо создать информационную структуру, описывающую мир . Чрезвычайно гибкая и удобная (для пользователя или математика, но не для реализующего ее обработку программиста) структура — граф. Т.е. набор узлов (в терминологии VRML — node) дополненный информацией о связях между ними. Узлы похожи на обычные структуры данных, они содержат поля (fields) и события (events). Cвязи между узлами реализуются с помощью полей, имеющих тип указателя (на узел). Фактически, события также представляют собою указатель на объект способный эти события генерировать, или воспринимать, что сразу разделяет их на два типа — исходящие (EventOut) и входящие (EvevnIn), соответственно.

Благодаря подобной концепции, VRML, несомненно, может считаться объектно-ориентированным языком. Все это безобразие, схематически изображенное на рисунке 1, в сумме описывает мир*, в VRML понимании этого слова. Поля Field 1 и 2 представляют собою первичные параметры (например, цвет или точка в трехмерном пространстве), Field 3 является набором указателей на другие узлы, а Event 1 событием, поступающим от двух узлов.

*С точки зрения функционального подхода правильнее говорить описание сцены или мир, но, когда мы займемся программированием на языке VRML, мы будем использовать процессуальное название программа.

Структура есть, предположим, что основные типы узлов, событий и полей также определены. Но, пока, это лишь на бумаге и в мыслях, нам же необходимо создать синтаксис языка — формальное описание возможного содержимого файла, в рамках которого наш мир будет формулироваться человеком или редактором. А затем, возможно, он будет интерпретироваться и демонстрироваться программой клиентом (так "успешно" обозванной мною обозревателем). Разумеется, обозревателя также необходимо разработать и написать, хотя, формально, рамки стандарта заканчиваются уже на этапе формулировки синтаксиса и описания функционирования определенных заранее узлов. Конкретная реализация программы, то, как она будет представлять информацию пользователю и то, как она будет обеспечивать его взаимодействие с виртуальным миром, остаются на совести разработчиков. Впрочем, этот факт совершенно не спасает от стойкого ощущения дежавю во время работы с большинством распространенных на данный момент клиентов. Достаточное ограничение в простор реализации вносят четкие правила относительно генерации событий и строго фиксированный набор параметров, определяющих визуальное (геометрия, материал и освещение) описание объектов. Подводя итоги, составим следующую табличку:

VRML технология



СтратегияОписание трехмерного виртуального мира, возможность взаимодействия с объектами.
Понятийный уровеньПонятие узла, набора, поля, события.
Событийный уровеньПравила генерации событий.
Структурный уровеньКонкретные типы полей и событий (точка, число, цвет, URL,…).
Конкретные типы узлов, их структура (источник,…).
Языковой уровеньСинтаксис описания структур ([], {}, ROUTE, DEF,…).
Синтаксис описания узлов (Field, EventIn,…).
Имена предопределенных типов полей (SFColor, SFBool,…).
Имена предопределенных типов событий (addChildren,…).
Имена предопределенных типов узлов (Anchor, Material,…).
Клиентский уровеньСреда распространения VRML описаний (файлы, HTTP,…).
Среда визуализации (OpenGL устройства, принтер,…).
Интерфейс навигации и взаимодействия (мышь, вид из глаз,…).

Типы, странные и не очень

Разберемся с первичными типами, основными строительными кирпичиками языка VRML. Все типы полей делятся на два класса, содержащие одно значение (так называемые SF типы) и наборы (MF). Для пущей простоты, имена первых всегда начинаются с букв SF, а вторых, как Вы, наверное, уже догадались, с MF. Для записи элементов набора используются квадратные скобки. Например, если у нас есть поле, набор целого типа MFInt32, под названием MyIntegerSet, мы можем описать его следующим образом:

MFInt32 MyIntegerSet

Кстати, VRML болезненно чувствителен к разнице между заглавными и строчными буквами. Поэтому, sfint32 и SFInt32 — два различных идентификатора. Это к слову, а теперь, попробуем заполнить наш набор значениями:

MyIntegerSet [ 1, 0, 0, 1 ]

В одной очень известной трехмерной игре, помнится, как раз подобной комбинацией и открывалась крайне важная дверь. Разумеется, еще мы можем оставить набор пустым или записать в него лишь одно значение:

MyIntegerSet [ ]

MyIntegerSet [ 1 ] или MyIntegerSet 0

И, даже, поступить так:

MyIntegerSet [ 0, ]

Некоторые первичные типы имеют как SF так и MF разновидность, например, если тип называется Color то соответствующие имена записываются как SFColor и MFColor,. Следующая таблица претендует на некоторую долю информативности:

Первичные типы данных

Имена типовОписаниеПример значения
SFBoolЛогический типTRUE
FALSE
SFColor
MFColor
Цвет (три плавающих числа из диапазона 0.0…1.0)0.1 1.0 0.0
[ 0.1 0.2 0.3, 0.3 0.2 0.1 ]
SFFloat
MFFloat
Плавающее число (IEEE, 32 бит, С нотация)1.1
[ 3.1415926, .01e-22, 1. ]
SFImageИзображение в виде X Y NC <данные> NC=1 — 255 градаций серого на одну точку
2 — по 255 градаций серого и прозрачности на точку.
3 — по 255 градаций RGB на одну точку.
4 — по 255 градаций RGB и прозрачности на точку.

320 200 1 0xff 0xff 0x00 0x2f… <Сер.>

20 30 2 0x1200 0x1300 0x00ff…<Сер.><Проз.>

30 20 3 0xff00ff 0x00ff00… <Кр.><Син.><Зел.>
25 25 4 0xff00ff00 0x000000ff… <Кр.><Син.><Зел.><Проз.>
SFInt32
MFInt32
Целый тип (со знаком, 32 бит, С нотация)0x33
[ 0xffabcd9, 1, 2, -555555 ]
SFNode
MFNode
Определяет ссылку на узел. В качестве значения можно использовать экземпляр узла. Anchor { … }
[ Anchor { … }, Material {…} ]
SFRotation
MFRotation
Поворот. (ось поворота и угол, X Y Z Alpha). 0 1 0.0 3.1415926
[0 1 0 1.1, 1.0 .0 .0 1.0, …]
SFString
MFString
Строка. (код UTF-8, в C нотации)."Hello, world!\n"
["\"Sam\" it's me", "www.microsoft.com"]
SFTimeВремя, секунд с 1 января 1970 года. (UNIX формат, плавающее число, 64 бит, в С нотации).1.34343454545e20
SFVec2f
MFVec2f
Двумерный вектор. (Плавающие числа 32 бита, в С нотации).0.0 1.0
[ 1.0 2.0, 1.0 0.0 ]
SFVec3f
MFVec3f
Трехмерный вектор. (Плавающие числа 32 бита, в С нотации).0.0 1.0 2.0
[1.0 1.0 2.0, 1.0 1.0 0.0 ]

Засим, первичные типы успешно закончились.

Узлы, связи и все все все…

А теперь посмотрим все остальное. Основной объект языка — узел. VRML файл (программа) состоит из некоторого количества прототипов (определений новых типов узлов), некоторого количества узлов, заполненных конкретной информацией, и не менее некоторого количества событийных связей между узлами. Все эти элементы могут быть расположены в произвольном порядке.

Экземпляры узлов описываются и заполняются так:

<Название существующего типа> {
<тип поля> <значение>

}

Где специальное слово ROUTE позволяет установить автоматическую отправку конкретного исходящего события одного узла в конкретное входящее событие другого. Также, можно создавать именованyые экземпляры узлов, с возможностью их одновременного использования в нескольких местах программы:

DEF <Имя узла> <Экземпляр узла>

Подобный именованный узел может быть далее использован с помощью другого ключевого слова:

USE <Имя узла>

Заполним, для примера, узел предопределенного типа Anchor, попутно продемонстрировав использование неразлучной парочки DEF/USE:

# Простой красный материал
DEF SimplyRedMaterial Material {
diffuseColor 1 0 0
}

# Ссылка в виде шарика

Anchor {
  url "http://www.microsoft.com/"
  children [
    Shape {
      geometry Sphere {
        radius 2.0
      }
      appearance Appearance {
        material USE SimplyRedMaterial
      }
    }
  ]
}

Определяет ссылку на сайт всеми любимой компании, которая (ссылка, не компания) содержит объект, содержащий, в свою очередь, геометрическую информацию (сфера единичного радиуса) и описание материала имеющего красный цвет в рассеянном свете. Уф… Вот такая вложенная структура данных понадобилась ради одного маленького красненького шарика, неправда ли, это эффективное средство убийства времени набирающего подобные программы человека? Шутки в сторону, вернемся к примеру. Поле children является стандартным для всех узлов, содержащих подчиненные узлы (так называемые "дети") и представляет собою набор типа MFNode. Как правило, узел каким то образом влияет на всех своих детей, например, перемещая их в пространстве, масштабируя, или придавая им какие либо общие свойства. В действительности, узел типа Material имеет множество других параметров, но, в данном примере, мы полагаемся на их значения по умолчанию, определенные где-то в недрах языка. Обратите внимание на комментарий, который обозначается символом # и продолжается до конца строки включительно. Кстати, если добавить в предыдущий пример такую вот первую строчку:

#VRML V2.0 utf8

обязательную для всех VRML 2.0 программ, мы получим полноценный файл, который можно назвать "КакВамУгодно.wrl", открыть в соответствующем обозревателе и даже кликнуть (по красному шарику). До сих пор, мы имели дело с заранее определенными, в языке, типами узлов Anchor, Shape, Sphere и Material. Но, если мы того пожелаем, можно легко определить новый тип узла. Делается это следующим образом:

PROTO <Название нового типа> [
<классификатор>

] {
<Экземпляр узла на основе которого строится новый тип>
<Экземпляры других используемых узлов>
<Описание пути событий>
<Прототип>

}

Классификатор определяет каждый конкретный член нового типа узла. Возможны следующие классификаторы:

field <Тип> <Имя> <Значение>Обычное поле данных
exposedField <Тип> <Имя> <Значение>Поле данных, реагирующее на события
eventIn <Тип> <Имя>Входящее событие
eventOut <Тип> <Имя>Исходящее событие

Поле данных, реагирующее на события (exposedField) порождает исходящее событие <Имя поля>_changed, которое генерируется при изменении значения данного поля каким либо образом и входящее событие set_<Имя поля>, генерируя которое, значение поля можно менять. Разумеется, тип данных этих событий совпадает с типом обслуживаемого или поля. В квадратных скобках оператора PROTO задается интерфейс нового типа узла (доступные для использования поля и события), а в фигурных описывается его реализация. События представляют собою данные, какого либо типа, передаваемые от узла к узлу. Причем, настройка путей передачи происходит специальным ключевым словом ROUTE:

ROUTE <Имя узла>.<Имя исходящего события> TO <Имя узла>.<Имя входящего события>

Вот пример использования ROUTE — столь любимый мною красный шарик, издающий звук, когда с ним сталкивается наблюдатель:

DEF SphereWithSound Collision {
  children [
    Shape {
      geometry Sphere { }
      appearance Appearance {
        material USE SimplyRedMaterial
      }
    }
    Sound {
      source DEF BoomSound AudioClip {
        url "boom.wav"
      }
    }
  ]
}

ROUTE SphereWithSound.collideTime TO BoomSound.startTime

Подобным образом можно легко строить сложно связанные иерархии объектов, в которых изменение каких либо параметров одного узла вызывает незамедлительную реакцию всей системы. Толкнул кубик, а с ним двинулся и шарик, и все такое… Приведу небольшую VRML программу, демонстрирующую не только определение новых типов узлов, но и другие возможностями языка:

#VRML V2.0 utf8

PROTO TwoColorStool [
  field SFColor legColor  .8 .4 .7
  field SFColor seatColor .6 .6 .1
] {
  Transform { children [
    # Сиденье стула
    Transform {
      translation 0 0.6 0
      children Shape {
        appearance Appearance {
          material Material { diffuseColor IS seatColor }
        }
        geometry Box { size 1.2 0.2 1.2 }
      }
    }
    # Первая нога
    Transform {
      translation -.5 0 -.5
      children DEF Leg Shape {
        appearance Appearance {
          material Material { diffuseColor IS legColor }
        }
        geometry Cylinder { height 1 radius .1 }
      }
    }
    # Вторая нога
    Transform {
      translation .5 0 -.5
      children USE Leg
    }
    # Третья
    Transform {
       translation -.5 0 .5
       children USE Leg
    }
    # Последняя
    Transform {
       translation .5 0 .5
       children USE Leg
    }
  ]}
}

Это определение нового типа узла — двухцветной табуретки. У нее есть два поля определяющие цвет сиденья и ножек соответственно. Давайте внимательно посмотрим на использованные для ее создания узлы:

  • Transform — осуществляет геометрическое преобразование своих детей, например сдвиг, поворот или масштабирование.
  • Shape — видимый объект, состоит из описания геометрии и параметров ее отображения, таких как материал, текстура и т.д.
  • Box, Cylinder — прямоугольник и цилиндр, соответственно.

Также, нам встретился новый оператор IS:

  • <Имя поля> IS <Имя поля декларируемого типа узла>
  • <Имя события> IS <Имя события декларируемого типа узла>

Который позволяет связывать параметры и сообщения узлов, из которых состоит реализация создаваемого нами типа, с его интерфейсными параметрами и сообщениями.

Продолжим:

DEF XForm Transform { children [
  TwoColorStool { legColor 1 0 0 seatColor 0 0 1 }
  DEF Clicker TouchSensor {}
  DEF TimeSource TimeSensor { cycleInterval 2.0 }
  # Animate one full turn about Y axis:
  DEF Animation OrientationInterpolator {
       key      [ 0,      .33,       .66,        1.0 ]
       keyValue [ 0 1 0 0, 0 1 0 2.1, 0 1 0 4.2, 0 1 0 0 ]
  }
]}

ROUTE Clicker.touchTime TO TimeSource.startTime
ROUTE TimeSource.fraction_changed TO Animation.set_fraction
ROUTE Animation.value_changed TO XForm.rotation
NavigationInfo { type "EXAMINE" }

Здесь, мы определяем новый узел XForm типа Transform, который кроме уже описанной нами табуретки (синего цвета с зелеными ножками, рисунок 2) содержит датчик прикосновений TouchSensor, порождающий событие, когда в обозревателе по нашей табуретке щелкают мышкой (т.е. касаются) и таймер TimeSensor. Таймер настроен таким образом, что постоянно генерирует событие fraction_changed значение которого пробегает значение от 0 до 1 за две секунды. Также используется узел OrientationInterpolator, интерполирующий значение типа SFRotation по таблице в зависимости от значения поля fraction. Затем соответствующим образом построено взаимодействие между датчиком прикосновений, таймером, интерполятором и трансформатором позиции табуретки (три ROUTE). В итоге мы получили объект (в нашем случае табуретку, но на ее месте может быть узел любого заранее определенного типа) способный повернуться вокруг себя за две секунды, если к нему прикоснулись. Избушка, избушка, встань к монитору… Последняя строчка переводит обозреватель перейти в режим изучения объекта, в котором наблюдатель не двигается, а просто рассматривает и трогает предмет.

Небольшое продолжение к нашему примеру демонстрирует возможность использования Java Script (если быть корректным — ECMA Script) в VRML программах:

DEF Sizer Script {
  eventIn SFTime startSizing
  eventOut SFVec3f scale
  field SFFloat sc 1.0
  field SFBool sizeUp TRUE
  url "javascript:
    function startSizing() {
      if(sizeUp) sc+=0.04;
            else sc-=0.04;
      if(sc<0.8||sc>1.3) sizeUp=!sizeUp;
      scale[0]=sc;
      scale[1]=sc;
      scale[2]=sc;
    }
  "
}

DEF Ticker TimeSensor {
  cycleInterval 0.05
  loop TRUE
  enabled FALSE
}

ROUTE Clicker.isOver TO Ticker.set_enabled
ROUTE Ticker.cycleTime TO Sizer.startSizing
ROUTE Sizer.scale TO XForm.scale

Вот так, с помощью предопределенного узла Script мы получаем практически безграничные возможности в определении правил, по которым будет жить наш мир. В данном примере мы заставляем нашу табуретку циклически менять размер (дышать), пока над ней находится курсор обозревателя, вне зависимости от того, прикоснулись мы к ней или нет. Для этого используется событие isOver узла TouchSenser, реагирующее на описанную выше ситуацию с мышиным курсором, таймер генерирующий 20 раз в секунду событие cycleTime и небольшой скрипт, создающий масштабирование, которое затем применяется к объекту.

Дополнения

Все, что было написано ранее, ни в коем случае не претендует на роль руководства или описания. Это лишь попытка показать, что же в действительности стоит за весьма претенциозным термином VRML. Любители формальных грамматик и полных описаний, а также просто заинтересованные читатели могут заглянуть сюда. Где можно найти исчерпывающее описание синтаксиса и концепций VRML 2.0. И множество прокомментированных примеров от SGI, послуживших отличной основой для написания приведенных выше VRML программ. Впрочем, будьте внимательны: в доступных по этому адресу примерах, к моему искреннему удивлению, практически сразу обнаружилось несколько грубых ошибок. Которые, разумеется, убили некое сверхплановое количество свободного времени, но были успешно опознаны и уничтожены. Предвидя возможные недостаток желания или нехватку сетевого времени, приведу список некоторых предопределенных узлов VRML 2.0, отметив, где и как их можно использовать:

Группировка объектов:

AnchorСсылка на URL или URN (альтернативная форма URL)
BillboardМодификатор осей координат
CollisionОбработка столкновений
GroupПростая группа
TransformРазличные преобразования систем координат

Специальные группы:

InlineВставка VRML текста из любого URL
LODУправление уровнем детализации объекта при отрисовке
SwitchУправляемый выбор одного ребенка

Общие узлы:

AudioClipАудио, MIDI или WAV
DirectionalLightНаправленный источник света
PointLightТочечный источник света
ScriptПоддержка внешних языков (ECMA Script, Java,…)
ShapeОтображаемый объект
SoundИсточник 3D звука
SpotLightИсточник света типа прожектор
WorldInfoДополнительная текстовая информация про данный мир

Генераторы событий:

CylinderSensorПреобразует движения мыши в координаты на поверхности цилиндра
PlaneSensorТо же, но в плоскости
ProximitySensorРегион в пространстве чувствительный к проникновению в него
SphereSensorПреобразует движения мыши в координаты на поверхности сферы
TimeSensorТаймер
TouchSensorДатчик прикосновений
VisibilitySensorДатчик видимости

Геометрическая информация:

BoxПрямоугольник
ConeКонус
CylinderЦилиндр
ElevationGridПоверхность вида z=f(x,y)
ExtrusionФигура образованная 2D контуром, протянутым вдоль кривой
IndexedFaceSetНабор точек и построенных по ним граней
IndexedLineSetНабор точек и построенных по ним линий
PointSetНабор точек
SphereСфера
TextТекст

Дополнительная информация:

ColorНабор цветов для каждой вершины объекта
CoordinateНабор координат
NormalНабор векторов нормалей
TextureCoordinateПривязка текстуры

Свойства внешнего вида:

AppearanceВсе в купе для отображаемого объекта
FontStyleПараметры шрифта
ImageTextureТекстура, в виде URL на изображение
MaterialМатериал
MovieTextureАнимационная текстура, URL на клип
PixelTextureТекстура, задаваемая прямо в программе
TextureTransformДополнительное преобразование текстурных координат

Интерполяторы по таблице значений:

ColorInterpolatorЦвета
CoordinateInterpolatorКоординат
NormalInterpolatorВекторов нормалей
OrientationInterpolatorОриентации (поворота)
PositionInterpolatorПозиции
ScalarInterpolatorЛюбого плавающего значения

Управление глобальными параметрами обозревателя:

BackgroundФон изображения
FogХарактеристики атмосферы
NavigationInfoРежим навигации и взаимодействия
ViewpointТочка обзора

Клиенты всегда правы

Все клиенты обладают достаточно схожим интерфейсом. Как правило, навигация осуществляется манипулятором, например мышкой, причем есть несколько легко переключаемых режимов:

  • Движение вперед-назад и повороты вправо-влево
  • Движение вверх-вниз и вправо-влево
  • Повороты вверх-вниз и вправо-влево
  • Автоматическое движение до указанного объекта
  • Переход на заранее определенную точку зрения
  • Возможность "потрогать" объект


Эти действия являются стандартными практически для любой клиентской программы. Опишу два самых успешных, распространенных и самозабвенно конкурирующих обозревателя, соответствующих стандарту VRML 2.0.

Cosmo Software — Cosmo Player:

Разработка SGI. Представляет собою plug-in для браузера, интегрируется в Netscape 3.0 и более или Microsoft Explorer 4.0 и более. Для отображения использует библиотеку OpenGL, и, следовательно, аппаратную акселерацию на любом OpenGL совместимом ускорителе. Для создания объемного звука используется DirectSound (DirectX 3.0) и выше, следовательно, также поддерживается аппаратное ускорение. Клиент соответствует стандарту VRML 2.0 и VRML 97. Поддерживает полноценные Java классы (а не только ECMA Script). Файлы VRML 1.0 автоматически конвертируются в VRML 2.0. Все передаваемые данные могут быть запакованы в GZIP архив, для уменьшения времени загрузки мира. Может быть использован любой программой, как встроенный ActiveX элемент, что позволяет программистам легко добавлять поддержку просмотра VRML в свои продукты. Содержит множество полезных мелочей, начиная с отката действий и заканчивая отладочной консолью для создающих VRML файлы разработчиков. Среди досадных ошибок — неправильная обработка параметров некоторых источников освещения, некоторые проблемы с заданием скорости перемещения из программы и поддержкой анимационных GIF изображений. В поставку входит очень миролюбивая игра "Chomp", с акулой в главной роли, полностью написанная на VRML и ECMA Script. Отличные скоростные качества. Данный клиент всячески рекомендуется мною к использованию. Поддерживаются различные платформы, в том числе: SGI, Windows (9x/NT/3.11) и Mac OS. Органы управления подробно изображены на рисунке 4, взятом из документации. Последнюю версию (Cosmo Player 2.1), море информации и отлично оформленный сайт с VRML афишками Вы найдете по адресу cosmosoftware.com

Microsoft VRML 2.0 viewer:

Разработка … понятно чья. Основан на коде упомянутого ранее WorldView. Представляет собою plug-in для браузера, интегрируется в Microsoft Explorer 3.0 и более. Для отображения использует библиотеку DirectX 3.x и выше, и, следовательно, аппаратную акселерацию на любом DirectX совместимом ускорителе. Соответствует стандарту VRML 2.0 (есть некоторые несущественные расхождения). Поддерживает полноценные Java классы (а не только ECMA Script), но только как URL, а не внутри VRML текста. Поддерживает файлы VRML 1.0. Есть некоторые проблемы с GZIP файлами, приводящие, как правило, к предупреждениям которые можно игнорировать, но иногда прекращающие загрузку миров. Есть некоторые проблемы с реализацией ProximitySensor и обработкой сообщений таймера и событий, связанных с взаимодействием, что крайне печально. Достаточно компактный и удобный интерфейс. Несколько бестолковые настройки. Производительность (немного) и визуальное качество (сильно) уступают Cosmo Player. Рекомендуется как замена Cosmo Player, в случае невозможности использовать его по какой либо причине. Более подробная и глубокая справочная информация, подробно рассмотрено большое количество неоднозначных аспектов конкретной реализации. Не может быть использован как ActiveX элемент в сторонних программах. Только Windows (9x/NT) платформа. Последнюю версию, информацию и устаревшую галерею Вы найдете по адресу www.microsoft.com/vrml/

Впрочем, полуось (IBM OS/2) также не забыта разработчиками: фирма Now Interprises разработала OS/2 VRML viewer.

Редакторы, корректоры, конверторы:

Существует огромное множество инструментария для работы с VRML. Сформулируем, в кратце, основные категории подобных продуктов:

  • Конвертеры — преобразуют файлы других трехмерных форматов в VRML.
  • Валидаторы — проверяют VRML файлы на наличие синтаксических и структурных ошибок.
  • Интерактивные редакторы — позволяют редактировать VRML миры без непосредственного программирования, как это делается в большинстве трехмерных студий.

Где красиво убить время

Обязательно загляните на сайт Российской компании ParallelGraphics

Заключение

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

P.S.

В настоящее время на рынке VRML браузеров доминируют три следующие программы:

  1. Blaxxun Contact 4.3 (www.blaxxun.com) — поддержка сплайновых поверхностей (NURBS), версии с поддержкой DirectX/OpenGL, PIII-оптимизация геометрических вычислений, клиент к многопользовательским VRML-мирам;
  2. Cortona VRML client 2.1 (www.paragraph.ru) - поддержка сплайнов и сплайновых поверхностей (NURBS), поддержка Macromediа Flash и Real Video технологий, графические API DirectX/OpenGL, звуковой EAI2, PIII-оптимизация, версия клиента для многопользовательских VRML-миров;
  3. CosmoPlayer 2.1 — DirectX/OpenGL

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