| 1 | // Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
| 3 | |
| 4 | #include "joint_p.h" |
| 5 | #include <Qt3DRender/private/managers_p.h> |
| 6 | #include <Qt3DCore/QJoint> |
| 7 | #include <Qt3DCore/private/qjoint_p.h> |
| 8 | |
| 9 | #include <algorithm> |
| 10 | |
| 11 | QT_BEGIN_NAMESPACE |
| 12 | |
| 13 | namespace Qt3DRender { |
| 14 | namespace Render { |
| 15 | |
| 16 | using namespace Qt3DCore; |
| 17 | |
| 18 | Joint::Joint() |
| 19 | : BackendNode(Qt3DCore::QBackendNode::ReadOnly) |
| 20 | , m_localPose() |
| 21 | , m_jointManager(nullptr) |
| 22 | , m_skeletonManager(nullptr) |
| 23 | { |
| 24 | } |
| 25 | |
| 26 | void Joint::cleanup() |
| 27 | { |
| 28 | m_inverseBindMatrix.setToIdentity(); |
| 29 | m_localPose = Sqt(); |
| 30 | m_childJointIds.clear(); |
| 31 | m_name.clear(); |
| 32 | m_owningSkeleton = HSkeleton(); |
| 33 | setEnabled(false); |
| 34 | } |
| 35 | |
| 36 | void Joint::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) |
| 37 | { |
| 38 | const Qt3DCore::QJoint *joint = qobject_cast<const Qt3DCore::QJoint *>(object: frontEnd); |
| 39 | if (!joint) |
| 40 | return; |
| 41 | |
| 42 | bool jointDirty = firstTime; |
| 43 | if (m_localPose.scale != joint->scale()) { |
| 44 | m_localPose.scale = joint->scale(); |
| 45 | jointDirty = true; |
| 46 | } |
| 47 | if (m_localPose.rotation != joint->rotation()) { |
| 48 | m_localPose.rotation = joint->rotation(); |
| 49 | jointDirty = true; |
| 50 | } |
| 51 | if (m_localPose.translation != joint->translation()) { |
| 52 | m_localPose.translation = joint->translation(); |
| 53 | jointDirty = true; |
| 54 | } |
| 55 | if (m_inverseBindMatrix != joint->inverseBindMatrix()) { |
| 56 | // Setting the inverse bind matrix should be a rare operation. Usually it is |
| 57 | // set once and then remains constant for the duration of the skeleton. So just |
| 58 | // trigger a rebuild of the skeleton's SkeletonData which will include obtaining |
| 59 | // the inverse bind matrix. |
| 60 | m_inverseBindMatrix = joint->inverseBindMatrix(); |
| 61 | m_skeletonManager->addDirtySkeleton(dirtyFlag: SkeletonManager::SkeletonDataDirty, skeletonHandle: m_owningSkeleton); |
| 62 | } |
| 63 | if (m_name != joint->name()) { |
| 64 | // Joint name doesn't affect anything in the render aspect so no need |
| 65 | // to mark anything as dirty. |
| 66 | m_name = joint->name(); |
| 67 | |
| 68 | // TODO: Notify other aspects (animation) about the name change. |
| 69 | } |
| 70 | |
| 71 | Qt3DCore::QNodeIdVector childIds = qIdsForNodes(nodes: joint->childJoints()); |
| 72 | std::sort(first: std::begin(cont&: childIds), last: std::end(cont&: childIds)); |
| 73 | if (m_childJointIds != childIds) |
| 74 | m_childJointIds = childIds; |
| 75 | |
| 76 | if (jointDirty) { |
| 77 | markDirty(changes: AbstractRenderer::JointDirty); |
| 78 | m_jointManager->addDirtyJoint(jointId: peerId()); |
| 79 | } |
| 80 | |
| 81 | BackendNode::syncFromFrontEnd(frontEnd, firstTime); |
| 82 | } |
| 83 | |
| 84 | |
| 85 | JointFunctor::JointFunctor(AbstractRenderer *renderer, |
| 86 | JointManager *jointManager, |
| 87 | SkeletonManager *skeletonManager) |
| 88 | : m_renderer(renderer) |
| 89 | , m_jointManager(jointManager) |
| 90 | , m_skeletonManager(skeletonManager) |
| 91 | { |
| 92 | } |
| 93 | |
| 94 | Qt3DCore::QBackendNode *JointFunctor::create(Qt3DCore::QNodeId id) const |
| 95 | { |
| 96 | Joint *backend = m_jointManager->getOrCreateResource(id); |
| 97 | backend->setRenderer(m_renderer); |
| 98 | backend->setJointManager(m_jointManager); |
| 99 | backend->setSkeletonManager(m_skeletonManager); |
| 100 | return backend; |
| 101 | } |
| 102 | |
| 103 | Qt3DCore::QBackendNode *JointFunctor::get(Qt3DCore::QNodeId id) const |
| 104 | { |
| 105 | return m_jointManager->lookupResource(id); |
| 106 | } |
| 107 | |
| 108 | void JointFunctor::destroy(Qt3DCore::QNodeId id) const |
| 109 | { |
| 110 | m_jointManager->removeDirtyJoint(jointId: id); |
| 111 | m_jointManager->releaseResource(id); |
| 112 | } |
| 113 | |
| 114 | } // namespace Render |
| 115 | } // namespace Qt3DRender |
| 116 | |
| 117 | QT_END_NAMESPACE |
| 118 | |