ehem. OMSI - Forum

Dieses Forum wurde geschlossen. Das neue Forum befindet sich auf www.omnibussimulator.de/forum !
 
StartseiteStartseite  FAQFAQ  SuchenSuchen  MitgliederMitglieder  NutzergruppenNutzergruppen  AnmeldenAnmelden  LoginLogin  

Teilen | 
 

 [WIP][NO DOWNLOAD] Busfanats Skript-Test-Bus

Nach unten 
AutorNachricht
Busfanat



Anzahl der Beiträge : 50
Anmeldedatum : 30.04.09
Alter : 25

BeitragThema: [WIP][NO DOWNLOAD] Busfanats Skript-Test-Bus   Do 10 Nov - 21:47

Hallo zusammen,

wie bereits in einem anderen Thread erwähnt, beschäftige ich mich derzeit mit dem OMSI-Code, da ich des 3D-Modellings vollkommen untalentiert scheine und auch sonst ein großes Interesse für's Programmieren habe.

Ich habe meine Codes in keiner logischen Reihenfolge geschrieben sondern nach Lust und Laune. Und ich werde die Skripts auch nicht nach logischer Reihenfolge vorstellen, sondern, wie es sich ergibt.

Ich möchte in diesem Thread meine Ansätze zu Problemlösungen vorstellen, die in neuen Fahrzeugen eingesetzt werden können. Daher gibt es hier keine Codes zum Download, da sie keine Mods in dem Sinne darstellen.

Da es mich als erstes interessiert hat, wie Außenschwingtüren in OMSI funktionieren könnten, hab ich das mal versucht, zu realisieren.

Die Antriebsstangen der Türen bewegen den Türflügel in einer Kreisbahnbewegung. Der Knick in der Stange dient ausschließlich dazu, nicht mit der Karosserie zu kollidieren. Das brachte mich auf die Idee, den Türflügel mit einer Art Parameterdarstellung zu animieren. Ich animiere also X- und Y-Achse getrennt, um die Schwingbewegung darzustellen. Zusätzlich wäre eine Bewegung entlang der Z-Achse möglich, um das Entriegeln der Türen zu simulieren.

Daher braucht die Bewegung pro Flügel 2 oder 3 Variablen, je nachdem, wie viele Achsen animiert werden.

Bei meinem Beispiel sieht also die Varlist-Datei so aus:

posx_T1_F1
posy_T1_F1
posx_T1_F2
posy_T1_F2
posx_T2_F1
posy_T2_F1
posx_T2_F2
posy_T2_F2

Die Positionen in X und Y sind von einer gemeinsamen Variable abhängig: dem Öffnungswinkel des Türflügels, daher sind noch weitere Variablen nötig:

pos_T1_F1
pos_T1_F2
pos_T2_F1
pos_T2_F2

Damit lässt sich die Bewegung des Türflügels grundsätzlich bereits beschreiben. Eine Vereinfachung habe ich getroffen: In der Modell.cfg ist die Drehung der Türstange so definiert, dass 0 zu bedeutet und der max. Schwingwinkel, in meinem Testmodell 135°, ganz offen. Dadurch muss ich alle Formeln nur für einen Flügel entwickeln und kann alles für die anderen Flügel durch einfaches Kopieren und Variablenersetzen adaptieren.

Als nächstes zunächst eine Skizze:


den Öffnungswinkel der Tür bezeichne ich gewohnheitshalber mit einem kleinen phi. Ich vermute, ihr würdet alpha für die Beschriftung vorziehen, aber alpha ist in der Technik die Winkelbeschleunigung und die könnte später noch im Code gebraucht werden.

Die Variable pos_T?_F? ist also der Winkel phi in der Zeichnung und der Radius r (in der Skizze gleich der Dreieckseite c) ist durch die Türstange fixiert.

Apropos fixiert: Also ab in's Const-File mit dem Wert. Und zweitens entspricht der Winkel, der die Nullposition darstellt, nicht einem Winkel von 0°. Diesen Offset muss man auch ins Const-File eintragen.

Als nächstes müssen posx_T?_F? und posy_T?_F? endlich von pos_T?_F? abhängig gemacht werden.
Am einfachsten kann man sich die Umsetzung des Winkels in X- und Y-Komponente mit einem rechtwinkligen Dreieck darstellen.

Die längste Seite, meist als c bezeichnet, ist unsere Hypotenuse bzw. der Radius des Kreisbogens.
Die Seite b ist die X-Komponente der Hypotenuse, während die Seite a die Y-Komponente darstellt.

Per Definition ist der Sinus eines Winkels das Verhältnis zwischen Hypotenuse und Gegenkathete des Winkels phi.
Das Verhältnis Hypotenuse zu Ankathete wird mit dem Cosinus des Winkels beschrieben. Da das OMSI-Skript keine Cosinus-Funktion bietet, muss man sich mit dem Wissen helfen, dass Sinus und Cosinus um 90° phasenverschoben sind.

Der Winkel, von dem die X- und Y-Komponenten berechnet werden sollen, ist immer um den Winkel phi_null, den die Türstange im geschlossenen Zustand bereits hat, größer als der Wert in der Variable pos_T?_F?.
Daher ist X=Radius_Türstange*sin(phi_null+pos_T?_F?)
und Y=Radius_Türstange*sin(phi_null+pos_T?_F?+90)

als nächstes muss beachtet werden, dass OMSI, wie viele Programme Winkel nicht in Grad sondern in Radiant berechnet. Der Umrechnungsfaktur hierzu beträgt. rad=Grad*(pi/180)

somit ist X=Radius_Türstange*sin((phi_null+pos_T?_F?)*(pi/180))
und Y=Radius_Türstange*sin((phi_null+pos_T?_F?+90)*(pi/180))

Da der Nullpunkt des Objektes Türflügel nicht dem Rotationspunkt der Türstange entspricht, muss noch einmal ein Offset bemüht werden, der das berücksichtigt:

X=Radius_Türstange*sin((phi_null+pos_T?_F?)*(pi/180))±Offset_x
und Y=Radius_Türstange*sin((phi_null+pos_T?_F?+90)*(pi/180))±Offset_y

Transferieren in die OMSI-Code-Syntax ergibt:

(C.L.phi_Null) (L.L.pos_T?_F?) + pi * 180 / sin (C.L.radius_Turstange) * (C.L.Offset_x_T?_F?) ± (S.L.posx_T?_F?)
(C.L.phi_Null) (L.L.pos_T?_F?) + 90 + pi * 180 / sin (C.L.radius_Turstange) * (C.L.Offset_y_T?_F?) ± (S.L.posy_T?_F?)

Die Türstange kann nun über pos_T?_F? beliebig beschleunigt/verzögert/animiert werden, der Türflügel folgt der Türstange wie gewünscht.

Wenn Fragen auftauchen, einfach stellen.

Schönen Abend noch,

Busfanat

P.S.: @Mods: wenn falscher Bereich, bitte verschieben, mir ist nichts besseres eingefallen.
Nach oben Nach unten
Benutzerprofil anzeigen
Busfanat



Anzahl der Beiträge : 50
Anmeldedatum : 30.04.09
Alter : 25

BeitragThema: Re: [WIP][NO DOWNLOAD] Busfanats Skript-Test-Bus   Fr 18 Nov - 20:19

Hallo zusammen,

Weiter geht's mit dem beliebten Thema Vollmatrix.

Bei diesem Thema habe ich zu Beginn diverse Schwierigkeiten erwartet:
- mind. 2 Schriftgrößen wie aus einem Guss aussehen lassen
- zentrieren der Schrift und trotzdem exaktes ausrichten nach dem Hintergrund (ausgeschaltete LEDs)
- Implementierung von Groß- und Kleinschreibung

Ich habe mich bereits zu Beginn dafür entschieden, den Zeichensatz mit der größeren Schrift auf eine eigene Texttextur zu legen, weil ich ansonsten auf Sonderzeichen, die mit der Tastatur nicht ohneweiteres erzeugt werden können, zurückgreifen müsste und noch dazu die Logik Schaden nehmen würde und die Koordinierung der Texturen noch komplexer wäre.

Das bedeutet für Blender, dass pro Zielanzeige drei Flächen mit Texttexturen belegt werden müssen.

Dementsprechend habe ich als benötigte Stringvariablen deklariert:
Ziel_vorne_groß
Ziel_vorne_oben
Ziel_vorne_unten
Ziel_rechts_groß
Ziel_rechts_oben
Ziel_rechts_unten

Zudem habe ich, da es im Skriptablauf erforderlich wurde, Strings kurzzeitig zu speichern, zusätzlich 3 Stringregister als lokale Stringvariablen definiert:
StringRegist0
StringRegist1
StringRegist2

Die Matritzen für vorne und rechts sind deshalb getrennt, weil ich auf der Seite testhalber die Liniennummer weggelassen habe.

Grundsätzlich ist im folgenden eine Funktion beschrieben, die durch eine Änderung des Zielschildes aufgerufen wird und sollte deshalb auch als Macro definiert werden.

Schritt 1: Laden der Endhaltestellenstring
(L.L.Bediengeraet_akt_Ziel) (M.V.GetTerminusIndex) s0
l0 (S.L.target_index_int)
l0 1 (M.V.GetTerminusString) (S.$.StringRegist0)
l0 2 (M.V.GetTerminusString) (S.$.StringRegist1)

Soweit, so klar. Als Hintergrundinformation: Die Liniennummer ist in meinem Beispiel als (L.L.Bediengeraet_Linie) gespeichert.
Als nächstes kommt das wirklich aufwändige: Das Aufbereiten der Strings, um sie im Anschluss als Texttexturen auszugeben.
Da nach Möglichkeit eine Kompatibilität zu den bestehenden HOF-Files gewährleistet werden sollte und diese zur Darstellung auf den Zielanzeigen von SD und D Leerzeichen enthalten, die bei der Zentrierung stören könnten, müssen diese unnötigen Leerzeichen am Anfang und Ende des Strings als erstes entfernt werden.

Da dies nicht nur mit einem String passieren muss, habe ich das in ein eigenes Macro ausgelagert.
Das Macro entfernt immer die Leerzeichen im String (L.$.StringRegist0), also muss ein bisschen was herumgeschoben werden

Im Anschluss das Macro gekürzt wiedergegeben. Im Code empfehle ich, die ifs bis zur Länge 1 weiterzuführen.

Spoiler:
 

Das Macro ist für beide Zielschild-Strings (oben und unten) auszuführen.

Als nächstes kann ermittelt werden, ob die Matrix in den Ein- oder Zweizeilenmodus "geschaltet" wird:
' Ausgabe an der Zielanzeige EIN- oder ZWEI-zeilig?
(L.$.Bediengeraet_Ziel_oben) " " $=
(L.$.Bediengeraet_Ziel_unten) " " $= ||
{if}
' EINzeilige Ausgabe
{else}
' ZWEIzeilige Ausgabe
{endif}

Im Falle der Einzeiligen Ausgabe werden als erstes alle Strings, die in der kleinen Schriftgröße dargestellt würden mit dem Leerstring "" überschrieben.
Zudem muss ermittelt werden, ob nun die obere oder untere Zeile ausgegeben werden soll:
(L.$.Bediengeraet_Ziel_oben) " " $=
{if}
(L.$.Bediengeraet_Ziel_unten) (S.$.Ziel_vorne_groß)
{else}
(L.$.Bediengeraet_Ziel_oben) (S.$.Ziel_vorne_groß)
{endif}

Durch das Macro CutLeerzeichen werden alle Strings, die nur aus Leerzeichen bestehen auf ein einzelnes Leerzeichen gekürzt und alle Leerstrings werden durch ein einfaches Leerzeichen ersetzt. Dadurch kann mit einem einfachen Leerzeichen überprüft werden, welcher der Strings angezeigt werden muss.

Um den Zieltext korrekt zentrieren zu können, muss als erstes die Liniennummer hinsichtlich ihrer Breite in Matrixpunkten untersucht werden.
Wenn die Liniennummer 0 ist, kann man sich die Ermittlung sparen, ansonsten habe ich mich dazu entschlossen, die Berechnung der Breite wieder auszulagern.

Hierzu gibt es wieder ein Macro, das mit den benötigten Parametern via (String-)Register versorgt wird.
(M.L.StringlengthPunkte_groß)
' Input-Variablen: StringRegist0 (String, von dem die Länge in Punkten zu ermitteln ist)
' Arbeits-Variablen: Register 0 (Länge des Strings in Zeichen)
' StringRegist1 (aktuell betrachtetes Zeichen)
' Output-Variablen: Register 1 (Länge des Strings in Punkten)

Das Macro ermittelt die Breite/Länge des Strings in Matrixpunkten, es addiert also die Längen aller Zeichen im String. Um zu wissen, wie breit die Zeichen sind, ist im Script für jedes darstellbares Zeichen die Punktbreite in der Form
Spoiler:
 
hinterlegt.

Das Macro ist etwas komplexer geworden, da das OMSI-Script keine Schleifen gestattet. Da ich in letzter Zeit viel mit php zu tun hatte und deshalb noch einen entsprechenden Präprozessor auf meinem Rechner installiert habe, habe ich mich entschieden, die Schleife in php zu realisieren und das ausgegebene Ergebnis in die osc-Datei zu kopieren. Das gleiche sollte aber mit jeder anderen Programmier oder Skriptsprache funktionieren, die Schleifen unterstützt und das Ergebnis in einer Form ausgeben kann, das Copy&Paste-fähig ist.

Ein ähnliches Macro gibt es noch einmal für die kleinere Schriftgröße.

Nach jedem Macro, das Werte zurückgibt, ist es wichtig, diese Werte sofort in Variablen zu schreiben, die vom weiteren Ablauf erst wieder verändert werden, wenn die Werte nicht mehr gebraucht werden!

Im Anschluss wird die LEDPunkteLänge des Zieltextes wieder mit dem Macro ermittelt.

Zum Abschluss wird der String zusammengebaut, der dann am Zielschild angezeigt wird.

' //Matrixlänge (121) - LN-Länge = Platz für Ziel
' //(Platz für Ziel - Länge Zielstring) / 4 = aufzufüllende Leerzeichen
121 (L.L.Matrix_Laenge_oben) - l1 - 4 / s2
"<" (L.$.StringRegist2) $+ " " l2 $* $+ (L.$.StringRegist0) $+ " " l2 $* $+ " " $+ (S.$.Ziel_vorne_groß)

121 l1 - 4 / s2
"<" " " l2 $* $+ (L.$.StringRegist0) $+ " " l2 $* $+ " " $+ (S.$.Ziel_rechts_groß)

Rechts wird wiederum extra behandelt, weil da keine Liniennummer angezeigt wird.

Für die zweizeilige Ausgabe gilt im Grunde das selbe, nur dass eben die Variablennamen zum Teil anders sind und ein Teil einmal für oben und einmal für unten auszuführen ist.

Hiermit bin ich vorerst am Ende meines bereits vorhandenen Codes. In naher Zukunft möchte ich mich mit dem Thema FSD (Fahrscheindrucker) beschäftigen. Hierzu muss ich noch ein paar Skizzen des Originals anfertigen. Ich möchte versuchen, den Zelisko FSD4R umzusetzen und im Anschluss darüber einen Fahrzeuginternen DFI-Monitor mit Haltestellenvorschau anzusteuern.

Sollte ich mich irgendwo missverständlich ausgedrückt haben, oder wenn Fragen auftauchen, einfach posten.

Schönen Abend noch,

Busfanat

P.S.: @Mods: Sry für Doppelpost, wollte die Kapitel einfach trennen. Wenn nicht erwünscht, bitte Posts zusammenfassen.

EDIT, 19.11.11:

Hallo zusammen,

gestern habe ich als Antwort auf diesen Post eine E-Mail vom Nutzer "Flopsi" erhalten, welche ich hier beantworten möchte. Ich habe von ihm die Erlaubnis bekommen, diese Mail hier zu zitieren:

Zitat :
Flopsi schrieb (per E-Mail):

N'abend Busfanat,

ich habe mich gerade mal durch deinen Beitrag gelesen, in dem du über das Scripten einer Vollmatrix schreibst.
Ich wüsste gern, in wie fern diese Scripts einzufügen sind. Ich habe mich gerade darin versucht, diese Schnipsel zu verwenden, doch ich erhalte nur Fehlermeldungen.

Ist es nötig neue Dateien zu erstellen oder die Vorhandenen nur zu ändern?
Ich finde es auf jeden Fall super, dass du dich damit beschäftigt und wie es aussieht auch verstanden hast.

Bedanke mich schonmal im Voraus für eine Atnwort und wünsch erstmal noch einen schönen Abend.

Gruss
Flopsi

Meine Skripts sind nicht für bestehende Busse entwickelt sondern für Modder gedacht, die neue Fahrzeuge erstellen. Aus diesem Grunde stimmen z.B. auch die Variablennamen nicht mit denen der mitgelieferten Busse überein.

Für jede Matrixanzeige sind vier Texturen nötig. Eine Hintergrundtextur, die alle LEDs in "Aus" darstellt, eine Texttextur für die "große" Schriftart, mit der die LN- Nummer und der Text eines einzeiligen Ziels angezeigt wird und zwei Texttexturen für die "kleine" Schriftart, mit der die Texte eines zweizeiligen Ziels angezeigt werden, einmal oben und einmal unten. Die Größe der Texturen ist von den verwendeten Schriften abhängig.

Danke für dein Kompliment, dass ich es verstanden hätte. Ich habe in der letzten Zeit in unterschiedlichen Programmiersprachen Einführungen genossen und kann mich relativ schnell in neue Syntaxen einarbeiten. Allerdings bin ich mir sicher, dass sich vor allem der Code für die Matrix noch optimieren, sprich kürzen, lässt.

Sollte jemand die Code-Teile einsetzen wollen, bin ich gerne bereit, beim Einsetzen der Codes zu helfen.

mfG,

Busfanat
Nach oben Nach unten
Benutzerprofil anzeigen
 
[WIP][NO DOWNLOAD] Busfanats Skript-Test-Bus
Nach oben 
Seite 1 von 1

Befugnisse in diesem ForumSie können in diesem Forum nicht antworten
ehem. OMSI - Forum :: OMSI-Design (deutsch) :: Scriptprogrammierung-
Gehe zu: