Guest3d.wohlnet.ru
некоммерческий проект, цель которого объединить профессионалов для обмена опытом и знаниями в области real-time рендеринга
guest3d
4.05: Экспертный уровень: Lua скриптинг (Lua scripting)

Каналы Quest3D - это строительные блоки, содержащие предварительно скомпилированный код C++ и DirectX. Весь набор каналов предоставляет функциональность для многих аспектов разработки 3D реального времени.

Несмотря на открытую и логичную структуру системы каналов, определенная функциональность может быть управляема более эффективно с помощью скриптового языка. Quest3D поддерживает Lua, бесплатную скриптовую среду от стороннего производителя.

Lua в Quest3D особенно применяем в таких случаях, как загрузка и выгрузка групп каналов, сложных просчетов и повторяющихся структур (циклов ‘for loop’).

Скрипт канала Lua отображается в окне настроек:

Функции Lua (Lua functions)
Каналы Lua могут иметь одну из двух функций, или обе.

Первая, ‘CallChannel’, и запускается она просто когда вызывается канал.

Вторая - ‘GetValue’, и запускается она, когда канал Lua используется, как значение (value). Фактическое значение канала Lua равно значению, которое ‘возвращает’ скрипт в конце функции.

Переменные (Variables)
Так же, как и в других скриптовых языках и языках программирования, переменные, используемые в скрипте Lua должны быть ‘объявлены’. Это утверждение выделяет память для переменной. Слово локальная (‘local’) означает, что переменная используется только в одном конкретном месте, в данном случае, в канале Lua. Как только скрипт будет выполнен, память будет очищена снова.

local variable

Вы также можете присвоить значение переменной во время ее объявления.

local variable = 1

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

variable = variable + 1

Group functions
Quest3D поддерживает следующие стандартные групповые функции Lua: ‘base’, ‘string’ и ‘math’. Вдобавок, существует группа ‘q’, содержащая особые функции Quest3D.

Два примера функций:

local variable = math.cos(value)

local variable = q.GetTick()

Первый пример просчитывает косинус значения между скобками. Второй получает количество отметок (Tick Count) из Quest3D Lua группы ‘q’.

Потомки (Children)
Любое количество потомков любого типа может быть подключено к каналу Lua.

Доступ к потомкам в скрипте Lua может быть получен с помощью соответствующей функции. Как обычно, сначала они должны быть объявлены. Утверждение ниже получает доступ к первому потомку, присоединенному к каналу Lua (в позиции ‘0’).

local variable = channel.GetChild(0)

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

local variable = channel.GetChild(0)
variable:CallChannel()

Обратите внимание на разницу в использовании встроенных и локальных структур. Для встроенных структур, таких, как ‘channel’, функция предваряется ‘.’ (точкой). Для локальных структур, таких, как переменные, функция предваряется ‘:’ (двоеточием).

Фактическое значение канала Value, подключенного к каналу Lua может быть получено с помощью следующих команд.

local variable = channel.GetChild(0)
local value = variable:GetValue()

Текст также может быть извлечен с помощью утверждения ниже.

local variable = channel.GetChild(0)
local text = variable:GetText()

Значение или текст потомка может быть задан с помощью следующих команд:

variable:SetValue(value)
variable:SetText(text)

Цикл For Loop
Повторяющиеся структуры, подобные ‘For Loop’ в Quest3D, могут быть написаны с помощью следующего утверждения:

while i < max do i = i + 1 end

Загрузка групп (Group loading)
Особенно полезны функции по загрузке и выгрузке групп каналов. Утверждения следующие:

q.LoadChannelGroup("group.cgr", "PoolName", instance) q.RemoveChannelGroup("PoolName", instance)

Эти команды делают управление группами в Quest3D очень простым.

Больше информации по Lua в целом может быть
найдено на официальном вебсайте:
http://www.lua.org

Урок
Lua существенно расширяет ‘комплектную’ функциональность набора каналов Quest3D. Следующее упражнение нацелено на ознакомление вас с внутренней работой канала Lua и его двух главных функций : ‘CallChannel’ и ‘GetValue’.

Второй урок детализирует более продвинутое использование Lua в Quest3D: динамическую загрузку.

Необходимые шаблоны:
Logic \ Empty Lua Script (x2)
Logic \ Channel Caller.
Variables \ Value \ Value (x2)
Logic \ User Input \ User Input

Шаг за шагом:

  • Начните новый проект Quest3D, выбрав ‘New Project’ из меню File.
  • Перетяните канал Lua в Граф Каналов. Обратите внимание, что он автоматически установлен стартовым каналом (Start Channel). Дважды щелкните по нему для открытия его окна настроек. Обратите внимание, что окно уже содержит скрипт для двух функций.
  • В функции ‘GetValue’, объявите новую переменную, введя следующий код:
local currentvalue = 1
  • Установите значение канала Lua на значение переменной, заменив следующую строку:
return -1
на
return currentvalue
  • Нажмите кнопку ‘CallValue’ для запуска функции ‘GetValue’. Обратите внимание, что фактическое значение канала Lua сменилось на ‘1’.

  • Добавьте канал Channel Caller и переименуйте его в ‘Project Start’. Задайте его как стартовый канал (Start Channel).
  • Добавьте канал Value и подключите его к каналу ‘Project Start’.
  • Подключите канал Lua к Value. Теперь канал Lua вызывается каждый кадр, как значение. Другими словами, функция ‘GetValue’ скрипта Lua теперь запускается каждый кадр. Или: значение переменной ‘currentvalue’ (текущее значение) просчитывается и ‘возвращается’ каждый кадр.
  • Смените скрипт на следующее:
function GetValue()
local currentvalue = 1
currentvalue = currentvalue + 1
return currentvalue
end

Нажмите ‘OK’ для подтверждения. Обратите внимание, что значение канала Lua сейчас ‘2’.

  • Перетяните другой канал Value в Граф Каналов и подключите его к каналу Lua. Смените его значение на ‘3’.
  • Получите доступ к потомку, сменив скрипт Lua на следующее:
function GetValue()
local child0 = channel.GetChild(0)
local currentvalue = child0:GetValue()
return currentvalue
end

Нажмите ‘OK’ для подтверждения. Обратите внимание, что значение канала Lua теперь то же, что и значение его потомка: ‘3’.

  • Добавьте другой канал Value и подключите его ко второму потомственному входу канала Lua. Смените его значение на ‘4’.
  • Измените скрипт так, чтобы он возвращал сумму значений его двух потомков. Возможно множество решений. Одно из них приведено ниже:
function GetValue()
local child0 = channel.GetChild(0)
local value0 = child0:GetValue()
local child1 = channel.GetChild(1)
local value1 = child1:GetValue()
local sum = value0 + value1
return sum
end

Нажмите ‘OK’ для подтверждения. Обратите внимание, что значение канала Lua сейчас равно ‘7’, сумме значений двух его потомков.

Также обратите внимание, что для простых вычислений, проще использовать канал Expression Value.

  • Перетяните другой канал Lua в Граф Каналов и подключите его к каналу ‘Project Start’.
  • Добавьте канал User Input и подключите его к каналу Lua.
  • Перетяните Channel Caller в Граф Каналов и подключите его ко второму потомственному входу канала Lua.
  • Добавьте другой Channel Caller и подключите его к первому Channel Caller.
  • Смените скрипт для функции ‘CallChannel’ так, чтобы она вызывала второго потомка только когда значение первого равняется ‘1’. Это должно выглядеть подобно коду, приведенному ниже.
function CallChannel()
local child0 = channel.GetChild(0)
local userinput = child0:GetValue()
local child1 = channel.GetChild(1)
if userinput == 1 then
child1:CallChannel()
end
end

Нажмите ‘OK’ для подтверждения. Обратите внимание, что Channel Caller активен. Это благодаря утверждению ‘GetChild’ в скрипте.

  • Переключитесь в Run Mode.
  • Протестируйте скрипт с помощью зажатия пробела. Обратите внимание, что пока пробел нажат, второй Channel Caller также вызывается. Отпустите пробел. Обратите внимание, что Channel Caller больше не вызывается.

Также заметьте, что для простого вызова каналов по условию в Quest3D легче использовать канал If.

Законченная сцена:
..\Tutorials\4.5 – Lua Scripting\Lua scripting 1 – Complete.cgr
Если вы хотите, вы можете сохранить текущую группу каналов в вашу папку проектов. Следующие шаги будут связаны с новой сценой.

Урок2
Необходимая сцена Quest3D:
..\Tutorials\4.5 – Lua Scripting\Lua scripting 2.cgr

Шаг за шагом:

  • Откройте файл ‘Lua Scripting 2.cgr’. Он содержит простую логическую структуру. Обратите внимание на синий публичный канал вызова Public Call Channel. Он отображает ошибку, ‘Not Found’ (не найдено). Это правильно.
  • Дважды щелкните по каналу ‘Lua: Load Group’ для открытия его настроек. Введите следующи код:
function CallChannel()
q.LoadChannelGroup (“Environment.cgr”, “Environment”, 0)
end

Этот скрипт загружает группу каналов ‘Environment.cgr’ в пул, ‘Environment’. Ноль отображает количество дублей. Нажмите ‘OK’ для подтверждения.

  • Переключитесь в Run Mode.
  • Нажмите пробел для загрузки определенной группы. Обратите внимание, что окружение отобразилось в обзорном виде Animation 3D View.
  • Переключитесь в Edit Mode.
  • Добавьте линию для загрузки группы ‘Character.cgr’ в пул ‘Character’.
function CallChannel()
q.LoadChannelGroup (“Environment.cgr”, “Environment”, 0)
q.LoadChannelGroup (“Character.cgr”, “Character”, 0)
end
  • Переключитесь в Run Mode.
  • Нажмите пробел для загрузки обеих указанных групп. Обратите внимание, что персонаж пока не отображается в обзорном виде Animation 3D View. Это потому, что он пока не был вызван.
  • Переключитесь в Edit Mode.
  • Нажмите на закладку ‘Groups’.
  • Перетяните пул ‘Character’ в нижний Граф Каналов.
  • Перетяните соединение от канала ‘Character’ в нижнем Графе Каналов до канала ‘Render’ в верхнем Графе Каналов. Обратите внимание, что канал ‘Character’ стал красным, а в верхнем Графе Каналов был создан синий канал.
  • Нажмите закладку ‘Animation 3D View’. Обратите внимание, что персонаж отображается в окне.
  • Дважды щелкните по синему каналу ‘Character: Character -> Character’ для открытия окна его настроек. Выберите опцию ‘Disable Autoload’ (отключить автозагрузку) и нажмите ‘OK’ для подтверждения.
  • Откройте канал ‘Lua: Unload Group’ и введите следующий код:
function CallChannel()
q.RemoveChannelGroup (“Character”, 0)
end

Этот скрипт выгружает пул “Character”. Ноль означает количество дублей. Нажмите ‘OK’ для подтверждения.

  • Переключитесь в Run Mode.
  • Нажмите клавишу бэкспейс (backspace) для выгрузки заданной группы. Обратите внимание, что персонаж исчез из окна Animation 3D View. Также обратите внимание, что синий канал ‘Character’ сообщил об ошибке ‘Not Found’ (не найден).
  • Снова нажмите пробел для загрузки заданных групп. Обратите внимание, что персонаж вновь появился и синий канал ‘Character’ снова верный.

Законченная сцена:
..\Tutorials\4.5 – Lua Scripting\Lua scripting 2 – Complete.cgr

Если у вас есть материалы, или вы хотите дополнить существующие, если вы хотите писать новости относящиеся к технологиям реалтайм рендеринга, или имеете полезные файлы, вы можете стать резидентом guest3d.wohlnet.ru. Для этого нужно написать письмо в свободной форме на den@wohlnet.ru, с указанием вашей мотивации. Кроме того, каждый резидент получает возможность создать свою страницу, ссылка на которую будет прикреплена к каждому опубликованному вами материалу.
вход