#ifndef DUST3D_POSE_DOCUMENT_H #define DUST3D_POSE_DOCUMENT_H #include #include #include #include "skeletondocument.h" #include "rigger.h" struct PoseHistoryItem { std::map> parameters; }; class PoseDocument : public SkeletonDocument { Q_OBJECT signals: void turnaroundChanged(); void cleanup(); void nodeAdded(QUuid nodeId); void edgeAdded(QUuid edgeId); void nodeOriginChanged(QUuid nodeId); void parametersChanged(); public: bool undoable() const override; bool redoable() const override; bool hasPastableNodesInClipboard() const override; bool originSettled() const override; bool isNodeEditable(QUuid nodeId) const override; bool isEdgeEditable(QUuid edgeId) const override; void copyNodes(std::set nodeIdSet) const override; void updateTurnaround(const QImage &image); void updateRigBones(const std::vector *rigBones, const QVector3D &rootTranslation=QVector3D(0, 0, 0)); void reset(); void toParameters(std::map> ¶meters, const std::set &limitNodeIds=std::set()) const; void fromParameters(const std::vector *rigBones, const std::map> ¶meters); public slots: void saveHistoryItem(); void clearHistories(); void undo() override; void redo() override; void paste() override; void moveNodeBy(QUuid nodeId, float x, float y, float z); void setNodeOrigin(QUuid nodeId, float x, float y, float z); float findGroundY() const; void switchChainSide(const std::set nodeIds); public: static const float m_nodeRadius; static const float m_groundPlaneHalfThickness; static const bool m_hideRootAndVirtual; static const float m_outcomeScaleFactor; private: QString findBoneNameByNodeId(const QUuid &nodeId); std::map> m_boneNameToIdsMap; QUuid m_groundPartId; QUuid m_bonesPartId; QUuid m_groundEdgeId; std::deque m_undoItems; std::deque m_redoItems; std::vector m_riggerBones; static float fromOutcomeX(float x); static float toOutcomeX(float x); static float fromOutcomeY(float y); static float toOutcomeY(float y); static float fromOutcomeZ(float z); static float toOutcomeZ(float z); }; #endif