LightWaveでメカの多重関節を作る

最終更新:2017/02/10

以前はメカの関節についてはモデラーの中心点移動ツールを使って中心点を関節の駆動部分に指定することで実現していた。今でもこの方法は有効だけど、すべてのパーツを別のレイヤーかオブジェクトとしてあらかじめ分割しておく必要があった。

この方法は、煩雑な設定が不要で簡便なのが長所で、簡単なモデルの場合はいいんだけど、人型ロボットのように見栄えがするようにスタイリングやポージングを懲りたい場合はバランスの調整が難しいという欠点があった。現在はメカにもボーンを組み込んでウェイト・マップを使って関節を動かすのが主流になりつつあるので、単純に今風な方法でないとも言える。

LightWaveでのメカの多関節化についてはノウハウがあまり貯まっていなかったので、人型ロボットのような本格的なメカに取り組む前に数本程度のボーンで構成される簡単な多関節モデルで試してみることにした。

モデラー

今回は、次の画像のようなモデルを用意した。すべての部分が1レイヤー上に配置されている。このうち盾のような部分を三軸で回転させられる可動モデルとしたい。

難しいことはやってないので作り方は省略するけど、5ポイント以上のポリゴンがあるとボーンの旋回に綺麗に追随してくれないことがあり、悪くするとレンダリングした時に無視できないくらいの誤差が生じ、共有しているはずのエッジが分離してしまう不具合を起こすので、極力4ポイント以下のポリゴンに整理しておく。

スケルゴンの構成

モデルには次の画像のような構造の5本のスケルゴンを組み込んである。実際の動作に必要なスケルゴンはCenter、Arm及びShieldのみ。Rootは母機であるパワーユニットを固定するために存在する。Null_BoneはCenterスケルゴンとArmスケルゴンの回転軸のほんのわずかなズレを補うためにあり、動作には直接関係ない。繰り返しになるけど、Rootスケルゴンを最初に作る時だけドラッグで引き切らないと長さがゼロのスケルゴンができてしまうので注意。

モデルの座標情報を参照してスケルゴンの位置を回転の中心軸に可能な限り精密に合わせておく。中心軸になりそうなところにポイントができるように平均統合(Weld Average)ツールなどを利用すると座標を取得しやすい。

Shieldスケルゴンを最終的にはバンク(スケルゴンのヘッドからテイル方向を軸とする回転)で制御したい関係上、他のスケルゴンもすべてバンクで制御することになってしまった。ロボットの腕や脚などを作りたい場合はジンバルロックを避けるためにも極力ピッチで制御するのが常套手段ではある。

画像を示す必要があるかどうかは微妙だけど、スケルゴンツリーは次の画像のとおり。左右の区別の必要があるかもしれないと思って接尾辞に「_L」を付けてあるけど、同じレイヤー上に左右のスケルゴンを置かない場合は必要なかった(上の画像では接尾辞を省略している)。表示上、Null_Boneのウェイト・マップ名も出ているけど、実際のマップは作成していない。

バンクハンドルの設定

これは後でもいいんだけど、レイアウトに移した時にボーンのバンク角に中途半端な値が入ってしまって操作しづらくなることがあるので、スケルゴン回転(Rotate Skelegons)でバンクハンドル(Bank Handle/Pitch Plane)をキリの良い値に設定しておく。3つの値のうち、いずれかひとつを1.000にすればいいんだけど、今回のようにスケルゴンが三次元的に直角に連なっている場合はどっちが前か後ろかはっきりしないので、どこをその値にすればいいのかはスケルゴンにより異なり、これといった決まりがない。レイアウトに移してみないとどうなるかわからないのが実際のところで、こういったところがLightWaveのわかりにくいところ。

スケルゴン編集(Edit Skelegons)でも同様のことはできるけど、数値入力ウィンドウがなく、どうしても誤差が入るので、スケルゴン編集で視覚的に大体整えたらスケルゴン回転で一番大きい値を1.000にするのが一番確実。

ウェイト・マップの作成

各所のウェイト・マップを作成する。ウェイト・マップ名はレイアウトでの作業を簡略化するために、スケルゴンと同じ名前にしておく。メカは基本的に100%か0%かの2値しかないので、MAP値指定(Set Map Value)で割り当てていく。

次の画像は、前後(垂直)方向へ回転させるためのCenterスケルゴンに対応する部分をウェイトシェイドで表示したもの。

同じく、左右(水平)方向へ回転させるためのArmスケルゴンに対応する部分。なお、Centerスケルゴンに対応する部分とはポイントを共有しないように一度分割しておかないと、スケルゴンを回転させた時にねじれてしまう。

最後に、盾の部分をひねり方向へ回転させるためのShieldスケルゴンに対応する部分。

残りの部分にはウェイト・マップを設定しなくても特に問題ないけど、気になるようならRootスケルゴンに対応するウェイト・マップに設定しておくとよい。

スケルゴン回転でチェック

次に、スケルゴン回転(Rotate Skelegons)でうまくスケルゴンとウェイト・マップが連動しているかをテストする。関節になるはずの部分がつながっていたりするようなモデリングのミスに気付くこともある。ここでは、バンク角のみを使用する。

ちなみに、スケルゴン回転でチェックできるのは、ウェイト・マップによる変形のみで、レイアウトにおけるボーンからの距離のフォールオフによる変形の影響をチェックすることはできない。

次の画像は、Centerスケルゴンを指定しての垂直方向の回転のチェック(入力はバンク)。Centerスケルゴンの子スケルゴン以下のすべてのスケルゴンが旋回に追従しているのがわかる。

一度スケルゴンの回転をリセットしてから、Armスケルゴンの水平方向の回転チェック(同じく入力はバンク)。次の画像のように、水平方向にのみ旋回している。

次の画像は、Shieldスケルゴンのひねり方向の回転チェック。同スケルゴンはアームの蝶つがい部分を中心に引いてあるので盾の部分は180°で裏表が反転するように動く。

レイアウト

モデラーで問題ないようであれば、レイアウトに移る。モデルをアイテムの追加で呼び出し、スケルゴン変換かSkelegon Readerプラグインでボーンを組み込む。スケルゴン・エディタを使わなかった場合は、どちらでもほぼ同じ結果になると思う。Skelegon Readerは、スケルゴン・エディタでのバンクの整列などが反映されるけど、スケルゴン変換は反映されないという違いがある。

そのままの状態で、各所のボーンを旋回させると次の画像のようにモデルが大きく歪む。特に、Centerボーンを旋回させた時の歪み具合がひどいけど、場所によってはボーンからモデルが離れてしまっている。ワイヤーフレームで表示させてみると、細かいところであちこち歪んでいるのが確認できる。

これは、ウェイト・マップ以外にもボーンからの距離のフォールオフで変形してしまっているのが原因。オブジェクトの頂点は、接続している一連のボーンによる変形にも影響を受けるので、更に歪みがひどくなる。ウェイト・マップとフォールオフの併用は、モデラーとレイアウトが独立していて二者間を行ったり来たりしなければならないという難点を克服しようと試みたものであり、生物系モデルのアニメーションの場合などはワークフローを改善する。ウェイトの設定が多少雑でもなんとかなるLightWaveの特徴でもあるんだけど、メカの場合はかえって邪魔になる。

そこで、Root、Center、Arm及びShieldの各ボーンのプロパティを次の画像のように変更する。「ウェイトのみ使用(Use Weight Map Only)」にチェックを入れるとボーンのフォールオフの影響をまったく受けなくなる。ただし、無効にも関わらずフォールオフ種はグレーアウトされないので、非常に紛らわしい。

「ウェイト正規化(Weight Normalization)」はデフォルトでチェックが入っているけど、ひとつの頂点のウェイトの合計値が100%を超えないようにするためのもので、今回は100%と0%以外は使っていないので、チェックを入れても外しても変化はない。「固定長の強さで乗算(Multiply Strength by Rest Length)」のチェックは外しておく。

ちなみに、「高速ボーン(Faster Bones)」は影響を受けるボーンを近いものから4本までに限定するもの。ボーンが多くて変形に時間がかかりすぎる場合に使うもので、ここではあまり関係ない。

Null_Boneについては、次の画像のように「ボーン有効(Bone Active)」のチェックを外してボーンそのものを無効にしておく。有効なままにしておくと、モデラーのスケルゴン回転では想定していなかった変形を生じたり、ウェイト・マップを割り当てていない部分全体が回転してしまったり何かしらの影響を与えてしまうことがある。

ボーンの設定が終わると、初期状態で生じていた歪みは解消され、モデラーのスケルゴン回転でチェックしたとおりの旋回を行えるようになる。旋回角度が大きければ大きいほど歪みがひどくなる傾向にあるので、少し回転させて問題ないようなら、デザイン上の制限はともかく180°くらいまで一気に回転させてテストしてみる。これで歪みが解消されているかどうか最終確認ができる。

なお、Shieldボーンが二重になっているように見えるのは、盾を内側と外側に分割して個別に動くように後で改善したため。

完成

以上の方法で多重関節化したモデルが次の画像。大きく前に旋回させても歪みは生じていない。これでLightWaveでも1レイヤー上にデザインした多関節メカのモデルをボーンとウェイト・マップで動かすことができるようになった。

参考記事


JanetterでRTユーザーにも相互フォローアイコンを表示する

最終更新:2017/02/01

TwitterクライアントJanetterでは、ツイートの発信元のユーザーと相互フォローになっている場合はツイート・ヘッダーに相互フォローアイコンとしてスマイル・マークが表示される。どのユーザーと相互フォローなのかひと目で判るJanetterの特徴のひとつ。本家Twitterの純正クライアントではタイムラインに相互フォローかどうかを示す情報は直接表示されない。

しかしながら、ツイート・フッターに表示される、リツイートしたユーザーを示す「Retweeted by (ユーザー名)」には同様のアイコンは表示されない。そこで、リツイートしたユーザーも相互フォローかどうかを判定し、ユーザー名にアイコンを表示するように改良する。

免責事項

本記事で紹介しているコードを使用したことによって生じた事態に当方は一切責任を負えない。動作を保証するものではないし、動作したとしても運用上生じたあらゆる問題にも同様に責任を負いかねる。相互フォローアイコンはあくまでもTwitterサーバーの応答を元にした目安であって、アイコンが表示されていないことをもってフォローを解除してしまったりして相手の心証を害することになっても関知できない。

決まり文句だけど、大事なことなので。

テンプレートの加工

Janetterカスタム・テーマのtweet.tplからリツイートユーザーを表示している次のようなコードを探す。独自にあちこち変更しているので、行番号はおおよその位置。

カスタム・テーマの作り方がわからない場合は、以前の記事をよく読んでもらって、新しくカスタム・テーマを追加する。くれぐれも、コモン・コードや標準で実装されているテーマに手を加えて上書きしてしまわないこと。

								<div class="tweet-footer-text">
									<p class="from">
										<span class="source">
											{if $sender}{* DM *}
												{if $isMe}
													&nbsp;to&nbsp;{$recipientName}
												{/if}
											{elseif $sourcevisible}
												{if $retweeted_status}{* RT *}
													via&nbsp;{$retweeted_status.source}
												{else}
													via&nbsp;{$source}
												{/if}
											{/if}
										</span>
									</p>
									{if $retweeted_status}
										<p class="retweetedBy">
											<span class="icon-rtby"></span><span>Retweeted by </span>
											{$retweetedBy}
										</p>
									{/if}
								</div>

位置を特定できたら、「Retweeted by」のテキストとユーザー名を示す{$retweetedBy}の間に次のようなコードを追加する。

ツイート・ヘッダーと同じようにユーザー名の後にアイコンが続くようにしてデザインを統一したいと思うかもしれないけど、ユーザー名が長い場合はタイムラインからはみ出した部分が自動的にカットされてしまうので、相互フォローアイコンが見えなくなる。

								<div class="tweet-footer-text">
									<p class="from">
										<span class="source">
											{if $sender}{* DM *}
												{if $isMe}
													&nbsp;to&nbsp;{$recipientName}
												{/if}
											{elseif $sourcevisible}
												{if $retweeted_status}{* RT *}
													via&nbsp;{$retweeted_status.source}
												{else}
													via&nbsp;{$source}
												{/if}
											{/if}
										</span>
									</p>
									{if $retweeted_status}
										<p class="retweetedBy">
											<span class="icon-rtby"></span><span>Retweeted by </span>
											{if $friendvisible && $user && $user.both_following}
												<span class="friend-rt"/>
											{/if}
											{$retweetedBy}
										</p>
									{/if}
								</div>

Janetterのデバッグ・モードを使えばわかるんだけど、122~124行と125行のコードを入れ換えればユーザー名の後にアイコンを表示すること自体はできるので、どうしてもアイコンの位置にこだわりたい人はデベロッパ・ツールを駆使して調べてみるといいだろう。

CSSの追加

上のテンプレートのコードでは、friend-rtというクラスを新しく使用しているので、tweet.cssの任意の場所に次のCSSを追加する。200行あたりに相互フォローアイコンに関する設定があるので、その辺がちょうどいいかもしれない。行番号は同じく大体の位置。

span.friend-rt{
	display: inline-block;
	width: 9px;
	height: 9px;
	text-indent: -99999px;
	background-image: url(../../../Common/images/timeLine/smile.png);
}

ちなみに、float: left;float: right;などを追加すると、相互フォローアイコンだけ独立して表示させることもできる。改行されてしまって見栄えはあまり良くないので、お好みで。

関連記事


WordPressのビジュアルエディタにFont Awesomeを表示する

最終更新:2017/01/16

本記事は、前の記事の方法でFont Awesomeを導入していることを前提としています。


Font Awesomeを導入しただけでは、プレビューを含む実際のサイトの表示にしか反映されない。ビジュアル・エディタにも表示されるようにしないと、プレビューでマークアップが間違っていないか逐一確認しなければならないので執筆の能率が落ちる。Font Awesomeは便利だけど、能率が悪くなると使う動機が薄れていく。可能ならばビジュアル・エディタにもFont Awesomeを表示させたい。

本記事を書いている時点でのFont Awesomeのバージョンは4.7.0。

WP Visual Icon Fontsは更新が停滞中

Font Awesomeをサイトとビジュアル・エディタの両方に表示させるプラグインとしてはWP Visual Icon Fontsが有名だけど、更新が年単位で滞っている。Font Awesome 4.0.3の時点で止まっているので、比較的最近追加されたアイコンフォントには対応していない。最初はその方法しか見つからなかったので試してみたけど、WordPress 4.7.1でも動作はするようだ。

使えないアイコンがあるとなると少々気持ち悪い。メジャーどころのアイコンは4.0までで実装されていたので実用上はそれほど困らないだろうけど、WP Visual Icon Fontsがいつまで使えるかはわからない。なんとかプラグインに頼らない方法はないか調べることにした。

エディタのCSSにスタイルを追加する方法

当初は、Font Awesome用のCSSをeditor-style.cssに単純にインポートすればいいのではないかと考えたんだけど、どうもそれではうまくいかない。強引に全体をコピー&ペーストする方法も考えたけど、Font Awesomeがバージョンアップする度にそれをやるのでは今後のメンテナンス作業に手間がかかりすぎる。CDN(Contents Delivery Network)を使って本家からCSSを引っ張ってくる方法を紹介している記事もあったけど、せっかく自分のサーバーにFont Awesomeを導入したのにビジュアル・エディタの表示のためだけにCDNを使うのでは二度手間になる。

そこで、functions.phpに次のコードを追加する。念のため、不具合があった時にすぐに戻せるように子テーマを編集するほうが好ましい。add_editor_style関数は、WordPress 3.0で追加された比較的新しい関数で、editor-style.cssに記述されているビジュアルエディタ専用スタイルシートに更にスタイルを追加するもの。引数にはFont AwesomeのCSSを指定するわけだけど、テーマが存在しているディレクトリ(フォルダ)から見て相対パスで指定する。

function vf_add_editor_styles() {
	add_editor_style( 'font-awesome/css/font-awesome.min.css' );
}
add_action( 'admin_init', 'vf_add_editor_styles' );

functions.phpを保存してテーマのディレクトリにアップロードする。

表示の確認

新規記事を用意してテキスト・エディタでマークアップを打ち込んだ後、ビジュアル・エディタに切り替えると次のように表示される。Font Awesome 4.1~4.7で実装されたアイコンも表示されているので、WP Visual Icon Fontsを無効化し忘れたということはないことがわかる。

問題点

綺麗にまとまったように思えるけど、欠点もある。

WP Visual Icon Fontsは、TinyMCE(ビジュアル・エディタ)にアイコン挿入用のドロップダウンメニューを追加し、視覚的にアイコンを選べるようになっている。これはこれで便利で、上記の方法を使う場合は従前のようにFont Awesomeのページに行って、使いたいアイコンとそのクラス名を調べてこなければならない。

最新のアイコンは使えなくてもいいから手軽にアイコンを入力できるほうがいいか、プラグインの更新に左右されずに最新のアイコンと機能を使えるほうがいいかを選択することになる。同居させてもおそらく問題は起きないだろうけど、CSSは重複してお互いに打ち消し合う。

もっとも、WP Visual Icon Fontsのドロップダウンメニューでアイコンを選んだ場合でも、次のようなマークアップが挿入されてしまう。公式では<span>要素は文脈上必要でない限り、必須ではないとされている。

<i class="fa fa-camera-retro"><span style="color: transparent; display: none;">icon-camera-retro</span></i>

Font Awesome 4.0の頃はこれが正式な書き方だったのかもしれないけど、場合によってはテキスト・エディタに移って消して回らなければならないという問題も起こりえるため、一概にどちらが優れているとは言えないかもしれない。

関連記事

参考記事


WordPressにFont Awesomeを導入する

最終更新:2017/01/15

WordPressの基本テーマのひとつであるtwentyfifteenは、コンテント・フッターのメタ情報などの表示にGenericonsを使用していて、それに関連するファイルも内蔵して配布されている。本ブログのテーマもtwentyfifteenを親テーマとしてGenericonsを引き継いで使用している。

GenericonsはGenericons Neueへ

ところが最近(2016年後半?)、GenericonsはGenericons Neueと名前が変わった。インターネット・サービスのブランドなどに関連する一部のアイコンが削除され、従来のアイコンのデザインも変わり、装いも新たになった。しかしながら、SVGを使う方式がメインになったのか、使い方が変わってしまったようだ。WordPressをはじめとする、レンタルサーバーなどで運用されている一般のサイトに実装するためのガイドが書かれているわけでもない。

GitHubを見るとicon-fontというフォルダに旧Genericonsと似たような構成のファイルもあるようだけど、ダウンロード用パッケージが用意されているわけではないので、ちょっとハードルが高い。もともとWordPressのデフォルト・テーマを流用していただけなので旧Genericonsの使い方をちゃんと理解しているとは言い難く、旧版のコードの書き方も今となっては調べようがない。そのため、仮にバイナリを含むファイルをダウンロードできたとしても、その先どうしたらいいのか見当がつかない。プログラミング言語は世界共通語と言え、言葉は通じなくてもやりたいことが伝わることもよくあるから、説明は英語で書いてあっても、コード例が書いてあればなんとなくわかることも多いんだけども。

いずれにせよ、新アイコンを使うならファイルの差し替え程度では済まないので、Genericons Neueをちゃんと理解してテーマを改造しなければならなくなった。個人利用でも商利用でも目的に制限を受けないGPL-2.0ライセンスだったのは魅力だったんだけど、使い方を理解できないのでは仕方ない。Genericons Neueを使うために膨大な作業時間と試行錯誤を要することが予想されるのも気が進まない理由のひとつ。

そこで、旧Genericonsと似たようなフォント感覚で使用できるFont Awesomeを試してみることにした。

本記事を書いている時点でFont Awesomeのバージョンは4.7.0。

Font Awesomeのアップロード

Font AwesomeのWEBサイトからzipアーカイブのパッケージをダウンロードして作業フォルダに解凍する。zipアーカイブにはバージョン番号がついているので、削除してフォルダ名をfont-awesomeとしておくと後の作業がしやすい。

使用しているテーマが存在するディレクトリにfont-awesomeフォルダごとアップロードする。実際にはどこのパスにアップロードしてもいいんだけど、テーマ内のディレクトリのほうがわかりやすいだろう。今回はCSSを使用して導入するので、赤字以外のディレクトリとファイルは必要ないので削除するけど、あっても特に支障はない。

  • font-awesome
    • css
      • font-awesome.css
      • font-awesome.min.css
    • fonts
      • FontAwesome.otf
      • fontawesome-webfont.eot
      • fontawesome-webfont.svg
      • fontawesome-webfont.ttf
      • fontawesome-webfont.woff
      • fontawesome-webfont.woff2
    • less
    • scss
    • HELP-US-OUT.txt

なお、上のリストのフォルダアイコンやファイルアイコンはFont Awesomeで実現している。

functions.phpからFont Awesomeを組み込む

Font Awesomeは、<head>要素内の<link>要素からCSSをリンクして使用する。WordPressに正しくスタイルを取り込ませる方法として、wp_enqueue_style関数を使用する。テーマのfunctions.phpに次のコードを追加する。引数にはget_stylesheet_directory_uri関数を使用してstyle.cssのある場所を参照し、その後に続く相対パスを連結して指定する。get_stylesheet_directory_uri関数は末尾にスラッシュ(/)を返さないので、相対パスの前に必ずスラッシュを書き足しておく。

function enqueue_font_awesome_stylesheets(){
	wp_enqueue_style('font-awesome', get_stylesheet_directory_uri() . '/font-awesome/css/font-awesome.min.css');
}
add_action('wp_enqueue_scripts','enqueue_font_awesome_stylesheets');

header.phpに直接<link>要素を書き込んでも結果は同じだけど、WordPressに「style.css以外にどういったスタイルシートを組み込みたいのか」を明確に知らせることができる。twentytwelve以降はfunctions.phpからCSSを読み込む仕組みになっているはずなので、そこに追加するという意味合いになる。繰り返しになるけど、本ブログのテーマはtwentyfifteenをベースにした子テーマを使用している。

(非推奨)header.phpに直接Font Awesomeを組み込む

※この節の方法は、functions.phpからwp_enqueue_style関数でスタイルシートを組み込んでいない古いタイプのテーマでのみ使うべき。誤った作業の記録として残してある。

Font Awesomeは、<head>要素内の<link>要素からCSSをリンクして使用するようになっている。テーマのheader.phpを次のように編集し、スタイルシートを読み込ませるのが最も簡単な方法。相対パスを指定すると、各投稿ページのURLをベース・ディレクトリとしてそこからFont Awesomeを探してしまうので、長くなっても絶対パスを指定する。

<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>">
	<meta name="viewport" content="width=device-width">
	<link rel="profile" href="http://gmpg.org/xfn/11">
	<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
	<!--[if lt IE 9]>
	<script src="<?php echo esc_url( get_template_directory_uri() ); ?>/js/html5.js"></script>
	<![endif]-->
	<?php wp_head(); ?>
	<!-- Font-Awesome 4.7.0 stylesheet -->
		<link rel="stylesheet" href="http://example.domain.name/wp-content/themes/twentyfifteen-child/font-awesome/css/font-awesome.min.css">
</head>

表示例

 camera-retro
recycle (Ver. 4.1)
bus (Ver. 4.2)
motorcycle (Ver. 4.3)
battery-3 (Ver. 4.4)
hashtag (Ver. 4.5)
question-circle (Ver. 4.6)
thermometer-three-quarters (Ver. 4.7)
snowflake-o (Ver. 4.7)

<i class="fa fa-fw fa-2x fa-camera-retro"></i> camera-retro
<i class="fa fa-fw fa-2x fa-recycle"></i> recycle (Ver. 4.1)
<i class="fa fa-fw fa-2x fa-bus"></i> bus (Ver. 4.2)
<i class="fa fa-fw fa-2x fa-motorcycle"></i> motorcycle (Ver. 4.3)
<i class="fa fa-fw fa-2x fa-battery-3"></i> battery-3 (Ver. 4.4)
<i class="fa fa-fw fa-2x fa-hashtag"></i> hashtag (Ver. 4.5)
<i class="fa fa-fw fa-2x fa-question-circle"></i> question-circle (Ver. 4.6)
<i class="fa fa-fw fa-2x fa-thermometer-three-quarters"></i> thermometer-three-quarters (Ver. 4.7)
<i class="fa fa-fw fa-2x fa-snowflake-o"></i> snowflake-o (Ver. 4.7)

関連記事

参考記事


固定ページに構造化データを考慮してパンくずリストを追加する

最終更新:2017/01/13

WordPressの固定ページにパンくずリストを追加する。どうせ追加するなら、Googleが収集して階層構造を認識してくれる構造化データを考慮したマークアップ記述にしたい。

基本的に、構造化データの記述を支援してくれるBreadcrumb NavXTプラグインを利用する。本記事を書いている時点での最新バージョンは5.6.0

インストール方法に特別変わった手順は必要ないので省略する。

パンくずリストを追加すること自体はそれほど難しくはないけど、構造化データを考慮するとなると話が異なってくる。最初は気付かずにだいぶ古い記事を参考にしていたのでGoogleの構造化データテストツールで試行錯誤しても一向にエラーが解消されずに苦労したので、改めて書き留めておく。

Breadcrumb NavXTの設定

Breadcrumb NavXTにはデフォルトでパンくずリストの各要素のためのマークアップがあらかじめ設定されているけど、Googleのパンくずリスト(Breadcrumbs)に関するドキュメントやサンプルを見ると若干異なる。今回は、RFDa形式のマークアップを参考にした。

また、Googleのサンプルには<li>要素にパンくずリスト用のプロパティやフィールドが直接記述されているけど、Breadcrumb NavXTの設定画面でそれをやろうとすると拒否されてしまう。そのため、<span>要素をもうひとつ追加し、その中にプロパティを記述することにした。

リンクありのマークアップ

次のマークアップは固定ページ用、あるいはホームページ用の「リンクあり」のパンくずリストの要素。見やすくするために改行、インデントしてあるけど、実際の設定画面に入力する時は改行やタブを削除する。

<li>
	<span property="itemListElement" typeof="ListItem">
		<a property="item" typeof="WebPage" href="%link%" class="%type%">
			<span property="name">%htitle%</span>
		</a>
		<meta property="position" content="%position%">
	</span>
</li>

リンクなしのマークアップ

次のマークアップは固定ページあるいはホームページのもので、現在表示されているページなど、リンクする必要がないページのパンくずリスト。

<li>
	<span property="itemListElement" typeof="ListItem">
		<span property="name">%htitle%</span>
		<meta property="position" content="%position%">
	</span>
</li>

投稿などのフォーマットについて

ブログ記事などの投稿(post)にパンくずリストを表示したいケースもあるだろうし、Breadcrumb NavXTにも設定項目が備えられてはいる。ただ、投稿の場合は複数のカテゴリを設定できるために親子関係が複雑になりがちで、Breadcrumb NavXTの設定以外にも考えなければならないことが多くなる。基本的な考え方やマークアップは固定ページと同じだけど、本記事ではとりあげない。

テンプレートにパンくずリストを追加する

いつも使っているテーマのテンプレートにパンくずリストを追加する。次のコードは、twentyfifteenテーマの一般用固定ページを表示するcontent-page.phpに変更を加えた例。

	<header class="entry-header">
		<?php /* breadcrumbs */ ?>
			<ol class="breadcrumbs" typeof="BreadcrumbList" vocab="http://schema.org/">
				<?php if(function_exists('bcn_display'))
				{
					bcn_display();
				}?>
			</ol>
		<?php /* breadcrumbs */ ?>

		<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
	</header><!-- .entry-header -->

RFDa形式の構造化データとしてリスト化したい場合は、3行目と8行目のパンくずリストを囲むタグを<ol>要素にして順序のあるリストにしておくことをGoogleは推奨している。

Googleで受け付けてくれる構造化データを意識しない場合は、Breadcrumb NavXTのインストールガイドにもあるように3行目と8行目は<div>タグでもよく、リストの各要素はデフォルト設定のような<span>要素でも構わない。特にCSSを設定しなくても簡素なテキストとして横一列にパンくずリストが並ぶ。

CSSの調整が手間だったので、パンくずリストをエントリ・ヘッダーの中に入れてしまったけど、サイトのデザインや他の構造化データの問題で都合が悪い場合は外に出してしまっても問題ない。構造化データというのは、ブラウザに表示されない<meta>要素などとは異なり、検索エンジンが識別に使用するクラス、プロパティ、フィールドが設定してありさえすれば、どういう文脈のところに入っていても識別される。つまり、検索エンジンが識別するためだけの特別なデータを別に用意する必要はなく、人間が見るための情報を検索エンジンに意味をわからせるためのデータとして兼ねてしまえるということ。

テンプレート・ファイルの変更が済んだらWordPressのサーバーにアップロードする。

構造化データのテスト

念のため、エラーが出ていないか構造化データ テストツールで固定ページ固有のURLを入力し、テストする。マークアップの改善がテストツールにすぐに反映されない場合は、ページのソースを表示させてパンくずリストの部分だけコピーしてエラーや警告が出ている部分に貼り付けたり、手入力で修正することでチェックだけはできる。

RFDa形式の場合、Googleによって解釈されたパンくずリストは次のように表示される。問題ないようならば、Googleボットがクロールに来るのを待つ。

クローラーが来て情報が収集されると、構造化データに従い、次の画像のようにパンくずリストが検索結果にも表示されるようになる。

CSSの追加

最後に、パンくずリスト用のCSSをテーマのstyle.cssに追加する。構造化した上で普通のテキストでいい場合はリストを横並びにするCSSだけでいいはず。

デザインは好みの問題が大半を占めるので、次のCSSはあくまでも例に過ぎない。特に、最近のCSSは高度化していて画像を使っていないのが不思議なくらい非常に凝った作りになっているものも多いので、CSSのコードを眺めているだけでは何を意図したプロパティなのかはわかりにくいと思われる。気になるデザインのパンくずリストを見つけたらブラウザの要素解析ツールで検証してみるといいだろう。

.breadcrumbs {
	list-style: none;
	display: table;
	margin-bottom: 2px;
	font-size: 12px;
}

.breadcrumbs li {
	display: table-cell;
	position: relative;
	left: 20px;
	padding: 0 20px 0 0;
	margin: 0;
	background-color: #c7dcef;
	line-height: 20px;
/* 	color: #fff; */
}

.breadcrumbs li > span {
	position: relative;
	padding: 0 10px;
}

.breadcrumbs li:after {
	content: "";
	position: absolute;
	top: 0;
	right: -4px;
	border: 0 solid #fff;
	border-left: 10px solid #c7dcef;
	border-top: 10px solid #c7dcef;
	border-width: 10px 10px;
	width: 0;
	height: 0;
}

.breadcrumbs li:before {
	content: "";
	position: absolute;
	top: 0;
	left: -20px;
	border: 0 solid #c7dcef;
	border-left: 10px solid transparent;
	border-top: 10px solid transparent;
	border-width: 10px 10px;
	width: 0;
	height: 0;
}

上記のCSSを使うと、次のようにパンくずリストが表示される。リストの各要素の前(:before疑似要素)と後(:after疑似要素)に斜めの切り欠きを追加している。

参考記事


LightWaveで二次元キャラ系人物モデリング奮闘記 ―視線コントロール編―

最終更新:2017/01/13

視線コントロールには、一般には目の中心軸の延長線上に視線用ターゲット・オブジェクトを配置し、両目からそれを参照させてIKを用いて視線をコントロールする。IKを使いたい場合は目を球状のオブジェクトとしてモデリングする必要があり、扁平な顔が基本の二次元イラストやアニメ調の作風にはなかなか合わせにくい傾向がある。劇画調を目指している場合を除き、IKを使いたいがために眼球がちゃんとはまるようにするには、顔のモデリングに必要な工夫の労力が釣り合わないことが多い。

そこで、瞳の動きにはモーフを使いながら、擬似的にIKのような視線コントロールを実現する方法を考える。

瞳の後退モーフによるカメラ目線

カメラ目線を実現するには、MMDなどでよく使われている方法を使う。MMD方式のカメラ目線は簡単に言うと、目の位置を後退させて、三次元的に瞳の中心をずらすことによって擬似的にカメラ目線になっているように見せる。

これまでは白目を自己発光させて陰影が出ないように設定していたけど、まぶたに白目が透けてしまったりする問題があったため、自己発光度を0%に変更し、拡散レベルを400%という非常に大きい値にすることで陰影を極力落とす。

morph031

目を後退させると、眼窩の内側が見えてしまうので、内側を白に染めて目の後退がわかりにくいような仕組みを作る。内側を自己発光度の設定してある白に染めてしまうと、目を閉じても内側が透けて見えてしまう。上のサーフェース設定はその対策でもある。

morph032

逆に、瞳の中心は目を後退させることでライトの光線が届かなくなり、徐々に暗くなっていってしまうので、自己発光度を「40%」に設定する。拡散レベルは「60%」に設定し、自己発光度と拡散レベルの合計が100%になるように設定すると、自己発光度を設定していなかった場合と色合いがあまり変わらないようにできる。

morph033 morph034

目の後退によるカメラ目線の例が次の画像。白目と眼窩の内側の境界がわからないようにunReal Xtreme2のToon Tracerピクセルフィルター・プラグインの設定を変更しておく。

morph035

上の画像だけではカメラ目線になっているかどうかが少しわかりにくいので、俯瞰構図と仰視構図も示しておく。いずれもモーフ量は同じで、瞳の位置を後ろに下げただけ。カメラの位置を上下に動かしても瞳はカメラの方を向いているように見える。

morph041
俯瞰
morph042
仰視

エクスプレッションによる視線コントロール

眼を独立した球状オブジェクトとして作成しなかったので、視線の制御にIKを使えない。二次元キャラクターの目を球体として作成しようとする場合に発生しうる問題は以前にも述べたとおりで、瞳は水平、垂直の二軸のみで動くようにデザインしている。

モーフを使っている場合でも、グラフ編集に用意されていている「Channel Follower」モディファイヤを使用すれば、ターゲット・オブジェクトの特定のチャンネルの値の変動にモーフを連動させる簡易的な視線コントロールはできる。ただ、ターゲットの距離などを考慮して左右のモーフ量を個別に制御できないので、両目をひとつのターゲットで制御するのは容易くない。

morph030

ただし、Channel Followerをモーフのグラフ(エンベロープ)に適用する場合に限り、X、Y、Zの座標系チャンネルだけにしか追随させられない。H、P、Bの回転系チャンネルに追随させようとしても不可解な値が返されてしまい(特定のチャンネルだけまともな数値が出ることもあるけど、ほとんどの場合、0に限りなく近い極小の値になる)、サインカーブのような動きをさせることはできない。モーフは線形補間なので、ある意味当たり前と言えば当たり前なんだけど、Channel Followerで連動する要素に回転系のチャンネルを指定してもエラーも警告も出ないので、設定か計算の間違いだと勘違いしやすい。

そうかと言って、どこか一点を注視するような視線をモーフのスライダーだけで実現するのは楽ではない。アニメーションさせることを考えに入れたりすると、キーフレームごとにモーフ量を計算するか、その都度目分量で調整しなければならず、かなり労力がかかりそうなことは想像に難くない。

そこで、注視している場所を大雑把に指示するターゲット・オブジェクトを用意して、モーフ適用量を計算させる。視線コントロールの基本的な考え方は次の図のとおり。IKでも考え方そのものは同じ。

morph040

この図から、目の正面方向と注視点に対する方向がなす角度\thetaについてのタンジェントは次のとおりに求められる。

     \begin{align*} \tan \theta&=\frac{X_{sight} - X_{eye}}{Z_{sight} - Z_{eye}} \end{align*}

タンジェントの逆関数インバース・タンジェント(又はアークタンジェント)を用いて\thetaを求める。

     \begin{align*} \theta &= \tan^{-1} \frac{X_{sight} - X_{eye}}{Z_{sight} - Z_{eye}} \end{align*}

これをLightWaveで受け付けられるエクスプレッションに置き換える。プログラミング言語ではインバース・タンジェント(アークタンジェント)を「atan」などと記述することが多い。次の式は左目のエクスプレッションの例。名称は左右の区別がつきやすく、わかりやすければなんでもいい。

式の出力はラジアンではなく、関数電卓などで「DEG」と表される円周360°の角度なので、0^\circ \leq \theta \leq 90^\circの範囲の値をとる。必要であれば、これに定数を掛けて調整する。

atan(([Null_EyeSight.Position.X] - [Null_Eye_L.Position.X]) / ([Null_Eye_L.Position.Z] - [Null_EyeSight.Position.Z]))

エクスプレッションと、グラフで表されるチャンネルはそれぞれ独立していて、一義に定まる名称で識別されるエクスプレッションを複数のチャンネルに割り当てられるようになっている。そのため、最初は左目用のエクスプレッションを右目のチャンネルにも割り当ててしまったり、重複したエクスプレッションの除去に手間取ったり、インターフェースにとっつきにくさを感じるかもしれない。

同じく次の式は右目のエクスプレッションの例。右目のX座標は左目の正負反転なので、参照するチャンネルが異なるだけで式はほぼ同じ。両目とも瞳を顔の外側に動かすほうをモーフ量のプラスにしている場合は、全体をマイナスで正負を反転する。

atan(([Null_EyeSight.Position.X] - [Null_Eye_R.Position.X]) / ([Null_Eye_R.Position.Z] - [Null_EyeSight.Position.Z]))

それぞれの目のモーフにエクスプレッションを適用(アタッチ)し、両目のグラフを同時に表示させると次の画像のようになる。注視ターゲット・オブジェクトは-1m \leq X_{sight} \leq 1mの範囲で行ったり来たりさせているだけ。Z軸座標は目から約1m先に固定で、注視距離によって必要があれば移動させる。Z_{sight}を移動させるとグラフの振幅が変動する。

morph036

ターゲット・オブジェクトを注視させた場合と、スライダーで視線を手動設定した場合の比較。ターゲット・オブジェクトとは言うものの、上の式では精密に注視させることはできないので、あくまでも擬似的な制御。IKではないのでモーフ量と視線の角度を完全に同期させるにはエクスプレッションを更に作り込む必要がある。

morph038
両目ともモーフ適用量「100%」。視線は交わらずに平行になっている。
morph037
エクスプレッションで視線コントロールをしたもの。左目のモーフ量は「88.78%」、右目は「66.20%」。


今回は水平方向のモーフしか使っていないけど、同様に上下方向のモーフを作っておけば、理屈はまったく同じで瞳の上下運動も可能。

関連記事


LightWaveで二次元キャラ系人物モデリング奮闘記 ―表情モーフ編―

最終更新:2016/10/14

モーフィングも昔は高度な技術のひとつだったけど、今では安価な3DCGソフトウェアでも比較的手軽に利用できるようになった。

LightWaveでは、サブパッチやキャトマルといったリアルタイムに編集可能なサブディビジョン技術を備えたことによって、モデル全体のポリゴンを実際に細分化して固定させなくてもローポリゴンのまま、ハイポリゴン状態のモーフィングを実現できるようになった。また、それがモーフであるかどうかをあまり意識しないでモーフ・マップを作成及び編集できる機能を備えている。

ただ、勘違いされがちなんだけど、モーフィングは線形補間なので、ベース・モデルからモーフターゲット(LightWaveでは「エンドモーフ(Endomorph)」と呼んでいる)までは直線的に変形され、何らかの曲線を経由させるような変形や、捻りといった回転系の変形は難しい。よって、関節の旋回を伴う指などに使うことは稀なんだけど、デザイン上、指が少なかったり関節があってもないと見なせるようなデフォルメ風キャラクターなどの場合はボーンを節約してリグを簡略化したい場合は指にモーフを使うこともある。普通は顔の各所の表情や、息を吸ったり吐いたりすることによって胸や腹が規則的に膨らんだり縮んだりするモーションに用いられるのが一般的。

目を閉じるモーフの作成

「マップ」メニューグループにある新規モーフ(New Endomorph)で新しいモーフ・マップを作成する。モーフ・マップ名には、ファイル名やサーフェース名と同様に日本語全角文字(マルチバイト文字)を避けて命名する。

また、マップ名をピリオドで区切ることでモーフ・マップをグループ化することができる。グループ数にはメモリの許す限り特に上限がないので、左右を別々に管理したり、顔のパーツごとではなく「笑い」「怒り」「泣き」など表情ごとに一括管理したければそのようにすることも可能。

ここでは、左右の区別なく、目に関するモーフをすべて「EYE」グループに分類する。左右を区別する時はボーンのように「_L」や「_R」といった接尾辞をつけることで管理する。

morph000

モーフ・マップの種別を「相対」に設定し、「作成」ボタンを押す。なお、モデラーウィンドウの右下に並んでいるボタンから「M」を選択して「(新規)」を選択しても同じ結果になる。ちなみに、「絶対」モーフ・マップというのはベース・モデルの形状に関係なく固定の形状にモーフィングするために使うものだけど、キネマティック・アートやモーション・グラフィックスのようなケースを除くとそんなに使う機会はないかもしれない。

モーフ・マップを作成すると、同時にモーフ・マップ編集モードに移される。LightWave 11から表示が改善され、HUD(ヘッド・アップ・ディスプレイ)が表示されるようになった。すべてのビューの左上に編集中のモーフ・マップ名とその種別、現在編集中を意味するビューを囲む枠が表示されるようになったため、誤ってベースや意図しないモーフを編集してしまうといったミスを未然に防止できる。

morph001

表情に関係ない部分をすべて隠し(Shift+-:「=」キー)、左目が閉じるようにポイントをひたすら調整する。ちょっと顔側のパッチの数が足りなくてまぶたが伸びきってしまったけど、まだなんとかなるレベル。ここでいったんオブジェクトを保存する。

morph002

今度は右目のモーフを作る。左目のモーフを先に作ってしまってから左右対称になるようにモデリングするのは困難だし、そうかと言って両目を対称モードで一度にモデリングしてしまうとウィンクができなくなってしまうので、左目のモーフを複製して作成する。まずは、頂点マップのコピー(Copy Vertex Map)で左目のモーフを単純に複製して「EYE.CLOSE_R」モーフ・マップを作成する。

morph003

このままだと両方のモーフ・マップが左目を閉じるモーフになってしまうので、「EYE.CLOSE_R」モーフ・マップ上の左目のモーフを右目側に反転して複製する。

「ユーティリティ」メニューグループからMMorphプラグインを選択する。「Keep Original Map Value」にチェックを入れると、元になったモーフをそのまま残して複製する。身近なところで言い換えると「コピー&ペースト」に似たような動作になる。チェックを外すと、元のモーフを残さない「カット&ペースト」と似たような動作になる。

morph004

反転して複製してみたところ、右目の閉じ方が左目と同じようにならなかった。原因としては、まつ毛の先端の非常に近い距離に6個ほどあるポイント群を結合していなかったために、ポイントにモーフを適用する順番が狂ってしまったことが考えられる。

morph005

ポイントの位置そのものは左右対称なのでモーフで問題になるとは想定していなかったんだけど、解決策はある。とりあえず、左右ともまつ毛の先端のポイントをひとつに結合してしまう。結合してしまうと先端が尖らなくなるので、先端のポイントをひとつ選択し、「詳細」メニューグループにあるCCシャープネス設定(Set CC Sharpness)を選択する。

morph006

値はいくつでもいいけど、結合前と大体同じくらいの尖鋭度になるように「80%」とした。ここで設定したシャープネス値は「エッジ・ウェイト」とも呼ばれるけど、必ずしもエッジを選択しないと設定できないわけではない。LightWaveに限ったことではないけど、マップ類はすべてポイントで管理されているので、エッジ単位でなければエッジ・ウェイトを設定できないなんてことはない、というのは勘の良い人ならすぐ気付くはず。

再度、左目を閉じるモーフを右目に反転複製する。今度は次の画像のとおり左右対称になった。両目ができたらオブジェクト・ファイルを保存する。

morph006a

レイアウトに移り、アイテムプロパティウィンドウの「変形タブ」を選択し、変位プラグイン追加から「Morph Mixer」を選択する。オブジェクト・ファイルをちゃんと保存していれば、自動的にエンドモーフ(モーフ・マップ)が読み込まれ、レイアウト内のオブジェクトにも反映される。以後、オブジェクト・ファイルを更新する度に自動的にモーフ・マップの増減と変更が反映されるようになるけど、たまにクラッシュするので適宜シーン・ファイルも保存しておく。

morph007

モーフミキサーのプロパティを選択すると、次の画像のような設定パネルが表示される。グループ化した部位が階層化されて表示される。

morph008

パネル左下の「オプション」を選択すると「スライダー範囲を設定」を選択できる。

morph009

モデラーでのモーフ・マップは適用量「100%」の状態を編集しているわけだけど、レイアウトでは適用量を任意の範囲に拡大又は制限できる。極端な話、「1000%」や「-300%」なんていう指定も可能なんだけど、アニメーションとして動かしてみたら思っていたより変位量が足りなかったとか、海外アニメのカートゥーンのようにもっと大袈裟にしたいといったケースに対応するためのもので、動きの範囲が限られている人間の表情モーフを作る上では使う機会はほぼないと言って良い。最低値を「0」にしておいてもいい。

morph010

両目のモーフ適用量を100%にしてテスト・レンダリングしてみたところ、まぶたの裏にあるはずの目が見えてしまい、寝ている人にマジックで目を落書きされてしまったみたいになってしまった。理由は明快で、SSSの深度を100mmとありえないくらいの値にしているために、皮膚の表皮にあたる半透明部分が想定よりも深くなっていて、目が透けて見えている。

morph011

SSSの設定を見直すのが一番いいんだけど、一応悪あがきとして目の位置をモーフ・マップを利用して頭の中まで後退させるという方法を使ってみた。次の画像のように、まぶたに目は映らなくはなったんだけど、眼窩にぽっかりと穴が開いているのは変わらないため、結局眼窩の影がまぶたに映り込んでしまうという結果になった。

morph012

遠景なのであまり目立たないけど、顔をアップにすると細かいところに問題が起きているので、いずれにせよSSSの設定は近いうちに見直さなければならなかった。

ひとまず、Epidermis DistanceとSubdermis Distanceを「10mm」に修正した。

morph013

SSSを修正してレンダリングしたのが次の画像。影の境界線がやや鋭くなって肌がマットな感じになってしまったけど、モーフで問題が起きるのを回避するにはこのくらいにする必要がある。また、影が鋭くなってしまう問題についてはライティングの方向を見直すことで少し改善できる。

morph014

口を閉じるモーフの作成

同様にして、口を閉じる「MOUTH.CLOSE」モーフ・マップを作成していく。まぶたは筋肉と皮膚だけでできていて骨は入っていないので顔の輪郭には影響しないんだけど、口の場合は開閉によって顎の骨が動くため、顔の輪郭にも影響が出る。

最初は強引に下唇を引き上げて口を閉じようとしてみたけど、全体的に位置が高く、不自然になってしまった。

morph015

そこで、口を全体的に下げてみた。多少は顔のパーツの配置のバランスは改善したけど、顎が長く面長に見えるのはあまり改善しなかった。二次元アニメでは口と顎が必ずしも連動しているわけではないので、輪郭をいじらないようにモデリングする方法もないことはないけど、口が開いている状態を先にモデリングしてしまったので輪郭をいじらないほうが無理がきてしまった。

morph016

更に、口が完全に閉じるまでモーフ・マップを調整し、下顎を少し上げて顔の輪郭を整えた。しかし、今度は口が完全に閉じてしまったことでどこに口があるのか判りにくくなってしまった。

morph017

口が開いている状態を基準にしていたスケッチ色の配置を見直し、上唇と下唇を色分けする。その際、異なるスケッチ色が隣り合わないように注意する。スケッチ色が隣り合っていると想定外のところに境界線が引かれてしまう原因になる。

morph018

スケッチ色の再塗り分けが終わったら、次の画像のようにモーフ・マップで口を閉じてみて、唇の上下のスケッチ色が隣り合っていることを確認する。

morph019

再びレイアウトに戻り、unReal Xtreme2のToon Tracerピクセルフィルター・プラグインのパラメータを調整する。口を閉じている状態を基準にスケッチ色を塗り分けたので、今度は口が開いていると輪郭線が引かれなくなる。そこで、境界設定で「深度境界」を追加し、「深度しきい値」をひとまず「50mm」とした。

morph020

「MOUTH.CLOSE」モーフ・マップの適用量100%でレンダリングしてみたのが次の画像。口が閉じていても輪郭線が引かれているのがわかる。口の位置が判りやすくなった。

morph021

次の画像は「MOUTH.CLOSE」モーフ・マップの適用量90%のもの。輪郭線は引かれなくなるものの、口の中の影が赤く見えるようになるので、口が行方不明になったりはしない。

morph022

次の画像は「MOUTH.CLOSE」モーフ・マップの適用量50%のもの。

morph023

次の画像は「MOUTH.CLOSE」モーフ・マップの適用量0%、つまりベース・モデルのもの。これまでは口の向かって右側に輪郭線が引かれていたけど、深度境界を指定したことによって向かって左側に輪郭線が引かれるようになっている。若干口元の印象が変わった気もしないでもないけれど、特に不自然なところはないので、Toon Tracerの設定はこれで仮決めとする。

morph024

表情集

morph026
視線右
morph027
視線左

 

morph028
怒りの表情
morph029
悲しみの表情(要見直し)

関連記事


WordPressの子テーマに固定ページ用テンプレートを追加する

最終更新:2017/01/13

WordPressの子テーマは親テーマのコードを直接変更することなくコードを差し替えたり追加したりできるため、各自の好みや目的に応じたカスタマイズがしやすいという特徴がある。

仮に手に負えなくなったとしても、子テーマを丸ごとサーバーから削除してしまえば元に戻せるため、初心者でも挑戦しやすい。もちろん、プログラミングの一種であることに変わりはないため、子テーマをカスタマイズしたことによって発生した事態には当方は一切責任を負えない。

テーマを構成するコードのほとんどはPHPというスクリプト言語で記述されている。一般的なHTMLの途中にPHPスクリプトをタグのような形式で挟んでいくような記述スタイルを採用しているので、HTMLさえ理解していれば比較的取っつきやすい。

一方、WEBデザインで頻繁に使われるものでも、JavaScriptはスクリプトのほうが優位で、HTMLタグはあくまでもJavaScriptから出力される文字列という扱いになるため、HTMLの階層構造がわかりやすくなるようにインデントしながら記述するのは難しいという特徴がある。できないわけではないけど、JavaScriptの構文上のネストなのかHTMLを見やすくするためのネストなのか判別しづらくなるためJavaScriptの都合に合わせるのが一般的で、スクリプト内のHTMLはキリのいいところまでひたすら1行で書くというのもそれほど珍しい話ではない。見た目にもまさにプログラムコードといった趣で、動的HTMLを実現する方法がJavaScriptくらいしかなかった時代にはオブジェクト指向言語にも通じる記述方法も相まって決して初心者向きとは言えなかった。

また、JavaScriptはウェブ・ブラウザのようなクライアント側で動作するものであるのに対し、PHPはサーバー側が適切なバージョンのライブラリを実装していないと動作しないという性質のあるものなので、一般的な環境のローカルPCでは試験できない。手直ししたコードをサーバーに逐一アップロードしなければならないため動作確認に若干時間がかかり、それなりに根気が必要になるという点は覚えておいたほうがいい。

当ブログのデザインはWordPress標準のTwenty Fifteenテーマをベースにした子テーマを使用しているけど、WordPressに実装されているテンプレート関連タグ(関数群)は共通なので、他のテーマでも作業そのものは大差ない。プログラムに詳しくなくても親テーマのコードを参考にして見よう見まねで組んでもなんとかなる。

テンプレートの追加

親テーマの固定ページ用テンプレート・ファイルpage.phpを複製し、追加テンプレート用のファイルを用意する。テンプレートは固定ページにしか使えないものなので自明ではあるんだけど、念のため「page」という単語をファイル名のどこかに入れておいたほうが後々改良を加えたくなった時にどこを変更すればいいのか思い出しやすくなる。

page.phpの記述は次のようになっている。ヘッダーと記事ループとフッターが記述されているだけのシンプルなもので、ここで悩むようなことはないだろう。24行目でcontent-page.phpというテンプレートファイルを読み込んでいる。

<?php
/**
 * The template for displaying pages
 *
 * This is the template that displays all pages by default.
 * Please note that this is the WordPress construct of pages and that
 * other "pages" on your WordPress site will use a different template.
 *
 * @package WordPress
 * @subpackage Twenty_Fifteen
 * @since Twenty Fifteen 1.0
 */

get_header(); ?>

	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

		<?php
		// Start the loop.
		while ( have_posts() ) : the_post();

			// Include the page content template.
			get_template_part( 'content', 'page' );

			// If comments are open or we have at least one comment, load up the comment template.
			if ( comments_open() || get_comments_number() ) :
				comments_template();
			endif;

		// End the loop.
		endwhile;
		?>

		</main><!-- .site-main -->
	</div><!-- .content-area -->

<?php get_footer(); ?>

新テンプレート用のファイル名の長さには特に制限はないけど、あまり長くてもメリットはないので、vfpage.phpとした。WordPressテーマの決まり事として、最初のコメント行にテンプレート名を必ず書いておく。WordPressはここに書いたテンプレート名を識別して編集画面に反映する仕様になっている。

<?php
/*
Template Name: VANGUARD FLIGHT
*/

get_header(); ?>

	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

		<?php
		// Start the loop.
		while ( have_posts() ) : the_post();

			// Include the page content template.
			get_template_part( 'content', 'vfpage' );

			// If comments are open or we have at least one comment, load up the comment template.
			if ( comments_open() || get_comments_number() ) :
				comments_template();
			endif;

		// End the loop.
		endwhile;
		?>

		</main><!-- .site-main -->
	</div><!-- .content-area -->

<?php get_footer(); ?>

16行目をget_template_part( 'content', 'vfpage' );に書き換え、content-vfpage.phpを呼び出すように変更しておく。表示させたい内容に変更がない場合は書き換えなくても問題はないだろうけど、テンプレートを分岐させておきながら、結局親テーマのテンプレートを再度呼び出すようなプログラミングは後で混乱の元になるため、内容はまったく同じでもcontent-page.phpを複製してcontent-vfpage.php作成しておく。

ここまで作成すると、固定ページ編集画面の「ページ属性」ボックスに追加したテンプレート名が追加される。

wordpress000

テンプレートを切り替えると、WordPressによって生成されたHTMLのbodyタグに「page-template-vfpage」といった、デフォルトとは異なるテンプレートを使用しているということを示すクラスが自動的に追加されるので、子テーマのstyle.cssに必要なスタイルを書き加える。

.page-template-vfpage h1,
.page-template-vfpage h2,
.page-template-vfpage h3,
.page-template-vfpage h4,
.page-template-vfpage h5,
.page-template-vfpage h6 {
	clear: none;
}

.page-template-vfpage table.infobox {
	table-layout: auto;
	float: right;
	width: 360px;
	margin: 0.5em 0 0.5em 1em;
}

Twenty Fifteenのデフォルトではレベルを問わず見出し行が来ると、CSSのfloatプロパティの左寄せ、右寄せが強制的に解除(clear: both;)されるようになっていたので、見出しが来ても右寄せ、左寄せを解除しないように変更した。また、infoboxというクラスを持つtableタグのスタイルを定義した。クラスを限定してあるので投稿フォーマットのブログ記事のスタイルにはまったく影響しない。

もちろん、新テンプレート専用のCSSファイルを別に用意してlinkタグで個別に読み込ませることもできるけど、テンプレート用のクラスをWordPressが追加してくれていることで煩雑な条件判定は既に済んでいると見なせるので、コード記述やファイル管理の手間が増える割にはメリットは少ない。

サイドバーの増設

Twenty Fifteenは片側のみ(デフォルトは左)のサイドバーしか想定していないので、親テーマのfunctions.phpには次に示すコードのように「sidebar-1」という名前のサイドバーがひとつしか登録されていない。有料テーマなど凝ったものでは複数のサイドバーがあらかじめ用意されているものもあるようだけど、WordPressが標準で用意してくれているテーマはいわば白地図のようなもので、各自のカスタマイズが前提みたいなところもあるので、あまり期待はしないほうがいい。

/**
 * Register widget area.
 *
 * @since Twenty Fifteen 1.0
 *
 * @link https://codex.wordpress.org/Function_Reference/register_sidebar
 */
function twentyfifteen_widgets_init() {
	register_sidebar( array(
		'name'          => __( 'Widget Area', 'twentyfifteen' ),
		'id'            => 'sidebar-1',
		'description'   => __( 'Add widgets here to appear in your sidebar.', 'twentyfifteen' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget'  => '</aside>',
		'before_title'  => '<h2 class="widget-title">',
		'after_title'   => '</h2>',
	) );
}
add_action( 'widgets_init', 'twentyfifteen_widgets_init' );

サイドバーも「sidebar-vfpage.php」のようなテンプレート名を含むファイルを用意すれば、<?php get_sidebar('vfpage'); ?>といったコードでテンプレートによるデザインの切り替えも可能なんだけど、ダッシュボードの「外観」>「ウィジェット」からGUIを利用してウィジェットを編集可能なダイナミック・サイドバーを使えたほうが何かと都合が良い。

追加ダイナミック・サイドバーのために子テーマのfunctions.phpに次のようなコードを追加する。functions.phpがなく、style.cssだけでも子テーマとしては成立するし、特にエラーにもならないけど、ダッシュボードからコードを追加・編集することもできるようになるので、まったくの白紙状態でもいいからお約束としてfunctions.phpファイルは用意しておいたほうがいい。ただし、誤動作の元になるので親テーマのfunctions.phpを無闇に丸ごとコピーしてはいけない。

/* Add Extra Sidebar */
function vf_widgets_init() {
	register_sidebar( array(
		'name'          => __( 'VF用ウィジェット エリア', 'VANGUARD FLIGHT' ),
		'id'            => 'sidebar-2',
		'description'   => __( 'VF用サイドバーに表示されるウィジェットを追加できます。', 'VANGUARD FLIGHT' ),
		'before_widget' => '<aside id="%1$s" class="widget %2$s">',
		'after_widget'  => '</aside>',
		'before_title'  => '<h2 class="widget-title">',
		'after_title'   => '</h2>',
	) );
}
add_action( 'widgets_init', 'vf_widgets_init' );

ダイナミック・サイドバー(ウィジェット・エリア)を追加すると、ウィジェット編集画面に次の画像のように2つのウィジェット・エリアが表示されるようになる。

wordpress001

コンテンツでサイドバーを切り替える

Twenty Fifteenテーマはヘッダーエリアとサイドバーエリアが左側のエリアを共有していて、上下に分け合って表示される仕組みになっているので、サイドバー本体はheader.phpから呼び出されるようになっている。ヘッダーエリアが独立していてタイトルとメインメニューの表示のみに使っているテーマの場合は、記事ループが記述されているテンプレートからフッターの直前にサイドバーを呼び出すようになっているものもある。

親テーマのsidebar.phpは次のコードのようになっている。サイドバーをひとつしか使わないことを前提としたコードなので、ブログの記事を表示していても、固定ページを表示していても同じサイドバーが表示される。

		<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
			<div id="widget-area" class="widget-area" role="complementary">
				<?php dynamic_sidebar( 'sidebar-1' ); ?>
			</div><!-- .widget-area -->
		<?php endif; ?>

そこで、子テーマにsidebar.phpを複製して作成し、特定のテンプレートを使用している場合のみ新しく登録したダイナミック・サイドバーを表示するように条件分岐を書き加える。is_page_template関数は特定のテンプレート・ファイルを経由して表示しようとしているかどうかを判定するため、テンプレート・ファイル名を引数として指定する。

		<?php if ( is_page_template( 'vfpage.php' ) ) :
			if ( is_active_sidebar( 'sidebar-2' ) ) : ?>
				<div id="widget-area" class="widget-area" role="complementary">
					<?php dynamic_sidebar( 'sidebar-2' ); ?>
				</div><!-- .widget-area -->
			<?php endif;
		else :
			if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
				<div id="widget-area" class="widget-area" role="complementary">
					<?php dynamic_sidebar( 'sidebar-1' ); ?>
				</div><!-- .widget-area -->
			<?php endif;
		endif; ?>

なお、PHPは、主にHTMLと混在している箇所で条件分岐内等のブロックコードの始まりと終わりを意味する中括弧{…}は必須ではない、というプログラミング言語としては変わった仕様を持つ。ブロックの開始はコロン(:)で置き換え可能で、終始の記号が一対一で対応している必要も、何かの記号で閉じる必要も特にない。

記事のメタ情報の書式変更

投稿(post)フォーマットのコンテント・フッターには次の画像のようにメタ情報が表示される。ここに、最終更新日の情報を追加したい。

wordpress002
改修前のコンテント・フッター

template-tags.phpに含まれる関数の移設

Twenty Fifteenテーマのコンテント・フッターは厳密にはテンプレートではなく、inc/template-tags.phpというファイルに記述された関数群で実現している。一度読み込まれると上書きを拒否するコードになっているため、他のテンプレート・ファイルと同様の感覚で子テーマにinc/template-tags.phpを追加して編集しても変更が反映されることはない。

まず、親テーマのtemplate-tags.phpの中からtwentyfifteen_entry_metaという関数を探す。

if ( ! function_exists( 'twentyfifteen_entry_meta' ) ) :
/**
 * Prints HTML with meta information for the categories, tags.
 *
 * @since Twenty Fifteen 1.0
 */
function twentyfifteen_entry_meta() {
:
:
(中略)
:
:
	}
}
endif;

template-tags.phpの代わりに、子テーマのfunctions.phpに同名の関数を追加、登録する。親テーマのtemplate-tags.phpよりも先に子テーマのfunctions.phpが実行されるため、こちらが優先される。

上のif ( ! function_exists( 'twentyfifteen_entry_meta' ) ) :endif;というコードで、一度定義された関数は重複して定義しないようになっているので、親テーマの同名の関数で上書きされたり、二重定義でエラーになったりすることはない。

15~37行が投稿日と最終更新日に関するコード。詳しくは説明しないけど、ところどころ出てくるprintf関数やsprintf関数がJavaScript式のHTML挿入方法によく似ていて、HTMLタグでは普通使わない「%1」や「$s」が出てきてプログラム初心者には少し敷居が高そうに見えるかもしれない。関数そのものはC++の祖先のC言語時代からある「初心者がまず最初に覚える関数」のひとつではあるんだけど、本来は英語であるシステム・メッセージの多言語翻訳の都合もあり、WordPressでは使い方がやや高度。

function twentyfifteen_entry_meta() {
	if ( is_sticky() && is_home() && ! is_paged() ) {
		printf( '<span class="sticky-post">%s</span>', __( 'Featured', 'twentyfifteen' ) );
	}

	$format = get_post_format();
	if ( current_theme_supports( 'post-formats', $format ) ) {
		printf( '<span class="entry-format">%1$s<a href="%2$s">%3$s</a></span>',
			sprintf( '<span class="screen-reader-text">%s </span>', _x( 'Format', 'Used before post format.', 'twentyfifteen' ) ),
			esc_url( get_post_format_link( $format ) ),
			get_post_format_string( $format )
		);
	}

	if ( in_array( get_post_type(), array( 'post', 'attachment' ) ) ) {
		$time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>';

		$time_string = sprintf( $time_string,
			esc_attr( get_the_date( 'c' ) ),
			get_the_date(),
			esc_attr( get_the_modified_date( 'c' ) ),
			get_the_modified_date()
		);

		printf( '<span class="posted-on"><span class="screen-reader-text">%1$s </span><a href="%2$s" rel="bookmark">%3$s</a></span>',
			_x( 'Posted on', 'Used before publish date.', 'twentyfifteen' ),
			esc_url( get_permalink() ),
			$time_string
		);

		if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
			printf( '<span class="updated-on"><time class="updated" datetime="%1$s">%2$s</time></span>',
				esc_attr( get_the_modified_date( 'c' ) ),
				get_the_modified_date()
			);
		}
	}

	if ( 'post' == get_post_type() ) {
		if ( is_singular() || is_multi_author() ) {
			printf( '<span class="byline"><span class="author vcard"><span class="screen-reader-text">%1$s </span><a class="url fn n" href="%2$s">%3$s</a></span></span>',
				_x( 'Author', 'Used before post author name.', 'twentyfifteen' ),
				esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
				get_the_author()
			);
		}

		$categories_list = get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'twentyfifteen' ) );
		if ( $categories_list && twentyfifteen_categorized_blog() ) {
			printf( '<span class="cat-links"><span class="screen-reader-text">%1$s </span>%2$s</span>',
				_x( 'Categories', 'Used before category names.', 'twentyfifteen' ),
				$categories_list
			);
		}

		$tags_list = get_the_tag_list( '', _x( ', ', 'Used between list items, there is a space after the comma.', 'twentyfifteen' ) );
		if ( $tags_list ) {
			printf( '<span class="tags-links"><span class="screen-reader-text">%1$s </span>%2$s</span>',
				_x( 'Tags', 'Used before tag names.', 'twentyfifteen' ),
				$tags_list
			);
		}
	}

	if ( is_attachment() && wp_attachment_is_image() ) {
		// Retrieve attachment metadata.
		$metadata = wp_get_attachment_metadata();

		printf( '<span class="full-size-link"><span class="screen-reader-text">%1$s </span><a href="%2$s">%3$s &times; %4$s</a></span>',
			_x( 'Full size', 'Used before full size attachment link.', 'twentyfifteen' ),
			esc_url( wp_get_attachment_url() ),
			$metadata['width'],
			$metadata['height']
		);
	}

	if ( ! is_single() && ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
		echo '<span class="comments-link">';
		/* translators: %s: post title */
		comments_popup_link( sprintf( __( 'Leave a comment<span class="screen-reader-text"> on %s</span>', 'twentyfifteen' ), get_the_title() ) );
		echo '</span>';
	}
}

Genericonsの新規使用指定

Twenty FifteenはGenericonsを使用している。せっかくなので見栄えも揃えたい。上で改変したtwentyfifteen_entry_meta関数では更新日の表示にupdated-onクラスを新たに使用することにしているので、当該クラスをstyle.cssのGenericonsを使用するクラスに追加する。

.social-navigation a:before,
.secondary-toggle:before,
.dropdown-toggle:after,
.bypostauthor > article .fn:after,
.comment-reply-title small a:before,
.comment-navigation .nav-next a:after,
.comment-navigation .nav-previous a:before,
.posted-on:before,
.updated-on:before,
.byline:before,
.cat-links:before,
.tags-links:before,
.jetpack_views:before,
.comments-link:before,
.entry-format:before,
.edit-link:before,
.full-size-link:before,
.pagination .prev:before,
.pagination .next:before,
.image-navigation a:before,
.image-navigation a:after,
.format-link .entry-title a:after,
.entry-content .more-link:after,
.entry-summary .more-link:after,
.author-link:after {
	-moz-osx-font-smoothing: grayscale;
	-webkit-font-smoothing: antialiased;
	display: inline-block;
	font-family: "Genericons";
	font-size: 16px;
	font-style: normal;
	font-weight: normal;
	font-variant: normal;
	line-height: 1;
	speak: none;
	text-align: center;
	text-decoration: inherit;
	text-transform: none;
	vertical-align: top;
}

使いたいアイコンをウェブサイトのサンプルから選び、アイコン・コードをstyle.cssのGenericonsの各クラス定義部分に追加する。

.format-aside .entry-format:before {
	content: "\f101";
}

.format-image .entry-format:before {
	content: "\f473";
}

.format-gallery .entry-format:before {
	content: "\f103";
}

.format-video .entry-format:before {
	content: "\f104";
}

.format-status .entry-format:before {
	content: "\f105";
}

.format-quote .entry-format:before {
	content: "\f106";
}

.format-link .entry-format:before {
	content: "\f107";
}

.format-chat .entry-format:before {
	content: "\f108";
}

.format-audio .entry-format:before {
	content: "\f109";
}

.posted-on:before {
	content: "\f307";
}

.updated-on:before {
	content: '\f420';
}

.byline:before {
	content: "\f304";
}

.cat-links:before {
	content: "\f301";
}

.tags-links:before {
	content: "\f302";
}

.comments-link:before {
	content: "\f300";
}

.full-size-link:before {
	content: "\f402";
}

.edit-link:before {
	content: "\f411";
}

改修が終わったコンテント・フッター。矢印が円形につながっている更新マーク(正確にはリフレッシュ・アイコン)の後に最終更新日が表示されている。

wordpress003
改修後のコンテント・フッター

参考記事


LightWaveで二次元キャラ系人物モデリング奮闘記 ―プリーツスカート編―

最終更新:2017/01/13

今回はプリーツスカートがテーマ。なんとなくそれらしい形のものを作るのは簡単なので、学生の制服やアイドルユニットのお揃いの衣装などでお馴染みのチェック柄のスカートを作る。チェック柄なんて珍しくもないけど、チェック柄を甘く見てはいけない。

3DCG隆盛の昨今でも、チェック柄のスカートを身にまとった美少女キャラクターの3Dモデルというのは驚くほど見かけない。まず考えられる理由としては、UVマップに格子状に展開したチェック柄を歪ませないように維持したままスカートをモデリングするのが難しいからというのが挙げられる。単純に裾を広く、ウェストを細くすると上に行くほど柄が細くなってしまい、不自然になってしまう。

仮に、モデルを単純化してテクスチャの描き方を工夫するにしても、放射状に広がる裾に合わせてチェック柄を描くのは、柄の連続性をどうやって担保するのかといった問題も含め、控えめに言っても労力がかかる。立体化を前提、想定、又は期待してキャラクターデザインをする場合、チェック柄のスカートは全般的に避けられる傾向にある。現実世界では街に出ればチェック柄のスカートばかりが目立つのに、二次元世界では学園物の作品でも制服のプリーツスカートにチェック柄を採用している学校のほうが珍しい。もっとも、立体化の前にアニメ化やコミカライズといった二次元化があり、単純に描くのが面倒という現実的な問題もある。

また、プリーツスカートの縫製の特殊性にも理由がある。縫い目を切り離して展開してみると、大抵の人が想像するような扇形や台形の生地ではなく、実は長方形の布1枚でできている。それを末広がりの独特のラインに仕立てるために、「曲線折り」という特殊な折り方を採用している。ウェストが細くなるようにまっすぐに折るといずれチェック柄が斜めに傾いていってしまうのを避けられない。

本物の布や折り紙であれば基本的に伸び縮みはないので、順序よく折り目をつけていけば自然にプリーツスカートの形になっていくんだけど、3Dモデリングの場合、ポイントを移動させるとエッジがいくらでも伸縮してしまう特性があるため、エッジの長さを固定したまま折り畳むという操作がそもそも難しい。

そのプリーツスカートを現実のものとほぼ同様の発想でモデリングすることにあえて挑戦する。挑戦しないのであれば、わざわざ記事にする必要はない。例によって拡張プラスと移動ツールでモデリングしていく方法を今更紹介されても「またその組み合わせ?」と言われかねない。

基礎を作る

それでも、3DCGソフトウェアの制限には逆らえないので、まずはセオリーどおり円筒から作る。ディスク(Disc)ツールで原点に直径1m、高さ1mの標準的な大きさの筒を作る。これからややこしい計算をすることになるので、初期座標くらいは単純にしておきたい。

ひだの数があまり多いと作業が大変だし、逆に少なすぎるとプリーツスカートとは呼べなくなるので、15個とした。折り返し分を計算に入れて30面の円筒を作る。15という数字は、1周分の360°を割り切れるから。ついでに言うと、UVは幅が100%(LightWaveの内部では1.0 = 1m = 100%は等価)なので、100と360の公約数だと更に計算しやすい。とは言うものの、100と360の公約数は1、2、4、5、10、20の6つしかなく、実質10か20しか選択肢がない。

Skirt000

上面と底面は必要ないので、削除する。大抵要らなくなるので、「上面と底面をふさがない」というオプションがあれば便利なんだけど、些細なことなので文句を言っていても始まらない。

Skirt001

サーフェースがデフォルトのままだと何かと不便なので、次の画像のように「Skirt_Check」というサーフェースを割り当てておく。

Skirt002

とりあえず、スムージングはかけないでおく。

Skirt003

早々にUVマップを作成する。極めて単純な形状のオブジェクトなので、標準機能の新規UVテクスチャ(New UV Map)ツールで円柱状に展開する。今回の目標はUVマップを基準にしてモデリングのほうを工夫することなので、手芸店などで計り売りされている1枚布のようなマップが必要。

Skirt004

なお、プリーツの数が4で割り切れるのであれば、4分の1だけモデリングしてあとは90°ずつ回転させて複製し、境界線をつなぎ合わせればモデリングの労力をほぼ4分の1にできる。ただ、その場合のUVは4箇所とも同じ位置に重複してマッピングされることになるので、UVの扱いに慣れていて混乱しない自信があれば試してみてもいいかもしれない。それから、モデリングを済ませてしまってからUVを展開してももちろんいいんだけど、plg_Make_UV_Editなどによる自動展開は多少なりとも歪むので、UVの調整にそれなりに時間を要する。プリーツを折り畳んでしまってからLightWaveの標準機能によるUV展開は使えないと思っていい。

次の画像のような簾状のマップを作る。

Skirt005

更に、作成したUVにチェック柄のテクスチャを割り当てる。モデリングの説明が思いのほか長くなりそうなので、チェック柄のテクスチャの作り方はまた今度説明する。Adobe Photoshopのスマートオブジェクトはチェック柄の変更や修正に柔軟に対応できて便利なので一番おすすめではあるんだけど、レイヤーが扱えて標準的なレイヤーモードを備えている画像編集ソフトウェアであれば簡単に作れる。

Skirt006

次の画像の状態が基準になる。以後、この模様が歪まないように工夫を凝らしていく。

Skirt007

すべての面の幅が一定ではプリーツスカートにならないので、折り返す部分を短くする。次の画像のようにUVマップのビューでひとつおきにポイントを選択する。三面図の上面からのビューで選択しても同じだけど、チェック柄の連続性を維持するためにはマップの左右端にあたるポイントは間違っても動かせないので、UVマップ内で選択したほうが結果的には手早く済む。

Skirt008

スカートのデザインにもよるんだけど、ひだの表側に見えている部分と折り返し部分の比率は4:1にすることにした。ひだの数は15個で、現在5:5になっている比率を8:2にしたいので、100 \div 15 \times 0.3 = 2 \, [\%]だけUVのU成分をずらす。UV値の変換(Transform UV)ツールで次の画像のとおりに入力する。

Skirt009

「OK」ボタンを押すと、次の画像のようにUVマップが変換される。

Skirt010

UVマップを変換しただけなので、三次元空間の筒の形状には変化がないけど、チェック柄が歪んでいるのが確認できる。

Skirt011

ポイントの選択を解除しないようにして、今度は三次元空間のポイントを360 \div 15 \times 0.3 = 7.2 \, [^\circ]だけ回転させる。正負の方向はUVの歪みを見て判断する。

Skirt012

正しい方向に回転させられれば、テクスチャの見た目上は最初の状態に戻る。これでプリーツスカートを作る準備ができた。チェック柄のパターンは15×15なので縦方向が圧縮されて縦横比が一致していないけど、この段階では横方向の模様が歪んでいなければいい。

Skirt013

アポロニウスの円

ここからが本題。ひとつのひだを4:1に分割したまでは良かったんだけど、その比率を維持しながら折り返すのが結構難しい。比率さえ維持できていればUVを歪ませずに済むので、この際長さは変わってしまってもいい。

ここで久しぶりに数学らしい数学を利用する。

2つの点ABからの距離の比がm:n\; (m \neq n)で一定である点Pが描く軌跡を求めたい。結論から先に言うと、その軌跡Pは円になるんだけど、その円の中心点をCとする。各点はXとYの成分を持っているので、それぞれA(\alpha), B(\beta), C(\gamma)とする。

C点の座標\gammaは、次の式で求める。要は、X座標とY座標をそれぞれ別に同じ式で計算するということ。

     \begin{align*} \gamma=\frac{\displaystyle -n^2\alpha+m^2\beta}{\displaystyle m^2-n^2} \end{align*}

C点の座標が求まればA点とB点との距離は三平方の定理で求められるけど、今は試験問題を解いているわけではないので、ポイントの計測(Measure Points)ツールを使って簡単に求める。

線分ACBCの距離が求まれば、点Cを中心とする円Pの半径rは次の式で求められる。

     \begin{align*} r=\sqrt{{AC} \cdot {BC}} \end{align*}

計算と作図がしやすいように、B点が(X,Z)=(-0.5,0)の位置にあるところを選んだ。これらの式から求めた数値をディスクツールの数値入力ウィンドウに入力する。座標を参照するだけなので高さは0でいい。サイドが36なのは言うまでもなく、10°刻みにするため。

Skirt015

計算が合っていれば4:1の折り目で分割しているポイントを通過する円が描けるはず。実際に作図してみると思ったより半径は小さかった。精度としては4.006:1~3.995:1くらいだから誤差±0.16%前後。

Skirt016

このような円をアポロニウスの円と言う。一般的には次の画像のような図で表される。図はm:n = 3:2になっている。A点とB点が水平に一列になっていたほうが理解しやすいのでこのように描くけど、二次元的に斜めにずれていても円の位置と半径は求められる。図を見るとわかるように、比率が一定になるだけで長さまでは一定にならないことに注意。

Skirt014

なんでこのような式になるのかまでは省略。ネットで「アポロニウスの円」を検索すれば高校の先生が詳しく証明してくれているページがたくさんある。つまり、まったく憶えてはいないけど高校の数学で習ったはずで、センター試験にも出題されるポピュラーな平面幾何学の定理。更に発展させた複素数平面を使った解法は2004年(平成16年)を最後に今の高校では教えていないらしいけど、コンピュータの発達した21世紀に生きる私がすぐには思いつかなかった方法を紀元前の数学者が既に考案していたというのだからまったく皮肉なことだ。

ある平面上で線分APBPの比率を一定にしたまま分割点Pを移動させたいという要求はありそうだけど、Adobe Illustratorのようなベクター画像編集ソフトウェアのツールにも意外と備えられていない。少し調べたところでは、Illustratorでもアポロニウスの円を描いてその円の外縁にスナップするようにパスの制御点を移動させるという方法が採られているようだ。

こんな手間のかかる計算までしなくてもいいのでは、と言われそうだけど、アポロニウスの円は平面上にある2点についてしか通用しないものなので、今使わないと使う機会がなくなる。それに、いつも「適当に、感覚で」と繰り返すのでは何の参考にもならない。それほど厳密でなくても良ければ、ひだの角度を直角と仮定して三角関数の正接(\tan \theta)が0.25になるおおよその位置を求める方法もある(あくまでも仮定なので、実際に操作すると直角にはならないため、無視できないほどの誤差が出る)。

A点とB点の間の分割点を選択し、スナップドラッグ(Snap Drag)ツール(Shift+G)でアポロニウスの円上にある任意の点にスナップさせる。この時、「操作ビューに沿う」にチェックを入れておかないと水平に動いてくれないので注意。

Skirt017

次の画像のように、4:1の比率を維持したまま折り返すことができた。

Skirt018

15個あるひだの数だけアポロニウスの円を作るのはさすがに大変なので、スカート全体を15分の1、つまり24°ずつ回転させて、スナップドラッグを繰り返す。原点を中心にしてアポロニウスの円をスカートの外縁を周回させても同じだけど、円周率が無理数であるために回転は誤差が蓄積しやすいツールなので、変形の基準にするものはできるだけ移動させたくない。

Skirt019

15個のひだを折り返し終わった状態が次の画像。ここでウェスト部分を絞ってしまうと、冒頭でも書いたようにチェック柄が先細りしてしまう。

Skirt020

縦横の模様を合わせる

ここでチェック柄の縦の模様を横の模様に一致させる。ひとつのひだの長さは既にわかっているので、それを15倍すると裾の周囲の長さが求められる。結果、4.4306205mと求まり、スカートの丈の長さは1mなので、裾の周囲に対する割合は22.5702 \dots \, [\%]となる。

上端のポイントを選択し、これをUV値の設定(Set UV Value)ツールでUVのV成分に入力する。

Skirt021

上を下に移動させたほうが計算が楽なのでそうしたけど、下を上に移動させても結果は同じ。

Skirt022

上の画像と見比べてもらえば、チェック柄の縦横比が合っているのがわかると思う。

Skirt023

曲線折りの模擬

次はいよいよ曲線折りを行っていく。まず、ウェストに向かって絞りたい部分を分割する。全体を半分に分割し、上半分をさらに半分に分割する。

この時、必ずバンドソープロ(Band Saw Pro)を使う。まだ単純な形状なのでナイフツールを使ってもいいような気もするし、一見すると似たような動作ではあるけど、ナイフツールはUVを壊してしまうことがある。バンドソープロが優れているところは、どんなに入り組んでいようと、ポリゴンが連続さえしていれば正確に分割できることばかりではなく、UVを破損させることがない点。

Skirt024

次の画像のように3分割した。

Skirt025

分割点をひとつのひだの10%分だけ左にずらしていく。ひとつのひだのUVにおける幅は15分の1、つまり6.666 \dots \, [\%]なので、その10分の1をUV値の変換ウィンドウに入力する。

Skirt026

裾側から順に、8:2(=4:1)7:36:4(=3:2)5:5(=1:1)になっている。

Skirt027

すべての段の折り目について、アポロニウスの円を作図するのがもっとも正確な方法なんだけど、(x_A,y_A)=(0,0)(x_B,y_B)=(1,0)として単純化してみて気が付いたことがある。

分割点がA点とB点からの距離の比が8:2の時、アポロニウスの円の半径は次のように求められる。

     \begin{align*} x_C&=\frac{\displaystyle -2^2x_A+8^2x_B}{\displaystyle 8^2-2^2}=\frac{\displaystyle 16}{\displaystyle 15}\\ r&=\sqrt{x_C \times (x_C - x_B)}=\sqrt{\frac{\displaystyle 16}{\displaystyle 15} \times \left(\frac{\displaystyle 16}{\displaystyle 15}-1\right)}\\ &=\sqrt{\frac{\displaystyle 16}{\displaystyle 15}}=0.2666 \dots \end{align*}

同様に、7:3の場合は次のとおり。

     \begin{align*} x_C&=\frac{\displaystyle -3^2x_A+7^2x_B}{\displaystyle 7^2-3^2}=\frac{\displaystyle 49}{\displaystyle 40}\\ r&=\sqrt{x_C \times (x_C - x_B)}=\sqrt{\frac{\displaystyle 49}{\displaystyle 40} \times \left(\frac{\displaystyle 49}{\displaystyle 40}-1\right)}\\ &=\sqrt{\frac{\displaystyle 441}{\displaystyle 1600}}=0.525 \end{align*}

同、6:4の場合は次のとおり。

     \begin{align*} x_C&=\frac{\displaystyle -4^2x_A+6^2x_B}{\displaystyle 6^2-4^2}=\frac{\displaystyle 9}{\displaystyle 5}\\ r&=\sqrt{x_C \times (x_C - x_B)}=\sqrt{\frac{\displaystyle 9}{\displaystyle 5} \times \left(\frac{\displaystyle 9}{\displaystyle 5}-1\right)}\\ &=\sqrt{\frac{\displaystyle 36}{\displaystyle 25}}=1.2 \end{align*}

つまり、ものすごくざっくりではあるけど、比率が1割変動するたびに半径は約2倍になっている。半径の計算に平方根を使っていることに多分関係がある。円の中心点Cは移動するので単純に2倍では本当はダメなんだけど、同じ作業を60回繰り返すのはちょっと辛いので、ある程度は近似できるということも併記しておく。

なお、5:5の場合はm=nなので、m^2-n^2は0になってしまい、計算できなくなる。分割点がちょうど中間の場合は、点A、点B及び点Pをつなぐ三角形は二等辺三角形になり、点Pの軌跡は直線になる。つまり、アポロニウスの円の半径は無限大になり、円にならないということ。とは言え、計算できないと座標が求められないので、6:4の場合の更に2倍と仮定して求める。

ひだの短いほうのエッジを選択し、ストレッチ(Stretch)ツール(Hキー)の中心点は(X,Z)=(-0.5,0)に固定、下から順に200%、400%、800%まで内側に向かって拡大する。

Skirt028

ウェストの絞り込み

最後に、ウェストに向かって細くなるように各段のエッジを1周分選択して縮小する。冒頭で「ウェストに向かって絞ったらプリーツスカートの意味がない」と言っていたことと矛盾するように感じるかもしれないけど、これまでの操作で上の段に行くほどプリーツの幅は広くなっているので、最後に帳尻合わせのために縮小しなければならない。エッジの長さを固定して折り畳めないならば、一度広げてから縮小して元のスケールに戻すという発想。

裾から数えて2段目の設定。裾のひだの長いほうのエッジが8に対して7なので87.5%と求めた。

Skirt029

Skirt029a

裾から数えて3段目の設定。裾のひだの長いほうのエッジが8に対して6なので75.0%と求めた。

Skirt030

Skirt030a

裾から数えて4段目、つまり上端の設定。裾のひだの長いほうのエッジが8に対して5なので62.5%と求めた。

Skirt031

Skirt031a

拡大してよく見てもらえればわかると思うけど、折り返し部分も含めた裾の長さの総計に対し、上の段の長さは必ずしも一定ではない。プリーツの表側と折り返し部分の比率はほぼ計算どおりなので、折り返しの角度が深すぎるために長くなってしまっている。

基本版完成

以上の操作がすべて完了してできあがったのが次の画像のようなモデル。水車のような形にはなっているけど、とてもではないけどお世辞にもスカートのようには見えない。

Skirt032

ところが、これにサブパッチ(キャトマル)をかけると、不思議なことにかなりそれらしいプリーツスカートに早変わりする。チェック柄もそれほど大きくは歪んでいない。見直す余地はまだあるけど、方向性は間違っていないことが確認できた。

Skirt033

最後に、アポロニウスの円を各段ごとに作成したという証拠物件。後でどうしても正確を期したくなった場合に再利用する。これらの円を使って作業している途中で円の半径が比率の2乗にほぼ比例することに気が付いた。

Skirt034

途中経過

作業のしやすさを重視して単位長(1メートル)の範囲内でモデリングしていたので、実際のモデルに着せるには大きさを全体的に拡大し、ウェストの位置とサイズに合うように調整する。あとは、多少脚がはみ出していても、物理演算でなんとかできる。

ClothFXを次の画像のように設定する。構造維持(Hold Structure)は「100」くらいにしておかないと体のラインに合うように変形してくれないのであまり上げすぎないほうがいい。一方、粘性(Viscosity)と抵抗(Resistance)をそこそこの数値にしておかないと、スカートの形状がなかなか落ち着いてくれないし、わざわざ計算までして比率を揃えたプリーツが不規則に歪むのを抑制できない。

skirt036

ちょっと短かったけど、いつものモデルに着せてみるとこんな感じ。

skirt037

チェック柄を解除して無地にするとこんな感じ。ウェストの余裕を厳しくしすぎたために、スカート右側の一部のプリーツがモデルに貫通してしまっている。上の画像でも同様の現象は起きているんだけど、柄がなくなったので目立ってしまった。

skirt038

関連記事

参考記事


LightWaveで二次元キャラ系人物モデリング奮闘記 ―手指FK編―

最終更新:2016/12/05

手の指にはIK(インバース・キネマティクス)を設定しないで、FK(フォワード・キネマティクス)のままにしてある。手の指はFKにすることが多いというので盲目的にそれに倣っていたわけだけど、なぜ手の指だけはFKのほうがいいのかという理由まではよくわかっていなかった。

最近ようやくその理由がわかった。まったく合理的なもので、FKなら「5本の指をひとつのコントローラで一度に操作できる」から。具体的には、5本指の全関節のボーン旋回をまとめて、ひとつのコントローラ・オブジェクトの回転に追従させるようにする。こういった設定を3DCG分野では一般にコンストレイン(Constrain = 拘束)と言う。

手は狭い範囲に関節が集中するところなのでIKを使いたくなるんだけど、IKの場合それぞれの指先にひとつずつゴールオブジェクトが必要になる。指の折り曲げ方の加減を個別に決められる反面、手を握ったり開いたりするような単純な動作をさせる場合でも単純に5本分の手間がかかる。また、IKを設定した関節の角度はゴールオブジェクトの位置から逆算的に求められるので、ある関節だけ曲げ、ある関節だけ伸ばすといった制御が難しくなる。

コンストレインをうまく利用すると、手のおおまかな握り方はコントローラで決定し、それぞれの指の調整が必要な場合は直接指定といったことができるようになる。ただ、それを実現するためには熟慮した設定が必要になるため、IKよりも手間がかかる。リグというのは本当に奥が深くて、直感的な操作を可能にしようとすればするほど設定は複雑になっていく傾向にある。

本記事ではLightWave 2015のGENOMA2を利用しているけど、標準機能のスケルゴンやボーンを利用しても設定可能。LightWaveでいつからコンストレインができるようになったかは定かではないけど、少なくともLW 9.6の頃には既に使えていた。

ボーンの二重化

単純に5本指を握ったり開いたりするだけで良ければ、既存のボーンの「回転アイテム」にコントローラ・オブジェクトを指定すれば全部の指を同時に操作できるようになる。ただ、そうした場合は文字通り回転アイテムに完全に拘束されてしまうので、個別にヘディングやピッチを直接入力してもその値は無効となり、コントローラ以外の方法で指を操作できなくなる。

そこで、コンストレイン用のボーンを作成し、ボーンを二重化する。次の画像は初期状態。

HandFK000

いずれかのボーンを選択し、Ctrl+Cでコピーし、Ctrl+Vで同じ場所にペーストする。次の画像は中指の根元のボーンを選択した状態。

HandFK001

選択を解除しないで拡大縮小ツール(Shift+H)で適度な大きさまで縮小する。アクションの中心は「選択範囲モード」を使用する。

HandFK002

どのボーンがコンストレイン用なのか判別できればいいので、大きさは任意。あまり目立たないようにと思い、だいぶ小さくしてしまって後で選択しにくくなってしまったので、50%前後がちょうどいいかもしれない。

HandFK003

コンストレイン用のボーンを選択し、スナップドラッグ(Snap)ツール(Shift+G)の数値入力ウィンドウで「全ポイント」を指定する。

HandFK004

本来のボーンの根元にスナップさせる。スナップドラッグではポイントの結合はしないので、浮動スケルゴンになっているけど、理論上はこのままでもコンストレイン用のボーンとして機能する。もののついでなので、指の関節の長さを調節した。指の第3関節の長さを100%とした時、第2関節はその75%、第1関節は更にその75%(つまり、第3関節の56.25%)にすると美しく見えるそうだ。

HandFK005

同様にして、5本指のすべてのボーンに対してコンストレイン用のボーンを作成する。手間のかかる作業だけど、リギング作業というのは究極的にはこういう地味な作業の繰り返しなので、目的に対して作業のコストがかかりすぎると思う場合は省略してもいい。そういった割り切りもリギングのうちとも言える。

コンストレイン用のボーンを作成し終わったら、次の画像のように判別しやすいようなスケッチ色をつけておく。また、余裕があったらGENOMAプロパティの「アイテム」タブでアイテム色を「レッド」に設定しておくとレイアウトでも赤いボーンとして表示されるので視覚的に識別しやすくなる。

HandFK006

GENOMA2を使っている場合は、コンストレイン用のボーンに一括でコントローラを指定できる。上の画像で赤色のボーンを選択し、「GENOMA編集」のセットのドロップダウンメニューから「コントローラ」を選択する。

HandFK007

次の画像は5本指のもっとも手のひらに近いボーンのコントローラ設定。握ったり開いたりする他に、指を揃えたりジャンケンのパーのように開いた状態を実現するためにピッチもコンストレインしている。

HandFK008

次の画像はその他の指の関節に相当するボーンのコントローラ設定。指の途中からピッチ方向に旋回してしまうと骨折したようになってしまうので、ヘディング方向だけコンストレインしている。

HandFK009

GENOMA2を利用している場合は、モデラーでボーンの親子関係を変更しておく。これまで使っていたボーンをコンストレイン用のボーンの子になるように設定し、コンストレイン用のボーンをその前の節のボーンの子になるようにする。GENOMAは親子関係を特に指定してある場合はスケルゴンツリーを無視するので、従来のスケルゴンの接続を切り離す必要はない。

途中で頭が混乱してくるかもしれないけど、最悪レイアウトでGENOMAリグを組ませてみて確認してもいいので、地道に作業する。この親子関係を言葉で説明するとわかりにくいので、次のスケマティックビューを見てもらったほうが理解しやすいだろう。

HandFK027

右手への複製

右手は基本的に鏡面X(Mirror X)で左手を複製するんだけど、GENOMAスケルゴンの場合は内部的に様々な設定が入っているので、ただ複製してリネームしただけだと何かの設定が競合又は衝突するようで、レイアウトでGENOMAリグを編成する際にLightWaveがクラッシュする。

そこで、次の画像のようにいったんGENOMAのタグを消去して通常のスケルゴンに戻した。まさかクラッシュするとまでは思っていなかったので右手のボーンを全部削除してしまったんだけど、よくよく考えてみたらボーン・ウェイトの設定も消してしまったことになるので、従来のボーンは活かしておいて、コンストレイン用のボーンだけ鏡面複製するほうが賢明。もし、原因不明のクラッシュが頻発する場合はGENOMAタグの消去を試してみると改善するかもしれない。

HandFK010

右手のセットアップをほとんどやり直す羽目になったけど、右手も左手と同様に設定した状態が次の画像。

HandFK011

コンストレイン用のボーンにはボーン・ウェイトを設定してなくても大丈夫だとは思うんだけど、左手と重複するウェイトが設定してあるのはさすがに問題なので、スケルゴンツリーで確認しておく。

左手を右手に複製した時にポイントを共有するボーンがすべて結合されてしまったので、ツリーとしてはかなり不可解な状態になっている。GENOMA2を使わない場合は、このままレイアウトにもっていって、親子関係をSceneEditorなどで修正することになる。

HandFK012

スケルゴンツリーの「ウェイトマップ」欄をダブルクリックするとボーン・ウェイトの設定を変更できるので、左手のウェイトが割り当たっている場合は右手のものに変更する。

HandFK013

コンストレインの設定

手を握ったり開いたりする動作は人差し指から小指まで同じヘディングで制御するので設定は同様でいいんだけど、指を水平に開いたり閉じたりする動作はピッチ制御で行うので、中指を基準(0倍)にして外側に行くほど大きくなるように倍率を変えて設定する。次に例示する各設定はGENOMA2を利用した場合のもの。

中指

自分の手を動かしてみればわかると思うけど、指を水平方向に開いたり閉じたりしても中指はほとんど動かない。これを利用してピッチの基準にする。コントローラ・オブジェクトのピッチに影響を受けないように、「x / +」の「x」側を「0.0」にする。

なお、GENOMA2で「回転アイテム」を指定しておくこともできるけど、モデラー上に存在しないアイテム名を指定するとレイアウトでGENOMAリグの作成に失敗する。今回はレイアウトで後付けでコントローラを追加するので「NONE」のままにしている。

HandFK014

GENOMA2を使わない場合は、レイアウトで次の画像のように設定する。「回転アイテム」に指の制御用のNullオブジェクトを指定してある。他の設定は同様なので、中指だけ例示しておく。

HandFK028

薬指

薬指はコントローラのピッチの影響を通常通り受けるので、「x / +」の「x」側を「1.0」のままにしておく。水平方向に開く方をピッチのプラスにしているけど、マイナス方向にしたい場合は「-1.0」にすればいい。

HandFK015

小指

小指は薬指よりも更に外側に開くので、「x / +」の「x」側を「2.0」にし、コントローラのピッチの影響を2倍にする。

HandFK016

人差し指

人差し指は薬指とは反対方向に開くので、正負を反転させる。「x / +」の「x」側を「-1.0」にし、コントローラのピッチの影響を逆にする。

HandFK017

親指

親指が結構難問で、次の画像の設定でもうまくいっているかどうかは今のところなんとも言えない。親指は他の指とは異なり、握り方向がピッチに寄っているので、少なくとも追跡するコントローラの成分を入れ換える必要がある。ヘディングはコントローラのピッチを、ピッチはコントローラのヘディングを追跡するようになっている。右手の場合は更に正負を逆転させる必要が出てくることもあるので、予想しきれなくなったらレイアウトでテストしてみて影響量を判断する。

HandFK018

リグのテスト

レイアウトでGENOMAリグを作成した後、コントローラ用のNullオブジェクトを作成し、コンストレイン用のボーンに参照させる。コントローラの指定はSceneEditorで複数のボーンを一度に選択して右クリック、「操作」-「モーションオプション」でまとめて設定できるので、GENOMAの使用に関わらず片手ごとに1回で済むはず。

なお、コントローラ用のNullオブジェクトは手首のIK用のNullオブジェクトの位置にコンストレインしてある。コントローラはできれば手に近い場所にあったほうがいい。

次の画像はGENOMAリグを作成した直後のニュートラルの状態。赤く見えるのがコンストレイン用のボーン。

HandFK019

次の画像はコントローラのピッチを「10°」に設定した状態。水平方向に指が開いているのがわかる。

HandFK020

次の画像はコントローラのピッチを「-10°」に設定した状態。水平方向に指が揃えられているのがわかる。

HandFK021

次の画像はコントローラのヘディングを「30°」に設定した状態。5本の指が一斉に握る方向に曲がっているのがわかる。

HandFK022

次の画像はコントローラのヘディングを「30°」、ピッチを「-10°」に設定した状態。5本の指が揃えられた状態で握る方向に曲がっているのがわかる。これでコンストレインのテストは終了。

HandFK023

次に、コントローラのヘディングを「80°」、ピッチを「-10°」に設定し、ジャンケンのグーの状態にした上で、コンストレインで拘束されていない青いボーンを選択し、ヘディングを「-80°」にすることで人差し指と親指を伸ばしている。コンストレインで拘束されている赤いボーンは下を向いているけど、強制的に前を向かせているのがわかる。

HandFK024

GENOMA2での親子関係の設定が正しくできていれば、SceneEditorにおけるボーンの階層構造は次の画像のような形になっている。GENOMAを使わない場合は、このようなツリーになるように親子関係を設定する。親子関係を変更することでオブジェクトの形状が崩れてしまう場合はコンストレイン用のボーンのボーン・ウェイトを削除するか、「中心点回転記録」を有効にすると改善することがある。

HandFK025

途中経過

レイアウトでの操作を簡単にするためとは言え、リグを結構本気でやろうとすると非常に手間がかかることがよくわかった。CGアニメーションの制作会社にはリグを専門に担当する技術者がいるというのも納得できる。

ただ、手間はかかるものの、このようなリギング作業を済ませておくと、コントローラ・オブジェクトをひとつ回転させるだけで手の握り具合を簡単に制御できるようになり、指の制御を億劫に感じなくなる。一度この感覚を覚えてしまうと、指を1本ずつ操作するのが非常に面倒に思えてくる。

LightWaveの欠点ともされるボーンとモデルの変更がレイアウトに即座に同期しないという特徴も、考えようによってはボーンやNullオブジェクトの設定をまったく変更しないでモデルのレイヤーだけ入れ換えることで別の人物モデルにリグをすべて移行できるということでもあるため、大変な思いをするのは一度だけでいいという長所にもなる。

HandFK026

指の関節の長さを見直してみたけど、苦労した割にはあまり変わっていない気もする。たぶん、太さや曲がり始める箇所のウェイトの見直しも同時に必要なのだろう。

関連記事

参考記事