300 likes | 466 Views
Kollisionen erkennen. Kollisions- und Schnittpunkttests auf Dreieckbasis Kollisions- und Schnittpunkttests auf Viereckbasis Einsatz von achsenausgerichteten Bounding Boxen für die Verbesserung der Performance bei Kollisions- und Schnittpunkttests auf Dreieckbasis
E N D
Kollisionen erkennen Kollisions- und Schnittpunkttests auf Dreieckbasis Kollisions- und Schnittpunkttests auf Viereckbasis Einsatz von achsenausgerichteten Bounding Boxen für die Verbesserung der Performance bei Kollisions- und Schnittpunkttests auf Dreieckbasis Kollision zweier 3D Modelle: OOB-OOB-Test AABB-OOB_Test
Kollisions- und Schnittpunkttests auf Dreieckbasis (1) • 3D Modell auf Dreieckbasis • Drahtgittermodell (besteht aus Dreiecken) mit Texturüberzug • Dreiecke werden zu Kollisions- und Schnittpunkttests herangezogen • Punkt-in-Dreieck-Test • Wofür: z.B. um festzustellen ob ein Spieler gegen die Wand gerannt ist • Strahl-schneidet-Dreieck-Test: • Wofür: Zur Bestimmung der Fußboden- und Terrainhöhe
Kollisions- und Schnittpunkttests auf Dreieckbasis (2) • 1. Schnittpunkt in der Ebene bestimmen (allgemein): • Mit Normalenform einer Ebene Es muss zuerst überprüft werden ob zwischen den Objekten in der Umgebung und dem jeweiligen Dreieck in einer Ebene einen Schnittpunkt gibt - Wenn Punkt innerhalb der Ebene liegt, liegt der Vektor ∆ in der Ebene und ist damit senkrecht zur Flächennormalen n. - Das Skalarprodukt (relative Lage der zwei Vektoren zueinander) ist gleich Null
Kollisions- und Schnittpunkttests auf Dreieckbasis (2) • Schnittpunktberechnung (konkret)
Kollisions- und Schnittpunkttests auf Dreieckbasis (3) • Dreieck in der Ebene (Konstruktion einer Ebene aus Eckpunkten) • Wir kennen die Eckpunkte (Vertices) des Dreiecks aus denen das 3D Modell zusammengesetzt ist (wurden festgelegt als das Gittermodell entworfen wurde) • Daraus muss die Ebene berechnet werden
Kollisions- und Schnittpunkttests auf Dreieckbasis (4) • Der Halbseitentest • Was können wir schon? • Aus Punkten Ebene berechnen • Wir kennen Methode zur Schnittpunktberechnung mit Ebene • Schnittpunkt muss nicht innerhalb des Dreiecks sein • Ebene hat unendliche Ausdehnung • Ausdehnung eines Dreiecks ist aber begrenzt • Methode um festzustellen ob ein Schnittpunkt einer Ebene innerhalb des Dreiecks liegt ist Halbseitentest • Es wird überprüft auf welcher Seite einer Dreieckskante der Schnittpunkt liegt • Liegt der Schnittpunkt immer innerhalb der drei Dreieckskanten, liegt er auch innerhalb des Dreiecks
Kollisions- und Schnittpunkttests auf Dreieckbasis (5) • Halbseitentest die Zweite: Test ist möglich für zweidimensionale, konvexe Polygone Konvex = Innenwinkel aller benachbarter Kanten ist < 180 ° Für dreidimensionale Polygone gibt es den Halbraumtest • Kleiner mathematisch-terminologischer Exkurs: • Der Mathematiker bezeichnet sowohl die Innen-, als auch die Außenseite als Halbseite • Deshalb der Name
Kollisions- und Schnittpunkttests auf Dreieckbasis (6) • Auf zur Praxis: • Klasse CTriangle wird implementiert Dreiecksnummer 3 Vektoren für die Eckpunkte 3 Vektoren für die Senkrechten der Dreieckskanten Normalenvektor Konstruktor/Destruktor hat keine Funktion
Kollisions- und Schnittpunkttests auf Dreieckbasis (7) Was machen die Funktionen: Init_Triangle() • Aufgabe: Initialisierung eines Dreiecks • Skalierte sowie unskalierte Eckpunkte können übergeben werden • Damit das Dreieck mit unskalierten Eckpunkten richtig skaliert werden kann, muss der Skalierungsfaktor mit übergeben werden - Nach Zuweisung der Eckpunkte wird der Normalvektor, sowie die Senkrechten der Dreieckskanten berechnet Warum skaliert, warum unskalierte Eckpunkte: • Bei wenigen Objekten ist es sinnvoll die Eckpunkte als skaliert schon vorliegen zu haben (also ein 3D Modell zu übergeben) • Bei mehreren Objekten ist es sinnvoller wenige 3D Modelle zu verwenden und durch Variation des Skalierungsfaktors variable Objekte zu erzeugen (bsplw. Bei Asteroiden)
Kollisions- und Schnittpunkttests auf Dreieckbasis (8) • Test_for_Ray_Intersection() • Führt Schnittpunkttest zwischen einem Strahl (z.B. Sonnenstrahl) und einem Dreieck durch • Schritt 1: es wird überprüft ob Normalvektor und die Richtung des Strahls senkrecht zueinander sind • Wenn ja, kann es keinen Schnittpunkt geben • Schritt 2: intersection_parameter (entspricht Variable a aus 7.3) wird berechnet • Um Schnittpunkt zu bestimmen wird dieser Parameter anschließend in die Geradengleichung eingesetzt • Schritt 3: Halbseitentest
Kollisions- und Schnittpunkttests auf Dreieckbasis (9) • Test_for_Point_Collision() • Kollisionstest zwischen Punkt und einem Dreieck wird gemacht (Raketen, Laserimpulswaffen ) • Übergeben werden: • Adresse des Ortsvektors der Objektmittelpunktes • Adresse der Objektflugrichtung • Adresse einer Ganzzahlvariablen • Im Falle eines positiven Kollisionstests übergibt man die Dreiecksnummer • Diese Funktion für den Punkt und die „Strahlfunktion“ sind identisch • Einziger Unterschied: • Abstandstest zwischen Dreieck und Objektmittelpunkt • Ist der Abstand zu groß liegt keine Kollision vor • Ist Abstand in bestimmten Rahmen, liegt Kollision vor • Die Größe des Rahmens soll man durch ausprobieren herausfinden
Test_for_Point_Collision_Wall() • Abwandlung der Test_for_Point_Collision() für den Kollisionstest an einer Wand • Keine Adresse der Bewegungsrichtung wird mit übergeben • Als Richtung wird immer der negative Normalenvektor der Wand verwendet
Kollisions- und Schnittpunkttests auf Dreieckbasis (10) • CTriangle() wird später zur genauen Treffer- und Schnittpunkterkennung in Indoor und Terainrenderer verwendet • Bei der Initialisierung werden immer die Modellkoordinaten der Dreiecke einer 3 D Modells an die Funktion Init_Triangle() übergeben • Im Spiel hingegen unterliegen die Modelle ständigen Transformationen • Frage: Wie soll Treffererkennung ohne Kenntnis der Weltkoordinaten der 3 D Modelle funktionieren?
Kollisions- und Schnittpunkttests auf Dreieckbasis (11) • Beispiel: • Rakete fliegt, Raumschiff (fliegt), Treffer soll erkannt werden • Mittels Funktion Test_for_Point_Collision() soll getroffenes Dreieck gefunden werden • Lösung: • Ortsvektor und Bewegungsrichtung der Rakete müssen so transformiert werden, dass Modellkoordinaten der Dreiecke des Raumschiffs für die Treffererkennung verwendet werden können
Rücktransformation • Für Treffertest müssen Position und Flugrichtung transformiert werden • - Inverse Rotationsmatrix des Raumschiffes wird benötigt Inverse Rotationsmatrix macht die Transformationen der Oirginalmatrix wieder rückgängig
Kollisions- und Schnittpunkttests auf Dreieckbasis (12) • Dreieck-Dreieck-Kollisionstest • Wenn sich zwei Dreiecke schneiden muss mindestens eine Kante des einen Dreiecks eine Fläche des anderen schneiden • Schnittpunktberechnungsfunktion kennen wir bereits • Die Dreieckskante die man der Funktion übergibt muss man relativ zu den Modellkoordinaten des anderen Dreiecks transformieren • Eckpunkte des Dreiecks transformieren und aus ihnen die Kanten berechnen • Dann intersection_parameter berechnen • Hat dieser einen Wert >=0 und <=1schneidet die Kante diejenige Ebene in der das andere Dreieck liegt
Kollisions- und Schnittpunkttests auf Viereckbasis (1) • Unterschied zu Tests auf Dreieckbasis: • Beim Halbseitentest kommt eine weitere Kante hinzu • Mit Klasse ClQuad() • Hat zwei weitere Funktionen • Test_for_axis_aligned_Ray_Intersection() • Schnittpunkt zwischen Strahl und achsenausgerichtetem Rechteck/Quader kann schneller berechnet werden als mit Test_for_Ray_Intersection() Schnittpunkte sind einfacher und auf Halbseitentest kann verzichtet werden, und nur Ausdehnung in x-, y- und z-Richtung wird benötigt • Test_Portal_Durchtritt() • Verwendet Seitentest den wir schon kennen (in Verbindung mit Portalen)
Einsatz von achsenausgerichteten Bounding Boxen für die Verbesserung der Performance bei Kollisions- und Schnittpunkttests auf Dreieckbasis • Sind viele Objekte vorhanden deren Kollisionen berechnet werden müssen kommt es ab einem gewissen Grad zu Performance-Problemen (alle Dreiecke müssen auf Kollision getestet werden) • Bounding Boxen bringen hier große Vorteile • Zuerst Treffertest mit Boxen und Waffe durchgeführt • Ist dieser positiv können alle Dreiecke in anderen Boxen vernachlässigt werden • Nur die in der positiv getesteten Box liegenden Dreiecke werden getestet • Treffertest zwischen AABB und Lenkwaffe ist ohne großen Rechenaufwand möglich • Position der Lenkwaffe wird mit den Eckpunkten der Box verglichen
Einsatz von achsenausgerichteten Bounding Boxen für die Verbesserung der Performance bei Kollisions- und Schnittpunkttests auf Dreieckbasis (2) • Bei Schnittpunktberechnung zwischen Strahl und Box wird überprüft ob der Strahl eine der sechs Flächen der Box schneidet • Bei Verwendung von AABB kann Test_for_axis_aligned_Ray_Intersection()- Methode benutzt werden • Praktikabelste Lösung ist eine eigene Klasse zur Erzeugung einer AA Bounding Box anzulegen • Damit AABB korrekt initialisiert werden kann, müssen der Klasseninstanz vor dem Aufruf der Initialisierungmethode die minimalen und maximalen x-, y- und z-Werte übergeben werden
Einsatz von achsenausgerichteten Bounding Boxen für die Verbesserung der Performance bei Kollisions- und Schnittpunkttests auf Dreieckbasis (3) Ermittlung der Eckpunkte der Box 3 Seiten Quelltext Siehe Buch S. 204-208 (Aufruf der CAABB Kollisions- und Schnittpunkttests aus einer 3D Modellklasse heraus)
Kollision zweier 3D Modelle (1) • Kollisionsprüfungen brauchen sehr viel Zeit (wurde schon sehr oft gesagt ) • Dem entgegen wirken Boundingboxen (wurde auch schon oft gesagt ) • Man hat die Wahl diese Boxen in einer einfachen Baumstruktur zu organisieren • Hierarchisches Kollisionsmodell • Oder als einen Satz gleichberechtigter Boxen zu definieren • All-equal Kollisionsmodell • Muss Modellgeometrie möglichst gut wiedergeben
Kollision zweier 3D Modelle (1) • All-equal Kollisionsmodell • Kommt mit wenigen Boxen aus und ist einfach zu implementieren • Ohne weitere Optimierung ist die benötigte Rechenzeit für einen vollständigen Prüflauf an Dreieck-Dreieck Kollisionstests deutlich höher als bei einem hierarchischem Kollisionsmodell • Bei nur 6 Boxen müssten schlimmstenfalls 36 Box-Box -Kollisionstests durchgeführt werden • Bestenfalls nur ein Test
Kollision zweier 3D Modelle (2) • Hierarchisches Kollisionsmodell: • Jedes Dreieck soll von einer Bounding Box umschlossen werden • Baumstruktur • Sollte augeglichen sein • Kommt in der Realität aber fast nie vor • Findet eine Box-Box Kollision statt, wird noch ein Dreieck-Dreieck-Kollisionstest durchgeführt • Zudem kann es vorkommen, dass die zu testende Box des einen Baumes mehrere Boxen eines anderen Baumes schneidet • Dadurch müssen mehrere Testläufe in Kauf genommen werden • Bounding-Box-Kollisionstests • 3D Modelle unterliegen in der Spielerealität ständigen Veränderungen, weshalb der AABB-AABB Kollisionstest nicht angewendet werden kann • Deshalb gibt es eine logische Erweiterung, den OBB-OBB Kollisionstest
Kollision zweier 3D Modelle (2) • Der OBB-OBB Kollisionstest • OB Boxen haben unendlich viele Orientierungsmöglichkeiten • Es ergeben sich nicht weniger als 15 potentielle separierbare Achsen, die nacheinander geprüft werden müssen • Siehe Beispiel S. 210-215 • OBB-OBB Kollisionstest wird genau unter die Lupe genommen und Problemfälle erläutert
Kollision zweier 3D Modelle (2) • AABB-OBB-Kollisionstest • Etwas einfacher aufgebaut, da eine achsenausgerichtete BB eines untransformierten Objektes gegen eine orientierte BB eines transformierten Objektes getestet werden muss • Orientierte BB des transf. Objektes müssen auf die Modellkoordinaten des untransformierten Objektes rücktransformiert werden • Siehe S. 216-219
Kollision zweier 3D Modelle (3) • Ein all-equal Modell im Einsatz • Mit Hilfe einer Methode, aus C_OBB, Init_as_AABB() können achsenausgerichtete BB für die 3D Modelle erzeugt werden • 1. Schritt eines Kollisionstests besteht also darin die BB des einen Objektes (pObject[jj]) auf die Modellkoordinaten des anderen Objektes (pObject[j]) rück zu transformieren • Dafür stehen drei Rotationsmatrizen zur Verfügung:
Kollision zweier 3D Modelle (4) • Im einfachsten Fall werden dann alle ausger. BB des untr. Objektes (pObject[j]) paarweise gegen alle OBB des tr. Obejktes (pObject[jj]) auf mögliche Kollision getestet