|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "skeletonsubtools.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "skeletontool.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tscenehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tobjecthandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tframehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheethandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshlevelhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjecttree.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjectcmd.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tpinnedrangeset.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/hook.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/skeleton.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stageobjectutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <tsystem.h></tsystem.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <math.h></math.h>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace SkeletonSubtools;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// DragCenterTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DragCenterTool::DragCenterTool(SkeletonTool *tool)
|
|
Shinya Kitaoka |
120a6e |
: DragTool(tool)
|
|
Shinya Kitaoka |
120a6e |
, m_objId(TTool::getApplication()->getCurrentObject()->getObjectId())
|
|
Shinya Kitaoka |
120a6e |
, m_frame(TTool::getApplication()->getCurrentFrame()->getFrame()) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragCenterTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
m_center = m_oldCenter = xsh->getCenter(m_objId, m_frame);
|
|
Shinya Kitaoka |
120a6e |
m_firstPos = pos;
|
|
Shinya Kitaoka |
120a6e |
m_affine = xsh->getPlacement(m_objId, m_frame).inv() *
|
|
Shinya Kitaoka |
120a6e |
xsh->getParentPlacement(m_objId, m_frame);
|
|
Shinya Kitaoka |
120a6e |
m_affine.a13 = m_affine.a23 = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragCenterTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
double factor = 1.0 / Stage::inch;
|
|
Shinya Kitaoka |
120a6e |
m_center = m_oldCenter + (m_affine * (pos - m_firstPos)) * factor;
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->getXsheet()->setCenter(
|
|
Shinya Kitaoka |
120a6e |
m_objId, m_frame, m_center);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragCenterTool::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
UndoStageObjectCenterMove *undo =
|
|
Shinya Kitaoka |
120a6e |
new UndoStageObjectCenterMove(m_objId, m_frame, m_oldCenter, m_center);
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
undo->setObjectHandle(app->getCurrentObject());
|
|
Shinya Kitaoka |
120a6e |
undo->setXsheetHandle(app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(undo);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// DragChannelTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DragChannelTool::DragChannelTool(SkeletonTool *tool, TStageObject::Channel a0)
|
|
Shinya Kitaoka |
120a6e |
: DragTool(tool) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
m_before.setFrameHandle(app->getCurrentFrame());
|
|
Shinya Kitaoka |
120a6e |
m_before.setObjectHandle(app->getCurrentObject());
|
|
Shinya Kitaoka |
120a6e |
m_before.setXsheetHandle(app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
m_before.add(a0);
|
|
Shinya Kitaoka |
120a6e |
if (tool->isGlobalKeyframesEnabled()) {
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_X);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Y);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Z);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_SO);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ScaleX);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ScaleY);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Scale);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Path);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ShearX);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ShearY);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_after = m_before;
|
|
Shinya Kitaoka |
120a6e |
m_dragged = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DragChannelTool::DragChannelTool(SkeletonTool *tool, TStageObject::Channel a0,
|
|
Shinya Kitaoka |
120a6e |
TStageObject::Channel a1)
|
|
Shinya Kitaoka |
120a6e |
: DragTool(tool) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
m_before.setFrameHandle(app->getCurrentFrame());
|
|
Shinya Kitaoka |
120a6e |
m_before.setObjectHandle(app->getCurrentObject());
|
|
Shinya Kitaoka |
120a6e |
m_before.setXsheetHandle(app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
m_before.add(a0);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(a1);
|
|
Shinya Kitaoka |
120a6e |
if (tool->isGlobalKeyframesEnabled()) {
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_X);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Y);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Z);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_SO);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ScaleX);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ScaleY);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Scale);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_Path);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ShearX);
|
|
Shinya Kitaoka |
120a6e |
m_before.add(TStageObject::T_ShearY);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_after = m_before;
|
|
Shinya Kitaoka |
120a6e |
m_dragged = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragChannelTool::start() {
|
|
Shinya Kitaoka |
120a6e |
m_before.updateValues();
|
|
Shinya Kitaoka |
120a6e |
m_after = m_before;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD DragChannelTool::getCenter() {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = app->getCurrentObject()->getObjectId();
|
|
Shinya Kitaoka |
120a6e |
int frame = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
return xsh->getParentPlacement(objId, frame).inv() *
|
|
Shinya Kitaoka |
120a6e |
xsh->getPlacement(objId, frame) *
|
|
Shinya Kitaoka |
120a6e |
(Stage::inch * xsh->getCenter(objId, frame));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragChannelTool::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
if (m_dragged) {
|
|
Shinya Kitaoka |
120a6e |
if (getTool()->isGlobalKeyframesEnabled()) m_after.setGlobalKeyframe();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
UndoStageObjectMove *undo = new UndoStageObjectMove(m_before, m_after);
|
|
Shinya Kitaoka |
120a6e |
undo->setObjectHandle(app->getCurrentObject());
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(undo);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentScene()->setDirtyFlag(true);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentObject()->notifyObjectIdChanged(
|
|
Shinya Kitaoka |
120a6e |
false); // Keyframes navigator reads this
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_dragged = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// DragPositionTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DragPositionTool::DragPositionTool(SkeletonTool *tool)
|
|
Shinya Kitaoka |
120a6e |
: DragChannelTool(tool, TStageObject::T_X, TStageObject::T_Y) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragPositionTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
start();
|
|
shun-iwasawa |
2d0135 |
m_firstPos = pos;
|
|
Jeremy Bullock |
66c844 |
m_firstDrag = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragPositionTool::leftButtonDrag(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
TPointD delta = pos - m_firstPos;
|
|
Jeremy Bullock |
66c844 |
if (m_firstDrag && (delta.x > 2.0 || delta.y > 2.0)) {
|
|
shun-iwasawa |
2d0135 |
m_firstPos = pos;
|
|
shun-iwasawa |
2d0135 |
delta = TPointD(0.0, 0.0);
|
|
shun-iwasawa |
2d0135 |
m_firstDrag = false;
|
|
Jeremy Bullock |
66c844 |
}
|
|
Shinya Kitaoka |
120a6e |
if (e.isShiftPressed()) {
|
|
Shinya Kitaoka |
120a6e |
if (fabs(delta.x) > fabs(delta.y))
|
|
Shinya Kitaoka |
120a6e |
delta.y = 0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
delta.x = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
double factor = 1.0 / Stage::inch;
|
|
Shinya Kitaoka |
120a6e |
setValues(getOldValue(0) + delta.x * factor,
|
|
Shinya Kitaoka |
120a6e |
getOldValue(1) + delta.y * factor);
|
|
Shinya Kitaoka |
120a6e |
m_dragged = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// DragRotationTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DragRotationTool::DragRotationTool(SkeletonTool *tool, bool snapped)
|
|
Shinya Kitaoka |
120a6e |
: DragChannelTool(tool, TStageObject::T_Angle), m_snapped(snapped) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragRotationTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
m_lastPos = pos;
|
|
Shinya Kitaoka |
120a6e |
m_center = getCenter();
|
|
Shinya Kitaoka |
120a6e |
start();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void DragRotationTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &) {
|
|
Shinya Kitaoka |
120a6e |
TPointD a = m_center - m_lastPos;
|
|
Shinya Kitaoka |
120a6e |
TPointD b = m_center - pos;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double a0 = norm2(pos - m_lastPos);
|
|
Shinya Kitaoka |
120a6e |
if (a0 < 2 && !m_dragged) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double a2 = norm2(a), b2 = norm2(b);
|
|
Shinya Kitaoka |
120a6e |
const double eps = 1e-1;
|
|
Shinya Kitaoka |
120a6e |
if (a2 < eps || b2 < eps) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double dang = asin(cross(a, b) / sqrt(a2 * b2)) * M_180_PI;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_snapped) {
|
|
Shinya Kitaoka |
120a6e |
if (fabs(dang) < 2) return;
|
|
Shinya Kitaoka |
120a6e |
m_snapped = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
setValue(getValue(0) + dang);
|
|
Shinya Kitaoka |
120a6e |
m_dragged = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_lastPos = pos;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// ParentChangeTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
1c557b |
ParentChangeTool::ParentChangeTool(SkeletonTool *tool, TToolViewer *viewer)
|
|
Shinya Kitaoka |
120a6e |
: DragTool(tool)
|
|
Shinya Kitaoka |
120a6e |
, m_viewer(viewer)
|
|
Shinya Kitaoka |
120a6e |
, m_index(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_snapped(true)
|
|
Shinya Kitaoka |
120a6e |
, m_pixelSize(tool->getPixelSize()) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ParentChangeTool::leftButtonDown(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
// colonna, id e frame corrente
|
|
Shinya Kitaoka |
120a6e |
int currentColumnIndex = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
int currentFrame = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = TStageObjectId::ColumnId(currentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = xsh->getStageObject(id);
|
|
Shinya Kitaoka |
120a6e |
obj->getCenterAndOffset(m_oldCenter, m_oldOffset);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// trovo il centro della colonna corrente
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = xsh->getPlacement(id, currentFrame);
|
|
Shinya Kitaoka |
120a6e |
TPointD center = Stage::inch * xsh->getCenter(id, currentFrame);
|
|
Shinya Kitaoka |
120a6e |
m_center = aff * center;
|
|
Shinya Kitaoka |
120a6e |
// mi serve in coordinate assolute (per questo non uso direttamente pos)
|
|
Shinya Kitaoka |
120a6e |
m_lastPos = m_viewer->winToWorld(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
m_lastPos2 = pos;
|
|
Shinya Kitaoka |
120a6e |
// if(m_mode==1) getTool()->setParentProbe(pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// cerco centri e hooks di tutte le altre colonne (non discendenti)
|
|
Shinya Kitaoka |
120a6e |
int nextName = 10000;
|
|
Shinya Kitaoka |
120a6e |
for (int col = 0; col < xsh->getColumnCount(); col++) {
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(currentFrame, col);
|
|
Shinya Kitaoka |
120a6e |
if (cell.isEmpty()) continue;
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId colId = TStageObjectId::ColumnId(col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se colId e' un discendente di id non e' un candidato a diventare
|
|
Shinya Kitaoka |
120a6e |
// il padre di id.
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId tmpId = colId;
|
|
Shinya Kitaoka |
120a6e |
while (tmpId.isColumn() && tmpId != id)
|
|
Shinya Kitaoka |
120a6e |
tmpId = xsh->getStageObjectParent(tmpId);
|
|
Shinya Kitaoka |
120a6e |
if (tmpId == id) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// registro alcune informazioni relative a colId:
|
|
Shinya Kitaoka |
120a6e |
// placement, bbox, centro, hooks, name, ecc.
|
|
Shinya Kitaoka |
120a6e |
Element element;
|
|
shun-iwasawa |
2d0135 |
element.m_columnIndex = col;
|
|
shun-iwasawa |
2d0135 |
TImageP img = cell.getImage(false);
|
|
Shinya Kitaoka |
120a6e |
if (img) element.m_bbox = img->getBBox();
|
|
shun-iwasawa |
2d0135 |
element.m_aff = xsh->getPlacement(colId, currentFrame);
|
|
Shinya Kitaoka |
120a6e |
Peer peer;
|
|
Shinya Kitaoka |
120a6e |
peer.m_columnIndex = col;
|
|
Shinya Kitaoka |
120a6e |
peer.m_handle = 0;
|
|
Shinya Kitaoka |
120a6e |
peer.m_name = nextName++;
|
|
Shinya Kitaoka |
120a6e |
peer.m_pos =
|
|
Shinya Kitaoka |
120a6e |
element.m_aff * (Stage::inch * xsh->getCenter(colId, currentFrame));
|
|
Shinya Kitaoka |
120a6e |
element.m_peers.push_back(peer);
|
|
Shinya Kitaoka |
120a6e |
TXshLevel *xl = cell.m_level.getPointer();
|
|
Shinya Kitaoka |
120a6e |
if (xl) {
|
|
Shinya Kitaoka |
120a6e |
HookSet *hookSet = xl->getHookSet();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = xsh->getStageObject(colId);
|
|
Shinya Kitaoka |
120a6e |
if (hookSet && pegbar) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < hookSet->getHookCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (!hookSet->getHook(i)) continue;
|
|
Shinya Kitaoka |
120a6e |
peer.m_handle = 1 + i;
|
|
Shinya Kitaoka |
120a6e |
peer.m_pos =
|
|
Shinya Kitaoka |
120a6e |
element.m_aff * hookSet->getHook(i)->getAPos(cell.m_frameId);
|
|
Shinya Kitaoka |
120a6e |
peer.m_name = nextName++;
|
|
Shinya Kitaoka |
120a6e |
element.m_peers.push_back(peer);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_elements[col] = element;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// m_newParentCenter = TPointD();
|
|
Shinya Kitaoka |
120a6e |
m_firstWinPos = e.m_pos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_affine = xsh->getParentPlacement(id, currentFrame).inv();
|
|
Shinya Kitaoka |
120a6e |
m_objId = id;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ParentChangeTool::leftButtonDrag(const TPointD &pos,
|
|
Shinya Kitaoka |
120a6e |
const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
if (m_snapped && norm2(e.m_pos - m_firstWinPos) > 200) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
int currentColumnIndex = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = TStageObjectId::ColumnId(currentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectCmd::setParent(objId, TStageObjectId::NoneId, "",
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
m_snapped = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_snapped) return;
|
|
Shinya Kitaoka |
120a6e |
getTool()->setParentProbe(getTool()->getCurrentColumnParentMatrix() * pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
2d0135 |
m_index = m_viewer->posToColumnIndex(e.m_pos, 5.0, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_lastPos = m_viewer->winToWorld(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_handle = -1;
|
|
Shinya Kitaoka |
120a6e |
if (m_index >= 0) {
|
|
Shinya Kitaoka |
120a6e |
double minDist2 = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_elements[m_index].m_peers.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TPointD targetPos = m_elements[m_index].m_peers[i].m_pos;
|
|
Shinya Kitaoka |
120a6e |
double dist2 = norm2(targetPos - m_lastPos);
|
|
Shinya Kitaoka |
120a6e |
if (m_handle < 0 || dist2 < minDist2) {
|
|
Shinya Kitaoka |
120a6e |
minDist2 = dist2;
|
|
Shinya Kitaoka |
120a6e |
m_handle = m_elements[m_index].m_peers[i].m_handle;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ParentChangeTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
int currentColumnIndex = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
int currentFrame = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = TStageObjectId::ColumnId(currentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
getTool()->resetParentProbe();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_snapped) {
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(objId)->setCenterAndOffset(m_oldCenter, m_oldOffset);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (getTool()->getMagicLinkCount() > 0) {
|
|
Shinya Kitaoka |
120a6e |
MagicLink magicLink = getTool()->getMagicLink(0);
|
|
Shinya Kitaoka |
120a6e |
HookData h0 = magicLink.m_h0;
|
|
Shinya Kitaoka |
120a6e |
HookData h1 = magicLink.m_h1;
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = xsh->getStageObject(objId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int parentColumnIndex = h1.m_columnIndex;
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId parentId = TStageObjectId::ColumnId(parentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
std::string parentHandle = h1.getHandle();
|
|
Shinya Kitaoka |
120a6e |
std::string handle = "";
|
|
Shinya Kitaoka |
120a6e |
if (h0.m_columnIndex < 0) {
|
|
Shinya Kitaoka |
120a6e |
handle = obj->getHandle();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
handle = h0.getHandle();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TUndoManager *undoManager = TUndoManager::manager();
|
|
Shinya Kitaoka |
120a6e |
// undoManager->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
// TStageObjectCmd::resetPosition(id, app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
TStageObjectCmd::setHandle(objId, handle, app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
TStageObjectCmd::setParent(objId, parentId, parentHandle,
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
// undoManager->endBlock();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectCmd::setParent(objId, TStageObjectId::NoneId, "",
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(objId)->setCenterAndOffset(m_oldCenter, m_oldOffset);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ParentChangeTool::draw() { getTool()->drawHooks(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// IKTool helper functions
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
66c844 |
// This needs some clarification.
|
|
Jeremy Bullock |
66c844 |
namespace {
|
|
Shinya Kitaoka |
120a6e |
class Graph {
|
|
Jeremy Bullock |
66c844 |
// local variables defined below are:
|
|
Jeremy Bullock |
66c844 |
// Nodes m_nodes;
|
|
Jeremy Bullock |
66c844 |
// std::map<int, int=""> m_leaves;</int,>
|
|
Jeremy Bullock |
66c844 |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
typedef std::set<int> Links;</int>
|
|
Shinya Kitaoka |
120a6e |
typedef Links::const_iterator LinkIter;
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// the second part of the nodes map is a set if ints
|
|
Shinya Kitaoka |
120a6e |
typedef std::map<int, links=""> Nodes;</int,>
|
|
Shinya Kitaoka |
120a6e |
typedef Nodes::const_iterator NodeIter;
|
|
Shinya Kitaoka |
120a6e |
typedef std::map<int, int=""> LeaveTable;</int,>
|
|
Shinya Kitaoka |
120a6e |
typedef LeaveTable::const_iterator LeaveIter;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Graph() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int touch(int id) {
|
|
Jeremy Bullock |
66c844 |
// insert an empty node if not found
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes.count(id) == 0) m_nodes[id] = Links();
|
|
Shinya Kitaoka |
120a6e |
return id;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// check if a node is found in m_nodes
|
|
Shinya Kitaoka |
120a6e |
bool isNode(int id) const { return m_nodes.count(id) > 0; }
|
|
shun-iwasawa |
2d0135 |
|
|
Shinya Kitaoka |
120a6e |
int getNodeCount() const { return (int)m_nodes.size(); }
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
void link(int a, int b) {
|
|
Shinya Kitaoka |
120a6e |
touch(a);
|
|
Shinya Kitaoka |
120a6e |
touch(b);
|
|
Shinya Kitaoka |
120a6e |
m_nodes[a].insert(b);
|
|
Shinya Kitaoka |
120a6e |
m_nodes[b].insert(a);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool areLinked(int a, int b) const {
|
|
Shinya Kitaoka |
120a6e |
NodeIter it = m_nodes.find(a);
|
|
Shinya Kitaoka |
120a6e |
return it == m_nodes.end() ? false : it->second.count(b);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
2d0135 |
|
|
Shinya Kitaoka |
120a6e |
const Links &getLinks(int id) const {
|
|
Shinya Kitaoka |
120a6e |
static const Links empty;
|
|
Shinya Kitaoka |
120a6e |
NodeIter it = m_nodes.find(id);
|
|
Shinya Kitaoka |
120a6e |
return it == m_nodes.end() ? empty : it->second;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
int getLinkCount(int id) const { return (int)getLinks(id).size(); }
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
int getFirstLink(int id) const {
|
|
Shinya Kitaoka |
120a6e |
const Links &links = getLinks(id);
|
|
Shinya Kitaoka |
120a6e |
return links.empty() ? -1 : *(links.begin());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
NodeIter begin() const { return m_nodes.begin(); }
|
|
Shinya Kitaoka |
120a6e |
NodeIter end() const { return m_nodes.end(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
66c844 |
// Wht is a leave?
|
|
Jeremy Bullock |
66c844 |
// m_leaves is a std map of int int
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
bool isLeave(int id) const { return m_leaves.count(id); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
enum LeaveType {
|
|
Shinya Kitaoka |
120a6e |
PINNED = 0x1,
|
|
Shinya Kitaoka |
120a6e |
TEMP = 0x2,
|
|
Shinya Kitaoka |
120a6e |
CHILD_END = 0x4,
|
|
Shinya Kitaoka |
120a6e |
PARENT_END = 0x8
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
int getLeaveType(int id) const {
|
|
Shinya Kitaoka |
120a6e |
LeaveIter it = m_leaves.find(id);
|
|
Shinya Kitaoka |
120a6e |
return it == m_leaves.end() ? 0 : it->second;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
2d0135 |
|
|
Shinya Kitaoka |
120a6e |
void setLeaveType(int id, int type) { m_leaves[id] = type; }
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// This gets rid of a node.
|
|
Shinya Kitaoka |
120a6e |
void remove(int id) {
|
|
Shinya Kitaoka |
120a6e |
NodeIter it = m_nodes.find(id);
|
|
Shinya Kitaoka |
120a6e |
if (it != m_nodes.end()) {
|
|
shun-iwasawa |
2d0135 |
// iterate over the links
|
|
Shinya Kitaoka |
120a6e |
for (LinkIter j = it->second.begin(); j != it->second.end(); ++j)
|
|
Shinya Kitaoka |
120a6e |
m_nodes[*j].erase(id);
|
|
Shinya Kitaoka |
120a6e |
m_nodes.erase(it->first);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void clear() {
|
|
Shinya Kitaoka |
120a6e |
m_nodes.clear();
|
|
Shinya Kitaoka |
120a6e |
m_leaves.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
Nodes m_nodes;
|
|
Shinya Kitaoka |
120a6e |
std::map<int, int=""> m_leaves;</int,>
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool hasPinned(const Skeleton::Bone *bone, const Skeleton::Bone *prevBone) {
|
|
Shinya Kitaoka |
120a6e |
if (!bone) return false;
|
|
Shinya Kitaoka |
120a6e |
bool isHandle = prevBone == 0;
|
|
Shinya Kitaoka |
120a6e |
bool isChild = prevBone != 0 && prevBone == bone->getParent();
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
if (bone->getPinnedStatus() != Skeleton::Bone::FREE) return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (bone->getParent() && bone->getParent() != prevBone &&
|
|
Jeremy Bullock |
66c844 |
hasPinned(bone->getParent(), bone)) {
|
|
shun-iwasawa |
2d0135 |
return true;
|
|
Jeremy Bullock |
66c844 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
66c844 |
for (int i = 0; i < bone->getChildCount(); i++) {
|
|
shun-iwasawa |
2d0135 |
if (bone->getChild(i) != prevBone) {
|
|
shun-iwasawa |
2d0135 |
if (hasPinned(bone->getChild(i), bone)) {
|
|
shun-iwasawa |
2d0135 |
return true;
|
|
Jeremy Bullock |
66c844 |
}
|
|
shun-iwasawa |
2d0135 |
}
|
|
Jeremy Bullock |
66c844 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// create the tree from the skeleton. the tree contains the active chain only
|
|
Toshihiro Shimizu |
890ddd |
// i.e. the nodes bounded by the pinned nodes and the handle
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool addToActiveChain(Graph &tree, const Skeleton::Bone *bone,
|
|
Shinya Kitaoka |
120a6e |
const Skeleton::Bone *prevBone) {
|
|
Shinya Kitaoka |
120a6e |
if (!bone) return false;
|
|
shun-iwasawa |
2d0135 |
|
|
Jeremy Bullock |
66c844 |
// The handle is what you grabbed
|
|
shun-iwasawa |
2d0135 |
bool isHandle = prevBone == 0;
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
bool isChild = prevBone != 0 && prevBone == bone->getParent();
|
|
Shinya Kitaoka |
120a6e |
bool isParent = prevBone != 0 && prevBone->getParent() == bone;
|
|
Shinya Kitaoka |
120a6e |
int pinnedStatus = bone->getPinnedStatus();
|
|
Shinya Kitaoka |
120a6e |
bool isFree = pinnedStatus == Skeleton::Bone::FREE;
|
|
Shinya Kitaoka |
120a6e |
// bool isPinned = pinnedStatus == Skeleton::Bone::PINNED;
|
|
Shinya Kitaoka |
120a6e |
bool isTempPinned = pinnedStatus == Skeleton::Bone::TEMP_PINNED;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool propagate = false;
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// Go up the chain from what you grabbed and add bones
|
|
Jeremy Bullock |
66c844 |
if (!isChild && isFree) {
|
|
shun-iwasawa |
2d0135 |
if (bone->getParent()) {
|
|
shun-iwasawa |
2d0135 |
propagate |= addToActiveChain(tree, bone->getParent(), bone);
|
|
shun-iwasawa |
2d0135 |
}
|
|
Jeremy Bullock |
66c844 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> children;</int>
|
|
Jeremy Bullock |
66c844 |
// Once you reach the top parent, add the other children
|
|
Jeremy Bullock |
66c844 |
if (isHandle || isFree) {
|
|
shun-iwasawa |
2d0135 |
for (int i = 0; i < bone->getChildCount(); i++) {
|
|
shun-iwasawa |
2d0135 |
if (bone->getChild(i) != prevBone) {
|
|
shun-iwasawa |
2d0135 |
propagate |= addToActiveChain(tree, bone->getChild(i), bone);
|
|
Jeremy Bullock |
66c844 |
}
|
|
shun-iwasawa |
2d0135 |
}
|
|
Jeremy Bullock |
66c844 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool insert = false;
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
if (isHandle) // the handle must be added anyway
|
|
Shinya Kitaoka |
120a6e |
insert = true;
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
else if (isChild) // add child if it's pinned or if some gran-child has been
|
|
Shinya Kitaoka |
120a6e |
// added
|
|
Shinya Kitaoka |
120a6e |
insert = !isFree || propagate;
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
else if (isTempPinned) {
|
|
Shinya Kitaoka |
120a6e |
// parent temp pinned are normally added, but if another branch is pinned we
|
|
Shinya Kitaoka |
120a6e |
// are not
|
|
Shinya Kitaoka |
120a6e |
// able to handle the configuration: then consider it as pinned
|
|
Shinya Kitaoka |
120a6e |
bool locked = false;
|
|
Shinya Kitaoka |
120a6e |
// if(bone->getParent()) locked |= hasPinned(bone->getParent(), bone);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < bone->getChildCount() && !locked; i++)
|
|
Shinya Kitaoka |
120a6e |
if (bone->getChild(i) != prevBone)
|
|
Shinya Kitaoka |
120a6e |
locked |= hasPinned(bone->getChild(i), bone);
|
|
Shinya Kitaoka |
120a6e |
insert = !locked;
|
|
Shinya Kitaoka |
120a6e |
} else // add parent if free and grand-parent or some other child has been
|
|
Shinya Kitaoka |
120a6e |
// added; don't add pinned parent
|
|
Shinya Kitaoka |
120a6e |
insert = isFree && propagate;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (insert) {
|
|
Shinya Kitaoka |
120a6e |
int index = tree.touch(bone->getColumnIndex());
|
|
Shinya Kitaoka |
120a6e |
if (!isFree)
|
|
Shinya Kitaoka |
120a6e |
tree.setLeaveType(index, isTempPinned ? 2 : 1);
|
|
Shinya Kitaoka |
120a6e |
else if (!isChild && bone->getParent() &&
|
|
Shinya Kitaoka |
120a6e |
!tree.isNode(bone->getParent()->getColumnIndex())) {
|
|
Shinya Kitaoka |
120a6e |
// the parent has not been added. it was locked => this node act as pinned
|
|
Shinya Kitaoka |
120a6e |
tree.setLeaveType(index, 2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (prevBone) tree.link(prevBone->getColumnIndex(), index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return isHandle || !isFree || propagate;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// IKToolUndo
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace SkeletonSubtools {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
d1f6c4 |
class IKToolUndo final : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
struct Node {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId m_id;
|
|
Shinya Kitaoka |
120a6e |
double m_oldAngle, m_newAngle;
|
|
Shinya Kitaoka |
120a6e |
bool m_wasKeyframe;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
std::vector<node> m_nodes;</node>
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId m_firstFootId;
|
|
Shinya Kitaoka |
120a6e |
TAffine m_oldFootPlacement, m_newFootPlacement;
|
|
Shinya Kitaoka |
120a6e |
int m_frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
IKToolUndo() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void setFirstFootId(const TStageObjectId &firstFootId) {
|
|
Shinya Kitaoka |
120a6e |
m_firstFootId = firstFootId;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void setFirstFootOldPlacement(const TAffine &oldPlacement) {
|
|
Shinya Kitaoka |
120a6e |
m_oldFootPlacement = oldPlacement;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void setFirstFootNewPlacement(const TAffine &newPlacement) {
|
|
Shinya Kitaoka |
120a6e |
m_newFootPlacement = newPlacement;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void addNode(const TStageObjectId &id) {
|
|
Shinya Kitaoka |
120a6e |
m_nodes.push_back(Node());
|
|
Shinya Kitaoka |
120a6e |
m_nodes.back().m_id = id;
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
int frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *param =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(id)->getParam(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
m_nodes.back().m_oldAngle = param->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
m_nodes.back().m_wasKeyframe = param->isKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onAdd() override {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
m_frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_nodes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *param =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(m_nodes[i].m_id)->getParam(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_newAngle = param->getValue(m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void setFootPlacement(const TAffine &placement) const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_firstFootId.isColumn()) return;
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = xsh->getStageObject(m_firstFootId);
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet();
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setPlacement(placement);
|
|
Shinya Kitaoka |
120a6e |
while (obj->getParent().isColumn())
|
|
Shinya Kitaoka |
120a6e |
obj = xsh->getStageObject(obj->getParent());
|
|
Shinya Kitaoka |
120a6e |
obj->invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_nodes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *param =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(m_nodes[i].m_id)->getParam(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes[i].m_wasKeyframe)
|
|
Shinya Kitaoka |
120a6e |
param->setValue(m_frame, m_nodes[i].m_oldAngle);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
param->deleteKeyframe(m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_firstFootId.isColumn()) setFootPlacement(m_oldFootPlacement);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_nodes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *param =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(m_nodes[i].m_id)->getParam(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
param->setValue(m_frame, m_nodes[i].m_newAngle);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_firstFootId.isColumn()) setFootPlacement(m_newFootPlacement);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override {
|
|
Shinya Kitaoka |
120a6e |
return sizeof(*this) + (int)m_nodes.size() * sizeof(Node);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Shinya Kitaoka |
120a6e |
} // namespace SkeletonSubtools
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// IKTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
1c557b |
IKTool::IKTool(SkeletonTool *tool, TToolViewer *viewer, Skeleton *skeleton,
|
|
Shinya Kitaoka |
120a6e |
int columnIndex)
|
|
Shinya Kitaoka |
120a6e |
: DragTool(tool)
|
|
Shinya Kitaoka |
120a6e |
, m_viewer(viewer)
|
|
Shinya Kitaoka |
120a6e |
, m_skeleton(skeleton)
|
|
Shinya Kitaoka |
120a6e |
, m_pos()
|
|
Shinya Kitaoka |
120a6e |
, m_columnIndex(columnIndex)
|
|
Shinya Kitaoka |
120a6e |
, m_valid(false)
|
|
Jeremy Bullock |
66c844 |
, m_frameOnNewPin(false)
|
|
Shinya Kitaoka |
120a6e |
, m_foot(0)
|
|
Shinya Kitaoka |
120a6e |
, m_firstFoot(0)
|
|
Shinya Kitaoka |
120a6e |
, m_undo(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
IKTool::~IKTool() { delete m_skeleton; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool IKTool::isParentOf(int columnIndex, int childColumnIndex) const {
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = m_skeleton->getBoneByColumnIndex(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *childBone =
|
|
Shinya Kitaoka |
120a6e |
m_skeleton->getBoneByColumnIndex(childColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
return bone && childBone && childBone->getParent() == bone;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Jeremy Bullock |
66c844 |
// This is a beast.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::initEngine(const TPointD &pos) {
|
|
Shinya Kitaoka |
120a6e |
m_valid = false;
|
|
Shinya Kitaoka |
120a6e |
m_engine.clear();
|
|
Shinya Kitaoka |
120a6e |
m_joints.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// build the active chain (bounded by m_columnIndex and pinned nodes)
|
|
Shinya Kitaoka |
120a6e |
Graph chain;
|
|
Shinya Kitaoka |
120a6e |
addToActiveChain(chain, m_skeleton->getBoneByColumnIndex(m_columnIndex), 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// mark leaves as child_end or parent_end: a leave is child/parent_end iff
|
|
Shinya Kitaoka |
120a6e |
// all its link are parent/child
|
|
Shinya Kitaoka |
120a6e |
for (Graph::NodeIter it = chain.begin(); it != chain.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
if (chain.getLeaveType(it->first) & (Graph::PINNED | Graph::TEMP)) {
|
|
Shinya Kitaoka |
120a6e |
int type = 0;
|
|
Shinya Kitaoka |
120a6e |
for (Graph::LinkIter j = it->second.begin(); j != it->second.end(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
int f =
|
|
Shinya Kitaoka |
120a6e |
isParentOf(*j, it->first) ? Graph::CHILD_END : Graph::PARENT_END;
|
|
Shinya Kitaoka |
120a6e |
if (type == 0)
|
|
Shinya Kitaoka |
120a6e |
type = f;
|
|
Shinya Kitaoka |
120a6e |
else if (type != f) {
|
|
Shinya Kitaoka |
120a6e |
type = 0;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
chain.setLeaveType(it->first, chain.getLeaveType(it->first) | type);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// search the foot (i.e. the pinned node). if there are no pinned node find
|
|
Jeremy Bullock |
66c844 |
// the first temp-pinned
|
|
Shinya Kitaoka |
120a6e |
int foot = -1;
|
|
Shinya Kitaoka |
120a6e |
for (Graph::NodeIter it = chain.begin(); it != chain.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
if (chain.isLeave(it->first)) {
|
|
Shinya Kitaoka |
120a6e |
if ((chain.getLeaveType(it->first) & Graph::PINNED) != 0 || foot < 0)
|
|
Shinya Kitaoka |
120a6e |
foot = it->first;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (foot < 0 || !chain.isNode(foot)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If the chain descend from the foot then the whole foot should be still
|
|
Shinya Kitaoka |
120a6e |
// (e.g. no rotation)
|
|
Shinya Kitaoka |
120a6e |
// => chop the foot
|
|
Shinya Kitaoka |
120a6e |
if (chain.getLinkCount(foot) == 1 &&
|
|
Shinya Kitaoka |
120a6e |
(chain.getLeaveType(foot) & Graph::PINNED)) {
|
|
Shinya Kitaoka |
120a6e |
int nextNode = chain.getFirstLink(foot);
|
|
Shinya Kitaoka |
120a6e |
if (isParentOf(foot, nextNode)) {
|
|
Shinya Kitaoka |
120a6e |
chain.remove(foot);
|
|
Shinya Kitaoka |
120a6e |
foot = nextNode;
|
|
Shinya Kitaoka |
120a6e |
chain.setLeaveType(foot, 3);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if the handle is a terminal node (i.e. just one link) and the next node is
|
|
Jeremy Bullock |
66c844 |
// a child move the handle to the next node
|
|
Shinya Kitaoka |
120a6e |
int handle = m_columnIndex;
|
|
Shinya Kitaoka |
120a6e |
if (chain.getLinkCount(handle) == 1) {
|
|
Shinya Kitaoka |
120a6e |
int nextNode = chain.getFirstLink(handle);
|
|
Shinya Kitaoka |
120a6e |
if (isParentOf(handle, nextNode)) {
|
|
Shinya Kitaoka |
120a6e |
chain.remove(handle);
|
|
Shinya Kitaoka |
120a6e |
handle = nextNode;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// "reverse" the tree to suit the IKEngine convention
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<int, *="" skeleton::bone="">> stack;</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> done;</int>
|
|
Shinya Kitaoka |
120a6e |
stack.push_back(std::make_pair(foot, (Skeleton::Bone *)0));
|
|
Shinya Kitaoka |
120a6e |
while (!stack.empty()) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = m_skeleton->getBoneByColumnIndex(stack.back().first);
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *prev = stack.back().second;
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *prev2 = prev;
|
|
Shinya Kitaoka |
120a6e |
stack.pop_back();
|
|
Shinya Kitaoka |
120a6e |
for (;;) {
|
|
Shinya Kitaoka |
120a6e |
int id = bone->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
done.push_back(id);
|
|
Shinya Kitaoka |
120a6e |
double sign = 1;
|
|
Shinya Kitaoka |
120a6e |
if (prev) {
|
|
Shinya Kitaoka |
120a6e |
if (prev->getParent() == bone) sign = -1;
|
|
Shinya Kitaoka |
120a6e |
} else if (done.size() == 1) {
|
|
Shinya Kitaoka |
120a6e |
if (chain.getLeaveType(id) & Graph::CHILD_END) sign = -1;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (chain.getLeaveType(id) & Graph::PARENT_END) sign = -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Graph::Links links = chain.getLinks(bone->getColumnIndex());
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)done.size(); i++) links.erase(done[i]);
|
|
Shinya Kitaoka |
120a6e |
if (links.size() == 0) {
|
|
Shinya Kitaoka |
120a6e |
// terminal point
|
|
Shinya Kitaoka |
120a6e |
m_joints.push_back(Joint(bone, prev, sign));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
Graph::LinkIter it = links.begin();
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *next = m_skeleton->getBoneByColumnIndex(*it++);
|
|
Shinya Kitaoka |
120a6e |
for (; it != links.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
stack.push_back(std::make_pair(*it, prev));
|
|
shun-iwasawa |
2d0135 |
if (links.size() > 1 ||
|
|
shun-iwasawa |
2d0135 |
(prev && next &&
|
|
shun-iwasawa |
2d0135 |
(prev->getParent() == bone && next->getParent() == bone))) {
|
|
Shinya Kitaoka |
120a6e |
bone = next;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_joints.push_back(Joint(bone, prev, sign));
|
|
Shinya Kitaoka |
120a6e |
prev = bone;
|
|
Shinya Kitaoka |
120a6e |
bone = next;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// if(m_joints.size()>=2 && m_joints[1].m_prevBone == m_joints[0].m_bone)
|
|
Shinya Kitaoka |
120a6e |
// m_joints[0].m_sign = m_joints[1].m_sign;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// feed the engine
|
|
Shinya Kitaoka |
120a6e |
m_engine.setRoot(m_joints[0].m_bone->getCenter());
|
|
Shinya Kitaoka |
120a6e |
for (int i = 1; i < (int)m_joints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
int parent = -1;
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < i; j++)
|
|
Shinya Kitaoka |
120a6e |
if (m_joints[j].m_bone == m_joints[i].m_prevBone) {
|
|
Shinya Kitaoka |
120a6e |
parent = j;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (parent < 0) {
|
|
Shinya Kitaoka |
120a6e |
assert(0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_engine.addJoint(m_joints[i].m_bone->getCenter(), parent);
|
|
Shinya Kitaoka |
120a6e |
if (m_joints[i].m_bone->getPinnedStatus() != Skeleton::Bone::FREE)
|
|
Shinya Kitaoka |
120a6e |
m_engine.lock(i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// add the handle
|
|
Shinya Kitaoka |
120a6e |
bool handleFound = false;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_joints.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_joints[i].m_bone->getColumnIndex() == handle) {
|
|
Shinya Kitaoka |
120a6e |
m_engine.addJoint(pos, i);
|
|
Shinya Kitaoka |
120a6e |
handleFound = true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!handleFound) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
setAngleOffsets();
|
|
Shinya Kitaoka |
120a6e |
computeIHateIK();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_valid = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
66c844 |
// This sets foot placement data
|
|
Jeremy Bullock |
66c844 |
// and checks if the current frame is the start
|
|
Jeremy Bullock |
66c844 |
// of a new pinned center
|
|
Jeremy Bullock |
66c844 |
// The name of this function should be changed once it
|
|
Jeremy Bullock |
66c844 |
// actually works. Until then, the name is fitting.
|
|
Shinya Kitaoka |
120a6e |
void IKTool::computeIHateIK() {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstageobject *=""> objs;</tstageobject>
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_skeleton->getBoneCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
objs.push_back(m_skeleton->getBone(i)->getStageObject());
|
|
Shinya Kitaoka |
120a6e |
int n = (int)objs.size();
|
|
Shinya Kitaoka |
120a6e |
int frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
m_foot = m_firstFoot = 0;
|
|
shun-iwasawa |
2d0135 |
m_frameOnNewPin = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
66c844 |
// this just finds the first pin
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
shun-iwasawa |
2d0135 |
for (i = 0; i < n && !objs[i]->getPinnedRangeSet()->isPinned(frame); i++) {
|
|
shun-iwasawa |
2d0135 |
}
|
|
Shinya Kitaoka |
120a6e |
if (i == n) return;
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// this makes m_foot to be the current pin
|
|
Shinya Kitaoka |
120a6e |
m_foot = objs[i];
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// check to see if this frame is the start of a new pin
|
|
Shinya Kitaoka |
120a6e |
const TPinnedRangeSet::Range *range =
|
|
Shinya Kitaoka |
120a6e |
m_foot->getPinnedRangeSet()->getRange(frame);
|
|
Shinya Kitaoka |
120a6e |
if (!range || range->first != frame) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
66c844 |
m_frameOnNewPin = true;
|
|
shun-iwasawa |
2d0135 |
int firstFrame = frame - 1;
|
|
shun-iwasawa |
2d0135 |
m_firstFoot = m_foot;
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// the frame is the start of a new pinned frame, find the previous pin
|
|
Shinya Kitaoka |
120a6e |
for (;;) {
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < n && !objs[i]->getPinnedRangeSet()->isPinned(firstFrame);
|
|
shun-iwasawa |
2d0135 |
i++) {
|
|
shun-iwasawa |
2d0135 |
}
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
if (i == n) break;
|
|
Shinya Kitaoka |
120a6e |
m_firstFoot = objs[i];
|
|
Shinya Kitaoka |
120a6e |
range = m_firstFoot->getPinnedRangeSet()->getRange(firstFrame);
|
|
Shinya Kitaoka |
120a6e |
if (!range) break;
|
|
Shinya Kitaoka |
120a6e |
firstFrame = range->first - 1;
|
|
Shinya Kitaoka |
120a6e |
if (firstFrame < 0) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
m_footPlacement = m_foot->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
m_firstFootPlacement = m_firstFoot->getPinnedRangeSet()->getPlacement();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::setAngleOffsets() {
|
|
Shinya Kitaoka |
120a6e |
int frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_joints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
double angle = m_joints[i].m_bone->getStageObject()->getParam(
|
|
Shinya Kitaoka |
120a6e |
TStageObject::T_Angle, frame);
|
|
Shinya Kitaoka |
120a6e |
double theta0 = angle * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
double theta1 = m_joints[i].m_sign * m_engine.getJointAngle(i);
|
|
Shinya Kitaoka |
120a6e |
m_joints[i].m_angleOffset = theta1 - theta0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::storeOldValues() {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_joints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectValues values(m_joints[i].m_bone->getStageObject()->getId(),
|
|
Shinya Kitaoka |
120a6e |
TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
if (getTool()->isGlobalKeyframesEnabled()) {
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_X);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_Y);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_Z);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_SO);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_ScaleX);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_ScaleY);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_Scale);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_Path);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_ShearX);
|
|
Shinya Kitaoka |
120a6e |
values.add(TStageObject::T_ShearY);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
values.setFrameHandle(app->getCurrentFrame());
|
|
Shinya Kitaoka |
120a6e |
values.setXsheetHandle(app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
values.updateValues();
|
|
Shinya Kitaoka |
120a6e |
m_joints[i].m_oldValues = values;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Jeremy Bullock |
66c844 |
// This is called on movement of the mouse with button down
|
|
Shinya Kitaoka |
120a6e |
void IKTool::apply() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_valid) return;
|
|
Shinya Kitaoka |
120a6e |
TStageObject *rootObj = m_skeleton->getRootBone()->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
if (!m_undo) {
|
|
Shinya Kitaoka |
120a6e |
m_undo = new IKToolUndo();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_joints.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
m_undo->addNode(m_joints[i].m_bone->getStageObject()->getId());
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
66c844 |
if (m_frameOnNewPin && m_firstFoot) {
|
|
Shinya Kitaoka |
120a6e |
m_undo->setFirstFootId(m_firstFoot->getId());
|
|
Shinya Kitaoka |
120a6e |
m_undo->setFirstFootOldPlacement(
|
|
Shinya Kitaoka |
120a6e |
m_firstFoot->getPinnedRangeSet()->getPlacement());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_joints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = m_joints[i].m_bone->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *param = obj->getParam(TStageObject::T_Angle);
|
|
Shinya Kitaoka |
120a6e |
double theta = m_joints[i].m_sign * m_engine.getJointAngle(i) -
|
|
Shinya Kitaoka |
120a6e |
m_joints[i].m_angleOffset;
|
|
Shinya Kitaoka |
120a6e |
theta *= M_180_PI;
|
|
Shinya Kitaoka |
120a6e |
double oldTheta = param->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
double delta = theta - oldTheta;
|
|
Shinya Kitaoka |
120a6e |
if (fabs(delta) > 180) theta += (theta < oldTheta ? 1 : -1) * 360;
|
|
Shinya Kitaoka |
120a6e |
param->setValue(frame, theta);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_skeleton->getRootBone()->getStageObject()->invalidate();
|
|
Jeremy Bullock |
66c844 |
if (m_frameOnNewPin) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *rootObj = m_skeleton->getRootBone()->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
rootObj->setStatus(TStageObject::XY);
|
|
Shinya Kitaoka |
120a6e |
rootObj->invalidate();
|
|
Shinya Kitaoka |
120a6e |
TAffine rootBasePlacement = rootObj->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
rootObj->setStatus(TStageObject::IK);
|
|
Shinya Kitaoka |
120a6e |
rootObj->invalidate();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *rangeSet = m_firstFoot->getPinnedRangeSet();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine oldFootPlacement = m_foot->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
TAffine relativeOldFootPlacement =
|
|
Shinya Kitaoka |
120a6e |
rootBasePlacement.inv() * oldFootPlacement;
|
|
Shinya Kitaoka |
120a6e |
TAffine correction = rootBasePlacement.inv() * m_footPlacement *
|
|
Shinya Kitaoka |
120a6e |
oldFootPlacement.inv() * rootBasePlacement;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setPlacement(correction * rangeSet->getPlacement());
|
|
Shinya Kitaoka |
120a6e |
rootObj->invalidate();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine currentFootPlacement = m_foot->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
TAffine check = m_footPlacement.inv() * currentFootPlacement;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(check.isIdentity(0.01));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::leftButtonDown(const TPointD &p, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = m_viewer->winToWorld(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
m_pos = pos;
|
|
Shinya Kitaoka |
120a6e |
initEngine(pos);
|
|
Shinya Kitaoka |
120a6e |
storeOldValues();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::leftButtonDrag(const TPointD &p, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_valid) return;
|
|
Shinya Kitaoka |
120a6e |
if (m_engine.getJointCount() > 0) {
|
|
Shinya Kitaoka |
120a6e |
TPointD tmp = m_viewer->winToWorld(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
m_engine.drag(tmp);
|
|
Shinya Kitaoka |
120a6e |
apply();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::leftButtonUp(const TPointD &p, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
if (m_undo) {
|
|
Jeremy Bullock |
66c844 |
if (m_frameOnNewPin && m_firstFoot)
|
|
Shinya Kitaoka |
120a6e |
m_undo->setFirstFootNewPlacement(
|
|
Shinya Kitaoka |
120a6e |
m_firstFoot->getPinnedRangeSet()->getPlacement());
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(m_undo);
|
|
Shinya Kitaoka |
120a6e |
m_undo = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_valid = false;
|
|
Shinya Kitaoka |
120a6e |
m_engine.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void IKTool::draw() {
|
|
Shinya Kitaoka |
120a6e |
int err = glGetError();
|
|
Shinya Kitaoka |
120a6e |
assert(err == GL_NO_ERROR);
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
int frame = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double unit =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentTool()->getTool()->getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_engine.getJointCount() > 0) {
|
|
Shinya Kitaoka |
120a6e |
glColor3d(1, 0, 1);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_engine.getJointCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TPointD pa = m_engine.getJoint(i);
|
|
Shinya Kitaoka |
120a6e |
tglDrawDisk(pa, 5 * unit);
|
|
Shinya Kitaoka |
120a6e |
if (i > 0) {
|
|
Shinya Kitaoka |
120a6e |
int j = m_engine.getJointParent(i);
|
|
Shinya Kitaoka |
120a6e |
tglDrawSegment(pa, m_engine.getJoint(j));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// ChangeDrawingTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class ChangeDrawingUndo final : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
int m_row, m_col;
|
|
Shinya Kitaoka |
120a6e |
TFrameId m_oldFid, m_newFid;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ChangeDrawingUndo(int row, int col) : m_row(row), m_col(col) {
|
|
Shinya Kitaoka |
120a6e |
m_oldFid = getDrawing();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFrameId getDrawing() const {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(m_row, m_col);
|
|
Shinya Kitaoka |
120a6e |
return cell.m_frameId;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void setDrawing(const TFrameId &fid) const {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(m_row, m_col);
|
|
Shinya Kitaoka |
120a6e |
cell.m_frameId = fid;
|
|
Shinya Kitaoka |
120a6e |
xsh->setCell(m_row, m_col, cell);
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(m_col));
|
|
Shinya Kitaoka |
120a6e |
pegbar->setOffset(pegbar->getOffset());
|
|
Shinya Kitaoka |
120a6e |
// solo per invalidare l'imp. TODO da fare meglio
|
|
Shinya Kitaoka |
120a6e |
// l'idea e' che cambiando drawing corrente, se ci sono hook la posizione
|
|
Shinya Kitaoka |
120a6e |
// della pegbar (o delle pegbar figlie) puo' cambiare
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onAdd() override { m_newFid = getDrawing(); }
|
|
Shinya Kitaoka |
473e70 |
void undo() const override { setDrawing(m_oldFid); }
|
|
Shinya Kitaoka |
473e70 |
void redo() const override { setDrawing(m_newFid); }
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override { return sizeof(*this); }
|
|
Shinya Kitaoka |
120a6e |
TFrameId getOldDrawing() const { return m_oldFid; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ChangeDrawingTool::ChangeDrawingTool(SkeletonTool *tool, int dir)
|
|
Shinya Kitaoka |
120a6e |
: DragTool(tool), m_oldY(0), m_dir(dir), m_undo(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ChangeDrawingTool::leftButtonDown(const TPointD &, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
m_oldY = e.m_pos.y;
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
int row = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
int col = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
m_undo = new ChangeDrawingUndo(row, col);
|
|
Shinya Kitaoka |
120a6e |
if (m_dir > 0)
|
|
Shinya Kitaoka |
120a6e |
changeDrawing(1);
|
|
Shinya Kitaoka |
120a6e |
else if (m_dir < 0)
|
|
Shinya Kitaoka |
120a6e |
changeDrawing(-1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ChangeDrawingTool::leftButtonDrag(const TPointD &, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
if (m_dir != 0) return;
|
|
Shinya Kitaoka |
120a6e |
int delta = e.m_pos.y - m_oldY;
|
|
Shinya Kitaoka |
120a6e |
int h = 5;
|
|
Shinya Kitaoka |
120a6e |
int increment = delta > 0 ? delta / h : -(-delta) / h;
|
|
Shinya Kitaoka |
120a6e |
if (increment == 0) return;
|
|
Shinya Kitaoka |
120a6e |
changeDrawing(-increment);
|
|
Shinya Kitaoka |
120a6e |
m_oldY += h * increment;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ChangeDrawingTool::leftButtonUp(const TPointD &, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
ChangeDrawingUndo *u = dynamic_cast<changedrawingundo *="">(m_undo);</changedrawingundo>
|
|
Shinya Kitaoka |
120a6e |
if (u) {
|
|
Shinya Kitaoka |
120a6e |
if (u->getOldDrawing() != u->getDrawing())
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(u);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
delete u;
|
|
Shinya Kitaoka |
120a6e |
m_undo = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// cambia il frame della cella corrente, scorrendo (in maniera
|
|
Toshihiro Shimizu |
890ddd |
// ciclica) i drawings del livello
|
|
Toshihiro Shimizu |
890ddd |
// ritorna true se ci riesce
|
|
Shinya Kitaoka |
120a6e |
bool ChangeDrawingTool::changeDrawing(int delta) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
int row = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
int col = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(row, col);
|
|
Shinya Kitaoka |
120a6e |
if (!cell.m_level || !cell.m_level->getSimpleLevel()) return false;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tframeid> fids;</tframeid>
|
|
Shinya Kitaoka |
120a6e |
cell.m_level->getSimpleLevel()->getFids(fids);
|
|
Shinya Kitaoka |
120a6e |
int n = fids.size();
|
|
Shinya Kitaoka |
120a6e |
if (n < 2) return false;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tframeid>::iterator it;</tframeid>
|
|
Shinya Kitaoka |
120a6e |
it = std::find(fids.begin(), fids.end(), cell.m_frameId);
|
|
Shinya Kitaoka |
120a6e |
if (it == fids.end()) return false;
|
|
Shinya Kitaoka |
120a6e |
int index = std::distance(fids.begin(), it);
|
|
Shinya Kitaoka |
120a6e |
while (delta < 0) delta += n;
|
|
Shinya Kitaoka |
120a6e |
index = (index + delta) % n;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ChangeDrawingUndo *u = dynamic_cast<changedrawingundo *="">(m_undo);</changedrawingundo>
|
|
Shinya Kitaoka |
120a6e |
if (u) u->setDrawing(fids[index]);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
CommandHandler::CommandHandler() : m_skeleton(0), m_tempPinnedSet(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
CommandHandler::~CommandHandler() { delete m_skeleton; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CommandHandler::setSkeleton(Skeleton *skeleton) {
|
|
Shinya Kitaoka |
120a6e |
if (m_skeleton != skeleton) {
|
|
Shinya Kitaoka |
120a6e |
delete m_skeleton;
|
|
Shinya Kitaoka |
120a6e |
m_skeleton = skeleton;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CommandHandler::clearPinnedRanges() {
|
|
Shinya Kitaoka |
120a6e |
if (m_skeleton) {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
m_skeleton->clearAllPinnedRanges();
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentScene()->setDirtyFlag(true);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
m_skeleton->getRootBone()->getStageObject()->setStatus(TStageObject::XY);
|
|
Shinya Kitaoka |
120a6e |
delete m_skeleton;
|
|
Shinya Kitaoka |
120a6e |
m_skeleton = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_tempPinnedSet) m_tempPinnedSet->clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|