Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 08:15

Foren-Übersicht » Programmierung » Mathematik-Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Autor Nachricht
 Betreff des Beitrags: gluLookAt und Upvector
BeitragVerfasst: Mo Aug 15, 2005 03:24 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Hallo, hallo,

ich habe mir eine camera Klasse von einem anderen Programmierer geklaut und in mein Programm integriert. Diese Klasse hält die von gluLookAt benötigten Informationen bereit und verändert sie je nach Benutzerwunsch. Wird gluLookAt mit diesen Informationen aufgerufen, dann sollte sich immer die richtige Ansicht darbieten.

Informationen: Kameraposition, Blickrichtung und Upvector.

Die von dieser Klasse bereitgestellten Funktionen sind das bewegen der Kamere links/rechts, des zoomen der Kamera in den Bildschirm und wieder heraus und das drehen der Kamera um jede beliebige Achse.

Ich bin allerdings zu der Ansicht gelangt, dass das drehen der Kamera um die Achsen nie richtig ausprobiert oder getestet wurde. Bei einem Upvector 0,1,0 funktioniert die Drehung um die Y-Achse, bei einem Upvector von 1,0,0 um die X-Achse und bei einem Upvector von 0,0,1 um die Z-Achse. Habe ich den Upvector immer gleich (bei mir 0,1,0), stellt sich die Drehung nicht rund dar sondern unsymmetrisch. Ausserdem kippt die Drehung bei einem bestimmten Punkt um 180°.

Man muss den Upvector also auch anpassen und nicht nur die Kameraposition oder die Blickrichtung neu berechnen.

Ich habe auch schon einige Hinweise darauf gefunden, aber keine richtige Anleitung.

Kann mir vielleicht jemand sagen wie ich den Upvector anpassen muss bei

1. einer Drehung der Kameraposition um einen Punkt
2. eine Drehung des Blickpunktes um die Kamera
3. einer Bewegung der Kamera hoch/runter (an der Y-Achse entlang)

Das wäre super,

Danke

Hier die Klasse:

Code:
  1.  
  2. // die aus meiner unit OpenGLUtil benötigten definitionen:
  3. type
  4.   TGLVector = packed record
  5.     x,y,z: GLfloat;
  6.   end;
  7.  
  8. // die kameraklasse
  9. unit CameraClass;
  10.  
  11. interface
  12.  
  13.   Uses DglOpenGL, OpenGLUtil, Windows, Classes;
  14.  
  15.   type TCamera = object
  16.     Position : TGLvector;      // The camera's position
  17.     View     : TGLvector;      // The camera's View
  18.     UpVector : TGLvector;      // The camera's UpVector
  19.     procedure PositionCamera(PositionVec: TGLvector;
  20.                                    ViewVec: TGLvector;
  21.                                    upVec: TGLvector);
  22.     procedure RotateView(const X, Y, Z : glFloat);
  23.     procedure MoveCameraByMouse(MouseX, MouseY,
  24.                                 MiddleX, MiddleY: integer);
  25.     procedure RotateAroundPoint(const Center : TGLvector;
  26.                                 const X, Y, Z : glFloat);
  27.     procedure PanCamera(speed : glFloat);   // schwenken der kamera links/rechts
  28.     procedure LiftCamera(speed : glFloat);    // nach oben/unten bewegen
  29.     procedure ZoomCamera(speed : glFloat);// in den bildschirm rein/aus dem bildschirm raus
  30.   end;
  31.  
  32.   var SCREEN_WIDTH, SCREEN_HEIGHT : Integer;
  33.  
  34. implementation
  35.  
  36. { TCamera }
  37.  
  38. {------------------------------------------------------------------------}
  39. {--- This function sets the camera's position and view and up vVector ---}
  40. {------------------------------------------------------------------------}
  41. procedure TCamera.PositionCamera(PositionVec: TGLvector;
  42.                                        ViewVec: TGLvector;
  43.                                        upVec: TGLvector);
  44. begin
  45.   Position.X := PositionVec.X;
  46.   Position.Y := PositionVec.Y;
  47.   Position.Z := PositionVec.Z;
  48.  
  49.   View.X     := ViewVec.X;
  50.   View.Y     := ViewVec.Y;
  51.   View.Z     := ViewVec.Z;
  52.  
  53.   UpVector.X := UpVec.X;
  54.   UpVector.Y := UpVec.Y;
  55.   UpVector.Z := UpVec.Z;
  56. end;
  57.  
  58. {-----------------------------------------------------------------------------}
  59. {--- This will move the camera forward or backward depending on the speed  ---}
  60. {-----------------------------------------------------------------------------}
  61. procedure TCamera.ZoomCamera(speed: glFloat);
  62. var V : TGLvector;
  63. begin
  64.   // Get our view vVector (The direciton we are facing)
  65.   V.X := View.X - Position.X;              // This gets the direction of the X
  66.   V.Y := View.Y - Position.Y;              // This gets the direction of the Y
  67.   V.Z := View.Z - Position.Z;              // This gets the direction of the Z
  68.  
  69.   Position.X := Position.X + V.X * speed;  // Add our acceleration to our position's X
  70.   Position.Y := Position.Y + V.Y * speed;  // Add our acceleration to our position's Y
  71.   Position.Z := Position.Z + V.Z * speed;  // Add our acceleration to our position's Z
  72.  
  73.   View.X := View.X + V.X * speed;          // Add our acceleration to our view's X
  74.   View.Y := View.Y + V.Y * speed;          // Add our acceleration to our view's Y
  75.   View.Z := View.Z + V.Z * speed;          // Add our acceleration to our view's Z
  76. end;
  77.  
  78. {-----------------------------------------------------------}
  79. {--- The mouse look function. Use mouse to look around   ---}
  80. {-----------------------------------------------------------}
  81. {procedure TCamera.ZoomCameraByMouse;
  82. var mousePos : TPoint;
  83.     middleX, middleY : Integer;
  84.     deltaY, rotateY : glFloat;
  85. begin
  86.   middleX := SCREEN_WIDTH SHR 1;       // This is a binary shift to get half the width
  87.   middleY := SCREEN_HEIGHT SHR 1;      // This is a binary shift to get half the height
  88.  
  89.   // Get the mouse's current X,Y position
  90.   GetCursorPos(mousePos);
  91.  
  92.   // If our cursor is still in the middle, we never moved... so don't update the screen
  93.   if (mousePos.X = middleX) AND (mousePos.Y = middleY) then
  94.     exit;
  95.  
  96.   // Set the mouse position to the middle of our window
  97.   SetCursorPos(middleX, middleY);
  98.  
  99.   // Get the direction the mouse moved in, but bring the number down to a reasonable amount
  100.   rotateY := (middleX - mousePos.X)/500;
  101.   deltaY  := (middleY - mousePos.Y)/1000;
  102.  
  103.   // Multiply the direction vVector for Y by an acceleration (The higher the faster is goes).
  104.   View.Y := View.Y + deltaY*5;
  105.  
  106.   // Check if the distance of our view exceeds 60 from our position, if so, stop it. (UP)
  107.   if View.Y - Position.Y > 10 then
  108.      View.Y := Position.Y + 10;
  109.  
  110.   // Check if the distance of our view exceeds -60 from our position, if so, stop it. (DOWN)
  111.   if View.Y - Position.Y < -10 then
  112.      View.Y := Position.Y - 10;
  113.  
  114.   // Here we rotate the view along the X avis depending on the direction (Left of Right)
  115.   RotateView(0, -rotateY, 0);
  116. end;}
  117. procedure TCamera.MoveCameraByMouse (MouseX, MouseY,
  118.                                      MiddleX, MiddleY: integer);
  119. // ich musste die mausfunktionen dieser neuen funktion vorlagern, sonst
  120. // geht es halt nicht. die werte werden jetzt als parameter übergeben, die in
  121. // der prozedur BewegeKameraDurchMaus erfasst werden.
  122. var
  123.   deltaY, rotateY : glFloat;
  124. begin
  125.   // Get the direction the mouse moved in, but bring the number down to a reasonable amount
  126.   rotateY := (MiddleX - MouseX)/500;
  127.   deltaY  := (MiddleY - MouseY)/1000;
  128.  
  129.   // Multiply the direction vVector for Y by an acceleration (The higher the faster is goes).
  130.   View.Y := View.Y + deltaY*500;
  131.  
  132.   // Check if the distance of our view exceeds 60 from our position, if so, stop it. (UP)
  133.   //if View.Y - Position.Y > 60 then
  134.   //  View.Y := Position.Y + 60;
  135.  
  136.   // Check if the distance of our view exceeds -60 from our position, if so, stop it. (DOWN)
  137.   //if View.Y - Position.Y < -60 then
  138.   //   View.Y := Position.Y - 60;
  139.  
  140.   // Here we rotate the view along the Y avis depending on the direction (Left of Right)
  141.   RotateView(0, -rotateY, 0);
  142. end;
  143.  
  144. {---------------------------------------------------------------------}
  145. {--- This pans the camera left and right depending on the speed ---}
  146. {---------------------------------------------------------------------}
  147. procedure TCamera.PanCamera(speed: glFloat);
  148. var
  149.   Cross, ViewVector : TGLvector;
  150. begin
  151.   // Get the view vVector of our camera and store it in a local variable
  152.   ViewVector := SubtractVector (View, Position);
  153.  
  154.   // Calculate the cross product of our up vVector and view vVector
  155.   Cross := CrossProduct (UpVector, ViewVector);
  156.  
  157.   // Add the resultant vVector to our position
  158.   Position.X := Position.X + Cross.X * speed;
  159.   Position.Z := Position.Z + Cross.Z * speed;
  160.  
  161.   // Add the resultant vVector to our view
  162.   View.X := View.X + Cross.X * speed;
  163.   View.Z := View.Z + Cross.Z * speed;
  164. end;
  165.  
  166. {---------------------------------------------------------------------}
  167. {--- This lifts the camera up and down depending on the speed      ---}
  168. {---------------------------------------------------------------------}
  169. procedure TCamera.LiftCamera(speed: glFloat);
  170. var
  171.   Cross, ViewVector: TGLvector;
  172. begin
  173.   // Get the view vVector of our camera and store it in a local variable
  174.   ViewVector := SubtractVector (View, Position);
  175.  
  176.   // Calculate the cross product of our up vVector and view vVector
  177.   Cross := CrossProduct (UpVector, ViewVector);
  178.  
  179.   // Add the resultant vVector to our position
  180.   Position.Y := Position.Y + Cross.Y * speed;
  181.   Position.Z := Position.Z + Cross.Z * speed;
  182.  
  183.   // Add the resultant vVector to our view
  184.   View.Y := View.Y + Cross.Y * speed;
  185.   View.Z := View.Z + Cross.Z * speed;
  186. end;
  187.  
  188. {-----------------------------------------------------------}
  189. {--- This rotates the view around the position           ---}
  190. {-----------------------------------------------------------}
  191. procedure TCamera.RotateView(const X, Y, Z: glFloat);
  192. {
  193. var
  194.   viewVector : TGLvector;
  195. begin
  196.   // Get our view vVector (The direction we are facing)
  197.   viewVector.X := View.X - Position.X; // This gets the direction of the X
  198.   viewVector.Y := View.Y - Position.Y; // This gets the direction of the Y
  199.   viewVector.Z := View.Z - Position.Z; // This gets the direction of the Z
  200.  
  201.   // If we pass in a negative X Y or Z, it will rotate the opposite way,
  202.   // so we only need one function for a left and right, up or down rotation.
  203.   if X <> 0 then
  204.   begin
  205.     View.Z := Position.Z + sin(X)*viewVector.Y + cos(X)*viewVector.Z;
  206.     View.Y := Position.Y + cos(X)*viewVector.Y - sin(X)*viewVector.Z;
  207.   end;
  208.  
  209.   if Y <> 0 then
  210.   begin
  211.     View.Z := Position.Z + sin(Y)*viewVector.X + cos(Y)*viewVector.Z;
  212.     View.X := Position.X + cos(Y)*viewVector.X - sin(Y)*viewVector.Z;
  213.   end;
  214.  
  215.   if Z <> 0 then
  216.   begin
  217.     View.X := Position.X + sin(Z)*viewVector.Y + cos(Z)*viewVector.X;
  218.     View.Y := Position.Y + cos(Z)*viewVector.Y - sin(Z)*viewVector.X
  219.   end;
  220. }
  221. var
  222.   vVector : TGLvector;
  223.   Sinus, Cosinus, Mult: single;
  224.     oldUp: TGLvector;
  225. begin
  226.   oldUp := UpVector;
  227.   //InitVector (UpVector);
  228.   Mult := 1{2*pi/360};
  229.  
  230.   // Get our view vVector (The direction we are facing)
  231.   vVector := SubtractVector (View, Position);
  232.  
  233.   // If we pass in a negative X Y or Z, it will rotate the opposite way,
  234.   // so we only need one function for a left and right, up or down rotation.
  235.   if X <> 0 then
  236.   begin
  237.     Cosinus := cos (x*Mult);
  238.     Sinus := sin(x*Mult);
  239.     //UpVector.x := 1;
  240.     View.Z := Position.Z + Sinus*vVector.Y + Cosinus*vVector.Z;
  241.     View.Y := Position.Y + Cosinus*vVector.Y - Sinus*vVector.Z;
  242.   end
  243.   else if Y <> 0 then
  244.   begin
  245.     Cosinus := cos (y*Mult);
  246.     Sinus := sin(y*Mult);
  247.     //UpVector.y := 1;
  248.     View.Z := Position.Z + Sinus*vVector.X + Cosinus*vVector.Z;
  249.     View.X := Position.X + Cosinus*vVector.X - Sinus*vVector.Z;
  250.   end
  251.   else if Z <> 0 then
  252.   begin
  253.     Cosinus := cos (z*Mult);
  254.     Sinus := sin(z*Mult);
  255.     //UpVector.z := 1;
  256.     View.X := Position.X + Sinus*vVector.Y + Cosinus*vVector.X;
  257.     View.Y := Position.Y + Cosinus*vVector.Y - Sinus*vVector.X
  258.   end;
  259. end;
  260.  
  261. procedure TCamera.RotateAroundPoint(const center: tglvector;
  262.                                     const x,y,z: TGLfloat);
  263. var
  264.     PosViewVector: TGLvector;
  265. begin
  266.   // Get the viewVector from our position to the center we are rotating around
  267.   PosViewVector := SubtractVector (Position, Center);
  268.  
  269.   // Rotate the position up or down, then add it to the center point
  270.   if X <> 0 then
  271.   begin
  272.     Position.Z := Center.Z + sin(X)*PosViewVector.Y + cos(X)*PosViewVector.Z;
  273.     Position.Y := Center.Y + cos(X)*PosViewVector.Y - sin(X)*PosViewVector.Z;
  274.   end
  275.   else if Y <> 0 then
  276.   begin
  277.     Position.Z := Center.Z + sin(Y)*PosViewVector.X + cos(Y)*PosViewVector.Z;
  278.     Position.X := Center.X + cos(Y)*PosViewVector.X - sin(Y)*PosViewVector.Z;
  279.   end
  280.   else if Z <> 0 then
  281.   begin
  282.     Position.X := Center.X + sin(Z)*PosViewVector.Y + cos(Z)*PosViewVector.X;
  283.     Position.Y := Center.Y + cos(Z)*PosViewVector.Y - sin(Z)*PosViewVector.X;
  284.   end;
  285. end;
  286. end.
  287.  


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Foren-Übersicht » Programmierung » Mathematik-Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 16 Queries | GZIP : On ]