Difference between revisions of "Rotation/ja"

From Second Life Wiki
Jump to navigation Jump to search
Line 53: Line 53:
</div></div>
</div></div>


== Order of rotation for Euler Vectors ==
==オイラーvector用のrotationの命令==


From the above discussion, it's clear that when dealing with rotations around more than one axis, the order they are done in is critical. In the ''Euler'' discussion above this was kind of glossed over a bit, the individual rotations around the three axis define an overall ''rotation'', but that begs the question: What axis order are the rotations done in? The answer is '''Z, Y, X''' in global coordinates. If you are trying to rotate an object around more than one axis at a time using the ''Euler'' representation, determine the correct ''Euler'' {{LSLG|vector}} using the Z, Y, X rotation order, then use the {{LSLG|llEuler2Rot}} function to get the '''rotation''' for use in combining rotations or applying the rotation to the object.
上記の記述より、一つの軸以上に機能するrotationで対処するときにはっきりするのは、行われる命令が臨界ということです。この上記の'''オイラー'''の記述は、少しもっともらしい類で、3つの角度周りの単一のrotationは全体の''rotation''として定義されますが、rotationは何度にすればいいのかという質問をされます。この答えはグローバル座標中の'''Z、Y、X'''です。''オイラー''の描写を用いて、一回で一つの軸以上の周囲をオブジェクトが回転するように試すのなら、Z、Y、X rotationの順に用いた正しいオイラー{{LSLG|vector/ja|vector}}を決定して、オブジェクトに結合したrotationあるいは適用したrotationで用いるための'''rotation'''を取得するための{{LSLG|llEuler2Rot/ja|llEuler2Rot}}を用います。


== Local vs Global (World) rotations ==
==ローカル rotation vs グローバル rotation==


It is important to distinguish between the '''rotation''' relative to the world, and the '''rotation''' relative to the local object itself.  In the editor, you can switch back and forth from one to the other.  In a script, you must convert from one to the other to get the desired behavior.
インワールドに相対な'''rotation'''とローカルオブジェクト自身に相対な'''rotation'''とを区別することは重要です。エディタにて、お互いをいったりきたりさせることができます。スクリプトにて、望ましい振る舞いを得るために互いに変換させるべきです。


'''Local''' rotations are ones done around the axes embedded in the object itself forward/back, left/right, up/down, irrespective of how the object is rotated in the world. '''Global''' rotations are ones done around the world axes, North/South, East/West, Higher/Lower. You can see the difference by rotating a prim, then edit it and change the axes settings between local and global, notice how the colored axes arrows change.
'''ローカル'''rotationは、どのようにインワールドにてオブジェクトが回転するかに関わらず、オブジェクト自身の前後、左右、上下に埋め込まれた角度の周りで行われます。'''グローバル'''rotationは、南北、東西、高低のインワールド角度周りにて行われます。プリムを編集してローカルとグローバル間で角度を変えると、どのように色づけされた角度の矢印が変わるか、プリムを回転させることで違いを見ることができます。


In LSL, the difference between doing a '''local''' or '''global''' rotation is the order the '''rotations''' are evaluated in the statement.
LSLでは、rotationを''ローカル''''''グローバル'''にするかの違いは、ステートメントでrotationの評価される方法によります。


This does a '''local''' 30 degree rotation by putting the constant 30 degree '''rotation''' to the left of the object's starting '''rotation''' (myRot). It is like the first operation in the first example above, just twisting the dart 30 degrees around its own long axis.
このrotationは、一定の30度の'''rotation'''へオブジェクトが左向きに''rotation'''(myRot)を開始している状態によるものが''ローカル'''の30度のrotationです。最初の例であげた最初の演算の、ダーツ自身の長軸周りをダーツが30度ひねっているものようなものです。


<div id="box"><div style="padding: 0.5em">
<div id="box"><div style="padding: 0.5em">
{| cellpadding=0 cellspacing=0
{| cellpadding=0 cellspacing=0
|-
|-
|rotation localRot = ||rot30X * myRot;||// do a local rotation by multiplying a constant rotation by a world rotation
|rotation localRot = ||rot30X * myRot;||// 空間のrotationによる、一定のrotationtで掛け算されたローカルのrotationを行ないます。
|}
|}
</div></div>
</div></div>


To do a '''global''' rotation, use the same '''rotation''' values, but in the opposite order. This is like the second operation in the second example, the dart rotating up and to the right around the world X axis. In this case, the existing rotation (myRot) is rotated 30 degrees around the global X axis.
同じ'''rotation'''の値を用いて'''グローバル'''rotationをすることは、その逆の命令ということではありません。これは2つめの例の2つめの演算で、ダーツが上昇回転して、空間のX軸にそって右に回るようなものです。このケースでは、存在しているrotation(myrot)はグローバルのX軸周りを30度回転しています。


<div id="box"><div style="padding: 0.5em">
<div id="box"><div style="padding: 0.5em">
{| cellpadding=0 cellspacing=0
{| cellpadding=0 cellspacing=0
|-
|-
|rotation globalRot || = myRot * rot30X;||// do a global rotation by multiplying a world rotation by a constant rotation
|rotation globalRot || = myRot * rot30X;||// 一定のrotationにより、空間のrotationで掛け算されたグローバルのrotationを行ないます。
|}
|}
</div></div>
</div></div>


== Another way to think about combining rotations ==
==rotationの結合について他の方法を考える==


You may want to think about this '''local''' vs '''global''' difference by considering that '''rotations''' are done in evaluation order, that is left to right except for parenthesized expressions.
左右を括弧で覆われたものを除いて、評価する命令の中で行なわれる'''rotation'''を考えることにより、この'''ローカル''''''グローバル'''の違いについて考えたくなるでしょう。


In the localRot case, what happened was that starting from <0, 0, 0>, the rot30X was done first, rotating the prim around the world X axis, but since when it's unrotated, the local and global axes are identical it has the effect of doing the rotation around the object's local X axis. Then the second '''rotation''' myRot was done which rotated the prim to its original rotation, but now with the additional X axis rotation baked in. What this looks like is that the prim rotated in place, around its own X axis, with the Y and Z rotations unchanged, a '''local''' rotation.
<0,0,0>から始まって発生するlocalRotのケースではrot30Xが最初に行なわれ、空間のX軸にそってプリムが回転し、回転している間は、ローカルとグローバルの角度はオブジェクトのローカルX軸に沿っての回転を行なう効果を識別します。2つめの'''rotation'''であるmyRotはプリムをオリジナルのrotationに回転させましたが、それではさらにX軸のrotationが焼きつきます。何と、これはプリムがX軸にそって回転して、YとZのrotationが変わらなかった'''ローカル'''rotationのようなものです。


In the globalRot case, again starting from <0, 0, 0>, first the object is rotated to its original rotation (myRot), but now the object's axes and the world's axes are no longer aligned! So, the second '''rotation''' rot30x does exactly what it did in the local case, rotates the object 30 degrees around the world X axis, but the effect is to rotate the object through a cone around the world X axis since the object's X axis and the world's X axis aren't the same this time. What this looks like is that the prim pivoted 30 degrees around the world X axis, hence a '''global''' rotation.
<0,0,0>から再び始まっているglobalRotのケースでは、最初にオブジェクトはオリジナルrotation(myrot)まで回転されますが、それではオブジェクトの角度と空間の角度は長くは調整されません。そこで、2つめの'''rotation'''であるrot30Xはローカルのケースで、オブジェクトを空間のX軸に沿って30度回転させ、確実に行ないますが、効果はオブジェクトのX軸と空間のX軸が今回一致しなくなってから、空間のX軸にそった円錐体をとおしてオブジェクトを回転することです。なんと、これはプリムが空間のX軸にそって30度旋回したもので、ゆえに'''グローバル'''rotationのようなものです。


'''Division''' of '''rotations''' has the effect of doing the rotation in the opposite direction, multiplying by a 330 degree '''rotation''' is the same as dividing by a 30 degree '''rotation'''.
'''rotation'''の割り算は、反対の方向のrotationにする効果があり、330度のrotationによる掛け算は、30度の'''rotation'''による割り算と同じです。
==rotationを使う==


==Using Rotations ==
'''R.x、R.y、R.z、 そしてR.s'''(R.w'''ではありません''')による'''rotation'''Rの特定の構成でアクセスが可能です。スカラー部R.sはrotationのアングルの半分のコサインです。vector部(R.x、R.y、R.z)はrotationの一般的な角度とrotationのアングルの半分のサインの積です。x、y、zが無効になることによる(あるいは無効な値をつくることにより)、逆の'''rotation'''を生成可能です。余談ですが、{{LSLG|float/ja|float}} 値のリポジトリとして'''rotation'''を使うことも可能で、各'''rotation'''は4つの{{LSLG|float/ja|float}} 値を貯蓄し、'''rotation'''から成り立つ{{LSLG|list/ja|list}}{{LSLG|float/ja|float}}の集まりから成り立つ{{LSLG|list/ja|list}}よりもさらに効率的ですが、それの中身を覗くのはコストが高いでしょう。
 
You can access the individual components of a '''rotation''' '''R''' by '''R.x, R.y, R.z, & R.s''' ('''not''' R.w).  The scalar part R.s is the cosine of half the angle of rotation.  The vector part (R.x,R.y,R.z) is the product of the normalized axis of rotation and the sine of half the angle of rotation.  You can generate an inverse '''rotation''' by negating the x,y,z members (or by making the s value negative). As an aside, you can also use a '''rotation''' just as a repository of {{LSLG|float}} values, each '''rotation''' stores four of them and a {{LSLG|list}} consisting of '''rotation''' is more efficient than a {{LSLG|list}} consisting of {{LSLG|float}}s, but there is overhead in unpacking them.


<div id="box"><div style="padding: 0.5em">
<div id="box"><div style="padding: 0.5em">
{| cellpadding=0 cellspacing=0
{| cellpadding=0 cellspacing=0
|-
|-
|rotation rot30X ||= {{LSLG|llEuler2Rot}}(<30, 0,0> * [[#DEG_TO_RAD|DEG_TO_RAD]] );||// Create a rotation constant
|rotation rot30X ||= {{LSLG|llEuler2Rot}}(<30, 0,0> * [[#DEG_TO_RAD|DEG_TO_RAD]] );||// rotation定数を作成する
|-
|-
|rotation rotCopy ||= rot30X;||// Just copy it into rotCopy, it copies all 4 float components
|rotation rotCopy ||= rot30X;||// rotCopyに全4つのfloatの構成をコピーします
|-
|-
|float X ||= rotCopy.x;||// Get out the individual components of the rotation
|float X ||= rotCopy.x;||// rotationの特定の構成を出力します
|-
|-
|float Y ||= rotCopy.y;||
|float Y ||= rotCopy.y;||
Line 112: Line 111:
|float S ||= rotCopy.s;||
|float S ||= rotCopy.s;||
|-
|-
|rotation anotherCopy ||= <X, Y, Z, S>;||// Make another rotation out of the components
|rotation anotherCopy ||= <X, Y, Z, S>;||// 構成から他のrotationを作ります
|}
|}
</div></div>
</div></div>




There is a built in constant for a zero '''rotation''' [[#ZERO_ROTATION|ZERO_ROTATION]] which you can use directly or, if you need to invert a '''rotation R''', divide [[#ZERO_ROTATION|ZERO_ROTATION]] by '''R'''. As a reminder from above, this works by first rotating to the zero position, then because it is a divide, rotating in the opposite sense to the original  '''rotation''', thereby doing the inverse rotation.
直接、あるいは'''rotation R'''を反転する必要があるならば、'''R'''によって[[#ZERO_ROTATION|ZERO_ROTATION]]を分割して使うことが出来る、zero '''rotation'''のビルトイン定数があります。上記の注意として、最初のzero potitionの回転による作業は 次にそれを分割させるため、オリジナルの'''rotation'''の逆向きに回転させ、その結果反転のrotationにします。
<div id="box"><div style="padding: 0.5em">
<div id="box"><div style="padding: 0.5em">
{| cellpadding=0 cellspacing=0
{| cellpadding=0 cellspacing=0
|-
|-
|rotation rot330X ||= <-rot30X.x, -rot30X.y, -rot30X.z, rot30X.s>;||// invert a rotation - NOTE the s component isn't negated
|rotation rot330X ||= <-rot30X.x, -rot30X.y, -rot30X.z, rot30X.s>;||// rotationの反転 - この構成は有効ではありません
|-
|-
|rotation another330X ||= [[#ZERO_ROTATION|ZERO_ROTATION]] / rot30X;||// invert a rotation by  division, same result as rot330X
|rotation another330X ||= [[#ZERO_ROTATION|ZERO_ROTATION]] / rot30X;||// 割り算によるrotationの反転で、rot330Xと結果は同じです
|-
|-
|rotation yetanother330X ||= <rot30X.x, rot30X.y, rot30X.z, -rot30X.s>;||// not literally the same but works the same.
|rotation yetanother330X ||= <rot30X.x, rot30X.y, rot30X.z, -rot30X.s>;||// まったくの同じものではありませんが、同じ働きをします
|}
|}
</div></div>
</div></div>


==Single or Root Prims vs Linked Prims vs Attachments ==
==単一もしくはルートプリム vs リンクプリム vs アタッチメント ==


The reason for talking about single or linked prim rotations is that for things like doors on vehicles, the desired motion is to move the door relative to the vehicle, no matter what the rotation of the overall vehicle is. While possible to do this with global rotations, it would quickly grow tedious.
単一かリンクプリムのrotationについて話す理由は乗り物のドラのようなもののためで、期待された動作は、たとえ乗り物全体のrotationに何があろうとも、乗り物と相対的にドアが動くことです。可能な限りこれをグローバルrotationにする間は、手をつけることすらないでしょう。
There are generally three coordinate systems a prim can be in: all alone, part of a {{LSLG|linkset}}, or part of an {{LSLG|attachment}}. When a prim is alone, i.e., not part of a {{LSLG|linkset}}, it acts like a root prim; when it is part of an {{LSLG|attachment}}, it acts differently and is a bit broken.
プリムには独自で、{{LSLG|linkset}}の一部、{{LSLG|attachment}}の一部があり、一般的な3つの等位なシステムがあります。プリムが独立しているとき、たとえば{{LSLG|linkset}}の一部ではなく、ルーとプリムのように動いたり、{{LSLG|attachment}}の一部のときは、ちょっと壊れたような異なる動きをします。


{{LSLRotGetSet}}
{{LSLRotGetSet}}


==Rotating Vectors ==
==Vectorの回転==


In LSL, rotating a {{LSLG|vector}} is very useful if you want to move an object in an arc or circle when the center of rotation isn't the center of the object.
LSLで、rotationの中心がオブジェクトの中心はないときに輪や弧の中でオブジェクトを動かしたいのなら、{{LSLG|vector/ja|vector}}の回転はとても使い勝手がよいです。


This sounds very complex, but there is much less here than meets the eye. Remember from the above discussion of rotating the [[#Combining Rotations|dart]], and replace the physical dart with a {{LSLG|vector}} whose origin is the tail of the dart, and whose components in X, Y, and Z describe the position of the tip of the dart. Rotating the dart around its tail moves the tip of the dart through and arc whose center of rotation is the tail of the dart. In exactly the same way, rotating a {{LSLG|vector}} which represents an offset from the center of a prim rotates the prim through the same arc. What this looks like is the object rotates around a position offset by the {{LSLG|vector}} from the center of the prim.
とても整っていますが、目で見るものは殆どありません。上記の[[#Combining Rotations|ダーツ]]の回転の議論を思い出しして、物理のダーツと{{LSLG|vector/ja|vector}}を、基点をダーツの尾尻、そしてX、Y、Zの構成ダーツの頂点のポジションと記述して、置き換えてみましょう。ダーツの尾尻にそって回転しているダーツは全体の頂点が移動し、rotationの中心はダーツの尾尻の弧です。まったく同じものは プリムの中心から同じ弧を通してプリムが回転する補正値を描写する、回転している{{LSLG|vector/ja|vector}}です。なんと、これはオブジェクトがプリムの中心からの{{LSLG|vector/ja|vector}}位置補正値周辺を回転するかのようにみえます。
<div id="box"><div style="padding: 0.5em">
<div id="box"><div style="padding: 0.5em">
{| cellpadding=0 cellspacing=0
{| cellpadding=0 cellspacing=0
|-
|-
|rotation rot30X ||= {{LSLG|llEuler2Rot}}(<30, 0,0> * [[#DEG_TO_RAD|DEG_TO_RAD]] );||// create a rotation constant, 30 degrees around the X axis
|rotation rot30X ||= {{LSLG|llEuler2Rot}}(<30, 0,0> * [[#DEG_TO_RAD|DEG_TO_RAD]] );||// X軸周りの30度のrotationの定数を作成します
|-
|-
|vector offset ||= <0, 1, 0>;||// create an offset one meter in the global positive Y direction
|vector offset ||= <0, 1, 0>;||// グローバルの有効なY方向に補正値1メートルを作成します
|-
|-
|vector rotatedOffset || = offset * rot30X;||// rotate the offset to get the motion caused by the rotations
|vector rotatedOffset || = offset * rot30X;||// グローバルの有効なY方向に補正値1メートルを作成します
|-
|-
|vector newPos || = {{LSLG|llGetPos}}() + rotatedOffset;||// move the prim position by the rotated offset amount
|vector newPos || = {{LSLG|llGetPos}}() + rotatedOffset;||// 補正値総数で回転したプリムのポジションを移動します
|}
|}
</div></div>
</div></div>


'''Nota Bene:''' Doing this is a move, so don't forget about issues of moving a prim off world, below ground, more than 10 meters etc.
'''Nota Bene:''' これによっておこなう移動は、10mもしくはそれ以下の地下に埋まっているオフワールドのプリムが移動する問題について忘れてはいけません。


== Constants ==
==定数==
=== [[ZERO_ROTATION]] ===
=== [[ZERO_ROTATION]] ===
ZERO_ROTATION = <0.0, 0.0, 0.0, 1.0>;<br/>
ZERO_ROTATION = <0.0, 0.0, 0.0, 1.0>;<br/>
A rotation constant representing a Euler angle of <0.0, 0.0, 0.0>.
このrotation定数は<0.0, 0.0, 0.0>のオイラーアングルの代数です。
 
=== [[DEG_TO_RAD]] ===
=== [[DEG_TO_RAD]] ===
DEG_TO_RAD = 0.01745329238f;<br/>
DEG_TO_RAD = 0.01745329238f;<br/>
A float constant that when multiplied by an angle in degrees gives the angle in radians.
DEGREES(角度)のアングルをラジアンのアングルに渡して乗算するときのfloat定数です。


=== [[RAD_TO_DEG]] ===
=== [[RAD_TO_DEG]] ===
RAD_TO_DEG = 57.29578f;<br/>
RAD_TO_DEG = 57.29578f;<br/>
A float constant when multiplied by an angle in radians gives the angle in degrees.
ラジアンのアングルをDEGREES(角度)のアングルに渡して乗算するときのfloat定数です。




[[Category:LSL_Types|Rotation]][[Category:LSL_Math]][[Category:LSL_Math/3D]][[Category:LSL_Constants]]
[[Category:LSL_Types|Rotation]][[Category:LSL_Math]][[Category:LSL_Math/3D]][[Category:LSL_Constants/ja]]

Revision as of 18:07, 7 January 2008

Rotation

LSL のrotation型は3Dでの方位描写に用いられます。(型名を太字で書くように心がけています。)方位あるいは3Dアングルは四方位と呼ばれる数学的オブジェクトによって描写されます。3つが各々面を表し、4つめがオブジェクトが右か左を向いているのかを表す、4つの数字による四方位を思い浮かべることができます。四方位を用いる主な強みは、ジンバルロックの影響を受けないことです。

四方位数学の込み入った内部処理はquaternionを参照しましょう。

listの関数とイベントのrotationとの関連はRotation Synopsisを参照しましょう。

テクスチャのテクスチャの回転時に関しても情報があります。

その他の説明

rotationは<X, Y, Z>の三つの数値で表現する以外にも、オブジェクトの各角度の回転量でも表現します。これはEdit Windowで使用され、例えば人々が見たとおりに作りやすくします。これら3つの数字はvector' であってrotation ではないのですが、同じ情報として表現できるようになっています。

3番目の方法は、手前のポイント、上部のポイント、そして左側のポイントをさす、3つのvectorを用いることです。実際には3つのうち2つが必要とされ、3つめは2つから計測します。

よくある事象として、4つの数字を結合することで成り立つrotationは分かりやすいけど、初心者が理解するには難しいというものです。幸いにも実際に内部でrotatonにて表現することが必要になるのは早々無く、簡単に変換をやり取りする関数があります。

フレミングの法則

LSLの全rotationはフレミングの法則に沿っています。右手の、人差し指は有効なX軸の方向をさします。中指はY軸を さすことでしょう。親指はZ軸をさします。オブジェクトを編集するとき、三色の軸の矢印はそれぞれ有効な軸(X: red, Y: green, Z: blue) を示します。

http://en.wikipedia.org/wiki/Right_hand_rule

また、右手を動かさないまま、有効な回転方向の決定にも使います。右手を握り、親指を立てて、好きな軸の方向をさします。人差し指と中指を有効なrotationの方向に向けて曲げます。Rotationは、X、Y、Z軸と回転、傾斜角度、揺れを参照する、よくある特殊な伝達手段です。

Roll Pitch Yaw

Rotationの結合

Rotationを結合するには、掛け算割り算の演算子を用います。rotationへの足し算もしくは引き算の演算子は予期する動作にはならないので、使おうとはしないでください。掛け算の演算子は 方向の加算に、割り算の演算子は方向の引き算に応用されます。つまり、X.s = -X.sのような構成ではないということです。 float以外の型は、floatに変換されます。 non-commutativeが重要です。 rotatonへの変換はRLで重要で、理由は単純です。例えば、4つの羽のあるダーツを持っていたとして、rotation<0,0,0>の尾尻から始めて、有効なX軸方面に照準をつけ、羽をZとY軸のみにし、そしてダーツの軸とダーツ盤の軸を一直線上にします。私達はXを45度前後で、Yを30度前後回転させてやっていますが、それは間違いです。

始めに、X軸を45度回転の後にダーツはX軸上にまだあり、ぶれないまま、長時間軸にそって回転したあと、ダーツは軸を45度にするでしょう。Y軸を30度前後回転しているダーツは、X軸から30度XZ面へ降下するでしょう(rotationでのフレミングの法則は、降下移動したY軸の周囲で小さく有効に回転する、という意味だと思い出しましょう)。ダーツ風の上昇先を30度下げ、飛び始めと同じ高さを飛びますが、ダーツはそう長くは昇降せずに長時間軸に沿って回転されます。

ほかの方法を取るとするならば、最初にY軸を30度回転させて、ダーツがXZ面に回転降下するのでしょうが、X軸上にはそう長くはいないことに注目します。ダーツのX軸とダーツ板が一直線上にはならないからです。今X軸周りを45度回転するダーツは、ダーツの尾尻を中心にし、40度右上がり向きに、長時間有効なダーツ板のX軸が30度の円錐上にあるポイントへ従います。X軸へと降下しているように見えたなら、ダーツはX軸の30度以下のポイントから旋回し、右上がりにXZ面上から出て、XY面上の最初の四分儀以下のポイントへ、ダーツは回転して進みます。

明らかにこれは最初のrotationとは異なる結果ですが、rotationの結果が変えられるだけのことです。

ラジアンの構成(オイラーアングルと呼ばれる)でX、Y、Zアングルによるvectorで作成できうる値を定義する必要がある、rotation'の要素を定数のrotationにすることは、llEuler2Rot 関数にて用いるrotationに変換するということです。直に自然なrotationを代わる代わる作ることができます。実際の箇所はrotationのアングルの半分のコサインで、vectorの部分はrotationのアングルの半分のサインとrotationの標準的な角度を掛け算されたものです。llRot2Eulerを使ってrotationからオイラーアングルの vectorにしましょう。

NOTE:LSLのアングルはラジアンであって角度ではありませんが、ビルトイン定数RAD_TO_DEGDEG_TO_RADを使うことで、簡単に変換できます。X軸周りの30度のrotationのために、あなたはこう使うこともできます。

rotation rot30X = llEuler2Rot(<30, 0,0> * DEG_TO_RAD); // 角度からラジアンに変換して、vectorをrotationのrot30Xに代入します。
vector vec30X = llRot2Euler(rot30X ); // rotationからvectorへ逆変換します。(値はラジアンとなるでしょう。)

オイラーvector用のrotationの命令

上記の記述より、一つの軸以上に機能するrotationで対処するときにはっきりするのは、行われる命令が臨界ということです。この上記のオイラーの記述は、少しもっともらしい類で、3つの角度周りの単一のrotationは全体のrotationとして定義されますが、rotationは何度にすればいいのかという質問をされます。この答えはグローバル座標中のZ、Y、Xです。オイラーの描写を用いて、一回で一つの軸以上の周囲をオブジェクトが回転するように試すのなら、Z、Y、X rotationの順に用いた正しいオイラーvectorを決定して、オブジェクトに結合したrotationあるいは適用したrotationで用いるためのrotationを取得するためのllEuler2Rotを用います。

ローカル rotation vs グローバル rotation

インワールドに相対なrotationとローカルオブジェクト自身に相対なrotationとを区別することは重要です。エディタにて、お互いをいったりきたりさせることができます。スクリプトにて、望ましい振る舞いを得るために互いに変換させるべきです。

ローカルrotationは、どのようにインワールドにてオブジェクトが回転するかに関わらず、オブジェクト自身の前後、左右、上下に埋め込まれた角度の周りで行われます。グローバルrotationは、南北、東西、高低のインワールド角度周りにて行われます。プリムを編集してローカルとグローバル間で角度を変えると、どのように色づけされた角度の矢印が変わるか、プリムを回転させることで違いを見ることができます。

LSLでは、rotationをローカル'グローバルにするかの違いは、ステートメントでrotationの評価される方法によります。

このrotationは、一定の30度のrotationへオブジェクトが左向きにrotation(myRot)を開始している状態によるものがローカルの30度のrotationです。最初の例であげた最初の演算の、ダーツ自身の長軸周りをダーツが30度ひねっているものようなものです。

rotation localRot = rot30X * myRot; // 空間のrotationによる、一定のrotationtで掛け算されたローカルのrotationを行ないます。

同じrotationの値を用いてグローバルrotationをすることは、その逆の命令ということではありません。これは2つめの例の2つめの演算で、ダーツが上昇回転して、空間のX軸にそって右に回るようなものです。このケースでは、存在しているrotation(myrot)はグローバルのX軸周りを30度回転しています。

rotation globalRot = myRot * rot30X; // 一定のrotationにより、空間のrotationで掛け算されたグローバルのrotationを行ないます。

rotationの結合について他の方法を考える

左右を括弧で覆われたものを除いて、評価する命令の中で行なわれるrotationを考えることにより、このローカルグローバルの違いについて考えたくなるでしょう。

<0,0,0>から始まって発生するlocalRotのケースではrot30Xが最初に行なわれ、空間のX軸にそってプリムが回転し、回転している間は、ローカルとグローバルの角度はオブジェクトのローカルX軸に沿っての回転を行なう効果を識別します。2つめのrotationであるmyRotはプリムをオリジナルのrotationに回転させましたが、それではさらにX軸のrotationが焼きつきます。何と、これはプリムがX軸にそって回転して、YとZのrotationが変わらなかったローカルrotationのようなものです。

<0,0,0>から再び始まっているglobalRotのケースでは、最初にオブジェクトはオリジナルrotation(myrot)まで回転されますが、それではオブジェクトの角度と空間の角度は長くは調整されません。そこで、2つめのrotationであるrot30Xはローカルのケースで、オブジェクトを空間のX軸に沿って30度回転させ、確実に行ないますが、効果はオブジェクトのX軸と空間のX軸が今回一致しなくなってから、空間のX軸にそった円錐体をとおしてオブジェクトを回転することです。なんと、これはプリムが空間のX軸にそって30度旋回したもので、ゆえにグローバルrotationのようなものです。

rotationの割り算は、反対の方向のrotationにする効果があり、330度のrotationによる掛け算は、30度のrotationによる割り算と同じです。

rotationを使う

R.x、R.y、R.z、 そしてR.s(R.wではありません)によるrotationRの特定の構成でアクセスが可能です。スカラー部R.sはrotationのアングルの半分のコサインです。vector部(R.x、R.y、R.z)はrotationの一般的な角度とrotationのアングルの半分のサインの積です。x、y、zが無効になることによる(あるいは無効な値をつくることにより)、逆のrotationを生成可能です。余談ですが、float 値のリポジトリとしてrotationを使うことも可能で、各rotationは4つのfloat 値を貯蓄し、rotationから成り立つlistfloatの集まりから成り立つlistよりもさらに効率的ですが、それの中身を覗くのはコストが高いでしょう。

rotation rot30X = llEuler2Rot(<30, 0,0> * DEG_TO_RAD ); // rotation定数を作成する
rotation rotCopy = rot30X; // rotCopyに全4つのfloatの構成をコピーします
float X = rotCopy.x; // rotationの特定の構成を出力します
float Y = rotCopy.y;
float Z = rotCopy.z;
float S = rotCopy.s;
rotation anotherCopy = <X, Y, Z, S>; // 構成から他のrotationを作ります


直接、あるいはrotation Rを反転する必要があるならば、RによってZERO_ROTATIONを分割して使うことが出来る、zero rotationのビルトイン定数があります。上記の注意として、最初のzero potitionの回転による作業は 次にそれを分割させるため、オリジナルのrotationの逆向きに回転させ、その結果反転のrotationにします。

rotation rot330X = <-rot30X.x, -rot30X.y, -rot30X.z, rot30X.s>; // rotationの反転 - この構成は有効ではありません
rotation another330X = ZERO_ROTATION / rot30X; // 割り算によるrotationの反転で、rot330Xと結果は同じです
rotation yetanother330X = <rot30X.x, rot30X.y, rot30X.z, -rot30X.s>; // まったくの同じものではありませんが、同じ働きをします

単一もしくはルートプリム vs リンクプリム vs アタッチメント

単一かリンクプリムのrotationについて話す理由は乗り物のドラのようなもののためで、期待された動作は、たとえ乗り物全体のrotationに何があろうとも、乗り物と相対的にドアが動くことです。可能な限りこれをグローバルrotationにする間は、手をつけることすらないでしょう。 プリムには独自で、linksetの一部、attachmentの一部があり、一般的な3つの等位なシステムがあります。プリムが独立しているとき、たとえばlinksetの一部ではなく、ルーとプリムのように動いたり、attachmentの一部のときは、ちょっと壊れたような異なる動きをします。

Getting and setting rotations of prims
Function Ground (rez'ed) Prims Attached Prims
Root Children Root Children
llGetRot
llGPP:PRIM_ROTATION
llGetObjectDetails
global rotation of prim global rotation of prim global rotation of avatar global rotation of avatar * global rotation of prim (Not Useful)
llGetLocalRot
llGPP:PRIM_ROT_LOCAL
global rotation of prim rotation of prim relative to root prim rotation of attachment relative to attach point rotation of prim relative to root prim
llGetRootRotation global rotation of prim global rotation of root prim global rotation of avatar global rotation of avatar
llSetRot*
llSPP:PRIM_ROTATION*
set global rotation complicated, see llSetRot set rotation relative to attach point set rotation to root attachment rotation * new_rot.
llSetLocalRot*
llSPP:PRIM_ROT_LOCAL*
set global rotation set rotation of prim relative to root prim set rotation relative to attach point set rotation of prim relative to root prim
llTargetOmega
ll[GS]PP:PRIM_OMEGA
spin linkset around prim's location spin prim around its location spin linkset around attach point spin prim around its location
Physical objects which are not children in a linkset will not respond to setting rotations.
†  For non-Physical objects llTargetOmega is executed on the client side, providing a simple low lag method to do smooth continuous rotation.

Vectorの回転

LSLで、rotationの中心がオブジェクトの中心はないときに輪や弧の中でオブジェクトを動かしたいのなら、vectorの回転はとても使い勝手がよいです。

とても整っていますが、目で見るものは殆どありません。上記のダーツの回転の議論を思い出しして、物理のダーツとvectorを、基点をダーツの尾尻、そしてX、Y、Zの構成ダーツの頂点のポジションと記述して、置き換えてみましょう。ダーツの尾尻にそって回転しているダーツは全体の頂点が移動し、rotationの中心はダーツの尾尻の弧です。まったく同じものは プリムの中心から同じ弧を通してプリムが回転する補正値を描写する、回転しているvectorです。なんと、これはオブジェクトがプリムの中心からのvector位置補正値周辺を回転するかのようにみえます。

rotation rot30X = llEuler2Rot(<30, 0,0> * DEG_TO_RAD ); // X軸周りの30度のrotationの定数を作成します
vector offset = <0, 1, 0>; // グローバルの有効なY方向に補正値1メートルを作成します
vector rotatedOffset = offset * rot30X; // グローバルの有効なY方向に補正値1メートルを作成します
vector newPos = llGetPos() + rotatedOffset; // 補正値総数で回転したプリムのポジションを移動します

Nota Bene: これによっておこなう移動は、10mもしくはそれ以下の地下に埋まっているオフワールドのプリムが移動する問題について忘れてはいけません。

定数

ZERO_ROTATION

ZERO_ROTATION = <0.0, 0.0, 0.0, 1.0>;
このrotation定数は<0.0, 0.0, 0.0>のオイラーアングルの代数です。

DEG_TO_RAD

DEG_TO_RAD = 0.01745329238f;
DEGREES(角度)のアングルをラジアンのアングルに渡して乗算するときのfloat定数です。

RAD_TO_DEG

RAD_TO_DEG = 57.29578f;
ラジアンのアングルをDEGREES(角度)のアングルに渡して乗算するときのfloat定数です。