Использование PascalScript совместно с GLScene

(написал Снег Север).

В этой статье объясняется, как использовать PascalScript совместно с GLScene. Это можно делать разными способами. Самый простой, на мой взгляд – это создания своих классов-«оберток» над объектами GLScene. Именно этот способ я использую в следующих примерах.  

Создадим новый проект с необходимыми компонентами (glscript00). Затем добавим в проект новый модуль и создадим в нем свой класс:

unit MyClassUnit;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, GLMisc, GLScene, GLTexture, GLObjects, GLPolyhedron;

  type

      TMySceneClass = class

      protected

          FSceneObj :TGLCustomSceneObject;

          function GetSceneObj :TObject;

      public

          constructor Create(AParentname :string; AType :string);

          property SceneObj :TObject read GetSceneObj;

          procedure SetMaterial(matname :string);

          procedure SetPosition(x, y, z :single);

          procedure SetScale(factor :single);

          procedure Rotate(Axe :byte; Angle :single);

      end;

 

implementation

uses MainUnit;

  constructor TMySceneClass.Create(AParentname :string; AType :string);

  var GraphObj : TGLBaseSceneObject;

  begin

       inherited Create;

       GraphObj := MainForm.GLScene1.FindSceneObject(AParentname);

       if UpperCase(AType)='TGLDUMMYCUBE' then

             begin

                  FSceneObj := TGLDummyCube.CreateAsChild(GraphObj);

                  FSceneObj.Name := 'MyDummyCube1';

             end;

       if UpperCase(AType)='TGLCUBE' then

             begin

                  FSceneObj := TGLCube.CreateAsChild(GraphObj);

                  FSceneObj.Name := 'MyCube1';

             end;

       if UpperCase(AType)='TGLSPHERE' then

             begin

                  FSceneObj := TGLSphere.CreateAsChild(GraphObj);

                  FSceneObj.Name := 'MySphere1';

             end;

       if UpperCase(AType)='TGLICOSAHEDRON' then

             begin

                  FSceneObj := TGLIcosahedron.CreateAsChild(GraphObj);

                  FSceneObj.Name := 'MyLIcosahedron1';

             end;

       FSceneObj.Material.MaterialLibrary := MainForm.GLMaterialLibrary1;

  end;

 

  procedure TMySceneClass.SetMaterial(matname :string);

  begin

       FSceneObj.Material.LibMaterialName := matname;

  end;

 

  procedure TMySceneClass.Rotate(Axe :byte; Angle :single);

  begin

       case Axe of

       1: FSceneObj.Turn(Angle);

       2: FSceneObj.Pitch(Angle);

       3: FSceneObj.Turn(Angle);

       end;

  end;

 

  procedure TMySceneClass.SetPosition(x, y, z :single);

  begin

       FSceneObj.Position.x := x;

       FSceneObj.Position.y := y;

       FSceneObj.Position.z := z;

  end;

 

  procedure TMySceneClass.SetScale(factor :single);

  begin

       FSceneObj.Scale.Scale(factor);

  end;

 

  function TMySceneClass.GetSceneObj :TObject;

  begin

       Result := FSceneObj;

  end;

end.

 

Этот класс позволяет создать объект сцены, как потомка имеющегося объекта (для простоты предусмотрена возможность создавать только объекты типа TGLDummyCube, TGLCube, TGLSphere и TGLIcosahedron), назначить объектам материал из имеющейся библиотеки материалов GLMaterialLibrary1 и делать некоторые манипуляции с объектами – менять их позицию, масштабировать, вращать.

 

Теперь, сделаем модуль импорта для этого класса, как это описано в статье Использование классов с RemObjects PascalScript. Сгенерированный модуль uPSI_MyClassUnit.pas подключим к проекту и к списку плагинов компилятора PascalScript:

procedure TMainForm.FormCreate(Sender: TObject);

var

   Plugin :TPSPlugin;

begin

  ...

     Plugin := TPSImport_MyClassUnit.Create(self);

     TPSPluginItem(ce.Plugins.Add).Plugin := Plugin;

end;

 

Теперь напишем простой скрипт создания нового куба в сцене:

program glscript00;

var

     MySceneClass : TMySceneClass;   

begin

     MySceneClass := TMySceneClass.Create('GLDummyCube1','TGLCUBE');

     MySceneClass.SetPosition(2,0,0);

     MySceneClass.SetScale(2);

     MySceneClass.SetMaterial('cube');

 

end.

Запустим программу и выполним этот скрипт нажатием кнопки Do. На сцене появится цветной куб.

 

Разумеется, скрипты можно использовать не только для создания объектов сцены, но и для управления этими объектами. Немного доработаем проект (glscript01). В событие GLCadencer1Progress добавим код:

procedure TMainForm.GLCadencer1Progress(Sender: TObject; const deltaTime,

  newTime: Double);

begin

     if compiled then

                     ce.ExecuteFunction([1, 90*deltaTime], 'RotateObject');

end;

Функция RotateObject – это скриптовая процедура, которая будет принимать два параметра – номер оси вращения (1..3) и угол поворота. Разумеется, эту процедуру надо написать и включить в скрипт. Новый скрипт будет выглядеть так:

var

     MySceneClass : TMySceneClass;

procedure RotateObject(a:integer; ang :single);

begin

        MySceneClass .Rotate(a, ang);

end;  

begin

     MySceneClass := TMySceneClass.Create('GLDummyCube1','TGLCUBE');

     MySceneClass.SetPosition(2,0,0);

     MySceneClass.SetScale(2);

     MySceneClass.SetMaterial('cube');

end.

Запустим программу и выполним этот скрипт нажатием кнопки Do. На сцене появится цветной куб. Включим вращение нажатием на элемент управления «Cadencer On/Off», рядом с кнопкой. Куб начнет вращаться.

 

Пример выполнения более сложного скрипта - glscript02.

В нем создаются три объекта сцены и вращаются независимо:

program glscript;

var

     MySceneClass1, MySceneClass2, MySceneClass3 : TMySceneClass;

procedure RotateObject(num, a :integer; ang :single);

begin

    case num of

     1: MySceneClass1.Rotate(a, ang);

     2: MySceneClass2.Rotate(a, ang);  

     3: MySceneClass3.Rotate(a, ang);

    end

end;  

begin

     MySceneClass1 := TMySceneClass.Create('GLDummyCube1','TGLCUBE');

     MySceneClass1.SetPosition(1,0,0);

     MySceneClass1.SetScale(2);

     MySceneClass1.SetMaterial('cube');

 

     MySceneClass2 := TMySceneClass.Create('MyCube1','TGLSphere');

     MySceneClass2.SetPosition(0,3,0);

     MySceneClass2.SetScale(2);

     MySceneClass2.SetMaterial('sphere');

   

     MySceneClass3 := TMySceneClass.Create('MySphere1','TGLIcosahedron');

     MySceneClass3.SetPosition(0,0,2);

     MySceneClass3.SetScale(1);

     MySceneClass3.SetMaterial('icos');

end.

 Соответственно, в событии GLCadencer1Progress идут три вызова скриптовой функции:

procedure TMainForm.GLCadencer1Progress(Sender: TObject; const deltaTime,

  newTime: Double);

begin

     if compiled and executed then

     begin

          ce.ExecuteFunction([1, 1, 90*deltaTime], 'RotateObject');

          ce.ExecuteFunction([2, 2, 90*deltaTime], 'RotateObject');

          ce.ExecuteFunction([3, 3, 90*deltaTime], 'RotateObject');

     end;

end;

Вернуться к списку статей Вернуться на главную страницу SourceForge.net Logo