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:
- 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) ? - Jak obliczyć odwrotne macierze wiązania dla każdego połączenia?
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
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
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 –