Бета версия
Для разработчиков.
Загрузить : plugins.rar. Этот файл надо распаковать в папку программы. В нём находится папка plugins, в которой есть другие две папки с двумя плагинами, по принципу один плагин - одна папка. Исходники находятся в папках source.
Плагины могут получить от программы большинство из имеющихся в ней данных.
Плагины можно использовать ( на данный момент ) для экспорта данных в свой формат или в какой-нибудь известный. Для рендеринга имеющихся в программе данных. Для тестирования чего-либо на-лету, без сохранения на диск.
В файле находятся два плагина с исходниками на языке Паскаль ( Дельфи ) и одна простенькая программка для облегчения написания плагинов без ЛОДки.
Плагины - это обычные dll-файлы с двумя экспортируемыми функциями GetInfo1 и RunPlugin1.
После того, как поток передан ЛОДкой плагину, данные из него распаковываются и помещаются в структуру TPlugDataA, описанную в файле uLodka3dPluginFunctions.pas.
Выбрана именно структура, а не класс, объект, или что нибудь ещё потому, что она наиболее проста для понимания как это всё работает. Вот она, с комментариями :
TPlugDataA = record StreamPluginType : Integer; // Описывает какие данные переданы плагину. FileName : string; // Имя файла с которым работает программа. // Meshes MeshB1 : TMeshBs; // Структура с мешами. См. ниже. MeshCur, FaceGrCur : Integer; // Выбранные меш и Группа. PrimitiveMatrix : TMatrix; // Матрица примитива. Куда его вставляют. isPrimSelectPoints, // Нужно ли выделять точки и треугольники isPrimSelTriangles : Boolean; // после добавления в программу примитива. // Materials MatDatas : TMatDatas; // Структура с материалами. См. ниже. TxRectPos : TVector; // Позиция рамки в редакторе текстуры. SelMaterial : Integer; // Выбранный материал. // Ligth schemes FileLightOptAss, // Структуры со схемами освещения LODkaLightOptAss : TLightOptAss; // Файловыми и программными. FileLightOptCur, // Выбранные схемы освещения. LODkaLightOptCur : Integer; isLightOptFileUse : Boolean; // Используется ли файловая схема. // File Text Info FileTextInfo : string; // Текстовая информация текущего файла. // Camera CamOptions : TPluginCamOptions; // Параметры камер программы. // Skeleton SkelBones : TSkelBones; // Структура с костями модели. SkelAnims : TSkelAnims; // Структура с анимациями модели. SkelBoneSelInd, // Выбранные кость и анимация SkelAnimSelInd : Integer; SkelFrameSelInds : TIntegers; // Выбранные фреймы анимации. isSkelEnabled, // Включён ли скелет. isSkelBoneEditorEnabled : Boolean; // Включён ли редактор костей. end;
TMeshBs - массив структур в которых описаны все меши со всеми их фейс-группами.
// All meshes. TMeshBs = array of TMeshB; // Массив мешей. // Mesh. TMeshB = record Name : string; // Имя меша. Points : array of TPointsB; // Массив с точками Points вершинами. Normals : array of TAffineVector; // Массив нормалей. Textr1 : array [0..1] of TTexturPoints; // Массив текстурных координат. FaceG : TFaceGrBs; // Массив Фэйс-групп. См. ниже. Visible : Boolean; // Виден ли этот меш. end;
В программе списка нормалей Normals нету. Потому, что они высчитываются на лету по группам сглаживания Smooth-groups. А массив Normals - это и есть массив с высчитанными уже нормалями. В принципе он аналогичен массиву Points.
Массив Textr1 имеет размерность [0..1]. Это потому, что текстур две. Первый - это текстурные координаты первой текстуры, а второй - второй.
TFaceGrBs - массив структур в которых описаны все фэйс-группы со всеми их треугольниками.
// Array of Face groops. TFaceGrBs = array of TFaceGrB; // Массив с фэйс-группами // One FaceGroup. TFaceGrB = record // Одна фэйс-группа. FgTrig : array of TFgTrig; // Массив треугольников. Name : string; // Имя фэйс-группы. MaterialName : string; // Имя первого материала. MaterialName2 : string; // Имя второго материала. Visible : Boolean; // Видна ли эта фэйс-группа. NormalsIndexes : array of Integer; // Индексы нормалей треугольников. end;
Массив NormalsIndexes по размерности должен быть втрое больше чем массив FgTrig. Так как в каждом треугольнике по три вершины.
TMatDatas - содержит информацию обо всех материалах программы.
// All materials. TMatDatas = array of TMatData; // Массив материалов программы. TPlugMatDatas = TMatDatas; // One material. TMatData = record // Один материал программы. MaterialName, // Имя материала, имя его файла и FileName, SecondTexture : string; // имя второй текстуры. MatParam1 : TMatParamA; // Структура с параметрами материала. Bitmap : TBitmap; // Картинка текстуры. end;
Все текстуры передаются в плагины строго в формате bmp. То есть это картинка формата bmp сохранённая ЛОДкой в поток, а потом, в плагине она грузится из потока в Bitmap, и помещается в эту структуру.
Все остальные структуры думаю более менее понятны из файла uLodka3dPluginFunctions.pas и не нуждаются в особых пояснениях.
Плагин DemoShowInfoSimple - это самый простой вариант плагина. В нём нет формы, он только получает данные от ЛОДки и выводит информацю о том, сколько в неё сейчас мешей, материалов, анимаций и т. д.
Рассмотрим файл DemoShowInfoSimple.dpr.
Функция GetInfo1 ( передаёт в ЛОДку информацию о плагине ):
// Plugin information. function GetInfo1: TLODka3DPluginRegistration; stdcall; begin Result.InterfaceType := 1; // Must be 1. Result.DataToPluginType := iedMeshes or iedMaterials or iedSkeleton or iedCamera or iedFileLightSchemes or iedFileTextInfo; Result.DataFromPluginType := 0; Result.Data1[0] := 0; // Must be 0. Result.Data1[1] := 0; // Must be 0. Result.Data1[2] := 0; // Must be 0. Result.Data1[3] := 0; // Must be 0. Result.DLLType := dlltExport; Result.DLLVersion := 1; Result.Name := 'Demo Information plugin'; Result.CopyrightInfo := 'c LODka3D 2006'; Result.FileExtension := '.lod'; end;
Основные данные здесь - это DataToPluginType, в котором мы указываем какие данные от ЛОДки нам нужны. В данном случае мы затребываем их все. И Name. Имя плагина которое будет выводиться в меню.
Функция RunPlugin1 ( вызывается ЛОДкой при запуске пользователем плагина ) :
// Run plugin. procedure RunPlugin1(aStream : IStream); stdcall; begin // Load data from aStream to PlugA.Data. if PlugA.LoadData(aStream) then begin // Загружаем данные из потока в PlugA.Data // Do something with PlugA.Data. MainPluginFunction; // Вызываем основную функцию программы. end; // Free bitmaps. PlugA.FreeBitmaps; // Освобождаем картинки, чтобы небыло утечек памяти. end;
Когда пользователь кликнул мышкой на пункт меню вызова этого плагина, то ЛОДка упаковывает в поток IStream свои данные и вызывает эту функцию. В функции данные из потока распаковываются в структуру PlugA.Data, вызывается основная функция плагина MainPluginFunction, после чего освобождаются картинки и работа плагина завершается.
Функция MainPluginFunction - основная функция плагина :
// Main plugin function. Work with PlugA here. procedure MainPluginFunction; begin with PlugA.Data do ShowMessage( ' Model information:' +#13#10+#13#10 +'FileName: ' +FileName +#13#10 +'Mesh count: ' +IntToStr(Length(MeshB1)) +#13#10 +'Material count: ' +IntToStr(Length(MatDatas)) +#13#10 +'Bone count: ' +IntToStr(Length(SkelBones)) +#13#10 +'Animation count: ' +IntToStr(Length(SkelAnims)) +#13#10 ); end;
Здесь мы всего лишь выводим окошко функцией ShowMessage, с информацией о данных переданных ЛОДкой и помещённых в PlugA.Data
Вместо окошка, здесь, само собой может быть написано, например, сохранение данных в какой либо формат, или что-нибудь подобное.
Плагин DemoShowInfoWithForm отличается от предыдущего тем, что выводит форму, в которой показывается более подробная информация о данных полученных от ЛОДки, демонстрируются её текстуры, и появляется возможность сохранить поток данных от лодки в файл, для дальнейшего их использования уже без ЛОДки.
Функция MainPluginFunction была изменена :
// Main plugin function. Work with PlugA here. procedure MainPluginFunction; var MainForm : TMainForm; begin MainForm := TMainForm.Create(Application); // Создаём форму MainForm. try MainForm.PlugA := @PlugA; // Передаём форме указатель на PlugA. MainForm.Stream1 := PlugA.Stream; // Передаём форме указатель на поток. MainForm.ParsePlugDate; // Парсим переданные данные. MainForm.ShowModal; // Показываем форму и ждём её закрытия. finally MainForm.Free; // Удаляем форму. end; end;
Парсить данные формы можно и из самой формы. Это не принципиально. Что из себя представляет форма - тоже не принципиально. Можно её изменить или написать свою. В данном случае она полезна тем, что позволяет сохранить поток полученный от ЛОДки в файл.
Это небольшая программка позволяющая загружать потоки сохранённые в предыдущем плагине ( парочка прилагается ), и отображать форму из предыдущего плагина с этими данными.
Таким образом, не надо каждый раз грузить ЛОДку, а можно разрабатывать и тестировать форму загружая в неё данные из сохранённых потоков, а потом, когда всё будет нормально работать, просто перенести эту форму в dll-плагин, и скомпелировать его.
Вопросы, пожелания, обратная свзяьЕсли вы сделали свой плагин не на GLScene - обязательно напишите мне об этом, чтобы я учитывал это при дальнейшей разработке плагинового интерфейса.