Paranoid

Перевод LightWave SDK Documentation

Introduction (Введение)

Преамбула

Когда-то давным давно, начал я перевод документации к LightWave SDK. Пару кусочков этого перевода даже "опубликовал" в скайп-чатике лайтвэйвовском, но после этого забросил. И вот сейчас я вновь вернулся к этому занятию. Однако программист из меня "не очень" (в далеком детстве писал на бэйсике а потом на ассемблере для 8-ми битного процессора 6502), то как следствие, в переводе могут присутствовать "ляпы", связанные с недостатком у меня опыта программирования на Си. Поэтому у меня есть просьба к камрадам, хорошо ориентирующимся в парадигме языка Си: пишите в комментариях свои замечания по этому переводу, а я в свою очередь буду вносить в перевод исправления. Кроме того интересует - есть ли вообще у нашего комьюнити заинтересованность в данном материале на русском языке? В принципе я начал этот перевод "для себя", так как иногда возникает потребность в каком-либо простом инструменте, отсутствующем в LightWave. Однако в процессе перевода я подумал, что возможна эта инфа может оказаться полезной еще кому-нибудь. Поэтому принял решение опубликовать её, а не держать в личном сундуке. В общем приветствуются любые комментарии - от смысловых исправлений до рекомендаций "переводить/не переводить" термины, используемые в документации (например "обратный вызов" или callback).

PS: Насколько хватит моего "запала" с этим переводом я конечно предсказать не могу, но если кто-либо еще возьмет на себя труд помочь в этом деле, то буду этому весьма рад. Кроме того, в последствии этот перевод может перекочевать на другой, родственный ресурс, где его дальнейшее развитие будет происходить в более удобной, с технической точки зрения, форме. Но это не ближайшая перспектива и её реализация зависит от создателя данного сайта.


Ссылка на англоязычную версию: http://static.lightwave3d.com/sdk/2015/html/intro.html


ВВЕДЕНИЕ

Это документация для LightWave® 3D SDK. Информация приведенная здесь актуальна для версий LightWave®, начиная с 6-ой. Несмотря на то, что приведенная здесь информация относится конкретно к LightWave®, другие продукты компании Newtek тоже могут поддерживать LightWave® плагины. Документация для более ранних версий (до 6-ой) и вопросы совместимости между разными версиями LightWave® и продуктами Newtek обсуждаются на странице compatibility (ссылка).

В этом введении я буду излагать материал от первого лица, чтобы Вы почувствовали, что на самом деле документация написана человеком. Но чтобы оставаться честным, я должен предупредить Вас о том, что этот материал всё же является техническим описанием с изрядным количеством "сухого текста". Это предъявляет особые требования к читателю и предполагает, в том числе, достаточно свободный уровень владения LightWave®, языком Си и наличие опыта программирования 3D графики. В связи с этим, после первого прочтения, многое может оказаться не понятным для Вас.

Это нормально и естественно. Не расстраивайтесь из-за этого. Информация, излагаемая в этой документации, трудна для восприятия по своей природе. Из-за этого её восприятие является нелёгким делом не только для Вас но и для любого другого человека.

Принимая во внимание вышесказанное, я буду стараться выражаться как можно более ясно, чётко и точно. Я также опираюсь на знания и опыт других людей, чьи знания материала проистекают непосредственно из процесса создания API для плагинов со стороны самого приложения (LightWave®). Некоторые из этих людей приложили усилия, чтобы разъяснить сложные участки материала и мне самому. Я уже исправил ряд ошибок, указанных читателями, в предыдущих версиях документации, но к сожалению ошибки неизбежны, и скорее всего Вы обнаружите хотя бы одну.

В следующих разделах я привожу список литературы, содержащей необходимые базовые знания которые Вам потребуются. Также там описываются некоторые концепции программирования с которыми Вы можете быть еще не знакомы и проводится краткий обзор принципов работы плагинов. Это принципы, которые будут подразумеваться в важных частях этой документации. Для тех, кто уже имел опыт разработки плагинов для более ранних версий LightWave® (до 6-ой), я остановлюсь на некоторых из основных изменений, появившихся в версии 6.0

Ernie Wright, December 2001


ДЛЯ КОГО И ДЛЯ ЧЕГО ЭТА ДОКУМЕНТАЦИЯ

Этот документ описывает интерфейс взаимодействия с LightWave® посредством использования языка программирования Си. Подразумевается, что Вы владеете этим языком, поэтому мы не будем изучать здесь язык Си. В частности мы не будем обсуждать абстрактные концепции создания динамических библиотек или вопросы написания thread-safe кода. Эта документация также не научит Вас программированию 3D графики или, за отсутствием лучшего термина, пользовательской парадигме LightWave®.

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

Моя любимая книга для обучения программированию на языке Си это Al Kelley and Ira Pohl, A Book on C, 4th ed., Addison-Wesley, ISBN 0201183994

Также Вам может пригодиться хорошая книга с описанием алгоритмов. У меня есть такая Robert Sedgewick, Algorithms in C, Addison-Wesley, ISBN 0201514257

3D графика в значительной мере опирается на тригонометрию и линейную алгебру, но в большинстве случаев вам не потребуется углубленное знание этих дисциплин. Вам чаще всего нужно будет знать, что такое синус, косинус и тангенс. А так же Вам нужно понимать арифметические операции над векторами и матрицами. Узнать о этих базовых операциях Вы можете из множества книг, перечисленных ниже. Для более глубокого изучения Вы можете посетить ближайший университетский книжный магазин и взять любой учебник, используемый на вводных курсах.

Любой хороший вводный учебник по программированию графики способен обеспечить достаточную основу для понимания основных понятий в компьютерной графике. Мне нравятся такие учебники:

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

Также рекомендуется к ознакомлению двух томный сборник статей Jim Blinn's в IEEE Computer Graphics and Applications и зачастую новаторские статьи в ежегодном ACM SIGGRAPH Proceedings. В дополнение к этому, Вы также можете иногда находить информацию и статьи, касающиеся программирования для LightWave® в книгах и журналах из розничных магазинов. Некоторые из этих статей написаны членами команды разработчиков LightWave®. Не забывайте и о LightWave® User Manual - это лучший источник информации о том как работает LightWave®. И конечно Вы можете найти дополнительный материал любого уровня сложности в интернете.

В случае если никто еще не смог отговорить Вас от изучения темы программирования плагинов для LightWave®, я опишу одну из основополагающих концепций написания плагинов. Понимание этой концепции может оказаться не очень простым, но тем не менее необходимым. Но если Вы уже знаете что такое "обратные вызовы" (callback), то можете сразу переходить к следующей части.


УКАЗАТЕЛИ НА ФУНКЦИИ (Function pointers)

В плагинах для LightWave® широко используются указатели на функции. Для программистов моего поколения, выросших на BASIC, FORTRAN и Pascal, указатели на функции выглядят несколько экзотично на первый взгляд. В обычной программе, содержащей в себе весь необходимый для работы функционал, есть мало причин для того чтобы использовать их. Однако "указатели на функции" это просто другой тип переменной, и они являются крайне полезными в случае когда двум отдельным модулям (программам) необходимо выполнять код друг друга.

Определение типа для указателя на функцию может выглядить следующим образом:

typedef int ( *FooFunc )( int, double );

Такое определение типа означает, что FooFunc является функцией, возвращающей значение типа int (обратите внимание: не int *) и принимающая значения int и double в качестве аргументов. В соответствии с этим определением Вы теперь можете объявлять переменные типа FooFunc *,

FooFunc *foo;

Вы можете написать FooFunc функцию,

int myfoo( int count, double size );
{
return ( int )( size * count );
}

и присвоить эту функцию вашей FooFunc переменной,

foo = myfoo;

Вы также можете передавать FooFunc-ции как аргумент другим функциям.

int bar( FooFunc *foo );

Вы можете добиться того же эффекта посредством явного прототипа функции foo в заголовке функции bar.

int bar( int ( *foo )( int, double ));

Стандартная динамическая библиотека C содержит как минимум две функции, принимающие указатели на функции в качестве аргументов - bsearch и qsort. Протототипы для обоих из них обычно находятся в stdlib.h. Эти прототипы выглядят так:

void *bsearch( const void *key, const void *a, size_t n, size_t size,
int ( *compar )( const void *, const void * ));
void qsort( void *a, size_t n, size_t size,
int ( *compar )( const void *, const void * ));

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


ОБРАТНЫЕ ВЫЗОВЫ (Callbacks)

Функция сравнения для bsearch и qsort как раз является примером "обратного вызова", т.е. функцией, которую Вы насписали для того, чтобы её вызывал другой модуль. Исполняющая среда Си сможет вызывать Вашу функцию сравнения всякий раз когда ей будет нужно проранжировать два элемента из Вашего массива.

Обратные вызовы часто встречаются в коде пользовательских интерфейсов современных оконных сред, где они используются для сбора "событий" ("events") вызванных действиями пользователя. Встроенный механизм пользовательского интерфейса LightWave® использует обратные вызовы точно таким же образом, но обратные вызовы также используются и в других местах API для плагинов. Плагины класса "Layout handler" содержат обратные вызовы, которые выполняются на определенных этапах процесса рендеринга, а плагины для Modeler'а используют обратные вызовы для нумерации точек и полигонов объекта.

Вы организуете обратные вызовы конечно же используя указатели на функции.


КРАТКИЙ ОБЗОР

Эта глава представляет собой краткий, неформальный обзор системы плагинов и механизма их работы. Здесь я также буду ссылаться на другие области документации, в которых эти механизмы рассматриваются более детально. Также Вы возможно захотите прочесть "Часть I" из Box Tutorial, который вы можете найти в разделе статей (Articles). Материал этого урока охватывает большую часть описываемой здесь темы, но несколько другим путём - проводя Вас шаг за шагом через процесс создания простого плагина.

Если Вы уже имели опыт написания плагинов для LightWave® до версии 6.0 и Вы просто хотите узнать, что изменилось с тех пор, то можете сразу перейти к параграфу "Что нового".

Плагины это динамические библиотеки кода, расширяющие возможности LightWave®. LightWave® продается с множеством плагинов в комплекте, и исходный код для многих из них включен в SDK.

Плагины подразделяются на разные типы, называемые классами (classes). Это не тоже самое что классы в C++, но общая идея совпадает. Разные классы плагинов подключаются к LightWave® в разных местах и служат для разных целей. Существуют классы для:

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

Некоторые плагины также могут выдавать команды (commands). Большинство команд выполняют те же действия, которые пользователь может производить вручную посредством интерфейса LightWave®. В то время как глобальные функции (globals) в первую очередь используются для считывания параметров, команды (commands) используются для установки этих параметров.

Более половины всех плагинов принадлежат к классу "обработчик" (handler). В отличие от плагинов которые запускаются, чтобы произвести какие-либо действия и после этого прекращают свою работу, обработчики (handlers) постоянно готовы выполнять действия. Они обслуживают обратные вызовы (callbacks) производимые LightWave® в те моменты, когда они (обработчики) должны выполнять свои задачи. Большинство обработчиков задействуются в процессе рендера и вызываются в каждом кадре для того, чтобы например перемещать объекты, окрашивать поверхности или добавлять кадры к файлу анимации. Некоторые обработчики реагируют на действия, производимыми пользователем через пользовательский интерфейс для управления объектами интерфейса.

Обработчики могут быть применены или вызваны многократно. Например обработчик движения какого-либо элемента (item motion handler) может управлять движением нескольких разных элементов в сцене. Каждый вызов обработчика вызывает его (обработчика) экземпляр (instance), и для каждого такого экземпляра обработчик создаст некоторые данные, которые будет использовать для отслеживаеия этого экземпляра. Эти данные обработчик обычно использует для хранения пользовательских установок и предпрощитанных параметров, но вообще эти данные могут содержать любую необходимую обработчику информацию.

Обработчики обслуживают обратные вызовы для загрузки и сохранения данных их экземпляров в файлах сцен и объектов. Фактическое считывание и запись данных в этих файлах осуществляется посредством функций файлового ввода-вывода, предоставляемых LightWave®. Глобальные функции (global) позволяют плагинам любого класса использовать те же функции и с другими файлами, что может быть использовано например для платформо-независимого создания и чтения файлов конфигураций ваших плагинов.

Функции файлового ввода-вывода являются одним из нескольких общих механизмов для плагинов разных классов, имеющих похожие потребности. Два других механизма это - система ввода-вывода изображений (image I/O system) используемая при загрузке и сохранении изображений и анимаций, и функции трассировки лучей (raytracing functions) используемые шэйдерами, рендерерами объёмов (volume renderers) и фильтрами.

Каждый плагин имеет функцию активации (activation function). Это входная точка плагина, т.е. функция, которую LightWave® вызывает для того чтобы начать взаимодействие между программой (LightWave®) и Вашим плагином. Для НЕ-обработчиков (non-handlers) это функция в которой производится вся работа плагина. Однако для обработчиков (handlers) это лишь место где плагин сообщает LightWave® как найти обработчиков обратных вызовов плагина. Функция активации (activation function) имеет одинаковый формат для плагинов всех классов с одним лишь отличающимся для разных классов аргументом.

Файл плагина может содержать в себе больше одного плагина. Каждый файл содержит массив "записей сервера" (server records). Каждая из этих записей соответствует одному из плагинов, содержащихся в файле. "запись сервера" для плагина содержит в себе имя и класс плагина, а также адрес его функции активации. Массив "записей сервера" является внешней структурой данных, т.е. блоком данных в файле, который операционная система может обнаружить по его (блока данных) имени. Когда LightWave® впервые загружает какой-либо плагин, он запрашивает у операционной системы адрес массива "записей сервера" (server record array). Получив этот адрес, LightWave® ищет в этом массиве адреса функций активации, содержащихся в данном файле. Зная эти адреса, LightWave® в дальнейшем может запускать эти функции, а в случае с обработчиками (handlers) - получать адреса других функций, содержащихся в файле.

Большинство плагинов имеют пользовательский интерфейс и он обычно реализован как часть функции активации. Классы обработчиков (handlers) имеют ассоциированные классы интерфейса, чьи функции активации соответствуют предназначению этих обработчиков. Вы можете создавать свои интерфейсы используя специфические платформо-зависимые элементы, но SDK предоставляет полную, платформо-независимую систему для построения интерфейсов из элементов имеющих одинаковый на всех платформах и привычный для LightWave® вид. Эта система описана в данной документации на страницах "Panels" и "XPanels".

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


N_A

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