मैं एक quaternion आधारित कैमरा कैसे लागू करूं?


14

अद्यतन यहाँ त्रुटि एक बहुत आसान था। मैंने एक रेडियन को डिग्री रूपांतरण में याद किया है। अगर आपको कोई और समस्या है तो पूरी बात पढ़ने की ज़रूरत नहीं है।

मैंने इस बारे में कई ट्यूटोरियल देखे और जब मुझे लगा कि मैं समझ गया हूं कि मैंने एक चतुष्कोणीय आधारित कैमरा लागू करने की कोशिश की है। समस्या यह है कि यह सही ढंग से काम नहीं करता है, लगभग घूमने के बाद। 10 डिग्री यह वापस -10 डिग्री तक कूदता है। मुझे नहीं पता कि क्या गलत है। मैं OpenTK का उपयोग कर रहा हूं और इसमें पहले से ही एक चतुष्कोणीय वर्ग है। मैं opengl में एक noob हूँ, मैं यह सिर्फ मनोरंजन के लिए कर रहा हूँ, और वास्तव में quaternions को नहीं समझ रहा हूँ, इसलिए शायद मैं यहाँ कुछ बेवकूफ बना रहा हूँ। यहाँ कुछ कोड दिया गया है: (वास्तव में लगभग सभी कोड को छोड़कर जो एक vbo को लोड और आकर्षित करते हैं (यह एक OpenTK नमूने से लिया गया है जो vbo-s प्रदर्शित करता है)

मैं एक घन को एक vbo में लोड करता हूं और कैमरे के लिए quaternion को इनिशियलाइज़ करता हूं

protected override void OnLoad(EventArgs e) {
    base.OnLoad(e);

    cameraPos = new Vector3(0, 0, 7);
    cameraRot = Quaternion.FromAxisAngle(new Vector3(0,0,-1), 0);

    GL.ClearColor(System.Drawing.Color.MidnightBlue);
    GL.Enable(EnableCap.DepthTest);

    vbo = LoadVBO(CubeVertices, CubeElements);
}

मैं यहां एक परिप्रेक्ष्य प्रक्षेपण लोड करता हूं। यह शुरुआत में लोड होता है और हर बार मैं विंडो का आकार बदल देता हूं।

protected override void OnResize(EventArgs e) {
    base.OnResize(e);

    GL.Viewport(0, 0, Width, Height);

    float aspect_ratio = Width / (float)Height;

    Matrix4 perpective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect_ratio, 1, 64);
    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadMatrix(ref perpective);
}

यहां मुझे अंतिम रोटेशन वैल्यू मिलती है और एक नया क्वाटर्नियन बनाता है जो केवल अंतिम रोटेशन का प्रतिनिधित्व करता है और इसे कैमरा क्वाटरनियन से गुणा करता है। इसके बाद मैंने इसे एक्सिस-एंगल में बदल दिया ताकि ऑपनेंग इसका इस्तेमाल कर सके। (यह है कि मैं इसे कई ऑनलाइन quaternion ट्यूटोरियल से समझा)

protected override void OnRenderFrame(FrameEventArgs e) {
    base.OnRenderFrame(e);

    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    double speed = 1;
    double rx = 0, ry = 0;

    if (Keyboard[Key.A]) {
        ry = -speed * e.Time;
    }

    if (Keyboard[Key.D]) {
        ry = +speed * e.Time;
    }

    if (Keyboard[Key.W]) {
        rx = +speed * e.Time;
    }

    if (Keyboard[Key.S]) {
        rx = -speed * e.Time;
    }

    Quaternion tmpQuat = Quaternion.FromAxisAngle(new Vector3(0,1,0), (float)ry);
    cameraRot = tmpQuat * cameraRot;
    cameraRot.Normalize();

    GL.MatrixMode(MatrixMode.Modelview);
    GL.LoadIdentity();

    Vector3 axis;
    float angle;

    cameraRot.ToAxisAngle(out axis, out angle);
    //////////////////////////////////////////////////////////////////////
    // THIS IS WHAT I DID WRONG: I NEED TO CONVERT FROM RADIANS TO DEGREES
    //////////////////////////////////////////////////////////////////////
    //BEFORE
    //GL.Rotate(angle, axis);
    //AFTER
    GL.Rotate(angle * (float)180.0/(float)Math.PI, axis);
    GL.Translate(-cameraPos);

    Draw(vbo);
    SwapBuffers();
}

बेहतर ढंग से समझाने के लिए यहां 2 चित्र दिए गए हैं: मैं थोड़ी देर घुमाता हूं और इससे:

इस

यह इस में कूदता है

यहाँ छवि विवरण दर्ज करें

किसी भी मदद की सराहना की है।

Update1 : मैं इन्हें एक फाइल में लिखने वाले स्ट्रीमराइटर में जोड़ता हूं:

    sw.WriteLine("camerarot: X:{0} Y:{1} Z:{2} W:{3} L:{4}", cameraRot.X, cameraRot.Y, cameraRot.Z, cameraRot.W, cameraRot.Length);
    sw.WriteLine("ry: {0}", ry);

लॉग यहां उपलब्ध है: http://www.pasteall.org/26133/text । 770 के दशक में क्यूब दाईं से बाईं ओर उछलता है, जब कैमराट्रॉट। मैं संकेत बदलता है। मुझे नहीं पता कि क्या यह सामान्य है।

Update2 यहाँ पूरी परियोजना है।


2
मैं समस्या को नहीं समझता। क्या आपने उन बटेरों को छापने की कोशिश की है जिनका आप उपयोग कर रहे हैं?
निकोल बोलस

1
सहमत, अपने rx, ry और Quaternion मूल्यों को डीबग करें।
deceleratedcaviar

आप अपना पूरा प्रोजेक्ट कहीं रैपडेसरे पर क्यों नहीं अपलोड करते? आसान हो जाएगा।
बॉबोबोबो

ठीक है मैं इसे घर ले जाने पर अपलोड कर दूंगा।
ज्योजो कुदोर

जवाबों:


9

जब आपने यहां मेरी धारणा को सत्यापित करने के लिए आवश्यक कोड नहीं दिखाया है, तो मैं लगभग गारंटी दे सकता हूं कि आपकी समस्या वास्तव में यही है:

cameraRot.ToAxisAngle(out axis, out angle);

रेडियन में व्यक्त कोण मान लौटा रहा है , जबकि

GL.Rotate(angle, axis);

कोण को डिग्री में प्रदान करना चाहता है ।

इसे ठीक करने के लिए, आपको इस तरह से GL.Rotate () को पास करते समय कोण मान को बदलना होगा:

GL.Rotate(angle * 180.0/3.141593, axis);

हां, यही समस्या थी। :) बहुत बहुत धन्यवाद। मुझे पता था कि opengl डिग्री की अपेक्षा करता है, मैंने मान लिया कि ToAxisAngle की डिग्री है। मैंने सिर्फ ओपेकेंट कोड को देखा और यह रेडियन है। BTW मैंने अंत में पूर्ण स्रोत कोड प्रदान किया है।
ज्योजो कुदोर

@NickCaplinger सही ढंग से इंगित करता है कि C # में, एक Math.Piनिरंतर उपलब्ध है, जिसका उपयोग उस अंतिम गणना में उपयोग किए गए शाब्दिक 3.141593 मूल्य को वरीयता देने के लिए किया जाना चाहिए।
ट्रेवर पॉवेल

1

मत करो। ऐसा प्रतीत हो सकता है कि एक कैमरा होना कम काम होगा जो अन्य दृश्य वस्तुओं की तरह हेरफेर किया जा सकता है, लेकिन लंबे समय में एक कैमरा होना बेहतर है जहां आप एक स्थिति, आंख की दिशा और अप वेक्टर को परिभाषित कर सकते हैं। विशेष रूप से जब आप प्रोग्रामिंग गति मॉडल शुरू करते हैं तो यह वास्तव में क्वाटर्न्स के साथ काम करने के लिए एक दर्द है।


1
माना। मैं "अगर यह उच्चारण करना कठिन है तो बेहतर होगा" का एक प्रशंसक नहीं हूं, मेरे अनुप्रयोगों को डिजाइन करने की विधि भी =)
पैट्रिक ह्यूजेस

Quaternion उच्चारण करने में कठिन है?
नॉटलेश

1
थोड़ा हास्य एक लंबा रास्ता तय करता है = डी अनुमान के अनुसार, मैं किसी ऐसे व्यक्ति से सवाल करता हूं जिसे कोई पता नहीं है कि वह एक विचित्र कैमरा क्यों चाहता है, बस यह एक नीरस चर्चा है और ओएमजी मैं चाहता हूं कि यह अब बुरा हो! यह निश्चित रूप से निपटने के लिए एक विषय नहीं है जब ऊपर टूटे हुए कोड में रेडियन और डिग्री मापदंडों को ठीक से संभालने जैसे कुछ भी ठीक से निपटा नहीं है।
पैट्रिक ह्यूजेस

3
यह सवाल वास्तव में कैमरों के बारे में नहीं है; यह गेम कोड में घुमावों का प्रतिनिधित्व करने के तरीके के बारे में है, और उन खेल अभ्यावेदन को ऐसे रूप में कैसे परिवर्तित किया जाए कि ओपनजीएल उनका उपयोग कर सके। यह पूरी तरह से वैध सवाल है, और मुझे नहीं लगता कि ओपी की डोमेन अनुभव की कमी किसी भी तरह से मददगार है। ऐसा नहीं है कि ओपी ने एक बेवकूफ गलती की है; कोणों को व्यक्त करते समय डिग्री का उपयोग करने पर ओपेनग्ल का आग्रह सर्वथा विचित्र है। हर कोई इस गलती को पहली बार OpenGL का उपयोग करके करता है। तो अपने ऊँचे घोड़ों, लोगों को निकालो। गीज़।
ट्रेवर पॉवेल

मैं सिर्फ यह समझना चाहता था कि एक चतुर्भुज आधारित कैमरा कैसे काम करता है और मैंने यह प्रोजेक्ट एक दिन में बनाया जब मेरे पास करने के लिए और कुछ नहीं था। मेरी इसके साथ कोई वास्तविक योजना नहीं है।
ज्योजो कुदोर

0

OpenTK इंटर्नल के बारे में ज्यादा जानकारी नहीं है। अपने अनुभव में मैंने क्वैट के उचित कार्यान्वयन के साथ गणित की लाइब्रेरी नहीं देखी जो सटीक (मशीन) आवश्यक है, क्योंकि उनमें से सभी e ^ 2-e ^ 3 त्रुटियों को प्रभावित करते हैं। तो आप जो प्रभाव देखते हैं: परिशुद्धता (और एप्सिलॉन मान) लगभग 10 ^ -5 है, और यह शून्य के पास 'कूदता है'। यह मेरा अनुमान है :)

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