Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

V10 - Kollisionen Nicolas Matentzoglu. Inhalt der Präsentation Kollisionserkennung bei Hindernissen Verhalten der Kugel über verschiedenen Untergründen.

Ähnliche Präsentationen


Präsentation zum Thema: "V10 - Kollisionen Nicolas Matentzoglu. Inhalt der Präsentation Kollisionserkennung bei Hindernissen Verhalten der Kugel über verschiedenen Untergründen."—  Präsentation transkript:

1 V10 - Kollisionen Nicolas Matentzoglu

2 Inhalt der Präsentation Kollisionserkennung bei Hindernissen Verhalten der Kugel über verschiedenen Untergründen

3 Beschreibung der physikalischen Eigenschaften der Untergründe struct untergrund { int typ; char *name; float daempfung; }; untergrund mein_untergrund[5] = { { WASSER, "Wasser", 0.6f}, { HOLZ, "Holz", 0.9f}, { STEIN, "Stein", 0.8f}, { GRAS, "Gras", 0.7f}, { ZIEL, "Ziel", 0.9f} };

4 Beschreibung der physikalischen Eigenschaften der Untergründe Der Name dient dem Zweck, eine lesbare Ausgabe der Kugelposition in display_info zu erreichen Daempfung ist der Faktor, um den die Kugelgeschwindigkeit verlangsamt wird, wenn sie auf einen bestimmten Untergrund trifft (Bremswirkung)

5 Beschreibung der Hindernisse struct hindernis { int typ; char *name; float faktor; }; hindernis mein_hindernis[3] = { { 0, "Kegel", 0.9f}, { 1, "Bumper", 2.5f}, { 2, "Markierung", 0} }; Der Faktor gibt an, wie sich der Geschwindigkeitsvektor ändert, wenn die Kugel an ein Hindernis stößt.

6 Die Positionsinformationen der Kugel struct posinfo { int innerhalb; // Ist die Kugel noch im Spielfeld? int zeile; // Spielfeldzeile int spalte; // Spielfeldspalte D3DXVECTOR3 mitte; // Mittelpunkt des Spielfelds float aq; // Das Quadrat des Abstands der Kugel vom Mittelpunkt des Feldes untergrund *ugrnd; // Zeiger auf den Untergrund des Feldes hindernis *hnd; // Zeiger auf ein evtl. Hindernis };

7 Abfrage der Positionsinfos: get_info() (In class spielfeld (public):) void get_info( D3DXVECTOR3 v, posinfo *p); v ist die Position, für die wir uns interessieren In unserer Struktur sollen die Ergebnisse eingetragen werden

8 Abfrage der Positionsinfos: get_info() void spielfeld::get_info( D3DXVECTOR3 v, posinfo *p) { int h; p->spalte = (int)floor((v.x + 2*spalten)/4); // Umkehrung der Berechnung p->zeile = (int)floor((v.z + 2*zeilen)/4); // von verschiebung_x (/z) p->mitte.x = verschiebung_x( p->spalte); // Anwendung der p->mitte.y = 0; // Funktionen verschiebung_x (/_y) auf die Spalte (Zeile) p->mitte.z = verschiebung_z( p->zeile); p->aq = (v.x-p->mitte.x)*(v.x-p->mitte.x)+(v.z-p->mitte.z)*(v.z-p- >mitte.z); // Pythagoras (Quadrat des Abstands vom Mittelpunkt) p->innerhalb = (p->zeile >= 0) && (p->zeile spalte >= 0) && ( p->spalte < spalten); // Zeile und Spalte in gültigem Bereich?

9 Abfrage der Positionsinfos: get_info() if( p->innerhalb) // wenn die Kugel innerhalb liegt { p->ugrnd = mein_untergrund + felder[p->zeile][p->spalte]; // Zeiger auf den Untergrund h = hind[p->zeile][p->spalte]; // Hindernis zunächst in h p->hnd = h != NICHTS ? mein_hindernis + h : 0; // wenn es eins gibt, wird es in p->hnd eingetragen }

10 Ausgabe der Positionsinformationen void balance::display_info() { posinfo p; switch( info) {... case 2: mein_spielfeld.get_info( kugelposition, &p); if( p.innerhalb) {... (SIEHE NÄCHSTE FOLIE) } else mein_directx.display_text( 4, "Kugel ausserhalb"); Break; } }

11 Ausgabe der Positionsinformationen mein_directx.display_text( 4, "Zeile %d, Spalte %d, Abstand zur Mitte %f", p.zeile, p.spalte, sqrtf( p.aq)); // beim dritten Parameter muss noch die Wurzel gezogen werden mein_directx.display_text( 5, "Untergrund %s, Hindernis %s", p.ugrnd->name, // hier wird aus unserer struct der Name geholt p.hnd ? p.hnd->name : "(kein)"); // wenn da keiner steht...

12 Die Kollisionsberechnung Wenn die Kugel in den Bereich eines Kegels tritt, muss der Schnittpunkt der Kugelhülle mit dem Kegelumkreis in der Höhe des Kugelradius berechnet werden Der genaue Auftreffpunkt ist für uns allerdings erst einmal nicht so wichtig

13 Die Kollisionsberechnung Uns interessiert der Punkt, an dem sich beim Aufprall der Mittelpunkt der Kugel befindet Dazu müssen wir berechnen, wann er versucht, den äußeren Radius (siehe letzte Folie) zu durchbrechen Da wir den Radius nur nur näherungsweise brauchen, rechnen wir ihn anhand einer Skizze aus (rechts): 1,615

14 Die Kollisionsberechnung Um den Schnittpunkt einer Strecke mit einem Kreis zu Berechnen, verwenden wir ein iteratives Verfahren, bei dem, ausgehend von Start und Endpunkt der Strecke, der Abstand zum gesuchten Schnittpunkt mit jedem Verfahrensschritt halbiert wird.

15 Die Kollisionsberechnung Wir gehen von einer Strecke aus, die außerhalb des Radius beginnt und innerhalb enden soll. Annahme: Es gibt nur einen Schnittpunkt der Strecke mit dem Kreis Iteration: Es wird ein Punkt P auf halber Strecke ermittelt. Liegt P außerhalb des Radius, ist P der neue Anfangspunkt der Strecke, liegt er innerhalb, der neue Endpunkt

16 Berechnung des Schnittpunkts: void schnittpunkt() Die Paramter der Funktion void_schnittpunkt() void schnittpunkt( D3DXVECTOR3 *s, // Zeiger auf den Vektor in den der // Schnittpunkt später eingetragen wird D3DXVECTOR3 start, // Startpunkt der Strecke D3DXVECTOR3 ziel, // Endpunkt der Strecke D3DXVECTOR3 m, // Mittelpunkt des Kreises float rq // Quadrat des Kreisradius, damit bei der Abstandsberechnung // nicht die Wurzelfunktion verwendet werden muss )

17 Berechnung des Schnittpunkts: void schnittpunkt() void schnittpunkt(..) { D3DXVECTOR3 t; float aq; int n; for( n = 10; n; n) //max. 10 Iterationen (reicht) { // SIEHE NÄCHSTE FOLIE } *s = t; //Rückgabe des gefundenen Punkts }

18 Berechnung des Schnittpunkts: void schnittpunkt() t = (start+ziel)/2.0f; // Mittelpunkt zwischen Start und // Ende wird neuer Testpunkt. aq = (t.x-m.x)*(t.x-m.x) + (t.z-m.z)*(t.z-m.z); // Bestimmung des Abstandsquadrats t von Kreismittelpunkt. if( fabs( aq - rq) < 0.01) // liegt t schon nahe genug an der break; // Kreislinie: Ende des Verfahrens. if( aq > rq) // je nachdem, ob der Testpunkt außerhalb start = t; else // oder innerhalb des Kreises liegt ziel = t; // wird Start- oder Zielpunkt neu bestimmt.

19 Kollision: Die Ablenkung der Kugel Wir müssen den Richtungsvektor an der Normalen am Kollisionspunkt spiegeln Also: Drehung des Richtungsvektors um 180 Grad um die Normale und Richtungsänderung

20 Die Ablenkung der Kugel: kugel_rollen() Berechnung des Zielpunkts, auf den die Kugel (kneu) zusteuert: D3DXMatrixRotationY( &dreh, -drehung); // Kompensation der Spielfelddrehung D3DXVec3TransformNormal( &neu, &kugelgeschwindigkeit, &dreh); // drehung des Geschwindigkeitsvektors mit dieser Matrix kneu = kugelposition + neu; // Addition dieses Vektors mit der aktullen Kugelpsoition mein_spielfeld.get_info( kneu, &pneu); // Positioninformation vom Spielfeld einholen

21 Die Ablenkung der Kugel: kugel_rollen() if( pneu.innerhalb) // wenn die Kugel im Feld ist { //(sonst: kontrollierter Absturz) if( pneu.hnd && (pneu.aq < 2.6f)) // gibt es ein Hindernis? // Kommt die Kugel um den Mittelpunkt { // des Hindernisses an (1.615hoch2=2.6)? if( pneu.hnd->typ == MARKIERUNG) // wenn es sich um { // eine Markierung handelt... mein_spielfeld.hind[pneu.zeile][pneu.spalte] = NICHTS; mein_spielfeld.anzahl_markierungen--; //entferne diese und } //rechne die Zahl der im Spiel befindlichen Markierungen runter

22 Die Ablenkung der Kugel: kugel_rollen() else // wenn es sich nicht um eine Markierung handelt { schnittpunkt( &s, kugelposition, kneu, pneu.mitte, 2.6f); neu = s – kugelposition; rachse = s – pneu.mitte; // Vektor vom Mittelpunkt (kreis) zum Schnittpunkt rachse.y = 0; D3DXMatrixRotationAxis( &reflect, &rachse, D3DX_PI); // dreh 180 D3DXVec3TransformNormal( &kugelgeschwindigkeit, &kugelgeschwindigkeit, &reflect); // Kugelgeschw. Mit // Rotationsmatrix gedreht kugelgeschwindigkeit = -pneu.hnd->faktor*kugelgeschwindigkeit; // Richtung wir umgekehrt (-) und entsprechend des Faktors verändert kugelgeschwindigkeit.y = 0;}

23 Die Ablenkung der Kugel: kugel_rollen() else if(pneu.ugrnd->typ == WASSER) { //ist der Untergrund Wasser pneu.mitte.y = -1; // wird die Position der Kugel um eins nach unten verändert. neu = (pneu.mitte – kugelposition)/4; } // ein Viertel der Strecke zum // Ruhepunkt (mitte des Feldes) wird noch zurückgelegt else if((pneu.ugrnd->typ == ZIEL) && (pneu.aq < 1.0f)) { // wenn Ziel neu = (pneu.mitte – kugelposition)/4; } // das selbe wie gerade kugelgeschwindigkeit.x = pneu.ugrnd->daempfung* (kugelgeschwindigkeit.x – kippx); kugelgeschwindigkeit.z = pneu.ugrnd- >daempfung*(kugelgeschwindigkeit.z – kippz); } // Änderung der Kugelgeschwindigkeit entsprechend der // Materialeigenschaften.

24 Die Ablenkung der Kugel: kugel_rollen() else // wenn die Kugel außerhalb des Feldes liegt { kugelgeschwindigkeit.x *= 0.95f; kugelgeschwindigkeit.y -= 0.05f; // kontrollierter Absturz kugelgeschwindigkeit.z *= 0.95f; } kugelposition += neu; // das zuvor berechnete Wegstück hinzu.. D3DXVec3Cross( &kippachse, &neu, &D3DXVECTOR3( 0, 1, 0)); // dann wird die Kugel bewegt v = D3DXVec3Length( &neu); //Drehung der Kugel wie gehabt D3DXMatrixRotationAxis( &dreh, &kippachse, -v); D3DXMatrixMultiply(&kugelrotation, &kugelrotation, &dreh); }

25 Ende Hinweis auf das Referat nächste Woche: Kollisionserkennung und Meshes Kollisionserkennung bei komplizierteren Strukturen


Herunterladen ppt "V10 - Kollisionen Nicolas Matentzoglu. Inhalt der Präsentation Kollisionserkennung bei Hindernissen Verhalten der Kugel über verschiedenen Untergründen."

Ähnliche Präsentationen


Google-Anzeigen