剛体表示
モーション再生の積み残しになっていたBulletの使い方について調べ中。
ARTK_MMD
http://ppyy.hp.infoseek.co.jp/artk_mmd.html
のソースを組み合わせてSDLのOpenGLで再生するところまでできた。
今からbullet部分の調査に入る。
pmdフォーマット
http://blog.goo.ne.jp/torisu_tetosuki/e/84c42d8fa190b4b61f9c326112de2d2e
pmdボーンに対してbulletの剛体を作る。
で、モーションとの連動はフレーム毎に
①ボーン位置・回転を更新
②ボーンIK解決
③剛体位置を今の骨の位置に合わせる
④物理シミュレーション(重力・衝突・位置あわせの加速)
⑤シミュレーション結果をボーンに反映
という一連の処理をボーン加えていくことでやっている。
②、③、④の順番などをどうするかってのが微妙な問題のようだ。
変更すると足がスカートを突き抜けやすくなったりと動きが変わる。
http://www11.atwiki.jp/darui_program/pages/60.html
を参考に剛体を表示してみた。
少しわかった。
追加コード
/////////////////////////////////////////////////////////////////////////////// // draw shape /////////////////////////////////////////////////////////////////////////////// static void drawShape(const btBoxShape *shape) { glPushMatrix(); btVector3 halfExtent = shape->getHalfExtentsWithMargin(); glScalef(halfExtent[0]*2, halfExtent[1]*2, halfExtent[2]*2); glutWireCube(1); glPopMatrix(); } static void drawShape(const btSphereShape *shape) { glPushMatrix(); glutWireSphere(shape->getRadius(), 12, 8); glPopMatrix(); } static void drawShape(const btCapsuleShape *shape) { glPushMatrix(); glScalef(shape->getRadius(), shape->getHalfHeight()*2, shape->getRadius()); glRotatef(90, 1, 0, 0); glutWireSphere(1, 12, 8); glPopMatrix(); } void cBulletPhysics::draw() { glPushMatrix(); // 本体の描画にあわせる glScalef(1.0f, 1.0f, -1.0f); glDisable(GL_DEPTH_TEST); //オブジェクトの数を取得 int numObject = m_pBtWorld->getNumCollisionObjects(); for( int i = 0; i < numObject; i++){ // btCollisionObject btCollisionObject* colObj = m_pBtWorld->getCollisionObjectArray()[i]; // upcast: btCollisionObject -> btRigidBody btRigidBody* body = btRigidBody::upcast( colObj ); //変換行列の取得 btScalar m[16]; if( body && body->getMotionState() ){ btDefaultMotionState* motion = (btDefaultMotionState*)body->getMotionState(); motion->m_graphicsWorldTrans.getOpenGLMatrix( m ); }else{ colObj->getWorldTransform().getOpenGLMatrix(m); } glPushMatrix(); glMultMatrixf( m ); int shapeType=colObj->getCollisionShape()->getShapeType(); switch(shapeType) { case BOX_SHAPE_PROXYTYPE: { drawShape(static_cast<const btBoxShape*>( colObj->getCollisionShape())); } break; case SPHERE_SHAPE_PROXYTYPE: { drawShape(static_cast<const btSphereShape*>( colObj->getCollisionShape())); } break; case CAPSULE_SHAPE_PROXYTYPE: { drawShape(static_cast<const btCapsuleShape*>( colObj->getCollisionShape())); } break; case STATIC_PLANE_PROXYTYPE: // skip break; default: std::cout << "unknown type: " << shapeType << std::endl; break; } glPopMatrix(); } // restore glEnable(GL_DEPTH_TEST); glPopMatrix(); }
getOpenGLMatrixでさくっとできる。