| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| using namespace PlasticToolLocals; |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| class AnimateValuesUndo : public TUndo |
| { |
| int m_row, m_col; |
| int m_v; |
| |
| public: |
| SkDKey m_oldValues, m_newValues; |
| |
| public: |
| AnimateValuesUndo(int v) |
| : m_row(::row()), m_col(::column()), m_v(v) {} |
| |
| |
| |
| int getSize() const { return 10 << 10; } |
| |
| void redo() const |
| { |
| PlasticTool::TemporaryActivation tempActivate(m_row, m_col); |
| |
| if (m_v >= 0) |
| l_plasticTool.setSkeletonSelection(m_v); |
| |
| l_suspendParamsObservation = true; |
| |
| l_plasticTool.deformation()->deleteKeyframe(m_row - 1); |
| l_plasticTool.deformation()->setKeyframe(m_newValues); |
| |
| l_suspendParamsObservation = false; |
| l_plasticTool.onChange(); |
| } |
| |
| void undo() const |
| { |
| PlasticTool::TemporaryActivation tempActivate(m_row, m_col); |
| |
| if (m_v >= 0) |
| l_plasticTool.setSkeletonSelection(m_v); |
| |
| l_suspendParamsObservation = true; |
| |
| l_plasticTool.deformation()->deleteKeyframe(m_row - 1); |
| l_plasticTool.deformation()->setKeyframe(m_oldValues); |
| |
| l_suspendParamsObservation = false; |
| l_plasticTool.onChange(); |
| } |
| }; |
| |
| } |
| |
| |
| |
| |
| |
| void PlasticTool::mouseMove_animate(const TPointD &pos, const TMouseEvent &me) |
| { |
| |
| m_pos = pos; |
| |
| m_svHigh = m_seHigh = -1; |
| |
| if (m_sd) { |
| double d, highlightRadius = getPixelSize() * HIGHLIGHT_DISTANCE; |
| |
| |
| int v = deformedSkeleton().closestVertex(pos, &d); |
| if (v >= 0 && d < highlightRadius) |
| m_svHigh = v; |
| |
| invalidate(); |
| } |
| } |
| |
| |
| |
| void PlasticTool::leftButtonDown_animate(const TPointD &pos, const TMouseEvent &me) |
| { |
| |
| m_pressedPos = m_pos = pos; |
| |
| setSkeletonSelection(m_svHigh); |
| |
| if (m_svSel.hasSingleObject()) { |
| |
| m_pressedVxsPos = std::vector<TPointD>(1, deformedSkeleton().vertex(m_svSel).P()); |
| m_sd->getKeyframeAt(frame(), m_pressedSkDF); |
| } |
| |
| invalidate(); |
| } |
| |
| |
| |
| void PlasticTool::leftButtonDrag_animate(const TPointD &pos, const TMouseEvent &me) |
| { |
| |
| m_pos = pos; |
| |
| if (m_sd && m_svSel.hasSingleObject() && m_svSel > 0) |
| { |
| l_suspendParamsObservation = true; |
| |
| |
| double frame = ::frame(); |
| |
| |
| SkVD *vd = m_sd->vertexDeformation(::skeletonId(), m_svSel); |
| assert(vd); |
| |
| |
| if (m_keepDistance.getValue()) { |
| ::setKeyframe(vd->m_params[SkVD::ANGLE], frame); |
| |
| |
| m_sd->updateAngle(*skeleton(), deformedSkeleton(), frame, m_svSel, pos); |
| } else { |
| ::setKeyframe(vd->m_params[SkVD::ANGLE], frame); |
| ::setKeyframe(vd->m_params[SkVD::DISTANCE], frame); |
| |
| m_sd->updatePosition(*skeleton(), deformedSkeleton(), frame, m_svSel, pos); |
| } |
| |
| l_suspendParamsObservation = false; |
| |
| |
| |
| m_deformedSkeleton.invalidate(); |
| invalidate(); |
| } |
| } |
| |
| |
| |
| void PlasticTool::leftButtonUp_animate(const TPointD &pos, const TMouseEvent &me) |
| { |
| |
| m_pos = pos; |
| |
| if (m_svSel.hasSingleObject() && m_dragged) { |
| |
| if (m_globalKey.getValue()) |
| ::setKeyframe(m_sd, ::frame()); |
| else |
| stageObject()->updateKeyframes(); |
| |
| |
| AnimateValuesUndo *undo = new AnimateValuesUndo(m_svSel); |
| |
| undo->m_oldValues = m_pressedSkDF; |
| m_sd->getKeyframeAt(frame(), undo->m_newValues); |
| |
| TUndoManager::manager()->add(undo); |
| |
| |
| TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(false); |
| } |
| |
| |
| |
| updateMatrix(); |
| invalidate(); |
| } |
| |
| |
| |
| void PlasticTool::addContextMenuActions_animate(QMenu *menu) |
| { |
| bool ret = true; |
| |
| if (!m_svSel.isEmpty()) { |
| QAction *setKey = menu->addAction(tr("Set Key")); |
| ret = ret && connect(setKey, SIGNAL(triggered()), &l_plasticTool, SLOT(setKey_undo())); |
| |
| QAction *setRestKey = menu->addAction(tr("Set Rest Key")); |
| ret = ret && connect(setRestKey, SIGNAL(triggered()), &l_plasticTool, SLOT(setRestKey_undo())); |
| } |
| |
| QAction *setGlobalKey = menu->addAction(tr("Set Global Key")); |
| ret = ret && connect(setGlobalKey, SIGNAL(triggered()), &l_plasticTool, SLOT(setGlobalKey_undo())); |
| |
| QAction *setGlobalRestKey = menu->addAction(tr("Set Global Rest Key")); |
| ret = ret && connect(setGlobalRestKey, SIGNAL(triggered()), &l_plasticTool, SLOT(setGlobalRestKey_undo())); |
| |
| menu->addSeparator(); |
| |
| assert(ret); |
| } |
| |
| |
| |
| void PlasticTool::keyFunc_undo(void (PlasticTool::*keyFunc)()) |
| { |
| assert(m_svSel.objects().size() <= 1); |
| |
| double frame = ::frame(); |
| |
| AnimateValuesUndo *undo = new AnimateValuesUndo(m_svSel); |
| m_sd->getKeyframeAt(frame, undo->m_oldValues); |
| |
| (this->*keyFunc)(); |
| |
| m_sd->getKeyframeAt(frame, undo->m_newValues); |
| |
| TUndoManager::manager()->add(undo); |
| } |
| |
| |
| |
| void PlasticTool::draw_animate() |
| { |
| double pixelSize = getPixelSize(); |
| |
| PlasticSkeleton &deformedSkeleton = this->deformedSkeleton(); |
| |
| |
| if (m_sd) { |
| drawOnionSkinSkeletons_animate(pixelSize); |
| drawSkeleton(deformedSkeleton, pixelSize); |
| drawSelections(m_sd, deformedSkeleton, pixelSize); |
| drawAngleLimits(m_sd, m_skelId, m_svSel, pixelSize); |
| } |
| |
| drawHighlights(m_sd, &deformedSkeleton, pixelSize); |
| } |
| |