Bulletを使用して一人称カメラを実装しました。これはカプセル形状の剛体です。Bulletを使用して数日しか経っていませんが、物理エンジンは初めてです。私はそれbtRigidBody::setLinearVelocity()
を移動するために使用し、それは世界と完全に衝突します。唯一の問題は、Y値が自由に移動することです。これは、ボディを移動する前に、並進ベクトルのY値をゼロに設定することで一時的に解決しました。これは、高所から落下する場合を除いて、すべての場合に機能します。
体が背の高いオブジェクトから落ちた場合でも、移動ベクトルのY値がゼロに設定されているため、移動を停止して地面に落ちるまで速度は設定されます。これを解決するには、ボディからレイをダウンキャストしてワールドのY値を決定し、その値とカメラボディのY値の差を確認して、次の場合は動きを無効にするか、速度を遅くします違いは十分に大きいです。
光線を投射し、光線が当たった世界のY値を特定するだけで、少し行き詰まりました。私はこのコールバックを実装しました:
struct AllRayResultCallback : public btCollisionWorld::RayResultCallback{
AllRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld)
: m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld), m_closestHitFraction(1.0){}
btVector3 m_rayFromWorld;
btVector3 m_rayToWorld;
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
float m_closestHitFraction;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
{
if(rayResult.m_hitFraction < m_closestHitFraction)
m_closestHitFraction = rayResult.m_hitFraction;
m_collisionObject = rayResult.m_collisionObject;
if(normalInWorldSpace){
m_hitNormalWorld = rayResult.m_hitNormalLocal;
}
else{
m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal;
}
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, m_closestHitFraction);
return 1.0f;
}
};
そして、移動機能で、私はこのコードを持っています:
btVector3 from(pos.x, pos.y + 1000, pos.z); // pos is the camera's rigid body position
btVector3 to(pos.x, 0, pos.z); // not sure if 0 is correct for Y
AllRayResultCallback callback(from, to);
Base::getSingletonPtr()->m_btWorld->rayTest(from, to, callback);
だから私はcallback.m_hitPointWorld
ベクトルを持っています、それはちょうど各フレームのカメラの位置を示しているようです。Googleで光線のキャストの例とBulletのドキュメントを検索しましたが、例を見つけるのは簡単ではありませんでした。例が本当に必要なすべてです。
または、剛体を地面に保つ方法がBulletにあるのでしょうか。
私はレンダリングエンジンとしてOgre3Dを使用しており、レイをキャストするのは非常に簡単ですが、簡単にするためにすべてのレイのキャストをBullet内に保持したいと考えています。
誰かが私を正しい方向に向けることができますか?ありがとう。