Bei der Programmierung von 3D-Anwendungen ist es äußerst sinnvoll die Rechenzeit nur für Objekte zu verwenden, die der Nutzer später auch sehen wird. Deshalb muss man heraus finden, ob ein Objekt im Blickfeld liegt oder nicht. Um solch einen Test durchzuführen, überprüft man lediglich ein paar Eckpunkte des Objektes, da eine Überprüfung des gesamten Objektes zu kompliziert wäre. Normalerweise benutzt man hierzu sogenannte "Bounding Boxes". Diese Boxen werden ganz einfach durch den minimalen und den maximalen X/Y/Z-Wert des Objektes beschrieben. Hier folgt nun der Code zur Berechnung des Blickfeldes und zur Überprüfung ob eine "Bounding Box" im Blickfeld liegt: Option Explicit ' Deklarationen ' Das berechnete Blickfeld setzt sich aus den ' 6 Seiten zusammen Private Frustum(5) As D3DPLANE ' Wir speichern uns den Index für jede Seite in ' einer Aufzählung. So ist es später einfacher ' die Seiten zu identifizieren Private Enum FrustumSide FS_RIGHT = 0 ' RECHTE Seite FS_LEFT = 1 ' LINKE Seite FS_BOTTOM = 2 ' UNTERE Seite FS_TOP = 3 ' OBERE Seite FS_BACK = 4 ' HINTERE Seite FS_FRONT = 5 ' VORDERE Seite End Enum ' Diese Matrix wird aus der Projektions- und ' Blickfeld-Matrix multipliziert Dim matClip As D3DMATRIX ' Funktion zum Berechnen das Blickfelds Public Sub CalculateFrustum() ' matView = Blickfeld-Matrix ' matProj = Projektions-Matrix D3DXMatrixMultiply matClip, matView, matProj ' Die nachfolgenden Berechnungen sind etwas ' kompliziert. Man muss sich schon ziemlich gut mit ' Matrizen-Berechnung auskennen, um die Berechnungen ' zu verstehen. Wir müssen nur wissen, dass hier das ' Blickfeld aus einer Matrix in die Planes ' konvertiert wird ' Rechts With Frustum(FS_RIGHT) .a = matClip.m14 - matClip.m11 .b = matClip.m24 - matClip.m21 .c = matClip.m34 - matClip.m31 .d = matClip.m44 - matClip.m41 End With D3DXPlaneNormalize Frustum(FS_RIGHT), Frustum(FS_RIGHT) ' Links With Frustum(FS_LEFT) .a = matClip.m14 + matClip.m11 .b = matClip.m24 + matClip.m21 .c = matClip.m34 + matClip.m31 .d = matClip.m44 + matClip.m41 End With D3DXPlaneNormalize Frustum(FS_LEFT), Frustum(FS_LEFT) ' Unten With Frustum(FS_BOTTOM) .a = matClip.m14 + matClip.m12 .b = matClip.m24 + matClip.m22 .c = matClip.m34 + matClip.m32 .d = matClip.m44 + matClip.m42 End With D3DXPlaneNormalize Frustum(FS_BOTTOM), Frustum(FS_BOTTOM) ' Oben With Frustum(FS_TOP) .a = matClip.m14 - matClip.m12 .b = matClip.m24 - matClip.m22 .c = matClip.m34 - matClip.m32 .d = matClip.m44 - matClip.m42 End With D3DXPlaneNormalize Frustum(FS_TOP), Frustum(FS_TOP) ' Hinten With Frustum(FS_BACK) .a = matClip.m14 - matClip.m13 .b = matClip.m24 - matClip.m23 .c = matClip.m34 - matClip.m33 .d = matClip.m44 - matClip.m43 End With D3DXPlaneNormalize Frustum(FS_BACK), Frustum(FS_BACK) ' Vorne With Frustum(FS_FRONT) .a = matClip.m14 + matClip.m13 .b = matClip.m24 + matClip.m23 .c = matClip.m34 + matClip.m33 .d = matClip.m44 + matClip.m43 End With D3DXPlaneNormalize Frustum(FS_FRONT), Frustum(FS_FRONT) End Sub ' Überprüft ob eine Box im Blickfeld der Kamera ist ' (indem die maximalen und minimalen Werte der Box ' übergeben werden) Public Function BoxInFrustum(Max As D3DVECTOR, _ Min As D3DVECTOR) As Boolean Dim i As Integer ' Alle 6 Planes testen For i = 0 To 5 ' PlaneDorCoord führt eine PLANE-Gleichung durch, ' die Formel dafür lautet: ' ------------------------- ' A * x + B * y + C * z + D ' ------------------------- ' Die Großbuchstaben stehen hiebrei für die Werte ' aus D3DPLANE, die Kleinbuchstaben für die ' Vertex-Koordinate, die wir testen möchten BoxInFrustum = True If D3DXPlaneDotCoord(Frustum(i), Max) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), _ MakeVector(Min.x, Max.y, Max.z)) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), _ MakeVector(Max.x, Min.y, Max.z)) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), _ MakeVector(Min.x, Min.y, Max.z)) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), _ MakeVector(Max.x, Max.y, Min.z)) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), _ MakeVector(Min.x, Max.y, Min.z)) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), _ MakeVector(Max.x, Min.y, Min.z)) <= 0 Or _ D3DXPlaneDotCoord(Frustum(i), Min) <= 0 Then BoxInFrustum = False: Exit For End If Next Ic End Function ' Hilfsgunktion um einen Vektor zu erstellen Public Function MakeVector(x As Single, _ y As Single, z As Single) As D3DVECTOR With MakeVector .x = x .y = y .z = z End With End Function Diese Funktionen habe ich von einem C++ OGL Sample von gametutorials.com in VB übersetzt. Nach meinen Erfahrungen ist diese Methode um einiges schneller als die D3DXVec3Unproject-Methode, da das Blickfeld vorberechnet wird. Dieser Tipp wurde bereits 14.269 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
sevGraph (VB/VBA) Grafische Auswertungen Präsentieren Sie Ihre Daten mit wenig Aufwand in grafischer Form. sevGraph unterstützt hierbei Balken-, Linien- und Stapel-Diagramme (Stacked Bars), sowie 2D- und 3D-Tortendiagramme und arbeitet vollständig datenbankunabhängig! Tipp des Monats März 2024 Dieter Otter UTF-8 Konvertierung von Dateien und Strings VB6 selbst verfügt über keine Funktionen zur UTF-8 Konvertierung von Daten. Mit Hilfe des ADODB.Stream-Objekts lassen sich diese fehlenden Funktionen aber schnell nachrüsten. Access-Tools Vol.1 Über 400 MByte Inhalt Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |