unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, GLCollision, GLNavigator, GLCadencer, GLWin32Viewer,
  GLMisc, GLScene,inifiles, GLTexture, GlObjects, GLGeomObjects,
  GLVectorFileObjects,jpeg,GLFile3ds,GLFileMD2,Keyboard,GLSkydome,Geometry,
  ComCtrls;

type
  TForm1 = class(TForm)
    GLScene1: TGLScene;
    GLSceneViewer1: TGLSceneViewer;
    GLCadencer1: TGLCadencer;
    GLNavigator1: TGLNavigator;
    GlCollision: TCollisionManager;
    MainMenu1: TMainMenu;
    OpenDialog1: TOpenDialog;
    Abrir1: TMenuItem;
    GLMaterialLibrary1: TGLMaterialLibrary;
    StatusBar1: TStatusBar;
    procedure Abrir1Click(Sender: TObject);
    procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
      newTime: Double);
    procedure FormCreate(Sender: TObject);
    procedure GlCollisionCollision(Sender: TObject; object1,
      object2: TGLBaseSceneObject);
    procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure GLSceneViewer1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure GLSceneViewer1AfterRender(Sender: TObject);
  private
    { Private declarations }
    cargadoEscena:boolean;
    HayColision:boolean;
    mdx, mdy : Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Abrir1Click(Sender: TObject);
var
  ScnFile : TIniFile;
  FileGLS, FileGLM,FileActor,MallaFile,MallaName:string;
  NumMallas,i: integer;
  auxCol : TGLBCollision;
begin
 if OpenDialog1.Execute then
 begin //Abrimos el fichero
   ScnFile := TIniFile.Create(OpenDialog1.FileName);
   FileGLS := ScnFile.ReadString('General','File','');
   FileGLM := ScnFile.ReadString('General','Materials','');
   FileActor := ScnFile.ReadString('General','Actor_File','');
   NumMallas := ScnFile.ReadInteger('General','Number_of_Mallas',0);

   //Carga la escena y los materiales
   statusbar1.SimpleText := 'Cargando materiales...';
   application.ProcessMessages;
   GLMaterialLibrary1.LoadFromFile(FileGLM);
   application.ProcessMessages;
   
   for i := 0 to glmateriallibrary1.Materials.Count-1 do
      glmateriallibrary1.Materials.Items[i].Material.Texture.TextureMode := tmModulate;

   statusbar1.SimpleText := 'Cargando escena...';

   application.ProcessMessages;
   GlScene1.LoadFromFile(FileGLS);
   application.ProcessMessages;

   //Configuramos los objetos y asignamos la camara
   GLCadencer1.Scene := GLScene1;
   GLSceneViewer1.Camera := TGLCamera(GLScene1.Objects.FindChild('CamActor',false));

   //Carga las mallas
   for i := 0 to  NumMallas-1 do
   begin
       MallaFile := ScnFile.ReadString('Malla'+IntToStr(i),'File','');
       statusbar1.SimpleText := 'Cargando '+ MallaFile+' ...';
       MallaName := ScnFile.ReadString('Malla'+IntToStr(i),'Name','');

       application.ProcessMessages;
       TGLFreeForm(GLScene1.Objects.FindChild(MallaName,false)).LoadFromFile(MallaFile);
       application.ProcessMessages;
       
       //Colisiones
       auxCol := TGLBCollision.Create(nil);
       auxCol.BoundingMode := cbmCube;//cbmCube cbmSphere;
       auxcol.GroupIndex := 1;
       auxCol.Manager := GlCollision;
       TGLFreeForm(GLScene1.Objects.FindChild(MallaName,false)).Behaviours.Add(auxCol);
       TGLFreeForm(GLScene1.Objects.FindChild(MallaName,false)).BuildOctree;
       application.ProcessMessages;
   end;

   //Carga del personaje
   if FileActor <> '' then
   begin
      TGLActor(GLScene1.Objects.FindChild('personaje',false)).LoadFromFile(FileActor);

      //Colisiones
      auxCol := TGLBCollision.Create(nil);
      auxCol.BoundingMode := cbmSphere;
      auxcol.GroupIndex := 0;
      auxCol.Manager := GlCollision;
      TGLActor(GLScene1.Objects.FindChild('col_personaje',false)).Behaviours.Add(auxCol);

      TGLActor(GLScene1.Objects.FindChild('personaje',false)).Animations.LoadFromFile('Quake2Animations.aaf');
      TGLActor(GLScene1.Objects.FindChild('personaje',false)).AnimationMode:=aamLoop;
      TGLActor(GLScene1.Objects.FindChild('personaje',false)).SwitchToAnimation('stand');
      TGLActor(GLScene1.Objects.FindChild('personaje',false)).FrameInterpolation:=afpLinear;
   end;
   application.ProcessMessages;
   GLNavigator1.MovingObject := GLScene1.Objects.FindChild('Actor',false);

   cargadoescena := true;
   statusbar1.SimpleText := 'Cargando...';
   application.ProcessMessages;
   GLSceneViewer1.Visible :=true;
   
   application.ProcessMessages;
 end;
end;

procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
var
   cWalkStep,cStrafeStep,cRotAngle:integer;
   moving,mov_ant:string;
   startPosition,newPosition:TVector;
begin
    if cargadoEscena then
       mov_ant :=TGLActor(GLScene1.Objects.FindChild('personaje',false)).CurrentAnimation;
    if (IsKeyDown(VK_SHIFT)) then
    begin
       cStrafeStep := 5;
       cWalkStep := 5;
       cRotAngle := 95;
    end else
    begin
       cStrafeStep := 3;
      cWalkStep := 2;
       cRotAngle := 70;
    end;
    moving := 'stand';

    if IsKeyDown(VK_RIGHT) then
    begin
      moving := 'run';
      if IsKeyDown(VK_CONTROL) then
          GLNavigator1.StrafeHorizontal(-cStrafeStep*deltaTime)
      else
          GLNavigator1.TurnHorizontal(-cRotAngle*deltaTime);
    end;
   if IsKeyDown(VK_LEFT) then begin
      moving := 'run';  
      if IsKeyDown(VK_CONTROL) then
          GLNavigator1.StrafeHorizontal(cStrafeStep*deltaTime)
      else
          GLNavigator1.TurnHorizontal(cRotAngle*deltaTime);
   end;

   if IsKeyDown(VK_UP) then
   begin
       GLNavigator1.MoveForward(cWalkStep*deltaTime);
       glcollision.CheckCollisions;
       moving := 'run';
       if (HayColision) then
       begin
          moving := mov_ant;
          GLNavigator1.MoveForward(-cWalkStep*deltaTime);
       end;
   end;
   if IsKeyDown(VK_DOWN) then
   begin
       GLNavigator1.MoveForward(-cWalkStep*deltaTime);
       glcollision.CheckCollisions;
       moving := 'run';
       if (HayColision) then
       begin
          moving := mov_ant;
          GLNavigator1.MoveForward(cWalkStep*deltaTime);
       end;
   end;

   if cargadoEscena then
   begin
     if TGLActor(GLScene1.Objects.FindChild('personaje',false)).CurrentAnimation<>moving then begin
        TGLActor(GLScene1.Objects.FindChild('personaje',false)).SwitchToAnimation(moving);
     end;
   end;
   HayColision := false;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    cargadoescena := false;
    HayColision := false;
end;

procedure TForm1.GlCollisionCollision(Sender: TObject; object1,
  object2: TGLBaseSceneObject);

begin
  HayColision := true;
end;

procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);

begin
   if Shift<>[] then
     GLSceneViewer1.Camera.MoveAroundTarget(mdy-y, mdx-x);
   mdx:=x; mdy:=y;
end;

procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
	mdx:=x; mdy:=y;
end;

procedure TForm1.GLSceneViewer1AfterRender(Sender: TObject);
begin
  statusbar1.SimpleText := '';
end;

end.
