Nichtlineare Bewegung

Einstiegsfragen, Mathematik, Physik, künstliche Intelligenz, Engine Design
Antworten
Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Nichtlineare Bewegung

Beitrag von Zudomon » 26.03.2009, 19:35

Hi!

Vielleicht könnt ihr mir auch bei diesem Problem helfen:
Eine lineare Bewegung auf die Zeit abzustimmen ist ja kein Problem... da wird ja einfach das Timedelta mit dem Wert multipliziert.
Aber wie ist es, wenn eine Art Abbremsung realisieren möchte:
v = v * 0.9

Wie bekomme ich da meine Timedelta mit rein? Gibt es dafür eine einfache Lösung oder muss ich da schon mit Beschleunigung und Geschwindigkeit rann?

MfG
Zudomon

TomCat
Beiträge: 10
Registriert: 02.03.2002, 10:29

Re: Nichtlineare Bewegung

Beitrag von TomCat » 26.03.2009, 19:48

Bei einer konstanten Beschleunigung (Abbremsung ist auch ne Beschleunigung, nur andere Richtung, Musst Du einfach die Geschwindigkeit pro Zeiteinheit um immer den gleichen Wert add/subtrahieren) Die höhe des Wertes ergibt sich aus Zeitdelta mal gewünschter Beschleunigung.

ciao,
TomCat
Schnelle Autos !
Schnelle Frauen !
Schneller Code !

knivil
Beiträge: 14
Registriert: 03.04.2008, 01:03

Re: Nichtlineare Bewegung

Beitrag von knivil » 26.03.2009, 20:10

Wie sieht denn deine Bewegungsgleichung aus? Also hast du mehr anzubieten als v = 0.9 * v? Wie gross ist denn dein dt, fuer das die Gleichung gilt.

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 26.03.2009, 20:15

Mehr anzubieten habe ich nicht... bis jetzt habe ich sowas halt benutzt, um die Kamerabewegung etwas gleiten zu lassen. Da kam es dann auf eine perfekte Gleichung nicht an, sondern sollte einfach nur gut aussehen. Aber wenn die FPS steigen, dann ist die Bewegung natürlich verfälscht. Aber was TomCat sagt, hört sich gut an... das werde ich probieren... aber erstmal noch ein paar andere Probleme lösen ;)

Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 22:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von CodingCat » 26.03.2009, 20:23

Hm, ich verstehe dein Problem nicht. Wenn du eine bestimmte Geschwindigkeit v hast, dann berechnest du deine nächset Position wohl mit x += v * d_t, wobei d_t die verstrichene Zeit seit dem letzten Frame ist. Selbes kannst du nun auf die Geschwindigkeit anwenden, d.h. du behälst die Bewegungsgleichung bei und veränderst zusätzlich jedes Frame v. Wenn du lineare Beschleunigung haben willst, geht das analog zur Bewegung mit v += a * d_t, wobei a für Bremsen natürlich negativ wäre, für Beschleunigen positiv. Alternativ könntest du auch noch exponentielle Beschleunigung / Bremsung versuchen, mit v *= pow(f, d_t). Das wirkt als ganz cool, wenn du die Geschwindigkeit sehr schnell anpassen möchtest, aber trotzdem einen weichen Übergang beibehalten willst.
Diese Art der Beschleunigung / Bremsung habe ich z.B. hier eingesetzt: http://vimeo.com/3435479 (Video, eher gegen Ende sichtbar)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 26.03.2009, 20:29

Ich schätze mal, dass da auch kein echtes Problem hinter steckt. Hab halt nur noch nicht so ganz den zusammenhang verstanden gehabt...
Werde das nun mal versuchen umzusetzen!

Dein Video ist sehr nice... vor allem das SSAO sieht ganz gut aus! :D

Benutzeravatar
Schrompf
Moderator
Beiträge: 4051
Registriert: 26.02.2009, 00:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Schrompf » 26.03.2009, 22:01

Die pow-Methode ist die korrekte. Wenn Du vorher pro meinetwegen 20ms ein v *= 0.9 ausgeführt hast, wäre die korrekte Formel für beliebige Zeitdifferenzen ein v *= pow( 0.9, zeitdiff / 0.02sek)
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 27.03.2009, 10:26

Ich hatte das gestern noch probiert mit dem, was vorher gesagt wurde. Das ganze kann man ja eigentlich für Partikelsimulationen verwenden. Allerdings klappt das bei der Kamerasteuerung überhaupt nicht.

Die Lösung von Schrompf ist genau das, was ich brauchte!! Ich hatte mir damals eine Lösung erarbeitet, die fast genauso aussah:
v *= pow(0.9, zeitdiff)
Allerdings funktionierte das auch nur beschränkt. Ich hatte da zwar erkannt, dass man jede Sekunde das v mit 0.9 multipliziert, aber um das schneller schwinden zu lassen habe ich dann die 0.9 immer kleiner werden lassen... z.B. auf 0.00001... so richtig funktionierte das dann alles nicht mehr...
Das man zeitdiff einfach noch durch die gewünschte Schrittweite teilt, darauf bin ich nicht gekommen! Danke dafür! :D


===== NACHTRAG =====

Nein, zu früh gefreut... komischerweise ist das alles immer noch Frameabhängig.
Ich beschreibe mal, was ich mache und zwar beim strafen mit der Maus:

Code: Alles auswählen

  if MButtonL and MButtonR and not MButtonM then begin
    CamMove.add(AxisHorizontal.GetAxisY * yPosRelative * -speedP);
    CamMove.add(AxisHorizontal.GetAxisX * xPosRelative *  speedP);
  end;

  xPosRelative:=0;
  yPosRelative:=0;

  l := power(lng(CamMove),0.3)*0.25;
  Campos := Campos + CamMove * l;
  CamMove.scl(power(0.5, Clock.Delta / 0.01 ));

//  sleep(20);

In CamMove wird das Mausdelta übertragen und skaliert. Anschließend das Mausdelta auf 0 gesetzt. Dann berechne ich mir ein l aus der Länge von CamMove. Dieser Wert wird mit CamMove multipliziert. Das ganze ist dafür da, damit man sich weiter fortbewegt, wenn man die Maus schneller bewegt.
Anschließend wird das CamMove runterskaliert mit der von Schrompf vorgeschlagenen Formel.

Ich habe da ( bis jetzt noch ) über 1000 FPS und das ganze klappt perfekt... Wenn ich allerdings das "sleep(20)" da rein mache, wird meine Bewegung zu langsam. Also das fühlt sich dann garnicht mehr an, wie vorher.

Weiß noch jemand Rat?

Benutzeravatar
Schrompf
Moderator
Beiträge: 4051
Registriert: 26.02.2009, 00:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Schrompf » 27.03.2009, 13:08

Das hat ja mit der Dämpfung aus dem Orginalbeitrag nix mehr zu tun. Du hast schlicht vergessen, auch bei CamPos += irgendwas * CamMove noch die Zeitdifferenz einzuberechnen. Auch CamMove muss mit der Zeitdifferenz skalieren.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 27.03.2009, 13:20

Stimmt, mit der Dämpfung hat das nichts mehr zu tun und müsste auch perfekt funktionieren.

Die Frage ist nun nur noch, wie ich das ganze Konstrukt Zeitabhängig bekomme.
Du sagst, CamMove muss mit der Zeitdifferenz skalieren.
Aber wie? CamMove ist ja von der Maus abhängig. Also angenommen man bewegt die Maus um 20 Pixel, das wird dann in einem Frame gemessen und wieder zurückgesetzt. Nun rechnet man die Zeitdifferenz in CamMove mit ein. So würden z.B. 3 Pixel an effektivbewegung übrig bleiben, allerdings fehlen ja nun 17 Pixel.

Ich würde behaupten, dass die Mausbewegung an sich ja schon eine Integration über das TimeDelta des Frames darstellt und deswegen nicht mehr mit dt multipliziert werden darf.

Benutzeravatar
Schrompf
Moderator
Beiträge: 4051
Registriert: 26.02.2009, 00:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Schrompf » 27.03.2009, 13:50

Hmm... eigentlich hast Du Recht. Die Mauskoordinaten bzw. deren Differenz ist ja bereits zeitskaliert. Wenn Du seltener abfragst, bekommst Du größere Differenzen.

Ich ging dort davon aus, dass das die typische "Pos = Pos + zeitdiff * Geschwindigkeit" Formel wäre. Allerdings war das nur unvollständig gelesen, sehe ich gerade. Ich weiß jetzt nicht genau, was Du da überhaupt vorhast. Wie soll die Steuerung sich denn verhalten?

Und ganz am Ende könnte Dein aktueller Fehler auch nur ein Messfehler sein: dass Du zwar ein sleep(20) eingebaut hast, aber Deine Zeitmessmethode diese 20ms nicht enthält, weil Du z.B. die Zeitmessung pro Frame schon vorher nimmst... schau da mal nach, das wär eine ebenso schlichte Vermutung.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 27.03.2009, 14:27

Leider funktioniert die Zeitmessung korrekt, weil ich darüber auch die FPS berechne. Und das kommt alles hin.

Es ist schwer das Bewegungsverhalten zu beschreiben. Also erstmal soll sie ziemlich genau die Mausbewegung übertragen. Zudem soll die Bewegung größer sein, wenn man die Maus schneller bewegt. Und das ganze soll noch irgendwie weich sein.

Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 14:27

Re: Nichtlineare Bewegung

Beitrag von eXile » 27.03.2009, 14:33

De-factor ist doch sowas eigentlich nur ein iterativer Löser für eine Gleichung (häufig Differentialgleichung mit Anfangswertbedingen). Jeder Frame ist ein Iterationsschritt des Lösers. Dementsprechend müsste man auch Ansätze wie Runge-Kutta-Integration pro Frame durchführen können, und man müsste bessere Ergebnisse bekommen, als "einfach mit dem Zeitdelta zu multiplizieren".

Passend zum Thema: Erlaubt ist alles, solange nicht sowas bei rauskommt ;)

Benutzeravatar
Krishty
Establishment
Beiträge: 7253
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Krishty » 27.03.2009, 14:55

Zudomon hat geschrieben:Es ist schwer das Bewegungsverhalten zu beschreiben. Also erstmal soll sie ziemlich genau die Mausbewegung übertragen. Zudem soll die Bewegung größer sein, wenn man die Maus schneller bewegt. Und das ganze soll noch irgendwie weich sein.
„Mafia“ *schwärm* hatte so ein Mausverhalten. Damit konnte man hochpräzise zielen, sich aber dennoch sehr schnell umdrehen.

Wenn es nur um die Drehung geht, fallen mir zwei Methoden ein (die letzte würde ich bevorzugen):

a) Anhand der Framezeit und der Mausbewegung bestimmen, wieviel Grad (oder Bogenmaß, je nachem) pro Sekunde sich der Betrachter drehen möchte. Den Wert quadrieren. Dann werden kleine Mausbewegungen sehr klein, hastige Bewegungen sehr groß. Hat den Nachteil, dass die Bewegung abrupt aufhört, wenn auch der User aufhört die Maus zu bewegen.

b) Eine „virtuelle“ Drehung speichern, die exakt den unbearbeiteten Mauskoordinaten entspricht. Die „reale“ Drehung, die du anzeigst, ergibt sich zu jedem Zeitpunkt aus einer Interpolation zwischen der realen und der virtuellen Drehung. Benutzt du für die Interpolation kleine Werte, wird die virtuelle Drehung immer weiter von der angezeigten Drehung abweichen. Dadurch wird die reale Drehung sanft immer größer. Wenn die Maus still steht, nähert sich die angezeigte Drehung immer weiter der virtuellen an und die Drehung kommt dadurch sanft zum Stillstand. Die angezeigte Drehung dürfte dann exakt eine Bézierkurve mit der virtuellen Drehung als Kontrollpunkten sein, die Kamera verhält sich dann, als besäße sie Trägheit und würde durch den Cursor gezogen.

Ich werde letzteres gleich selbst mal implementieren, um zu gucken, wie es aussieht.

Gruß, Ky

Edit: Gerade implementiert. Bei einem Faktor von 0.2 ist es SO weich, dass es schon fast wehtut. Bei 0.5 ist alles großartig glatt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne

knivil
Beiträge: 14
Registriert: 03.04.2008, 01:03

Re: Nichtlineare Bewegung

Beitrag von knivil » 27.03.2009, 17:27

Aber wenn die FPS steigen, dann ist die Bewegung natürlich verfälscht.
Wie waere es denn erstmal mit einem FPS unabhaengigen Gameloop?

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 27.03.2009, 18:24

knivil hat geschrieben:
Aber wenn die FPS steigen, dann ist die Bewegung natürlich verfälscht.
Wie waere es denn erstmal mit einem FPS unabhaengigen Gameloop?
Im Notfall wird mir da nichts anderes übrig bleiben. Sollte man ja für Physikberechnungen und dergleichen eigentlich auch machen.
Krishty hat geschrieben:Edit: Gerade implementiert. Bei einem Faktor von 0.2 ist es SO weich, dass es schon fast wehtut. Bei 0.5 ist alles großartig glatt.
Weich bekomme ich das ja auch, aber ebend nicht FPS unabhängig, da liegt das Hauptproblem.

Benutzeravatar
Krishty
Establishment
Beiträge: 7253
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Krishty » 27.03.2009, 18:54

Zudomon hat geschrieben:Weich bekomme ich das ja auch, aber ebend nicht FPS unabhängig, da liegt das Hauptproblem.

Code: Alles auswählen

// Die virtuelle Rotation deiner Kamera.
const float l_fVirtualXRotation = …;
const float l_fVirtualYRotation = …;

// In einer Sekunde soll sich die Kamera zu 99% an die virtuelle Position (die Zielposition) anpassen.
const float l_fCameraInertiaPerSecond = 1.0f - 0.99f;

// Füllst du mit der erwarteten Zeit dieses Frames, in Sekunden.
const float l_fFrameTimeInSeconds = …;

// Gibt an, wie stark sich die Kamera ergo innerhalb dieses Frames an die Zielposition anpasst.
const float l_fThisFramesCameraInertia = ::pow(l_fCameraInertiaPerSecond, l_fFrameTimeInSeconds);

// Jetzt bloß noch wie gehabt interpolieren …
const float l_fXRotation = (l_fVirtualXRotation * (1.0f - l_fThisFramesCameraInertia)) + (l_fXRotation * l_fThisFramesCameraInertia);
const float l_fYRotation = (l_fVirtualYRotation * (1.0f - l_fThisFramesCameraInertia)) + (l_fYRotation * l_fThisFramesCameraInertia);
Habe es mit 40 und vier fps getestet.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 27.03.2009, 19:24

Stimmt, so ist das weich und Zeitunabhängig! Super! Danke für den Code!

===== NACHTRAG =====
Wenn man das so für die Position nimmt, klappt das auch gut.
Das einzigste, was jetzt noch rein müsste, wäre, dass man sich schneller bewegt, wenn man schneller die Maus bewegt.

Helmut
Establishment
Beiträge: 231
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Helmut » 27.03.2009, 22:02

Wahrscheinlich willst du das jetzt nicht hören, aber ich würde solche Sachen nicht fps unabhängig programmieren. Zum einen ist es ziemlich anstrengend und aufwendig (manchmal sogar unmöglich) sowas so zu programmieren, zum anderen verlierst du so den Determinismus und erschwerst zB die Kollisionsberechnungen erheblich.
Eine feste FPS mit Frameskip hat eigentlich kaum Nachteile finde ich:)

Ciao

Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 14:27

Re: Nichtlineare Bewegung

Beitrag von eXile » 28.03.2009, 00:53

IMHO gibt es gerade bei Multiplayerspielen häufig eine Obergrenze (z.B. bei Doom 3 60 Hz). Das liegt daran, dass gerade wenn neben Physik und KI auch noch Netzwerk mit reinspielen, ganz komische Nebeneffekte auftreten können.

Benutzeravatar
Krishty
Establishment
Beiträge: 7253
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Krishty » 28.03.2009, 14:01

Zudomon hat geschrieben:Das einzigste, was jetzt noch rein müsste, wäre, dass man sich schneller bewegt, wenn man schneller die Maus bewegt.
Das müsste aber selbst bei simpelsten Implementierungen der Mausbewegungen der Fall sein … wie berechnest du denn die Rotation/Position aus der Mausbewegung?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 28.03.2009, 14:09

Krishty hat geschrieben:
Zudomon hat geschrieben:Das einzigste, was jetzt noch rein müsste, wäre, dass man sich schneller bewegt, wenn man schneller die Maus bewegt.
Das müsste aber selbst bei simpelsten Implementierungen der Mausbewegungen der Fall sein … wie berechnest du denn die Rotation/Position aus der Mausbewegung?
Klar, an sich ist das ja drin... also wenn man in einem Frame die Maus 10 Pixel bewegt, dann ist sind es auch nur 10 Einheiten, die bewegt werden... bei 20 Pixel ebend dann 20 Einheiten...
Was ich jetzt da noch gerne hätte wäre, das wenn man innerhalb von 0.1 Sekunden die Maus 10 Pixel bewegt, dass das z.B. dann nur halb so weit ist, wie wenn man die Maus 10 Pixel innerhalb von 0.05 Sekunden bewegt.

Vielleicht ist das alles übertrieben, das mal so exakt zu erörtern, aber ich würde es gerne mal "richtig" implementieren. ;)

Gruß
Zudomon

Benutzeravatar
Krishty
Establishment
Beiträge: 7253
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Krishty » 28.03.2009, 14:20

Achso, jau, das ist dann das, was in den meisten Games als nichtlineare Bewegung tituliert wird … ganz einfach :)
Du berechnest aus der Mausbewegung und der aktuellen Frame-Zeit, um wieviel Einheiten (Grad oder Bogenmaß oder Meter) sich die Maus pro Sekunde bewegt … den Wert potenzierst du dann (Quadrat müsste reichen, aber kannst gerne experimentieren, interessiert mich auch) … multiplizierst dann wieder mit der Frame-Zeit und das ist dann die „neue“ Mausbewegung, mit der du im gewohnten Mechanismus weiter rechnen kannst.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 28.03.2009, 15:20

Okay :D
Ich werde mich da gleich nochmal rannsetzen...
Krishty hat geschrieben:...als nichtlineare Bewegung tituliert wird.
Da bin ich ja froh, dass der Threadname dann doch nicht so falsch gewählt war!

Ich schätze mal, um die Mauswegung dann richtig zu erfassen, sollte man dann so einen fließenden Mittelwert ( oder wie das heißt ) einsetzen...

Benutzeravatar
Krishty
Establishment
Beiträge: 7253
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Krishty » 28.03.2009, 15:29

Ja, wenn bei hohen Frameraten die Mausbewegung immer nurnoch entweder null oder ein Pixel groß ist, wird das Verhalten wieder linear … dann über mehrere Frames zählen. Bis 100fps sollte es aber gut funktionieren.

So extrem wie Helmut, dass man mit einer fixen Framerate arbeiten soll, sehe ich es zwar nicht – aber Bildwiederholraten über der Monitor-Aktualisierungsrate sind imho von Spezialanwendungen und Tests abgesehen Schwachsinn. Von daher würde ich den Mehraufwand für das Abdichten so hoher Framerates überhaupt nicht eingehen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 28.03.2009, 16:45

Irgendwie habe ich das Gefühl, ich bin zu dumm.
Also den gleitenden Mittelwert habe ich nun... gezählt wird das mittel der Differenz der Maus über 0.1 Sekunden. Nun das ganze zum Quadrat und diesen Wert mit der Mausverschiebung multiplizieren. Das funktioniert wunderbar... bei 1000 FPS... bei 100 ist wirkt die exponentiale Komponente viel stärker... wenn ich nun noch einfach das TimeDelta rein multipliziere bringt das auch nichts...

Bei der normalen Mausverschiebung darf man das Timedelta nicht mit rein multiplizieren, weil das durch die Art der Datenerfassung schon passiert ist. Wenn man nun den Mittelwert über 0.1 Sekunden berechnet, ist das ja auch schon eine entsprechende Integration und vom Gefühl her würde ich sagen, dass man da ebenfalls kein TimeDelta reinmultiplizieren darf.

Benutzeravatar
Krishty
Establishment
Beiträge: 7253
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Krishty » 28.03.2009, 17:28

Du hast es also doch so implementiert … sind mehr als 100 fps denn wirklich soooo wichtig? Und du bist auch noch irgendwie total mit den Größen durcheinander gekommen …

Also, von Anfang an:

Du berechnest den gleitenden Mittelwert der Mausbewegung. Der Wert liegt dann – wie jede Mausbewegung – in Pixeln vor. (Floats benutzen!)

Durch die Division durch die Framezeit berechnest du die aktuelle Bewegungsgeschwindigkeit der Maus in Pixeln÷Sekunden.

Dann korrigierst du diesen Wert nach deinen Vorlieben (z.B. quadrieren).

Das multiplizierst du wiederum mit der Rotationsempfindlichkeit des Betrachters in Bogenmaß÷Pixel. Das Ergebnis ist die Rotation des Betrachters in Bogenmaß÷Sekunde.

Diesen Wert multiplizierst du mit der aktuellen Framezeit. Das Ergebnis (Bogenmaß) ist die Rotation, die du zu der des vorherigen Frames aufaddierst (bzw zur „virtuellen“ Rotation, wenn man unseren Glättungs-Mechanismus berücksichtigt).

Da wird nichts quadriertes mit der Mausbewegung multipliziert. Darum bin ich übrigens dafür, Dimensionsanalyse standardmäßig allen Programmiersprachen hinzuzufügen … ;)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne

Benutzeravatar
Zudomon
Establishment
Beiträge: 2136
Registriert: 25.03.2009, 08:20
Kontaktdaten:

Re: Nichtlineare Bewegung

Beitrag von Zudomon » 28.03.2009, 18:09

Danke für die ausführliche Beschreibung. Ich will es noch nicht beschwören, aber ich glaube, jetzt funktioniert es.
Allerdings gibt es da noch ein paar Stolperfallen:

Der gemittelte Mittelwert, da darf man nicht durch die Anzahl der Samples teilen ( was mein Problem war ). Also speichert sich alle Datenwertepaare XY und den Zeitstempel, am besten in einem Ringarray. Dann durchläuft man dieses und summiert alle XY Paare, die kleiner als der gewünschte Zeitbereich ist.
Außerdem summiert man die Länge aller XY Paare, um diese "Beschleunigung" nicht Richtungsabhängig zu haben.

Der 2D Vektor der summierten Paare wird normalisiert, damit man eine gemittelte Richtung der Mausbewegung bekommt. Der Längenwert wird wie Krishty schon sagte,
erstmal durch die betrachtete Zeit geteilt, um die Änderung auf Sekunden um zu rechnen, und dann den Bedürfnissen angepasst... z.B. quadriert und skaliert.
Anschließend wird die Länge auf das TimeDelta des Frames runterskaliert und mit der gemittelten Richtung multipliziert.

Das Ergebnis dann auf die echte Rotation aufaddiert. Die virtuelle Rotation kann dann durch die vorgeschlagene weiche interpolation ermittelt werden.
Danke für eure Hilfe!! Ich probier das jetzt noch ein wenig aus, in der Hoffnung, diesmal endlich am Ziel zu sein. :D

Für alle, die sich fragen, warum denn diese exponentielle Bewegung: Ich will dadurch erreichen, dass man durch Rotation jeden Punkt mit der Maus ansteuern kann... was bei einer linearen Übertragung nicht Möglich ist.

Edit: Funktioniert nach ein paar weiteren Tests auf jeden Fall immernoch stabil. Bei 100, wie 1000 FPS alles super! Auch für die Postionierung der Kamera ist geeignet. Habe übrigens erstmal einen kleinen Wert von 1.25 als Exponent genommen. Cool ist auch das nun automatisch entstehende MotionBlur durch die flüssige Bewegung. :)

Antworten