Saya sudah mengimplementasikan kamera orang pertama menggunakan Bullet - ini adalah tubuh yang kaku dengan bentuk kapsul. Saya hanya menggunakan Bullet selama beberapa hari dan mesin fisika baru bagi saya. Saya gunakan btRigidBody::setLinearVelocity()
untuk memindahkannya dan bertabrakan dengan sempurna dengan dunia. Satu-satunya masalah adalah nilai-Y bergerak bebas, yang untuk sementara saya selesaikan dengan mengatur nilai-Y dari vektor terjemahan menjadi nol sebelum tubuh dipindahkan. Ini bekerja untuk semua kasus kecuali ketika jatuh dari ketinggian.
Saat tubuh menjatuhkan benda tinggi, Anda masih bisa meluncur karena nilai Y vektor terjemahan diatur ke nol, sampai Anda berhenti bergerak dan jatuh ke tanah (kecepatan hanya diatur saat bergerak). Jadi untuk menyelesaikan ini, saya ingin mencoba melemparkan sinar ke bawah dari tubuh untuk menentukan nilai-Y dunia, dan memeriksa perbedaan antara nilai itu dan nilai-Y dari tubuh kamera, dan menonaktifkan atau memperlambat gerakan jika perbedaannya cukup besar.
Saya agak terjebak pada hanya melempar sinar dan menentukan nilai-Y dari dunia di mana ia melanda. Saya sudah menerapkan panggilan balik ini:
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;
}
};
Dan dalam fungsi pergerakan, saya memiliki kode ini:
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);
Jadi saya punya callback.m_hitPointWorld
vektor, yang sepertinya hanya menunjukkan posisi kamera setiap frame. Saya telah mencari Google untuk contoh sinar casting, serta dokumentasi Bullet, dan sulit untuk hanya menemukan contoh. Contoh adalah yang saya butuhkan.
Atau mungkin ada beberapa metode di Bullet untuk menjaga tubuh tetap kaku di tanah?
Saya menggunakan Ogre3D sebagai mesin rendering, dan casting sinar ke bawah cukup mudah dengan itu, namun saya ingin menyimpan semua pengecoran sinar dalam Bullet untuk kesederhanaan.
Adakah yang bisa mengarahkan saya ke arah yang benar? Terima kasih.