Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
反转父qt3d实体变换(不适用于缩放3D)_Qt_Qml_Qt Quick_Qt3d - Fatal编程技术网

反转父qt3d实体变换(不适用于缩放3D)

反转父qt3d实体变换(不适用于缩放3D),qt,qml,qt-quick,qt3d,Qt,Qml,Qt Quick,Qt3d,由于比这个最小测试用例更复杂的原因,我需要另一个实体(parentEntity,洋红色框)的子实体(parentEntity,青色框),但是childEntity应该独立于parentEntity的转换 因此,我添加了这个处理程序: QtQuick.Connections { target: parentTransform onMatrixChanged: { // cancel parent's transform var m = parentT

由于比这个最小测试用例更复杂的原因,我需要另一个实体(
parentEntity
,洋红色框)的子实体(
parentEntity
,青色框),但是
childEntity
应该独立于
parentEntity
的转换

因此,我添加了这个处理程序:

QtQuick.Connections {
    target: parentTransform
    onMatrixChanged: {
        // cancel parent's transform
        var m = parentTransform.matrix
        var i = m.inverted()
        childTransform.matrix = i

        // debug:
        console.log(parentTransform.matrix.times(i))
    }
}
这对于取消父对象的平移和旋转效果很好,但对于缩放效果不佳

当父级的
scale3D
不是[1,1,1]并且还设置了旋转时,则
childEntity
出现扭曲,尽管
parentTransform.matrix
乘以
childTransform.matrix
给出了4x4恒等式。为什么?

最小测试用例:(加载到
QQuickView


问题在于QTransform节点没有将转换存储为一般4x4矩阵。相反,is将矩阵分解为3个变换,这些变换按固定顺序应用:

  • S-a对角标度矩阵
  • R-旋转矩阵
  • T-翻译
然后按T*R*S*X的顺序将其应用于点X

矩阵属性的文档介绍了此分解步骤

因此,当父节点上的变换为M=T*R*S时,子节点上的逆矩阵将为M^-1=S^-1*R^-1*T^-1。在子QTTransform上设置反转将尝试以相同的方式分解它:

M^-1=T_i*R_i*S_i=S^-1*R^-1*T^-1

这是行不通的,因为特别是S和R不这样通勤

设置childTransform.matrix后,您可以在代码中通过比较childTransform.matrixi的值来测试这一点

我认为唯一的解决方案是在嵌套在子级之上的实体上有3个QT转换,以实现正确的反转顺序,如S^-1*R^-1*T^-1


从父QTransform中的相应参数计算逆S^-1,R^-1 T^-1非常简单。

您最终是如何解决这个问题的?Opened:这里有一个非常好的解释:如果我有3个额外的嵌套实体,像这样:
e0
e1
e2
从父到子,那么哪一个应该有
S^-1
?哪个
R^-1
?哪个
T^-1
?只需再次检查正确的顺序=)实体需要嵌套,因此e0包含e1包含e2。我认为正确的顺序应该是:e0有S^-1 e1有R^-1=R^T e2有T^-1=-T
import QtQml 2.12 as QtQml
import QtQuick 2.12 as QtQuick
import QtQuick.Controls 2.12 as QtQuickControls
import QtQuick.Scene3D 2.0

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0

Scene3D {
    function change_translation_and_rotation() {
        parentTransform.translation.x = 0.1
        parentTransform.translation.y = 0.5
        parentTransform.translation.z = 2
        parentTransform.rotationX = 30
        parentTransform.rotationY = 60
        parentTransform.rotationZ = 10
    }

    function change_rotation_and_scale() {
        parentTransform.rotationX = 30
        parentTransform.rotationY = 60
        parentTransform.rotationZ = 10
        parentTransform.scale3D.x = 0.1
        parentTransform.scale3D.y = 0.5
        parentTransform.scale3D.z = 2
    }

    function reset_transform() {
        parentTransform.translation.x = -0.5
        parentTransform.translation.y = 0
        parentTransform.translation.z = 0.5
        parentTransform.rotationX = 0
        parentTransform.rotationY = 0
        parentTransform.rotationZ = 0
        parentTransform.scale3D.x = 1
        parentTransform.scale3D.y = 1
        parentTransform.scale3D.z = 1
    }

    data: [
        QtQml.Connections {
            target: parentTransform
            onMatrixChanged: {
                // cancel parent's transform
                var m = parentTransform.matrix
                var i = m.inverted()
                childTransform.matrix = i

                // debug:
                console.log(parentTransform.matrix.times(i))
            }
        },

        QtQuick.Column {
            spacing: 5
            QtQuick.Repeater {
                id: buttons
                model: ["change_translation_and_rotation", "change_rotation_and_scale", "reset_transform"]
                delegate: QtQuickControls.Button {
                    text: modelData.replace(/_/g, ' ')
                    font.bold: focus
                    onClicked: {focus = true; scene3d[modelData]()}
                }
            }
        }
    ]

    id: scene3d
    anchors.fill: parent
    aspects: ["render", "logic", "input"]

    Entity {
        id: root
        components: [RenderSettings {activeFrameGraph: ForwardRenderer {camera: mainCamera}}, InputSettings {}]

        Camera {
            id: mainCamera
            projectionType: CameraLens.PerspectiveProjection
            fieldOfView: 45
            aspectRatio: 16/9
            nearPlane : 0.1
            farPlane : 1000.0
            position: Qt.vector3d(-3.46902, 4.49373, -3.78577)
            upVector: Qt.vector3d(0.41477, 0.789346, 0.452641)
            viewCenter: Qt.vector3d(0.0, 0.5, 0.0)
        }

        OrbitCameraController {
            camera: mainCamera
        }

        Entity {
            id: parentEntity
            components: [
                CuboidMesh {
                    xExtent: 1
                    yExtent: 1
                    zExtent: 1
                },
                PhongMaterial {
                    ambient: "#6cc"
                },
                Transform {
                    id: parentTransform
                    translation: Qt.vector3d(-0.5, 0, 0.5)
                }
            ]

            Entity {
                id: childEntity
                components: [
                    CuboidMesh {
                        xExtent: 0.5
                        yExtent: 0.5
                        zExtent: 0.5
                    },
                    PhongMaterial {
                        ambient: "#c6c"
                    },
                    Transform {
                        id: childTransform
                        translation: Qt.vector3d(-0.5, 0, 0.5)
                    }
                ]
            }
        }

        QtQuick.Component.onCompleted: reset_transform()
    }
}