140 likes | 299 Views
Simulation physikalischer Einflüsse. Simulation physikalischer Einflüsse. Geschosse und deren Flugbahnen Simulation von Reibungseinflüssen Modellierung besonderer physikalischer Eigenschaften, bspw. „Schwarze Löcher“ und Gravitationsschockwellen. Grundsätzliches.
E N D
Simulation physikalischer Einflüsse • Geschosse und deren Flugbahnen • Simulation von Reibungseinflüssen • Modellierung besonderer physikalischer Eigenschaften, bspw. „Schwarze Löcher“ und Gravitationsschockwellen
Grundsätzliches • Gute Bewegungsmodelle fördern den Realismus eines Spiels. • Voraussetzung für gute Bewegungsmodelle: Klärung, welche Bewegungsfreiheitsgrade ein Objekt haben kann (in Translations- und Rotationsbewegungen)? • Sind diese voneinander abhängig oder unabhängig?
Geschossflugbahnen • Simulation der Flugbahn durch • Berechnung der Anfangsgeschwindigkeit • Berücksichtigung von Wind und Erdanziehung • Überprüfung, ob etwas getroffen wurde
Geschossflugbahnen Anfangsgeschwindigkeit = muendungsgeschwindigkeit* flugrichtung muendungsgeschwindigkeit : Vektorbetrag; abhängig von der Kanone flugrichtung: Ausrichtung der Kanone in drei Dimensionen, entspricht Definition der Polarkoordinaten einer Kugel: Eigenverschiebung.x = velocity*cosf(Anstellwinkel)* sinf(Schwenkwinkel); Eigenverschiebung.y = velocity*sinf(Anstellwinkel); Eigenverschiebung.z = velocity*cosf(Anstellwinkel)* cosf(Schwenkwinkel);
// Wenn Kanone geladen ist, dann kann sie abgefeuert werden: if(Cannon_loaded == TRUE) { // Kanone kann abgefeuert werden mit: Fire_Cannon = TRUE; } // Wenn Kanone abgefeuert wird: if(Fire_Cannon == TRUE && Cannon_fired == FALSE) { // Anfangsgeschwindigkeit initialisieren Eigenverschiebung.x = velocity*cosf(Anstellwinkel)* sinf(Schwenkwinkel); Eigenverschiebung.y = velocity*sinf(Anstellwinkel); Eigenverschiebung.z = velocity*cosf(Anstellwinkel)* cosf(Schwenkwinkel); Cannon_fired = TRUE; Fire_Cannon = FALSE; Treffer = FALSE; Load_Cannon = TRUE; // Kanone neu laden } // Wenn Kanone abgefeuert wurde und das Geschoss unterwegs ist: if(Cannon_fired == TRUE) { if(Eigenverschiebung.y > y_velocity_Max) Eigenverschiebung.y -= g*FrameTime; Eigenverschiebung += Wirkungsfaktor*Windgeschwindigkeit; Verschiebungsvektor = Eigenverschiebung*FrameTime-PlayerVerschiebung; // Überprüfung von eventuellen Treffern if(Treffer == TRUE) Cannon_fired = FALSE; }
Reibung • Haftreibung (Bodenhaftung) muss immer überwunden werden, um ein Objekt in Bewegung zu versetzen. -> bestünde diese nicht, würde jede noch so kleine Beschleunigung zu Bewegung führen. • Gleitreibung, Kraft, die alle bewegten Objekte gleichmäßig abbremst. -> befindet sich ein Objekt in Bewegung, betrachten wir nur noch die Gleitreibung. (stark idealisierte Bedingungen, da Bodenbeschaffenheit außer acht gelassen wird, Berücksichtigung durch Reibungskoeffizienten) Eigenverschiebung += Reibungsbeschleunigung; Reibungsbeschleunigung = Reibungskoeffizient * - BewegungsrichtungReibungskoeffizient = μ * g , wobei μ materialabhängig ist. Hier ist der Spieldesigner gefragt!
Reibungskräfte in verschiedenen Ebenen • Horizontale Ebene:Nur die Reibung wirkt der Zugkraft entgegen: Reibungsbeschleunigung = Reibungskoeffizient * -Bewegungsrichtung; • Schiefe Ebene: Es wirkt eine Gegenkraft, zusammengesetzt aus Reibung und Hangabtriebskraft, die sich über Winkelfunktionen berechnen lassen: Gegenbeschleunigung = (Reibungskoeffizient*sinf(a)+g*cosf(a))* -Bewegungsrichtung;
Rasante Kurvenfahrt Zentrifugalbetrag=Masse*Geschwindigkeitsbetrag*Lenkgeschwindigkeit; if(Zentrifugalbetrag > Bodenhaftung) { // Driftbewegung } • Weil die Driftbewegung senkrecht zur Fahrtrichtung und Drehachse ist, ist sie gleich dem Kreuzprodukt dieser drei Vektoren: D3DXVec3Cross(&Driftrichtung, &Drehachse, &Fahrtrichtung); • Die Driftbeschleunigung ergibt sich jetzt aus der Differenz von Fliehkraft und Gleitreibung: Driftbeschleunigung =(Zentrifugalbetrag-Gleitreibung)/Masse*Driftrichtung;
Ein schwarzes Loch ... Das newtonsche Gravitationsgesetz besagt, dass sich die Gravitationskraft F, mit der sich zwei Massen m1 und m2 anziehen, proportional zu den Massen beider Körper und umgekehrt proportional zum Quadrat des Abstandes r der Massenschwerpunkte verhält ... Vereinfachung! Richtung = Ortsvektor_schwarzesLoch – Ortsvektor_Raumschiff; Entfernung = NormalizeVector(&Richtung, &Richtung); acceleration_betrag = Masse_SchwarzesLoch/(Entfernung*Entfernung);// G=1, damit gibt’s aber auch keine Masse in Kilogramm Eigenverschiebung += acceleration_betrag*FrameTime*Richtung;
Modellierung von (Gravitations-)Schockwellen // Initialisierung der ersten Schockwelle: Schockwelle_Entstehungszeit = GetTickCount()+lrnd(300000, 600000); Schockwelle_LebensdauerMax = lrnd(10000, 20000); Schockwelle_Wirkungsdauer = lrnd(2000, 5000); Schockwelle_Masse = frnd(1000.0f, 10000.0f); Schockwelle_Lebensdauer = 0; Schockwelle_aktiv = FALSE // Irgendwo im Quellcode: actual_time = GetTickCount(); if(Schockwelle_aktiv == FALSE) { if(actual_time >= Schockwelle_Entstehungszeit) Schockwelle_aktiv = TRUE } if(Schockwelle_aktiv == TRUE) { // Berechnung der momentanen Lebensdauer der Schockwelle: Schockwelle_Lebensdauer=actual_time-Schockwelle_Entstehungszeit if(Schockwelle_Lebensdauer < Schockwelle_LebensdauerMax) { Richtung = Ortsvektor_schwarzesLoch – Ortsvektor_Raumschiff; Entfernung = NormalizeVector(&Richtung, &Richtung); //Liegt Objekt im Wirkungsbereich der Schockwelle? if(Entfernung < Lightspeed*Schockwelle_Lebensdauer) { if(Entfernung > Lightspeed*(Schockwelle_Lebensdauer- Schockwelle_Wirkungsdauer)){ // Berechnung der Beschleunigung acceleration_betrag = Masse_SchwarzesLoch/(Entfernung*Entfernung); Eigenverschiebung += acceleration_betrag* FrameTime*Richtung; } } } else { // Neue Schockwelle initialisieren Schockwelle_Entstehungszeit=actual_time+lrnd(300000, 600000); Schockwelle_LebensdauerMax = lrnd(10000, 20000); Schockwelle_Wirkungsdauer = lrnd(2000, 5000); Schockwelle_Masse = frnd(1000.0f, 10000.0f); Schockwelle_Lebensdauer = 0; Schockwelle_aktiv = FALSE } }