मैं बुलेट भौतिकी / Ogre3D के साथ आरपीजी में एक चरित्र को कैसे स्थानांतरित करूंगा?


9

हाल ही में मुझे अपने Ogre3D गेम में अपने चरित्र को आगे बढ़ाने में समस्या हो रही है। मूल रूप से मैं बुलेट के RigidBody->translate()फ़ंक्शन के साथ चरित्र को आगे बढ़ा रहा हूं , लेकिन ऐसा करते समय और एक दीवार में टकराते हुए, मैं इसके माध्यम से थोड़ा सा जाता हूं और फिर वापस बाउंस हो जाता हूं। मैं सोच रहा हूं कि क्या दीवारों के साथ एक साधारण प्लेन-प्रकार की दुनिया में मेरे चरित्र को स्थानांतरित करने का एक और अच्छा तरीका है (जो एक गोलाकार टक्कर का आकार है)?

मैं जिन पुस्तकालयों का उपयोग कर रहा हूं, वे 'ओग्रे 3 डी' और 'बुलेट फिजिक्स' के सापेक्ष हैं।

जवाबों:


9

हालाँकि मैंने विशेष रूप से बुलेट फ़िज़िक्स इंजन के साथ काम नहीं किया है, लेकिन मैंने दूसरे फ़िज़िक्स इंजन में कुछ ऐसा ही किया है। जिस तरह से मैंने इसे हल किया वह सीधे अनुवाद करने के बजाय कठोर शरीर के रैखिक वेग को निर्धारित करना था। आंदोलन और टकराव तब स्वचालित रूप से भौतिकी इंजन अपडेट चरण द्वारा नियंत्रित किए गए थे।

प्रलेखन से एक ऐसी btRigidBody::setLinearVelocityविधि प्रतीत होती है जिसका आप उपयोग कर सकते हैं। उदाहरण के लिए, यदि आप कोई त्वरण नहीं चाहते हैं, तो जब भी चरित्र चल रहा हो, तो रैखिक वेग को एक उचित मान पर सेट करें, और इसे वापस (0,0,0) पर सेट करें जब चरित्र को रोकना है (यानी जब खिलाड़ी कुंजी जारी करता है)।

जिन मूल्यों का उपयोग करने के लिए, सामान्य दृष्टिकोण आपके चरित्र की वांछित गति (एक फ्लोट / स्केलर के रूप में) के साथ शुरू करना होगा और फिर इसे एक सामान्यीकृत वेक्टर द्वारा गुणा करना होगा जो उस दिशा में इंगित कर रहा है जिसे आप स्थानांतरित करना चाहते हैं। मैं क्या देख सकता हूँ btVector3कक्षा में पहले से ही इस सब के लिए तरीके हैं।

वैकल्पिक रूप से, आप वर्ण को पूर्ण भौतिकी वस्तु के रूप में मान सकते हैं, और या तो applyForceया applyImpulseविधियों का उपयोग करके आंदोलन को संभाल सकते हैं । इनसे शरीर में तेजी आएगी, इसलिए आपके पात्रों में गति आएगी और परिणाम संभवत: इस तरह से अच्छे लगेंगे। लेकिन, उदाहरण के लिए, यह सुनिश्चित करने के लिए आपको कुछ अतिरिक्त उपाय करने की आवश्यकता है, रैखिक वेग कभी भी एक निश्चित सीमा से अधिक नहीं होता है, या तो इसे क्लैंप करके या भिगोना / घर्षण के साथ खेलता है। इसलिए इसे लागू करना और परिमित होना थोड़ा कठिन होगा।

दोनों दृष्टिकोणों के साथ प्रयोग करें और फिर अपनी आवश्यकताओं के निकटतम व्यवहार का चयन करें।


ठीक है, त्वरित उत्तर के लिए धन्यवाद, Im अभी इसे बाहर की कोशिश करने जा रहा हूं।
मोलमासेपिक

LinearVelocity चाल एक आकर्षण की तरह एक उम्मीद के रूप में काम किया! कुछ किन्क्स थे जिन्हें मुझे ठीक करना था लेकिन इसके काम करने का 100% उत्तर के लिए बहुत बहुत धन्यवाद!
मोलमासेपिक

9

रिकॉर्ड के लिए, भौतिकी के साथ मेरा अनुभव एक 2 डी गेम इंजन में चिंपंक का उपयोग कर रहा है, लेकिन मुझे पूरा यकीन है कि यह अवधारणा 3 डी में ठीक अनुवाद है।

मैं मान रहा हूं कि आपका चरित्र वजन और इस तरह का एक भौतिकीय शरीर है। ऐसा करने का सबसे अच्छा तरीका है कि चलने का एक बहुत ही सरल अनुकरण करना। इसे इस तरह समझें: यदि आप खड़े हैं, तो आपके पैरों में बहुत घर्षण है, इसलिए आप बस इधर-उधर नहीं भागते। जब आपकी चलती है, तो यह लगभग उस घर्षण को दूर करने के बराबर है (क्योंकि आप अपने पैरों से आंदोलन का विरोध नहीं कर रहे हैं) और एक दिशा बल लागू कर रहे हैं। मैं यह नहीं कह रहा हूं कि आपको व्यक्तिगत रूप से जमीन पर धकेलने वाले प्रत्येक पैर का अनुकरण करना चाहिए - एक कठोर शरीर वह है जो आप चाहते हैं।

  • जब आपका चरित्र सक्रिय रूप से हिलने-डुलने की कोशिश नहीं कर रहा है, तो उनके वेग को अधिक ऊँचा कर दें ताकि वे स्थिर रहें।
  • जब आपका चरित्र घूम रहा हो, तो उनके वेग को कम कर दें और गति की दिशा में एक बल लगा दें। अपने भिगोना और बल को सेट करें ताकि चरित्र एक उचित गति से आगे बढ़े।
  • यदि चरित्र हवा में है, तो भिगोना बहुत कम सेट करें। यदि आप यथार्थवादी होना चाहते हैं, तो उन्हें हवा में रहते हुए अपनी दिशा बदलने के लिए किसी भी बल को लागू करने की अनुमति न दें। आप यहां एक खुशहाल माध्यम पर हमला कर सकते हैं, जिससे उन्हें बहुत छोटे बल लगाने की अनुमति मिलती है, जिससे उन्हें हवाई यात्रा करते समय अपने प्रक्षेपवक्र को समायोजित करने की कुछ सीमित क्षमता मिलती है।

यहाँ है जहाँ एक छोटे से जटिल हो जाता है:

  • यदि चरित्र पहले से ही चल रहा है और वे दिशा बदलते हैं, तो आपको उस गति को समायोजित करने की आवश्यकता होगी जिसमें आप बल लागू करते हैं। उदाहरण के लिए, यदि आपका चरित्र उत्तर की ओर बढ़ रहा है और पूर्व की ओर मुड़ता है, तो आपको अपने बल को उस दिशा में लागू करने की आवश्यकता है जो चरित्र की वर्तमान दिशा की यात्रा के विपरीत दिशा और उनकी यात्रा की इच्छित दिशा के बीच का आधा रास्ता है। जैसे-जैसे यात्रा की दिशा बदलती है, बल को समायोजित करें ताकि दोनों के बीच हमेशा आधा रास्ता रहे, और आपका चरित्र जल्दी और आसानी से दिशा बदल देगा।

यदि आप अपने बल को धुनते हैं और सही ढंग से डंप करते हैं, तो बल लागू करने से आपको हमेशा सबसे यथार्थवादी परिणाम मिलेगा, खासकर अगर चरित्र चारों ओर धकेलने वाला है। अनुवाद करना सबसे बुरा तरीका है, क्योंकि भौतिकी इंजन वास्तव में इस बात पर विचार नहीं करता है कि यह आंदोलन है। वेग को सीधे सेट करना कुछ हद तक बेहतर है, लेकिन मेरे अनुभव में बल और भिगोना का उपयोग करके सर्वोत्तम परिणाम प्राप्त किए जा सकते हैं।

उम्मीद है कि मैंने इसे अच्छी तरह समझाया। यदि आपको स्पष्टीकरण की आवश्यकता है तो बेझिझक पूछें। :)


0

2.87 बुलेट के लिए यह उचित विधि प्रतीत होता है कि एक टिक कॉलबैक है जो आंतरिक सिमुलेशन अद्यतन दर (संभवत: 100 हर्ट्ज) के कई अपडेट करता है, और कीनेमेटिक निकायों पर सेटवर्ल्डट्रांसफॉर्म () आसानी से स्थिति को अपडेट करेगा:

यह हिस्सा मैनुअल में है:

// set the rigid body as kinematic
rigid_body->setCollisionFlags(
    rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
rigid_body->setActivationState(DISABLE_DEACTIVATION);
...

इस भाग को पता लगाने के लिए अधिक मुश्किल था:

void externalTickCallback(btDynamicsWorld *world, btScalar timeStep)
{
  // get object passed into user data point
  Foo* foo = static_cast<Foo*>(world->getWorldUserInfo());
  ... loop through all the rigid bodies, maybe foo has them
  {
    if (rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT)
    {
      btVector3 kinematic_linear_vel = ... // get velocity from somewhere
      btTransform trans;
      rigid_body->getMotionState()->getWorldTransform(trans);
      trans.setOrigin(trans.getOrigin() + kinematic_linear_vel * time_step);
      // TODO support angular velocity
      rigid_body_->getMotionState()->setWorldTransform(trans);
    }
  }
}
...
my_dynamics_world->setInternalTickCallback(tickCallback, static_cast<void*>(this), true);

यह btRigidBody.h https://github.com/bulletphysics/bullet3/blob/master/src/BulletDynamics/Dynamics/btRigidBody.h में सहायक दस्तावेज था :

/// - सी) कैनेमैटिक ऑब्जेक्ट, जो बिना द्रव्यमान के ऑब्जेक्ट हैं, लेकिन उपयोगकर्ता उन्हें स्थानांतरित कर सकता है। एक तरफ़ा बातचीत होती है, और बुलेट टाइमस्टेप और पिछले और वर्तमान विश्व परिवर्तन के आधार पर एक वेग की गणना करता है।

setLearearVelocity () गतिज वस्तुओं के लिए काम नहीं करता है (शायद यह पहले के संस्करणों में इस्तेमाल किया गया था?)। लेकिन डायनामिक्स की दुनिया सेटवर्ल्ड ट्रांसफॉर्मर () को समझेगी और कीनेमेटिक ऑब्जेक्ट पर getLinearVelocity () को कॉल टिकबैक में सेट किए गए वेग को वापस कर देगी (यह संभवत: एक औसत देता है यदि उन वेगों को आंतरिक टिक से टिक में बदलने के लिए था)।

https://github.com/bulletphysics/bullet3/issues/1204 - समस्या पोस्टर में सही विचार है, लेकिन प्रतिक्रिया सहायक नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.