Плагины для программы LODka 3D Разработчикам

Бета версия

Для разработчиков.

Общее описание

Загрузить : plugins.rar. Этот файл надо распаковать в папку программы. В нём находится папка plugins, в которой есть другие две папки с двумя плагинами, по принципу один плагин - одна папка. Исходники находятся в папках source.

Плагины могут получить от программы большинство из имеющихся в ней данных.

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

В файле находятся два плагина с исходниками на языке Паскаль ( Дельфи ) и одна простенькая программка для облегчения написания плагинов без ЛОДки.

Плагины - это обычные dll-файлы с двумя экспортируемыми функциями GetInfo1 и RunPlugin1.

  1. GetInfo1 - информирует ЛОДку как называется плагин, какие ему ЛОДка должна передать данные в момент вызова и некоторую дополнительную информацию.
    Этот вызов происходит в момент запуска ЛОДки и название плагина полученное отсюда заносится в список в меню Plugins.
  2. RunPlugin1 - вызыв плагина ЛОДкой. Происходит когда человек выбрал пункт меню, с именем этого плагина. При этом ему передаётся поток aStream : IStream, в котором находится вся затребованная им в функции GetInfo1 информация.
    Поток IStream для передачи информации выбран потому, что он позволяет передавать данные произвеольной длины в обе стороны. Кроме того он есть в Си++, что даёт возможность писать плагины и на этом языке.

После того, как поток передан ЛОДкой плагину, данные из него распаковываются и помещаются в структуру 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 - это самый простой вариант плагина. В нём нет формы, он только получает данные от ЛОДки и выводит информацю о том, сколько в неё сейчас мешей, материалов, анимаций и т. д.

Рассмотрим файл DemoShowInfoSimple.dpr.

  1. Функция 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. Имя плагина которое будет выводиться в меню.

  2. Функция 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, после чего освобождаются картинки и работа плагина завершается.

  3. Функция 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

Плагин 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;

Парсить данные формы можно и из самой формы. Это не принципиально. Что из себя представляет форма - тоже не принципиально. Можно её изменить или написать свою. В данном случае она полезна тем, что позволяет сохранить поток полученный от ЛОДки в файл.

TestDllForm

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

Таким образом, не надо каждый раз грузить ЛОДку, а можно разрабатывать и тестировать форму загружая в неё данные из сохранённых потоков, а потом, когда всё будет нормально работать, просто перенести эту форму в dll-плагин, и скомпелировать его.

Вопросы, пожелания, обратная свзяь

Если вы сделали свой плагин не на GLScene - обязательно напишите мне об этом, чтобы я учитывал это при дальнейшей разработке плагинового интерфейса.




©  LODka3D  2006 —
Hosted by uCoz