5

का उपयोग करके 6 डीओएफ कैमरा में 'रोल' को लागू करने में समस्याएं मैंने इस मुद्दे पर कुछ सप्ताह बिताए हैं और उचित समाधान नहीं ढूंढ रहे हैं और कुछ सलाह चाहिए।एलडब्ल्यूजेजीएल - क्वाटरनियंस और अनुवाद मैट्रिक्स

मैं एलडब्ल्यूजेजीएल/जावा का उपयोग कर कैमरा कक्षा बनाने पर काम कर रहा हूं, और असर (यो), पिच और रोल रोटेशन को संभालने के लिए क्वाटरनियंस का उपयोग कर रहा हूं। मैं इस कैमरे को 3 डी स्पेस, और रोल में सभी 6 डिग्री आंदोलन को संभालने के लिए चाहता हूं। असर, पिच और रोल सभी quaternions हैं। मैं उन्हें 'परिवर्तन' quaternion में गुणा करता हूं, और उस से अनुवाद मैट्रिक्स बना देता हूं। मैंने इसे एक फ्लोट बफर में रखा है, और रोटेशन मैट्रिक्स वाले मेरे बफर द्वारा मॉडलव्यू मैट्रिक्स को गुणा करें।

मैं असर और पिच घूर्णन ठीक से काम करने के लिए प्राप्त कर सकता हूं, लेकिन जब मैं रोल लागू करता हूं, तो मैं मुद्दों में भाग ले रहा हूं। मुख्य रूप से, जेड-अक्ष (रोलिंग) के चारों ओर घुमावदार काम नहीं कर रहा है। जब भी मैं कैमरे को "रोल" करता हूं, तो यह स्थानीय कैमरा दिशा अक्ष के बजाय वैश्विक जेड अक्ष के चारों ओर घूमता प्रतीत होता है। मैं आमतौर पर quaternions गुणा करने के क्रम के आधार पर काम करने के लिए 3 में से 2 प्राप्त कर सकते हैं, लेकिन मैं उन्हें एक साथ काम नहीं कर सकता।

चूंकि वे सभी स्वतंत्र रूप से काम करते हैं, इसलिए मुझे लगता है कि मेरी ओरिएंटेशन विधि में कुछ गड़बड़ है जहां मैं उन्हें जोड़ता हूं और एक रोटेशन मैट्रिक्स बनाता हूं। मैं समस्याओं में पूरी कक्षा चिपकाने आ रही है, इसलिए यहाँ के तरीकों और घोषणाओं रोटेशन से संबंधित हैं:

private final static float DEGTORAD = (float)(Math.PI/180);  

//Eye - position of the camera in the 3D world. 
private Vector3f eye; 

//Camera axis vectors, calculated each time reorient() is called. 
//Initialized to global x, y, and z axis initially. 
private Vector3f up; 
private Vector3f right; 
private Vector3f direction; 

//Angles of rotation (in degrees)  
private float pitchAngle; 
private float bearingAngle; 
private float rollAngle; 

private Quaternion pitch; 
private Quaternion bearing; 
private Quaternion roll; 

private FloatBuffer viewMatrixBuffer = BufferUtils.createFloatBuffer(16); 
private Quaternion currentOrientation; 

...

/** 
* Change the bearing (yaw) 
* @param bearing delta in degrees 
*/ 
public void bearing(float bearingDelta){ 
    bearingAngle += bearingDelta; 
    if(bearingAngle > 360){ 
     bearingAngle -= 360; 
    }else if(bearingAngle < 0){ 
     bearingAngle += 360; 
    } 
    bearing.setFromAxisAngle(new Vector4f(0f, 1f, 0f, bearingAngle * DEGTORAD)); 
    bearing.normalise(); 
} 

/** 
* Change the pitch 
* @param pitch delta in degrees 
*/ 
public void pitch(float pitchDelta){ 
    pitchAngle += pitchDelta; 
    if(pitchAngle > 360){ 
     pitchAngle -= 360; 
    }else if(pitchAngle < 0){ 
     pitchAngle += 360; 
    } 
    pitch.setFromAxisAngle(new Vector4f(1f, 0f, 0f, pitchAngle * DEGTORAD)); 
    pitch.normalise(); 
} 

/** 
* @param initialRoll 
*/ 
public void roll(float initialRoll) { 
    rollAngle += initialRoll; 
    if(rollAngle > 360){ 
     rollAngle -= 360; 
    }else if(rollAngle < 0){ 
     rollAngle += 360; 
    } 
    roll.setFromAxisAngle(new Vector4f(0, 0, 1, rollAngle * DEGTORAD)); 
    roll.normalise(); 
} 

/** 
* Change direction to focus on a certain point in the world 
* @param eye 
*/ 
public void lookThrough(){ 
    reorient(); 
    GL11.glMultMatrix(viewMatrixBuffer); 
}  

public void reorient(){ 
    //Multiply in order: bearing, pitch, roll. Non-commutative! 
    Quaternion change = new Quaternion(); 
    Quaternion.mul(bearing, pitch, change); 
    Quaternion.mul(roll, change, change); 
    // orient the camera... 
    Matrix4f rotationMatrix = getRotationMatrix(change); 

    //Get the looking direction 
    direction.x = rotationMatrix.m20; 
    direction.y = rotationMatrix.m21; 
    direction.z = rotationMatrix.m22; 

    //Set the position 
    rotationMatrix.m30 = eye.x; 
    rotationMatrix.m31 = eye.y; 
    rotationMatrix.m32 = eye.z; 
    rotationMatrix.m33 = 1; 

    rotationMatrix.invert(); 
    rotationMatrix.store(viewMatrixBuffer); 

    viewMatrixBuffer.rewind(); 

    Vector3f.cross(new Vector3f(0,1,0), direction, null).normalise(right); 
    Vector3f.cross(right, direction, null).normalise(up);    
} 

Vector3f, Quaternion, और Matrix4f सभी LWJGL वर्ग हैं, कस्टम नहीं बनाया गया।

तो मेरा सवाल है, असर, पिच और रोल का प्रतिनिधित्व करने वाले 3 क्वाटरनियंस दिए गए हैं, मैं इन रोटेशन का सटीक रूप से प्रतिनिधित्व करने के लिए मॉडल व्यू मैट्रिक्स को कैसे संशोधित करूं?

संपादित करें: मुझे लगता है कि यह बहुत करीब है। RiverC की टिप्पणी में गिस्ट लिंक देखें। इतनी सारी डिग्री घूर्णन करने के बाद, रोलिंग के दौरान सामान्य पर वापस आने से पहले दृश्य बहुत करीब कूदता है। इसका सारांश वहां है, लेकिन यह अभी भी थोड़ा दूर है।

उत्तर

3

आप गलत क्रम में गुणा कर रहे हैं।

दो रोटेशन q1 और q2 के लिए, यदि q2 q1 का पालन करना है (चूंकि घूर्णन आम तौर पर गैर-संवादात्मक होते हैं) तो आप q2 * q1 गुणा करते हैं।

एफपीएस के लिए नियंत्रण जैसे जिम्बल स्टाइल सिस्टम में, प्राथमिकता आदेश हमेशा yaw, पिच, रोल होता है। यह निम्न गणित सुझाव है:

roll * pitch * yaw 

एक जावा बिंदु के रूप में, मैं होगा हर अद्यतन के लिए नए Quaternions बनाने नहीं करने का सुझाव देते हैं, लेकिन वैसे भी

change = Quaternion.mul(Quaternion.mul(roll, pitch, change), yaw, change); 

आप कोड को देखो, तो तीसरे Quaternion सिर्फ होगा परिणाम के साथ ओवरराइट किया जाना चाहिए, इसलिए इसे रीसेट करने या प्रत्येक फ्रेम/अपडेट को फिर से बनाने की आवश्यकता नहीं है।

यह घूर्णन आदेश वस्तु उलझन में है, लेकिन यदि आप Quaternions पर विकी पेज देखते हैं, तो यह सामान्य नियम है।

+0

अद्यतन के लिए धन्यवाद। थोड़ी देर में इस कोड को छुआ नहीं है, इसलिए मैं एलडब्ल्यूजेजीएल के साथ गति के लिए बैक अप ले रहा हूं। मुझे लगता है कि मैं करीब हूँ। Gsimard द्वारा सुझाए गए परिवर्तन और परिवर्तन करने के बाद, मैं करीब आ रहा हूं। हालांकि, जब जबड़े (प्रश्न में असर) 0 पर है, पिच ठीक है। जब yaw 180 पर होता है, पिच उलट जाता है (पिच ऊपर कैमरे को नीचे ले जाता है)। इसके अलावा, घूर्णन लगभग 20 डिग्री घूर्णन के बाद sporadic हो जाता है। अगर मैं इसे स्तरों को घूर्णन करता रहता हूं। तो कुछ अभी भी सही नहीं है। मैं कोड को जिथब पर रखूंगा और बाद में इस सवाल को आज रात अपडेट कर दूंगा। मुझे लगता है कि यह लगभग वहाँ है। एक बार फिर धन्यवाद। – framauro13

+0

इसे बनाने के बाद आप रोटेशन मैट्रिक्स में सामान क्यों करते हैं? आपको सीधे शेडर को एक Mat4 भेजने में सक्षम होना चाहिए और इसे संशोधित किए बिना दृश्य के शिखर को गुणा करने के लिए इसका उपयोग करना चाहिए। मेरा मतलब है, कोड के '// सेट दिशा' भाग। ऐसा लगता है कि आप गुणा के माध्यम से कैमरे को ऑफसेट करने के लिए इसका उपयोग करने की कोशिश कर रहे हैं, लेकिन मेरे अनुभव में यह हिट और मिस गया है। इसे छोड़ने का प्रयास करें। –

+0

मैं * सोचता हूं * शुरूआती कारण मैंने ऐसा किया था ताकि मैं आंख वेक्टर के साथ दिशा वेक्टर को दुनिया में वस्तुओं के साथ बातचीत करने के लिए वेक्टर उत्पन्न कर सकूं। एक 'पिकिंग' वेक्टर कम या ज्यादा। इसके अलावा, मैंने पिच फ़्लिपिंग के साथ इस मुद्दे को ठीक किया। मैंने असर और पिच के आदेश को बदल दिया, इसलिए लाइन 'Quaternion.mul (Quaternion.mul (रोल, असर, परिवर्तन), पिच, परिवर्तन) पढ़ती है; ' अभी भी यह पता लगाने की कोशिश कर रहा है कि एक निश्चित रोलिंग के बाद रोल क्यों जीत गया रकम। – framauro13

3

मुझे पता है कि यह पुराना है, लेकिन मुझे वैसे भी अनुमान लगाने की अनुमति दें। समस्या यह है कि आपने स्वयं क्या कहा:

जब भी मैं कैमरे को "रोल" करता हूं, तो यह स्थानीय कैमरा दिशा धुरी के बजाय वैश्विक जेड अक्ष के आसपास रोल लगता है।

ऐसा इसलिए होता है क्योंकि आपने इसे वेक्टर (0,0,1), यानी वैश्विक जेड अक्ष के चारों ओर रोल करने के लिए कहा था।

यह यूनिट quaternions क्या करता है: वे डब्ल्यू स्केलर के कुछ कोण समारोह द्वारा उनके काल्पनिक वेक्टरियल भाग (एक्स, वाई, जेड) द्वारा निर्दिष्ट अक्ष के चारों ओर एक वेक्टर (यहां वेक्टरों का एक सेट, अपने रोटेशन मैट्रिक्स) घुमाते हैं (डब्ल्यू = कॉस (कोण/2))।

roll.setFromAxisAngle(new Vector4f(direction.x, direction.y, direction.z, rollAngle * DEGTORAD)); 

मैं:

तो मैं समझता हूँ कि आप यह है कि जब बाएं से दाएं अपने सिर झुकाव के रूप में अपने कैमरे चल रहा है करने के लिए कोशिश कर रहे हैं, तो आप अपने दिशा वेक्टर के चारों ओर एक रोल चार का समुदाय बनाने चाहिए मुझे लगता है कि आपकी दिशा वेक्टर सामान्यीकृत है, या एलडब्ल्यूजेजीएल जानता है कि setFromAxisAngle पर कॉल करते समय गैर-एकता अक्ष अक्ष वेक्टर के साथ क्या करना है।

+0

अद्यतन के लिए धन्यवाद। मैंने यह परिवर्तन किया और यह करीब है, हालांकि मुझे अभी भी कुछ अजीब व्यवहार मिल रहा है। मैंने RiverC द्वारा सुझाए गए एक के साथ यह परिवर्तन किया, और वहां एक टिप्पणी में नई समस्याओं की व्याख्या की। जब मैं आज रात घर लौटता हूं तो मैं अपडेट करूंगा। फिर से धन्यवाद, मैं मदद की सराहना करता हूं। – framauro13

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