我正在尝试对Qt3D中的对象进行动画处理,使其绕特定轴(而不是原点)旋转,同时执行其他转换(例如缩放和平移)。
以下代码根据需要旋转对象,但还没有动画。
QMatrix4x4 mat = QMatrix4x4();
mat.scale(10);
mat.translate(QVector3D(-1.023, 0.836, -0.651));
mat.rotate(QQuaternion::fromAxisAndAngle(QVector3D(0,1,0), -20));
mat.translate(-QVector3D(-1.023, 0.836, -0.651));
//scaling here after rotating/translating shifts the rotation back to be around the origin (??)
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(root);
transform->setMatrix(mat);
//...
entity->addComponent(transform); //the entity of the object i am animating
我没有按照我的意愿将QPropertyAnimation与此代码合并。仅对rotationY属性设置动画不会让我包含旋转原点,因此它会绕错误的轴旋转。为矩阵属性设置动画会产生最终结果,但是旋转的方式在我的场景中是不希望的/不现实的。那么如何为该旋转设置动画以使其绕给定轴旋转?
编辑:有一个QML相当于我想要的。在那里,您可以指定旋转的原点并仅设置角度值的动画:
Rotation3D{
id: doorRotation
angle: 0
axis: Qt.vector3d(0,1,0)
origin: Qt.vector3d(-1.023, 0.836, -0.651)
}
NumberAnimation {target: doorRotation; property: "angle"; from: 0; to: -20; duration: 500}
如何在C ++中做到这一点?
答案 0 :(得分:1)
我认为可以通过简单地修改updateMatrix()
中的orbittransformcontroller.cpp
方法来使用Qt 3D: Simple C++ Example来获得所需的内容:
void OrbitTransformController::updateMatrix()
{
m_matrix.setToIdentity();
// Move to the origin point of the rotation
m_matrix.translate(40, 0.0f, -200);
// Infinite 360° rotation
m_matrix.rotate(m_angle, QVector3D(0.0f, 1.0f, 0.0f));
// Radius of the rotation
m_matrix.translate(m_radius, 0.0f, 0.0f);
m_target->setMatrix(m_matrix);
}
注意:将圆环变成小球形以观察旋转会更容易。
提问者的编辑:这个想法确实是解决问题的一种很好的方法!要将其专门应用于我的方案,updateMatrix()
函数必须看起来像这样:
void OrbitTransformController::updateMatrix()
{
//take the existing matrix to not lose any previous transformations
m_matrix = m_target->matrix();
// Move to the origin point of the rotation, _rotationOrigin would be a member variable
m_matrix.translate(_rotationOrigin);
// rotate (around the y axis)
m_matrix.rotate(m_angle, QVector3D(0.0f, 1.0f, 0.0f));
// translate back
m_matrix.translate(-_rotationOrigin);
m_target->setMatrix(m_matrix);
}
我已经将_rotationOrigin
设置为控制器类中的一个属性,然后可以在外部为每个控制器将其设置为不同的值。