• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

llTargetOmega Timingproblem

argus Portal

Freund/in des Forums
Hallo

Ich möchte per llTargetOmega eine weiche, aber kontrollierte Bewegung
umsetzen. Mit diesem Beispiel rotiere ich ein Linkset mit 1 Hz um die z-achse:

llTargetOmega(<0.0,0.0,1.0>,TWO_PI,1.0);


Ich will die Bewegung aber jeweils bei 180 Grad (also die Hälfte) umkehren. Also ein Hin und Zurück.
Am jeweiligen Endpunkt setze ich die Position per llSetLinkPrimitiveParamsFast auf den jeweiligen Grad.



Also starte ich einen 0.5-Sekunden-Timer.

Bei jedem Timerevent sollte das Linkset also jeweils an einem Endpunkt angelangt sein. Rein optisch
ist es aber nur knapp die Hälfte; es sieht also aus, als bewege sich das Objekt jeweils nur um 90 Grad.

Rufe ich mit Rechtsklick das Bearbeiten-Fenster und lasse es geöffnet, blockiere ich damit ja
die llTargetOmega-Bewegung und kann somit die Wirkung von llSetLinkPrimitiveParamsFast beobachten:
Das Objekt pendelt dann in der Tat korrekt zwischen beiden Endlagen.

Übersehe ich da etwas ? Oder ist das Zusammenspiel von Timer und llTargetOmega per se ungenau und man
muss sich eine Korrektur-Konstante selbst ermitteln ?
 
Nachtrag: Ich kann das kompensieren, wenn ich nach Erreichen der Endlagen eine kleine Pause einlege. Je nach Projekt
ist das kein Problem. Aber ich würde lieber eine andere Lösung einsetzen, die kein nachträgliches Justieren benötigt.
 
LSLwiki: "NOTE: Currently llTargetOmega() is not performing properly, especially when involved in an avatar attachment. llTargetOmega cannot currently be relied upon to rotate avatar attachments properly, and exhibits inconsistent results on non-attached objects."

Klappt also nicht so zuverlässig an Avataren (falls das bei Deinem Objekt der Fall ist). Außerdem wird bei nichtphysikalischen Objekten (wohl der häufigere Fall) die Rotation nur im Viewer simuliert. Das Objekt auf dem Server weiß dann nicht wirklich, in welchen Positionen die verschiedenen Avatare die Drehung gerade sehen.

Wenn Du das Objekt physikalisch machen kannst, wird auf dem Server gedreht. Sonst wirst Du wohl tricksen müssen.
 
Zuletzt bearbeitet:
Das ist es ja, weswegen ich den Timer benötige (tricksen). Das Linkset ist nicht physikalisch.

Über den Timer kann man sich ausrechnen, bei wieviel Grad man aktuell ist. Leider wohl nur ungefähr.

Danke für dein LSLwiki-Zitat. Unter http://wiki.secondlife.com/wiki/LlTargetOmega ist das nicht so deutlich hervorgehoben.
("is not performing properly").
 
llTargetOmega ist wenig geeignet, das errechnet der Viewer selbst, also sieht jeder was andres.
Weiterhin musst du für eine exakte Bewegung (zB Tür) erst manuell eine Ausgangsposition setzen, die auch noch minimal unterschiedlich zur aktuellen Position sein muss (sonst bewegt sich oft gar nichts)

ich würde llKeyFramedMotion im Modus KFM_PING_PONG benutzen
Eigentlich kann dabei sogar der Timer entfallen.
Falls du doch einen nimmst, dann halt zur Synchronisation und zum Ausgleichen des Drifts
 
Falls man exakte Timer in SL braucht muss man, je nach dem, was man machen will, leider auch manchmal die Time Dilation des Servers noch beachten.

Time Dilation ist dabei die Verzögerung zwischen dem Funktionsbefehl in einem Script und zwischen dem Zeitpunkt, zu dem das dann tatsächlich auch auf dem Server passiert. (Und zwischen dem, was auf dem Server passiert und zwischen dem, was der Viewer in Europa dann anzeigt vergehen noch mal rund 150ms oder so, da kommt noch mal bisschen Verzögerung rein weil das Signal über den Atlantik muss.)

Normal liegt die Dilation irgendwo deutlich über 95% (0.95 , der Simulator läuft dann mit deutlich über 95% der Geschwindigkeit) macht sich also kaum bemerkbar. Aber wenn viel los ist mit Physik und sonstiger Last für den Server, dann kann die Dilation durchaus mal auf unter 50% fallen. Womit der Server nur noch mit halber Geschwindigkeit läuft. Und ein Timer, der mit 0.5s tickt, der kann dann eben deutlich länger als 0.5s brauchen bis er wieder tickt. Das liegt daran, dass der Server unter viel Last erst mal die Scriptausführung ausbremst. Während andere Prozesser auf dem Server durchaus normal weiterlaufen können. Das ist mit ein Grund warum llTargetOmega alles andere als exakt ist. Und warum zwei Scripte, die gleichzeitig mit dem selben Timer gestartet wurden, manchmal leicht unterschiedlich schnell laufen. Helfen kann in so einem Fall dann manchmal eine klitzeleine Zwangspause um z.B. Scripte wieder neu synchronisieren zu können.

Die Time Dilation in SL kriegt man mit llGetRegionTimeDilation() als Wert zwischen 0.0 (Server hält Scripte an) und 1.0 (normale Geschwindigkeit) , dieser Wert hat vor allem auf llSetTimerEvent einen ziemlich großen Einfluss.
 
wir könnten llGetUnixTime nehmen, als direkter Kernelaufruf ziemlich fix und millisekundengenau.
Die SIM kann zwar trotzdem noch hinterherhängen aber wir Summieren die Abweichungen nicht.
 
llTargetOmega ist wenig geeignet, das errechnet der Viewer selbst, also sieht jeder was andres.

Ja. Aber man kann das verhindern, indem man an "geeigneten" Positionen am besten mittels llSetLinkPrimitiveParamsFast
eine Art "Synchronisationsimpuls" sendet. Alle Avatare sehen ab dem Moment exakt dasselbe, weil das "llTargetOmega"-System
im Viewer neu initialisiert wird. Ich denke, es reicht sogar ein erneuter llTargetOmega-Aufruf. (Speziell das habe ich noch nicht
getestet, aber ich bin mir sicher, das es funktioniert).


ich würde llKeyFramedMotion im Modus KFM_PING_PONG benutzen
Eigentlich kann dabei sogar der Timer entfallen.
Falls du doch einen nimmst, dann halt zur Synchronisation und zum Ausgleichen des Drifts

Diese Funktion setze ich gerne für Aufzüge ein. Aber sie passt nicht immer. Z.b. bekommst du ein Problem,
wenn du einen Avatar bewegst und während der Bewegung zwischen verschiedenen Animationen wechseln willst.
Das führt dann zu einer Scriptwarnung.


P.S.: Weil du llKeyFramedMotion vorschlugst: Meine Frage bezieht sich auf kein aktuelles Projekt, sondern mein
kleiner Testaufbau dient nur der Entwicklung einer universell einsetzbaren Lösung für alle Fälle, wo weiche Bewegung
gefordert ist; bei möglichst kompletter Kontrolle über jede Position/Rotation zu jeder Zeit.

"universell, alle Fälle, jede Zeit" werden natürlich nicht zu 100% erreichbar sein ;-)
 
Zuletzt bearbeitet:
wir könnten llGetUnixTime nehmen, als direkter Kernelaufruf ziemlich fix und millisekundengenau.
Die SIM kann zwar trotzdem noch hinterherhängen aber wir Summieren die Abweichungen nicht.

Genau den Gedanken habe ich auch. In einer Schleife (event-basiert und nicht for, while usw.) die Zeit abfragen und berechnen.

Das ist um Welten genauer als der Timer.
 
Ja. Aber man kann das verhindern, indem man an "geeigneten" Positionen am besten mittels llSetLinkPrimitiveParamsFast
eine Art "Synchronisationsimpuls" sendet.
Das versuchte ich oben anzudeuten (Zeile 2)

Ich denke, es reicht sogar ein erneuter llTargetOmega-Aufruf.
Meißt nicht, auch kein zweiter Aufruf ohne vorher bisschen zu verdrehen

Z.b. bekommst du ein Problem, wenn du einen Avatar bewegst und während der Bewegung zwischen verschiedenen Animationen wechseln willst.
Das war oben nicht ersichtlich, was du genau vorhast.

Das führt dann zu einer Scriptwarnung.
Motion pausieren (geht superfix und erhält die Bewegungskette) ist Pflicht bei jedweder Ortsveränderung
moving_end ist ein brauchbares Event für positionsrelevantes Eingreifen oder auch den Aufruf von llGetUnixTime
(zB statt KFM_PING_PONG nur eine Halbbewgung in der ersten Liste programmieren, und fürs zurück eine zweite Bewegungsliste verwenden)
 
Das versuchte ich oben anzudeuten (Zeile 2)
Motion pausieren (geht superfix und erhält die Bewegungskette) ist Pflicht bei jedweder Ortsveränderung
moving_end ist ein brauchbares Event für positionsrelevantes Eingreifen oder auch den Aufruf von llGetUnixTime
(zB statt KFM_PING_PONG nur eine Halbbewgung in der ersten Liste programmieren, und fürs zurück eine zweite Bewegungsliste verwenden)

Die Bewegung pausieren bedeutet in der Tat nur eine winzige Verzögerung, die ich pers. fast gar nicht wahrnehme. Aber ein Kunde war damit letztens unzufrieden und so musste ich das anders umsetzen. Das sind so die kleinen Dinge in SL, wo man Workarounds suchen muss ;-)
 

Users who are viewing this thread

Zurück
Oben Unten