スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Pov-Ray各材質の表現 ODE連携

今週は引き続きPov-Rayの材質表現を追加したり,設定をファイルに保存できるようにする.

ウレタンゴム,カーボンの表現:


ウレタンゴムはSSLT(Subsurface Light Transport)による拡散透過表現.
pigment { color rgb<187/255,150/255,30/255> }

finish {diffuse 0.7 roughness 0.01 reflection 0.03
subsurface { translucency <1.0,1.0,1.0>*3.0 }}

interior { ior 1.50 }

カーボンはdifuseを下げたチェッカー模様+弱い鏡面反射設定でそれらしくなる.
pigment{checker color rgb<0.1,0.1,0.1> color rgb<0.3,0.3,0.3> scale 2}

finish {diffuse 0.1 specular 0.5 roughness 0.2 reflection 0.03}



材質設定は面倒な作業だが,少なくとも1回行えばファイルロードで2回目からは不要になるようにした.


次に材質設定をODEに反映させて物理シミュレーションが行えるようにする.
約1000個のランダムなサイズの積み木+鉄のブロックの衝突:



材料ごとの密度からポリゴンの体積,重量や重心,慣性モーメントは計算で求まるため,材質の割り当てのみで済む.
ODEでは直方体,球,円柱といった基本図形のほか,3角形ポリゴンの自由形状も扱うことができる.
3角形ポリゴンの体積は3角メッシュの頂点(vector_a1,vector_a2,vector_a3)と原点(vector_a4(0,0,0))で作られる微小3角錐の体積を総和して求める.
プログラム例:
struct Zahyo{
float x;
float y;
float z;
}
//***********3角ポリゴンと原点を結んでできる3角錐の体積を返す*****************
float Get_Volume_Triangular_Pyramid(Zahyo a1,Zahyo a2,Zahyo a3)
{
Zahyo v1;
float s;
v1.x=a1.y*a2.z-a1.z*a2.y; //a1xa2(外積)の計算
v1.y=a1.z*a2.x-a1.x*a2.z;
v1.z=a1.x*a2.y-a1.y*a2.x;
s=(v1.x*a3.x+v1.y*a3.y+v1.z*a3.z)/6.0; //a3をかける
return s;
}
//***********3角ポリゴンと原点を結んでできる3角錐の重心を返す*****************
Zahyo Get_Gpos_Triangular_Pyramid(Zahyo a1,Zahyo a2,Zahyo a3)
{
Zahyo v1;
v1.x=(a1.x+a2.x+a3.x)/4.0; //3点+原点を通る3角錐の重心
v1.y=(a1.y+a2.y+a3.y)/4.0; //3点+原点を通る3角錐の重心
v1.z=(a1.z+a2.z+a3.z)/4.0; //3点+原点を通る3角錐の重心
return v1;
}

//***********ポリゴンから簡易的に質量,重心を求める******************
void Set_STL_MASS_Param_Light(void)
{
int i,j,max_cnt;
float dv,vo;
Zahyo g_pos,sum_p;

Copy_Rocal_STL_DATA();//STLをロードした時の姿勢に復帰

for(j=0;j max_cnt=STL_FACE_NO[j];

vo=0;
g_pos.Reset_ZERO();
sum_p.Reset_ZERO();

for(i=0;i dv=Get_Volume_Triangular_Pyramid(STL_MULT[j][i].a,STL_MULT[j][i].b,STL_MULT[j][i].c); //微小体積を積算
vo+=dv;
g_pos=Get_Gpos_Triangular_Pyramid(STL_MULT[j][i].a,STL_MULT[j][i].b,STL_MULT[j][i].c); //微小三角錐の重心位置
sum_p.x+=g_pos.x*dv;
sum_p.y+=g_pos.y*dv;
sum_p.z+=g_pos.z*dv;
}

sum_p.x/=vo;
sum_p.y/=vo;
sum_p.z/=vo;
STL_COG[j]=sum_p; //重心座標[mm]
Part_Weight[j]=MAT_Density[MAT_NO[j]]*vo/1000.0; //重量[kg]
}
}


慣性モーメントはODEのAPIを使って求める.
dMass m;
m.mass=Part_Weight[i]; //重量=体積x密度
dMassSetTrimeshTotal(&m,Part_Weight[i],stl_plygons[i].geom); //慣性テンソル行列を取得
dGeomSetPosition(stl_plygons[i].geom, -m.c[0], -m.c[1], -m.c[2]);//ジオメトリを重心位置に動かす
dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]);//重心位置をオフセット

これらのソフト間で形状データを受け渡す際の注意点として,座標軸の向きがある.
ODE,OpenGLは右手系 Pov-Rayは左手系である。また,初期のZ方向の向きなどが違う.
左右や天地が反転した画像が出力される場合,原因は座標系にある場合が多い.
平行移動だけでなく,3角メッシュの表裏を決定する3角形の頂点座標の回転順序も逆になるので要注意!

よってODEの結果をOpen_GL,Pov-Rayでレンダリングする際には物体の姿勢行列を入れ替える必要がある.
ODE⇒OpenGL
//********回転行列をODEのものからGL用の横型に変換する**********
void TransRate_RotMatrixGL(float rot_matrix[])
{
int i;
float rot_buf[16];
//**********ODEのマトリクス成分→OpenGLのマトリクス成分に変換********
rot_buf[0]=rot_matrix[0];
rot_buf[4]=rot_matrix[1];//
rot_buf[8]=rot_matrix[2];

rot_buf[12]=rot_matrix[3];

rot_buf[1]=rot_matrix[4];
rot_buf[5]=rot_matrix[5];//
rot_buf[9]=rot_matrix[6];

rot_buf[13]=rot_matrix[7];

rot_buf[2]=rot_matrix[8];
rot_buf[6]=rot_matrix[9];//
rot_buf[10]=rot_matrix[10];

rot_buf[14]=rot_matrix[11];
//*********ODEの行列は3×3***********
rot_buf[3]=0;
rot_buf[7]=0;
rot_buf[11]=0;
rot_buf[15]=1;

for(i=0;i<16;i++)
rot_matrix[i]=rot_buf[i];
}

OpenGL⇒Pov-Ray
物体を配置する際,以下の変換を行う.

rotate 90*x
matrix<
1,0,0,
0,-1,0,
0,0,1,
0,0,0>






スポンサーサイト

材質設定の追加

今週はSTL-Pov変換ソフトに材質設定の機能を実装する.
STLデータをPovに渡す際に,オブジェクトごとの材質をリストから選択して設定できるようにした.
ロボットでよく使う材料をあらかじめ登録しておき,リストからマテリアルを指定すると色や表面反射などが一度に設定される.

ソフトのスクリーンキャプチャ



レンダリング結果



シャーシはABSのナチュラル色,シャフトは鉄,ホイールはアルミ,タイヤはゴム・・というように1部品ずつ設定するとそれらしいレンダリング結果になる.
ただ,この方法は部品数が多くなるとけっこう厳しい.
本来はCADの「共有」機能で複数のオブジェクトに同一素材を割り当てた情報を引き継げると最も効率が良いのだが,STLは色や材質データを保持できないためそうも行かない.
 モデラーがメタセコイアのようなCGソフトならOBJ形式等でもっと効率の良い受け渡しができそうだが,いかんせんCGソフトはモデリング機能が機械の設計向きではない.
フォトリアルなレンダリング出力のオプションがついた商用ソフトはたくさんあるみたいだが,フリーではまだ見当たらない.
やはりこの辺が限界なのか・・・

法線処理速度UP

今日はSTLの法線平滑化プログラムをブラッシュアップする.
面法線を平滑化した頂点法線に変換する際,計算量が多いのが共通頂点座標の探索である.
これを総当たりでやると,指数関数的に計算量が増えてしまう.

そこで「共通法線は読み込んだファイルデータのあるエリアに固まっている」という仮定のもと,
探索を効率的に行えるようにした.
たいていのモデルで従来に対し1/4程度の計算で済むようになった.

動きが軽快になったため,WEB上で閲覧できる3Dモデルもサクッと高画質レンダリングできるようになった.
例:VEX-Pro shopの部品
ここの部品ショップではPDF等のデータシート以外に現物の3Dデータ(STEPデータ)をダウンロードできる.
これをCADで開いてSTLエクスポートし,自作ソフトでPov-Ray形式に変換してレンダリングする.

メカナムホイール:




マルチモータギアボックス:



ダウンロードからレンダリングまで3分~5分程度でできる.
フリーソフトでこれだけできれば,もはや高価なCGレンダラーやハイエンドCADは不要なのではないかとすら思える.

なお,今のところ処理を全自動にするため材質設定は入れていない.また,着色はランダムで行っている.
材料指定もほぼ半自動でできる処理も今後はソフトに盛り込んでいきたい.

Semi-glossy reflectionのテスト

今日はPov-Rayの金属的な質感向上をテストする.
金属の表面といえば鏡面反射がイメージされるが,実際に身の回りの金属でできたものを見てみると,
ツルツルで鏡のように光っているものは少ない.
たいていは少しボケたような,曇ったような半鏡面になっている.

この「ちょっとくもった鏡面反射」をCGで表現するには,表面の光の散乱をシミュレーションしなければならないが,
残念ながらPov-Rayにはまだその機能が実装されていない.
何とか実際の金属表面に近い質感表現ができないかいろいろ探った.

まずは単純に反射率を落としてみる.


完全鏡面が1.0となる反射率を0.1に設定した.
映り込みが弱くなっただけで,ツルツルの質感は変わらない.
いかにもCGっぽい感じでイマイチである.

次に表面法線を乱して凹凸を表現する機能を使ってみる.



Pov-Rayの設定
normal {marble 0.5 turbulence 0.2}
なんとなくボケた金属っぽい感じは見られるようになった.
表面にたくさんのスジが入り,それが金属の切削加工跡っぽくも見えなくもない.

同様にもう一パターン


Pov-Rayの設定
normal {agate 0.1 }
こちらもランダムなマイクロバンプによって鋳物ぽい感じが出た.
プロフィール

もやね

Author:もやね
長野県在住の会社員(メカニカル・エンジニア).
ロボットは完全な趣味としてやってます.
E-mail:
mo_ya_ne[a]yahoo.co.jp
[a]⇒@

最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
FC2カウンター
ブログ内検索
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。