Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjecttree.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectspline.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/observer.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcamera.h"
Toshihiro Shimizu 890ddd
#include "toonz/doubleparamcmd.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpinnedrangeset.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzExt includes
Toshihiro Shimizu 890ddd
#include "ext/plasticskeleton.h"
Toshihiro Shimizu 890ddd
#include "ext/plasticskeletondeformation.h"
Toshihiro Shimizu 890ddd
#include "ext/plasticdeformerstorage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tconst.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qmetaobject></qmetaobject>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <fstream></fstream>
Toshihiro Shimizu 890ddd
#include <set></set>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Per un problema su alcune macchine, solo Release.
Toshihiro Shimizu 890ddd
// il problema si verifica ruotando gli oggetti sul camera stand
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
e280ae
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#pragma optimize("", off)
Toshihiro Shimizu 890ddd
#endif
Campbell Barton b3bd84
static TAffine makeRotation(double ang) { return TRotation(ang); }
e280ae
#ifdef _MSC_VER
Toshihiro Shimizu 890ddd
#pragma optimize("", on)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TStageObject, 102)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
enum StageObjectType {
Shinya Kitaoka 120a6e
  NONE   = 0,
Shinya Kitaoka 120a6e
  CAMERA = 1,
Shinya Kitaoka 120a6e
  TABLE  = 2,
Shinya Kitaoka 120a6e
  PEGBAR = 5,
Shinya Kitaoka 120a6e
  COLUMN = 6
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int StageObjectTypeShift = 28;
Shinya Kitaoka 120a6e
const int StageObjectMaxIndex  = ((1 << StageObjectTypeShift) - 1);
Toshihiro Shimizu 890ddd
const int StageObjectIndexMask = ((1 << StageObjectTypeShift) - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    TStageObjectParams  implementation
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectParams::TStageObjectParams() : m_spline(0), m_noScaleZ(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStageObjectParams::TStageObjectParams(TStageObjectParams *data)
Shinya Kitaoka 120a6e
    : m_id(data->m_id)
Shinya Kitaoka 120a6e
    , m_parentId(data->m_parentId)
Shinya Kitaoka 120a6e
    , m_children(data->m_children)
Shinya Kitaoka 120a6e
    , m_keyframes(data->m_keyframes)
Shinya Kitaoka 120a6e
    , m_cycleEnabled(data->m_cycleEnabled)
Shinya Kitaoka 120a6e
    , m_spline(data->m_spline)
Shinya Kitaoka 120a6e
    , m_status(data->m_status)
Shinya Kitaoka 120a6e
    , m_handle(data->m_handle)
Shinya Kitaoka 120a6e
    , m_parentHandle(data->m_parentHandle)
Shinya Kitaoka 120a6e
    , m_x(data->m_x)
Shinya Kitaoka 120a6e
    , m_y(data->m_y)
Shinya Kitaoka 120a6e
    , m_z(data->m_z)
Shinya Kitaoka 120a6e
    , m_so(data->m_so)
Shinya Kitaoka 120a6e
    , m_rot(data->m_rot)
Shinya Kitaoka 120a6e
    , m_scalex(data->m_scalex)
Shinya Kitaoka 120a6e
    , m_scaley(data->m_scaley)
Shinya Kitaoka 120a6e
    , m_scale(data->m_scale)
Shinya Kitaoka 120a6e
    , m_posPath(data->m_posPath)
Shinya Kitaoka 120a6e
    , m_shearx(data->m_shearx)
Shinya Kitaoka 120a6e
    , m_sheary(data->m_sheary)
Shinya Kitaoka 120a6e
    , m_skeletonDeformation(data->m_skeletonDeformation)
Shinya Kitaoka 120a6e
    , m_noScaleZ(data->m_noScaleZ)
Shinya Kitaoka 120a6e
    , m_center(data->m_center)
Shinya Kitaoka 120a6e
    , m_offset(data->m_offset)
Shinya Kitaoka 120a6e
    , m_name(data->m_name)
Shinya Kitaoka 120a6e
    , m_isOpened(data->m_isOpened)
Shinya Kitaoka 120a6e
    , m_pinnedRangeSet(data->m_pinnedRangeSet->clone()) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectParams::~TStageObjectParams() { delete m_pinnedRangeSet; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectParams *TStageObjectParams::clone() {
Shinya Kitaoka 120a6e
  return new TStageObjectParams(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===========================================================================
Toshihiro Shimizu 890ddd
// Utility Functions
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectId toStageObjectId(string s) {
Shinya Kitaoka 120a6e
  if (s == "None")
Shinya Kitaoka 120a6e
    return TStageObjectId::NoneId;
Shinya Kitaoka 120a6e
  else if (s == "Table")
Shinya Kitaoka 120a6e
    return TStageObjectId::TableId;
Shinya Kitaoka 120a6e
  else if (isInt(s)) {
Shinya Kitaoka 120a6e
    TStageObjectId id;
Shinya Kitaoka 120a6e
    id.setCode(std::stoi(s));
Shinya Kitaoka 120a6e
    return id;
Shinya Kitaoka 120a6e
  } else if (s.length() > 3) {
Shinya Kitaoka 120a6e
    if (s.substr(0, 3) == "Col")
Shinya Kitaoka 120a6e
      return TStageObjectId::ColumnId(std::stoi(s.substr(3)) - 1);
Shinya Kitaoka 120a6e
    else if (s.substr(0, 3) == "Peg")
Shinya Kitaoka 120a6e
      return TStageObjectId::PegbarId(std::stoi(s.substr(3)) - 1);
Shinya Kitaoka 120a6e
    else if (s.length() > 6 && s.substr(0, 6) == "Camera")
Shinya Kitaoka 120a6e
      return TStageObjectId::CameraId(std::stoi(s.substr(6)) - 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return TStageObjectId::NoneId;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
ostream &operator<<(ostream &out, const TStageObjectId &id) {
Shinya Kitaoka 120a6e
  return out << id.toString();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    TStageObjectId  implementation
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStageObjectId::TStageObjectId() : m_id(NONE << StageObjectTypeShift) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStageObjectId::~TStageObjectId() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObjectId::isCamera() const {
Shinya Kitaoka 120a6e
  return m_id >> StageObjectTypeShift == CAMERA;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObjectId::isTable() const {
Shinya Kitaoka 120a6e
  return m_id >> StageObjectTypeShift == TABLE;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObjectId::isPegbar() const {
Shinya Kitaoka 120a6e
  return m_id >> StageObjectTypeShift == PEGBAR;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObjectId::isColumn() const {
Shinya Kitaoka 120a6e
  return m_id >> StageObjectTypeShift == COLUMN;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TStageObjectId TStageObjectId::NoneId(NONE << StageObjectTypeShift);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TStageObjectId TStageObjectId::TableId(TABLE << StageObjectTypeShift);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TStageObjectId TStageObjectId::CameraId(int index) {
Shinya Kitaoka 120a6e
  assert(0 <= index && index <= StageObjectMaxIndex);
Shinya Kitaoka 120a6e
  return TStageObjectId(CAMERA << StageObjectTypeShift | index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TStageObjectId TStageObjectId::PegbarId(int index) {
Shinya Kitaoka 120a6e
  assert(0 <= index && index <= StageObjectMaxIndex);
Shinya Kitaoka 120a6e
  return TStageObjectId(PEGBAR << StageObjectTypeShift | index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TStageObjectId TStageObjectId::ColumnId(int index) {
Shinya Kitaoka 120a6e
  assert(0 <= index && index <= StageObjectMaxIndex);
Shinya Kitaoka 120a6e
  return TStageObjectId(COLUMN << StageObjectTypeShift | index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
string TStageObjectId::toString() const {
Shinya Kitaoka 120a6e
  int index = m_id & StageObjectIndexMask;
Shinya Kitaoka 120a6e
  string shortName;
Shinya Kitaoka 120a6e
  switch (m_id >> StageObjectTypeShift) {
Shinya Kitaoka 120a6e
  case NONE:
Shinya Kitaoka 120a6e
    shortName = "None";
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case CAMERA:
Shinya Kitaoka 120a6e
    shortName = "Camera" + std::to_string(index + 1);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TABLE:
Shinya Kitaoka 120a6e
    shortName = "Table";
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case PEGBAR:
Shinya Kitaoka 120a6e
    shortName = "Peg" + std::to_string(index + 1);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case COLUMN:
Shinya Kitaoka 120a6e
    shortName = "Col" + std::to_string(index + 1);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    shortName = "BadPegbar";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return shortName;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
int TStageObjectId::getIndex() const { return m_id & StageObjectIndexMask; }
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {  // TStageObject Utility
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TDoubleKeyframe withFrame(TDoubleKeyframe k, double frame) {
Shinya Kitaoka 120a6e
  k.m_frame = frame;
Shinya Kitaoka 120a6e
  return k;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool setKeyframe(const TDoubleParamP ¶m, const TDoubleKeyframe &kf,
Shinya Kitaoka 120a6e
                 int frame, const double &easeIn, const double &easeOut) {
Shinya Kitaoka 120a6e
  if (!kf.m_isKeyframe) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDoubleKeyframe kfCopy = kf;
Toshihiro Shimizu 890ddd
shun-iwasawa 641c8e
  kfCopy.m_frame = frame;
shun-iwasawa 641c8e
  if (easeIn >= 0.0) kfCopy.m_speedIn = TPointD(-easeIn, kfCopy.m_speedIn.y);
Shinya Kitaoka 120a6e
  if (easeOut >= 0.0) kfCopy.m_speedOut = TPointD(easeOut, kfCopy.m_speedOut.y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  param->setKeyframe(kfCopy);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void setkey(const TDoubleParamP ¶m, int frame) {
Shinya Kitaoka 120a6e
  KeyframeSetter setter(param.getPointer(), -1, false);
Shinya Kitaoka 120a6e
  setter.createKeyframe(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void updateUnit(TDoubleParam *param) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < param->getKeyframeCount(); i++) {
Shinya Kitaoka 120a6e
    TDoubleKeyframe k = param->getKeyframe(i);
Shinya Kitaoka 120a6e
    k.m_value /= Stage::inch;
Shinya Kitaoka 120a6e
    param->setKeyframe(i, k);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
string convertTo4InchCenterUnits(string handle) {
Shinya Kitaoka 120a6e
  // per convenzione un handle del tipo 'a'..'z' utilizza
Shinya Kitaoka 120a6e
  // la vecchia convenzione per i centri (4 inch invece di 8)
Shinya Kitaoka 120a6e
  if (handle.length() == 1 && 'A' <= handle[0] && handle[0] <= 'Z' &&
Shinya Kitaoka 120a6e
      handle[0] != 'B')
Shinya Kitaoka 120a6e
    return string(1, handle[0] + 'a' - 'A');
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return handle;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD updateDagPosition(const TPointD &pos, const VersionNumber &tnzVersion) {
Shinya Kitaoka 120a6e
  if (tnzVersion < VersionNumber(1, 16)) return TConst::nowhere;
Shinya Kitaoka 120a6e
  return pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Update the passed stage object keyframe and keyframe type specification with
Toshihiro Shimizu 890ddd
// a new keyframe. Returns true if specifications match, false otherwise.
Toshihiro Shimizu 890ddd
bool touchEaseAndCompare(const TDoubleKeyframe &kf,
Shinya Kitaoka 120a6e
                         TStageObject::Keyframe &stageKf,
Shinya Kitaoka 120a6e
                         TDoubleKeyframe::Type &type) {
Shinya Kitaoka 120a6e
  bool initialization = (type == TDoubleKeyframe::None);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (initialization) type = kf.m_type;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (kf.m_type != type || (kf.m_type != TDoubleKeyframe::SpeedInOut &&
Shinya Kitaoka 120a6e
                            kf.m_type != TDoubleKeyframe::EaseInOut &&
Shinya Kitaoka 120a6e
                            (kf.m_prevType != TDoubleKeyframe::None &&
Shinya Kitaoka 120a6e
                             kf.m_prevType != TDoubleKeyframe::SpeedInOut &&
Shinya Kitaoka 120a6e
                             kf.m_prevType != TDoubleKeyframe::EaseInOut))) {
Shinya Kitaoka 120a6e
    stageKf.m_easeIn  = -1.0;
Shinya Kitaoka 120a6e
    stageKf.m_easeOut = -1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double easeIn = -kf.m_speedIn.x;
Shinya Kitaoka 120a6e
  if (initialization)
Shinya Kitaoka 120a6e
    stageKf.m_easeIn = easeIn;
Shinya Kitaoka 120a6e
  else if (stageKf.m_easeIn != easeIn)
Shinya Kitaoka 120a6e
    stageKf.m_easeIn = -1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double easeOut = kf.m_speedOut.x;
Shinya Kitaoka 120a6e
  if (initialization)
Shinya Kitaoka 120a6e
    stageKf.m_easeOut = easeOut;
Shinya Kitaoka 120a6e
  else if (stageKf.m_easeOut != easeOut)
Shinya Kitaoka 120a6e
    stageKf.m_easeOut = -1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    TStageObject::LazyData  implementation
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject::LazyData::LazyData() : m_time(-1.0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    TStageObject  implementation
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStageObject::TStageObject(TStageObjectTree *tree, TStageObjectId id)
Shinya Kitaoka 120a6e
    : m_tree(tree)
Shinya Kitaoka 120a6e
    , m_id(id)
Shinya Kitaoka 120a6e
    , m_parent(0)
Shinya Kitaoka 120a6e
    , m_name("")
Shinya Kitaoka 120a6e
    , m_isOpened(false)
Shinya Kitaoka 120a6e
    , m_spline(0)
Shinya Kitaoka 120a6e
    , m_status(XY)
Shinya Kitaoka 120a6e
    , m_x(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_y(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_z(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_so(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_rot(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_scalex(new TDoubleParam(1.0))
Shinya Kitaoka 120a6e
    , m_scaley(new TDoubleParam(1.0))
Shinya Kitaoka 120a6e
    , m_scale(new TDoubleParam(1.0))
Shinya Kitaoka 120a6e
    , m_posPath(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_shearx(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_sheary(new TDoubleParam())
Shinya Kitaoka 120a6e
    , m_center()
Shinya Kitaoka 120a6e
    , m_offset()
Shinya Kitaoka 120a6e
    , m_cycleEnabled(false)
Shinya Kitaoka 120a6e
    , m_handle("B")
Shinya Kitaoka 120a6e
    , m_parentHandle("B")
Shinya Kitaoka 120a6e
    , m_dagNodePos(TConst::nowhere)
Shinya Kitaoka 120a6e
    , m_camera(0)
Shinya Kitaoka 120a6e
    , m_locked(false)
Shinya Kitaoka 120a6e
    , m_noScaleZ(0)
Shinya Kitaoka 120a6e
    , m_pinnedRangeSet(0)
Shinya Kitaoka 120a6e
    , m_ikflag(0)
Shinya Kitaoka 120a6e
    , m_groupSelector(-1) {
Shinya Kitaoka 120a6e
  // NOTA: per le unita' di misura controlla anche tooloptions.cpp
c7649c
  m_x->setName("W_X");
Shinya Kitaoka 120a6e
  m_x->setMeasureName("length.x");
Shinya Kitaoka 120a6e
  m_x->addObserver(this);
Shinya Kitaoka 120a6e
c7649c
  m_y->setName("W_Y");
Shinya Kitaoka 120a6e
  m_y->setMeasureName("length.y");
Shinya Kitaoka 120a6e
  m_y->addObserver(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_z->setName("W_Z");
Shinya Kitaoka 120a6e
  m_z->setMeasureName(id.isCamera() ? "zdepth.cam" : "zdepth");
Shinya Kitaoka 120a6e
  m_z->addObserver(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_so->setName("W_SO");
Shinya Kitaoka 120a6e
  m_so->addObserver(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_rot->setName("W_Rotation");
Shinya Kitaoka 120a6e
  m_rot->setMeasureName("angle");
Shinya Kitaoka 120a6e
  m_rot->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_scalex->setName("W_ScaleH");
Shinya Kitaoka 120a6e
  m_scalex->setMeasureName("scale");
Shinya Kitaoka 120a6e
  m_scalex->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_scaley->setName("W_ScaleV");
Shinya Kitaoka 120a6e
  m_scaley->setMeasureName("scale");
Shinya Kitaoka 120a6e
  m_scaley->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_scale->setName("W_Scale");
Shinya Kitaoka 120a6e
  m_scale->setMeasureName("scale");
Shinya Kitaoka 120a6e
  m_scale->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_shearx->setName("W_ShearH");
Shinya Kitaoka 120a6e
  m_shearx->setMeasureName("shear");
Shinya Kitaoka 120a6e
  m_shearx->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_sheary->setName("W_ShearV");
Shinya Kitaoka 120a6e
  m_sheary->setMeasureName("shear");
Shinya Kitaoka 120a6e
  m_sheary->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_posPath->setName("posPath");
Shinya Kitaoka 120a6e
  m_posPath->setMeasureName("percentage2");
Shinya Kitaoka 120a6e
  m_posPath->addObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_x);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_y);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_z);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_so);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_rot);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_scalex);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_scaley);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_scale);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_shearx);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_sheary);
Shinya Kitaoka 120a6e
  m_tree->setGrammar(m_posPath);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (id.isCamera()) m_camera = new TCamera();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_pinnedRangeSet = new TPinnedRangeSet();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject::~TStageObject() {
Shinya Kitaoka 120a6e
  if (m_spline) {
Shinya Kitaoka 120a6e
    if (m_posPath) m_spline->removeParam(m_posPath.getPointer());
Shinya Kitaoka 120a6e
    m_spline->release();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_x) m_x->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_y) m_y->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_z) m_z->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_so) m_so->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_rot) m_rot->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_scalex) m_scalex->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_scaley) m_scaley->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_scale) m_scale->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_shearx) m_shearx->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_sheary) m_sheary->removeObserver(this);
Shinya Kitaoka 120a6e
  if (m_posPath) m_posPath->removeObserver(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation) {
Shinya Kitaoka 120a6e
    PlasticDeformerStorage::instance()->releaseDeformationData(
Shinya Kitaoka 120a6e
        m_skeletonDeformation.getPointer());
Shinya Kitaoka 120a6e
    m_skeletonDeformation->removeObserver(this);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  delete m_camera;
Shinya Kitaoka 120a6e
  delete m_pinnedRangeSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TStageObject::LazyData &TStageObject::lazyData() const {
otakuto 91a93e
  return m_lazyData([this](LazyData &ld) { this->update(ld); });
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject::LazyData &TStageObject::lazyData() {
Shinya Kitaoka 120a6e
  return const_cast<lazydata &="">(</lazydata>
Shinya Kitaoka 120a6e
      static_cast<const &="" tstageobject="">(*this).lazyData());</const>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::update(LazyData &ld) const {
Shinya Kitaoka 120a6e
  if (ld.m_time >= 0.0) invalidate(ld);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  updateKeyframes(ld);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::onChange(const class TParamChange &c) {
Shinya Kitaoka 120a6e
  // Rationale: Since a stage object holds many parameters (or par references),
Shinya Kitaoka 120a6e
  // it may receive multiple notifications at the same time - but it should
Shinya Kitaoka 120a6e
  // actually refresh its data only ONCE for 'em all.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Even worse, the stage object may be notified for EACH touched key of just
Shinya Kitaoka 120a6e
  // one of its parameters. This means this function gets called A LOT.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Thus, we're just SCHEDULING for a data refresh. The actual refresh happens
luzpaz 27707d
  // whenever the scheduled data is accessed.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (c.m_keyframeChanged)
Shinya Kitaoka 120a6e
    m_lazyData.invalidate();  // Both invalidate placement AND keyframes
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    invalidate();  // Invalidate placement only
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectId TStageObject::getId() const { return m_id; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TStageObject::paramsTime(double t) const {
Shinya Kitaoka 120a6e
  const KeyframeMap &keyframes = lazyData().m_keyframes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_cycleEnabled && keyframes.size() > 1) {
Shinya Kitaoka 120a6e
    int firstT = keyframes.begin()->first;
Shinya Kitaoka 120a6e
    if (t <= firstT) return t;
Shinya Kitaoka 120a6e
    int lastT  = keyframes.rbegin()->first;
Shinya Kitaoka 120a6e
    int tRange = lastT - firstT + 1;
Shinya Kitaoka 120a6e
    assert(tRange > 0);
Shinya Kitaoka 120a6e
    int it    = tfloor(t);
Shinya Kitaoka 120a6e
    double ft = t - it;
Shinya Kitaoka 120a6e
    return firstT + ((it - firstT) % tRange) + ft;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return t;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setName(const std::string &name) {
Shinya Kitaoka 120a6e
  m_name = (name == m_id.toString()) ? std::string() : name;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
string TStageObject::getName() const {
Shinya Kitaoka 120a6e
  if (m_name != "") return m_name;
Shinya Kitaoka 120a6e
  if (!m_id.isColumn()) return m_id.toString();
Shinya Kitaoka 120a6e
  return "Col" + std::to_string(m_id.getIndex() + 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
string TStageObject::getFullName() const {
Shinya Kitaoka 120a6e
  string name = getName();
Shinya Kitaoka 120a6e
  if (m_id.isColumn()) {
Shinya Kitaoka 120a6e
    if (name.find("Col") == 0 && name.length() > 3 &&
Shinya Kitaoka 120a6e
        name.find_first_not_of("0123456789", 3) == string::npos)
Shinya Kitaoka 120a6e
      return name;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return name + " (" + std::to_string(m_id.getIndex() + 1) + ")";
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return name;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setParent(const TStageObjectId &parentId) {
Shinya Kitaoka 120a6e
  assert(m_tree);
Shinya Kitaoka 120a6e
  TStageObject *newParent = 0;
Shinya Kitaoka 120a6e
  if (parentId != TStageObjectId::NoneId) {
Shinya Kitaoka 120a6e
    newParent = m_tree->getStageObject(parentId);
Shinya Kitaoka 120a6e
    assert(newParent);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // cerco di evitare i cicli
Shinya Kitaoka 120a6e
    TStageObject *p = newParent;
Shinya Kitaoka 120a6e
    while (p->m_parent) {
Shinya Kitaoka 120a6e
      if (p->m_parent->getId() == getId()) return;
Shinya Kitaoka 120a6e
      p = p->m_parent;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (!m_id.isCamera() && !m_id.isTable()) {
Shinya Kitaoka 120a6e
      newParent = m_tree->getStageObject(TStageObjectId::TableId);
Shinya Kitaoka 120a6e
      assert(newParent);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_parent) m_parent->m_children.remove(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_parent = newParent;
Shinya Kitaoka 120a6e
  if (m_parent) m_parent->m_children.insert(m_parent->m_children.end(), this);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Shinya Kitaoka 120a6e
  if (m_id.isCamera()) {
Shinya Kitaoka 120a6e
  } else if (m_id.isTable()) {
Shinya Kitaoka 120a6e
    assert(m_parent == 0);
Shinya Kitaoka 120a6e
  } else if (m_id.isColumn()) {
Shinya Kitaoka 120a6e
    assert(m_parent &&
Shinya Kitaoka 120a6e
           (m_parent->m_id.isTable() || m_parent->m_id.isColumn() ||
Shinya Kitaoka 120a6e
            m_parent->m_id.isPegbar() || m_parent->m_id.isCamera()));
Shinya Kitaoka 120a6e
  } else if (m_id.isPegbar()) {
Shinya Kitaoka 120a6e
    assert(m_parent && (m_parent->m_id.isTable() || m_parent->m_id.isCamera() ||
Shinya Kitaoka 120a6e
                        m_parent->m_id.isPegbar()));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::detachFromParent() {
Shinya Kitaoka 120a6e
  if (m_parent) m_parent->m_children.remove(this);
Shinya Kitaoka 120a6e
  m_parent = 0;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::attachChildrenToParent(const TStageObjectId &parentId) {
Shinya Kitaoka 120a6e
  while (!m_children.empty()) {
Shinya Kitaoka 120a6e
    TStageObject *son = *m_children.begin();
Shinya Kitaoka 120a6e
    if (son) son->setParent(parentId);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectId TStageObject::getParent() const {
Shinya Kitaoka 120a6e
  return m_parent ? m_parent->m_id : TStageObjectId();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isAncestor(TStageObject *stageObject) const {
Shinya Kitaoka 120a6e
  if (!stageObject) return false;
Shinya Kitaoka 120a6e
  if (stageObject == (TStageObject *)m_parent)
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  else if (m_parent == 0)
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return m_parent->isAncestor(stageObject);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectSpline *TStageObject::getSpline() const { return m_spline; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::doSetSpline(TStageObjectSpline *spline) {
Shinya Kitaoka 120a6e
  TDoubleParam *param = m_posPath.getPointer();
Shinya Kitaoka 120a6e
  bool uppkEnabled    = isUppkEnabled();
Shinya Kitaoka 120a6e
  if (!spline) {
Shinya Kitaoka 120a6e
    if (uppkEnabled && m_spline) m_spline->removeParam(param);
Shinya Kitaoka 120a6e
    if (m_spline) m_spline->release();
Shinya Kitaoka 120a6e
    m_spline = 0;
Shinya Kitaoka 120a6e
    enablePath(false);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (m_spline != spline) {
Shinya Kitaoka 120a6e
      if (m_spline && uppkEnabled) m_spline->removeParam(param);
Shinya Kitaoka 120a6e
      if (m_spline) m_spline->release();
Shinya Kitaoka 120a6e
      m_spline = spline;
Shinya Kitaoka 120a6e
      m_spline->addRef();
Shinya Kitaoka 120a6e
      if (m_spline && uppkEnabled) m_spline->addParam(param);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!isPathEnabled()) enablePath(true);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setSpline(TStageObjectSpline *spline) {
Shinya Kitaoka 120a6e
  doSetSpline(spline);
Shinya Kitaoka 120a6e
  TNotifier::instance()->notify(TXsheetChange());
Shinya Kitaoka 120a6e
  TNotifier::instance()->notify(TStageChange());
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setStatus(Status status) {
Shinya Kitaoka 120a6e
  if (m_status == status) return;
Shinya Kitaoka 120a6e
  bool oldPathEnabled = isPathEnabled();
Shinya Kitaoka 120a6e
  bool oldUppkEnabled = isUppkEnabled();
Shinya Kitaoka 120a6e
  m_status            = status;
Shinya Kitaoka 120a6e
  bool pathEnabled    = isPathEnabled();
Shinya Kitaoka 120a6e
  bool uppkEnabled    = isUppkEnabled();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (pathEnabled) {
Shinya Kitaoka 120a6e
    if (!m_spline)
Shinya Kitaoka 120a6e
      doSetSpline(m_tree->createSpline());
Shinya Kitaoka 120a6e
    else if (oldUppkEnabled != uppkEnabled) {
Shinya Kitaoka 120a6e
      TDoubleParam *param = getParam(T_Path);
Shinya Kitaoka 120a6e
      if (uppkEnabled)
Shinya Kitaoka 120a6e
        m_spline->addParam(param);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_spline->removeParam(param);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    doSetSpline(0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::enableAim(bool enabled) {
Shinya Kitaoka 120a6e
  setStatus((Status)((m_status & ~STATUS_MASK) | (enabled ? PATH_AIM : PATH)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::enablePath(bool enabled) {
Shinya Kitaoka 120a6e
  if (isPathEnabled() != enabled) setStatus(enabled ? PATH : XY);
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::enableUppk(bool enabled) {
Shinya Kitaoka 120a6e
  assert(isPathEnabled());
Shinya Kitaoka 120a6e
  setStatus((Status)((m_status & ~UPPK_MASK) | (enabled ? UPPK_MASK : 0)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setCenter(double frame, const TPointD ¢er) {
Shinya Kitaoka 120a6e
  TPointD c = center - getHandlePos(m_handle, (int)frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAffine aff   = computeLocalPlacement(frame);
Shinya Kitaoka 120a6e
  TPointD delta = aff * c - aff * m_center;
Shinya Kitaoka 120a6e
  m_center      = c;
Shinya Kitaoka 120a6e
  m_offset += delta;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD TStageObject::getCenter(double frame) const {
Shinya Kitaoka 120a6e
  return m_center + getHandlePos(m_handle, (int)frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD TStageObject::getOffset() const { return m_offset; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::setOffset(const TPointD &off) {
Shinya Kitaoka 120a6e
  m_offset = off;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::getCenterAndOffset(TPointD ¢er, TPointD &offset) const {
Shinya Kitaoka 120a6e
  center = m_center;
Shinya Kitaoka 120a6e
  offset = m_offset;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setCenterAndOffset(const TPointD ¢er,
Shinya Kitaoka 120a6e
                                      const TPointD &offset) {
Shinya Kitaoka 120a6e
  m_center = center;
Shinya Kitaoka 120a6e
  m_offset = offset;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setHandle(const std::string &s) {
shun-iwasawa 641c8e
  m_handle = s;
Shinya Kitaoka 120a6e
  if (!s.empty() && s[0] == 'H') m_offset = m_center = TPointD();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setParentHandle(const std::string &s) {
Shinya Kitaoka 120a6e
  m_parentHandle = s;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD TStageObject::getHandlePos(string handle, int row) const {
Shinya Kitaoka 120a6e
  double unit = 8;
Shinya Kitaoka 120a6e
  if (handle == "")
Shinya Kitaoka 120a6e
    return TPointD();
Shinya Kitaoka 120a6e
  else if (handle.length() > 1 && handle[0] == 'H')
Shinya Kitaoka 120a6e
    return m_tree->getHandlePos(m_id, handle, row);
Shinya Kitaoka 120a6e
  else if (handle.length() == 1 && 'A' <= handle[0] && handle[0] <= 'Z')
Shinya Kitaoka 120a6e
    return TPointD(unit * (handle[0] - 'B'), 0);
Shinya Kitaoka 120a6e
  else if (handle.length() == 1 && 'a' <= handle[0] && handle[0] <= 'z')
Shinya Kitaoka 120a6e
    return TPointD(0.5 * unit * (handle[0] - 'b'), 0);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return TPointD(0, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isKeyframe(int frame) const {
Shinya Kitaoka 120a6e
  const KeyframeMap &keyframes = lazyData().m_keyframes;
Shinya Kitaoka 120a6e
  return keyframes.find(frame) != keyframes.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::is52FullKeyframe(int frame) const {
Shinya Kitaoka 120a6e
  return m_rot->isKeyframe(frame) && m_x->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_y->isKeyframe(frame) && m_z->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_posPath->isKeyframe(frame) && m_scalex->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_scaley->isKeyframe(frame) && m_shearx->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_sheary->isKeyframe(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isFullKeyframe(int frame) const {
Shinya Kitaoka 120a6e
  return m_rot->isKeyframe(frame) && m_x->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_y->isKeyframe(frame) && m_z->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_so->isKeyframe(frame) && m_posPath->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_scalex->isKeyframe(frame) && m_scaley->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_scale->isKeyframe(frame) && m_shearx->isKeyframe(frame) &&
Shinya Kitaoka 120a6e
         m_sheary->isKeyframe(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject::Keyframe TStageObject::getKeyframe(int frame) const {
Shinya Kitaoka 120a6e
  const KeyframeMap &keyframes = lazyData().m_keyframes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<int, tstageobject::keyframe="">::const_iterator it;</int,>
Shinya Kitaoka 120a6e
  it = keyframes.find(frame);
Shinya Kitaoka 120a6e
  if (it == keyframes.end()) {
Shinya Kitaoka 120a6e
    TStageObject::Keyframe k;
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_Angle]  = m_rot->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_X]      = m_x->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_Y]      = m_y->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_Z]      = m_z->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_SO]     = m_so->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_ScaleX] = m_scalex->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_ScaleY] = m_scaley->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_Scale]  = m_scale->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_Path]   = m_posPath->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_ShearX] = m_shearx->getValue(frame);
Shinya Kitaoka 120a6e
    k.m_channels[TStageObject::T_ShearY] = m_sheary->getValue(frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_skeletonDeformation)
Shinya Kitaoka 120a6e
      m_skeletonDeformation->getKeyframeAt(frame, k.m_skeletonKeyframe);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    k.m_isKeyframe = false;
Shinya Kitaoka 120a6e
    return k;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setKeyframeWithoutUndo(int frame,
Shinya Kitaoka 120a6e
                                          const TStageObject::Keyframe &k) {
Shinya Kitaoka 120a6e
  KeyframeMap &keyframes = lazyData().m_keyframes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool keyWasSet = false;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_rot, k.m_channels[TStageObject::T_Angle], frame,
Shinya Kitaoka 120a6e
                            k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_x, k.m_channels[TStageObject::T_X], frame,
Shinya Kitaoka 120a6e
                            k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_y, k.m_channels[TStageObject::T_Y], frame,
Shinya Kitaoka 120a6e
                            k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_z, k.m_channels[TStageObject::T_Z], frame,
Shinya Kitaoka 120a6e
                            k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_so, k.m_channels[TStageObject::T_SO], frame,
Shinya Kitaoka 120a6e
                            k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_posPath, k.m_channels[TStageObject::T_Path],
Shinya Kitaoka 120a6e
                            frame, k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_scalex, k.m_channels[TStageObject::T_ScaleX],
Shinya Kitaoka 120a6e
                            frame, k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_scaley, k.m_channels[TStageObject::T_ScaleY],
Shinya Kitaoka 120a6e
                            frame, k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_scale, k.m_channels[TStageObject::T_Scale], frame,
Shinya Kitaoka 120a6e
                            k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_shearx, k.m_channels[TStageObject::T_ShearX],
Shinya Kitaoka 120a6e
                            frame, k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Shinya Kitaoka 120a6e
  keyWasSet = ::setKeyframe(m_sheary, k.m_channels[TStageObject::T_ShearY],
Shinya Kitaoka 120a6e
                            frame, k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
              keyWasSet;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation)
Shinya Kitaoka 120a6e
    keyWasSet = m_skeletonDeformation->setKeyframe(k.m_skeletonKeyframe, frame,
Shinya Kitaoka 120a6e
                                                   k.m_easeIn, k.m_easeOut) ||
Shinya Kitaoka 120a6e
                keyWasSet;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (keyWasSet) keyframes[frame] = k;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setKeyframeWithoutUndo(int frame) {
Shinya Kitaoka 120a6e
  if (isFullKeyframe(frame)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  setkey(m_x, frame);
Shinya Kitaoka 120a6e
  setkey(m_y, frame);
Shinya Kitaoka 120a6e
  setkey(m_z, frame);
Shinya Kitaoka 120a6e
  setkey(m_so, frame);
Shinya Kitaoka 120a6e
  setkey(m_posPath, frame);
Shinya Kitaoka 120a6e
  setkey(m_rot, frame);
Shinya Kitaoka 120a6e
  setkey(m_scalex, frame);
Shinya Kitaoka 120a6e
  setkey(m_scaley, frame);
Shinya Kitaoka 120a6e
  setkey(m_scale, frame);
Shinya Kitaoka 120a6e
  setkey(m_shearx, frame);
Shinya Kitaoka 120a6e
  setkey(m_sheary, frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Plastic keys are currently not *created* by xsheet commands.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*if(m_skeletonDeformation)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
const PlasticSkeleton* skeleton = m_skeletonDeformation->skeleton();
Shinya Kitaoka 120a6e
const tcg::list<plasticskeleton::vertex_type>& vertices = skeleton->vertices();</plasticskeleton::vertex_type>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
tcg::list<plasticskeleton::vertex_type>::const_iterator vt,</plasticskeleton::vertex_type>
Shinya Kitaoka 120a6e
vEnd(vertices.end());
Shinya Kitaoka 120a6e
for(vt = vertices.begin(); vt != vertices.end(); ++vt)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
SkVD* vd = m_skeletonDeformation->vertexDeformation(vt->name());
Shinya Kitaoka 120a6e
assert(vd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
for(int p=0; p
Shinya Kitaoka 120a6e
  setkey(vd->m_params[p], frame);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
}*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::removeKeyframeWithoutUndo(int frame) {
Shinya Kitaoka 120a6e
  KeyframeMap &keyframes = lazyData().m_keyframes;
Shinya Kitaoka 120a6e
  double &time           = lazyData().m_time;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!isKeyframe(frame)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  keyframes.erase(frame);
Shinya Kitaoka 120a6e
  m_rot->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_x->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_y->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_z->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_so->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_scalex->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_scaley->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_scale->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_posPath->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_shearx->deleteKeyframe(frame);
Shinya Kitaoka 120a6e
  m_sheary->deleteKeyframe(frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation) m_skeletonDeformation->deleteKeyframe(frame);
Toshihiro Shimizu 890ddd
shun-iwasawa 641c8e
  time = -1;
Shinya Kitaoka 120a6e
  if ((int)keyframes.size() < 2) m_cycleEnabled = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::moveKeyframe(int dst, int src) {
Shinya Kitaoka 120a6e
  assert(dst != src);
Shinya Kitaoka 120a6e
  if (isKeyframe(dst) || !isKeyframe(src)) return false;
Shinya Kitaoka 120a6e
  setKeyframeWithoutUndo(dst, getKeyframe(src));
Shinya Kitaoka 120a6e
  removeKeyframeWithoutUndo(src);
Shinya Kitaoka 120a6e
  assert(isKeyframe(dst));
Shinya Kitaoka 120a6e
  assert(!isKeyframe(src));
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::canMoveKeyframes(std::set<int> &frames, int delta) {</int>
Shinya Kitaoka 120a6e
  if (delta == 0) return false;
Shinya Kitaoka 120a6e
  std::set<int>::iterator it;</int>
Shinya Kitaoka 120a6e
  for (it = frames.begin(); it != frames.end(); ++it) {
Shinya Kitaoka 120a6e
    int f = *it;
Shinya Kitaoka 120a6e
    if (!isKeyframe(f)) return false;
Shinya Kitaoka 120a6e
    f += delta;
Shinya Kitaoka 120a6e
    if (f < 0) return false;
Shinya Kitaoka 120a6e
    if (frames.find(f) == frames.end() && isKeyframe(f)) 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
bool TStageObject::moveKeyframes(std::set<int> &frames, int delta) {</int>
Shinya Kitaoka 120a6e
  if (!canMoveKeyframes(frames, delta)) return false;
Shinya Kitaoka 120a6e
  if (delta < 0) {
Shinya Kitaoka 120a6e
    std::set<int>::iterator it;</int>
Shinya Kitaoka 120a6e
    for (it = frames.begin(); it != frames.end(); ++it) {
Shinya Kitaoka 120a6e
      bool ret = moveKeyframe(*it + delta, *it);
Shinya Kitaoka 120a6e
      assert(ret);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    std::set<int>::reverse_iterator ti;</int>
Shinya Kitaoka 120a6e
    for (ti = frames.rbegin(); ti != frames.rend(); ++ti) {
Shinya Kitaoka 120a6e
      bool ret = moveKeyframe(*ti + delta, *ti);
Shinya Kitaoka 120a6e
      assert(ret);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::getKeyframes(KeyframeMap &keyframes) const {
Shinya Kitaoka 120a6e
  keyframes = lazyData().m_keyframes;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool TStageObject::getKeyframeRange(int &r0, int &r1) const {
Shinya Kitaoka 120a6e
  const KeyframeMap &keyframes = lazyData().m_keyframes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (keyframes.empty()) {
Shinya Kitaoka 120a6e
    r0 = 0;
Shinya Kitaoka 120a6e
    r1 = -1;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  r0 = keyframes.begin()->first;
Shinya Kitaoka 120a6e
  r1 = keyframes.rbegin()->first;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::getKeyframeSpan(int row, int &r0, double &ease0, int &r1,
Shinya Kitaoka 120a6e
                                   double &ease1) const {
Shinya Kitaoka 120a6e
  const KeyframeMap &keyframes = lazyData().m_keyframes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  KeyframeMap::const_iterator it = keyframes.lower_bound(row);
Shinya Kitaoka 120a6e
  if (it == keyframes.end() || it == keyframes.begin() || it->first == row) {
Shinya Kitaoka 120a6e
    r0    = 0;
Shinya Kitaoka 120a6e
    r1    = -1;
Shinya Kitaoka 120a6e
    ease0 = ease1 = 0;
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  r1    = it->first;
Shinya Kitaoka 120a6e
  ease1 = it->second.m_easeIn;
Shinya Kitaoka 120a6e
  --it;
Shinya Kitaoka 120a6e
  r0    = it->first;
Shinya Kitaoka 120a6e
  ease0 = it->second.m_easeOut;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setParam(Channel type, double frame, double val) {
Shinya Kitaoka 120a6e
  assert(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TStageObject::getParam(Channel type, double frame) const {
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case T_Angle:
Shinya Kitaoka 120a6e
    return m_rot->getValue(frame);
Shinya Kitaoka 120a6e
  case T_X:
Shinya Kitaoka 120a6e
    return m_x->getValue(frame);
Shinya Kitaoka 120a6e
  case T_Y:
Shinya Kitaoka 120a6e
    return m_y->getValue(frame);
Shinya Kitaoka 120a6e
  case T_Z:
Shinya Kitaoka 120a6e
    return m_z->getValue(frame);
Shinya Kitaoka 120a6e
  case T_SO:
Shinya Kitaoka 120a6e
    return m_so->getValue(frame);
Shinya Kitaoka 120a6e
  case T_ScaleX:
Shinya Kitaoka 120a6e
    return m_scalex->getValue(frame);
Shinya Kitaoka 120a6e
  case T_ScaleY:
Shinya Kitaoka 120a6e
    return m_scaley->getValue(frame);
Shinya Kitaoka 120a6e
  case T_Scale:
Shinya Kitaoka 120a6e
    return m_scale->getValue(frame);
Shinya Kitaoka 120a6e
  case T_Path:
Shinya Kitaoka 120a6e
    return m_posPath->getValue(frame);
Shinya Kitaoka 120a6e
  case T_ShearX:
Shinya Kitaoka 120a6e
    return m_shearx->getValue(frame);
Shinya Kitaoka 120a6e
  case T_ShearY:
Shinya Kitaoka 120a6e
    return m_sheary->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TDoubleParam *TStageObject::getParam(Channel channel) const {
Shinya Kitaoka 120a6e
  switch (channel) {
Shinya Kitaoka 120a6e
  case T_X:
Shinya Kitaoka 120a6e
    return m_x.getPointer();
Shinya Kitaoka 120a6e
  case T_Y:
Shinya Kitaoka 120a6e
    return m_y.getPointer();
Shinya Kitaoka 120a6e
  case T_Z:
Shinya Kitaoka 120a6e
    return m_z.getPointer();
Shinya Kitaoka 120a6e
  case T_SO:
Shinya Kitaoka 120a6e
    return m_so.getPointer();
Shinya Kitaoka 120a6e
  case T_Angle:
Shinya Kitaoka 120a6e
    return m_rot.getPointer();
Shinya Kitaoka 120a6e
  case T_Path:
Shinya Kitaoka 120a6e
    return m_posPath.getPointer();
Shinya Kitaoka 120a6e
  case T_ScaleX:
Shinya Kitaoka 120a6e
    return m_scalex.getPointer();
Shinya Kitaoka 120a6e
  case T_ScaleY:
Shinya Kitaoka 120a6e
    return m_scaley.getPointer();
Shinya Kitaoka 120a6e
  case T_Scale:
Shinya Kitaoka 120a6e
    return m_scale.getPointer();
Shinya Kitaoka 120a6e
  case T_ShearX:
Shinya Kitaoka 120a6e
    return m_shearx.getPointer();
Shinya Kitaoka 120a6e
  case T_ShearY:
Shinya Kitaoka 120a6e
    return m_sheary.getPointer();
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
PlasticSkeletonDeformationP TStageObject::getPlasticSkeletonDeformation()
Shinya Kitaoka 120a6e
    const {
Shinya Kitaoka 120a6e
  return m_skeletonDeformation;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::setPlasticSkeletonDeformation(
Shinya Kitaoka 120a6e
    const PlasticSkeletonDeformationP &sd) {
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation == sd) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation) {
Shinya Kitaoka 120a6e
    PlasticDeformerStorage::instance()->releaseDeformationData(
Shinya Kitaoka 120a6e
        m_skeletonDeformation.getPointer());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_skeletonDeformation->setGrammar(0);
Shinya Kitaoka 120a6e
    m_skeletonDeformation->removeObserver(this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_skeletonDeformation = sd;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation) {
Shinya Kitaoka 120a6e
    m_skeletonDeformation->setGrammar(m_tree->getGrammar());
Shinya Kitaoka 120a6e
    m_skeletonDeformation->addObserver(this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject *TStageObject::clone() {
Shinya Kitaoka 120a6e
  assert(m_tree);
Shinya Kitaoka 120a6e
  TStageObjectId pegId    = getId();
Shinya Kitaoka 120a6e
  TStageObjectId newPegId = TStageObjectId::NoneId;
Shinya Kitaoka 120a6e
  int newIndex            = pegId.getIndex();
Shinya Kitaoka 120a6e
  if (pegId.isCamera()) {
Shinya Kitaoka 120a6e
    while ((m_tree->getStageObject(TStageObjectId::CameraId(newIndex), false) !=
Shinya Kitaoka 120a6e
            0L) ||
Shinya Kitaoka 120a6e
           (pegId.getIndex() == newIndex))
Shinya Kitaoka 120a6e
      ++newIndex;
Shinya Kitaoka 120a6e
    newPegId = TStageObjectId::CameraId(newIndex);
Shinya Kitaoka 120a6e
  } else if (pegId.isColumn()) {
Shinya Kitaoka 120a6e
    while ((m_tree->getStageObject(TStageObjectId::ColumnId(newIndex), false) !=
Shinya Kitaoka 120a6e
            0L) ||
Shinya Kitaoka 120a6e
           (pegId.getIndex() == newIndex))
Shinya Kitaoka 120a6e
      ++newIndex;
Shinya Kitaoka 120a6e
    newPegId = TStageObjectId::ColumnId(newIndex);
Shinya Kitaoka 120a6e
  } else if (pegId.isPegbar()) {
Shinya Kitaoka 120a6e
    while ((m_tree->getStageObject(TStageObjectId::PegbarId(newIndex), false) !=
Shinya Kitaoka 120a6e
            0L) ||
Shinya Kitaoka 120a6e
           (pegId.getIndex() == newIndex))
Shinya Kitaoka 120a6e
      ++newIndex;
Shinya Kitaoka 120a6e
    newPegId = TStageObjectId::PegbarId(newIndex);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(!"Unknown stage object type");
Shinya Kitaoka 120a6e
    return 0L;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(newPegId != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  assert(newIndex >= 0);
Shinya Kitaoka 120a6e
  assert(newPegId.getIndex() != pegId.getIndex());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // aggiunge lo stage object clonato nel stage object tree
Shinya Kitaoka 120a6e
  TStageObject *clonedPeg = m_tree->getStageObject(newPegId, true);
Shinya Kitaoka 120a6e
  TStageObject *cloned    = clonedPeg;
Shinya Kitaoka 120a6e
  assert(cloned);
Shinya Kitaoka 120a6e
  assert(cloned->m_tree == m_tree);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  KeyframeMap &keyframes       = lazyData().m_keyframes;
Shinya Kitaoka 120a6e
  KeyframeMap &clonedKeyframes = cloned->lazyData().m_keyframes;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<int, tstageobject::keyframe="">::iterator itKf = keyframes.begin();</int,>
Shinya Kitaoka 120a6e
  for (; itKf != keyframes.end(); ++itKf) {
Shinya Kitaoka 120a6e
    clonedKeyframes.insert(make_pair(itKf->first, itKf->second));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  cloned->m_cycleEnabled    = m_cycleEnabled;
Shinya Kitaoka 120a6e
  cloned->lazyData().m_time = lazyData().m_time;
Shinya Kitaoka 120a6e
  cloned->m_localPlacement  = m_localPlacement;
Shinya Kitaoka 120a6e
  cloned->m_absPlacement    = m_absPlacement;
Shinya Kitaoka 120a6e
  cloned->m_status          = m_status;
Shinya Kitaoka 120a6e
  cloned->doSetSpline(m_spline);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  cloned->m_x       = static_cast<tdoubleparam *="">(m_x->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_y       = static_cast<tdoubleparam *="">(m_y->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_z       = static_cast<tdoubleparam *="">(m_z->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_so      = static_cast<tdoubleparam *="">(m_so->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_rot     = static_cast<tdoubleparam *="">(m_rot->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_scalex  = static_cast<tdoubleparam *="">(m_scalex->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_scaley  = static_cast<tdoubleparam *="">(m_scaley->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_scale   = static_cast<tdoubleparam *="">(m_scale->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_posPath = static_cast<tdoubleparam *="">(m_posPath->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_shearx  = static_cast<tdoubleparam *="">(m_shearx->clone());</tdoubleparam>
Shinya Kitaoka 120a6e
  cloned->m_sheary  = static_cast<tdoubleparam *="">(m_sheary->clone());</tdoubleparam>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation)
Shinya Kitaoka 120a6e
    cloned->m_skeletonDeformation =
Shinya Kitaoka 120a6e
        new PlasticSkeletonDeformation(*m_skeletonDeformation);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  cloned->m_noScaleZ   = m_noScaleZ;
Shinya Kitaoka 120a6e
  cloned->m_center     = m_center;
Shinya Kitaoka 120a6e
  cloned->m_offset     = m_offset;
Shinya Kitaoka 120a6e
  cloned->m_name       = m_name;
Shinya Kitaoka 120a6e
  cloned->m_dagNodePos = m_dagNodePos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return cloned;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isCycleEnabled() const { return m_cycleEnabled; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::enableCycle(bool on) { m_cycleEnabled = on; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TStageObject *TStageObject::findRoot(double frame) const {
Shinya Kitaoka 120a6e
  if (!m_parent) return NULL;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStageObject *parent = m_parent;
Shinya Kitaoka 120a6e
  while (parent->m_parent && parent->lazyData().m_time != frame)
Shinya Kitaoka 120a6e
    parent = parent->m_parent;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return parent;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject *TStageObject::getPinnedDescendant(int frame) {
Shinya Kitaoka 120a6e
  if (getPinnedRangeSet()->isPinned(frame)) return this;
Shinya Kitaoka 120a6e
  for (list<tstageobject *="">::iterator it = m_children.begin();</tstageobject>
Shinya Kitaoka 120a6e
       it != m_children.end(); ++it) {
Shinya Kitaoka 120a6e
    TStageObject *child = *it;
Shinya Kitaoka 120a6e
    if (child->getPinnedRangeSet()->isPinned(frame)) return child;
Shinya Kitaoka 120a6e
    TStageObject *pinned = child->getPinnedDescendant(frame);
Shinya Kitaoka 120a6e
    if (pinned) return pinned;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TStageObject::computeIkRootOffset(int t) {
Shinya Kitaoka 120a6e
  if (m_ikflag > 0) return TAffine();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // get normal movement (which will be left-multiplied to the IK-part)
Shinya Kitaoka 120a6e
  setStatus(XY);
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
  TAffine basePlacement = getPlacement(t);
Shinya Kitaoka 120a6e
  setStatus(IK);
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStageObject *foot = getPinnedDescendant(t);
Shinya Kitaoka 120a6e
  if (foot == 0) {
Shinya Kitaoka 120a6e
    foot = this;
Shinya Kitaoka 120a6e
    setStatus(XY);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_ikflag++;
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAffine placement                   = foot->getPlacement(t).inv();
Shinya Kitaoka 120a6e
  int t0                              = 0;
Shinya Kitaoka 120a6e
  const TPinnedRangeSet::Range *range = foot->getPinnedRangeSet()->getRange(t);
shun-iwasawa 641c8e
  if (range) t0 = range->first;
Shinya Kitaoka 120a6e
  while (t0 > 0) {
Shinya Kitaoka 120a6e
    TStageObject *oldFoot = getPinnedDescendant(t0 - 1);
Shinya Kitaoka 120a6e
    if (oldFoot == 0) break;  // oldFoot = this;
Shinya Kitaoka 120a6e
    assert(oldFoot != foot);
Shinya Kitaoka 120a6e
    TAffine changeFootAff =
Shinya Kitaoka 120a6e
        oldFoot->getPlacement(t0).inv() * foot->getPlacement(t0);
shun-iwasawa 641c8e
    placement = changeFootAff * placement;
shun-iwasawa 641c8e
    foot      = oldFoot;
shun-iwasawa 641c8e
    range     = oldFoot->getPinnedRangeSet()->getRange(t0 - 1);
shun-iwasawa 641c8e
    t0        = 0;
Shinya Kitaoka 120a6e
    if (range) t0 = range->first;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_ikflag--;
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  placement = foot->getPinnedRangeSet()->getPlacement() * placement;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return basePlacement * placement;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
inline double getPosPathAtCP(const TStroke* path, int cpIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  int n = path->getControlPointCount();
Toshihiro Shimizu 890ddd
  return path->getLengthAtControlPoint(tcrop(cpIndex*4,0,n-1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TStageObject::computeLocalPlacement(double frame) {
Shinya Kitaoka 120a6e
  frame = paramsTime(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (lazyData().m_time != frame) {
Shinya Kitaoka 120a6e
    double sc  = m_scale->getValue(frame);
Shinya Kitaoka 120a6e
    double sx  = sc * m_scalex->getValue(frame);
Shinya Kitaoka 120a6e
    double sy  = sc * m_scaley->getValue(frame);
Shinya Kitaoka 120a6e
    double ang = m_rot->getValue(frame);
Shinya Kitaoka 120a6e
    double shx = m_shearx->getValue(frame);
Shinya Kitaoka 120a6e
    double shy = m_sheary->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPointD position;
Shinya Kitaoka 120a6e
    double posPath = 0;
Shinya Kitaoka 120a6e
    switch (m_status & STATUS_MASK) {
Shinya Kitaoka 120a6e
    case XY:
Shinya Kitaoka 120a6e
      position.x = m_x->getValue(frame) * Stage::inch;
Shinya Kitaoka 120a6e
      position.y = m_y->getValue(frame) * Stage::inch;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PATH:
Shinya Kitaoka 120a6e
      assert(m_spline);
Shinya Kitaoka 120a6e
      assert(m_spline->getStroke());
Shinya Kitaoka 120a6e
      posPath = m_spline->getStroke()->getLength() *
Shinya Kitaoka 120a6e
                m_posPath->getValue(frame) * 0.01;
Shinya Kitaoka 120a6e
      position = m_spline->getStroke()->getPointAtLength(posPath);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PATH_AIM:
Shinya Kitaoka 120a6e
      assert(m_spline);
Shinya Kitaoka 120a6e
      assert(m_spline->getStroke());
Shinya Kitaoka 120a6e
      posPath = m_spline->getStroke()->getLength() *
Shinya Kitaoka 120a6e
                m_posPath->getValue(frame) * 0.01;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      position = m_spline->getStroke()->getPointAtLength(posPath);
Shinya Kitaoka 120a6e
      if (m_spline->getStroke()->getLength() > 1e-5)
Shinya Kitaoka 120a6e
        ang +=
Shinya Kitaoka 120a6e
            rad2degree(atan(m_spline->getStroke()->getSpeedAtLength(posPath)));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case IK:
Shinya Kitaoka 120a6e
      return computeIkRootOffset(frame);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TAffine shear(1, shx, 0, shy, 1, 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TPointD handlePos = getHandlePos(m_handle, (int)frame);
Shinya Kitaoka 120a6e
    TPointD center    = (m_center + handlePos) * Stage::inch;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TPointD pos = m_offset;
Shinya Kitaoka 120a6e
    if (m_parent) pos += m_parent->getHandlePos(m_parentHandle, (int)frame);
Shinya Kitaoka 120a6e
    pos = pos * Stage::inch + position;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_localPlacement = TTranslation(pos) * makeRotation(ang) * shear *
Shinya Kitaoka 120a6e
                       TScale(sx, sy) * TTranslation(-center);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_localPlacement;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TStageObject::getPlacement(double t) {
Shinya Kitaoka 120a6e
  double &time = lazyData().m_time;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (time == t) return m_absPlacement;
Shinya Kitaoka 120a6e
  if (time != -1) {
Shinya Kitaoka 120a6e
    if (!m_parent)
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      findRoot(t)->invalidate();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double tt = paramsTime(t);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAffine place;
Shinya Kitaoka 120a6e
  if (m_parent)
Shinya Kitaoka 120a6e
    place = m_parent->getPlacement(t) * computeLocalPlacement(tt);
Shinya Kitaoka 120a6e
  else
shun-iwasawa 641c8e
    place = computeLocalPlacement(tt);
Shinya Kitaoka 120a6e
  m_absPlacement = place;
Shinya Kitaoka 120a6e
  time           = t;
Shinya Kitaoka 120a6e
  return place;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TStageObject::getZ(double t) {
Shinya Kitaoka 120a6e
  double tt = paramsTime(t);
Shinya Kitaoka 120a6e
  if (m_parent)
Shinya Kitaoka 120a6e
    return m_parent->getZ(t) + m_z->getValue(tt);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return m_z->getValue(tt);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TStageObject::getSO(double t) {
Shinya Kitaoka 120a6e
  double tt = paramsTime(t);
Shinya Kitaoka 120a6e
  if (m_parent)
Shinya Kitaoka 120a6e
    return m_parent->getSO(t) + m_so->getValue(tt);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return m_so->getValue(tt);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TStageObject::getGlobalNoScaleZ() const {
Shinya Kitaoka 120a6e
  return m_parent ? m_parent->getGlobalNoScaleZ() + m_noScaleZ : m_noScaleZ;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TStageObject::getNoScaleZ() const { return m_noScaleZ; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setNoScaleZ(double noScaleZ) {
Shinya Kitaoka 120a6e
  if (m_noScaleZ == noScaleZ) return;
Shinya Kitaoka 120a6e
  m_noScaleZ = noScaleZ;
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::invalidate(LazyData &ld) const {
Shinya Kitaoka 120a6e
  // Since this is an invalidation function, access to the invalidable data
Shinya Kitaoka 120a6e
  // should
Shinya Kitaoka 120a6e
  // not trigger a data update
Shinya Kitaoka 120a6e
  ld.m_time = -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::list<tstageobject *="">::const_iterator cit = m_children.begin();</tstageobject>
Shinya Kitaoka 120a6e
  for (; cit != m_children.end(); ++cit) (*cit)->invalidate();
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::invalidate() { invalidate(m_lazyData(tcg::direct_access)); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TStageObject::getParentPlacement(double t) const {
Shinya Kitaoka 120a6e
  return m_parent ? m_parent->getPlacement(t) : TAffine();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Rebuild the keyframes map
Shinya Kitaoka 120a6e
void TStageObject::updateKeyframes(LazyData &ld) const {
Shinya Kitaoka 120a6e
  KeyframeMap &keyframes = ld.m_keyframes;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Clear the map
Shinya Kitaoka 120a6e
  keyframes.clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Gather all sensible parameters in a vector
Shinya Kitaoka 120a6e
  std::vector<tdoubleparam *=""> params;</tdoubleparam>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_status == XY) {
Shinya Kitaoka 120a6e
    params.push_back(m_x.getPointer());
Shinya Kitaoka 120a6e
    params.push_back(m_y.getPointer());
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    params.push_back(m_posPath.getPointer());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  params.push_back(m_z.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_so.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_rot.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_scalex.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_scaley.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_scale.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_shearx.getPointer());
Shinya Kitaoka 120a6e
  params.push_back(m_sheary.getPointer());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation) {
Shinya Kitaoka 120a6e
    params.push_back(m_skeletonDeformation->skeletonIdsParam().getPointer());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Add Plastic Skeleton params too
Shinya Kitaoka 120a6e
    SkD::vd_iterator vdt, vdEnd;
Shinya Kitaoka 120a6e
    m_skeletonDeformation->vertexDeformations(vdt, vdEnd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; vdt != vdEnd; ++vdt) {
Shinya Kitaoka 120a6e
      const std::pair<const *="" *,="" qstring="" skvd=""> &vd = *vdt;</const>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int p = 0; p < SkVD::PARAMS_COUNT; ++p)
Shinya Kitaoka 120a6e
        params.push_back(vd.second->m_params[p].getPointer());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Scan each parameter for a key frame - add each in a set
Shinya Kitaoka 120a6e
  std::set<int> frames;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int p, pCount = params.size();
Shinya Kitaoka 120a6e
  for (p = 0; p < pCount; ++p) {
Shinya Kitaoka 120a6e
    TDoubleParam *param = params[p];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int k, kCount = param->getKeyframeCount();
Shinya Kitaoka 120a6e
    for (k = 0; k < kCount; ++k) {
Shinya Kitaoka 120a6e
      const TDoubleKeyframe &kf = param->getKeyframe(k);
Shinya Kitaoka 120a6e
      frames.insert((int)kf.m_frame);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Traverse said set and build a TStageObject keyframe for each found instant
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::set<int>::iterator ft, fEnd(frames.end());</int>
Shinya Kitaoka 120a6e
  for (ft = frames.begin(); ft != fEnd; ++ft) {
Shinya Kitaoka 120a6e
    int f = *ft;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Add values
Shinya Kitaoka 120a6e
    TStageObject::Keyframe stageKf;
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_Angle]  = m_rot->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_X]      = m_x->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_Y]      = m_y->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_Z]      = m_z->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_SO]     = m_so->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_ScaleX] = m_scalex->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_ScaleY] = m_scaley->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_Scale]  = m_scale->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_Path]   = m_posPath->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_ShearX] = m_shearx->getKeyframeAt(f);
Shinya Kitaoka 120a6e
    stageKf.m_channels[TStageObject::T_ShearY] = m_sheary->getKeyframeAt(f);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_skeletonDeformation)
Shinya Kitaoka 120a6e
      m_skeletonDeformation->getKeyframeAt(f, stageKf.m_skeletonKeyframe);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    stageKf.m_isKeyframe = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Build the stage keyframe's global ease factors
Shinya Kitaoka 120a6e
    stageKf.m_easeIn  = -1;
Shinya Kitaoka 120a6e
    stageKf.m_easeOut = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDoubleKeyframe::Type type = TDoubleKeyframe::None;
Shinya Kitaoka 120a6e
    bool easeOk                = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Start from analyzing standard channels
Shinya Kitaoka 120a6e
    for (int c = 0; easeOk && c < T_ChannelCount; ++c) {
Shinya Kitaoka 120a6e
      const TDoubleKeyframe &kf = stageKf.m_channels[c];
Shinya Kitaoka 120a6e
      if (!kf.m_isKeyframe) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      easeOk = touchEaseAndCompare(kf, stageKf, type);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Finally, check the skeleton deformation keyframes
Shinya Kitaoka 120a6e
    const std::map<qstring, skvd::keyframe=""> &vdfs =</qstring,>
Shinya Kitaoka 120a6e
        stageKf.m_skeletonKeyframe.m_vertexKeyframes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    std::map<qstring, skvd::keyframe="">::const_iterator vdft, vdfEnd(vdfs.end());</qstring,>
Shinya Kitaoka 120a6e
    for (vdft = vdfs.begin(); easeOk && vdft != vdfEnd; ++vdft) {
Shinya Kitaoka 120a6e
      for (int p = 0; p < SkVD::PARAMS_COUNT; ++p) {
Shinya Kitaoka 120a6e
        const TDoubleKeyframe &kf = vdft->second.m_keyframes[p];
Shinya Kitaoka 120a6e
        if (!kf.m_isKeyframe) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        easeOk = touchEaseAndCompare(kf, stageKf, type);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    keyframes[f] = stageKf;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::updateKeyframes() {
Shinya Kitaoka 120a6e
  return updateKeyframes(m_lazyData(tcg::direct_access));
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::saveData(TOStream &os) {
Shinya Kitaoka 120a6e
  TStageObjectId parentId = getParent();
Shinya Kitaoka 120a6e
  std::map<std::string, string=""> attr;</std::string,>
Shinya Kitaoka 120a6e
  attr["id"]           = parentId.toString();
Shinya Kitaoka 120a6e
  attr["handle"]       = m_handle;
Shinya Kitaoka 120a6e
  attr["parentHandle"] = m_parentHandle;
Shinya Kitaoka 120a6e
  os.openChild("parent", attr);
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
  if (m_name != "") os.child("name") << m_name;
Shinya Kitaoka 120a6e
  os.child("isOpened") << (int)m_isOpened;
Shinya Kitaoka 120a6e
  if (isGrouped()) {
Shinya Kitaoka 120a6e
    os.openChild("groupIds");
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < m_groupId.size(); i++) os << m_groupId[i];
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
    os.openChild("groupNames");
Shinya Kitaoka 120a6e
    for (i = 0; i < m_groupName.size(); i++) os << m_groupName[i];
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_pinnedRangeSet->saveData(os);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.child("center") << m_center.x << m_center.y << -m_offset.x << -m_offset.y;
Shinya Kitaoka 120a6e
  os.child("status") << (int)m_status;
Shinya Kitaoka 120a6e
  if (m_noScaleZ != 0) os.child("noScaleZ") << m_noScaleZ;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_spline) os.child("splinep") << m_spline;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_x->isDefault()) os.child("x") << *m_x;
Shinya Kitaoka 120a6e
  if (!m_y->isDefault()) os.child("y") << *m_y;
Shinya Kitaoka 120a6e
  if (!m_z->isDefault()) os.child("z") << *m_z;
Shinya Kitaoka 120a6e
  if (!m_so->isDefault()) os.child("so") << *m_so;
Shinya Kitaoka 120a6e
  if (!m_scalex->isDefault()) os.child("sx") << *m_scalex;
Shinya Kitaoka 120a6e
  if (!m_scaley->isDefault()) os.child("sy") << *m_scaley;
Shinya Kitaoka 120a6e
  if (!m_scale->isDefault()) os.child("sc") << *m_scale;
Shinya Kitaoka 120a6e
  if (!m_rot->isDefault()) os.child("rot") << *m_rot;
Shinya Kitaoka 120a6e
  if (!m_posPath->isDefault()) os.child("pos") << *m_posPath;
Shinya Kitaoka 120a6e
  if (!m_shearx->isDefault()) os.child("shx") << *m_shearx;
Shinya Kitaoka 120a6e
  if (!m_sheary->isDefault()) os.child("shy") << *m_sheary;
Shinya Kitaoka 120a6e
  if (m_cycleEnabled) os.child("cycle") << 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_skeletonDeformation) os.child("plasticSD") << *m_skeletonDeformation;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.child("nodePos") << m_dagNodePos.x << m_dagNodePos.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (getId().isCamera()) {
Shinya Kitaoka 120a6e
    os.openChild("camera");
Shinya Kitaoka 120a6e
    m_camera->saveData(os);
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*TDimensionD size = m_camera->getSize();
Shinya Kitaoka 120a6e
TDimension res = m_camera->getRes();
Shinya Kitaoka 120a6e
bool isXPrevalence = m_camera->isXPrevalence();
Shinya Kitaoka 120a6e
os.child("cameraSize") << size.lx << size.ly;
Shinya Kitaoka 120a6e
os.child("cameraRes") << res.lx << res.ly;
Shinya Kitaoka 120a6e
os.child("xPrevalence") << (int)isXPrevalence;*/
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  VersionNumber tnzVersion = is.getVersion();
Shinya Kitaoka 120a6e
  string tagName;
Shinya Kitaoka 120a6e
  QList<int> groupIds;</int>
Shinya Kitaoka 120a6e
  QList<wstring> groupNames;</wstring>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  KeyframeMap &keyframes = lazyData().m_keyframes;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "parent") {
Shinya Kitaoka 120a6e
      string parentIdStr  = is.getTagAttribute("id");
Shinya Kitaoka 120a6e
      string handle       = is.getTagAttribute("handle");
Shinya Kitaoka 120a6e
      string parentHandle = is.getTagAttribute("parentHandle");
Shinya Kitaoka 120a6e
      if (tnzVersion < VersionNumber(1, 15)) {
Shinya Kitaoka 120a6e
        handle       = convertTo4InchCenterUnits(handle);
Shinya Kitaoka 120a6e
        parentHandle = convertTo4InchCenterUnits(parentHandle);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (parentIdStr == "")  // vecchio formato
Shinya Kitaoka 120a6e
        is >> parentIdStr;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TStageObjectId parentId = toStageObjectId(parentIdStr);
Shinya Kitaoka 120a6e
      if (m_id != TStageObjectId::NoneId &&
Shinya Kitaoka 120a6e
          parentId != TStageObjectId::NoneId) {
Shinya Kitaoka 120a6e
        assert(parentId != m_id);
Shinya Kitaoka 120a6e
        setParent(parentId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (handle != "") setHandle(handle);
Shinya Kitaoka 120a6e
      if (parentHandle != "") setParentHandle(parentHandle);
Shinya Kitaoka 120a6e
    } else if (tagName == "center") {
Shinya Kitaoka 120a6e
      is >> m_center.x >> m_center.y >> m_offset.x >> m_offset.y;
Shinya Kitaoka 120a6e
      m_offset = -m_offset;
Shinya Kitaoka 120a6e
    } else if (tagName == "name")
Shinya Kitaoka 120a6e
      is >> m_name;
Shinya Kitaoka 120a6e
    else if (tagName == "x")
Shinya Kitaoka 120a6e
      is >> *m_x;
Shinya Kitaoka 120a6e
    else if (tagName == "y")
Shinya Kitaoka 120a6e
      is >> *m_y;
Shinya Kitaoka 120a6e
    else if (tagName == "z")
Shinya Kitaoka 120a6e
      is >> *m_z;
Shinya Kitaoka 120a6e
    else if (tagName == "so")
Shinya Kitaoka 120a6e
      is >> *m_so;
Shinya Kitaoka 120a6e
    else if (tagName == "rot")
Shinya Kitaoka 120a6e
      is >> *m_rot;
Shinya Kitaoka 120a6e
    else if (tagName == "sx")
Shinya Kitaoka 120a6e
      is >> *m_scalex;
Shinya Kitaoka 120a6e
    else if (tagName == "sy")
Shinya Kitaoka 120a6e
      is >> *m_scaley;
Shinya Kitaoka 120a6e
    else if (tagName == "sc")
Shinya Kitaoka 120a6e
      is >> *m_scale;
Shinya Kitaoka 120a6e
    else if (tagName == "shx")
Shinya Kitaoka 120a6e
      is >> *m_shearx;
Shinya Kitaoka 120a6e
    else if (tagName == "shy")
Shinya Kitaoka 120a6e
      is >> *m_sheary;
Shinya Kitaoka 120a6e
    else if (tagName == "pos")
Shinya Kitaoka 120a6e
      is >> *m_posPath;
Shinya Kitaoka 120a6e
    else if (tagName == "posCP") {
Shinya Kitaoka 120a6e
      TDoubleParam posCP;
Shinya Kitaoka 120a6e
      is >> posCP;
Shinya Kitaoka 120a6e
    }  // Ghibli 6.2 release. cfr
Shinya Kitaoka 120a6e
    else if (tagName == "noScaleZ")
Shinya Kitaoka 120a6e
      is >> m_noScaleZ;
Shinya Kitaoka 120a6e
    else if (tagName == "isOpened") {
Shinya Kitaoka 120a6e
      int v = 0;
Shinya Kitaoka 120a6e
      is >> v;
Shinya Kitaoka 120a6e
      m_isOpened = (bool)v;
Shinya Kitaoka 120a6e
    } else if (tagName == "pinnedStatus") {
Shinya Kitaoka 120a6e
      m_pinnedRangeSet->loadData(is);
Shinya Kitaoka 120a6e
    } else if (tagName == "status") {
Shinya Kitaoka 120a6e
      int v = 0;
Shinya Kitaoka 120a6e
      is >> v;
Shinya Kitaoka 120a6e
      m_status = (Status)v;
Shinya Kitaoka 120a6e
    } else if (tagName == "spline") {
Shinya Kitaoka 120a6e
      TStageObjectSpline *spline = m_tree->createSpline();
Shinya Kitaoka 120a6e
      is >> *spline;
Shinya Kitaoka 120a6e
      m_spline = spline;
Shinya Kitaoka 120a6e
      m_spline->addRef();
Shinya Kitaoka 120a6e
    } else if (tagName == "splinep") {
Shinya Kitaoka 120a6e
      TPersist *p = 0;
Shinya Kitaoka 120a6e
      is >> p;
Shinya Kitaoka 120a6e
      m_spline = dynamic_cast<tstageobjectspline *="">(p);</tstageobjectspline>
Shinya Kitaoka 120a6e
      m_tree->insertSpline(m_spline);
Shinya Kitaoka 120a6e
      m_spline->addRef();
Shinya Kitaoka 120a6e
    } else if (tagName == "cycle") {
Shinya Kitaoka 120a6e
      int dummy;
Shinya Kitaoka 120a6e
      is >> dummy;
Shinya Kitaoka 120a6e
      m_cycleEnabled = true;
Shinya Kitaoka 120a6e
    } else if (tagName == "nodePos") {
Shinya Kitaoka 120a6e
      TPointD pos;
Shinya Kitaoka 120a6e
      is >> pos.x >> pos.y;
Shinya Kitaoka 120a6e
      m_dagNodePos = updateDagPosition(pos, tnzVersion);
Shinya Kitaoka 120a6e
      // is >> m_dagNodePos.x >> m_dagNodePos.y;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    //***** camera parameters till toonz 6.0 ********
Shinya Kitaoka 120a6e
    else if (tagName == "cameraSize") {
Shinya Kitaoka 120a6e
      TDimensionD size(0, 0);
Shinya Kitaoka 120a6e
      is >> size.lx >> size.ly;
Shinya Kitaoka 120a6e
      if (m_camera) m_camera->setSize(size);
Shinya Kitaoka 120a6e
    } else if (tagName == "cameraRes") {
Shinya Kitaoka 120a6e
      TDimension res(0, 0);
Shinya Kitaoka 120a6e
      is >> res.lx >> res.ly;
Shinya Kitaoka 120a6e
      if (m_camera) m_camera->setRes(res);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    //***** camera parameters toonz 6.1 ******** november 2009
Shinya Kitaoka 120a6e
    else if (tagName == "camera")
Shinya Kitaoka 120a6e
      m_camera->loadData(is);
Shinya Kitaoka 120a6e
    else if (tagName == "groupIds") {
Shinya Kitaoka 120a6e
      int groupId;
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        is >> groupId;
Shinya Kitaoka 120a6e
        groupIds.push_back(groupId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "groupNames") {
Shinya Kitaoka 120a6e
      wstring groupName;
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        is >> groupName;
Shinya Kitaoka 120a6e
        groupNames.push_back(groupName);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "plasticSD") {
Shinya Kitaoka 120a6e
      PlasticSkeletonDeformation *sd = new PlasticSkeletonDeformation;
Shinya Kitaoka 120a6e
      is >> *sd;
Shinya Kitaoka 120a6e
      setPlasticSkeletonDeformation(sd);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw TException("TStageObject::loadData. unexpected tag: " + tagName);
Shinya Kitaoka 120a6e
    is.matchEndTag();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!groupIds.isEmpty()) {
Shinya Kitaoka 120a6e
    assert(groupIds.size() == groupNames.size());
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < groupIds.size(); i++) {
Shinya Kitaoka 120a6e
      setGroupId(groupIds[i]);
Shinya Kitaoka 120a6e
      setGroupName(groupNames[i]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (tnzVersion < VersionNumber(1, 13)) {
Shinya Kitaoka 120a6e
    updateUnit(m_y.getPointer());
Shinya Kitaoka 120a6e
    updateUnit(m_x.getPointer());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (tnzVersion < VersionNumber(1, 14)) {
Shinya Kitaoka 120a6e
    double factor = 1.0 / Stage::inch;
Shinya Kitaoka 120a6e
    m_center      = m_center * factor;
Shinya Kitaoka 120a6e
    m_offset      = m_offset * factor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (tnzVersion < VersionNumber(1, 16) && !keyframes.empty()) {
Shinya Kitaoka 120a6e
    std::map<int, tstageobject::keyframe="">::iterator itKf = keyframes.begin();</int,>
Shinya Kitaoka 120a6e
    std::set<int> keyframeIndexSet;</int>
Shinya Kitaoka 120a6e
    for (; itKf != keyframes.end(); itKf++)
Shinya Kitaoka 120a6e
      if (is52FullKeyframe(itKf->first)) keyframeIndexSet.insert(itKf->first);
Shinya Kitaoka 120a6e
    std::set<int>::iterator itKfInd = keyframeIndexSet.begin();</int>
Shinya Kitaoka 120a6e
    for (; itKfInd != keyframeIndexSet.end(); itKfInd++)
Shinya Kitaoka 120a6e
      setkey(m_scale, *itKfInd);
Shinya Kitaoka 120a6e
  }
shun-iwasawa 641c8e
  // Calling updateKeyframes() here may cause failure to load expressions
shun-iwasawa 641c8e
  // especially if it refers to a curve which is to be loaded AFTER this
shun-iwasawa 641c8e
  // function while loading scene process. So I will skip it assuming that
shun-iwasawa 641c8e
  // updateKeyframes() will be called when it is actually needed.
shun-iwasawa 641c8e
  // updateKeyframes();
Shinya Kitaoka 120a6e
  if (m_spline != 0 && isUppkEnabled())
Shinya Kitaoka 120a6e
    m_spline->addParam(m_posPath.getPointer());
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TStageObjectParams *TStageObject::getParams() const {
Shinya Kitaoka 120a6e
  TStageObjectParams *data = new TStageObjectParams();
Shinya Kitaoka 120a6e
  data->m_name             = m_name;
Shinya Kitaoka 120a6e
  data->m_center           = m_center;
Shinya Kitaoka 120a6e
  data->m_noScaleZ         = m_noScaleZ;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  data->m_id       = m_id;
Shinya Kitaoka 120a6e
  data->m_parentId = getParent();
Shinya Kitaoka 120a6e
  data->m_offset   = m_offset;
Shinya Kitaoka 120a6e
  data->m_status   = m_status;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  data->m_x       = m_x;
Shinya Kitaoka 120a6e
  data->m_y       = m_y;
Shinya Kitaoka 120a6e
  data->m_z       = m_z;
Shinya Kitaoka 120a6e
  data->m_so      = m_so;
Shinya Kitaoka 120a6e
  data->m_rot     = m_rot;
Shinya Kitaoka 120a6e
  data->m_scalex  = m_scalex;
Shinya Kitaoka 120a6e
  data->m_scaley  = m_scaley;
Shinya Kitaoka 120a6e
  data->m_scale   = m_scale;
Shinya Kitaoka 120a6e
  data->m_posPath = m_posPath;
Shinya Kitaoka 120a6e
  data->m_shearx  = m_shearx;
Shinya Kitaoka 120a6e
  data->m_sheary  = m_sheary;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  data->m_skeletonDeformation = m_skeletonDeformation;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  data->m_cycleEnabled = m_cycleEnabled;
Shinya Kitaoka 120a6e
  data->m_spline       = m_spline;
Shinya Kitaoka 120a6e
shun-iwasawa 641c8e
  data->m_handle       = m_handle;
shun-iwasawa 641c8e
  data->m_parentHandle = m_parentHandle;
Shinya Kitaoka 120a6e
  if (m_pinnedRangeSet) data->m_pinnedRangeSet = m_pinnedRangeSet->clone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return data;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TStageObject::assignParams(const TStageObjectParams *src,
Shinya Kitaoka 120a6e
                                bool doParametersClone) {
Shinya Kitaoka 120a6e
  m_name     = src->m_name;
Shinya Kitaoka 120a6e
  m_center   = src->m_center;
Shinya Kitaoka 120a6e
  m_noScaleZ = src->m_noScaleZ;
Shinya Kitaoka 120a6e
  m_offset   = src->m_offset;
Shinya Kitaoka 120a6e
  m_status   = src->m_status;
Shinya Kitaoka 120a6e
  if (m_spline) m_spline->release();
Shinya Kitaoka 120a6e
  m_spline = src->m_spline;
Shinya Kitaoka 120a6e
  if (m_spline) m_spline->addRef();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (doParametersClone) {
Shinya Kitaoka 120a6e
    m_x->copy(src->m_x.getPointer());
Shinya Kitaoka 120a6e
    m_y->copy(src->m_y.getPointer());
Shinya Kitaoka 120a6e
    m_z->copy(src->m_z.getPointer());
Shinya Kitaoka 120a6e
    m_so->copy(src->m_so.getPointer());
Shinya Kitaoka 120a6e
    m_rot->copy(src->m_rot.getPointer());
Shinya Kitaoka 120a6e
    m_scalex->copy(src->m_scalex.getPointer());
Shinya Kitaoka 120a6e
    m_scaley->copy(src->m_scaley.getPointer());
Shinya Kitaoka 120a6e
    m_scale->copy(src->m_scale.getPointer());
Shinya Kitaoka 120a6e
    m_posPath->copy(src->m_posPath.getPointer());
Shinya Kitaoka 120a6e
    m_shearx->copy(src->m_shearx.getPointer());
Shinya Kitaoka 120a6e
    m_sheary->copy(src->m_sheary.getPointer());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (src->m_skeletonDeformation)
Shinya Kitaoka 120a6e
      setPlasticSkeletonDeformation(
Shinya Kitaoka 120a6e
          new PlasticSkeletonDeformation(*src->m_skeletonDeformation));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_x = src->m_x.getPointer();
Shinya Kitaoka 120a6e
    m_x->addObserver(this);
Shinya Kitaoka 120a6e
    m_y = src->m_y.getPointer();
Shinya Kitaoka 120a6e
    m_y->addObserver(this);
Shinya Kitaoka 120a6e
    m_z = src->m_z.getPointer();
Shinya Kitaoka 120a6e
    m_z->addObserver(this);
Shinya Kitaoka 120a6e
    m_so = src->m_so.getPointer();
Shinya Kitaoka 120a6e
    m_so->addObserver(this);
Shinya Kitaoka 120a6e
    m_rot = src->m_rot.getPointer();
Shinya Kitaoka 120a6e
    m_rot->addObserver(this);
Shinya Kitaoka 120a6e
    m_scalex = src->m_scalex.getPointer();
Shinya Kitaoka 120a6e
    m_scalex->addObserver(this);
Shinya Kitaoka 120a6e
    m_scaley = src->m_scaley.getPointer();
Shinya Kitaoka 120a6e
    m_scaley->addObserver(this);
Shinya Kitaoka 120a6e
    m_scale = src->m_scale.getPointer();
Shinya Kitaoka 120a6e
    m_scale->addObserver(this);
Shinya Kitaoka 120a6e
    m_posPath = src->m_posPath.getPointer();
Shinya Kitaoka 120a6e
    m_posPath->addObserver(this);
Shinya Kitaoka 120a6e
    m_shearx = src->m_shearx.getPointer();
Shinya Kitaoka 120a6e
    m_shearx->addObserver(this);
Shinya Kitaoka 120a6e
    m_sheary = src->m_sheary.getPointer();
Shinya Kitaoka 120a6e
    m_sheary->addObserver(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_skeletonDeformation = src->m_skeletonDeformation;
Shinya Kitaoka 120a6e
    if (m_skeletonDeformation) m_skeletonDeformation->addObserver(this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_handle       = src->m_handle;
Shinya Kitaoka 120a6e
  m_parentHandle = src->m_parentHandle;
Shinya Kitaoka 120a6e
shun-iwasawa 641c8e
  m_cycleEnabled = src->m_cycleEnabled;
Shinya Kitaoka 120a6e
  if (m_pinnedRangeSet) *m_pinnedRangeSet = *src->m_pinnedRangeSet;
Shinya Kitaoka 120a6e
  updateKeyframes();
Shinya Kitaoka 120a6e
  if (m_spline && isUppkEnabled()) m_spline->addParam(m_posPath.getPointer());
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// objectZ e' la posizione dell'oggetto lungo l'asse Z
Shinya Kitaoka 120a6e
//   il default e' 0. valori grandi rappresentano oggetti piu' vicini alla
Shinya Kitaoka 120a6e
//   camera
Toshihiro Shimizu 890ddd
//   la distanza iniziale fra tavolo e camera e' 1000
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// cameraZ e' la posizione della camera lungo l'asse Z
Shinya Kitaoka 120a6e
//   il default e' 0. valori negativi indicano che la camera si avvicina al
Shinya Kitaoka 120a6e
//   tavolo
Toshihiro Shimizu 890ddd
//   (che raggiungerebbe per un valore di -1000)
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::perspective(TAffine &aff, const TAffine &cameraAff,
Shinya Kitaoka 120a6e
                               double cameraZ, const TAffine &objectAff,
Shinya Kitaoka 120a6e
                               double objectZ, double objectNoScaleZ) {
Shinya Kitaoka 120a6e
  TPointD cameraPos(cameraAff.a13, cameraAff.a23);
Shinya Kitaoka 120a6e
  TPointD objectPos(objectAff.a13, objectAff.a23);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const double focus     = 1000;
Shinya Kitaoka 120a6e
  const double nearPlane = 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*--
Shinya Kitaoka 120a6e
   * dzはカメラとオブジェクトの間の距離、focus(=1000)はPegbarをZ軸方向に動かさなかった場合のデフォルト距離
Shinya Kitaoka 120a6e
   * --*/
Shinya Kitaoka 120a6e
  double dz = focus + cameraZ - objectZ;
Shinya Kitaoka 120a6e
  if (dz < nearPlane) {
Shinya Kitaoka 120a6e
    aff = TAffine();
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double noScaleSc = 1 - objectNoScaleZ / focus;
Shinya Kitaoka 120a6e
  aff = cameraAff * TScale((focus + cameraZ) / dz) * cameraAff.inv() *
Shinya Kitaoka 120a6e
        objectAff * TScale(noScaleSc);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TStageObject::setGroupId(int value) {
Shinya Kitaoka 120a6e
  m_groupSelector++;
Shinya Kitaoka 120a6e
  m_groupId.insert(m_groupSelector, value);
Shinya Kitaoka 120a6e
  return m_groupSelector;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setGroupId(int value, int position) {
Shinya Kitaoka 120a6e
  assert(position >= 0 && position <= m_groupId.size());
Shinya Kitaoka 120a6e
  m_groupId.insert(position, value);
Shinya Kitaoka 120a6e
  if (m_groupSelector + 1 >= position) m_groupSelector++;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TStageObject::getGroupId() {
Shinya Kitaoka 120a6e
  return m_groupId.isEmpty() || m_groupSelector < 0 ||
Shinya Kitaoka 120a6e
                 m_groupSelector >= m_groupId.size()
Shinya Kitaoka 120a6e
             ? 0
Shinya Kitaoka 120a6e
             : m_groupId[m_groupSelector];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QStack<int> TStageObject::getGroupIdStack() { return m_groupId; }</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::removeGroupId(int position) {
Shinya Kitaoka 120a6e
  if (!isGrouped()) return;
Shinya Kitaoka 120a6e
  assert(position >= 0 && position <= m_groupId.size());
Shinya Kitaoka 120a6e
  m_groupId.remove(position);
Shinya Kitaoka 120a6e
  if (m_groupSelector + 1 >= position && m_groupSelector > -1)
Shinya Kitaoka 120a6e
    m_groupSelector--;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TStageObject::removeGroupId() {
Shinya Kitaoka 120a6e
  m_groupId.remove(m_groupSelector);
Shinya Kitaoka 120a6e
  if (m_groupSelector > -1) m_groupSelector--;
Shinya Kitaoka 120a6e
  return m_groupSelector + 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isGrouped() { return !m_groupId.isEmpty(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isContainedInGroup(int groupId) {
Shinya Kitaoka 120a6e
  return m_groupId.contains(groupId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::setGroupName(const wstring &name, int position) {
Shinya Kitaoka 120a6e
  int groupSelector = position < 0 ? m_groupSelector : position;
Shinya Kitaoka 120a6e
  assert(groupSelector >= 0 && groupSelector <= m_groupName.size());
Shinya Kitaoka 120a6e
  m_groupName.insert(groupSelector, name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
wstring TStageObject::getGroupName(bool fromEditor) {
Shinya Kitaoka 120a6e
  int groupSelector = fromEditor ? m_groupSelector + 1 : m_groupSelector;
Shinya Kitaoka 120a6e
  return m_groupName.isEmpty() || groupSelector < 0 ||
Shinya Kitaoka 120a6e
                 groupSelector >= m_groupName.size()
Shinya Kitaoka 120a6e
             ? L""
Shinya Kitaoka 120a6e
             : m_groupName[groupSelector];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QStack<wstring> TStageObject::getGroupNameStack() { return m_groupName; }</wstring>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TStageObject::removeGroupName(bool fromEditor) {
Shinya Kitaoka 120a6e
  int groupSelector = fromEditor ? m_groupSelector + 1 : m_groupSelector;
Shinya Kitaoka 120a6e
  if (!isGrouped()) return -1;
Shinya Kitaoka 120a6e
  assert(groupSelector >= 0 && groupSelector <= m_groupName.size());
Shinya Kitaoka 120a6e
  m_groupName.remove(groupSelector);
Shinya Kitaoka 120a6e
  return groupSelector;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::removeGroupName(int position) {
Shinya Kitaoka 120a6e
  int groupSelector = position < 0 ? m_groupSelector : position;
Shinya Kitaoka 120a6e
  assert(groupSelector >= 0 && groupSelector <= m_groupName.size());
Shinya Kitaoka 120a6e
  m_groupName.remove(groupSelector);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::removeFromAllGroup() {
Shinya Kitaoka 120a6e
  m_groupId.clear();
Shinya Kitaoka 120a6e
  m_groupName.clear();
Shinya Kitaoka 120a6e
  m_groupSelector = -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::editGroup() { m_groupSelector--; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TStageObject::isGroupEditing() {
Shinya Kitaoka 120a6e
  return isGrouped() && m_groupSelector == -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TStageObject::closeEditingGroup(int groupId) {
Shinya Kitaoka 120a6e
  if (!m_groupId.contains(groupId)) return;
Shinya Kitaoka 120a6e
  m_groupSelector = 0;
Shinya Kitaoka 120a6e
  while (m_groupId[m_groupSelector] != groupId &&
Shinya Kitaoka 120a6e
         m_groupSelector < m_groupId.size())
Shinya Kitaoka 120a6e
    m_groupSelector++;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TStageObject::getEditingGroupId() {
Shinya Kitaoka 120a6e
  if (!isGrouped() || m_groupSelector + 1 >= m_groupId.size()) return -1;
Shinya Kitaoka 120a6e
  return m_groupId[m_groupSelector + 1];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
wstring TStageObject::getEditingGroupName() {
Shinya Kitaoka 120a6e
  if (!isGrouped() || m_groupSelector + 1 >= m_groupName.size()) return L"";
Shinya Kitaoka 120a6e
  return m_groupName[m_groupSelector + 1];
Toshihiro Shimizu 890ddd
}