Rollende Kugel mit Textur

  • Dieses Thema soll als Diskussionsort für ein Problem dienen, welches wir kurz in der Shoutbox mit UEZ erörtert haben.

    Auch wenn du ( UEZ) paar Tage nichts von mir gehört hast, war ich nicht untätig.
    Ich habe mir brav FreeBasic angesehen.
    Da aber sowohl die Sprache, als auch die Thematik, für mich Neuland waren, musste ich ein eigenes Programm von Grundauf erstellen um die Sache zu verstehen, anstatt am vorhandenen Skript rumzudoktorn.
    Kurzum: Irgendwann habe ich aber entnervt aufgegeben - FB und ich werden wohl keine Freunde mehr.

    Anstatt mich nun noch mit einer anderen Sprache rumzuschlagen habe ich mir für das Thema good old AutoIt wieder hochgeholt und versucht damit nun zu zeigen wie ich mir das algorithmisch vorstelle, was ich in der Shoutbox beschrieben habe.
    Das ganze hat dann aber auch länger gebraucht, da ich absolut Null Plan von GDI+ hatte.

    Am Ende habe ich aber nun etwas vorzeigbares erstellt was evtl. als Grundlage für weitere Diskussionen und Verbesserungen dienen kann.
    Im Idealfall sind hieran die Mathematik dahinter schon erkennbar, so dass du bestimmte Dinge in dein FB-Programm übernehmen kannst:

    Die Texturdatei liegt im Anhang.

  • Vielen Dank AspirinJunkie :thumbup:

    Das Ganze läuft in Autoit ziemlich langsam ab (liegt in der Natur von Autoit) und mir kommt es vor, dass die Projektion des Bildes auf die Kugel nicht richtig aussieht, aber ich ziehe mir mal deine Mathematik rein. Bin sehr eingerostet, was Vektoren angeht.

    Ich habe den FB Code ein wenig frisiert und allen 15 Kugeln Texturen verpasst, die entsprechend dem Bewegungsvektor angezeigt werden, leider nicht physikalisch immer korrekt. Ich habe eukalyptus ' ASM Sinus / Cosinus verwendet, was zu einem echten Performance Boost gebracht hat. Der Flaschenhals waren Trigonometrie aufrufe in der MapImage2Sphere() Funktion.

    OneDrive: https://1drv.ms/f/s!AiLeZOpaFqSayCvkcMeBwRcp9ySN?e=qYN7qU (Simple 2D Ball Collision - Billiard Opening2.bas / .exe + die Bitmap Dateien 1-15).

    Schade, dass du dich nicht mit FB anfreunden wirst / kannst / willst! Irgendwie gefällt mir die Sprache besser als Autoit.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Sehr interessant. Hier noch eine Idee: Finde eine Transformation um die Einzelpixelrechnung komplett aus dem Spiel zu nehmen.

    Der Texturabdruck dieser Formel ist auch nicht ganz richtig für eine "korrekte" perspektivische Projektion einer Ebene auf eine Kugeloberfläche (Das Abbild ist eine um 45° gedrehte Raute). Da ich hier kein Profi bin ist Folgendes nur eine Vermutung: Die 3x2 Matrizen aus GDI+ werden hierfür wahrscheinlich nicht reichen, weil sie die Verzerrung nicht abbilden können. Dafür müsste man dann doch wieder nichtlineare Elemente einbringen die GDI+ nicht abbilden kann sodass man sie doch von Hand ausrechnen muss... Ist wahrscheinlich im Endeffekt kein Vorteil, aber ganz kurz dachte ich "vielleicht reicht die GDI+ übliche Matrix ja doch". Bin da kein Profi, von daher: Vielleicht bringt die Idee ja irgendwen weiter :D

    Den Texturfootprint kann man mit folgendem Skript einsehen:

    lg

    M

  • mir kommt es vor, dass die Projektion des Bildes auf die Kugel nicht richtig aussieht

    Evtl. kommt dies dadurch zustande, dass derzeit nur die Rotation um die X und Y-Achse implementiert wurde.
    Das sieht erstmal komisch aus, wenn die Geraden in der Textur immer gleich ausgerichtet bleiben.
    Aber für die reine Kugelbewegung ohne Spin gibt es tatsächlich ja auch keine Drehung um die Z-Achse.
    Das werde ich später sicherlich auch noch mit einbauen aber für die Thematik einer rollenden Kugel hier war das noch nicht nötig.

    Der Flaschenhals waren Trigonometrie aufrufe in der MapImage2Sphere() Funktion.

    Und jetzt stell dir vor wie deine Funktion rennen würde, wenn du die trigonometrischen Funktionen auf ein Minimum reduzieren könntest.
    Genau das habe ich ja versucht in meiner Funktion umzusetzen.
    Wenn man eine Kugel mit einem Radius von 25 Pixeln zeichnen lässt, dann sind die einzigen Aufrufe trigonometrischer Funktionen bei mir 25x ein ArcSin - das wars.

    Und wie man schön an Mars Beispiel sieht, ist die Texture-Map starr. Das heißt man kann diese für jede Kugel nur einmal erstellen und braucht dann lediglich die Offsets aufgrund der Rotationen hinzuzufügen. Dann kommt jeder neue Kugelframe komplett ohne trigonometrische Funktionsaufrufe aus.

    Mir ist schon bewusst, dass man sich das Leben viel leichter machen könnte, wenn man mit UV-Mapping da herangeht.
    Aber dann haben wir halt diese exzessive Nutzung von trigonometrischen Funktionen und ich denke unser Anspruch liegt höher ;)

    Der Texturabdruck dieser Formel ist auch nicht ganz richtig für eine "korrekte" perspektivische Projektion einer Ebene auf eine Kugeloberfläche (Das Abbild ist eine um 45° gedrehte Raute).

    Also perspektivisch stimmt das aus meiner Sicht schon erst einmal - Korrekturen sind aber natürlich erwünscht wenn ich daneben liegen sollte.
    Ein wirklicher Fehler steckt aber tatsächlich im Texturemapping - und zwar beim Mapping der Y-Koordinate.
    Wenn dort ein Bereichsüberlauf stattfindet, dann springt er auf die andere Seite (Modulo lässt grüßen).
    Bei der X-Koordinate ist das ja auch so richtig.
    Stattdessen wäre es aber ja für die Y-Koordinate korrekt den Überlauf an der jeweiligen Kante zu spiegeln.
    Oder um es plastisch zu machen: Wenn man die Erde mappt und bei der Arktis über den Nordpol hinaus mappt, dann hat man auf einmal die Antarktis als nächsten Pixel...
    Das passe ich natürlich unbedingt noch an - ist mir bei dieser symmetrischen Textur hier nicht aufgefallen.

  • Man(n) kann auch GDI+ benutzen, um die Textur auf die Kugel zu projizieren.

    Beispiel:

    Der Kern des Codes ist aus dem "Rotating Earth" Beispiel, irgendwann hier im Forum gepostet...


    Hier der FB Code + Exe.

  • Das ist ein super Beispiel. Hier wird Die Kugel einfach "Scheibchenweise" mit einer linearen Matrix gezeichnet, sodass insgesamt der Eindruck entsteht man hätte es irgendwie nichtlinear gelöst. Dafür muss man aber ein Sleep(100) einbauen und $iStep = 15 setzen, sonst sieht man das nicht weil es zu schnell und zu fein aufgelöst ist :D

  • Ihr habt beide komplett Recht.
    Da ist noch ein ziemlicher Schnitzer in der Projektion.
    Ich will aber auf Teufel komm raus kein klassisches UV-Mapping umsetzen sondern versuche immer noch eine möglichst performantere Variante zu finden.
    Mal sehen ob und wie weit ich komme.
    Bis dahin ist obiges Skript natürlich zu ignorieren.