原点に置いたスザンヌを親に、(0,0,-2)に移動したデフォルトキューブを子供にしました。 それぞれ、名前は Parent と Child にしました。 「順番に選んで、Ctrl-P で親子関係を付ける」というのが標準的な操作です。 その他にも、アウトライナー上で Shift を押しながらドラッグ&ドロップ で親子関係を付けることもできます。 親子関係を付ければ、親のスザンヌを動かしたり回転したりすると、それと一緒にキューブも移動します。 このあたりは、ごく普通に理解できるところです。 |
スザンヌを選択しながら、キューブのパラメーターを3Dビュー上のパネルで見ることはできません。 ということで、プロパティパネルでキューブをピン止め機能を利用して、こちらでキューブのパラメーターを見てみます。 スザンヌを選択して、動かしたり回したりしてみます。 ギズモの表示をローカル座標基準にすれば、スザンヌの座標の向きもギズモで直接見えます。 スザンヌを動かしてもぐるぐる回しても、キューブの座標は、(0,0,-2)のままで、あたかもパネルには 「親のスザンヌの座標系での、キューブの位置などの情報」 が表示されているように見えます。 この理解が直感的に分かりやすいのですが、実は違うのです。 |
一旦親子関係を解除して、位置や向きを整理します。 スザンヌを(2,0,0)と原点以外に置き、90度回してみました。 次いで、デフォルトキューブをスザンヌの下(2,0,-2)に置きます。 この状態から、スザンヌを親にキューブを子供にします。 |
スザンヌから見て赤い矢印(x軸)方向にキューブがあるわけですから、 キューブのスザンヌから見たローカル座標は(2,0,0)のはず…素直に考えればそうなります。 しかし、キューブの位置パラメーターは元のグローバル座標(2,0,-2)になっていて、 スザンヌを動かしても回してもそのままです。 パネル上に表示されている子供の位置情報は実は親から見たローカル座標ではないのですね。 どうもここで混乱が生じやすいようです。 |
このように奇麗な行列で表されます。 左上の3x3 の部分が回転とスケールを表します。 4列目の3つの数字は位置に対応します。 |
例えば(1,2,3)の位置にあるオブジェクトであれば、3x3の部分はそのままで、 4列目に位置情報が入りこのようになります。 (4行目は常に0,0,0,1になっていますが、ここの部分の情報は使いません。) |
実際にこれらの行列を表示させてみてみると 確かにそのような関係になっていることが分かります。 (数値誤差があるので、2ではなく1.999... となっていますが、そうした誤差は仕方が無いので無視します) あれっ?ローカル座標の情報、もってるじゃん |
先ほど見た、スザンヌの右側にあるのだから、ローカル座標は(2,0,0)ではないのかな? というサンプルで確認してみます。 誤差があるので、0 であるべきところが厳密に 0 にはなっていませんが、 位置(2,0,0)となっており、実はローカル座標も情報も持っていることが分かります。 |
直感的な「親の座標系」「子の座標系」の単純な考えで行きたい場合には、 この matrix_parent_inverse を間に挟まないでくれれば良いことになります。 それを行うのが、ctrl-P のメニューに、単純な親子付けの下にある幾つかの項目になっています。 Keep Transform Without Inverse(逆行列無しでトランスフォーム維持) は、仕組みを知らずに字面だけ見るとすぐには分からないのですが、 matrix_parent_inverse を無し(単位行列)にして親子付けをします。 |
こちらのメニューで親子付けをすれば、 直感的に理解しやすい形で、子供の位置情報が(2,0,0)、つまりスザンヌの右側と設定されます。 (スザンヌを90度回した状態で、回っていないキューブを親子化したので、 キューブは-90度回ったことになっていることに注意です) |
matrix_parent_inverse が効いていないので、 子供の位置を(0,0,0)に移動すれば、親と完全に重なります。 直感的な「親の座標系」「子の座標系」という理解で考えられることが分かります。 |
2手間かかってしまうのが面倒なのですが、 一旦 Alt-P で子供の位置を維持したまま親子関係を解除、 そして改めて(Keep Transform Without Inverse)で親子関係を組みなおせば良いことになります。 |
このように引き延ばしてスケールで歪めたスザンヌにたいして、 (Keep Transform Without Inverse)で親子関係を組んでみましたが、Scale のパラメーターが、 親のスケールに関係なく1のままです。 しかし、本来は親が拡大されれば子も拡大されるはずなので… 親のスケール変換を打ち消すための matrix 情報がどこかに残っているはずです。 |
子の matrix_parent_inverse を見ると、単位行列ではなく、スケールの情報が残っていることが分かります。 |
最終手段としては、スクリプトで強引に matrix_parent_inverse を単位行列に書き直す手もあります。 |
子供のキューブも、スケールも含めて完全に親の座標変換に影響されて、 引き延ばされたキューブになりました。 |