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

Aktuelle Zeit: Fr Jul 18, 2025 12:10

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



Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Frustum
BeitragVerfasst: Mi Feb 02, 2005 16:05 
Offline
DGL Member

Registriert: Mi Dez 15, 2004 20:36
Beiträge: 454
Wohnort: Wien, Österreich
so...
Wie bekomme ich die 4 Rays , die aus 4 Ecken meiner Kammera nach ausen "geschossen" sind.
Die 6 Frustumplanes habe ich schon aber ich will jetzt nicht die Schnittstelle jeweils zeier Ebenen suchen oder muss ich das doch so machen?
Das Problem ist nämlich, dass ich manchmal eine Seite der Skybox nicht sehe obwohl ich gerade vor dieser seite stehe, und dass nur weil ich die Ekcke der Skybox nicht im Frusum sehe (Point in Frusum? abfrage wird gemacht).
Jetzt versuche ich es mit RayCasting oder nennt man es so ? :wink:

_________________
"Meine Mutter sagt : 'Dumm ist der, der Dummes tut'." - Forrest Gump


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 03, 2005 15:10 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Probier doch mal folgendes:
wenn die vier Seiten, die dein Quad bilden jeweils paarweise an gegenügerliegenden Seiten außerhalb liegen aber in Z-Richtung innerhalb, dann liegt der Quad trotzdem innerhalb (zwar nur teilweise, aber was solls).
Also auf deutsch geasgt:
wenn die PointInFrustrum keinen bool zurückgibt, sondern ein Set=(links, drüber, drunter, zunah, zufern), dann kannst du die Ergebnisse der vier Abfragen vergleichen:
- mind. einer ein leeres set: quad liegt drin
- wenn sich alle ergebnisse ein elemet teilen (z.B. alle links): quad liegt draussen
das waren die einfachen
jetzt musst du kucken, ob gegenüberliegende Kanten deines Quads an gegenüberliegenden Seiten ausserhalb liegen. Dann umschließt dein Quad nämlich den frustrum und ist zumindest teilweise innerhalb.
ich hoffe ich konnte es verständlich erklären.

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 03, 2005 20:06 
Offline
DGL Member

Registriert: Mi Dez 15, 2004 20:36
Beiträge: 454
Wohnort: Wien, Österreich
Dieser Posting betrifft zwar nicht die Thematik aber es ist in der Richtung....
Ich habe 2 funktionen gebastelt, in der Hoffnung, dass sich jemand doch zum Thema meldet.
Also:
Code:
  1.  
  2. uses ...,Geometry,.....;
  3.  
  4. type
  5.   TPlane = record
  6.             PointOnPlane : TAffineFltVector;
  7.             PlaneNormal : TAffineFltVector;
  8.             end;
  9.  
  10.   Tline = record
  11.            PointOnLine1,PointOnLine2 : TAffineFltVector;
  12.           end;
  13.  
  14. //-------------------------------------
  15. // MatrixDetInternal
  16. //
  17. function MatrixDetInternal(const a1, a2, a3, b1, b2, b3, c1, c2, c3: Single): Single; register;
  18. // internal version for the determinant of a 3x3 matrix
  19. begin
  20.   Result:=  a1 * (b2 * c3 - b3 * c2)
  21.           - b1 * (a2 * c3 - a3 * c2)
  22.           + c1 * (a2 * b3 - a3 * b2);
  23. end;
  24. //===================================================================
  25. // intersect3D_2Planes_General(): the 3D intersect of two planes
  26. //    Input:  two planes Pn1 and Pn2
  27. //    Output: *L = the intersection line (when it exists)
  28. //    Return: 0 = disjoint (no intersection)
  29. //            1 = the two planes coincide
  30. //            2 = intersection in the unique line *L
  31.  
  32. // this is very slow , general version (slow comparing to others)
  33.  
  34. function Intersect3D_2Planes_General( Pn1, Pn2 : TPlane; var L : TLine ):Byte;
  35.  var cross : TAffineFltVector;
  36.      _Det,xDet,yDet,zDet,d1,d2,d3 : single;
  37. begin
  38.   cross := VectorCrossProduct(pn1.PlaneNormal,pn2.PlaneNormal);
  39.  
  40.   if ( (abs(cross[0]) + abs(cross[1]) + abs(cross[2]) ) <EPSILON) then
  41.         begin // no intersection
  42.          Result := 0;
  43.          Exit;
  44.         end;
  45.  
  46.   d1 := - VectorDotProduct(Pn1.PointOnPlane,Pn1.PlaneNormal);
  47.   d2 := - VectorDotProduct(Pn2.PointOnPlane,Pn2.PlaneNormal);
  48.   d3 := 0;
  49.  
  50.   _Det := MatrixDetInternal(pn1.planenormal[0],pn1.planenormal[1],pn1.planenormal[2],
  51.                             pn2.planenormal[0],pn2.planenormal[1],pn2.planenormal[2],
  52.                             cross[0], cross[1], cross[2]);
  53.  
  54.   if _Det = 0 then // this should never happen since the system could always be solved
  55.         begin
  56.          Result := 0;
  57.          Exit;
  58.         end;
  59.  
  60.   xDet := MatrixDetInternal(-d1,pn1.planenormal[1],pn1.planenormal[2],
  61.                             -d2,pn2.planenormal[1],pn2.planenormal[2],
  62.                             -d3, cross[1], cross[2]);
  63.  
  64.   yDet := MatrixDetInternal(pn1.planenormal[0],-d1,pn1.planenormal[2],
  65.                             pn2.planenormal[0],-d2,pn2.planenormal[2],
  66.                             cross[0], -d3, cross[2]);
  67.  
  68.   zDet := MatrixDetInternal(pn1.planenormal[0],pn1.planenormal[1],-d1,
  69.                             pn2.planenormal[0],pn2.planenormal[1],-d2,
  70.                             cross[0], cross[1], -d3);
  71.  
  72.   L.PointOnLine1[0] := xDet / _Det;
  73.   L.PointOnLine1[1] := yDet / _Det;
  74.   L.PointOnLine1[2] := zDet / _Det;
  75.  
  76.   L.PointOnLine2 := VectorAdd(L.PointOnLine1,cross);
  77.  
  78.   Result := 2;
  79.  
  80. end;
  81. //===================================================================
  82.  
  83. { die zweite variante ist doppelt so schnell wie die erste}
  84.  
  85. //===================================================================
  86.  
  87. // intersect3D_2Planes(): the 3D intersect of two planes
  88. //    Input:  two planes Pn1 and Pn2
  89. //    Output: *L = the intersection line (when it exists)
  90. //    Return: 0 = disjoint (no intersection)
  91. //            1 = the two planes coincide
  92. //            2 = intersection in the unique line *L
  93.  
  94. function Intersect3D_2Planes( Pn1, Pn2 : TPlane; var L : TLine ):Byte;
  95.  
  96.  var u,v,A : TAffineFltVector;
  97.      maxc : integer;        // abs max coordinate
  98.      iP : TAffineFltVector; // intersect point
  99.      d1, d2 : single;       // the constants in the 2 plane equations
  100. begin
  101.   VectorCrossProduct(Pn1.PlaneNormal,Pn2.PlaneNormal,u);// cross product
  102.  
  103.   A := u;
  104.   AbsVector(A);
  105.  
  106.     // test if the two planes are parallel
  107.     if ((a[0]+a[1]+a[2]) < geometry.EPSILON) then
  108.     begin       // Pn1 and Pn2 are near parallel
  109.         // test if disjoint or coincide
  110. //        v = Pn2.PointOnPlane - Pn1.PointOnPlane;
  111.         VectorSubtract(Pn2.PointOnPlane,Pn1.PointOnPlane,v);
  112.         if (VectorDotProduct(Pn1.PlaneNormal, v) = 0) then  // Pn2.PointOnPlane lies in Pn1
  113.             Result := 1                   // Pn1 and Pn2 coincide
  114.         else
  115.             Result := 0;                  // Pn1 and Pn2 are disjoint
  116.         Exit;
  117.     end;
  118.  
  119.     // Pn1 and Pn2 intersect in a line
  120.     // first determine max abs coordinate of cross product
  121.     if (a[0] > a[1]) then
  122.     begin
  123.         if (a[0] > a[2]) then maxc := 1 else maxc := 3
  124.     end
  125.     else
  126.         if (a[1] > a[2]) then maxc := 2 else maxc := 3;
  127.  
  128.     // next, to get a point on the intersect line
  129.     // zero the max coord, and solve for the other two
  130.     d1 := - VectorDotProduct(Pn1.PlaneNormal, Pn1.PointOnPlane);
  131.     d2 := - VectorDotProduct(Pn2.PlaneNormal, Pn2.PointOnPlane);
  132.  
  133.     case (maxc) of            // select max coordinate
  134.          1: begin                   // intersect with x=0
  135.         iP[0] := 0;
  136.         iP[1] := (d2 * Pn1.PlaneNormal[2] - d1 * Pn2.PlaneNormal[2]) / u[0];
  137.         iP[2] := (d1 * Pn2.PlaneNormal[1] - d2 * Pn1.PlaneNormal[1]) / u[0];
  138.         end;
  139.          2: begin                   // intersect with y=0
  140.         iP[0] := (d1 * Pn2.PlaneNormal[2] - d2 * Pn1.PlaneNormal[2]) / u[1];
  141.         iP[1] := 0;
  142.         iP[2] := (d2 * Pn1.PlaneNormal[0] - d1 * Pn2.PlaneNormal[0]) / u[1];
  143.         end;
  144.          3: begin                   // intersect with z=0
  145.         iP[0] := (d2 * Pn1.PlaneNormal[1] - d1 * Pn2.PlaneNormal[1]) / u[2];
  146.         iP[1] := (d1 * Pn2.PlaneNormal[0] - d2 * Pn1.PlaneNormal[0]) / u[2];
  147.         iP[2] := 0;
  148.         end;
  149.     end;
  150.     L.PointOnLine1 := iP;
  151.     L.PointOnLine2 :=  VectorAdd(iP,u);
  152. //    L->P0 = iP;
  153. //    L->P1 = iP + u;
  154.     Result := 2;
  155. end;
  156. //===================================================================
  157.  
  158.  

_________________
"Meine Mutter sagt : 'Dumm ist der, der Dummes tut'." - Forrest Gump


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 13, 2005 13:07 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Verbesserung meines letzten vorschlags:
Die Funtion PointInFrustrum gibt ein Bytewert zurück, der sich wie folgt gestaltet:
Bit 0 gesetzt, wenn der Punkt 'vor' dem Frustrum liegt (also näher als nearclipping)
Bit 1 gesetzt, wenn der Punkt 'hinter' dem Frustrum liegt (also weiter weg als farclipping)
Bit 2 gesetzt, wenn der punkt links ausserhalb liegt
Bit 3 gesetzt, wenn rechts
Bit 4 gesetzt, wenn oberhalb
Bit 5 gesetzt, wenn unterhalb
Bit 6 und Bit 7 immer null
Mehrfachantworten sind möglich, also z.b. 00000101b, wenn er davor UND links ausserhalb liegt.
Wenn jetzt mindestens ein Punkt 00000000b zurückliefert, liegt er innerhalb und du musst dein quad zeichnen.
Wenn die bitweise UND verknüpfung ALLER vier Punkte einen wert <> 00000000b zurückliefert, liegt der quad komplett ausserhalb und du musst nicht zeichnen.
Wenn die bitweise UND Verknüpfung ALLER vier Punkte 00000000b zurückliefert, dann 'umschließt' dein Quad das Frustrum und liegt teilweise drinnen. Dann musst du den Quad auch zeichnen.
Diese Methode ist schneller, wegen bitweisen vergleichen und nicht so umständlich wie mit den sets

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 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.009s | 14 Queries | GZIP : On ]