2011-09-29 16 views
11

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

सूत्र मैं अपने meshes skinning के लिए उपयोग कर रहा हूँ सीधी-सपाट है:

weighted; 
for (i = 0; i < joint_influences; i++) 
{ 
    weighted += 
     joint[joint_index[i]]->parent->local_matrix * 
     joint[joint_index[i]]->local_matrix * 
     skin->inverse_bind_pose[joint_index[i]] * 
     position * 
     skin->weight[j]; 
} 
position = weighted; 

और जहाँ तक साहित्य का संबंध है, यह सही तरीका है। अब, कोलाडा जोड़ों के लिए दो प्रकार के घूर्णन निर्दिष्ट करता है: स्थानीय और वैश्विक। संयुक्त के लिए स्थानीय परिवर्तन प्राप्त करने के लिए आपको घूर्णन को एकसाथ जोड़ना होगा।

संयुक्त रूप से स्थानीय घूर्णन और संयुक्त के वैश्विक घूर्णन के बीच कोलाडा दस्तावेज़ क्या अंतर नहीं करता है। लेकिन मैंने देखा है कि अधिकांश मॉडलों में, रोटेशन में rotate (वैश्विक) या jointOrient (स्थानीय) की आईडी हो सकती है।

जब मैं वैश्विक घूर्णन की अवहेलना करता हूं और केवल स्थानीय लोगों का उपयोग करता हूं, तो मुझे मॉडल के लिए बाध्यता मिलती है। लेकिन जब मैं संयुक्त स्थानीय परिवर्तन में वैश्विक घूर्णन जोड़ता हूं, तो अजीब चीजें होने लगती हैं।

यह वैश्विक रोटेशन का उपयोग किए बिना है:

Bind pose

और यह वैश्विक रोटेशन के साथ है:

Weird

दोनों स्क्रीनशॉट मैं कंकाल लाइनों का उपयोग कर ड्राइंग कर रहा हूँ में, लेकिन में सबसे पहले यह अदृश्य है क्योंकि जोड़ जाल के अंदर हैं। दूसरे स्क्रीनशॉट में शिखर सभी जगह पर हैं!

Collada viewer

यह देखना कठिन है, लेकिन आप देख सकते हैं कि जोड़ों दूसरा स्क्रीनशॉट में सही स्थिति में हैं:

तुलना के लिए, यह है कि क्या दूसरा स्क्रीनशॉट की तरह दिखना चाहिए है।

लेकिन अब अजीब बात है। अगर मैं उलटा बाँध उपेक्षा मुद्रा के रूप में कोलाडा द्वारा निर्दिष्ट और इसके बजाय संयुक्त के माता-पिता का प्रतिलोम ले स्थानीय बार संयुक्त के स्थानीय बदलना बदलना, मैं निम्नलिखित हो:

enter image description here

इस स्क्रीनशॉट में मैं एक ड्राइंग कर रहा हूँ प्रत्येक कशेरुक से जोड़ों के लिए जोड़ों के लिए लाइन। तथ्य यह है कि मैं बाँध मिल मुद्रा क्योंकि सूत्र अब हो जाता है, तो अजीब नहीं है:

world_matrix * inverse_world_matrix * position * weight 

लेकिन यह मेरे लिए सुराग पर शक करने के कोलाडा का उलटा बाँध मुद्रा है कि गलत स्थान में है।

तो मेरा सवाल यह है कि: COLLADA किस जगह में इसके विपरीत बाध्य मुद्रा को निर्दिष्ट करता है? और मैं जिस जगह की आवश्यकता है उसमें उलटा बाध्य मुद्रा कैसे बदल सकता हूं?

+0

क्या आपने 1.4.1 spec के "कोलाडा में एक कंकाल स्किनिंग" अनुभाग पढ़ा है? आपका फॉर्मूला – jterrace

उत्तर

10

मैंने अपने मूल्यों को एसिंप (ओपन सोर्स मॉडल लोडर) से पढ़ने वाले लोगों से तुलना करके शुरू किया। कोड के माध्यम से कदम उठाने पर मैंने देखा कि उन्होंने अपनी बाध्य मैट्रिक्स और उनके विपरीत बाइंड मैट्रिस का निर्माण किया था।

अंततः मैं SceneAnimator::GetBoneMatrices में समाप्त हो गया है, जो निम्नलिखित शामिल हैं:

// Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose 
// Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform 
for(size_t a = 0; a < mesh->mNumBones; ++a) 
{ 
    const aiBone* bone = mesh->mBones[a]; 
    const aiMatrix4x4& currentGlobalTransform 
     = GetGlobalTransform(mBoneNodesByName[ bone->mName.data ]); 
    mTransforms[a] = globalInverseMeshTransform * currentGlobalTransform * bone->mOffsetMatrix; 
} 

globalInverseMeshTransform हमेशा पहचान है, क्योंकि जाल कुछ भी बदलना नहीं है। currentGlobalTransform बाइंड मैट्रिक्स है, जो संयुक्त के माता-पिता के स्थानीय मैट्रिक्स संयुक्त के स्थानीय मैट्रिक्स के साथ मिलकर बनता है। और mOffsetMatrix उलटा बाध्य मैट्रिक्स है, जो सीधे त्वचा से आता है।

मैंने इन मैट्रिक्स के मूल्यों को अपने आप में चेक किया (ओह हाँ मैंने उन्हें घड़ी की खिड़की में तुलना की) और वे बिल्कुल 0.0001% से दूर थे, लेकिन यह महत्वहीन है। तो असिंप का संस्करण क्यों काम करता है और मेरा सूत्र भी समान नहीं है?

यहाँ मैं क्या मिला है:

Inversed!

Assimp अंत में skinning शेडर को मैट्रिक्स अपलोड करता है, वे निम्न करें:

helper->piEffect->SetMatrixTransposeArray("gBoneMatrix", (D3DXMATRIX*)matrices, 60); 

Waaaaait एक दूसरे। वे उन्हें स्थानांतरित अपलोड करते हैं? यह इतना आसान नहीं हो सकता है। बिल्कुल नहीं।

enter image description here

हाँ।

कुछ और मैं गलत कर रहा था: मैं समन्वय को सही सिस्टम (सेंटीमीटर से मीटर) में स्किनिंग मैट्रिस लागू करने से पहले परिवर्तित कर रहा था। इसका परिणाम पूरी तरह से विकृत मॉडल में होता है, क्योंकि मैट्रिस मूल समन्वय प्रणाली के लिए डिज़ाइन किए गए हैं।

भविष्य Googlers

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

हो गया!

+0

पुराना प्रश्न दिखता है लेकिन बहुत उपयोगी है! आपका बहुत बहुत धन्यवाद! – Jas

1

बीटीडब्लू, यदि आप अंत में मैट्रिक्स को ट्रांसपोज़ करने के बजाय उन्हें लोड करने पर मैट्रिस को ट्रांसफर करते हैं (जो एनिमेटिंग करते समय समस्याग्रस्त हो सकता है) तो आप अपने गुणा को अलग-अलग करना चाहते हैं (जिस विधि का आप ऊपर उपयोग करते हैं वह स्किनिंग का उपयोग करने के लिए प्रतीत होता है ओपनजीएल अनुकूल मैट्रिस का उपयोग करते समय डायरेक्टएक्स - ट्रांसफर को मिटा दें।)

डायरेक्टएक्स में जब मैं फ़ाइल से लोड होता हूं तो मैट्रिक्स को ट्रांसफर करता हूं और फिर मैं उपयोग करता हूं (नीचे दिए गए उदाहरण में मैं सरलता के लिए बस बाइंड को लागू कर रहा हूं) :

एक्सएमएमएटीआरएक्स l_oWorldMatrix = XMMatrixMultiply (l_oBindPose, in_oParentWorldMatrix);

एक्सएमएमएटीआरएक्स l_oMatrixPallette = XMMatrixMultiply (l_oInverseBindPose, l_oWorldMatrix);

एक्सएमएमएटीआरएक्स l_oFinalMatrix = XMMatrixMultiply (l_oBindShapeMatrix, l_oMatrixPallette);

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