ボーンのMatrixと、ActerのShapeのMatrixで、初期位置でのbindMatrixを作り、以後ActerとボーンのMatrixを橋渡しさせる必要がある。
キーフレームでまずアニメーションさせ、キャラクターのCollisionShapeと衝突しているのがわかれば、その部分以下の部位をPhysXを基にアニメーションさせれば、それっぽく見えるのではないだろうか。
それで衝突がなくなれば、キーフレームの位置にゆっくりあわせてやればキーフレーム側に復帰できると。
結構しんどそう。
2008年11月5日水曜日
スキンメッシュ完成
GLSLを勉強して、とりあえずvertex shaderを利用したスキニングに成功。
非常に動作が軽くなった。まぁ前のが異常すぎただけか。glVertexweightfEXTって命令使うとシェーダー使わなくても良い雰囲気するけど、これはこれでいいね。
ハマっていたことをメモメモ
・vertex shaderだけ使うってのは無理らしい。そのため、適当なfragment shaderも用意する必要がある。
・ハードウェアの制限でvertex shader に渡せるマトリックスが61個?らしい。
・attribute intは、ないっぽい。
明らかにきちんと動くはずなのに動かなかったりとか多い。(多分どこかミスがあるんだろうけど)しかもエラーログ吐かないので困る。GLSLってどうやってデバッグすればいいんだろう。
//GLSLのチュートリアルとか
NeHe
GLSLをつかったOpenGLプログラム
GLSL Tutorial von Lighthouse3D
OpenGL Shading Language Tutorials and Demos
yunoの雑記帳 - GLSL
OpenGL:Codes:Simple GLSL example
非常に動作が軽くなった。まぁ前のが異常すぎただけか。glVertexweightfEXTって命令使うとシェーダー使わなくても良い雰囲気するけど、これはこれでいいね。
ハマっていたことをメモメモ
・vertex shaderだけ使うってのは無理らしい。そのため、適当なfragment shaderも用意する必要がある。
・ハードウェアの制限でvertex shader に渡せるマトリックスが61個?らしい。
・attribute intは、ないっぽい。
明らかにきちんと動くはずなのに動かなかったりとか多い。(多分どこかミスがあるんだろうけど)しかもエラーログ吐かないので困る。GLSLってどうやってデバッグすればいいんだろう。
//GLSLのチュートリアルとか
NeHe
GLSLをつかったOpenGLプログラム
GLSL Tutorial von Lighthouse3D
OpenGL Shading Language Tutorials and Demos
yunoの雑記帳 - GLSL
OpenGL:Codes:Simple GLSL example
2008年10月26日日曜日
Skinned mesh
スキンメッシュのコアの部分をメモ
Colladaを読み込む事で、
バインドポーズ逆行列[i]・Jointの行列[i]・モデルの頂点座標・weight[i]が 取れる。(iはJointのIndex)
バインドポーズの逆行列はINV_BIND_MATRIXってColladaのファイル内に書かれている行列。Jointの行列[i] = (・・・*Joint[i]の親の親の変換行列*Joint[i]の親の変換行列*Joint[i]の変換行列)ってな感じで再帰的に計算する。
//変形後の頂点を得るための式
finalPosition = ∑( weight * JointMatrix[i] * BindPoseInversMatrix[i] * originalPosition );
でボーンを曲げた後の各頂点の位置を計算できる。
ここらへんを参照
http://www.gamedev.net/community/forums/topic.asp?topic_id=392338
http://marupeke296.com/DXG_No27_SkinMeshAnimation.html
http://marupeke296.com/DXG_No28_SkinMeshDrawing.html
ただ、今CPUで無理矢理計算しているので重すぎる。バーテックスシェーダーを使ったスキンメッシュに変えないと。自分のノートパソコンが対応してないようなので、学校のパソコン使わなきゃ。
Colladaを読み込む事で、
バインドポーズ逆行列[i]・Jointの行列[i]・モデルの頂点座標・weight[i]が 取れる。(iはJointのIndex)
バインドポーズの逆行列はINV_BIND_MATRIXってColladaのファイル内に書かれている行列。Jointの行列[i] = (・・・*Joint[i]の親の親の変換行列*Joint[i]の親の変換行列*Joint[i]の変換行列)ってな感じで再帰的に計算する。
//変形後の頂点を得るための式
finalPosition = ∑( weight * JointMatrix[i] * BindPoseInversMatrix[i] * originalPosition );
でボーンを曲げた後の各頂点の位置を計算できる。
ここらへんを参照
http://www.gamedev.net/community/forums/topic.asp?topic_id=392338
http://marupeke296.com/DXG_No27_SkinMeshAnimation.html
http://marupeke296.com/DXG_No28_SkinMeshDrawing.html
ただ、今CPUで無理矢理計算しているので重すぎる。バーテックスシェーダーを使ったスキンメッシュに変えないと。自分のノートパソコンが対応してないようなので、学校のパソコン使わなきゃ。
Colladaファイルの注意点
OpenGLは
float* m[16]={・・・略・・・};
glBegin(GL_POINTS);
glMultMatrixf(m);
glVertexf(x,y,z,1)
glEnd();
上記のコードではこんな行列計算をしている。
(m[0] m[4] m[8] m[12]) (x)
(m[1] m[5] m[9] m[13]) (y)
(m[2] m[6] m[10] m[14]) (z)
(m[3] m[7] m[11] m[15]) (1)
つまり、m[12],m[13],m[14]が平行移動の成分になる。
一方Colladaのファイル内は
m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15
のように書かれている。これが意味する行列計算は
(m0 m1 m2 m3 ) (x)
(m4 m5 m6 m7 ) (y)
(m8 m9 m10 m11) (z)
(m12 m13 m14 m15) (1)
つまり、m3,m7,m11が平行移動の成分となる。
OpenGLで使うときは、転置して保存してやる必要がある。
float* m[16]={・・・略・・・};
glBegin(GL_POINTS);
glMultMatrixf(m);
glVertexf(x,y,z,1)
glEnd();
上記のコードではこんな行列計算をしている。
(m[0] m[4] m[8] m[12]) (x)
(m[1] m[5] m[9] m[13]) (y)
(m[2] m[6] m[10] m[14]) (z)
(m[3] m[7] m[11] m[15]) (1)
つまり、m[12],m[13],m[14]が平行移動の成分になる。
一方Colladaのファイル内は
m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15
のように書かれている。これが意味する行列計算は
(m0 m1 m2 m3 ) (x)
(m4 m5 m6 m7 ) (y)
(m8 m9 m10 m11) (z)
(m12 m13 m14 m15) (1)
つまり、m3,m7,m11が平行移動の成分となる。
OpenGLで使うときは、転置して保存してやる必要がある。
FColladaの基本的な流れ
なんとか、スキンメッシュアニメーションを実装できた。
Colladaが比較的分かりやすいフォーマットだからだろうが、前作ろうとした時は断念したから、できて少しうれしい。
FColladaの使い方の基本的な流れをメモ。
// FCDDocumentに読み込む
FCollada::LoadDocumentFromFile(FCDDocument* document, const wchar_t* ファイル名);
↓
↓
//各要素のライブラリーを読み込む(例としてGeometryとする)
//Colladaのファイルの要素にもlibrary_geometriesとかあるので、それと同じと思えばよい
FCDGeometryLibrary* geolib = document->GetGeometryLibrary();
↓
↓
//エンティティを取る
FCDGeometry* geo = geolib->GetEntity();
↓
↓
必要な情報を抜き出し、保存する。
////////////////////////////////////
//ここまでで部品を読み込んだだけ
////////////////////////////////////
実際にシーン情報が保存されているのはColladaファイル内のlibrary_visual_scenesにある。
// sceneのルートノードを取る
FCDSceneNode* root=document->GetVisualSceneRoot();
↓
↓
各ノードを再帰的に呼び出す。
ルート以下のノードは、先ほど保存した各部品が指定されている。
FCDEntity* entity = node->GetInstance(i)->GetEntity(); //iはインスタンスのIndex
entity->GetDaeId()でIdを調べて、先ほどの読み込んだ部品と結びつける
と、頑張ってFCollada使って読み込んでみたけど、FColladaってもう更新行われないっぽい。
フォーラムにもう更新しませんっぽい事書かれてたし。Collada DOMを使えって事かなぁ。
Colladaが比較的分かりやすいフォーマットだからだろうが、前作ろうとした時は断念したから、できて少しうれしい。
FColladaの使い方の基本的な流れをメモ。
// FCDDocumentに読み込む
FCollada::LoadDocumentFromFile(FCDDocument* document, const wchar_t* ファイル名);
↓
↓
//各要素のライブラリーを読み込む(例としてGeometryとする)
//Colladaのファイルの要素にもlibrary_geometriesとかあるので、それと同じと思えばよい
FCDGeometryLibrary* geolib = document->GetGeometryLibrary();
↓
↓
//エンティティを取る
FCDGeometry* geo = geolib->GetEntity();
↓
↓
必要な情報を抜き出し、保存する。
////////////////////////////////////
//ここまでで部品を読み込んだだけ
////////////////////////////////////
実際にシーン情報が保存されているのはColladaファイル内のlibrary_visual_scenesにある。
// sceneのルートノードを取る
FCDSceneNode* root=document->GetVisualSceneRoot();
↓
↓
各ノードを再帰的に呼び出す。
ルート以下のノードは、先ほど保存した各部品が指定されている。
FCDEntity* entity = node->GetInstance(i)->GetEntity(); //iはインスタンスのIndex
entity->GetDaeId()でIdを調べて、先ほどの読み込んだ部品と結びつける
と、頑張ってFCollada使って読み込んでみたけど、FColladaってもう更新行われないっぽい。
フォーラムにもう更新しませんっぽい事書かれてたし。Collada DOMを使えって事かなぁ。
2008年10月10日金曜日
2008年9月26日金曜日
バグとの戦い
とりあえず、モデル完成?
Nima1.04のバグが多すぎて困る。新しいバージョンを公開してほしい。(公開してもらってるだけありがたいか…)
goal orientとDrive Springを設定しているにもかかわらず、関節が動かない時がある。その時は、Degrees of Freedome and limitsの設定を一度全部freeにしてから、元の設定に戻してやると動くようになる。その他にもMayaを落とすバグが数多くあり、こまめにセーブしながら作業する必要がある。
あと、セーブしたファイルをロードするとrigid constractがどこかに飛んでモデルが崩れている時があるが、Rigid Constractを平行移動→元に戻す(Ctrl+z)で元に戻る。
Nima1.04のバグが多すぎて困る。新しいバージョンを公開してほしい。(公開してもらってるだけありがたいか…)
goal orientとDrive Springを設定しているにもかかわらず、関節が動かない時がある。その時は、Degrees of Freedome and limitsの設定を一度全部freeにしてから、元の設定に戻してやると動くようになる。その他にもMayaを落とすバグが数多くあり、こまめにセーブしながら作業する必要がある。
あと、セーブしたファイルをロードするとrigid constractがどこかに飛んでモデルが崩れている時があるが、Rigid Constractを平行移動→元に戻す(Ctrl+z)で元に戻る。
2008年9月23日火曜日
NimaでRagdoll
とりあえず、Nimaで人のモデルを作れたのでその手順をメモ。
1. モデルを作って、ボーンを割り当てる。
2. ボーンのweightを編集する。weightは後から変えられないのできちんと作りこむ。
3. 新しいLayerを作ってRigid bodiesという名前にして、そのLayerを選択しておく(省略可)
4. モデルのメッシュを指定して、PhysX->Convex Hulls->Skin Collision Volume(SCV)で衝突に使う形状を自動生成する
5. 生成された形状の頂点を編集する。関節部分にスペースができるように(曲げるため)
6. 5で編集した全Collision Volumeを選択して、PhysX->Ragdolls->Extract ragdoll meshes from SCV
7. PhysX->Ragdolls->Create ragdoll rigid bodies
8. 新しいLayerを作ってRigid Constrains、そのLayerを選択しておく(省略可)
9. PhysX->Ragdolls->Create ragdoll rigid constrains
10.できたrigid constrainsを編集する。Nimaのサンプルにragdall_scene.maがあるのでこれをお手本にしながら作る。Degrees of freedom and limitsだけでなくTransform Attribute のRotate成分も編集する必要があるので注意。Rotate成分を編集した後、rigid constrainを適当に平行移動し元に戻す(Ctrl+z)する必要がある。(何故かわからないが、それをするとrigid constrainが持つ位置・方向がそろう。)
11.全ボーンのTransform AttributeのRotate成分がrigid constrainと連結しているため、このコネクションを切る。Attribute editorのRotateの項目で右クリック->Break connectionでコネクションを切れる。
12.Collision Volumeとボーンを対応付けるため、Parent Constrainを作る。Animationのメニューに切り替えて、Constrain->Parentを選択するとParent Constrainができる。(もちろん割り当てるのはTranslationとRotate。必要に応じてx成分の連携を止めるなどする必要があるかもしれない)Nimaのサンプルにragdall_scene.maを参照しながらParent Constrainを作れば問題ない。ここで注意するのが、rigid constrainと各ボーンを割り当てるのではなく、rigid bodyと各ボーンを割り当てる事。
ここまで終えると、とりあえずサンプルragdall_scene.maのようなモデルはできる
1. モデルを作って、ボーンを割り当てる。
2. ボーンのweightを編集する。weightは後から変えられないのできちんと作りこむ。
3. 新しいLayerを作ってRigid bodiesという名前にして、そのLayerを選択しておく(省略可)
4. モデルのメッシュを指定して、PhysX->Convex Hulls->Skin Collision Volume(SCV)で衝突に使う形状を自動生成する
5. 生成された形状の頂点を編集する。関節部分にスペースができるように(曲げるため)
6. 5で編集した全Collision Volumeを選択して、PhysX->Ragdolls->Extract ragdoll meshes from SCV
7. PhysX->Ragdolls->Create ragdoll rigid bodies
8. 新しいLayerを作ってRigid Constrains、そのLayerを選択しておく(省略可)
9. PhysX->Ragdolls->Create ragdoll rigid constrains
10.できたrigid constrainsを編集する。Nimaのサンプルにragdall_scene.maがあるのでこれをお手本にしながら作る。Degrees of freedom and limitsだけでなくTransform Attribute のRotate成分も編集する必要があるので注意。Rotate成分を編集した後、rigid constrainを適当に平行移動し元に戻す(Ctrl+z)する必要がある。(何故かわからないが、それをするとrigid constrainが持つ位置・方向がそろう。)
11.全ボーンのTransform AttributeのRotate成分がrigid constrainと連結しているため、このコネクションを切る。Attribute editorのRotateの項目で右クリック->Break connectionでコネクションを切れる。
12.Collision Volumeとボーンを対応付けるため、Parent Constrainを作る。Animationのメニューに切り替えて、Constrain->Parentを選択するとParent Constrainができる。(もちろん割り当てるのはTranslationとRotate。必要に応じてx成分の連携を止めるなどする必要があるかもしれない)Nimaのサンプルにragdall_scene.maを参照しながらParent Constrainを作れば問題ない。ここで注意するのが、rigid constrainと各ボーンを割り当てるのではなく、rigid bodyと各ボーンを割り当てる事。
ここまで終えると、とりあえずサンプルragdall_scene.maのようなモデルはできる
2008年9月13日土曜日
ありがたや
K大学からK先生がいらっしゃって、色々研究で困っている事を相談した。
K先生に相談したのは、色々な転倒事例を記した論文をどのように分析してプログラムのパラメータとして与えるべきであろうか、という事である。K先生は、どのような状況下の時にどのようなこけ方をするかを与えるのは一般化して、データさえ揃えばシミュレーションできるぞっていう所まで示したら良いのではないかとご助言いただいた。確かにそれならできるかもしれない。そのシステムを構築した後に、そのシステムで全ての転倒をカバーしてるっていう事を示すべきだとも忠告していただいた。なんか、以外な方向からの答えだったので驚き。偉い人は違うなぁ。
K先生に相談したのは、色々な転倒事例を記した論文をどのように分析してプログラムのパラメータとして与えるべきであろうか、という事である。K先生は、どのような状況下の時にどのようなこけ方をするかを与えるのは一般化して、データさえ揃えばシミュレーションできるぞっていう所まで示したら良いのではないかとご助言いただいた。確かにそれならできるかもしれない。そのシステムを構築した後に、そのシステムで全ての転倒をカバーしてるっていう事を示すべきだとも忠告していただいた。なんか、以外な方向からの答えだったので驚き。偉い人は違うなぁ。
2008年9月10日水曜日
Maya(Nima)→→[[Collada]]→→ColladaLoader
ひたすら、PhysXのMayaプラグインNimaを扱っていた。
ほとんどMayaを使ったことが無いので、色々苦労したが結構わかってきた。
lamp.mbとragdoll.mbを参考にRagdollのモデルに、キーフレームで作った動きをさせたいと考えている。まず、人体のスケルトンをコピーして、ragdollの横に配置。そのスケルトンはお手本となるキーフレームを持つスケルトンである。そして、お手本スケルトンの各リグのrotationの成分を、ragdollのconstraint内のgoal orientationに設定する。(ハイパーグラフ(connection)でお手本スケルトンのリグ内のrotation成分を、constraintのgoal orientationに連結する)そして、Drive spring twistとかDrive spring swingとかに適当な値を設定する。そうすることで、現在のキーフレームの動きポーズになるように、間接部分に力がかかる。(モーターを使ってる)
ただ、サンプルについていたRagdollのconstraintでその操作を行ってもうまくいかない。。。何故かわからないがconstraintを新しく作り直すとうまくいく。意味がわからない。また、colladaに吐き出した時に、このragdollのスキンがcolladaLoaderで表示できない。色々わからない部分があり、詰まり気味。
ほとんどMayaを使ったことが無いので、色々苦労したが結構わかってきた。
lamp.mbとragdoll.mbを参考にRagdollのモデルに、キーフレームで作った動きをさせたいと考えている。まず、人体のスケルトンをコピーして、ragdollの横に配置。そのスケルトンはお手本となるキーフレームを持つスケルトンである。そして、お手本スケルトンの各リグのrotationの成分を、ragdollのconstraint内のgoal orientationに設定する。(ハイパーグラフ(connection)でお手本スケルトンのリグ内のrotation成分を、constraintのgoal orientationに連結する)そして、Drive spring twistとかDrive spring swingとかに適当な値を設定する。そうすることで、現在のキーフレームの動きポーズになるように、間接部分に力がかかる。(モーターを使ってる)
ただ、サンプルについていたRagdollのconstraintでその操作を行ってもうまくいかない。。。何故かわからないがconstraintを新しく作り直すとうまくいく。意味がわからない。また、colladaに吐き出した時に、このragdollのスキンがcolladaLoaderで表示できない。色々わからない部分があり、詰まり気味。
2008年9月3日水曜日
連結
ひたすら、ColladaMayaで吐いたColladaファイルを見ていた。
キーフレームを持ったモデル(Lamp.ma)から作ったLamp.daeだが、それをMayaで読もうとすると問題あり。Lamp.ma内には2つのラ ンプがある。キーフレームだけで作っているランプは問題ないが、キーフレーム+PhysXのモデルの方のキーフレームの要素がなくなっている。 Lamp.maのDGを見てみると、キーフレーム+PhysXのモデルは、キーフレームだけで作っているランプのアニメーションを参照しているようだ。ど うやら、この部分の連結がうまくいってないらしい。その連結を考慮したLoaderにするべきのようだ。
キーフレームを持ったモデル(Lamp.ma)から作ったLamp.daeだが、それをMayaで読もうとすると問題あり。Lamp.ma内には2つのラ ンプがある。キーフレームだけで作っているランプは問題ないが、キーフレーム+PhysXのモデルの方のキーフレームの要素がなくなっている。 Lamp.maのDGを見てみると、キーフレーム+PhysXのモデルは、キーフレームだけで作っているランプのアニメーションを参照しているようだ。ど うやら、この部分の連結がうまくいってないらしい。その連結を考慮したLoaderにするべきのようだ。
2008年8月29日金曜日
少し進む
久しぶりに進んだ。切羽詰るとやはり進む。
FCollada(3.05B)を使ったColladaLoaderをちまちまとGLUTのプロジェクトに移植。
最初プロジェクトを見たときはファイルの数の多さに、やってられるか!って思ったが、よく見てみるとほとんどのファイルはコンテナとして用意されているだけだった。ColladaLoaderViewは、デバイスコンテキストとかウィンドウ関係の処理を記述しているだけだから、GLUTを使うならいらないし、ColladaLoaderDocはラッパーみたいな感じの処理ばかりで、CLMainをみたら移植できそう。
ただ、途中謎のエラーが発生したり(StdAfx.hなどインクルードを整理し解決)、glMultiTexCoord4fが謎のエラーを吐いたり(GLEWの初期化処理忘れ)して、一つづつデバッグしてた。GLEWなんて使ったことなかったよ。いい勉強になった。でもこんだけ拡張機能あっても全部使えないわ。なんだかんだで苦労した。(CStringはatlstr.hをインクルードして、そのまま利用しちゃった。MFCじゃないから気持ち悪い。時間があったら書き換えよう。)
とりあえず後はアニメーションとphysXのデータか。アニメーションの方はColladaLoaderでも読めるのでそれを参考に作るとして、問題はPhysXの方。まぁなんとかなるだろ。
FCollada(3.05B)を使ったColladaLoaderをちまちまとGLUTのプロジェクトに移植。
最初プロジェクトを見たときはファイルの数の多さに、やってられるか!って思ったが、よく見てみるとほとんどのファイルはコンテナとして用意されているだけだった。ColladaLoaderViewは、デバイスコンテキストとかウィンドウ関係の処理を記述しているだけだから、GLUTを使うならいらないし、ColladaLoaderDocはラッパーみたいな感じの処理ばかりで、CLMainをみたら移植できそう。
ただ、途中謎のエラーが発生したり(StdAfx.hなどインクルードを整理し解決)、glMultiTexCoord4fが謎のエラーを吐いたり(GLEWの初期化処理忘れ)して、一つづつデバッグしてた。GLEWなんて使ったことなかったよ。いい勉強になった。でもこんだけ拡張機能あっても全部使えないわ。なんだかんだで苦労した。(CStringは
とりあえず後はアニメーションとphysXのデータか。アニメーションの方はColladaLoaderでも読めるのでそれを参考に作るとして、問題はPhysXの方。まぁなんとかなるだろ。
2008年8月27日水曜日
Collada DOM と FCollada
Collada DOM を調べてたら、どうもCollada DOM 以外にFColladaという読み込むためのツールがあるそうだ。で、どっちがいいの?って思って調べてみるとこんな議論が。
Collada DOMはローレベル(悪い意味じゃなく)のAPIで、FColladaはハイレベルのAPIなのか。自分の用途としてはFColladaを使った方がよさげ。NimaもFCollada使ってるそうなので、なおさらFColladaの方がよさそう。なのでFColladaについて調べてみる。
Collada DOMはローレベル(悪い意味じゃなく)のAPIで、FColladaはハイレベルのAPIなのか。自分の用途としてはFColladaを使った方がよさげ。NimaもFCollada使ってるそうなので、なおさらFColladaの方がよさそう。なのでFColladaについて調べてみる。
2008年8月26日火曜日
NxuStream
PhysXのNxuStreamを使えば、Nimaで作った物理付Colladaからプログラム側へ持っていけるようなので調べていると、ある記事を発見。NxuStream does not do anything with the graphics portion of a COLLADA file. とある。要するにphysXのアトリビュートは持っていけるけど、ジオメトリとかキーフレームモーションとかは無理だよって事だと思う。キーフレームを持った物理付モデルのlamb.maみたいな事をしたいので他のライブラリを使った方がよさそう。Collada DOMを調べてみよう。
やりたいのはこういうこと。Keyframeを持ったモデルが物理的な影響を受けた時のアニメーションを作り出したい。
やりたいのはこういうこと。Keyframeを持ったモデルが物理的な影響を受けた時のアニメーションを作り出したい。
登録:
投稿 (Atom)