बुलेट फिजिक्स - कठोर शरीर से सीधे नीचे एक किरण को कास्टिंग करना (पहला व्यक्ति कैमरा)


10

मैंने बुलेट का उपयोग करके पहला व्यक्ति कैमरा लागू किया है - यह एक कैप्सूल आकार के साथ एक कठोर शरीर है। मैं केवल कुछ दिनों के लिए बुलेट का उपयोग कर रहा हूं और भौतिकी इंजन मेरे लिए नए हैं। मैं btRigidBody::setLinearVelocity()इसे स्थानांतरित करने के लिए उपयोग करता हूं और यह दुनिया के साथ पूरी तरह से टकराता है। एकमात्र समस्या यह है कि वाई-मूल्य स्वतंत्र रूप से चलता है, जिसे मैंने अस्थायी रूप से शरीर के स्थानांतरित होने से पहले अनुवाद वेक्टर के वाई-मूल्य को शून्य से हल किया है। ऊंचाई से गिरने पर यह सभी मामलों के लिए काम करता है।

जब शरीर एक लंबी वस्तु को गिरा देता है, तब भी आप चारों ओर सरक सकते हैं क्योंकि अनुवाद वेक्टर का वाई-मूल्य शून्य पर सेट किया जा रहा है, जब तक कि आप हिलना बंद नहीं करते हैं और जमीन पर गिर जाते हैं (गति केवल चलते समय सेट होती है)। तो इसे हल करने के लिए, मैं दुनिया के 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 को खोजा है, और केवल एक उदाहरण खोजना कठिन है। एक उदाहरण वास्तव में मेरी ज़रूरत है।

या शायद कठोर शरीर को जमीन पर रखने के लिए बुलेट में कुछ विधि है?

मैं एक रेंडरिंग इंजन के रूप में Ogre3D का उपयोग कर रहा हूं, और एक किरण नीचे डालना उसके साथ काफी सीधा है, हालांकि मैं सादगी के लिए बुलेट के भीतर सभी किरण कास्टिंग रखना चाहता हूं।

क्या कोई मुझे सही दिशा में रास्ता दिखा सकता है? धन्यवाद।

जवाबों:


10

यह पता चला है कि समाधान मूल प्रयास की तुलना में बहुत सरल है, और यदि आपको सिर्फ एक किरण टक्कर का परीक्षण करना है, तो उपवर्ग की कोई आवश्यकता नहीं है।

यहाँ आप सभी को टक्कर वेक्टर को पुनः प्राप्त करने के लिए करना होगा:

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());
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.