我已经使用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中。
有人能指出我正确的方向吗?谢谢。