.net - read - stl file format example



Lier les poses, transformer les articulations à Collada (1)

Je sais à quel format de fichier vous faites référence. Le format de fichier que vous utilisez (.anim) contient un fichier squelettique supplémentaire avec l'extension (.inv_bind_mats) et le même nom, vous n'avez pas besoin de calculer quoi que ce soit, mais lisez simplement le fichier .inv_bind_mats.

J'essaie d'exporter un format de modèle 3D personnalisé vers Collada. J'ai construit les classes de données Collada via XSD et les problèmes surviennent maintenant lorsque j'essaie de les remplir avec des données, en particulier pour ce qui concerne les matrices.

Ma classe squelette est fondamentalement un tableau de classes jointes que je lis dans le fichier binaire et chaque joint ressemble à ceci (les valeurs de traduction et de rotation sont relatives au joint parent, ou racine s'il n'y a pas de parent, toujours):

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

La première chose à faire est de construire les nœuds JOINT dans la section "library_visual_scenes" du fichier. Ce qui est assez simple et j'obtiens des résultats corrects:

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();
}

Voici un exemple de sortie:

<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>

Maintenant vient la partie délicate, car je dois aussi exporter des poids (données de skinning) dans la section "library_controllers" qui ressemble à ceci:

<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>

Ici, les 16 premières valeurs de skinU3D1_id-bind_poses-array doivent représenter la position de liaison inverse de bn_head de mon exemple.

Je peux construire le tableau des articulations correctement et je peux gérer les poids des sommets sans problème mais je ne comprends vraiment pas comment obtenir les matrices utilisées dans le contrôleur de skin. Je dois produire un modèle Collada avec l'orientation Y UP et tout ce que je sais, c'est que les matrices Collada sont des colonnes majeures.

À partir des données que j'ai, mes questions sont essentiellement les suivantes:

  1. Comment calculer le bind_shape_matrix (dans cet exemple, il s’agit d’une matrice d’identité mais j’ai également vu d’autres fichiers Collada dans lesquels il est différent)?
  2. Comment calculer les matrices de liaison inverse pour chaque articulation?




collada