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

Aktuelle Zeit: Fr Jul 18, 2025 08:17

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Autor Nachricht
 Betreff des Beitrags: Problem mit Frustum
BeitragVerfasst: So Jul 31, 2005 20:01 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jun 25, 2003 12:44
Beiträge: 29
Hallo!
Ich arbeite gerade daran, die Darstellung einer Height-Map zu Optimieren.
Da die Kameraeinstellung fest von (schräg) oben ist, habe ich mir folgendes überlegt:
1) Ich berechne die 6 Frustum-Ebenen (dank dem Tutorial von delphigl.de kein Problem :))
2) Ich berechne die Schnitt-Geraden der Left/Right/Top/Bottom-Ebene mit folgender Ebene: A=0 B=1 C=0 D=0 (diese Ebene "liegt" auf der X und Z Achse)
3) Ich berechne die Schnittpunkte dieser Geraden.
Wenn ich dann die jeweils größten und kleinsten X und Z Werte der Schnittpunkt nehme, habe ich dann einen kleinen Bereich der Heightmap eingegrenzt, den ich dann nur noch zu zeichnen brauche.

In der Theorie ists ja ganz einfach, nur in der Praxis hab ich gerade so meine Probleme.
Ich bin schon den ganzen Trag da dran, den Fehler zu finden, aber ich hatte bis jetzt noch keine Erfolge :(

Hier mal die wichtigsten Code-Stücke, vielleicht findet ja jemand den Fehler!?

Code:
  1. function Intersect3D_2Planes( Pn1, Pn2 : TPlane; var L : TLine ):Byte;
  2. var u,A : TAffineFltVector;
  3.     temp1,temp2,v,temp3:THomogeneousFltVector;
  4.     maxc : integer; // abs max coordinate
  5.     iP : TAffineFltVector; // intersect point
  6.     d1, d2 : single; // the constants in the 2 plane equations
  7. begin
  8.   u := VectorCrossProduct(Pn1.PlaneNormal,Pn2.PlaneNormal);
  9.  
  10.   A := u;
  11.   //AbsVector(A);
  12.   A[0] := abs(A[0]);
  13.   A[1] := abs(A[1]);
  14.   A[2] := abs(A[2]);
  15.  
  16.   // test if the two planes are parallel
  17.   if ((a[0]+a[1]+a[2]) < geometry.EPSILON) then
  18.   begin // Pn1 and Pn2 are near parallel
  19.     // test if disjoint or coincide
  20.     // v = Pn2.PointOnPlane - Pn1.PointOnPlane;
  21.  
  22. //    v := VectorSubtract(Pn2.PointOnPlane,Pn1.PointOnPlane);
  23.     v[0] := Pn2.PointOnPlane[0] - Pn1.PointOnPlane[0];
  24.     v[1] := Pn2.PointOnPlane[1] - Pn1.PointOnPlane[1];
  25.     v[2] := Pn2.PointOnPlane[2] - Pn1.PointOnPlane[2];
  26. //    if (VectorDotProduct(Pn2.PointOnPlane, v) = 0) then // Pn2.PointOnPlane lies in Pn1
  27.     if ((Pn2.PointOnPlane[0]*v[0]+Pn2.PointOnPlane[1]*v[1]+Pn2.PointOnPlane[2]*v[2]) = 0) then
  28.       Result := 1 // Pn1 and Pn2 coincide
  29.     else
  30.       Result := 0; // Pn1 and Pn2 are disjoint
  31.     Exit;
  32.   end;
  33.  
  34.   // Pn1 and Pn2 intersect in a line
  35.   // first determine max abs coordinate of cross product
  36.   if (a[0] > a[1]) then
  37.   begin
  38.     if (a[0] > a[2]) then
  39.       maxc := 1
  40.     else
  41.       maxc := 3;
  42.   end
  43.   else if (a[1] > a[2]) then
  44.     maxc := 2
  45.   else
  46.     maxc := 3;
  47.  
  48.   // next, to get a point on the intersect line
  49.   // zero the max coord, and solve for the other two
  50. //  d1 := - VectorDotProduct(Pn1.PlaneNormal, Pn1.PointOnPlane);
  51.   d1 := -(Pn1.PlaneNormal[0]*Pn1.PointOnPlane[0]+Pn1.PlaneNormal[1]*Pn1.PointOnPlane[1]+Pn1.PlaneNormal[2]*Pn1.PointOnPlane[2]);
  52. //  d2 := - VectorDotProduct(Pn2.PlaneNormal, Pn2.PointOnPlane);
  53.   d2 := -(Pn2.PlaneNormal[0]*Pn2.PointOnPlane[0]+Pn2.PlaneNormal[1]*Pn2.PointOnPlane[1]+Pn2.PlaneNormal[2]*Pn2.PointOnPlane[2]);
  54.                                  
  55.   case (maxc) of // select max coordinate
  56.     1: begin // intersect with x=0
  57.          iP[0] := 0;
  58.          iP[1] := (d2 * Pn1.PlaneNormal[2] - d1 * Pn2.PlaneNormal[2]) / u[0];
  59.          iP[2] := (d1 * Pn2.PlaneNormal[1] - d2 * Pn1.PlaneNormal[1]) / u[0];
  60.        end;
  61.     2: begin // intersect with y=0
  62.          iP[0] := (d1 * Pn2.PlaneNormal[2] - d2 * Pn1.PlaneNormal[2]) / u[1];
  63.          iP[1] := 0;
  64.          iP[2] := (d2 * Pn1.PlaneNormal[0] - d1 * Pn2.PlaneNormal[0]) / u[1];
  65.        end;
  66.     3: begin // intersect with z=0
  67.          iP[0] := (d2 * Pn1.PlaneNormal[1] - d1 * Pn2.PlaneNormal[1]) / u[2];
  68.          iP[1] := (d1 * Pn2.PlaneNormal[0] - d2 * Pn1.PlaneNormal[0]) / u[2];
  69.          iP[2] := 0;
  70.        end;
  71.   end;
  72.   L.PointOnLine1 := iP;
  73.   L.PointOnLine2[0] := iP[0]+u[0];
  74.   L.PointOnLine2[1] := iP[1]+u[1];
  75.   L.PointOnLine2[2] := iP[2]+u[2];
  76.   // L->P0 = iP;
  77.   // L->P1 = iP + u;
  78.   Result := 2;
  79. end;
  80.  
  81. procedure Intersect2D_2Lines( L1,L2:TLine2D; var P:TVector2D );
  82. var m1,m2,
  83.     x1,x2,
  84.     y1,y2:single;
  85. begin
  86.   m1 := (L1.PointOnLine2.y-L1.PointOnLine1.y)/(L1.PointOnLine2.x-L1.PointOnLine1.x);
  87.   m2 := (L2.PointOnLine2.y-L2.PointOnLine1.y)/(L2.PointOnLine2.x-L2.PointOnLine1.x);
  88.   x1 := L1.PointOnLine1.x;
  89.   x2 := L2.PointOnLine1.x;
  90.   y1 := L1.PointOnLine1.y;
  91.   y2 := L2.PointOnLine1.y;
  92.   P.x := (y2-y1+m1*x2-m2*x2)/(m1-m2);
  93.   P.y := y1+m1*(P.x-x1);
  94. end;
  95.  
  96.  
  97.  
  98. procedure TMap.Draw;
  99. //...
  100.  
  101. procedure MakeEbene(i:integer);
  102. begin
  103.   ebene.PlaneNormal[0] := Frustum.Frustum[i][0];
  104.   ebene.PlaneNormal[1] := Frustum.Frustum[i][1];
  105.   ebene.PlaneNormal[2] := Frustum.Frustum[i][2];
  106.   ebene.PointOnPlane[0] := Frustum.Frustum[i][0]*Frustum.Frustum[i][3];
  107.   ebene.PointOnPlane[1] := Frustum.Frustum[i][1]*Frustum.Frustum[i][3];
  108.   ebene.PointOnPlane[2] := Frustum.Frustum[i][2]*Frustum.Frustum[i][3];
  109. end;
  110.  
  111. procedure Swap(var a,b:single);
  112. var c:single;
  113. begin
  114.   c := a;
  115.   a := b;
  116.   b := c;
  117. end;
  118.  
  119. function SmallestValue(v1,v2,v3,v4:single):single;
  120. begin
  121.   if v1 > v2 then
  122.     Swap(v1,v2);
  123.   if v1 > v3 then
  124.     Swap(v1,v3);
  125.   if v1 > v4 then
  126.     Swap(v1,v4);
  127.   result := v1;
  128. end;
  129.  
  130. function GreatestValue(v1,v2,v3,v4:single):single;
  131. begin
  132.   if v1 < v2 then
  133.     Swap(v1,v2);
  134.   if v1 < v3 then
  135.     Swap(v1,v3);
  136.   if v1 < v4 then
  137.     Swap(v1,v4);
  138.   result := v1;
  139. end;
  140.  
  141.  
  142. begin
  143. //...
  144.   Frustum.Calculate;  //TFrustum Klasse von delphigl.de
  145.  
  146.   nullebene.PointOnPlane[0] := 0;
  147.   nullebene.PointOnPlane[1] := 0;
  148.   nullebene.PointOnPlane[2] := 0;
  149.   nullebene.PlaneNormal[0] := 0;
  150.   nullebene.PlaneNormal[1] := 1;
  151.   nullebene.PlaneNormal[2] := 0;
  152.  
  153.   //Links
  154.   MakeEbene(Left);
  155.   Intersect3D_2Planes(ebene,nullebene,lineTemp);
  156.   lineLeft.PointOnLine1.x := lineTemp.PointOnLine1[0];
  157.   lineLeft.PointOnLine1.y := lineTemp.PointOnLine1[2];
  158.   lineLeft.PointOnLine2.x := lineTemp.PointOnLine2[0];
  159.   lineLeft.PointOnLine2.y := lineTemp.PointOnLine2[2];
  160.  
  161.   //Rechts
  162.   MakeEbene(Right);
  163.   Intersect3D_2Planes(ebene,nullebene,lineTemp);
  164.   lineRight.PointOnLine1.x := lineTemp.PointOnLine1[0];
  165.   lineRight.PointOnLine1.y := lineTemp.PointOnLine1[2];
  166.   lineRight.PointOnLine2.x := lineTemp.PointOnLine2[0];
  167.   lineRight.PointOnLine2.y := lineTemp.PointOnLine2[2];
  168.  
  169.   //Oben
  170.   MakeEbene(Top);
  171.   Intersect3D_2Planes(ebene,nullebene,lineTemp);
  172.   lineTop.PointOnLine1.x := lineTemp.PointOnLine1[0];
  173.   lineTop.PointOnLine1.y := lineTemp.PointOnLine1[2];
  174.   lineTop.PointOnLine2.x := lineTemp.PointOnLine2[0];
  175.   lineTop.PointOnLine2.y := lineTemp.PointOnLine2[2];
  176.  
  177.   //Unten
  178.   MakeEbene(Bottom);
  179.   Intersect3D_2Planes(ebene,nullebene,lineTemp);
  180.   lineBottom.PointOnLine1.x := lineTemp.PointOnLine1[0];
  181.   lineBottom.PointOnLine1.y := lineTemp.PointOnLine1[2];
  182.   lineBottom.PointOnLine2.x := lineTemp.PointOnLine2[0];
  183.   lineBottom.PointOnLine2.y := lineTemp.PointOnLine2[2];
  184.  
  185.   // Left-Bottom
  186.   Intersect2D_2Lines(lineLeft,lineBottom,intersectLeftBottom);
  187.  
  188.   // Bottom-Right
  189.   Intersect2D_2Lines(lineBottom,lineRight,intersectBottomRight);
  190.  
  191.   // Right-Top
  192.   Intersect2D_2Lines(lineRight,lineTop,intersectRightTop);
  193.  
  194.   // Top-Left
  195.   Intersect2D_2Lines(lineTop,lineLeft,intersectTopLeft);
  196.  
  197.   SetRoundMode(rmDown);
  198.   minX := Round(SmallestValue(intersectLeftBottom.x,
  199.                               intersectBottomRight.x,
  200.                               intersectRightTop.x,
  201.                               intersectTopLeft.x));
  202.   SetRoundMode(rmUp);
  203.   maxX := Round(GreatestValue(intersectLeftBottom.x,
  204.                               intersectBottomRight.x,
  205.                               intersectRightTop.x,
  206.                               intersectTopLeft.x));
  207.   SetRoundMode(rmDown);
  208.   minY := Round(SmallestValue(intersectLeftBottom.y,
  209.                               intersectBottomRight.y,
  210.                               intersectRightTop.y,
  211.                               intersectTopLeft.y));
  212.   SetRoundMode(rmUp);
  213.   maxY := Round(GreatestValue(intersectLeftBottom.y,
  214.                               intersectBottomRight.y,
  215.                               intersectRightTop.y,
  216.                               intersectTopLeft.y));
  217.   SetRoundMode(rmNearest);
  218.  
  219. //...
  220.  
  221.   for i := minX to maxX do
  222.     for j := minY to maxY do
  223.       PunktZeichnen(i,j);
  224.  
  225. end;
  226.  


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 » OpenGL


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.007s | 16 Queries | GZIP : On ]