v10 - kollisionen nicolas matentzoglu. inhalt der präsentation kollisionserkennung bei hindernissen...

25
V10 - Kollisionen Nicolas Matentzoglu

Upload: fridric-wuthrich

Post on 05-Apr-2015

108 views

Category:

Documents


1 download

TRANSCRIPT

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

V10 - Kollisionen

Nicolas Matentzoglu

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

Inhalt der Präsentation

Kollisionserkennung bei Hindernissen

Verhalten der Kugel über verschiedenen Untergründen

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

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}};

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

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)

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

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.

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

Die Positionsinformationen der Kugel

struct posinfo{int innerhalb; // Ist die Kugel noch im Spielfeld?int zeile; // Spielfeldzeileint spalte; // SpielfeldspalteD3DXVECTOR3 mitte; // Mittelpunkt des Spielfeldsfloat 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};

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

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

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

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 < zeilen) && (p->spalte >= 0) && ( p->spalte < spalten); // Zeile und Spalte in gültigem Bereich?

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

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

}

}

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

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; } }

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

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...

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

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

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

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

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

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.

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

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

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

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

)

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

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

}

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

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.

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

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

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

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

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

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

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

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;}

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

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.

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

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);

}

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

Ende

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