|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tenv.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjectcmd.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzimageutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjecttree.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjectspline.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/dpiscale.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/skeleton.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tscenehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tobjecthandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tpinnedrangeset.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/stageobjectutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzQt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/selection.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/selectioncommandids.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzTools includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/tool.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/cursors.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tw/keycodes.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Shinya Kitaoka |
120a6e |
#include <qcoreapplication> // Qt translation support</qcoreapplication>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainter></qpainter>
|
|
Shinya Kitaoka |
120a6e |
#include <qglwidget> // for QGLWidget::convertToGLFormat</qglwidget>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainterpath></qpainterpath>
|
|
Toshihiro Shimizu |
890ddd |
#include <qstring></qstring>
|
|
Toshihiro Shimizu |
890ddd |
#include <qimage></qimage>
|
|
Toshihiro Shimizu |
890ddd |
#include <qfont></qfont>
|
|
Toshihiro Shimizu |
890ddd |
#include <qfontmetrics></qfontmetrics>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "skeletonsubtools.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "skeletontool.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace SkeletonSubtools;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEnv::IntVar SkeletonGlobalKeyFrame("SkeletonToolGlobalKeyFrame", 0);
|
|
Toshihiro Shimizu |
890ddd |
TEnv::IntVar SkeletonInverseKinematics("SkeletonToolInverseKinematics", 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define BUILD_SKELETON L"Build Skeleton"
|
|
Toshihiro Shimizu |
890ddd |
#define ANIMATE L"Animate"
|
|
Toshihiro Shimizu |
890ddd |
#define INVERSE_KINEMATICS L"Inverse Kinematics"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const double alpha = 0.4;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using SkeletonSubtools::HookData;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline std::string removeTrailingH(std::string handle) {
|
|
Shinya Kitaoka |
120a6e |
if (handle.find("H") == 0)
|
|
Shinya Kitaoka |
120a6e |
return handle.substr(1);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return handle;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// util
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// return true iff column ancestorIndex is column descentIndex or its parent or
|
|
Shinya Kitaoka |
120a6e |
// the parent of the parent, etc.
|
|
Shinya Kitaoka |
120a6e |
bool isAncestorOf(int ancestorIndex, int descendentIndex) {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId ancestorId = TStageObjectId::ColumnId(ancestorIndex);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId descendentId = TStageObjectId::ColumnId(descendentIndex);
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
while (descendentId != ancestorId && descendentId.isColumn())
|
|
Shinya Kitaoka |
120a6e |
descendentId = xsh->getStageObjectParent(descendentId);
|
|
Shinya Kitaoka |
120a6e |
return descendentId == ancestorId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void getHooks(std::vector<hookdata> &hooks, TXsheet *xsh, int row, int col,</hookdata>
|
|
Shinya Kitaoka |
120a6e |
TPointD dpiScale) {
|
|
Shinya Kitaoka |
120a6e |
// nota. hook position is in the coordinate system of the parent object.
|
|
Shinya Kitaoka |
120a6e |
// a inch is Stage::inch
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(row, col);
|
|
Shinya Kitaoka |
120a6e |
if (!cell.m_level) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId columnId = TStageObjectId::ColumnId(col);
|
|
Shinya Kitaoka |
120a6e |
// handle is the current handle (pivot) of the column. It can be H1,H2,... or
|
|
Shinya Kitaoka |
120a6e |
// A,B,C,...
|
|
Shinya Kitaoka |
120a6e |
std::string handle =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(TStageObjectId::ColumnId(col))->getHandle();
|
|
Shinya Kitaoka |
120a6e |
bool handleIsHook = handle.find("H") == 0;
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = xsh->getPlacement(columnId, row);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// imageDpiAff represent the scale factor between the image and the camera
|
|
Shinya Kitaoka |
120a6e |
// derived by dpi match (i.e. ignoring geometric transformation)
|
|
Shinya Kitaoka |
120a6e |
// cameraPos = imageDpiAff * imagePos
|
|
Shinya Kitaoka |
120a6e |
TAffine imageDpiAff;
|
|
Shinya Kitaoka |
120a6e |
if (cell.m_level->getSimpleLevel())
|
|
Shinya Kitaoka |
120a6e |
imageDpiAff =
|
|
Shinya Kitaoka |
120a6e |
getDpiAffine(cell.m_level->getSimpleLevel(), cell.m_frameId, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// center (inches)
|
|
Shinya Kitaoka |
120a6e |
TPointD center = xsh->getCenter(columnId, row); // getHooks
|
|
Shinya Kitaoka |
120a6e |
if (handleIsHook) center = TPointD(0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// add the hook #0 (i.e. the regular center)
|
|
Shinya Kitaoka |
120a6e |
hooks.push_back(HookData(xsh, col, 0, aff * TScale(Stage::inch) * center));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// add the regular hooks
|
|
Shinya Kitaoka |
120a6e |
HookSet *hookSet = cell.m_level->getHookSet();
|
|
Shinya Kitaoka |
120a6e |
if (hookSet && hookSet->getHookCount() > 0) {
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < hookSet->getHookCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
Hook *hook = hookSet->getHook(j);
|
|
Shinya Kitaoka |
120a6e |
if (hook && !hook->isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = hook->getAPos(cell.m_frameId);
|
|
Shinya Kitaoka |
120a6e |
pos = aff * imageDpiAff * pos;
|
|
Shinya Kitaoka |
120a6e |
hooks.push_back(HookData(xsh, col, j + 1, pos));
|
|
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 getConnectedColumns(std::set<int> &connectedColumns, TXsheet *xsh,</int>
|
|
Shinya Kitaoka |
120a6e |
int col) {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id;
|
|
Shinya Kitaoka |
120a6e |
// insert col and all column ancestors
|
|
Shinya Kitaoka |
120a6e |
id = TStageObjectId::ColumnId(col);
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
connectedColumns.insert(id.getIndex());
|
|
Shinya Kitaoka |
120a6e |
id = xsh->getStageObjectParent(id);
|
|
Shinya Kitaoka |
120a6e |
} while (id.isColumn());
|
|
Shinya Kitaoka |
120a6e |
// for each column
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < xsh->getColumnCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
id = TStageObjectId::ColumnId(i);
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstageobjectid> stack;</tstageobjectid>
|
|
Shinya Kitaoka |
120a6e |
// find a column ancestor already connected; put all the column ancestors in
|
|
Shinya Kitaoka |
120a6e |
// stack
|
|
Shinya Kitaoka |
120a6e |
while (id.isColumn() && connectedColumns.count(id.getIndex()) == 0) {
|
|
Shinya Kitaoka |
120a6e |
stack.push_back(id);
|
|
Shinya Kitaoka |
120a6e |
id = xsh->getStageObjectParent(id);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (id.isColumn()) {
|
|
Shinya Kitaoka |
120a6e |
// the stack is connected
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)stack.size(); j++)
|
|
Shinya Kitaoka |
120a6e |
connectedColumns.insert(stack[j].getIndex());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool canShowBone(Skeleton::Bone *bone, TXsheet *xsh, int row) {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = bone->getStageObject()->getId();
|
|
Shinya Kitaoka |
120a6e |
if (!xsh->getCell(row, id.getIndex()).isEmpty() &&
|
|
Shinya Kitaoka |
120a6e |
xsh->getColumn(id.getIndex())->isCamstandVisible())
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < bone->getChildCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (canShowBone(bone->getChild(i), xsh, row)) return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
HookData::HookData(TXsheet *xsh, int columnIndex, int hookId,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &pos)
|
|
Shinya Kitaoka |
120a6e |
: m_columnIndex(columnIndex)
|
|
Shinya Kitaoka |
120a6e |
, m_hookId(hookId)
|
|
Shinya Kitaoka |
120a6e |
, m_pos(pos)
|
|
Shinya Kitaoka |
120a6e |
, m_isPivot(false) {
|
|
Shinya Kitaoka |
120a6e |
std::string handle =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(TStageObjectId::ColumnId(columnIndex))->getHandle();
|
|
Shinya Kitaoka |
120a6e |
if (m_hookId == 0) {
|
|
Shinya Kitaoka |
120a6e |
// if the current handle is a hook the the hook#0 should be the default
|
|
Shinya Kitaoka |
120a6e |
// center, i.e. B
|
|
Shinya Kitaoka |
120a6e |
if (handle.find("H") == 0)
|
|
Shinya Kitaoka |
120a6e |
m_name = "B";
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
m_name = handle;
|
|
Shinya Kitaoka |
120a6e |
m_isPivot = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_name = std::to_string(m_hookId);
|
|
Shinya Kitaoka |
120a6e |
m_isPivot = "H" + m_name == handle;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
enum ToolDevice {
|
|
Shinya Kitaoka |
120a6e |
TD_None = -1,
|
|
Shinya Kitaoka |
120a6e |
TD_Translation = 1,
|
|
Shinya Kitaoka |
120a6e |
TD_Rotation,
|
|
Shinya Kitaoka |
120a6e |
TD_Center,
|
|
Shinya Kitaoka |
120a6e |
TD_ChangeParent,
|
|
Shinya Kitaoka |
120a6e |
TD_ChangeDrawing,
|
|
Shinya Kitaoka |
120a6e |
TD_IncrementDrawing,
|
|
Shinya Kitaoka |
120a6e |
TD_DecrementDrawing,
|
|
Shinya Kitaoka |
120a6e |
TD_InverseKinematics,
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TD_Hook = 10000,
|
|
Shinya Kitaoka |
120a6e |
TD_LockStageObject = 20000,
|
|
Shinya Kitaoka |
120a6e |
TD_MagicLink = 30000,
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TD_Test = 100000
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//============================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// SkeletonTool
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
SkeletonTool skeletonTool;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
SkeletonTool::SkeletonTool()
|
|
Shinya Kitaoka |
120a6e |
: TTool("T_Skeleton")
|
|
Shinya Kitaoka |
120a6e |
, m_active(false)
|
|
Shinya Kitaoka |
120a6e |
, m_device(TD_None)
|
|
Shinya Kitaoka |
120a6e |
, m_mode("Mode:")
|
|
Shinya Kitaoka |
120a6e |
, m_showOnlyActiveSkeleton("Show Only Active Skeleton", false)
|
|
Shinya Kitaoka |
120a6e |
, m_globalKeyframes("Global Key", false)
|
|
Shinya Kitaoka |
120a6e |
, m_dragTool(0)
|
|
Shinya Kitaoka |
120a6e |
, m_firstTime(true)
|
|
Shinya Kitaoka |
120a6e |
, m_currentFrame(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_parentProbe()
|
|
Shinya Kitaoka |
120a6e |
, m_parentProbeEnabled(false)
|
|
Shinya Kitaoka |
120a6e |
, m_otherColumn(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_otherColumnBBoxAff()
|
|
Shinya Kitaoka |
120a6e |
, m_otherColumnBBox()
|
|
Shinya Kitaoka |
120a6e |
, m_labelPos(0, 0)
|
|
Shinya Kitaoka |
120a6e |
, m_label("") {
|
|
Shinya Kitaoka |
120a6e |
bind(TTool::CommonLevels);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_mode);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_globalKeyframes);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_showOnlyActiveSkeleton);
|
|
Shinya Kitaoka |
120a6e |
m_mode.setId("SkeletonMode");
|
|
Shinya Kitaoka |
120a6e |
m_globalKeyframes.setId("GlobalKey");
|
|
Shinya Kitaoka |
120a6e |
m_showOnlyActiveSkeleton.setId("ShowOnlyActiveSkeleton");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(BUILD_SKELETON);
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(ANIMATE);
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(INVERSE_KINEMATICS);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_commandHandler = new CommandHandler();
|
|
Shinya Kitaoka |
120a6e |
m_commandHandler->setTempPinnedSet(&m_temporaryPinnedColumns);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkeletonTool::~SkeletonTool() { delete m_dragTool; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool SkeletonTool::onPropertyChanged(std::string propertyName) {
|
|
Shinya Kitaoka |
120a6e |
SkeletonGlobalKeyFrame = (int)(m_globalKeyframes.getValue());
|
|
Shinya Kitaoka |
120a6e |
// SkeletonInverseKinematics=(int)(m_ikEnabled.getValue());
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool SkeletonTool::isGlobalKeyframesEnabled() const {
|
|
Shinya Kitaoka |
120a6e |
return m_globalKeyframes.getValue();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::updateTranslation() {
|
|
Shinya Kitaoka |
120a6e |
// m_ikEnabled.setQStringName(tr("Inverse Kinematics"));
|
|
Shinya Kitaoka |
120a6e |
m_showOnlyActiveSkeleton.setQStringName(tr("Show Only Active Skeleton"));
|
|
Shinya Kitaoka |
120a6e |
m_globalKeyframes.setQStringName(tr("Global Key"));
|
|
Shinya Kitaoka |
120a6e |
m_mode.setQStringName(tr("Mode:"));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool SkeletonTool::doesApply() const {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
assert(xsh);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = app->getCurrentObject()->getObjectId();
|
|
Shinya Kitaoka |
120a6e |
if (objId.isColumn()) {
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *column = xsh->getColumn(objId.getIndex());
|
|
Shinya Kitaoka |
120a6e |
if (column && column->getSoundColumn()) return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::mouseMove(const TPointD &, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
int selectedDevice = pick(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
if (selectedDevice != m_device) {
|
|
Shinya Kitaoka |
120a6e |
m_device = selectedDevice;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::leftButtonDown(const TPointD &ppos, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
m_otherColumn = -1;
|
|
Shinya Kitaoka |
120a6e |
m_otherColumnBBox = TRectD();
|
|
Shinya Kitaoka |
120a6e |
m_otherColumnBBoxAff = TAffine();
|
|
Shinya Kitaoka |
120a6e |
m_labelPos = TPointD(0, 0);
|
|
Shinya Kitaoka |
120a6e |
m_label = "";
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
if (!doesApply()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(m_dragTool == 0);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
int currentColumnIndex = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = ppos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int selectedDevice = pick(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// cambio drawing
|
|
Shinya Kitaoka |
120a6e |
if (selectedDevice == TD_ChangeDrawing ||
|
|
Shinya Kitaoka |
120a6e |
selectedDevice == TD_IncrementDrawing ||
|
|
Shinya Kitaoka |
120a6e |
selectedDevice == TD_DecrementDrawing) {
|
|
Shinya Kitaoka |
120a6e |
int d = 0;
|
|
Shinya Kitaoka |
120a6e |
if (selectedDevice == TD_IncrementDrawing)
|
|
Shinya Kitaoka |
120a6e |
d = 1;
|
|
Shinya Kitaoka |
120a6e |
else if (selectedDevice == TD_DecrementDrawing)
|
|
Shinya Kitaoka |
120a6e |
d = -1;
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new ChangeDrawingTool(this, d);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool->leftButtonDown(ppos, e);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// click su un hook: attacca la colonna corrente tramite quell'hook
|
|
Shinya Kitaoka |
120a6e |
if (TD_Hook <= selectedDevice && selectedDevice < TD_Hook + 50) {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = TStageObjectId::ColumnId(currentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
TPointD p0 = getCurrentColumnMatrix() * TPointD(0, 0);
|
|
Shinya Kitaoka |
120a6e |
HookData hook(xsh, currentColumnIndex, selectedDevice - TD_Hook, p0);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectCmd::setHandle(objId, hook.getHandle(),
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// magic link
|
|
Shinya Kitaoka |
120a6e |
if (TD_MagicLink <= selectedDevice &&
|
|
Shinya Kitaoka |
120a6e |
selectedDevice < TD_MagicLink + (int)m_magicLinks.size()) {
|
|
Shinya Kitaoka |
120a6e |
magicLink(selectedDevice - TD_MagicLink);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_device = selectedDevice;
|
|
Shinya Kitaoka |
120a6e |
bool justSelected = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_device < 0) {
|
|
Shinya Kitaoka |
120a6e |
// nessun gadget cliccato. Eventualmente seleziono la colonna
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> columnIndexes;</int>
|
|
Shinya Kitaoka |
120a6e |
getViewer()->posToColumnIndexes(e.m_pos, columnIndexes, getPixelSize() * 5,
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Shinya Kitaoka |
120a6e |
if (!columnIndexes.empty()) {
|
|
Shinya Kitaoka |
120a6e |
int columnIndex;
|
|
Shinya Kitaoka |
120a6e |
columnIndex = columnIndexes.back();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (columnIndex >= 0 && columnIndex != currentColumnIndex) {
|
|
Shinya Kitaoka |
120a6e |
if (!isColumnLocked(columnIndex)) {
|
|
Shinya Kitaoka |
120a6e |
pos = getMatrix() * pos;
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentColumn()->setColumnIndex(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
updateMatrix();
|
|
Shinya Kitaoka |
120a6e |
currentColumnIndex = columnIndex;
|
|
Shinya Kitaoka |
120a6e |
justSelected = true;
|
|
Shinya Kitaoka |
120a6e |
pos = getMatrix().inv() * pos;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_label = "Column is locked";
|
|
Shinya Kitaoka |
120a6e |
m_labelPos = pos;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_device < 0) {
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getValue() == INVERSE_KINEMATICS)
|
|
Shinya Kitaoka |
120a6e |
m_device = TD_InverseKinematics;
|
|
Shinya Kitaoka |
120a6e |
else if (m_mode.getValue() == ANIMATE)
|
|
Shinya Kitaoka |
120a6e |
m_device = TD_Rotation;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// lock/unlock: modalita IK
|
|
Shinya Kitaoka |
120a6e |
if (TD_LockStageObject <= m_device && m_device < TD_LockStageObject + 1000) {
|
|
Shinya Kitaoka |
120a6e |
int columnIndex = m_device - TD_LockStageObject;
|
|
Shinya Kitaoka |
120a6e |
int frame = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
togglePinnedStatus(columnIndex, frame, e.isShiftPressed());
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = 0;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (m_device) {
|
|
Shinya Kitaoka |
120a6e |
case TD_Center:
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new DragCenterTool(this);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TD_Translation:
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new DragPositionTool(this);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TD_Rotation:
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new DragRotationTool(this, justSelected);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TD_ChangeParent:
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new ParentChangeTool(this, getViewer());
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case TD_InverseKinematics: {
|
|
Shinya Kitaoka |
120a6e |
Skeleton *skeleton = new Skeleton();
|
|
Shinya Kitaoka |
120a6e |
buildSkeleton(*skeleton, currentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new IKTool(this, getViewer(), skeleton, currentColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) {
|
|
Shinya Kitaoka |
120a6e |
m_dragTool->leftButtonDown(pos, e);
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) {
|
|
Shinya Kitaoka |
120a6e |
m_dragTool->leftButtonDrag(pos, e);
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
|
|
Shinya Kitaoka |
120a6e |
m_label = "";
|
|
Shinya Kitaoka |
120a6e |
m_labelPos = TPointD(0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) {
|
|
Shinya Kitaoka |
120a6e |
m_dragTool->leftButtonUp(pos, e);
|
|
Shinya Kitaoka |
120a6e |
delete m_dragTool;
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(
|
|
Shinya Kitaoka |
120a6e |
false); // Keyframes navigator reads this
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_device == TD_IncrementDrawing || m_device == TD_DecrementDrawing ||
|
|
Shinya Kitaoka |
120a6e |
m_device == TD_ChangeDrawing)
|
|
Shinya Kitaoka |
120a6e |
m_device = pick(e.m_pos);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_device = -1;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->endBlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool SkeletonTool::keyDown(int key, TUINT32 flags, const TPoint &pos) {
|
|
Shinya Kitaoka |
120a6e |
ChangeDrawingTool tool(this, 0);
|
|
Shinya Kitaoka |
120a6e |
if (key == TwConsts::TK_UpArrow)
|
|
Shinya Kitaoka |
120a6e |
tool.changeDrawing(1);
|
|
Shinya Kitaoka |
120a6e |
else if (key == TwConsts::TK_DownArrow)
|
|
Shinya Kitaoka |
120a6e |
tool.changeDrawing(-1);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TogglePinnedStatusUndo : public TUndo {
|
|
Shinya Kitaoka |
120a6e |
SkeletonTool *m_tool;
|
|
Shinya Kitaoka |
120a6e |
std::set<int> m_oldTemp, m_newTemp;</int>
|
|
Shinya Kitaoka |
120a6e |
int m_columnIndex, m_oldColumnIndex;
|
|
Shinya Kitaoka |
120a6e |
std::pair<int, int=""> m_newRange, m_oldRange;</int,>
|
|
Shinya Kitaoka |
120a6e |
TAffine m_oldPlacement, m_newPlacement;
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<tstageobjectid, tstageobject::keyframe="">> m_keyframes;</std::pair<tstageobjectid,>
|
|
Shinya Kitaoka |
120a6e |
int m_frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TogglePinnedStatusUndo(SkeletonTool *tool, int frame)
|
|
Shinya Kitaoka |
120a6e |
: m_tool(tool)
|
|
Shinya Kitaoka |
120a6e |
, m_oldTemp()
|
|
Shinya Kitaoka |
120a6e |
, m_newTemp()
|
|
Shinya Kitaoka |
120a6e |
, m_columnIndex(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_oldColumnIndex(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_newRange(0, -1)
|
|
Shinya Kitaoka |
120a6e |
, m_oldRange(0, -1)
|
|
Shinya Kitaoka |
120a6e |
, m_frame(frame) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void addBoneId(const TStageObjectId &id) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *stageObject = getXsheet()->getStageObject(id);
|
|
Shinya Kitaoka |
120a6e |
if (stageObject) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject::Keyframe k = stageObject->getKeyframe(m_frame);
|
|
Shinya Kitaoka |
120a6e |
m_keyframes.push_back(std::make_pair(id, k));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void setOldRange(int columnIndex, int first, int second,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &placement) {
|
|
Shinya Kitaoka |
120a6e |
m_oldColumnIndex = columnIndex;
|
|
Shinya Kitaoka |
120a6e |
m_oldRange = std::make_pair(first, second);
|
|
Shinya Kitaoka |
120a6e |
m_oldPlacement = placement;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void setNewRange(int columnIndex, int first, int second,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &placement) {
|
|
Shinya Kitaoka |
120a6e |
m_columnIndex = columnIndex;
|
|
Shinya Kitaoka |
120a6e |
m_newRange = std::make_pair(first, second);
|
|
Shinya Kitaoka |
120a6e |
m_newPlacement = placement;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void setOldTemp(const std::set<int> &oldTemp) { m_oldTemp = oldTemp; }</int>
|
|
Shinya Kitaoka |
120a6e |
void setNewTemp(const std::set<int> &newTemp) { m_newTemp = newTemp; }</int>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *getStageObject(int columnIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return TTool::getApplication()
|
|
Shinya Kitaoka |
120a6e |
->getCurrentXsheet()
|
|
Shinya Kitaoka |
120a6e |
->getXsheet()
|
|
Shinya Kitaoka |
120a6e |
->getStageObject(TStageObjectId::ColumnId(columnIndex));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *getRangeSet(int columnIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return getStageObject(columnIndex)->getPinnedRangeSet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXsheet *getXsheet() const {
|
|
Shinya Kitaoka |
120a6e |
return TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void notify() const {
|
|
Shinya Kitaoka |
120a6e |
m_tool->invalidate();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = getXsheet();
|
|
Shinya Kitaoka |
120a6e |
int index = m_columnIndex;
|
|
Shinya Kitaoka |
120a6e |
if (index < 0) index = m_oldColumnIndex;
|
|
Shinya Kitaoka |
120a6e |
if (index >= 0) {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = TStageObjectId::ColumnId(index);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId parentId;
|
|
Shinya Kitaoka |
120a6e |
while (parentId = xsh->getStageObjectParent(id), parentId.isColumn())
|
|
Shinya Kitaoka |
120a6e |
id = parentId;
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(id)->invalidate();
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->notifyObjectIdChanged(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
m_tool->setTemporaryPinnedColumns(m_oldTemp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_columnIndex >= 0)
|
|
Shinya Kitaoka |
120a6e |
getRangeSet(m_columnIndex)
|
|
Shinya Kitaoka |
120a6e |
->removeRange(m_newRange.first, m_newRange.second);
|
|
Shinya Kitaoka |
120a6e |
if (m_oldColumnIndex >= 0) {
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *rangeSet = getRangeSet(m_oldColumnIndex);
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setRange(m_oldRange.first, m_oldRange.second);
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setPlacement(m_oldPlacement);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = getXsheet();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_keyframes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *stageObject =
|
|
Shinya Kitaoka |
120a6e |
getXsheet()->getStageObject(m_keyframes[i].first);
|
|
Shinya Kitaoka |
120a6e |
if (!stageObject) continue;
|
|
Shinya Kitaoka |
120a6e |
stageObject->removeKeyframeWithoutUndo(m_frame);
|
|
Shinya Kitaoka |
120a6e |
if (m_keyframes[i].second.m_isKeyframe)
|
|
Shinya Kitaoka |
120a6e |
stageObject->setKeyframeWithoutUndo(m_frame, m_keyframes[i].second);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
notify();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = getXsheet();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_keyframes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *stageObject =
|
|
Shinya Kitaoka |
120a6e |
getXsheet()->getStageObject(m_keyframes[i].first);
|
|
Shinya Kitaoka |
120a6e |
if (stageObject) stageObject->setKeyframeWithoutUndo(m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_tool->setTemporaryPinnedColumns(m_newTemp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_oldColumnIndex >= 0)
|
|
Shinya Kitaoka |
120a6e |
getRangeSet(m_oldColumnIndex)
|
|
Shinya Kitaoka |
120a6e |
->removeRange(m_oldRange.first, m_oldRange.second);
|
|
Shinya Kitaoka |
120a6e |
if (m_columnIndex >= 0) {
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *rangeSet = getRangeSet(m_columnIndex);
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setRange(m_newRange.first, m_newRange.second);
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setPlacement(m_newPlacement);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
notify();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override { return sizeof *this; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::togglePinnedStatus(int columnIndex, int frame,
|
|
Shinya Kitaoka |
120a6e |
bool shiftPressed) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton skeleton;
|
|
Shinya Kitaoka |
120a6e |
buildSkeleton(skeleton, columnIndex);
|
|
Shinya Kitaoka |
120a6e |
if (!skeleton.getRootBone() || !skeleton.getRootBone()->getStageObject())
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = skeleton.getBoneByColumnIndex(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
assert(bone);
|
|
Shinya Kitaoka |
120a6e |
if (!bone) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TogglePinnedStatusUndo *undo = new TogglePinnedStatusUndo(this, frame);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < skeleton.getBoneCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = skeleton.getBone(i)->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
if (obj) {
|
|
Shinya Kitaoka |
120a6e |
undo->addBoneId(obj->getId());
|
|
Shinya Kitaoka |
120a6e |
obj->setKeyframeWithoutUndo(frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getApplication()->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
getApplication()->getCurrentObject()->notifyObjectIdChanged(false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
undo->setOldTemp(m_temporaryPinnedColumns);
|
|
Shinya Kitaoka |
120a6e |
bool isTemporaryPinned = m_temporaryPinnedColumns.count(columnIndex) > 0;
|
|
Shinya Kitaoka |
120a6e |
if (shiftPressed || isTemporaryPinned) {
|
|
Shinya Kitaoka |
120a6e |
if (isTemporaryPinned)
|
|
Shinya Kitaoka |
120a6e |
m_temporaryPinnedColumns.erase(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_temporaryPinnedColumns.insert(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TAffine placement =
|
|
Shinya Kitaoka |
120a6e |
xsh->getPlacement(bone->getStageObject()->getId(), frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId rootId = skeleton.getRootBone()->getStageObject()->getId();
|
|
Shinya Kitaoka |
120a6e |
TAffine rootPlacement = xsh->getPlacement(rootId, frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int pinnedStatus = bone->getPinnedStatus();
|
|
Shinya Kitaoka |
120a6e |
if (pinnedStatus != Skeleton::Bone::PINNED) {
|
|
Shinya Kitaoka |
120a6e |
int oldPinned = -1;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < skeleton.getBoneCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = skeleton.getBone(i)->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
if (obj->getPinnedRangeSet()->isPinned(frame)) {
|
|
Shinya Kitaoka |
120a6e |
oldPinned = i;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int lastFrame = 1000000;
|
|
Shinya Kitaoka |
120a6e |
if (oldPinned >= 0) {
|
|
Shinya Kitaoka |
120a6e |
assert(skeleton.getBone(oldPinned) != bone);
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = skeleton.getBone(oldPinned)->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
const TPinnedRangeSet::Range *range =
|
|
Shinya Kitaoka |
120a6e |
obj->getPinnedRangeSet()->getRange(frame);
|
|
Shinya Kitaoka |
120a6e |
assert(range && range->first <= frame && frame <= range->second);
|
|
Shinya Kitaoka |
120a6e |
lastFrame = range->second;
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet();
|
|
Shinya Kitaoka |
120a6e |
rangeSet->removeRange(frame, range->second);
|
|
Shinya Kitaoka |
120a6e |
obj->invalidate();
|
|
Shinya Kitaoka |
120a6e |
undo->setOldRange(oldPinned, frame, range->second,
|
|
Shinya Kitaoka |
120a6e |
rangeSet->getPlacement());
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < skeleton.getBoneCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = skeleton.getBone(i)->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
const TPinnedRangeSet::Range *range =
|
|
Shinya Kitaoka |
120a6e |
obj->getPinnedRangeSet()->getNextRange(frame);
|
|
Shinya Kitaoka |
120a6e |
if (range) {
|
|
Shinya Kitaoka |
120a6e |
assert(range->first > frame);
|
|
Shinya Kitaoka |
120a6e |
if (range->first - 1 < lastFrame) lastFrame = range->first - 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = bone->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet();
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setRange(frame, lastFrame);
|
|
Shinya Kitaoka |
120a6e |
if (frame == 0) {
|
|
Shinya Kitaoka |
120a6e |
// this code should be moved elsewhere, possibly in the stageobject
|
|
Shinya Kitaoka |
120a6e |
// implementation
|
|
Shinya Kitaoka |
120a6e |
// the idea is to remove the normal
|
|
Shinya Kitaoka |
120a6e |
TStageObject *rootObj = skeleton.getRootBone()->getStageObject();
|
|
Shinya Kitaoka |
120a6e |
rootObj->setStatus(TStageObject::XY);
|
|
Shinya Kitaoka |
120a6e |
placement = rootObj->getPlacement(0).inv() * placement;
|
|
Shinya Kitaoka |
120a6e |
rootObj->setStatus(TStageObject::IK);
|
|
Shinya Kitaoka |
120a6e |
rangeSet->setPlacement(placement);
|
|
Shinya Kitaoka |
120a6e |
rootObj->invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
undo->setNewRange(bone->getColumnIndex(), frame, lastFrame,
|
|
Shinya Kitaoka |
120a6e |
rangeSet->getPlacement());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
undo->setNewTemp(m_temporaryPinnedColumns);
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(undo);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawSkeleton(const Skeleton &skeleton, int row) {
|
|
Shinya Kitaoka |
120a6e |
bool buildingSkeleton = m_mode.getValue() == BUILD_SKELETON;
|
|
Shinya Kitaoka |
120a6e |
bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = getXsheet();
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> showBoneIndex;</int>
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < skeleton.getBoneCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = skeleton.getBone(i);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = bone->getStageObject()->getId();
|
|
Shinya Kitaoka |
120a6e |
bool canShow = canShowBone(bone, xsh, row);
|
|
Shinya Kitaoka |
120a6e |
if (!canShow) continue;
|
|
Shinya Kitaoka |
120a6e |
showBoneIndex.push_back(i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool changingParent = dynamic_cast<parentchangetool *="">(m_dragTool) != 0;</parentchangetool>
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId currentObjectId =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentObject()->getObjectId();
|
|
Shinya Kitaoka |
120a6e |
std::string currentHandle = xsh->getStageObject(currentObjectId)->getHandle();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)showBoneIndex.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = skeleton.getBone(showBoneIndex[i]);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = bone->getStageObject()->getId();
|
|
Shinya Kitaoka |
120a6e |
bool isCurrent = id == currentObjectId;
|
|
Shinya Kitaoka |
120a6e |
if (isCurrent && buildingSkeleton && m_parentProbeEnabled) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_magicLinks.empty()) {
|
|
Shinya Kitaoka |
120a6e |
drawBone(bone->getCenter(), m_magicLinks[0].m_h1.m_pos, false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
drawBone(bone->getCenter(), m_parentProbe, true);
|
|
Shinya Kitaoka |
120a6e |
} else if (ikEnabled) {
|
|
Shinya Kitaoka |
120a6e |
if (bone->getParent())
|
|
Shinya Kitaoka |
120a6e |
drawIKBone(bone->getCenter(), bone->getParent()->getCenter());
|
|
Shinya Kitaoka |
120a6e |
} else if (bone->getParent() || isCurrent) {
|
|
Shinya Kitaoka |
120a6e |
double pixelSize = getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
TPointD a = bone->getCenter();
|
|
Shinya Kitaoka |
120a6e |
TPointD b, pm;
|
|
Shinya Kitaoka |
120a6e |
if (bone->getParent()) {
|
|
Shinya Kitaoka |
120a6e |
b = bone->getParent()->getCenter();
|
|
Shinya Kitaoka |
120a6e |
pm = (a + b) * 0.5;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
pm = b = a + TPointD(0, 60) * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
bool boneIsVisible = false;
|
|
Shinya Kitaoka |
120a6e |
if (buildingSkeleton) {
|
|
Shinya Kitaoka |
120a6e |
boneIsVisible = true;
|
|
Shinya Kitaoka |
120a6e |
if (bone->isSelected())
|
|
Shinya Kitaoka |
120a6e |
drawBone(a, b, true);
|
|
Shinya Kitaoka |
120a6e |
else if (!m_showOnlyActiveSkeleton.getValue())
|
|
Shinya Kitaoka |
120a6e |
drawBone(a, b, false);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
boneIsVisible = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (boneIsVisible && isCurrent) {
|
|
Shinya Kitaoka |
120a6e |
// draw change parent gadget
|
|
Shinya Kitaoka |
120a6e |
double r = pixelSize * 5;
|
|
Shinya Kitaoka |
120a6e |
if (isPicking()) {
|
|
Shinya Kitaoka |
120a6e |
// int code = TD_ResetParent +
|
|
Shinya Kitaoka |
120a6e |
// bone->getStageObject()->getId().getIndex();
|
|
Shinya Kitaoka |
120a6e |
glPushName(TD_ChangeParent);
|
|
Shinya Kitaoka |
120a6e |
tglDrawDisk(pm, r);
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (m_device == TD_ChangeParent) {
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.47 * alpha, 0.6 * alpha, 0.65 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
r *= 1.5;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.37 * alpha, 0.5 * alpha, 0.55 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
glRectd(pm.x - r, pm.y - r, pm.x + r, pm.y + r);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
tglDrawRect(pm.x - r, pm.y - r, pm.x + r, pm.y + r);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)showBoneIndex.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = skeleton.getBone(showBoneIndex[i]);
|
|
Shinya Kitaoka |
120a6e |
if (!m_showOnlyActiveSkeleton.getValue() || bone->isSelected())
|
|
Shinya Kitaoka |
120a6e |
drawJoint(bone->getCenter(),
|
|
Shinya Kitaoka |
120a6e |
currentObjectId == bone->getStageObject()->getId() &&
|
|
Shinya Kitaoka |
120a6e |
currentHandle.find("H") != 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::getImageBoundingBox(TRectD &bbox, TAffine &aff, int frame,
|
|
Shinya Kitaoka |
120a6e |
int columnIndex) {
|
|
Shinya Kitaoka |
120a6e |
TAffine columnAff =
|
|
Shinya Kitaoka |
120a6e |
getXsheet()->getPlacement(TStageObjectId::ColumnId(columnIndex), frame);
|
|
Shinya Kitaoka |
120a6e |
// TAffine affine = getColumnMatrix(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = getXsheet()->getCell(frame, columnIndex);
|
|
Shinya Kitaoka |
120a6e |
TImageP image = cell.getImage(false);
|
|
Shinya Kitaoka |
120a6e |
TToonzImageP ti = image;
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vi = image;
|
|
Shinya Kitaoka |
120a6e |
if (ti) {
|
|
Shinya Kitaoka |
120a6e |
TAffine imageDpiAff;
|
|
Shinya Kitaoka |
120a6e |
if (cell.m_level->getSimpleLevel())
|
|
Shinya Kitaoka |
120a6e |
imageDpiAff =
|
|
Shinya Kitaoka |
120a6e |
getDpiAffine(cell.m_level->getSimpleLevel(), cell.m_frameId, true);
|
|
Shinya Kitaoka |
120a6e |
aff = columnAff * imageDpiAff;
|
|
Shinya Kitaoka |
120a6e |
bbox = ToonzImageUtils::convertRasterToWorld(convert(ti->getBBox()), ti) *
|
|
Shinya Kitaoka |
120a6e |
ti->getSubsampling();
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawRect(bbox * ti->getSubsampling(), TPixel32(200, 200, 200),
|
|
Shinya Kitaoka |
120a6e |
0x5555);
|
|
Shinya Kitaoka |
120a6e |
} else if (vi) {
|
|
Shinya Kitaoka |
120a6e |
bbox = vi->getBBox();
|
|
Shinya Kitaoka |
120a6e |
aff = columnAff;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
bbox = TRectD();
|
|
Shinya Kitaoka |
120a6e |
aff = TAffine();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawLevelBoundingBox(int frame, int columnIndex) {
|
|
Shinya Kitaoka |
120a6e |
TAffine affine = getCurrentColumnMatrix();
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = getXsheet()->getCell(frame, columnIndex);
|
|
Shinya Kitaoka |
120a6e |
TImageP image = cell.getImage(false);
|
|
Shinya Kitaoka |
120a6e |
TToonzImageP ti = image;
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vi = image;
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
if (affine != getMatrix()) tglMultMatrix(getMatrix().inv() * affine);
|
|
Shinya Kitaoka |
120a6e |
if (ti) {
|
|
Shinya Kitaoka |
120a6e |
TPointD dpiScale = getViewer()->getDpiScale();
|
|
Shinya Kitaoka |
120a6e |
glScaled(dpiScale.x, dpiScale.y, 1);
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox =
|
|
Shinya Kitaoka |
120a6e |
ToonzImageUtils::convertRasterToWorld(convert(ti->getBBox()), ti);
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawRect(bbox * ti->getSubsampling(), TPixel32(200, 200, 200),
|
|
Shinya Kitaoka |
120a6e |
0x5555);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (vi) {
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = vi->getBBox();
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawRect(bbox, TPixel32(200, 200, 200), 0x5555);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawIKJoint(const Skeleton::Bone *bone) {
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = bone->getCenter();
|
|
Shinya Kitaoka |
120a6e |
const double r0 = 6 * getPixelSize(), r1 = r0 / 3;
|
|
Shinya Kitaoka |
120a6e |
int code = TD_LockStageObject + bone->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
glPushName(code);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.8, 0.5, 0.05);
|
|
Shinya Kitaoka |
120a6e |
if (bone->getPinnedStatus() != Skeleton::Bone::FREE) {
|
|
Shinya Kitaoka |
120a6e |
if (bone->getPinnedStatus() == Skeleton::Bone::TEMP_PINNED) {
|
|
Shinya Kitaoka |
120a6e |
double r1 = r0 * 0.60;
|
|
Shinya Kitaoka |
120a6e |
glColor3d(60.0 / 255.0, 250.0 / 255.0, 1.0);
|
|
Shinya Kitaoka |
120a6e |
glRectd(pos.x - r0, pos.y - r0, pos.x + r0, pos.y + r0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.78, 0.62, 0);
|
|
Shinya Kitaoka |
120a6e |
glRectd(pos.x - r1, pos.y - r1, pos.x + r1, pos.y + r1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.1, 0.05);
|
|
Shinya Kitaoka |
120a6e |
tglDrawRect(pos.x - r0, pos.y - r0, pos.x + r0, pos.y + r0);
|
|
Shinya Kitaoka |
120a6e |
tglDrawRect(pos.x - r1, pos.y - r1, pos.x + r1, pos.y + r1);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0, 175.0 / 255.0, 1.0);
|
|
Shinya Kitaoka |
120a6e |
glRectd(pos.x - r0, pos.y - r0, pos.x + r0, pos.y + r0);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.1, 0.05);
|
|
Shinya Kitaoka |
120a6e |
tglDrawRect(pos.x - r0, pos.y - r0, pos.x + r0, pos.y + r0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (bone->isSelected())
|
|
Shinya Kitaoka |
120a6e |
glColor3d(1, 0.78, 0.19);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.78, 0.62, 0);
|
|
Shinya Kitaoka |
120a6e |
tglDrawDisk(pos, r0);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.1, 0.05);
|
|
Shinya Kitaoka |
120a6e |
tglDrawCircle(pos, r0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_device == code) {
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.9, 0.1, 0.1);
|
|
Shinya Kitaoka |
120a6e |
tglFillRect(pos.x - r1, pos.y - r1, pos.x + r1, pos.y + r1);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.1, 0.05);
|
|
Shinya Kitaoka |
120a6e |
const double r3 = 2 * getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
tglDrawCircle(pos, r3);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawJoint(const TPointD &pos, bool current) {
|
|
Shinya Kitaoka |
120a6e |
const double alpha = 0.8, ialpha = 1 - alpha;
|
|
Shinya Kitaoka |
120a6e |
double r0 = 4 * getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
if (current) {
|
|
Shinya Kitaoka |
120a6e |
glPushName(TD_Center);
|
|
Shinya Kitaoka |
120a6e |
if (m_device == TD_Center) {
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.9 * alpha, 0.8 * alpha, 0.2 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
r0 *= 1.5;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
glColor4d(((255.0 / 255.0) - ialpha) / alpha,
|
|
Shinya Kitaoka |
120a6e |
((200.0 / 255.0) - ialpha) / alpha,
|
|
Shinya Kitaoka |
120a6e |
((48.0 / 255.0) - ialpha) / alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
tglDrawDisk(pos, r0);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.1, 0.05);
|
|
Shinya Kitaoka |
120a6e |
tglDrawCircle(pos, r0);
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// in build skeleton center is clickable, but only the current one
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getValue() == BUILD_SKELETON)
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.60 * alpha, 0.60 * alpha, 0.60 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.78 * alpha, 0.62 * alpha, 0 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
tglDrawDisk(pos, r0);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.1, 0.05);
|
|
Shinya Kitaoka |
120a6e |
tglDrawCircle(pos, r0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawBone(const TPointD &a, const TPointD &b, bool selected) {
|
|
Shinya Kitaoka |
120a6e |
const double alpha = 0.8;
|
|
Shinya Kitaoka |
120a6e |
// se sono troppo vicini niente da fare
|
|
Shinya Kitaoka |
120a6e |
TPointD delta = b - a;
|
|
Shinya Kitaoka |
120a6e |
if (norm2(delta) < 0.001) return;
|
|
Shinya Kitaoka |
120a6e |
TPointD u = getPixelSize() * 2.5 * normalize(rotate90(delta));
|
|
Shinya Kitaoka |
120a6e |
if (selected)
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.9 * alpha, 0.9 * alpha, 0.9 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.58 * alpha, 0.58 * alpha, 0.58 * alpha, alpha);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_POLYGON);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a + u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(b);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a - u);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.3, 0.35);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a + u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(b);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a - u);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawIKBone(const TPointD &a, const TPointD &b) {
|
|
Shinya Kitaoka |
120a6e |
// se sono troppo vicini niente da fare
|
|
Shinya Kitaoka |
120a6e |
TPointD delta = b - a;
|
|
Shinya Kitaoka |
120a6e |
if (norm2(delta) < 0.001) return;
|
|
Shinya Kitaoka |
120a6e |
TPointD u = getPixelSize() * 2.5 * normalize(rotate90(delta));
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.58, 0.58, 0.58);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_POLYGON);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a + u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(b + u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(b - u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a - u);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.2, 0.3, 0.35);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a + u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(b + u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(a - u);
|
|
Shinya Kitaoka |
120a6e |
tglVertex(b - u);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::computeMagicLinks() {
|
|
Shinya Kitaoka |
120a6e |
// TODO: spostare qui il calcolo dei magic link
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawHooks() {
|
|
Shinya Kitaoka |
120a6e |
// camera stand reference system
|
|
Shinya Kitaoka |
120a6e |
// glColor3d(0,0,1);
|
|
Shinya Kitaoka |
120a6e |
// tglDrawRect(3,3,97,97);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// glColor3d(0,1,1);
|
|
Shinya Kitaoka |
120a6e |
// tglDrawRect(0,100,Stage::inch,110);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QTime time;
|
|
Shinya Kitaoka |
120a6e |
time.start();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_magicLinks.clear();
|
|
Shinya Kitaoka |
120a6e |
computeMagicLinks();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
int row = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
int col = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
TPointD dpiScale = getViewer()->getDpiScale();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// glColor3d(1,0,1);
|
|
Shinya Kitaoka |
120a6e |
// tglDrawRect(-100*dpiScale.x, -100*dpiScale.y, 0,0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// I should not show hooks of columns already connected with the current one
|
|
Shinya Kitaoka |
120a6e |
// ("linking" to those hooks would create evil loops in the hierarchy)
|
|
Shinya Kitaoka |
120a6e |
std::set<int> connectedColumns;</int>
|
|
Shinya Kitaoka |
120a6e |
getConnectedColumns(connectedColumns, xsh, col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<hookdata> currentColumnHooks;</hookdata>
|
|
Shinya Kitaoka |
120a6e |
std::vector<hookdata> otherColumnsHooks;</hookdata>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// fill currentColumnHooks
|
|
Shinya Kitaoka |
120a6e |
// detect otherColumn (i.e. the active column during a click&drag operator
|
|
Shinya Kitaoka |
120a6e |
int otherColumn = -1;
|
|
Shinya Kitaoka |
120a6e |
if (m_parentProbeEnabled) {
|
|
Shinya Kitaoka |
120a6e |
// qDebug(" parent probe enabled");
|
|
Shinya Kitaoka |
120a6e |
// currentColumnHooks <- current column & current handle
|
|
Shinya Kitaoka |
120a6e |
int hookId = 0;
|
|
Shinya Kitaoka |
120a6e |
std::string handle =
|
|
Shinya Kitaoka |
120a6e |
xsh->getStageObject(TStageObjectId::ColumnId(col))->getHandle();
|
|
Shinya Kitaoka |
120a6e |
if (handle.find("H") == 0) {
|
|
Shinya Kitaoka |
120a6e |
int j = 1;
|
|
Shinya Kitaoka |
120a6e |
while (j < (int)handle.size() && '0' <= handle[j] && handle[j] <= '9') {
|
|
Shinya Kitaoka |
120a6e |
hookId = hookId * 10 + (int)handle[j] - '0';
|
|
Shinya Kitaoka |
120a6e |
j++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currentColumnHooks.push_back(HookData(xsh, col, hookId, m_parentProbe));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// otherColumn = "picked" column not connected
|
|
Shinya Kitaoka |
120a6e |
TPoint parentProbePos = getViewer()->worldToPos(m_parentProbe);
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> indexes;</int>
|
|
Shinya Kitaoka |
120a6e |
getViewer()->posToColumnIndexes(parentProbePos, indexes,
|
|
Shinya Kitaoka |
120a6e |
getPixelSize() * 10, false);
|
|
Shinya Kitaoka |
120a6e |
for (int i = (int)indexes.size() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
if (connectedColumns.count(indexes[i]) == 0) {
|
|
Shinya Kitaoka |
120a6e |
otherColumn = indexes[i];
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// if the mouse is not on a stroke, I'm using the "old" m_otherColumn, if
|
|
Shinya Kitaoka |
120a6e |
// any.
|
|
Shinya Kitaoka |
120a6e |
// (this is needed because of the hooks put inside of unfilled regions)
|
|
Shinya Kitaoka |
120a6e |
if (otherColumn < 0 && m_otherColumn >= 0) {
|
|
Shinya Kitaoka |
120a6e |
if (m_otherColumnBBox.contains(m_otherColumnBBoxAff.inv() *
|
|
Shinya Kitaoka |
120a6e |
m_parentProbe))
|
|
Shinya Kitaoka |
120a6e |
otherColumn = m_otherColumn;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_otherColumn = -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// parent probe not enabled: get all hooks of current column. other column =
|
|
Shinya Kitaoka |
120a6e |
// -1
|
|
Shinya Kitaoka |
120a6e |
getHooks(currentColumnHooks, xsh, row, col, TPointD(1, 1)); // dpiScale);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// other columns hooks <- all hooks of all unlinked columns
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < xsh->getColumnCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (xsh->getColumn(i)->isCamstandVisible())
|
|
Shinya Kitaoka |
120a6e |
if (connectedColumns.count(i) == 0)
|
|
Shinya Kitaoka |
120a6e |
getHooks(otherColumnsHooks, xsh, row, i, TPointD(1, 1)); // dpiScale);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
qDebug(" time=%dms", time.elapsed());
|
|
Shinya Kitaoka |
120a6e |
qDebug(" %d hooks (current column)", currentColumnHooks.size());
|
|
Shinya Kitaoka |
120a6e |
for(int i=0;i<(int)currentColumnHooks.size();i++)
|
|
Shinya Kitaoka |
120a6e |
qDebug("
|
|
Shinya Kitaoka |
120a6e |
%d,%d",currentColumnHooks[i].m_columnIndex,currentColumnHooks[i].m_hookId);
|
|
Shinya Kitaoka |
120a6e |
qDebug(" %d hooks (other columns)", otherColumnsHooks.size());
|
|
Shinya Kitaoka |
120a6e |
for(int i=0;i<(int)otherColumnsHooks.size();i++)
|
|
Shinya Kitaoka |
120a6e |
qDebug("
|
|
Shinya Kitaoka |
120a6e |
%d,%d",otherColumnsHooks[i].m_columnIndex,otherColumnsHooks[i].m_hookId);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<trectd> balloons;</trectd>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw current column hooks
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)currentColumnHooks.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
const HookData &hook = currentColumnHooks[i];
|
|
Shinya Kitaoka |
120a6e |
if (hook.m_name == "") continue; // should not happen
|
|
Shinya Kitaoka |
120a6e |
int code = TD_Hook + hook.m_hookId;
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = hook.m_pos;
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawHook(pos, ToolUtils::OtherLevelHook);
|
|
Shinya Kitaoka |
120a6e |
glPushName(code);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 color(200, 220, 205, 200);
|
|
Shinya Kitaoka |
120a6e |
if (hook.m_isPivot)
|
|
Shinya Kitaoka |
120a6e |
color = TPixel32(200, 200, 10, 200);
|
|
Shinya Kitaoka |
120a6e |
else if (code == m_device)
|
|
Shinya Kitaoka |
120a6e |
color = TPixel32(185, 255, 255);
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawBalloon(pos, hook.m_name, color, TPoint(20, 20), isPicking(),
|
|
Shinya Kitaoka |
120a6e |
&balloons);
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_parentProbeEnabled) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)otherColumnsHooks.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawHook(otherColumnsHooks[i].m_pos,
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::OtherLevelHook);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// search for magic links
|
|
Shinya Kitaoka |
120a6e |
double minDist2 = 0;
|
|
Shinya Kitaoka |
120a6e |
double snapRadius2 = 100 * getPixelSize() * getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
double snapRadius2bis = 100;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_parentProbeEnabled) {
|
|
Shinya Kitaoka |
120a6e |
// "static" magic links: no parent probe
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)currentColumnHooks.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)otherColumnsHooks.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
double dist2 =
|
|
Shinya Kitaoka |
120a6e |
norm2(currentColumnHooks[i].m_pos - otherColumnsHooks[j].m_pos);
|
|
Shinya Kitaoka |
120a6e |
if (currentColumnHooks[i].m_hookId == 0 ||
|
|
Shinya Kitaoka |
120a6e |
otherColumnsHooks[j].m_hookId == 0)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (dist2 < snapRadius2bis) {
|
|
Shinya Kitaoka |
120a6e |
m_magicLinks.push_back(
|
|
Shinya Kitaoka |
120a6e |
MagicLink(currentColumnHooks[i], otherColumnsHooks[j], dist2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
qDebug(" magic link_a %d (%d,%d) %d (%d,%d); dist=%f", i,
|
|
Shinya Kitaoka |
120a6e |
currentColumnHooks[i].m_columnIndex,
|
|
Shinya Kitaoka |
120a6e |
currentColumnHooks[i].m_hookId, j,
|
|
Shinya Kitaoka |
120a6e |
otherColumnsHooks[j].m_columnIndex,
|
|
Shinya Kitaoka |
120a6e |
otherColumnsHooks[j].m_hookId, dist2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_parentProbeEnabled) {
|
|
Shinya Kitaoka |
120a6e |
// search for the closest hook of the picked column
|
|
Shinya Kitaoka |
120a6e |
int i = -1, j = -1;
|
|
Shinya Kitaoka |
120a6e |
double minDist2 = snapRadius2;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)otherColumnsHooks.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
double dist2 = tdistance2(otherColumnsHooks[i].m_pos, m_parentProbe);
|
|
Shinya Kitaoka |
120a6e |
if (dist2 < minDist2) {
|
|
Shinya Kitaoka |
120a6e |
j = i;
|
|
Shinya Kitaoka |
120a6e |
minDist2 = dist2;
|
|
Shinya Kitaoka |
120a6e |
otherColumn = otherColumnsHooks[i].m_columnIndex;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_parentProbeEnabled && otherColumn >= 0) // && m_magicLinks.empty()
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// "dynamic" magic links: probing and picking a column
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// show image bounding box
|
|
Shinya Kitaoka |
120a6e |
m_otherColumn = otherColumn;
|
|
Shinya Kitaoka |
120a6e |
getImageBoundingBox(m_otherColumnBBox, m_otherColumnBBoxAff, row,
|
|
Shinya Kitaoka |
120a6e |
otherColumn);
|
|
Shinya Kitaoka |
120a6e |
if (!m_otherColumnBBox.isEmpty()) {
|
|
Toshihiro Shimizu |
890ddd |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(m_otherColumnBBoxAff);
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawRect(m_otherColumnBBox, TPixel32(188, 202, 191), 0xF0F0);
|
|
Shinya Kitaoka |
120a6e |
// tglDrawRect(img->getBBox());
|
|
Toshihiro Shimizu |
890ddd |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(row, otherColumn);
|
|
Shinya Kitaoka |
120a6e |
//TAffine aff = xsh->getPlacement(TStageObjectId::ColumnId(otherColumn),row);
|
|
Shinya Kitaoka |
120a6e |
//m_otherColumnAff = aff;
|
|
Shinya Kitaoka |
120a6e |
TImageP img = cell.getImage(false);
|
|
Shinya Kitaoka |
120a6e |
if(img)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
getImageBoundingBox(m_otherColumnBBox, m_otherColumnBBoxAff, row, otherColumn);
|
|
Shinya Kitaoka |
120a6e |
//glColor3d(188.0/255.0, 202.0/255.0, 191.0/255.0);
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(aff * imageDpiAff);
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawRect(img->getBBox(), TPixel32(188,202,191), 0xF0F0);
|
|
Shinya Kitaoka |
120a6e |
//tglDrawRect(img->getBBox());
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
// search for the closest hook of the picked column
|
|
Shinya Kitaoka |
120a6e |
int i = -1, j = -1;
|
|
Shinya Kitaoka |
120a6e |
double minDist2 = snapRadius2;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)otherColumnsHooks.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (otherColumnsHooks[i].m_columnIndex == otherColumn) {
|
|
Shinya Kitaoka |
120a6e |
double dist2 = tdistance2(otherColumnsHooks[i].m_pos, m_parentProbe);
|
|
Shinya Kitaoka |
120a6e |
if (j < 0)
|
|
Shinya Kitaoka |
120a6e |
j = i;
|
|
Shinya Kitaoka |
120a6e |
else if (dist2 < minDist2 || otherColumnsHooks[i].m_hookId == 0) {
|
|
Shinya Kitaoka |
120a6e |
j = i;
|
|
Shinya Kitaoka |
120a6e |
minDist2 = dist2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// visualize a balloon for the closest hook
|
|
Shinya Kitaoka |
120a6e |
if (0 <= j && j < (int)otherColumnsHooks.size()) {
|
|
Shinya Kitaoka |
120a6e |
// I want to get a specific color when overlaying the label on white
|
|
Shinya Kitaoka |
120a6e |
int alfa = 100, ialfa = 255 - alfa;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 color(255 * (188 - ialfa) / alfa, 255 * (202 - ialfa) / alfa,
|
|
Shinya Kitaoka |
120a6e |
255 * (191 - ialfa) / alfa, alfa);
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawBalloon(otherColumnsHooks[j].m_pos,
|
|
Shinya Kitaoka |
120a6e |
otherColumnsHooks[j].m_name, // getHandle(),
|
|
Shinya Kitaoka |
120a6e |
color, TPoint(20, 20), false, &balloons);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
HookData baseHook = currentColumnHooks[0];
|
|
Shinya Kitaoka |
120a6e |
baseHook.m_pos = otherColumnsHooks[j].m_pos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// this is also a magic link
|
|
Shinya Kitaoka |
120a6e |
m_magicLinks.push_back(MagicLink(baseHook, otherColumnsHooks[j], 10000));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// visualize all the magic links
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_magicLinks.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
const MagicLink &magicLink = m_magicLinks[i];
|
|
Shinya Kitaoka |
120a6e |
const HookData &h1 = magicLink.m_h1;
|
|
Shinya Kitaoka |
120a6e |
std::string name;
|
|
Shinya Kitaoka |
120a6e |
name = (m_parentProbeEnabled ? "Linking " : "Link ") +
|
|
Shinya Kitaoka |
120a6e |
removeTrailingH(magicLink.m_h0.getHandle()) + " to Col " +
|
|
Shinya Kitaoka |
120a6e |
std::to_string(h1.m_columnIndex + 1) + "/" +
|
|
Shinya Kitaoka |
120a6e |
removeTrailingH(h1.getHandle());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int code = TD_MagicLink + i;
|
|
Shinya Kitaoka |
120a6e |
glPushName(code);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 color(100, 255, 100, 100);
|
|
Shinya Kitaoka |
120a6e |
if (code == m_device) color = TPixel32(185, 255, 255);
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawBalloon(magicLink.m_h0.m_pos, name, color, TPoint(20, -20),
|
|
Shinya Kitaoka |
120a6e |
isPicking(), &balloons);
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawDrawingBrowser(const TXshCell &cell,
|
|
Shinya Kitaoka |
120a6e |
const TPointD ¢er) {
|
|
Shinya Kitaoka |
120a6e |
if (!cell.m_level || cell.m_level->getFrameCount() <= 1) return;
|
|
Shinya Kitaoka |
120a6e |
double pixelSize = getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string name = ::to_string(cell.m_level->getName()) + "." +
|
|
Shinya Kitaoka |
120a6e |
std::to_string(cell.m_frameId.getNumber());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QString qText = QString::fromStdString(name);
|
|
Shinya Kitaoka |
120a6e |
QFont font("Arial", 10); // ,QFont::Bold);
|
|
Shinya Kitaoka |
120a6e |
QFontMetrics fm(font);
|
|
Shinya Kitaoka |
120a6e |
QSize textSize = fm.boundingRect(qText).size();
|
|
Shinya Kitaoka |
120a6e |
int arrowHeight = 10;
|
|
Shinya Kitaoka |
120a6e |
int minTextWidth = 2 * arrowHeight + 5;
|
|
Shinya Kitaoka |
120a6e |
if (textSize.width() < minTextWidth) textSize.setWidth(minTextWidth);
|
|
Shinya Kitaoka |
120a6e |
QSize totalSize(textSize.width(), textSize.height() + 2 * arrowHeight);
|
|
Shinya Kitaoka |
120a6e |
TPointD p = center + TPointD(30, -arrowHeight) * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
QRect textRect(0, arrowHeight, textSize.width(), textSize.height());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isPicking()) {
|
|
Shinya Kitaoka |
120a6e |
double x0 = p.x, x1 = p.x + totalSize.width() * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
double y0 = p.y, y3 = p.y + totalSize.height() * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
double y1 = y0 + arrowHeight * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
double y2 = y3 - arrowHeight * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
double x = (x0 + x1) * 0.5;
|
|
Shinya Kitaoka |
120a6e |
double d = arrowHeight * pixelSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0, 1, 0);
|
|
Shinya Kitaoka |
120a6e |
glPushName(TD_ChangeDrawing);
|
|
Shinya Kitaoka |
120a6e |
glRectd(x0, y1, x1, y2);
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
glPushName(TD_IncrementDrawing);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_POLYGON);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(x, y0);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(x + d, y0 + d);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(x - d, y0 + d);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
glPushName(TD_DecrementDrawing);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_POLYGON);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(x, y3);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(x + d, y3 - d);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(x - d, y3 - d);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == 0);
|
|
Shinya Kitaoka |
120a6e |
bool active = m_device == TD_ChangeDrawing ||
|
|
Shinya Kitaoka |
120a6e |
m_device == TD_IncrementDrawing ||
|
|
Shinya Kitaoka |
120a6e |
m_device == TD_DecrementDrawing;
|
|
Shinya Kitaoka |
120a6e |
QImage img(totalSize.width(), totalSize.height(), QImage::Format_ARGB32);
|
|
Shinya Kitaoka |
120a6e |
img.fill(Qt::transparent);
|
|
Shinya Kitaoka |
120a6e |
QPainter imgPainter(&img);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setRenderHints(QPainter::Antialiasing |
|
|
Shinya Kitaoka |
120a6e |
QPainter::TextAntialiasing);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// imgPainter.setPen(Qt::black);
|
|
Shinya Kitaoka |
120a6e |
// imgPainter.drawRect(0,0,totalSize.width(),totalSize.height());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setPen(Qt::NoPen);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setBrush(QColor(200, 200, 200, 200));
|
|
Shinya Kitaoka |
120a6e |
imgPainter.drawRect(textRect);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setPen(active ? Qt::red : Qt::black);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setFont(font);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.drawText(textRect, Qt::AlignCenter, qText);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (active) {
|
|
Shinya Kitaoka |
120a6e |
int x = textRect.center().x();
|
|
Shinya Kitaoka |
120a6e |
int d = arrowHeight - 4;
|
|
Shinya Kitaoka |
120a6e |
int y = 0;
|
|
Shinya Kitaoka |
120a6e |
QPainterPath upArrow;
|
|
Shinya Kitaoka |
120a6e |
upArrow.moveTo(x, y);
|
|
Shinya Kitaoka |
120a6e |
upArrow.lineTo(x + d, y + d);
|
|
Shinya Kitaoka |
120a6e |
upArrow.lineTo(x - d, y + d);
|
|
Shinya Kitaoka |
120a6e |
upArrow.lineTo(x, y);
|
|
Shinya Kitaoka |
120a6e |
y = totalSize.height() - 1;
|
|
Shinya Kitaoka |
120a6e |
QPainterPath dnArrow;
|
|
Shinya Kitaoka |
120a6e |
dnArrow.moveTo(x, y);
|
|
Shinya Kitaoka |
120a6e |
dnArrow.lineTo(x + d, y - d);
|
|
Shinya Kitaoka |
120a6e |
dnArrow.lineTo(x - d, y - d);
|
|
Shinya Kitaoka |
120a6e |
dnArrow.lineTo(x, y);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setPen(Qt::NoPen);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setBrush(m_device == TD_DecrementDrawing
|
|
Shinya Kitaoka |
120a6e |
? QColor(255, 0, 0)
|
|
Shinya Kitaoka |
120a6e |
: QColor(200, 100, 100));
|
|
Shinya Kitaoka |
120a6e |
imgPainter.drawPath(upArrow);
|
|
Shinya Kitaoka |
120a6e |
imgPainter.setBrush(m_device == TD_IncrementDrawing
|
|
Shinya Kitaoka |
120a6e |
? QColor(255, 0, 0)
|
|
Shinya Kitaoka |
120a6e |
: QColor(200, 100, 100));
|
|
Shinya Kitaoka |
120a6e |
imgPainter.drawPath(dnArrow);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QImage texture = QGLWidget::convertToGLFormat(img);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glRasterPos2f(p.x, p.y);
|
|
Shinya Kitaoka |
120a6e |
// glBitmap(0,0,0,0, 0,-size.height()+(y+delta.y), NULL); //
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
glDrawPixels(texture.width(), texture.height(), GL_RGBA, GL_UNSIGNED_BYTE,
|
|
Shinya Kitaoka |
120a6e |
texture.bits());
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::drawMainGadget(const TPointD ¢er) {
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == GL_NO_ERROR);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double r = 10 * getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
double cx = center.x + r * 1.1;
|
|
Shinya Kitaoka |
120a6e |
double cy = center.y - r * 1.1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(1, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isPicking()) {
|
|
Shinya Kitaoka |
120a6e |
glPushName(TD_Translation);
|
|
Shinya Kitaoka |
120a6e |
tglDrawDisk(TPointD(cx, cy), getPixelSize() * 9);
|
|
Shinya Kitaoka |
120a6e |
glPopName();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QImage img(19, 19, QImage::Format_ARGB32);
|
|
Shinya Kitaoka |
120a6e |
img.fill(Qt::transparent);
|
|
Shinya Kitaoka |
120a6e |
QPainter p(&img);
|
|
Shinya Kitaoka |
120a6e |
// p.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QPainterPath pp;
|
|
Shinya Kitaoka |
120a6e |
int dx = 1, dy = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < 4; i++) {
|
|
Shinya Kitaoka |
120a6e |
int x = 9 + dx * 8;
|
|
Shinya Kitaoka |
120a6e |
int y = 9 + dy * 8;
|
|
Shinya Kitaoka |
120a6e |
pp.moveTo(9, 9);
|
|
Shinya Kitaoka |
120a6e |
pp.lineTo(x, y);
|
|
Shinya Kitaoka |
120a6e |
pp.lineTo(x - 2 * dx - 2 * dy, y - 2 * dy + 2 * dx);
|
|
Shinya Kitaoka |
120a6e |
pp.moveTo(x, y);
|
|
Shinya Kitaoka |
120a6e |
pp.lineTo(x - 2 * dx + 2 * dy, y - 2 * dy - 2 * dx);
|
|
Shinya Kitaoka |
120a6e |
int d = dx;
|
|
Shinya Kitaoka |
120a6e |
dx = -dy;
|
|
Shinya Kitaoka |
120a6e |
dy = d;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p.setPen(QPen(Qt::white, 3));
|
|
Shinya Kitaoka |
120a6e |
p.drawPath(pp);
|
|
Shinya Kitaoka |
120a6e |
p.setPen(Qt::black);
|
|
Shinya Kitaoka |
120a6e |
p.drawPath(pp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p.setBrush(QColor(54, 213, 54));
|
|
Shinya Kitaoka |
120a6e |
p.drawRect(6, 6, 6, 6);
|
|
Shinya Kitaoka |
120a6e |
QImage texture = QGLWidget::convertToGLFormat(img);
|
|
Shinya Kitaoka |
120a6e |
// texture.save("c:\\urka.png");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glRasterPos2f(center.x + r * 1.1, center.y - r * 1.1);
|
|
Shinya Kitaoka |
120a6e |
glBitmap(0, 0, 0, 0, -9, -9, NULL);
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
glDrawPixels(texture.width(), texture.height(), GL_RGBA, GL_UNSIGNED_BYTE,
|
|
Shinya Kitaoka |
120a6e |
texture.bits());
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == GL_NO_ERROR);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::draw() {
|
|
Shinya Kitaoka |
120a6e |
// parent object reference system
|
|
Shinya Kitaoka |
120a6e |
// glColor3d(1,0,0);
|
|
Shinya Kitaoka |
120a6e |
// tglDrawRect(0,0,100,100);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_label != "")
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawBalloon(m_labelPos, m_label, TPixel32::Red, TPoint(20, -20),
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS;
|
|
Shinya Kitaoka |
120a6e |
assert(glGetError() == GL_NO_ERROR);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// l'xsheet, oggetto (e relativo placement), frame corrente
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = getXsheet();
|
|
Shinya Kitaoka |
120a6e |
assert(xsh);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = app->getCurrentObject()->getObjectId();
|
|
Shinya Kitaoka |
120a6e |
// se l'oggetto corrente non e' una colonna non disegno nulla
|
|
Shinya Kitaoka |
120a6e |
if (!objId.isColumn()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = xsh->getStageObject(objId);
|
|
Shinya Kitaoka |
120a6e |
int col = objId.getIndex();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int frame = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
if (m_currentFrame != frame) m_temporaryPinnedColumns.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = getMatrix();
|
|
Shinya Kitaoka |
120a6e |
// puo' suggere che il placement degeneri (es.: c'e' uno h-scale = 0%)
|
|
Shinya Kitaoka |
120a6e |
if (fabs(aff.det()) < 0.00001) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// m_unit = getPixelSize() * sqrt(fabs(aff.det()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!ikEnabled) drawLevelBoundingBox(frame, col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(aff.inv());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// camera stand reference system
|
|
Shinya Kitaoka |
120a6e |
// glColor3d(0,1,0);
|
|
Shinya Kitaoka |
120a6e |
// tglDrawRect(0,0,100,100);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool changingParent = dynamic_cast<parentchangetool *="">(m_dragTool) != 0;</parentchangetool>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// !changingParent &&
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getValue() == BUILD_SKELETON &&
|
|
Shinya Kitaoka |
120a6e |
!xsh->getStageObjectParent(objId).isColumn()) {
|
|
Shinya Kitaoka |
120a6e |
if (!changingParent) drawHooks();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Skeleton skeleton;
|
|
Shinya Kitaoka |
120a6e |
buildSkeleton(skeleton, col);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
drawSkeleton(skeleton, frame);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = xsh->getCell(frame, objId.getIndex());
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *rootBone = skeleton.getRootBone();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < skeleton.getBoneCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton::Bone *bone = skeleton.getBone(i);
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId currentId = bone->getStageObject()->getId();
|
|
Shinya Kitaoka |
120a6e |
bool isCurrent = (currentId == objId);
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = bone->getCenter();
|
|
Shinya Kitaoka |
120a6e |
if (isCurrent && m_mode.getValue() != BUILD_SKELETON) {
|
|
Shinya Kitaoka |
120a6e |
drawDrawingBrowser(cell, pos);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isActiveChain = bone->isSelected();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0, 1, 0);
|
|
Shinya Kitaoka |
120a6e |
if (ikEnabled) {
|
|
Shinya Kitaoka |
120a6e |
drawIKJoint(bone);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = bone->getCenter();
|
|
Shinya Kitaoka |
120a6e |
if (isCurrent && m_mode.getValue() == ANIMATE) {
|
|
Shinya Kitaoka |
120a6e |
drawMainGadget(pos);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_currentFrame = frame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) m_dragTool->draw();
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::onActivate() {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
if (m_firstTime) {
|
|
Shinya Kitaoka |
120a6e |
m_globalKeyframes.setValue(SkeletonGlobalKeyFrame ? 1 : 0);
|
|
Shinya Kitaoka |
120a6e |
m_mode.setValue(BUILD_SKELETON);
|
|
Shinya Kitaoka |
120a6e |
// m_ikEnabled.setValue(SkeletonInverseKinematics ? 1 : 0);
|
|
Shinya Kitaoka |
120a6e |
m_firstTime = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objId = app->getCurrentObject()->getObjectId();
|
|
Shinya Kitaoka |
120a6e |
if (objId == TStageObjectId::NoneId) {
|
|
Shinya Kitaoka |
120a6e |
int index = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
objId = TStageObjectId::ColumnId(index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// app->editStageObject(objId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::onDeactivate() {
|
|
Shinya Kitaoka |
120a6e |
// m_selection.selectNone();
|
|
Shinya Kitaoka |
120a6e |
// TSelection::setCurrent(0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SkeletonSubtools::MagicLink SkeletonTool::getMagicLink(int index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(0 <= index && index < (int)m_magicLinks.size());
|
|
Shinya Kitaoka |
120a6e |
return m_magicLinks[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::magicLink(int index) {
|
|
Shinya Kitaoka |
120a6e |
if (index < 0 || index >= (int)m_magicLinks.size()) return;
|
|
Shinya Kitaoka |
120a6e |
HookData h0 = m_magicLinks[index].m_h0;
|
|
Shinya Kitaoka |
120a6e |
HookData h1 = m_magicLinks[index].m_h1;
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
int columnIndex = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = TStageObjectId::ColumnId(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj = xsh->getStageObject(id);
|
|
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 |
|
|
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::setHandle(id, handle, app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
TStageObjectCmd::setParent(id, parentId, parentHandle,
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet());
|
|
Shinya Kitaoka |
120a6e |
// undoManager->endBlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int SkeletonTool::getCursorId() const {
|
|
Shinya Kitaoka |
120a6e |
switch (m_device) {
|
|
Shinya Kitaoka |
120a6e |
case TD_None:
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getValue() == BUILD_SKELETON)
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return ToolCursor::RotCursor;
|
|
Shinya Kitaoka |
120a6e |
case TD_Translation:
|
|
Shinya Kitaoka |
120a6e |
return ToolCursor::MoveCursor;
|
|
Shinya Kitaoka |
120a6e |
case TD_Rotation:
|
|
Shinya Kitaoka |
120a6e |
return ToolCursor::RotCursor;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
return ToolCursor::StrokeSelectCursor;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return ToolCursor::StrokeSelectCursor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::addContextMenuItems(QMenu *menu) {
|
|
Shinya Kitaoka |
120a6e |
bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ikEnabled) {
|
|
Shinya Kitaoka |
120a6e |
Skeleton *skeleton = new Skeleton();
|
|
Shinya Kitaoka |
120a6e |
buildSkeleton(
|
|
Shinya Kitaoka |
120a6e |
*skeleton,
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentColumn()->getColumnIndex());
|
|
Shinya Kitaoka |
120a6e |
if (skeleton->hasPinnedRanges() || skeleton->isIKEnabled()) {
|
|
Shinya Kitaoka |
120a6e |
m_commandHandler->setSkeleton(skeleton);
|
|
Shinya Kitaoka |
120a6e |
QAction *rp = menu->addAction(tr("Reset Pinned Center"));
|
|
Shinya Kitaoka |
120a6e |
menu->addSeparator();
|
|
Shinya Kitaoka |
120a6e |
bool ret = QObject::connect(rp, SIGNAL(triggered()), m_commandHandler,
|
|
Shinya Kitaoka |
120a6e |
SLOT(clearPinnedRanges()));
|
|
Shinya Kitaoka |
120a6e |
assert(ret);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
delete skeleton;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void SkeletonTool::buildSkeleton(Skeleton &skeleton, int columnIndex) {
|
|
Shinya Kitaoka |
120a6e |
int frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
skeleton.build(getXsheet(), frame, columnIndex, m_temporaryPinnedColumns);
|
|
Toshihiro Shimizu |
890ddd |
}
|