このページではFK Tipsについて掲載しています。
現在掲載している他にも注意しておきたい点がありましたらどんどん編集していってください。
FKの便利な活用方法を紹介します。
fk_Modelの親子関係は便利で強力な機能だが、扱う座標や姿勢の座標系を勘違いしていると思いもよらない挙動を引き起こす。ここでは混乱しがちな座標系を整理し、ありがちなミスの傾向と対策を述べる。
一番の罠は、グローバル座標系とローカル座標系という2つの考え方で理解しようとしてしまうことにある。3DCGにおける親子関係とは「子モデルにとってのグローバル座標系を、親モデルのローカル座標系に置き換える」という処理によって実現していることに注意しよう。
これに気がつくと、子モデルでglFocus()などのgl系関数を使う際に渡す引数は「その子モデルにとってのグローバル座標系上の値」でなければならないことが分かる。つまり「親モデルのローカル座標系上の値」を渡さないと意図通りの動作をしないわけだ。
このまま説明を続けると混乱するだろうから、ここでFKにおける座標系を以下の3種に分類することを提案したい。これらの区別ができれば理解は進むはずである。
いかがだろうか。ワールドとグローバルという概念を分離することで、fk_Modelで扱っているグローバル座標系は「1つ上の階層の座標系」という相対的なものを表していると認識できるだろう。親を持たないモデルは全てワールド座標系を親として持っている、という解釈もできる。
さて、そうなると親を持つモデルでgl系関数を使う場合、ワールド座標系の値をそのまま持ってくることは出来ないため、以下のようなコーディングが必要になる。glFocus()で任意のワールド座標の地点にモデルを向けたい場合の例を挙げる。
fk_Vector worldPos(x, y, z); fk_Vector parentPos; fk_Model *parent = childModel.getParent(); if(parent != NULL) { parentPos = parent->getInhInvMatrix()*worldPos; } else { parentPos = worldPos; } childModel.glFocus(parentPos);
getParent()で親モデルのポインタを取得し、getInhInvMatrix()でワールド座標から親モデルのローカル座標に変換する行列を得てワールド座標と乗算すれば、意図通りの結果が得られる。親子関係が外れている場合はポインタとしてNULLが帰ってくるため、その場合はワールド座標をそのまま渡してしまえばよい。
この一連の処理はFKの機能として取り込んでしまってもいいように思うので、今後検討していきたい。
光源やマテリアルの影響を受けずにテクスチャのピクセル色をそのまま表示するには以下のように記述する。
fk_Texture texture;//テクスチャを表すクラス texture.setTextureMode(FK_TEX_REPLACE);//画像モード
ただし、この場合はマテリアルの透明度も反映されなくなるので半透明表示もできなくなる。光源には影響されたくないが透明度だけ有効にしたい場合は上記の設定は行わず、以下のようなマテリアルを作成して用いるとよい。
fk_Material pixMat; pixMat.setAmbDiff(0.0, 0.0, 0.0); pixMat.setSpecular(0.0, 0.0, 0.0); pixMat.setEmission(1.0, 1.0, 1.0);
色などの材質に関するTipsです。
FKでマテリアルを扱うためには、マテリアルの初期化を行う必要がある。 初期化は1度だけで十分なので、Fl_Windowのend関数の直後あたりで行えばよい。
// マテリアルの初期化 fk_Material::initDefault()
初期化を行わないと、色を指定しても正しい色にならないので注意すること。
fk_Materialが持つ要素は以下の6つである。 ごく簡単な説明と共に紹介する。
既にsetMaterial()を行ったモデルに対して一時的に色や透明度を変更したい場合は、わざわざfk_Materialのオブジェクトを用意する必要はない。例えば透明度を変更したい場合は、以下のようなコードで実現できる。
hogeModel.getMaterial()->setAlpha(0.5);
一度もsetMaterial()を行っていない場合は正しく動作しないので注意すること。同じようなコードで、現在設定されている色の値も得ることができる。
逆に、setMaterial()で指定したマテリアルの色設定を後から変更するだけでは、既にセット済みのモデルには反映されない。何故ならマテリアルの設定は個々のモデルに値渡しされているためである。FKは基本的には参照渡しの関係が多いが、マテリアルに関しては例外であるため、気を付けて欲しい。
物質の色はfk_ModelのsetMaterial関数によって設定するが、線と点の色はそれぞれ別の関数によって設定する。
// 物質の材質設定 fk_Model model; fk_Block block; model.setShape(&block); model.setMaterial(White); // 線の色設定 fk_Line line; model.setShape(&line); model.setLineColor(0.0f, 0.0f, 1.0f); // 点の色設定 fk_Point point; model.setShape(&point); model.setPointColor(1.0f, 0.0f, 0.0f);
線や点の色設定を行わなかった場合に線や点を描画する場合は、設定されているマテリアルの環境反射係数の色が使われる。
半稜線構造や、fk_Solid関係の使い方に関するTipsです。
fk_Solidの位相要素(fk_Vertex, fk_Half, fk_Edge, fk_Loop)のIDは1から始まる。
fk_Loopは5角形以上の多角形を生成できます。 生成方法に違いはありません。
GUIを作るためのFLTK関連のTipsです。
FLTKは標準では日本語に対応していない。 FLTKで日本語を扱うには、FLTKがデフォルトで扱うフォントに日本語を指定する必要がある。
Fl::set_font(FL_HELVETICA, "フォント名"); // 例 Fl::set_font(FL_HELVETICA, "メイリオ");
指定する場所はマテリアルを初期化するあたりがお勧めです。
FL_HELVETICAとは、FLTKがデフォルトで利用するフォントを指す定数値です。 set_font()は指定した定数値が実際に利用するフォントを置き換える働きをします。 フォント名はWindowsのコントロールパネルのフォント一覧で表示されるものを指定します。 Vista以降なら"メイリオ"、XP以前なら"MS ゴシック"(MSは全角で、その後ろは半角スペース)を指定すれば安全です。