Inhalt
Drehung
Eine Rotation ist ähnlich aufgebaut wie ein vector, nur das sie aus 4 float Werte besteht. Diese werden als Quaternion? interpretiert und die einzelnen Komponenten sind wie beim Vektor direkt über 'x', 'y', 'z' und 's' (nicht 'w') ansprechbar.
Syntax:
float x = 0.0; float y = 0.0; float z = 0.0; kopiert diese Werte in die Werte der entsprechenden Rotation float s = 1.0; rotation rot_a = <0.0, 0.0, 0.0, 1.0>; //kopiert diese Werte in die Werte der entsprechenden Rotation rot_a.x = 1.0; // ändert rot_a zu <1.0,0.0,0.0,1.0> rotation rot_b =; //kopiert die Werte der Variablen nach rot rotation rot_c = rot_b; //kopiert den Wert von rot_b nach rot_c
Es gibt verschiedene Möglichkeiten beliebige Rotationen in 3 Dimensionen darzustellen.
Das einfachste ist, eine Rotation als 3 Rotationen um die x y und z Achse anzusehen (bekannt als Euler?-Repräsentation). In LSL? kann dies mit Hilfe des vector-Datentyps dargestellt werden, wobei x als Winkel der Rotation um die x-Achse, y als Winkel der Rotation um die y-Achse und z als Winkel der Rotation um die z-Achse festgelegt wird. Siehe auch Banking?.
Leider bereitet die Euler-Repräsentation Probleme, wenn man Rotationen miteinander kombiniert (siehe unten). Um diese Probleme zu lösen, stellt LSL? Rotationen in einer erweiterten mathematischen Darstellung, genannt Quaternion?, dar, welche aus 4 Elementen ( 'x', 'y', 'z', 's') besteht. Zu beachten ist, dass die x,y,z Elemente nicht als Winkel der Rotationen um die jeweilige Achse angesehen werden können. Weitere Informationen zu diesem Thema findet ihr auf der LSL-Quaternion? Seite oder bei der offiziellen Wikipedia
Quaternion Seite.
Es ist jedoch möglich Rotationen zu benutzen ohne sich mit den die einzelnen Elemente der Quaternionen zu beschäftigen. LSL bietet Hilfsfunktionen an, mit denen man Quaternionen aus Euler Repräsentationen (und umgekehrt) erzeugen kann: llEuler2Rot und llRot2Euler.
Hinweis: LSL erwartet die Winkel in
Bogenmaß-Darstellung anstelle der Grad?-Darstellung. Das Bogenmaß eines Winkels α (aufgefasst als Mittelpunktswinkel eines Kreises) ist definiert als das Verhältnis der Länge des Kreisbogens b zum Radius r. Die Einheit für Bogenmaß ist rad (abgekürzt von radian?) und 1 rad beträgt annäherungsweise 57,296°.
Dies bedeuted, dass ein voller Kreis (360°) in der Bogenmaß-Darstellung 2*PI? radians? groß ist. Ein halber Kreis (180°) beträgt dementsprechend PI? radians?. Diese Zahlen müssen wir uns zum Glück nicht merken, da in LSL? zwei Umrechnungskonstanten DEG_TO_RAD und RAD_TO_DEG für die Konvertierung von und zur Grad-Darstellung definiert sind.
Beispiel:
vector eul = <0,0,45>; //45 Grad zur z-Achse (Euler) eul = eul * DEG_TO_RAD; //Konvertiert ins Bogenmaß rotation quat = llEuler2Rot(eul); //Konvertiert in Quaternion llSetRot (quat); //Dreht das Objekt 45 Grad um die z-Achse
LSL definiert außerdem die Konstanten PI_BY_TWO (90°), PI (180°), und TWO_PI (360°), die es ermöglichen einfach von PI anzuleitende Werte direkt in Bogenmaß anzugeben.
vector x_ninety = <PI_BY_TWO, 0,0>; //90 Grad um die x-Achse
vector y_one_eighty = <0, PI, 0>; //180 Grad um die y-Achse
LSL? beinhalted auch die Konstante ZERO_ROTATION, die der Rotation mit einem Winkel von 0° entspricht.
Beim Aufrufen von llSetRot?(ZERO_ROTATION ) orientiert sich das Objekt derart, dass dessen Achsen mit den globalen Achsen übereinstimmen. Der Wert den llGetRot? zurückliefert ist die aktuelle Orientierung des Objekts auf die null? Rotation bezogen.
1.1 Kombinieren von Drehungen
Ein Gegenstand wird gedreht, indem man seine gegenwärtige Lagebestimmung mit der gewünschten Umdrehung multipliziert. Die Reihenfolge in der die Drehung definiert werden muß, hängt davon ab ob die Rotation im die globale Koordinatensystem? oder im lokalen durchgeführt wird.
Beispiel:
//Rotation von 45 Grad um die globale X-Achse (Die Achse die von West nach Ost verläuft) rotation x_45 = llEuler2Rot( <45 * DEG_TO_RAD, 0, 0> ); rotation new_rot = llGetRot() * x_45; // Globale Rotation berechnen llSetRot(new_rot); // Das Objekt entprechend ausrichten
Betrachten wir nun das Folgende:
rotation new_rot = x_45 * llGetRot(); //lokale Rotation berechnen llSetRot(new_rot); //Objekt entprechend ausrichten
Dies dreht das Objekt um dessen lokale X-Achse, deren Lage von seiner gegenwärtigen Orientierung im Raum abhängt. Dies kann man sich als eine Rotation aus der Sicht des Objektes vorstellen, also relativ zur aktuellen Blickrichtung des Objektes.
Umgekehrt funktioniert das auch bei der Division von 2 Rotationen:
rotation new_rot = x_45 / llGetRot(); //lokale Rotation berechnen llSetRot(new_rot); //Objekt entprechend ausrichten
Wie zuvor würde dieses das Objekt entlang der X-Achse entsprechend seiner gegenwärtigen Orientierung drehen, aber in entgegengesetzter Richtung.
Um einen Vektor zu drehen muß die Rotation von rechts mit ihm multipliziert werden:
vector new_vec = old_vec * x_45; // kompiliert vector new_vec = x_45 * old_vec; // kompiliert nicht
Hinweis: Ein Objekt kann um einen beliebigen Punkt gedreht werden, indem man einen Vektor mit einer Rotation in der eben beschriebenen Weise multipliziert. Dieser Vektor muß der Abstand zwischen der gegenwärtigen Position des Objekt und dem gewünschten Mittelpunkt der Rotation sein. Wenn man das Resultat dieser Multiplikation zum dem Mittelpunkt der Rotation addiert erhält man einen neuen Vektor, der die Position angibt an die man das Objekt verschieben muß um die gewünschte Rotation zu erreichen.
Beispiel:
rotation x_45 = llEuler2Rot( <45 * DEG_TO_RAD, 0, 0> ); // 45 Grad um x vector aktuellePosition = llGetPos(); vector mittelpunkt = llGetPos() + <1, 1, 1>; // in globalen Koordinaten vector abstand = aktuellePosition - mittelpunkt; vector neuePosition = mittelpunkt + ( abstand * x_45); llSetPos(newPos);
Bear in mind that any translation (position) operation can result in a vector that would put the object outside of the world, or require a move further than 10 meters--so plan for these possibilities
Bedenken Sie bei derartigen Rotationen, daß jede verschiebende Operation (Repositionierung) zu einem Vector führen kann, der das Objekt außerhalb der Welt platziert, oder eine Bewegung über mehr als 10 Meter erfordert — also sorgen sie für diese Fälle vor.
1.2 Funktionen
| Funktionen | Verwendungszweck |
| llAngleBetween | liefert den Winkel zwischen zwei Rotationen |
| llApplyRotationalImpulse | führt einen Rotationsimpuls aus |
| llAxes2Rot | konvertiert 3-Achsen in eine Rotation |
| llAxisAngle2Rot | liefert die Rotation die durch die Drehung um einen Winkel an einer Achse erzeugt wird |
| llDetectedRot | liefert die Rotation des ermittelten Objekts oder Agenten |
| llEuler2Rot | konvertiert den Vektor einer Euler-Rotation in eine Quaternion-Rotation |
| llGetCameraRot | liefert die Rotation der Kamera eines Benutzers |
| llGetLocalRot | liefert die lokale Rotation eines Objekts |
| llGetOmega | liefert die gegenwärtige Rotationsgeschwindigkeit |
| llGetPrimitiveParams | Gibt die Rotation und viele anderen Parameter zurück |
| llGetRootRotation | Gibt die globale Rotation des Rootobjektes zurück |
| llGetRot | Liefert die globale Rotation des Objekts |
| llGetTextureRot | gibt die Drehung der Textur einer Seite des Objekts zurück |
| llGetStatus | Ermittelt, ob ein Objekt gedreht werden kann |
| llList2Rot | konvertiert ein Listenelement in eine Rotation |
| llLookAt | Setzt das Ziel für das zu betrachtende Rotationsobjekt |
| llSetForceAndTorque | Setzt Rotations-und lineare Kräfte für ein physikalisches Objekt |
| llSetLocalRot | Setzt die lokale Rotation |
| llSetPrimitiveParams | Setzt Rotation sowie viele andere Parameter |
| llSetRot | Legt die globale Drehung fest |
| llSetStatus | unter anderen Parametern wird festgelegt ob ein Objekt gedreht werden kann |
| llSetTorque? | Legt den Rotationsimpuls für ein physikalisches Objekt fest |
| llSetVehicleRotationParam | Stellt den Fahrzeugrotations-Parameter ein |
| llSitTarget | Stellt das Sitzziel für ein Objekt unter Angabe der Rotation ein |
| llStopLookAt | Stoppt die Rotation, die durch llLookAt?oder llRotLookAt?begonnen wird |
| llRezAtRoot | Rezt ein Objekt unter Angabe der Rotation |
| llRezObject | Rezt ein Objekt unter Angabe der Rotation |
| llRotateTexture | Legt die Texturrotation einer Seite eines Objekts fest |
| llRot2Angle | Gibt den Rotationswinkel zurück |
| llRot2Axis | Gibt die Rotationsachse zurück |
| llRot2Euler | konvertiert eine Quaternion in eine Euler-Rotation |
| llRot2Fwd | Gibt den Einheitsvektor, der die vorwärtsgerichtete Achse nach einer Rotation darstellt, zurück. |
| llRot2Left | Gibt den Einheitsvektor, der die horizontale Achse nach einer Rotation darstellt, zurück |
| llRot2Up | Gibt den Einheitsvektor, der die vertikale Achse nach einer Rotation darstellt, zurück |
| llRotBetween | Liefert den kleinsten Winkel (als Rotation) zwischen zwei Vektoren |
| llRotLookAt | Stellt das Rotationsziel eines Objekts ein |
| llRotTarget | Setzt das Rotationsziel für ein Objekt |
| llRotTargetRemove | Entfernt das Rotationsziel für ein Objekt das durch sein handle (Griff) gegeben ist |
| llTargetOmega | Clientseitig ablaufende, weiche Rotation |
1.2.1Events
| Event Name | Verwendungszweck |
| at_rot_target | Wenn das Objekt innerhalb des Zielwinkels kommt |
| not_at_rot_target | Wenn das Objekt außerhalb des Zielwinkels ist |
| changed | Wenn die Textur geändert, aber das Objekt nicht rotiert wurde |
| control | Wenn der Avatar links oder rechts rotiert |
Q: Gibt es einen verlustlosen Weg, eine Rotation in einen String und diesen String wieder in eine Rotation zu konvertieren, so dass die resultierende Rotation die gleichen Werte hat wie die Originalrotation?
A: Siehe: Serialization?
Q: Ich sehe manchmal 1/rot. Was macht das genau?
A: Meinst du <0,0,0,1>/rot? Dies invertiert ein Quaternion. Oder meinst du <0,0,1>/rot? Dies multipliziert den Vektor mit dem inversen Quaternion.
Funktionen | Typen | Konstanten | Transformation | Quaternion | Vektoren | Euler