Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Телегин А.И., Елисеев В.П., Горожанин А.А.

УДК 681.3.06

X3D-МОДЕЛИРОВАНИЕ МЕХАНИЧЕСКИХ СИСТЕМ

Телегин А.И., Елисеев В.П., Горожанин А.А.

Рассматриваются варианты использования расширяемого языка разметки трёхмерной векторной графики (X3D) для моделирования и анимации движения тел управляемых механических систем (МС). Описаны методики повторного использования X3D-кода, увеличения его функционала, прототипирования подсистем и МС в целом, которые демонстрируются на примерах моделирования манипуляционных систем роботов (МСР) и шагающих аппаратов (ША). Приводятся листинги законченных и прошедших всестороннее тестирование X3D-кода. Чтение статьи не требует знаний XML-технолгий, и языка X3D.

 

Введение. Рассматриваемые МС состоят из абсолютно твёрдых тел, образующих между собой и, возможно, с землёй (со стойкой, станиной, опорной поверхностью) различные кинематические пары (КП). К таким МС относятся, например, МСР, ША, колёсные и гусеничные транспортные средства, подъёмно-транспортные механизмы и различные машины. С появлением и бурным развитием XML-технологий и, в частности, декларативного языка программирования X3D появилась возможность повысить эффективность формального описания и визуализации МС. В предлагаемой статье рассматриваются варианты использования возможностей X3D для моделирования и анимации (воспроизведения движений тел) МСР и ША.

1. Необходимые основы XML. XML (e X tensible M arkup L anguage, расширяемый язык разметки) – это метаязык, в котором описываются общие правила создания новых (корпоративных, отраслевых, предметно-ориентированных) языков разметки информации. Если язык уже разработан и описан, то пользователь может применять и расширять его по XML-правилам. Международный некоммерческий консорциум W3C специфицировал множество языков, например, XHTML (расширяемый язык разметки гипертекста), SVG (Scalable Vector Graphics, масштабируемая векторная графика), XForms (расширяемый язык разметки Web-форм), X3D. Разработчики программного обеспечения создали для них различные браузеры (плееры, плагины), позволяющие обрабатывать и воспроизводить (визуализировать) на экранах монитора соответствующие результаты. В настоящей статье рассматривается язык X3D и весь приводимый код прошел всестороннее тестирование плеером Instant Player.

Если X3D-код в листинге 1 набрать в блокноте, сохранить с расширением.x3d и открыть при помощи плеера Instant Player, то увидим в его окне зелёный куб на белом фоне.

 

Листинг 1. Зелёный куб с длинами рёбер 0.1 м. на белом фоне (сохранён в файле pkp.x3d).

<? xml version=" 1.0" encoding=" UTF-8"? > < X3D version='3.2'> < Scene> < Background skyColor=" 1 1 1" /> < Shape> < Box size=" 0.1 0.1 0.1" /> < Appearance> < Material diffuseColor=" 0 1 0" /> < /Appearance> < /Shape> < /Scene> < /X3D>  

 

Здесь и в дальнейшем справа от X3D-кода приводится вид X3D-сцены, соответствующий этому коду.

На примере X3D-кода в листинге 1 рассмотрим только те XML-правила, которые используются в настоящей статье. Начнём с правила составления пролога. Согласно ему любой xml-документ должен начинаться с объявления XML-разметки, которое заключается между символами <? и? >, содержит имя xml и несколько параметров (номер XML-версии, используемая кодировка и т.д.). В 1-й строке листинга 1 использовано простейшее объявление.

В правиле составления и записи элементов говорится, что размечаемая информация (контент) заключается между открывающими и закрывающими тегами и вместе с ними называется элементом, например, < Scene> …< /Scene>. Тег состоит из имени, заключенном в угловые скобки. Идентификатор имени открывающего и ему соответствующего закрывающего тега должен полностью совпадать, например, имена Scene и scene не совпадают. Перед именем закрывающего тега должен стоять слеш (наклонная черта). После имени открывающего тега через пробельный символ могут располагаться атрибуты элемента, например, < X3D version='3.2'>. То, что находится между тегами, называется содержимым элемента. Одни элементы могут входить в содержимое других элементов, например, < X3D version='3.2'> < Scene> … < /Scene> < /X3D>. Самый первый элемент, внутри которого размещаются все остальные элементы xml-документа, называется корневым элементом документа. Имя тега корневого элемента (как правило) совпадает с именем соответствующего языка разметки (в листинге 1 – это имя X3D). Элементы бывают пустыми, простыми и сложными. Сложным называется элемент, содержащий атрибуты или вложенные элементы (потомки), или и то, и другое. Простым называется элемент без атрибутов и без вложенных элементов, но с текстовым содержимым. Если простой элемент не имеет текстового содержимого, то он называется пустым. Для записи пустого элемента и сложного элемента без содержимого используется укороченная (стенографическая) форма, например, < Box size=" 0.1 0.1 0.1" />.

Правило записи атрибутов говорит о том, что элемент может иметь один или несколько атрибутов, отделенных друг от друга пробельным символом. Атрибут состоит из имени и значения, отделенных друг от друга знаком равенства (=). Значение атрибута помещается либо в двойные, либо в одинарные кавычки. Элемент не может иметь атрибуты с одинаковым именем. Атрибуты элемента описывают его свойства.

Из правила правильного вложения элементов следует, что содержимое одного элемента не должно пересекаться с содержимым другого элемента, т.е. последнему открывающему тегу соответствует первый закрывающий тег. Например, следующий фрагмент разметки не правильный < X3D version='3.2'> < Scene> … < /X3D> < /Scene>.

В рекомендациях именования элементов и атрибутов указывается, что эти имена должны записываться на языке основных пользователей. Поэтому имена элементов и атрибутов расширения, а также текстовые значения (кроме предопределённых) всех атрибутов будем задавать на русском языке. Каждую новую часть составного имени условимся начинать с заглавной буквы, а аббревиатуры записывать заглавными буквами. Например, атрибут с именем значенияОК будет введён (смотрите раздел …) в качестве контейнера для массива вещественных значений обобщённых координат (ОК) ША, а значениями атрибута начальныеЗначенияОК будут значения ОК в начальный момент времени.

Код в листинге 1 соответствует описанным правилам и отражает структуру x3d-документа. В листинге 1 первая строка сообщает браузеру, что перед ним xml-файл. В следующей строке записан открывающий тег корневого элемента с единственным атрибутом, содержащим номер версии используемого языка Х3D. Содержимым корневого элемента является разметка сцены.

Остальные XML-правила в настоящей статье не используются. Поэтому перейдём к изложению основ языка X3D.

2. Необходимые основы X3D. X3D-элементы принято называть узлами (nodes), а их атрибуты полями (fields). За редким исключением имена узлов начинаются с большой буквы, имена полей – с маленькой. X3D-узлы хранят свои свойства в полях. В описании узла для многих его полей определены значения по умолчанию. Поэтому если значение такого поля в X3D-файле не задано, то используется значение по умолчанию. Например, значением по умолчанию поля size узла Вох является тройка вещественных чисел size=”2.0 2.0 2.0”. Значение каждого поля относится к одному из допустимых типов данных. Все типы данных разбиты на два класса: Single-Value (однозначный) и Multiple-Value (многозначный). Имена типов полей класса Single-Value начинаются с символов SF и хранят только одно значение (число, 2-х или 3-х или 4-х мерный вектор и т.п.). Имена типов полей класса Multiple-Value начинаются с символов MF и могут содержать множество (список) перечисленных значений. Например, значения поля version относятся к типу SFFLoat (одно действиельное число). В Х3D используются следующие типы полей.

SFBool или MFBool – одно или несколько логических (булевых) значений true (истина) или false (ложь).

SFColor или MFColor – одно или несколько значений RGB-цвета, состоящих из трех действительных чисел, каждое от 0 до 1. Числа соответствуют красному, зеленому и синему компоненту цвета. Например, " 0 1 0" – это ярко-зеленый цвет.

SFColorRGBA или MFColorRGBA – одно или несколько цветовых значений с указанием прозрачности, состоящих из четырех действительных чисел, каждое от 0 до 1. Например, значение “1 0 0 0.32, 0 1 0 0.55, 0 0 1 0.66” типа MFColorRGBA описывает красный, зелёный и синий цвета разной прозрачности.

SFInt32 или MFInt32 – одно или несколько 32-битовых целых чисел, заданных в десятичном или шестнадцатиричном формате.

SFFloat или MFFloat – одно или несколько вещественных чисел.

SFDouble или MFDouble – одно или несколько вещественных чисел двойной точности.

SFImage или MFImage – одно или несколько значений изображения.

SFNode или SFNode – один или несколько узлов.

SFRotation или MFRotation – один или несколько кодов вращения вокруг определенной оси. Каждый код состоит из четверки действительных чисел, первые три из которых содержат координаты направляющего вектора оси вращения, а четвертое – величину угла поворота в радианах. Например, “0 0 1 1.57” – код поворота вокруг оси Z на угол 90 градусов.

SFTime или MFTime – одно или несколько значений времени (действительное число, выраженное числом секунд).

SFString или MFString – одно или несколько cтроковых значений.

SFVec2f или MFVec2f – один или несколько двумерных векторов. Каждый из них представляется двумя действительными числами.

SFVec3f или MFVec3f – один или несколько трехмерных векторов. Каждый из них представляется тройкой действительных чисел.

SFVec2d или MFVec2d – один или несколько двумерных векторов вещественных чисел двойной точности.

SFVec3d или MFVec3d – один или несколько трехмерных векторов вещественных чисел двойной точности.

Каждое поле имеет один из четырёх типов доступа. При создании узлов прототипов и скриптов (смотрите разделы 6, 7) типы доступа к новым полям задаются в атрибуте accessType. Если accessType=”initializeOnly”, то поле является закрытым, т.е. содержит неизменяемые исходные значения свойств узла. Поле у которого accessType=”inputOnly” будем называть in-полем (входным полем). Это поле является контейнером для изменяемых данных, которые могут поступать в это поле от выходных полей других узлов. Для выходного (out-) поля accessType=”outputOnly”. Оut-поле содержит значение, которое можно отправить в in-поле другого узла. Если accessType=”inputOutput”, то имеет место inOut-поле, в которое можно записать новое значение и прочитать изменившееся значение, т.е. inOut-поле является одновременно in-полем и оut-полем.

3. Простейшие графические узлы (ГУ). Реальное тело МС можно в первом приближении моделировать следующими ГУ: Box (прямоугольный параллелепипед), Cylinder (цилиндр), Cone (конус) и Sphere (сфера). В списке 1 приведены описания этих узлов и их свойств.

Большинство узлов могут содержать дочерние узлы и их группы. Каждый такой узел определяет для своих потомков невидимую систему координат (НСК), относительно которой можно задавать положения этих потомков. В X3D используется правая декартова НСК OXYZ, где ось Z перпендикулярна плоскости экрана и направлена к наблюдателю, ось Y вертикальна. Например, с узлом Scene связана НСК с началом в центре окна браузера. Длины измеряются в метрах, углы в радианах, положительным считается поворот против хода стрелки часов.

По умолчанию (смотрите список 1) длины рёбер узла Box равны двум метрам, начало НСК лежит в его геометрическом центре, рёбра параллельны координатным осям. В поле size задаются размеры прямоугольного параллелепипеда вдоль осей X, Y, Z НСК, например, < Вох size='1 2 3'/>. Согласно разметке в листинге 1 НСК узла Box будет совпадать с НСК сцены. Поэтому куб располагается в центре экрана монитора.

По умолчанию узел Cylinder имеет высоту 2 метра, радиус основания 1 м. Начало НСК находится в его геометрическом центре. Ось Y параллельна вертикали. В полях side, top и bottom записываются булевы значения (TRUE или FALSE) как признаки видимости боковой поверхности, верхнего и нижнего оснований, соответственно. С их помощью браузер определит, нужно (TRUE) или нет (FALSE) отображать соответствующую поверхность цилиндра. По умолчанию эти поля имеют значение TRUE. Если основание цилиндра закрыто другим ГУ, то его отображение лучше отключить, чтобы не задавать лишней работы браузеру. Следующий код:

< Cylinder radius='2' bottom='FALSE' top='FALSE'/>

размечает цилиндр высотой и радиусом оснований 2 метра, которые не видны.

Конус (Cone) сходен с цилиндром, только поле radius заменено полем bottomRadius (радиус основания) и отсутствует поле top. Ось конуса совпадает с осью Y его НСК, т.е. конус со свойствами по умолчанию будет простираться на метр ниже горизонтальной плоскости OXZ его НСК и на метр выше этой плоскости. В следующем ГУ все свойства конуса можно опустить, т.к. их значения используются по умолчании.

< Cone bottomRadius='1' height='2' bottom='TRUE' side='TRUE'/>

Узел Sphere в центре имеет начало своей НСК. Поле radius содержит числовое значение радиуса сферы (по умолчанию равно 1 м.) и должно быть больше нуля, например, < Sphere radius=" 7.2" />.

Условимся помещать в начале сцены узел < Background skyColor='1 1 1'/>, который задаёт однотонный белый фон. Узел Background (фон) позволяет размечать отдельно небо, землю, а также текстуру фона в целом. Но нам достаточно наблюдать за МС в сцене на белом фоне находясь на некотором удалении от сцены. Поэтому условимся за узлом Background размещать узел Viewpoint (точка зрения) со свойством position=’a b c’, где числа a, b, c – координаты наблюдателя относительно НСК сцены.

В дальнейшем (с целью сокращения текста листингов) мы будем приводить только код разметки заключённый между блоком

<? xml version=" l.0" encoding=" UTF-8"? >

< X3D version='3.2'> < Scene> < Background skyColor='1 1 1'/> < Viewpoint position=’a b c’/>

и концовкой < /Scene> < /X3D>, где вместо а, b, c должны стоять конкретные вещественные числа – координаты (в метрах) точки наблюдателя относительно НСК сцены. Эти числа необходимо подобрать так, чтобы ГУ X3D-мира не вышли за пределы экрана монитора.

Любой из рассмотренных ГУ должен быть потомком (дочерним узлом) узла Shape (форма), который содержит в себе узел Appearance (внешность), размечающий внешний вид ГУ. Информация о внешности ГУ содержится в узлах Material, ImageTexture и других потомках узла Appearance. Поэтому правильная разметка конуса имеет следующий вид.

 

Листинг 2. Зелёный конус высотой 0.1 м. и радиусом невидимого основания 0.1 м. на белом фоне (в файле bkp.x3d).

< Shape> < Cone bottomRadius='0.1' height='0.1' bottom=" FALSE" /> < Appearance> < Material diffuseColor=" 0 1 0" /> < /Appearance> < /Shape>

 

Это типовая структура разметки сцены, которая содержит одну форму (Shape), состоящую из ГУ, внешность (Appearance) которого описывается свойствами материала (Material). Цвет материала задаётся в свойстве diffuseColor в формате RGB.

4. Трансформации ГУ. В X3D можно использовать следующие типы преобразований (трансформаций) ГУ – перемещение (translation), вращение (rotation) и масштабирование (scale). Эти преобразования описываются в полях узла Transform (УТ), который содержит трансформируемые ГУ, например,

< Transform scale='1 1 2' rotation='0 0 1 1.57' translation='2 0 0'> … < /Transform>

Здесь вместо троеточия должны располагаться формы трансформируемых ГУ. Поле translation отвечает за перемещение (перенос) содержимого (всех потомков) УТ из одного места в другое. Значением этого поля являются три вещественных числа х-, у- и z-координаты (положительные или отрицательные), которые задают величины перемещения НСК УТ (вместе со своим содержимым) вдоль осей X, Y, Z НСК его предка. Преобразования осуществляются в следующем порядке: сначала масштабирование, затем поворот, и в конце – перемещение. Но поля УТ (и других x3d-узлов) могут быть объявлены в любом порядке.

Масштабирование умножает размеры потомков УТ на значения поля scale в соответствующем измерении. Масштабирование с коэффициентом нуль сделает ГУ бесконечно тонким в выбранном направлении. Чтобы объект не изменился, коэффициент масштабирования должен быть равен единице.

Поле rotation УТ содержит четыре вещественных числа. Первые три из них задают координаты (например направляющие косинусы) оси вращения, а четвертый определяет угол поворота в радианах. Например, чтобы повернуть потомков УТ на 45° вокруг оси X, следует написать: < Transform rotate=" 1 0 0 0.78" >. УТ может иметь вложенные УТ, что создаёт последовательности преобразований. Порядок, в котором выполняются преобразования, влияет на результат. Поворот после перемещения и перемещение после поворота – это не одно и то же.

В качестве примера в листинге 3 размечена система координат, которую будем жёстко связывать с каждым телом МС. Здесь ось OX представлена в виде тонкого (0.04*0.04) красного параллелепипеда длиной 0.2 м. Ось OY представлена в виде тонкого (радиуса 0.03 м.) зелёного цилиндра высотой 0.2 м. Ось OZ представлена в виде синего конуса высотой 0.3 м. и радиусом основания – 0.03 м.

 

Листинг 3. Связанная система координат (ССК) тела (XYZ.x3d). < Transform translation=" 0.1 0 0" > < Shape> < Box size=" 0.2 0.04 0.04" /> < Appearance> < Material diffuseColor=" 1 0 0" /> < /Appearance> < /Shape> < /Transform> < Transform translation=" 0 0.1 0" > < Shape> < Cylinder radius=" 0.03" height=" 0.2" /> < Appearance> < Material diffuseColor=" 0 1 0" /> < /Appearance> < /Shape> < /Transform> < Transform rotation=" 1 0 0 1.57" translation=" 0 0 0.15" > < Shape> < Cone bottomRadius=" 0.03" height=" 0.3" /> < Appearance> < Material diffuseColor=" 0 0 1" /> < /Appearance> < /Shape> < /Transform>      

 

5. Повторное использование кода. Если ГУ используется несколько раз в рамках одного и того же X3D-файла, то его можно тиражировать. При создании X3D-миров этот прием экономит много времени и места. Все получающиеся в результате тиражирования ГУ идентичны, но могут различаться, например, положением в пространстве. Тиражируемый узел называется оригиналом, а копии – экземплярами.

Для тиражирования используются поля USE и DEF. Полю DEF ГУ присваивается имя. Если это же имя использовать в поле USE пустой формы, то будет создан экземпляр этого ГУ. Например, в коде

< Shape DEF=”сфера-1”> < Sphere/> < Appearance> < Material/> < /Appearance> < /Shape>

< Transform translation=" 0.5 0 0" > < Shape USE=”сфера-1”/> < /Transform>

размечены две одинаковые сферы. Центр первой сферы совпадает с центром НСК сцены, так как предком первого узла Shape является сцена (узел Scene). Центр второй сферы сдвинут относительно НСК сцены по горизонтали на 0.5 м., так как второй узел Shape является потомком УТ, поле translation которого имеет значение 0.5 0 0. Здесь первая форма (узел Shape) использована повторно. Первый раз ей присвоен идентификатор ”сфера-1”. Второй раз в значении поля USE указан этот же идентификатор. Поэтому X3D-браузер интерпретирует вторую форму полностью совпадающей с первой, включая её содержимое, т.е. разметку сферы. Аналогичным образом можно определить для повторного использования узел любого типа или группу узлов. Например, если группа < Group DEF=”МС”> …< /Group> содержит разметку МС, то декларация < Transform translate=”1 0 0”> < Group USE=”МС”/> < /Transform> переместит эту МС на 1 метр вправо и покажет ещё раз эту же МС. Так можно разметить стройный отряд ША шагающих в две шеренги точно в ногу.

В другом способе повторного использования кода применяется узел Inline. Он берёт данные из внешнего X3D-файла и вставляют в X3D-мир на своё место. Если у вас есть X3D-модель расположенная в файле model.x3d, то можно вставить ее в сцену следующим образом: < Inline url='model.x3d'/>. Включаемый таким образом файл должен быть синтаксически правильным Х3D-файлом, т.е. иметь заголовок и другие разделы. Если файл не грузится в браузер самостоятельно, то его Inline-вставка в другой X3D-файл приведёт к ошибке.

И так для повторного использования кода служат поля DEF/USE и узлы Inline. При повторном использовании узлов получаются компактные и выразительные X3D-файлы.

В качестве примеров разметим тела трёхзвенной МСР с цилиндрической системой координат. Условимся направляющую поступательной КП (ПКП) изображать в виде зелёного куба размером рёбер 0.1 м. (смотрите листинг 1), цилиндрический шарнир вращательной КП (ВКП) изображать в виде зелёного конуса высотой и радиусом основания 0.1 м. (смотрите листинг 2), ось Y НСК которого направлена вдоль оси вращения. В листингах 4 – 7 приведены разметки основания и тел МСР. В листинге 4 для повторного использования кода применён узел Inline. Он берёт X3D-код из внешнего файла, адрес которого записан в качестве значения поля url, и вставляет его в X3D-сцену на своё место (вместо себя). Здесь в центр основания над его верхней гранью вставлен конус, который условно изображает вращательный шарнир с первым телом ВКП.

В листинге 4 УТ с полем showProxyGeometry='true' использован для визуализации ССК сцены, оси которой изображены в виде тонких линий (красной для оси OX, зелёной для оси OY и синей для оси OZ). В листингах 5 – 7 ГУ использованные в разметке тел сдвинуты относительно ССК этих тел, т.к. разметки сцен в файлах t1.x3d, t2.x3d, t3.x3d начинаются с узла < Inline url=" XYZ.x3d" />.

 

  Листинг 4. Основание (стойка) в виде квадратной пластины с ВКП сверху и ССК сцены в центре (t0.x3d). < Transform showProxyGeometry='true'> < Shape> < Box size=" 0.3 0.02 0.3" /> < Appearance> < Material/> < /Appearance> < /Shape> < Transform translation=" 0 0.07 0" > < Inline url=" bkp.x3d" /> < /Transform> < /Transform>
  Листинг 5. Первое тело в виде вертикального параллелепипеда с направляющей ПКП в конце и с ССК в начале (t1.x3d). < Inline url=" XYZ.x3d" /> < Transform translation=" 0 -0.1 0" > < Shape> < Box size=" 0.03 0.2 0.03" /> < Appearance> < Material/> < /Appearance> < /Shape> < Transform translation=" 0 -0.1 0" > < Inline url=" pkp.x3d" /> < /Transform> < /Transform>    
  Листинг 6. Второе тело в виде горизонтального параллелепипеда с направляющей для ПКП в конце и ССК в центре (t2.x3d). < Inline url=" XYZ.x3d" /> < Shape> < Box size=" 1 0.03 0.03" /> < Appearance> < Material/> < /Appearance> < /Shape> < Transform translation=" 0.5 0 0" > < Inline url=" pkp.x3d" /> < /Transform>    
Листинг 7. Третье тело в виде вертикального параллелепипеда с чёрным шаром в нижнем конце и ССК с началом на расстоянии 0.25 м. от нижнего конца (t3.x3d). < Inline url=" XYZ.x3d" /> < Transform translation=" 0 0.25 0" > < Shape> < Box size=" 0.03 1 0.03" /> < Appearance> < Material/> < /Appearance> < /Shape> < Transform translation=" 0 -0.47 0" > < Shape> < Sphere radius=" 0.06" /> < Appearance> < Material diffuseColor=" 0 0 0" /> < /Appearance> < /Shape> < /Transform> < /Transform>
           

6. Узел Script. Максимальные анимационные возможности связаны с использованием узла Script (УС) и кода, например, на языке Java Script (JS), в нём расположенного. УС позволяют создавать уникальные узлы с собственными полями. Визуальные и функциональные возможности такого узла программируются на языке JS (его интерпретатор встроен в X3D-браузер).

Положение УС в графе сцены не оказывает влияния на его функционирование. Высокоуровневый код УС состоит из JS-функций, каждая из которых выполняется в определенной ситуации. Все JS-функции имеют доступ ко всем полям, определенным в УС. Структурно УС содержит ноль или несколько узлов field и секцию CDATA, в которой расположен JS-код. Структура УС имеет следующий общий вид.

< Script DEF='имяУС'>

< field name='константа_1' type='тип1' accessType='initializeOnly' value=”знач_1”/>

……………………………………………………………………………..

< field name='константа_K' type='типK' accessType='initializeOnly' value=”знач_K”/>

< field name='вход_1' type='тип-1' accessType='inputOnly'/>

……………………………………………………………………………..

< field name='вход_N' type='тип-N' accessType='inputOnly'/>

< field name='входВыход_1' type='тип-1' accessType='inputOutput' value=”начЗнач_1”/>

……………………………………………………………………………..

< field name='входВыход_L' type='тип-L' accessType='inputOutput' value=”значЗнач_L”/>

< field name='выход_1' type='типВыхода-1' accessType='outputOnly'/>

……………………………………………………………………………..

< field name='выход_M' type='типВыхода-M' accessType='outputOnly'/>

<! [CDATA[ ecmascript: var a, b, …., h; // описание глобальных переменных

function initialize() { … } // код инициализации

function shutdown() { … } // код завершения

function eventsProcessed() { … } // код обработки прерываний

function вход_1(имя_1, время_1) { … } // код обработки 1-го входного значения

………………………………….

function вход_N(имя_N, время_N) { … } // код обработки N-го входного значения

function входВыход_1(имя-1, время-1) { … } // код обработки 1-го входного значения

………………………………….

function входВыход_L(имя-L, время-L) { … } // код обработки L-го входного значения

]]>

< /Script>

УС и прототипы (смотрите раздел 7) как X3D-узлы могут иметь уникальные поля, т.е. поля расширения определенные пользователем. Механизм описания этих полей реализован в дочерних узлах field. В полях name, type, accessType узла field вложенного в УС описывают имя, тип значений и тип доступа уникального поля УС. Условимся называть такое поле JS-полем. Через JS-поля УС связывается для обмена информацией с полями других узлов X3D-мира (смотрите раздел 8). В приведенном общем виде УС описаны JS-поля с именами константа_1, …, константа_К, вход_1, …, вход_N, входВыход_1, …, входВыход_L, выход_1, …, выход_M. Полям с типом доступа inputOnly и inputOutput должны быть поставлены в соответствие JS-функции с аналогичными именами. В приведённом общем виде УС это JS-функции с именами вход_1, …, вход_N, входВыход_1, …, входВыход_L. Эти функции имеют по два необязательных аргумента с произвольными именами, из них первый аргумент (как контейнер данных) содержит значение JS-поля с именем JS-функции. Второй аргумент содержит момент времени, в который это значение пришло в JS-поле. Например, ели аргументы названы как value и time, то value – это новое значение входного JS-поля, а второй параметр time – момент времени, в который это значение пришло в входное JS-поле. Эти параметры можно опускать, или использовать первый из них, но нельзя менять их местами. Таким образом обработка значений входных JS-полей осуществляется в JS-функциях, имена которых совпадают с именами этих JS-полей. Имена JS-полей с типом доступа outputOnly и inputOutput могут использоваться в левых частях операторов присваивания JS-функций. Для общего вида УС переменные входВыход_1, …, входВыход_L, выход_1, …, выход_M могут встречаться в левых частях операторов присваивания JS-функций. Только таким образом осуществляется изменение значений выходных JS-полей. JS-поля с типом доступа initializeOnly доступны во всех JS-функциях, как глобальные константы, и им должны быть назначены значения в полях value.

УС имеет предопределённые поля (url, directOutput и mustEvaluate) и может содержать стандартные (предопределённые) JS-функции. Предопределённая функция initialize() вызывается после завершения загрузки мира, но до того, как мир отобразится на экране. Те команды, которые необходимо выполнить в процессе инициализации мира, должны составить тело этой функции. JS-функция initialize () особенно важна, когда УС должен сначала установить сетевые подключения. Предопределённая функция shutdown() вызывается в конце работы мира, т.е. когда браузер закрывается или происходит переход по ссылке в другой XML-документ. Она полезна для зачистки " хвостов", например, закрытия временных (вспомогательных) приложений. JS-функция shutdown() автоматически вызывается, когда сцена закрывается, или когда сам УС выгружается или заменяется. Никакие другие JS-функции УС не могут быть вызваны сценой после вызова shutdown(). Это позволяет завершить функциональные возможности УС, такие как вывод результатов вычислений или закрытие сетевого подключения. Предопределённая функция eventsProcessed() вызывается после обработки ряда событий. Как часто это случается, зависит от браузера. Это может быть после каждого обработанного события или реже.

В листинге 8 размечена кинематическая схема (КС) МСР и использован УС, содержащий одно входное JS-поле, одну предопределённою функцию и JS-функцию с именем входного JS-поля.

 

Листинг 8. Разметка КС МСР с идентифицированными УТ тел и JS-кодом для изменения значений их полей. < Inline url=" t0.x3d" /> < Transform DEF=" тело_1" rotation=" 0 1 0 0.0" > < Inline url=" t1.x3d" /> < Transform DEF=" тело_2" translation=" 0.0 -0.2 0" > < Inline url=" t2.x3d" /> < Transform DEF=" тело_3" translation=" 0.5 0.0 0" > < Inline url=" t3.x3d" /> < /Transform> < /Transform> < /Transform>      

< Script mustEvaluate=" TRUE" directOutput='TRUE'>

< field name='начальныеОК' type='MFFloat' accessType=" initializeOnly" value=" 0.5 0.3 -0.3" />

< field name='векторОК' type='MFFloat' accessType='inputOnly'/>

<! [CDATA[ ecmascript: var тело1, тело2, тело3;

function initialize() { сцена=Browser.currentScene; тело1=сцена.getNamedNode('тело_1');

тело2=сцена.getNamedNode('тело_2'); тело3=сцена.getNamedNode('тело_3');

тело1.rotation=new SFRotation(0, 1, 0, начальныеОК[0]);

тело2.translation=new SFVec3f(начальныеОК[1], -0.2, 0);

тело3.translation=new SFVec3f(0.5, начальныеОК[2], 0); }

function векторОК(вектор) { тело1.rotation=new SFRotation(0, 1, 0, вектор[0]);

тело2.translation=new SFVec3f(вектор[1], -0.2, 0);

тело3.translation=new SFVec3f(0.5, вектор[2], 0); }

]]>

Здесь стойка, разметка которой сохранена в файле t0.x3d (листинг 4), подключена (узлом Inline) в центр НСК сцены. Первое тело, разметка которого сохранена в файле t1.x3d (листинг 5), подключена в центр НСК стойки и вложена в УТ с идентификатором “тело_1” так, что меняя четвертое вещественное число поля rotation, можно поворачивать 1-е тело вместе со своей ССК вокруг вертикальной оси этой ССК. Второе тело, разметка которого сохранена в файле t2.x3d (листинг 6), подключено в точке с координатами “0.0, -0.2, 0” относительно ССК 1-го тела, так как вложена в УТ с идентификатором “ тело_2” и значением поля translation=”0.0 -0.2 0”, который сам вложен в УТ 1-го тела. Такая структура вложения УТ обеспечивает поворот 2-го тела вместе с 1-м телом вокруг оси OY ССК 1-го тела. Если первое число в значении поля translation УТ “тело_2” поменять на 0.5 (вместо 0.0), то 2-е тело будет изображено смещенным вдоль оси OX ССК 1-го тела на расстояние 0.5 м. Таким образом записывая в поле translation УТ “тело_2” значение “х -0.2 0”, где x – величина перемещения 2-го тела относительно 1-го, мы можем осуществлять анимацию 2-го тела МСР. Третье тело, разметка которого сохранена в файле t3.x3d (листинг 7), подключено в точке с координатами “0.5 0.0 0” относительно ССК 2-го тела, так как вложено в УТ с идентификатором “тело_3” и значением поля translation=”0.5 0.0 0”, который сам вложен в УТ 2-го тела, т.е. их оси абсцисс совместятся. Таким образом записывая в поле transform УТ “тело_3” значение “0.5 y 0“, где y – величина перемещения 3-го тела относительно 2-го, мы можем осуществлять анимацию 3-го тела МСР.

УС имеет входное JS-поле “ векторOK ”, в которое можно отправлять несколько вещественных значений. В разметке анимации будет продекларировано отправка в это JS-поле трех значений обобщенных координат (OK) МСР, где векторOK[0] – угол поворота 1-го тела относительно стойки, векторOK[1] – величина смещения 2-го тела вдоль оси OX ССК 1-го тела, векторOK[2] – величина смещения 3-го тела вдоль оси OY 2-го тела. В JS-коде УС эти значения записываются в соответствующие места полей УТ подвижных тел МСР. Для этого использованы JS-объекты Browser, SFRotation, SFVec3f.

JS-объект Browser (браузер) является статическим. Поэтому не нужно создавать переменную этого типа перед тем, как обратиться к его свойствам и функциям. Для того чтобы использовать функцию " Браузера", нужно просто написать Browser.имяФункции. УС в листинге 8 имеет два поля, называемые directOutput и mustEvaluate. Они особенно важны при использовании интерфейса " Браузера". Если в поле mustEvaluate стоит TRUE, то JS-код будет обработан браузером как можно скорее. В принципе браузерам разрешается задерживать обработку JS-кода, если в мире происходят более важные процессы. Параметр же mustEvaluate заставит браузер перейти к выполнению JS-кода немедленно. Если в поле directOutput стоит TRUE, JS-коду разрешается непосредственно записывать информацию в входные поля доступных ему узлов и считывать информацию непосредственно из выходных полей таких узлов.

В JS структурированием данных занимаются объекты, т.к. они группируют данные (переменные, функции и другие объекты). Операция “точка” (.) называется операцией взятия члена структуры. Она позволяет обращаться к члену (переменной, функции, объекту) объекта, например, obj1.var1 или obj1.func1() или obj1.obj2. Часть данных, к которой обращаются, должна стоять справа от точки. Такой способ обращения к члену структуры (к переменной, функции или объекту) называют “точечной нотацией”. Операция индексирования применяется при обращении к части данных из массива, например, array1[2] – обращение к 3-му элементу массива с именем array1[2].

Согласно JS-кода листинга 8 перед загрузкой X3D-мира, т.е. в процессе инициализации в переменные тело1, тело2, тело3 будут помещены УТ “ тело_1 ”, “ тело_2 ”, “ тело_3 ”. При изменении хотя бы одной ОК МСР, т.е. угла поворота 1-го тела, величины горизонтального перемещения 2-го тела или величины вертикального перемещения 3-го тела, в JS-функции векторОК(вектор) в поле rotation УТ “тело_1”, в поле translation УТ “тело_2” и в поле translation УТ “тело_3” будут записываться (заноситься) новые значения этих ОК, что обеспечит соответствующее движение тел МСР.

7. Внешнее прототипирование. X3D позволяет осуществить прямое расширение своего языка путем использования прототипов для создания, объявления и многократного использования новых узлов. В определении прототипа, размечается новый узел с необходимыми полями. Он конструируется из других узлов, включая экземпляры ранее созданных прототипов. Затем это определение используется, для создания экземпляров. Объявления прототипов можно размещать в отдельном X3D-файле или в библиотечном архиве.

Часто используемые комбинации узлов и модели систем – являются хорошими кандидатами для прототипирования. Можно один раз создавать и постоянно улучшать (без изменения интерфейса) прототипы во внешнем файле, не изменяя варианты их использования в проекте.

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

Рекомендуется прототипировать работающий, отлаженный и всесторонне протестированный X3D-код, т.е. следует преобразовывать существующий код в объявление прототипа. Для этого выделенный фрагмент графа сцены должен быть обернут в узел ProtoDeclare, содержащий узлы ProtoInterface и ProtoBody. Поля прототипа описываются в узлах field узла ProtoInterface. Структура определяющая новый прототип имеет следующий общий вид:

< ProtoDeclare name='имя_прототипа'>

< ProtoInterface>

< field name='конст_1' type='тип1' accessType='initializeOnly' value=”знач_1”/>

……………………………………………………………………………..

< field name='конст_K' type='типK' accessType='initializeOnly' value=”знач_K”/>

< field name='вход_1' type='тип-1' accessType='inputOnly'/>

……………………………………………………………………………..

< field name='вход_N' type='тип-N' accessType='inputOnly'/>

< field name='входВыход_1' type='тип-1' accessType='inputОutput' value=”нач.Знач_1”/>

……………………………………………………………………………..

< field name='входВыход_L' type='тип-L' accessType='inputОutput' value=”нач.Знач_L”/>

< field name='выход_1' type='типВыхода-1' accessType='outputOnly'/>

……………………………………………………………………………..

< field name='выход_M' type='типВыхода-M' accessType='outputOnly '/>

< /ProtoInterface>

< ProtoBody> Тело прототипа < /ProtoBody>

< /ProtoDeclare>

Видно, что узел ProtoInterface аналогично УС определяет поля, которые составляют интерфейс нового узла. Каждый его дочерний узел field содержит поле name (имя нового поля), type (тип его значений), accessType (тип доступа) и (в случаях accessType=”initializeOnly” или accessType=”inputОutput”) value (возможное начальное значение). Узел < ProtoInterface> может не иметь полей.

Поля ProtoInterface отвечают следующим правилам, которые относятся к полям встроенным в узлы X3D (в том числе к полям УС). У закрытых полей (initializeOnly) должно быть начальное значение. У inOut-полей должно быть начальное значение. У in-полей и out-полей не должно быть начального значения.

В узле < field> может использоваться поле appinfo с текстовым описанием названия поля и поле documentation с url файла содержащего соответствующую документацию. Их значения позволяют обеспечивать дополнительные метаданные об определениях, например, appinfo='контейнер для записи ОК МСР.'

Каждый прототип должен иметь уникальное имя. Хорошие имена новых узлов и их полей очень важны, т.к. повышают понятийность и читабельность кода.

В процессе прототипирования необходимо строго контролировать типы узлов. Каждый заявленный узел прототипа соответствует типу первого (корневого) узла в теле прототипа. Это позволяет строгого контролировать типы узлов во время загрузки (проверяя родительско-дочерние отношения узлов). Таким образом, новым экземплярам прототипа можно вписаться в граф сцены только в тех местах, где разрешен первый узел тела прототипа. Другие узлы могут следовать в теле объявления прототипа, но только первый узел определяет используемый тип и только первый узел визуализируется. Поэтому для визуализации нескольких прототипируемых узлов их необходимо сгруппировать при помощи узла Group.

Интерфейсные поля прототипа связываются с полями в теле прототипа. Для этого в теле применяют узел < IS> и его дочерние узлы < connect>. IS-связывание соединяет поле существующего узла с полем интерфейса прототипа. Отметим, что IS-связь возможна между полями с одинаковым типом значений и доступа.

 

Листинг 9. Код протодекларации разметки МСР в листинге 8 (МСвнешнееПрото.x3d)

< ProtoDeclare name=" прототипМС" >

< ProtoInterface>

< field name=" q" type=" MFFloat" accessType=" inputOnly" />

< field name=" q0" type=" MFFloat" accessType=" initializeOnly" value=" 0.5 0.3 -0.3" />

< /ProtoInterface>

< ProtoBody>

< Group>

< Inline url=" t0.x3d" />

< Transform DEF=" тело_1" rotation=" 0 1 0 0.0" > < Inline url=" t1.x3d" />

< Transform DEF=" тело_2" translation=" 0.0 -0.2 0" > < Inline url=" t2.x3d" />

< Transform DEF=" тело_3" translation=" 0.5 0.0 0" >

< Inline url=" t3.x3d" />

< /Transform>

< /Transform>

< /Transform>

< Script mustEvaluate=" TRUE" directOutput='TRUE'>

< field name='начальныеОК' type='MFFloat' accessType=" initializeOnly" value=" 0.5 0.3 -0.3" >

< IS> < connect nodeField=" начальныеОК" protoField=" q0" /> < /IS>

< /field>

< field name='векторОК' type='MFFloat' accessType='inputOnly'>

< IS> < connect nodeField=" векторОК" protoField=" q" /> < /IS>

< /field>

<! [CDATA[ ecmascript: var тело1, тело2, тело3;

function initialize() { сцена=Browser.currentScene; тело1=сцена.getNamedNode('тело_1');

тело2=сцена.getNamedNode('тело_2'); тело3=сцена.getNamedNode('тело_3');

тело1.rotation=new SFRotation(0, 1, 0, начальныеОК[0]);

тело2.translation=new SFVec3f(начальныеОК[1], -0.2, 0);

тело3.translation=new SFVec3f(0.5, начальныеОК[2], 0); }

function векторОК(вектор) { тело1.rotation=new SFRotation(0, 1, 0, вектор[0]);

тело2.translation=new SFVec3f(вектор[1], -0.2, 0);

тело3.translation=new SFVec3f(0.5, вектор[2], 0); }

]]>

< /Script>

< /Group>

< /ProtoBody>

< /ProtoDeclare>

 

Здесь в интерфейсе задекларировано только одно входное поле с именем наборОК и типом значений MFFloat. В него будут передаваться три ОК МСР. Тело протодекларации содержит один узел < Group>, в который вложена вся прототипируемая разметка (иначе будет изображаться только основание МСР).

Условимся все протодекларации хранить в отдельной библиотеке (в файле прото.x3d). Тогда для использования конкретного прототипа необходимо в X3D-сцене определить внешний прототип следующим образом:

< ExternProtoDeclare name='имяПрототипа' url='прото.x3d#имяПротодекларации'/>

Под URL-адресом прототипа подразумевается полный или относительный адрес X3D-файла, в котором находится полное описание прототипа. Если файл содержит только один прототип, то URL-адресом прототипа будет имя файла прото.x3d. Если же этот файл содержит описание нескольких прототипов, то после символа # надо указывать имя той протодекларации, по описанию которой будет создаваться экземпляр прототипа, например, " прото.x3d#имяПротодекларации ".

Для создания экземпляра прототипа (новой копии узла) используется узел < ProtoInstance>. В его дочерних узлах < fieldValue> задаются значения полей. Каждый новый узел может быть настроен при инициализации (при создании экземпляра) с использованием узлов < fieldValue> для переопределения значений полей по умолчанию.

Узел < ExternProtoDeclare> внешней протодекларации должен предшествовать любому соответствующему узлу < ProtoInstance> инициализации (создания) экземпляра, используемого в сцене. Это требование позволяет браузеру распознавать каждый новый узел.

Узлы ProtoInstance могут иметь DEF-имена и USE-копии как любой другой узел. У экземпляров прототипа есть все возможности как и у встроенных X3D-узлов. Структура < ProtoInstance> имеет следующий общий вид

< ProtoInstance name='имя'>

< fieldValue name='имя_1' value='значение_1'/>

………………………………………..

< fieldValue name='имя_n' value='значение_n'/>

< /ProtoInstance>

Узел fieldValue используется (если это необходимо) для отмены заданных по умолчанию значений полей прототипа и назначения новых значений этих полей в момент инициализации экземпляра протоузла.

 

Листинг 10. Код протодекларации разметки МСР

< ExternProtoDeclare name=" прототипМС" url=" МСвнешнееПрото.x3d" />

< ProtoInstance DEF=" МС_1" name=" прототипМС" >

< fieldValue name=" q" /> < fieldValue name=" q0" value=" 0.2 0.4 -0.3" />

< /ProtoInstance>

< Transform translation=" -0.6 1 0" > < TouchSensor DEF='клик'/>

< Shape DEF=" кнопка" > < Rectangle2D size='0.8 0.2'/>

< Appearance DEF=" цвет" > < Material/> < /Appearance>

< /Shape>

< Shape> < Appearance DEF='надпись'> < Material diffuseColor='0 0 0'/> < /Appearance>

< Text string='ПУСК'>

< FontStyle DEF='шрифт' size='0.1' family='SANS' justify='MIDDLE'/>

< /Text>

< /Shape>

< /Transform>

< Script DEF='ск'>

< field name='шаг' type='SFTime' accessType='inputOnly'/>

< field name='qq' type='MFFloat' accessType='outputOnly'/>

<! [CDATA[ ecmascript: t=0.0; dt=0.01;

function шаг() { t=t+dt; qq[0]=2*t; qq[1]=t; qq[2]=-t; }

]]>

< /Script>

< ROUTE fromField='touchTime' fromNode='клик' toField='шаг' toNode='ск'/>

< ROUTE fromField='qq' fromNode='ск' toField='q' toNode='МС_1'/>

 

Из изображения сцены справа от листинга 8 видно, что координаты x, y, z верхнего конца 3-го тела МСР относительно ССК сцены, вычисляются по формулам

x = (q2+L2) cos q1 , y = -L1+ q3+L3, z = - (q2+L2) sin q1

где L1=0.2 – расстояние от начала ССК сцены до оси OX ССК 2-го тела, L2=0.5 – расстояние между осями OY ССК 2-го и 3-го тела, L3=0.5 – половина длины 3-го тела (расстояние от начала ССК 3-го тела до его конца), q1 – угол от оси OX ССК сцены до оси OX ССК 1-го тела, q2 – абсцисса начала ССК 2-го тела относительно ССК 1-го тела, q3 – ординаты начала ССК 3-го тела относительно ССК 2-го тела. Для отношения z/x получим tg q1 = -z/x. Для суммы x2 + y2 получим (q2+L2)2 = x2 + y2. Следовательно заданным координатам x, y, z соответствуют q1, q2, q3 вычисляемые по формулам

q1= - arctg (z/x), q2= - L2 + , q3=y + L1 – L3

8. Интерактивная (отладочная) анимация. Основой анимации является маршрутизация, т.е. механизм связывания out-поля одного узла с in-полем другого узла при помощи узла соединения ROUTE, который условимся называть узлом коммутации (УК). УК имеет следующий общий вид

< ROUTE

fromNode=”значение DEF-поля узла источника данных (УИД)”

fromField=”имя out-поля УИД или значение out-поля name узла field УС|прототипа“

toNode=”значение DEF-поля узла приемника данных (УПД)”

toField=”имя in-поля УПД или значение in-поля name узла field УС|прототипа“/>

Набор УК (граф путей) описывает поток данных между узлами. Момент времени t изменения значений полей, задействованных в графе путей равен моменту t изменения значения out-поля в вершине этого графа, т.е. поток данных осуществляется мгновенно (как ток в проводах) от вершины (от out-поля) к листьям графа (к in-полям).

Имя in-поля можно использовать в качестве значения поля toFild УК (но не в качестве значения поля fromFild). Значение out-поля одного узла можно отправить в in-поля других узлов. inOut-поле имеет одновременно свойства, как in-поля, так и out-поля. Когда inOut-поле в УК рассматривается как in-поле в начале его имени добавляется префикс set_ (установленное значение). Если же inOut-поле выступает в роли оut-поля, то к концу его значения приписывается суффикс _changed (изменённое значение). К in-полям и inOut-полям относятся как к полям ввода (input – ввод), т.к. в них можно ввести (направить в in-поле) новое значение. К оut-полям и inOut-полям отношение как к полям вывода (output – вывод), т.к. к ним можно обратиться и взять (вывести из этого out-поля) значение, например, переадресовать это значение в in-поле (или inOut-поле) другого узла при помощи УК. Можно смотреть на УК как на оператор присваивания в виде to-Node.toFild=fromNode.fromFild.

УК принято размещать в конце X3D-кода.

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

Прототип и УС реагирует на изменившиеся значения out-полей связанных с ним узлов, т.е. получает изменившиеся значения out-полей от связанных с ним узлов и принимает эти новые значения в in-поля name своих узлов field. JS-функция выполняемая при поступлении по УК нового значения во входное JS-поле по УК. Эту JS-функцию называют обработчиком изменившегося значения входного JS-поля.

X3D строго типизированный язык. Поэтому в УК необходимо соблюдать типы значений, связываемых полей. Нельзя связывать поле типа SFTime с полем типа SFBool. При необходимости можно написать JS-код, который каждому значению величины одного типа (например, SFTime) поставит соответствующую величину другого типа (например, SFBool).

Пример анимации от положения в положение.

9. Сенсоры. В анимации используются узлы-сенсоры. Среди сенсоров выделяют сенсоры окружающей среды, т.к. они отслеживают состояние окружающей среды, например, течение времени (TimeSensor). Остальные сенсоры в своих out-полях отслеживают действия пользователей, т.е. автоматически меняют значения этих полей в ответ на действия пользователей. Среди этих сенсоров выделяют узлы-манипуляторы: Anchor (якорь), TouchSensor (контактный сенсор), CylinderSensor (цилиндрический сенсор), PlaneSensor (плоский сенсор), SphereSensor (сферический сенсор). Последние три образуют подмножество сенсоров перемещений.

Узел TimeSensor меняет значение (измеряемое в секундах) поля time (типа SFTime, с типом доступа) с некоторой частотой (через некоторые промежутки времени), зависящей от браузера. Но момент времени каждого нового изменения значения поля time будет большим, по сравнению с моментом времени любого предшествующего изменения этого поля. Значение 0.0 поля time приходится на 00: 00: 00 1.01.1970 (время по Гринвичу). Отрицательные значения представляют время предшествующее началу 1-го января 1970 г.

Узел TouchSensor

Особую роль в анимации играют out-поля узлов TouchSensor и TimeSensor. Они, как правило, находятся в вершинах графов-маршрутов УК.

 

Заключение. Предложенные в статье теоретические материалы и примеры кодов можно рассматривать как краткое учебное пособие по основам быстро развивающегося декларативного языка программирования трёхмерных миров. На этих материалах основаны курсы лекций читаемых авторами на электротехническом факультете филиала ЮУрГУ в г. Миассе в некоторых дисциплинах информационного профиля. Примеры кодов используются в курсовом проектировании в разделах моделирования сложных управляемых систем (МСР и ША). Описание использованных здесь X3D-узлов версии 3.2, а также последнюю версию Instant Player можно найти в WWW по адресу https://www.instantreality.org.

<== предыдущая лекция | следующая лекция ==>
ЗАКЛЮЧЕНИЕ. В заключение данной работы следует сделать следующие выводы: | XVIII век в европейской и североамериканской




© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.