.net matrix 3d collada

.net - Posturas de unión, transformaciones conjuntas en Collada



matrix 3d (1)

Estoy intentando exportar un formato de modelo 3D personalizado a Collada. Construí las clases de datos Collada a través de XSD y ahora surgen problemas cuando trato de llenarlos con datos, especialmente para lo que concierne a las matrices.

La clase My Skeleton es básicamente una matriz de clases conjuntas que leo del archivo binario y cada conjunto se ve así (los valores de traslation y rotation son relativos a Joint Joint, o Root si no hay parent, siempre):

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

Lo primero que hago es construir los nodos JOINT en la sección "library_visual_scenes" del archivo. Lo cual es bastante simple y obtengo los resultados correctos:

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

Aquí hay un ejemplo de la salida:

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

Ahora viene la parte complicada, ya que también tengo que exportar pesos (desollar datos) a la sección "library_controllers" que se ve así:

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

Aquí, los primeros 16 valores de skinU3D1_id-bind_poses-array deberían representar la pose de enlace inverso de bn_head de mi ejemplo.

Puedo construir la matriz de uniones correctamente y puedo manejar pesos de vértices sin problemas, pero realmente no entiendo cómo obtener las matrices que se utilizan dentro del controlador de la piel. Necesito dar salida a un modelo Collada con orientación Y UP y todo lo que sé es que las matrices Collada son column-major.

A partir de los datos que tengo, mis preguntas básicamente son:

  1. ¿Cómo calculo bind_shape_matrix (en este ejemplo es una matriz de identidad pero también he visto otros archivos de Collada en los que es diferente)?
  2. ¿Cómo calculo las matrices de unión inversa para cada unión?

Sé a qué formato de archivo te refieres. El formato de archivo que utiliza (.anim) tiene un archivo esquelético más con la extensión (.inv_bind_mats) y el mismo nombre, no necesita calcular nada más que leer el archivo .inv_bind_mats.