Kamera (2)

Aus DGL Wiki
Version vom 15. Oktober 2005, 15:04 Uhr von Andyh (Diskussion | Beiträge)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

unit Camera;

interface

 Uses DglOpenGL, OpenGLUtil, Windows, Classes;
 type TCameraMatrix=Class
   Matrix: TArrMatrix;
   InverseMatrix: TArrMatrix;
   procedure Identity;
   procedure Load(M: TArrMatrix);
   constructor Create;
 end;
 TCamera=Class
   CameraMatrix: TCameraMatrix;
   Enabled  : boolean;
   Initiated: boolean;
   constructor Create;
   destructor Destroy;
   function Position: TGLvector;
   function UpVector: TGLvector;
   function ViewDirection: TGLvector;
   procedure RestorePosition(pos: integer);
   procedure SavePosition(pos: integer);
   procedure RotateCamera(ix, iy, iz: TGLdouble);
   procedure TranslateCamera(ix, iy, iz: TGLdouble);
   procedure CameraHome;
   procedure PositionCamera(PositionVec: TGLvector;

ViewVec: TGLvector; upVec: TGLvector);

   procedure Adjust;
   procedure Apply;
 private
   HomeMatrix: TCameraMatrix;
   PosArray: array [0..9] of TCameraMatrix;
   FPointOfRotation: TGLvector;
   procedure Identity;
   procedure RotateMatrix(ix, iy, iz: TGLdouble);
   procedure Offset(x, y, z: TGLfloat);
   procedure RotateRoundAxis(rx, ry, rz: TGLfloat);
 published
   property PointOfRotation: TGLvector read FPointOfRotation;
 end;
 TPCamera=^TCamera;

implementation

constructor TCameraMatrix.Create; // beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen begin

 Identity;

end;

procedure TCameraMatrix.Identity; // die Funktion GetArrIdentity findet Ihr in der Datei OpenGL.pas var

 i: integer;

begin

 Matrix := GetArrIdentity;
 InverseMatrix := GetArrIdentity;

end;

procedure TCameraMatrix.Load(M: TArrMatrix); // die Matrix mit den Werten einer beliebigen anderen matrix füllen var

 i: integer;

begin

 for i:=0 to 15 do
   Matrix[i]:=M[i];
 InvertMatrix (M, InverseMatrix);

end;


procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat); // hier drehen wir jetzt um die einzelnen Achsen. // die Parameter geben die "Drehgeschwindigkeit" vor. var

 newMatrix: TArrMatrix;

begin

 glMatrixMode (GL_MODELVIEW);
 glPushMatrix();
 // aktuelle Position und Lage der Kamera herstellen
 glLoadMatrixf(@CameraMatrix.Matrix);
 // wenn gewünscht um die X-Achse drehen
 if(rx <> 0) then
   glRotatef(rx,1,0,0);
 // wenn gewünscht um die Y-Achse drehen
 if(ry <> 0) then
   glRotatef(ry,0,1,0);
 // wenn gewünscht um die Z-Achse drehen
 if(rz <> 0) then
   glRotatef(rz,0,0,1);
 // die neu erzeugte Matrix auslesen
 glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
 // und in die Kameramatrix sichern
 CameraMatrix.Load(newMatrix);
 glPopMatrix();

end;

constructor TCamera.Create; var

 i: integer;

begin

 // Initiated wird gebraucht um einmal alle Positionsspeicher 
 // mit der Anfangsposition zu belegen
 Initiated := false;
 // Kameramatrix anlegen
 CameraMatrix := TCameraMatrix.Create;
 // Matrix der letzten Position von PositionCamera anlegen
 HomeMatrix := TCameraMatrix.Create;
 // Positionsspeicher anlegen
 for i := 0 to 9 do
   PosArray[i] := TCameraMatrix.Create;

end;

procedure TCamera.Identity; begin

 CameraMatrix.Identity;
 HomeMatrix.Identity;
 Enabled := true;

end;

destructor TCamera.Destroy; var

 i: integer;

begin

 HomeMatrix.Free;
 CameraMatrix.Free;
 for i := 0 to 9 do
   PosArray[i].Free;

end;

procedure TCamera.Offset(x, y, z: TGLfloat); var

 newMatrix: TArrMatrix;

begin

 glMatrixMode (GL_MODELVIEW);
 glPushMatrix();
 glLoadIdentity;
 glTranslatef(x,y,z);
 glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
 // wenn ich mit der funktion glMultMatrixf arbeite, wird die zeichnung
 // immer entlang der richtigen achsen verschoben. wenn ich matrixmultiply
 // nehme, wird sie auf den bildschirmachsen verschoben. das ist angenehmer
 // zum arbeiten
 MatrixMultiply (newMatrix, CameraMatrix.Matrix, newMatrix);
 CameraMatrix.Load(newMatrix);
 glPopMatrix();

end;


procedure TCamera.PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector); var

 newMatrix: TArrMatrix;
 i: integer;

begin

 Identity;
 FPointOfRotation := ViewVec;
 glMatrixMode (GL_MODELVIEW);
 glPushMatrix;
 glLoadIdentity;
 glTranslatef (PositionVec.X, PositionVec.Y, PositionVec.Z);
 gluLookAt (PositionVec.X, PositionVec.Y, PositionVec.Z,
            ViewVec.X, ViewVec.Y, ViewVec.Z,
            upVec.X, upVec.Y, upVec.Z);
 glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
 CameraMatrix.Load(newMatrix);
 HomeMatrix.Load(newMatrix);
 glPopMatrix;
 if not Initiated then
 begin
   for i := 0 to 9 do
     SavePosition (i);
   Initiated := true;
 end;

end;

// Move the camera to the home position procedure TCamera.CameraHome; begin

 CameraMatrix.Load(HomeMatrix.Matrix);

end;

procedure TCamera.SavePosition (pos: integer); begin

 if (pos < 0) or (pos > 9) then
   exit;
 PosArray[pos].Load(CameraMatrix.Matrix);

end;

procedure TCamera.RestorePosition (pos: integer); begin

 if (pos < 0) or (pos > 9) then
   exit;
 CameraMatrix.Load(PosArray[pos].Matrix);

end;

procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble); begin

 Offset (ix, iy, iz);

end;

procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble); begin

 RotateMatrix (ix, iy, iz);

end;

procedure TCamera.Apply; begin

 if not Enabled then
   exit;
 glMatrixMode (GL_MODELVIEW);
 glLoadMatrixf(@CameraMatrix.Matrix);
 glTranslatef (-PointOfRotation.X,
               -PointOfRotation.y,
               -PointOfRotation.Z);

end;

procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble); begin

 RotateRoundAxis (iy, ix, iz);

end;

function TCamera.Position: TGLvector; var

 return: TGLvector;

begin

 // position: letzte Spalte der Matrix
 InitVector (return,
             CameraMatrix.Matrix[12],
             CameraMatrix.Matrix[13],
             CameraMatrix.Matrix[14]);
 result := return;

end;

function TCamera.ViewDirection: TGLvector; var

 return: TGLvector;

begin

 // view direction: dritte Spalte der Matrix (Z-Achse)
 InitVector (return,
             CameraMatrix.Matrix[08],
             CameraMatrix.Matrix[09],
             CameraMatrix.Matrix[10]);
 result := return;

end;

function TCamera.UpVector: TGLvector; var

 return: TGLvector;

begin

 // upVector: zweite Spalte der Matrix (Y-Achse)
 InitVector (return,
             CameraMatrix.Matrix[04],
             CameraMatrix.Matrix[05],
             CameraMatrix.Matrix[06]);
result := return;

end;

procedure TCamera.Adjust; var

 temp: TArrMatrix;

begin

 // kamera senkrecht zur Y-Achse ausrichten
 // position beibehalten
 temp[00] := 1;
 temp[01] := 0;
 temp[02] := 0;
 temp[03] := 0;
 temp[04] := 0;
 temp[05] := 1;
 temp[06] := 0;
 temp[07] := 0;
 temp[08] := 0;
 temp[09] := 0;
 temp[10] := 1;
 temp[11] := 0;
 temp[12] := CameraMatrix.Matrix[12];
 temp[13] := CameraMatrix.Matrix[13];
 temp[14] := CameraMatrix.Matrix[14];
 temp[15] := CameraMatrix.Matrix[15];
 CameraMatrix.Load(temp);

end;

end.