Бета версия
Для разработчиков.
Загрузить : 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 - обязательно напишите мне об этом, чтобы я учитывал это при дальнейшей разработке плагинового интерфейса.