2009-07-02 5 views
5

पर iphon ई स्क्रीन करने के लिए दुनिया समस्या
ओपनगलएस में स्क्रीन-टू-वर्ल्ड समन्वय रूपांतरण एक आसान काम है?

मैं एक 3D मॉडल (घन) एक EAGLView में प्रदान की गई है और मैं पता लगाने के लिए जब मैं किसी दिए गए चेहरे के केंद्र को छू रहा सक्षम होना चाहते हैं (किसी भी अभिविन्यास कोण से) घन के। ध्वनि बहुत आसान है, लेकिन यह नहीं है ...

समस्या:
मैं कैसे सही ढंग से (ओपन 3 डी अंतरिक्ष में एक स्थान) विश्व निर्देशांक करने के लिए स्क्रीन-निर्देशांक (स्पर्श बिंदु) संबंधित हैं? निश्चित रूप से, किसी दिए गए बिंदु को स्क्रीन/विश्व-अक्ष के 'प्रतिशत' में परिवर्तित करना तार्किक फिक्स प्रतीत हो सकता है, लेकिन जब मुझे 3 डी स्पेस ज़ूम या घुमाने की आवश्यकता होती है तो समस्याएं उत्पन्न होती हैं। नोट: & घूर्णन 3 डी स्पेस में ज़ूम इन और 3 डी वर्ल्ड कॉर्ड के साथ 2 डी स्क्रीन कॉर्ड के रिश्ते को बदल देगा ... इसके अलावा, आपको 3 डी स्पेस में दृष्टिकोण और ऑब्जेक्ट्स के बीच 'दूरी' की अनुमति देनी होगी । सबसे पहले, यह एक 'आसान कार्य' जैसा प्रतीत हो सकता है, लेकिन जब आप वास्तव में आवश्यकताओं की जांच करते हैं तो वह बदल जाता है। और मुझे आईफोन पर ऐसा करने वाले लोगों का कोई उदाहरण नहीं मिला है। यह सामान्य रूप से कैसे किया जाता है?

जब वे आसान काम ?:
ज़रूर, एक गो-बीच स्क्रीन और दुनिया के बीच के रूप में कार्य करने के लिए एक एपीआई लिखने के कार्य हो सकता है, लेकिन इस तरह के एक रूपरेखा बनाने का कार्य कुछ गंभीर की आवश्यकता होगी डिजाइन और संभवतः 'समय' करने के लिए ले जाएगा - कुछ ऐसा नहीं जो 4-घंटे में एक-मानव हो सकता है ... और 4 घंटे मेरी समयसीमा होती है।

प्रश्न:

  • क्या को सरल तरीके से कुछ अगर मैं iPhone OpenGL ES दुनिया में 3 डी अंतरिक्ष में विशिष्ट स्थानों छुआ पता कर रहे हैं?
+0

AFAIK यह एक छोटी समस्या नहीं है जब तक कि आपने इसे हल नहीं किया है या जब तक कि आपके पर्यावरण में पहले से ही समर्थन नहीं है (जो मामला प्रतीत नहीं होता है)। मुझे पता है कि यह इससे आसान दिखता है, हमने अपने सहयोगियों के साथ भी यही चर्चा की है। – zoul

उत्तर

1

दो समाधान स्वयं उपस्थित होते हैं। उनमें से दोनों को अलग-अलग साधनों के बावजूद अंतिम लक्ष्य प्राप्त करना चाहिए: "दुनिया के समन्वय माउस के नीचे क्या है?" का जवाब देने के बजाय, वे सवाल करते हैं कि "माउस के नीचे क्या वस्तु प्रदान की जाती है?"।

एक आपके मॉडल का सरलीकृत संस्करण ऑफ-स्क्रीन बफर में खींचना है, प्रत्येक चेहरे का केंद्र एक अलग रंग का उपयोग करके प्रतिपादित करना है (और प्रकाश को समायोजित करना इतना रंग संरक्षित है)। फिर आप उन रंगों को बफर (उदा। पिक्समैप) में पहचान सकते हैं, और उन्हें माउस स्थान मानचित्र कर सकते हैं।

दूसरा ओपनजीएल पिकिंग का उपयोग करना है। एक सभ्य दिखने वाला ट्यूटोरियल here है।मूलभूत विचार ओपनजीएल को चुनिंदा मोड में रखना है, व्यू के बिंदु के आस-पास व्यूपोर्ट को एक छोटी (शायद 3x3 या 5x5) विंडो पर प्रतिबंधित करें, और उसके बाद ओपनजीएल "नाम" (पूर्णांक) का उपयोग करके दृश्य (या इसका सरलीकृत संस्करण) प्रस्तुत करें पहचानकर्ता) प्रत्येक चेहरे को बनाने वाले घटकों की पहचान करने के लिए। इस प्रक्रिया के अंत में, ओपनजीएल आपको उन नामों की एक सूची दे सकता है जो चयन व्यूपोर्ट में प्रस्तुत किए गए थे। इन पहचानकर्ताओं को वापस मूल ऑब्जेक्ट्स पर मैप करने से आपको यह निर्धारित करने दिया जाएगा कि माउस कर्सर के नीचे कौन सी वस्तु है।

+1

आईफोन के लिए बस एक नोट: ओपन जीएल ईएस 1.1 में कोई ओपनजीएल पिकिंग नहीं है, इसलिए आप भाग्य से बाहर हैं। – jv42

0

गूगल opengl screen to world के लिए (उदाहरण के लिए वहाँ एक धागा जहां किसी को वास्तव में क्या आप GameDev.net पर तलाश कर रहे हैं क्या करना चाहता है)। एक gluUnProject फ़ंक्शन है जो ठीक से करता है, लेकिन यह आईफोन पर उपलब्ध नहीं है, ताकि आपको इसे पोर्ट करना होगा (मेसा प्रोजेक्ट से this source देखें)। या हो सकता है कि पहले से ही कुछ सार्वजनिक रूप से उपलब्ध स्रोत पहले से ही हो?

+0

ईजीएलवी व्यू में 3 डी मॉडलों पर क्षेत्रों के साथ छूने वाला यह जटिल है? इस विषय पर थोड़ा सा कवरेज प्रतीत होता है .. आपके द्वारा प्रदान किया गया लिंक वास्तव में मुझे एक्सकोड में प्राप्त करने के लिए कोई संकेत नहीं प्रदान करता है। हालांकि, उत्तर के लिए धन्यवाद। – RexOnRoids

+0

मुझे लगता है कि यह वास्तव में जटिल है और यह लिंक आपके प्रश्न का उत्तर देता है, लेकिन चलो प्रतीक्षा करें - शायद कोई बेहतर उत्तर के साथ आएगा। – zoul

+0

ईएजीएलवी व्यू और ओपनजीएल आपके मॉडल ड्राइंग के लिए केवल उपकरण हैं। वे हिट डिटेक्शन या ऐसा कुछ भी नहीं करते हैं। आपको यह करना है। –

2

अपनी 3 डी मॉडल स्पेस में स्क्रीन टच पॉइंट के माध्यम से दर्शक की आंख
से एक रेखा की कल्पना करें।

यदि वह रेखा किसी भी घन के चेहरे को छेड़छाड़ करती है, तो उपयोगकर्ता ने घन को छुआ है।

+0

यह काम करेगा अगर यह 8 शिखर के साथ बस एक साधारण घन था। मेरा वास्तव में 500+ शिखर (शीर्ष पर सिलेंडरों से) के साथ एक 3 डी-लेगो घन है और डेटा स्वचालित रूप से ब्लेंडर निर्यात फ़ाइल से लोड होता है - यानी: मुझे नहीं पता कि मेरे 8 कोनों के रूप में ट्रैक करने के लिए 500+ कोने का कौन सा हिस्सा है और इस प्रकार मेरे चेहरों को ट्रैक नहीं कर सकता। – RexOnRoids

+0

आप अपने लेगो ब्लॉक के लिए बाध्य आयताकार प्रिज्म की गणना/अतिथि क्यों नहीं करते हैं, फिर चौराहे के लिए जांचें। चलते रहें, आप जानते हैं आप ऐसा करना चाहते हैं। –

+0

स्क्रीन पर 2 डी बिंदु वाले स्पर्श के संबंध में एक छेड़छाड़ के लिए मैं एक बाउंडिंग बॉक्स कैसे देखूं? – RexOnRoids

3

आपको ओपनग्ल प्रोजेक्शन और मॉडलव्यू मैट्रिस होना चाहिए। मॉडलव्यू प्रोजेक्शन मैट्रिक्स हासिल करने के लिए उन्हें गुणा करें। इस मैट्रिक्स को एक मैट्रिक्स प्राप्त करने के लिए बदलें जो क्लिप स्पेस निर्देशांक को विश्व निर्देशांक में बदल देता है। अपने स्पर्श बिंदु को बदलें ताकि यह क्लिप निर्देशांक से मेल खाती हो: स्क्रीन का केंद्र शून्य होना चाहिए, जबकि किनारों क्रमशः एक्स और वाई के लिए + 1/-1 होना चाहिए।

दो बिंदुओं का निर्माण, एक (0,0,0) और एक पर (touch_x, touch_y, -1) और इनवर्क्स मॉडलव्यू प्रक्षेपण मैट्रिक्स दोनों को परिवर्तित करें।

परिप्रेक्ष्य विभाजन के विपरीत करें।

आप "अब तक दूरी" (Farplane) में दो अंक कैमरे के केंद्र से एक लाइन का वर्णन मिलना चाहिए।

अपने मॉडल के सरलीकृत बाध्यकारी बक्से के आधार पर चयन करना। आप वेब पर रे/बॉक्स चौराहे एल्गोरिदम को बहुत अधिक ढूंढने में सक्षम होना चाहिए।

एक अन्य समाधान एक गुप्त बफर में एक अलग रंग में प्रत्येक मॉडल के रंग और वहाँ से स्पर्श बिंदु पर रंग पढ़ने के लिए, आपको बता जो Brich छुआ था है।

यहाँ एक कर्सर मैं बुलेट भौतिकी का उपयोग कर एक छोटे से परियोजना के लिए लिखा था के लिए स्रोत है:

float x=((float)mpos.x/screensize.x)*2.0f -1.0f; 
    float y=((float)mpos.y/screensize.y)*-2.0f +1.0f; 
    p2=renderer->camera.unProject(vec4(x,y,1.0f,1)); 
    p2/=p2.w; 
    vec4 pos=activecam.GetView().col_t; 
    p1=pos+(((vec3)p2 - (vec3)pos)/2048.0f * 0.1f); 
    p1.w=1.0f; 

    btCollisionWorld::ClosestRayResultCallback rayCallback(btVector3(p1.x,p1.y,p1.z),btVector3(p2.x,p2.y,p2.z)); 
    game.dynamicsWorld->rayTest(btVector3(p1.x,p1.y,p1.z),btVector3(p2.x,p2.y,p2.z), rayCallback); 
    if (rayCallback.hasHit()) 
    { 
     btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); 
     if(body==game.worldBody) 
     { 
      renderer->setHighlight(0); 
     } 
     else if (body) 
     { 
      Entity* ent=(Entity*)body->getUserPointer(); 

      if(ent) 
      { 
       renderer->setHighlight(dynamic_cast<ModelEntity*>(ent)); 
       //cerr<<"hit "; 
       //cerr<<ent->getName()<<endl; 
      } 
     } 
    } 
7

अब आप http://code.google.com/p/iphone-glu/ में gluUnProject पा सकते हैं। मुझे आईफोन-ग्लू प्रोजेक्ट के साथ कोई सहयोग नहीं है और मैंने अभी तक यह कोशिश नहीं की है, सिर्फ लिंक साझा करना चाहता था।

आप इस तरह के फ़ंक्शन का उपयोग कैसे करेंगे? This PDF कहा गया है कि:

उपयोगिता पुस्तकालय दिनचर्या gluUnProject() प्रदर्शन परिवर्तनों के इस विपरीत प्रतिक्रिया। किसी स्थान के लिए त्रि-आयामी विंडो निर्देशांक और उन सभी परिवर्तनों को देखते हुए जो उन्हें प्रभावित करते हैं, gluUnProject() दुनिया के निर्देशांक को कहां से उत्पन्न करता है।

int gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, 
const GLdouble modelMatrix[16], const GLdouble projMatrix[16], 
const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz); 

मानचित्र वस्तु में निर्दिष्ट खिड़की निर्देशांक (Winx, winy, winz) निर्देशांक, एक modelview मैट्रिक्स (modelMatrix), प्रक्षेपण मैट्रिक्स (projMatrix), और व्यूपोर्ट (व्यूपोर्ट) द्वारा परिभाषित परिवर्तनों का उपयोग कर । परिणामी ऑब्जेक्ट निर्देशांक objx, objy, और objz में वापस आते हैं। फ़ंक्शन GL_TRUE, सफलता का संकेत देता है, या GL_FALSE, विफलता का संकेत देता है (जैसे एक noninvertible मैट्रिक्स)। यह ऑपरेशन व्यूपोर्ट को निर्देशांक क्लिप करने या glDepthRange() के बाहर आने वाले गहराई मानों को खत्म करने का प्रयास नहीं करता है।

परिवर्तन प्रक्रिया को उल्टा करने की कोशिश कर में निहित कठिनाइयों कर रहे हैं।एक त्रि-आयामी स्क्रीन स्थान तीन-आयामी अंतरिक्ष में पूरी लाइन पर कहीं से भी उत्पन्न हो सकता था। परिणाम को असंबद्ध करने के लिए, gluUnProject() की आवश्यकता है कि एक विंडो गहराई समन्वय (winz) प्रदान किया जाए और वह winz gldepthRange() के संदर्भ में निर्दिष्ट किया जाए। GlDepthRange() के डिफ़ॉल्ट मानों के लिए, 0.0 पर winz निकट क्लिपिंग विमान पर रूपांतरित बिंदु के विश्व निर्देशांक का अनुरोध करेगा, जबकि 1.0 पर Winz दूर क्लिपिंग विमान पर बिंदु का अनुरोध करेगा।

उदाहरण 3-8 (फिर से, the PDF देखें) को दर्शाता है gluUnProject() माउस स्थिति पढ़ने और और दूर के पास कतरन विमानों जिसमें से यह बदल गया था पर तीन आयामी अंक का निर्धारण करके। गणना किए गए विश्व निर्देशांक मानक आउटपुट पर मुद्रित होते हैं, लेकिन प्रस्तुत विंडो स्वयं ही काला होती है।

प्रदर्शन के संदर्भ में, I found this quickly via Google जो आप शायद gluUnProject का उपयोग करके नहीं करना चाहते हैं, what might lead to a better alternative के लिंक के साथ। मुझे बिल्कुल पता नहीं है कि आईफोन के लिए यह कितना लागू है, क्योंकि मैं अभी भी ओपनजीएल ईएस के साथ एक नया हूँ। मुझे एक महीने में फिर से पूछो। ;-)

संबंधित मुद्दे