2015-07-01 28 views
24

Próbuję wyeksportować niestandardowy format modelu 3D do Collady. Zbudowałem klasy danych Collada przez XSD, a teraz pojawiają się problemy, gdy próbuję je wypełnić danymi, szczególnie w przypadku macierzy.Powiązane pozy, wspólne przekształcenia w Colladzie

Moja klasa szkieletu to w zasadzie szereg klas wspólnych, które czytam z pliku binarnego i każde złącze wygląda tak (wartości trasowania i rotacji odnoszą się do rodzica wspólnego lub root, jeśli nie ma rodzica, zawsze) :

class Joint 
{ 
    List<Joint> Children; 
    Quaternion Rotation; 
    Joint Parent; 
    String Name; 
    UInt32 Id; 
    Vector3 Traslation; 
} 

pierwszą rzeczą, którą robię jest budowa stawu węzły w sekcji „library_visual_scenes” pliku. Który jest dość prosty i uzyskać poprawne wyniki:

foreach (Joint joint in hierarchicalJoints) 
    WriteJointNodes(joint); 

private void WriteJointNodes(Joint joint) 
{ 
    Vector3 rotationEulers = Quaternion.ToEulers(joint.Rotation, EulersOrder.ZYX); 

    WriteStartElement("node"); 
    WriteAttributeString("id", String.Concat(joint.Name, "_id")); 
    WriteAttributeString("type", "JOINT"); 
    WriteAttributeString("name", joint.Name); 
    { 
     WriteElementString("translate", bone.Traslation); 
     WriteElementStringAttributes("rotate", String.Concat("0.0 0.0 1.0 ", rotation.Z.ToDegrees()), { "sid", "rotateZ" }); 
     WriteElementStringAttributes("rotate", String.Concat("0.0 1.0 0.0 ", rotation.Y.ToDegrees()), { "sid", "rotateY" }); 
     WriteElementStringAttributes("rotate", String.Concat("1.0 0.0 0.0 ", rotation.X.ToDegrees()), { "sid", "rotateX" }); 
     WriteElementString("scale", "1.0 1.0 1.0"); 

     Joint[] children = joint.GetChildren(); 

     for (Int32 i = 0; i < children.Length; ++i) 
      WriteJointNodes(children[i]); 
    } 
    WriteEndElement(); 
} 

Oto przykład wyjścia:

<node id="bn_head_id" type="JOINT" name="bn_head"> 
    <translate>0.0732510 0.0000000 0.0000000</translate> 
    <rotate sid="rotateZ">1.0 0.0 1.0 0.0</rotate> 
    <rotate sid="rotateY">0.0 1.0 0.0 9.0</rotate> 
    <rotate sid="rotateX">1.0 0.0 0.0 0.0</rotate> 
    <scale>1.0 1.0 1.0</scale> 

Teraz najtrudniejsze, bo ja też mam do odważników eksportowych (skórowania danych) do sekcja „library_controllers”, który wygląda tak:

<skin source="#geometry1_id"> 
    <bind_shape_matrix>1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</bind_shape_matrix> 
    <source id="skinU3D1_id-joints"> 
     <Name_array id="skinU3D1_id-joints-array" count="4">bn_head_id bn_jaw_id bn_lefteye_id bn_righteye_id</Name_array> 
     <technique_common> 
      <accessor source="#skinU3D1_id-joints-array" count="4" stride="1"> 
       <param name="JOINT" type="Name"/> 
      </accessor> 
     </technique_common> 
    </source> 
    <source id="skinU3D1_id-bind_poses"> 
     <float_array id="skinU3D1_id-bind_poses-array" count="64">0 0.999831 0.018391 -1.58086 -1 0 0 -0.000000 0 -0.018391 0.999831 0.041763 0 0 0 1 -0.00011 -0.374834 0.927092 0.564468 -1 -0.000506 -0.000323 0.000808 0.00059 -0.927092 -0.374834 1.45633 0 0 0 1 0 0.000036 1 -0.074606 1 0 0 0.032523 0 1 -0.000036 -1.638 0 0 0 1 -0.00004 0.000036 1 -0.074607 1 -0.000302 0.00004 -0.032021 0.000302 1 -0.000036 -1.63774 0 0 0 1</float_array> 
     <technique_common> 
      <accessor source="#skinU3D1_id-bind_poses-array" count="4" stride="16"> 
       <param name="TRANSFORM" type="float4x4"/> 
      </accessor> 
     </technique_common> 
     </source> 
     // <<Weights Source Here>> 
     <joints> 
      <input semantic="JOINT" source="#skinU3D1_id-joints"/> 
      <input semantic="INV_BIND_MATRIX" source="#skinU3D1_id-bind_poses"/> 
     </joints> 
     // <<Vertex Weights Here>> 
</skin> 

Tutaj pierwsze 16 wartości skinU3D1_id-bind_poses-array powinien reprezentować wiążą odwrotny od pozy bn_head mój przykład.

Potrafię poprawnie zbudować układ połączeń i mogę obsługiwać wagi wierzchołków bez problemów, ale naprawdę nie rozumiem, jak uzyskać macierze używane wewnątrz kontrolera skóry. Muszę wyprowadzić model Collada z orientacją Y UP i jedyne, co wiem, to to, że macierze Collady mają kolumnę główną.

Począwszy od danych mam, moje pytania są zasadniczo:

  1. W jaki sposób obliczyć bind_shape_matrix (w tym przykładzie jest to macierz jednostkowa, ale widziałem też inne pliki Collada w którym jest inaczej) ?
  2. Jak obliczyć odwrotne macierze wiązania dla każdego połączenia?
+1

Nie musisz obliczać swojej macierzy kształtu powiązania, masz ją, albo nie. Ta wartość jest w zasadzie przesunięciem względem powiązanej siatki. Jeśli jeszcze go nie masz (twój format pliku źródłowego go nie określa), zostaw go jako tożsamość. – FrozenKiwi

+0

A twoje macierze odwrotnych powiązań są określone w id_przepływu id = "skinU3D1_id-bind_poses-array? Wydaje się, że masz już prawidłowy eksport - nie jestem pewien, czy rozumiem twoje pytanie? – FrozenKiwi

+0

W rzeczywistości muszę zrozumieć, jak do obliczenia odwrotnych powiązań i lokalnych macierzy przekształceń, o ile wiem, kilka przetworników używa macierzy 4x3 do ich obliczenia –

Odpowiedz

0

Wiem, jakiego formatu pliku używasz. Format pliku, którego używasz (.anim), ma jeszcze jeden plik szkieletu z rozszerzeniem (.inv_bind_mats) i taką samą nazwą, nie musisz kalkulować niczego, ale po prostu odczytać plik .inv_bind_mats.

+0

@Azarathos też mógłbyś odpowiedzieć na małe pytanie, jak czytasz kwaternion rotacyjny? 2 bajty jako połowa precyzji, a następnie float lub co? –