Bullet Physics - Sert bir gövdeden düz bir ışın yayma (birinci şahıs kamerası)


10

Bullet kullanarak birinci şahıs kamera uyguladım - kapsül şeklinde sert bir gövde. Bullet'i sadece birkaç gündür kullanıyorum ve fizik motorları benim için yeni. Kullandığım btRigidBody::setLinearVelocity()taşımak için ve dünya ile mükemmel çarpışır. Tek sorun Y-değeri serbestçe hareket etmesidir, bu da çeviri vektörünün Y değerini vücut hareket ettirilmeden önce sıfıra ayarlayarak geçici olarak çözdüm. Bu, yükseklikten düşme hariç tüm durumlar için geçerlidir.

Gövde uzun bir nesneyi düşürdüğünde, siz çevirme vektörünün Y değeri, hareket etmeyi bırakıp yere düşene kadar sıfıra ayarlandığından hala kayabilirsiniz (hız yalnızca hareket ederken ayarlanır). Bunu çözmek için, dünyanın Y değerini belirlemek ve bu değer ile kamera gövdesinin Y değeri arasındaki farkı kontrol etmek için vücuttan bir ışın dökmeyi denemek ve hareketi devre dışı bırakmak veya yavaşlatmak istiyorum fark yeterince büyük.

Ben sadece bir ışın döküm ve vurduğu dünyanın Y değerini belirlemek biraz takılıp kaldım. Bu geri aramayı gerçekleştirdim:

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;
    }
};

Ve hareket fonksiyonunda, bu kod var:

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);

Bu yüzden callback.m_hitPointWorld, her karenin kameranın konumunu gösteren bir vektöre sahibim . Google'da döküm ışınlarının yanı sıra Bullet belgelerine ilişkin örnekler aradım ve sadece bir örnek bulmak zor oldu. Bir örnek gerçekten ihtiyacım olan tek şey.

Ya da belki de Bullet'te katı cismi yerde tutmak için bir yöntem var mı?

Ogre3D'yi bir oluşturma motoru olarak kullanıyorum ve bir ışın aşağı dökmek oldukça basittir, ancak basitlik için tüm ışın dökümünü Bullet içinde tutmak istiyorum.

Biri beni doğru noktaya yönlendirebilir mi? Teşekkürler.

Yanıtlar:


10

Çözümün orijinal girişimden çok daha basit olduğu ortaya çıkıyor ve sadece bir ışın çarpışmasını test ediyorsanız alt sınıflamaya gerek yok.

Çarpışma vektörünü almak için tek yapmanız gereken:

btVector3 btFrom(camPos.x, camPos.y, camPos.z);
btVector3 btTo(camPos.x, -5000.0f, camPos.z);
btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo);

Base::getSingletonPtr()->m_btWorld->rayTest(btFrom, btTo, res); // m_btWorld is btDiscreteDynamicsWorld

if(res.hasHit()){
    printf("Collision at: <%.2f, %.2f, %.2f>\n", res.m_hitPointWorld.getX(), res.m_hitPointWorld.getY(), res.m_hitPointWorld.getZ());
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.