PhysicEngine 3.1

  • Hi Leute,


    es ist so weit, nachdem meine Version 2 der Physik Engine so gut angekommen ist, hatte ich die Tage die Motivation eine Version 3 zu schreiben. Diese ist nun viel robuster um unterstützt Positionkorrektur, sodass man ohne Probleme mit Schwerkraft arbeiten kann. Außerdem fangen Körper die sich länger nicht bewegen an zu schlafen, sodass sie Leistung sparen. Aber seht selbst:


    Edit Version 3.1: Ich habe die Version jetzt dahin gebracht, wo Version 3.0 schon sein sollte. Man kann nun ohne Problem Objekte stapeln ohne Fehler, mit Reibung und ohne das sich die Objekt durchdringen. Außerdem wurde die Kollisionhirarchie überarbeitet um die Performence zu steiern. Ich hoffe euch gefällt diese Version nun ;).


    Update: Performance verbessert und Opengl Rendering hinzugefügt, sowie weitere kleine Verbesserungen
    Update2: Bessere Kollisionserkennung, andere Kollisionsverarbeitung, Geschwindigkeitssteigerung, bessere Oberfläche, bessere Kollisionshierarchie, Reibung, Fehler behoben


    Download : autoit.de/wcf/attachment/16514/
    alte Version2: autoit.de/wcf/attachment/16377/
    alte Version: autoit.de/wcf/attachment/16237/


    autoit.de/wcf/attachment/16474/


    es GAB noch kleine Felher mit der Reibung, aber ich arbeite dran ;)

  • Mir sind mehre Sachen aufgefallen...


    Die Körper "Springen" manchmal auseinander.
    (Wenn mehrere Körper auf engem Raum sind springt öfters einer raus, ohne aber die Gruppe zu verlassen)


    Bei Gruppen herrscht starke Unruhe, so stark würde das in echt nicht wackeln.


    Wenn ich das Fenster eine kleine Weile festhalte wirds komisch.
    Dann sind die Positionen teilweise außerhalb der Begrenzung...
    Das liegt (vermutlich) daran, dass die Bewegung für die verlorene Zeit trotzdem ausgeführt wird ohne dabei die kollisionen zu überprüfen.


    Beim klick auf "E" zum löschen erhalte ich folgendes.


    lg
    M

  • Hi,


    danke für die Rückmeldung, wenn du das Fenster festhälst wird nichts berechnet. Lässt du es wieder los wird der nächste zeitschritt berechnet, das heißt die objekte machen einen satz und könnne sich durchdringen. Das kann ich aber noch ändern. Der andere Fehler ist mir auch schon aufgefallen, da muss ich auf jeden fall mal schauen woran das liegt. Ich arbeite gerade noch an einem opengl renderer.


    grüße Moritz

  • Jop. Das liegt daran, weil du die Zeit als Wert benutzt.
    Je niedriger die Framerate desto ungenauer die Kollisionen. (Zum Test kannst du ja mal ein Sleep(100) in dein Beispiel einbauen um es auf 7-8 FPS zu drücken. Dann sieht man, dass die Objekte große Überschneidungsbereiche haben ohne zu "kollidieren")


    Es ist besser intern einen Counter laufen zu lassen und den bei jedem Schleifendurchlauf um 1 zu erhöhen.
    Dann funktioniert die Kollisionskontrolle auf jedem Computer gleich.
    Ansonsten sind die Resultate nicht reproduzierbar...


    Edit:
    Und vermutlich verbessert sich damit auch diese "Unruhe".
    Die entsteht glaube ich durch eingeschaltete Gravitation im Zusammenspiel mit dem Bezug der Bewegung zur Zeit.
    Im Beispiel können Objekte minimal in den Boden eindringen, da die Zeit zwischen den Frames einen Freien fall bedeuten (wenn ich das richtig interpretiere).

  • Mars, ich weiß woran das liegt :D ich habe das extra so gemacht, damit die PhysicEngine bei jedem gleich schnell läuft. Ich denke ich werde aber noch die option einbauen, dass wenn der zeitschritt zu groß ist, zb.größer als 30ms, dass dann ein fester zeitschritt verwendet wird. Außerdem werde ich noch die option einbauen, die winkelgeschwindigkeit und lineare geschwindigkeit zu limitieren.


    aber danke für deine hilfe, wie gefällt dir diese version sonst so?

  • Im Prinzip gefällt sie mir sehr gut.
    Im Download fehlt ein "=" in PhysicEngine_3_Draw.au3 an pos 154.


    Das mit der Zeit ist aber gleichzeitig das größte Problem.
    Ein Programm muss unabhängig von der Ausführgeschwindigkeit zum gleichen Ergebnis kommen.


    Die verlorenen Kollisionen müssen nachberechnet werden.
    Dazu muss überprüft werden ob sich die Richtungsvektoren der einzelnen Objekte (unter berücksichtigung der Gravitation) treffen.
    Gibt es einen Treffer müssen alle betroffenen Objekte neu berechnet werden.
    Anschließend muss wieder überprüft werden, wieder kollidiert werden, usw usw.
    Bis man an Dem Zeitpunkt angekommen ist der Ausgegeben werden soll.


    Daaan ist es möglich diese Engine unabhängig vom System zu benutzen und äquivalente Ergebnisse zu erhalten. (glaube ich^^)

  • Das Problem ist, das die Engine zu langsam ist, um alle Kollisionen nachzuberechnen, weil sie/autoit dafür schlicht zu langsam ist. Man würde nicht wieder im "Jetzt" ankommen :D


    Edit: Danke für die Info über dem Fehler mit dem '=', wobei die funktion eh nicht mehr gebraucht wird

  • Moin,


    hab jetzt auch mal kurz was zusammengeschustert.
    Im Prinzip müsste man (unter Berücksichtigung der Gravitation) für jedes Objekt eine/mehrere Funktionen 2ten grades aufstellen und (im übertragenen Sinn) die Graphen der funktionen (Gleichsetzen) auf Kollision prüfen. Anschließend wird der Zeitpunkt Tx (wir beginnen jeden Frame bei T0. Jeder Zeitpunkt Tx liegt zwischen T0 und T1) der ersten Kollision ermittelt und bis dahin gerechnet. Nachdem alle Vektoren neu berechnet sind gehts zu Ty, usw usw. Bis keine Kollision mehr stattfindet und T1 erreicht ist.


    Das muss man prinzipiell so machen, sollte es wirklich genau sein.
    Aber Feste Regeln/Frame reichen aus um bei gleichen Einstellungen Gleiche Ergebnisse zu liefern. Dazu muss nicht immer alles genau stimmen.
    Um die Ungenauigkeiten etwas kleinzumachen habe ich mir überlegt die Engine intern mehr Zyklen leisten zu lassen als sie anzeigt. (beseitigt effektiv das Ruckeln durch Gravitation).
    (Bis zu einer gewissen Anzahl Zyklen ist der Rechenaufwand geringer als er wäre, würde man das ganze über Funktionsgleichungen lösen)


    Das ganze ist so aufgebaut, dass man das $OBJ problemlos durch eine Struct ersetzen kann. Auf die Mathematik lässt man dann Basic los und schon rollen 500 Kugeln statt 15.
    Die Genauigkeit mit der gearbeitet wird ist in $nStep (0<x>=1) festgelegt. Es empfehlen sich aber Zahlen die 1 so teilen können, dass eine ganze Anzahl Zyklen resultiert. (z.B. 0.25 = 4 Zyklen)



    .
    .

  • Hi, cooles beispiel, ich hatte auch schon daran gedacht, die kollisionen auf dieses weise zu berechnen. Diese berechung mag bei kugel zuwar funktionieren, bei den polygonen erhält man jedoch x = sin(x)/cos(x), was sich nur numerisch lösen lässt oder durch ein approximation zb. mit einem taylor polynom. Weiterhin müsste man festlegen, wie viele iterationen maximal in einer frame passieren dürfen, weil es sonst ehr langsamer als schneller wird. Als nächstes kommt eh erstmal das opengl update und andere verbesserungen und cleanup.


    Nutz jemand sonst diese engine?


    grüße Moritz

  • Hab grade noch was lustiges probiert.
    Bereiche in denen die Gravitation wirkt. (mit beliebigem Vektor).
    Frisst natürlich auch schön CPU^^



    .
    .

  • Freut mich ungemein das du deine Engine wieder in Angriff genommen hast
    Diese Engine bietet ein riesen Potential


    Werd es mir bei genügend Zeit mal genau zur Gemüte führen



    /Ot :
    AutoIt.de hat keinen Thx-Buttons?

  • Hm. Also die letzte Version hat meiner Meinung nach Welten besser funktioniert. Hier fällt mir auf:


    • Objekte rutschen wild hin und her
    • Objekte springen ohne Grund wild durch den Raum, manchmal aber dann völlig ohne Grund
    • Objekte rutschen ineinander, kollidieren tun sie auch viel zu spät, sie überlappen sich fast immer
    • Schnelle Objekte verlassen einfach so den Raum, also durch die Wände. Wenn sich ein Objekt draußen befindet, stehen alle anderen (endlich :D ) still, und lassen sich nicht bewegen
    • Auf Objekte gezeichnete Fadenkreuze bleiben dort gezeichnet, bis sich das Objekt bewegt
    • Im Skript fehlt eine Swap-Funktion, die EXE hat eine unerhörte Breite ;)


    Denke das wird noch :D

  • Version 3 war halt komplett neu geschrieben, und enthält daher noch nen paar bugs, aber ich kann dir sagen, dass diese Version um Welten besser ist ;). Und du kannst die objekte nicht mehr bewegen weil sie "schlafen", wenn du 'w' wie wake drückst, dann gehts wieder

  • Update PhysicEngine Version 3.1

    Bessere
    Kollisionserkennung, andere Kollisionsverarbeitung,
    Geschwindigkeitssteigerung, bessere Oberfläche, bessere
    Kollisionshierarchie, Reibung, Fehler behoben

  • Ich kann das script leider nicht starten..


    PhysicEngine_3_Opengl.au3(297,14) : WARNING: $hBitmap: possibly used before declaration.
    PhysicEngine_3_Polygon.au3(627,141) : ERROR: phys_PolgonGetFarestPointInDirection() called with wrong number of args.
    PhysicEngine_3_Polygon.au3(594,189) : REF: definition of phys_PolgonGetFarestPointInDirection().


    Ich habe AutoIt version 3.3.8.1

  • Jetzt sind es noch mehr:




    Mit einem Klick auf Continue scheint es aber zu funktionieren. Allerdings sind die Objekte nicht mehr mit der Maus beeinflussbar..
    Die Compilierte Version zeichnet nichteinmal irgendwas. Es erscheint einfach nur eine leere Gui. Auf Xp/7 getested..

  • Also, die kompilete Version musste vllt zwei drei mal starten, weiß auch nicht wieso, und wenn du objekte beeinflussen willst musste erstmal in der settings.ini "debug=1" machen. dann kannste objekte mit der rechten maustaste selektieren und dann mit der linken kraft ausüben und wenn die objekte schlafen einfach mit "w" wie wake aufwecken.