在Collada结合姿势,联合变革

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Collada结合姿势,联合变革相关的知识,希望对你有一定的参考价值。

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

我的Skeleton类基本上是一个Joint类的数组,我从二进制文件中读取,每个Joint看起来像这样(traslation和rotation的值相对于父Joint,或者如果没有父,则始终为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的逆绑定姿势。

我可以正确地构建关节数组,我可以毫无问题地处理顶点权重,但我真的不明白如何获得皮肤控制器内使用的矩阵。我需要输出一个具有Y UP方向的Collada模型,我所知道的是Collada矩阵是列专业。

从我的数据开始,我的问题基本上是:

  1. 我如何计算bind_shape_matrix(在这个例子中它是一个单位矩阵,但我也看到了其他Collada文件,它们是不同的)?
  2. 如何计算每个关节的反向绑定矩阵?
答案

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

以上是关于在Collada结合姿势,联合变革的主要内容,如果未能解决你的问题,请参考以下文章

如何计算 COLLADA 文件的父子联合变换?

将 Collada dae 文件加载到 SceneKit 以进行联合操作

2022 年主要的技术变革内容

SQL注入常见的姿势一:联合查询注入

动态生成collada文件

众盟数据杨海玲:线下数据资产化推动商业智能变革