.net - Collada 中的绑定(bind)姿势、关节变换

标签 .net matrix 3d collada

我正在尝试将自定义 3D 模型格式导出到 Collada。我已经通过 XSD 构建了 Collada 数据类,现在当我尝试用数据填充它们时出现问题,特别是对于矩阵相关的问题。

我的 Skeleton 类基本上是我从二进制文件中读取的关节类数组,每个关节看起来像这样(平移和旋转的值相对于父关节,如果没有父关节,则始终为 Root):

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

我要做的第一件事是在文件的“library_visual_scenes”部分中构建 JOINT 节点。这很简单,我得到了正确的结果:
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();
}

以下是输出示例:
<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>

现在是棘手的部分,因为我还必须将权重(蒙皮数据)导出到“library_controllers”部分,如下所示:
<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>

在这里,skinU3D1_id-bind_poses-array 的前 16 个值应该代表我的示例中 bn_head 的反向绑定(bind)姿势。

我可以正确构建关节数组,并且可以毫无问题地处理顶点权重,但我真的不明白如何获取皮肤 Controller 内部使用的矩阵。我需要输出一个 Y UP 方向的 Collada 模型,我所知道的是 Collada 矩阵是列优先的。

从我拥有的数据开始,我的问题基本上是:
  • 如何计算 bind_shape_matrix(在本例中它是一个单位矩阵,但我也看到了其他不同的 Collada 文件)?
  • 如何计算每个关节的逆绑定(bind)矩阵?
  • 最佳答案

    我知道你指的是什么文件格式。您使用的文件格式 (.anim) 多了一个具有 (.inv_bind_mats) 扩展名和相同名称的骨架文件,您无需计算任何内容,只需读取 .inv_bind_mats 文件即可。

    关于.net - Collada 中的绑定(bind)姿势、关节变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31170380/

    相关文章:

    python - 如何检查 python 中的列或行(或对角线)是否都相等

    c# - 非方形螺旋矩阵打印不正确

    math - 如何将 2d 网格点 (x,y) 作为 3d 点 (x,y,z) 映射到球体上

    r - 如何向量化矩阵的每一行与所有其他行的比较

    .net - 当我达到 1GB 时出现 OutOfMemoryException

    c# - 雪花网连接器线程安全吗?

    c# - 如何在窗口窗体的datagridview单元格中放置自定义控件

    c# - 在 3D 场景中隐藏遮挡玩家的物体

    c++ - 使用 NDC 空间在近平面上投影点

    c# - 没有参数的 Event 应该定义自己的自定义 EventArgs 还是简单地使用 System.EventArgs?