剛体表示

モーション再生の積み残しになっていたBulletの使い方について調べ中。


ARTK_MMD
http://ppyy.hp.infoseek.co.jp/artk_mmd.html
のソースを組み合わせてSDLOpenGLで再生するところまでできた。
今から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でさくっとできる。