1
2
3 #include "toonz/tstageobject.h"
4
5 // TnzLib includes
6 #include "toonz/tstageobjecttree.h"
7 #include "toonz/tstageobjectspline.h"
8 #include "toonz/txsheet.h"
9 #include "toonz/observer.h"
10 #include "toonz/txshlevelcolumn.h"
11 #include "toonz/txshcell.h"
12 #include "toonz/stage.h"
13 #include "toonz/tcamera.h"
14 #include "toonz/doubleparamcmd.h"
15 #include "toonz/tpinnedrangeset.h"
16
17 // TnzExt includes
18 #include "ext/plasticskeleton.h"
19 #include "ext/plasticskeletondeformation.h"
20 #include "ext/plasticdeformerstorage.h"
21
22 // TnzCore includes
23 #include "tstream.h"
24 #include "tstroke.h"
25 #include "tconvert.h"
26 #include "tundo.h"
27 #include "tconst.h"
28
29 // Qt includes
30 #include <QMetaObject>
31
32 // STD includes
33 #include <fstream>
34 #include <set>
35
36 using namespace std;
37
38 //
39 // Per un problema su alcune macchine, solo Release.
40 // il problema si verifica ruotando gli oggetti sul camera stand
41 //
42
43 #ifdef _MSC_VER
44 #pragma optimize("", off)
45 #endif
makeRotation(double ang)46 static TAffine makeRotation(double ang) { return TRotation(ang); }
47 #ifdef _MSC_VER
48 #pragma optimize("", on)
49 #endif
50
51 DEFINE_CLASS_CODE(TStageObject, 102)
52
53 //************************************************************************************************
54 // Local namespace
55 //************************************************************************************************
56
57 namespace {
58
59 enum StageObjectType {
60 NONE = 0,
61 CAMERA = 1,
62 TABLE = 2,
63 PEGBAR = 5,
64 COLUMN = 6
65 };
66
67 const int StageObjectTypeShift = 28;
68 const int StageObjectMaxIndex = ((1 << StageObjectTypeShift) - 1);
69 const int StageObjectIndexMask = ((1 << StageObjectTypeShift) - 1);
70
71 } // namespace
72
73 //************************************************************************************************
74 // TStageObjectParams implementation
75 //************************************************************************************************
76
TStageObjectParams()77 TStageObjectParams::TStageObjectParams() : m_spline(0), m_noScaleZ(0) {}
78
79 //-----------------------------------------------------------------------------
80
TStageObjectParams(TStageObjectParams * data)81 TStageObjectParams::TStageObjectParams(TStageObjectParams *data)
82 : m_id(data->m_id)
83 , m_parentId(data->m_parentId)
84 , m_children(data->m_children)
85 , m_keyframes(data->m_keyframes)
86 , m_cycleEnabled(data->m_cycleEnabled)
87 , m_spline(data->m_spline)
88 , m_status(data->m_status)
89 , m_handle(data->m_handle)
90 , m_parentHandle(data->m_parentHandle)
91 , m_x(data->m_x)
92 , m_y(data->m_y)
93 , m_z(data->m_z)
94 , m_so(data->m_so)
95 , m_rot(data->m_rot)
96 , m_scalex(data->m_scalex)
97 , m_scaley(data->m_scaley)
98 , m_scale(data->m_scale)
99 , m_posPath(data->m_posPath)
100 , m_shearx(data->m_shearx)
101 , m_sheary(data->m_sheary)
102 , m_skeletonDeformation(data->m_skeletonDeformation)
103 , m_noScaleZ(data->m_noScaleZ)
104 , m_center(data->m_center)
105 , m_offset(data->m_offset)
106 , m_name(data->m_name)
107 , m_isOpened(data->m_isOpened)
108 , m_pinnedRangeSet(data->m_pinnedRangeSet->clone()) {}
109
110 //---------------------------------------------------------------------------
111
~TStageObjectParams()112 TStageObjectParams::~TStageObjectParams() { delete m_pinnedRangeSet; }
113
114 //---------------------------------------------------------------------------
115
clone()116 TStageObjectParams *TStageObjectParams::clone() {
117 return new TStageObjectParams(this);
118 }
119
120 //===========================================================================
121 // Utility Functions
122 //---------------------------------------------------------------------------
123
toStageObjectId(string s)124 TStageObjectId toStageObjectId(string s) {
125 if (s == "None")
126 return TStageObjectId::NoneId;
127 else if (s == "Table")
128 return TStageObjectId::TableId;
129 else if (isInt(s)) {
130 TStageObjectId id;
131 id.setCode(std::stoi(s));
132 return id;
133 } else if (s.length() > 3) {
134 if (s.substr(0, 3) == "Col")
135 return TStageObjectId::ColumnId(std::stoi(s.substr(3)) - 1);
136 else if (s.substr(0, 3) == "Peg")
137 return TStageObjectId::PegbarId(std::stoi(s.substr(3)) - 1);
138 else if (s.length() > 6 && s.substr(0, 6) == "Camera")
139 return TStageObjectId::CameraId(std::stoi(s.substr(6)) - 1);
140 }
141 return TStageObjectId::NoneId;
142 }
143
144 //-----------------------------------------------------------------------------
145
operator <<(ostream & out,const TStageObjectId & id)146 ostream &operator<<(ostream &out, const TStageObjectId &id) {
147 return out << id.toString();
148 }
149
150 //************************************************************************************************
151 // TStageObjectId implementation
152 //************************************************************************************************
153
TStageObjectId()154 TStageObjectId::TStageObjectId() : m_id(NONE << StageObjectTypeShift) {}
155
156 //-----------------------------------------------------------------------------
157
~TStageObjectId()158 TStageObjectId::~TStageObjectId() {}
159
160 //-----------------------------------------------------------------------------
161
isCamera() const162 bool TStageObjectId::isCamera() const {
163 return m_id >> StageObjectTypeShift == CAMERA;
164 }
165
166 //-----------------------------------------------------------------------------
167
isTable() const168 bool TStageObjectId::isTable() const {
169 return m_id >> StageObjectTypeShift == TABLE;
170 }
171
172 //-----------------------------------------------------------------------------
173
isPegbar() const174 bool TStageObjectId::isPegbar() const {
175 return m_id >> StageObjectTypeShift == PEGBAR;
176 }
177
178 //-----------------------------------------------------------------------------
179
isColumn() const180 bool TStageObjectId::isColumn() const {
181 return m_id >> StageObjectTypeShift == COLUMN;
182 }
183
184 //-----------------------------------------------------------------------------
185
186 const TStageObjectId TStageObjectId::NoneId(NONE << StageObjectTypeShift);
187
188 //-----------------------------------------------------------------------------
189
190 const TStageObjectId TStageObjectId::TableId(TABLE << StageObjectTypeShift);
191
192 //-----------------------------------------------------------------------------
193
CameraId(int index)194 const TStageObjectId TStageObjectId::CameraId(int index) {
195 assert(0 <= index && index <= StageObjectMaxIndex);
196 return TStageObjectId(CAMERA << StageObjectTypeShift | index);
197 }
198
199 //-----------------------------------------------------------------------------
200
PegbarId(int index)201 const TStageObjectId TStageObjectId::PegbarId(int index) {
202 assert(0 <= index && index <= StageObjectMaxIndex);
203 return TStageObjectId(PEGBAR << StageObjectTypeShift | index);
204 }
205
206 //-----------------------------------------------------------------------------
207
ColumnId(int index)208 const TStageObjectId TStageObjectId::ColumnId(int index) {
209 assert(0 <= index && index <= StageObjectMaxIndex);
210 return TStageObjectId(COLUMN << StageObjectTypeShift | index);
211 }
212
213 //-----------------------------------------------------------------------------
214
toString() const215 string TStageObjectId::toString() const {
216 int index = m_id & StageObjectIndexMask;
217 string shortName;
218 switch (m_id >> StageObjectTypeShift) {
219 case NONE:
220 shortName = "None";
221 break;
222 case CAMERA:
223 shortName = "Camera" + std::to_string(index + 1);
224 break;
225 case TABLE:
226 shortName = "Table";
227 break;
228 case PEGBAR:
229 shortName = "Peg" + std::to_string(index + 1);
230 break;
231 case COLUMN:
232 shortName = "Col" + std::to_string(index + 1);
233 break;
234 default:
235 shortName = "BadPegbar";
236 }
237 return shortName;
238 }
239
240 //-----------------------------------------------------------------------------
241
getIndex() const242 int TStageObjectId::getIndex() const { return m_id & StageObjectIndexMask; }
243
244 //=============================================================================
245 namespace { // TStageObject Utility
246 //-----------------------------------------------------------------------------
247
withFrame(TDoubleKeyframe k,double frame)248 TDoubleKeyframe withFrame(TDoubleKeyframe k, double frame) {
249 k.m_frame = frame;
250 return k;
251 }
252
253 //-----------------------------------------------------------------------------
254
setKeyframe(const TDoubleParamP & param,const TDoubleKeyframe & kf,int frame,const double & easeIn,const double & easeOut)255 bool setKeyframe(const TDoubleParamP ¶m, const TDoubleKeyframe &kf,
256 int frame, const double &easeIn, const double &easeOut) {
257 if (!kf.m_isKeyframe) return false;
258
259 TDoubleKeyframe kfCopy = kf;
260
261 kfCopy.m_frame = frame;
262 if (easeIn >= 0.0) kfCopy.m_speedIn = TPointD(-easeIn, kfCopy.m_speedIn.y);
263 if (easeOut >= 0.0) kfCopy.m_speedOut = TPointD(easeOut, kfCopy.m_speedOut.y);
264
265 param->setKeyframe(kfCopy);
266 return true;
267 }
268
269 //-----------------------------------------------------------------------------
270
setkey(const TDoubleParamP & param,int frame)271 void setkey(const TDoubleParamP ¶m, int frame) {
272 KeyframeSetter setter(param.getPointer(), -1, false);
273 setter.createKeyframe(frame);
274 }
275
276 //-----------------------------------------------------------------------------
277
updateUnit(TDoubleParam * param)278 void updateUnit(TDoubleParam *param) {
279 for (int i = 0; i < param->getKeyframeCount(); i++) {
280 TDoubleKeyframe k = param->getKeyframe(i);
281 k.m_value /= Stage::inch;
282 param->setKeyframe(i, k);
283 }
284 }
285
286 //-----------------------------------------------------------------------------
287
convertTo4InchCenterUnits(string handle)288 string convertTo4InchCenterUnits(string handle) {
289 // per convenzione un handle del tipo 'a'..'z' utilizza
290 // la vecchia convenzione per i centri (4 inch invece di 8)
291 if (handle.length() == 1 && 'A' <= handle[0] && handle[0] <= 'Z' &&
292 handle[0] != 'B')
293 return string(1, handle[0] + 'a' - 'A');
294 else
295 return handle;
296 }
297
298 //-----------------------------------------------------------------------------
299
updateDagPosition(const TPointD & pos,const VersionNumber & tnzVersion)300 TPointD updateDagPosition(const TPointD &pos, const VersionNumber &tnzVersion) {
301 if (tnzVersion < VersionNumber(1, 16)) return TConst::nowhere;
302 return pos;
303 }
304
305 //-----------------------------------------------------------------------------
306
307 // Update the passed stage object keyframe and keyframe type specification with
308 // a new keyframe. Returns true if specifications match, false otherwise.
touchEaseAndCompare(const TDoubleKeyframe & kf,TStageObject::Keyframe & stageKf,TDoubleKeyframe::Type & type)309 bool touchEaseAndCompare(const TDoubleKeyframe &kf,
310 TStageObject::Keyframe &stageKf,
311 TDoubleKeyframe::Type &type) {
312 bool initialization = (type == TDoubleKeyframe::None);
313
314 if (initialization) type = kf.m_type;
315
316 if (kf.m_type != type || (kf.m_type != TDoubleKeyframe::SpeedInOut &&
317 kf.m_type != TDoubleKeyframe::EaseInOut &&
318 (kf.m_prevType != TDoubleKeyframe::None &&
319 kf.m_prevType != TDoubleKeyframe::SpeedInOut &&
320 kf.m_prevType != TDoubleKeyframe::EaseInOut))) {
321 stageKf.m_easeIn = -1.0;
322 stageKf.m_easeOut = -1.0;
323
324 return false;
325 }
326
327 double easeIn = -kf.m_speedIn.x;
328 if (initialization)
329 stageKf.m_easeIn = easeIn;
330 else if (stageKf.m_easeIn != easeIn)
331 stageKf.m_easeIn = -1.0;
332
333 double easeOut = kf.m_speedOut.x;
334 if (initialization)
335 stageKf.m_easeOut = easeOut;
336 else if (stageKf.m_easeOut != easeOut)
337 stageKf.m_easeOut = -1.0;
338
339 return true;
340 }
341
342 //-----------------------------------------------------------------------------
343 } // namespace
344 //-----------------------------------------------------------------------------
345
346 //************************************************************************************************
347 // TStageObject::LazyData implementation
348 //************************************************************************************************
349
LazyData()350 TStageObject::LazyData::LazyData() : m_time(-1.0) {}
351
352 //************************************************************************************************
353 // TStageObject implementation
354 //************************************************************************************************
355
TStageObject(TStageObjectTree * tree,TStageObjectId id)356 TStageObject::TStageObject(TStageObjectTree *tree, TStageObjectId id)
357 : m_tree(tree)
358 , m_id(id)
359 , m_parent(0)
360 , m_name("")
361 , m_isOpened(false)
362 , m_spline(0)
363 , m_status(XY)
364 , m_x(new TDoubleParam())
365 , m_y(new TDoubleParam())
366 , m_z(new TDoubleParam())
367 , m_so(new TDoubleParam())
368 , m_rot(new TDoubleParam())
369 , m_scalex(new TDoubleParam(1.0))
370 , m_scaley(new TDoubleParam(1.0))
371 , m_scale(new TDoubleParam(1.0))
372 , m_posPath(new TDoubleParam())
373 , m_shearx(new TDoubleParam())
374 , m_sheary(new TDoubleParam())
375 , m_center()
376 , m_offset()
377 , m_cycleEnabled(false)
378 , m_handle("B")
379 , m_parentHandle("B")
380 , m_dagNodePos(TConst::nowhere)
381 , m_camera(0)
382 , m_locked(false)
383 , m_noScaleZ(0)
384 , m_pinnedRangeSet(0)
385 , m_ikflag(0)
386 , m_groupSelector(-1) {
387 // NOTA: per le unita' di misura controlla anche tooloptions.cpp
388 m_x->setName("W_X");
389 m_x->setMeasureName("length.x");
390 m_x->addObserver(this);
391
392 m_y->setName("W_Y");
393 m_y->setMeasureName("length.y");
394 m_y->addObserver(this);
395
396 m_z->setName("W_Z");
397 m_z->setMeasureName(id.isCamera() ? "zdepth.cam" : "zdepth");
398 m_z->addObserver(this);
399
400 m_so->setName("W_SO");
401 m_so->addObserver(this);
402
403 m_rot->setName("W_Rotation");
404 m_rot->setMeasureName("angle");
405 m_rot->addObserver(this);
406
407 m_scalex->setName("W_ScaleH");
408 m_scalex->setMeasureName("scale");
409 m_scalex->addObserver(this);
410
411 m_scaley->setName("W_ScaleV");
412 m_scaley->setMeasureName("scale");
413 m_scaley->addObserver(this);
414
415 m_scale->setName("W_Scale");
416 m_scale->setMeasureName("scale");
417 m_scale->addObserver(this);
418
419 m_shearx->setName("W_ShearH");
420 m_shearx->setMeasureName("shear");
421 m_shearx->addObserver(this);
422
423 m_sheary->setName("W_ShearV");
424 m_sheary->setMeasureName("shear");
425 m_sheary->addObserver(this);
426
427 m_posPath->setName("posPath");
428 m_posPath->setMeasureName("percentage2");
429 m_posPath->addObserver(this);
430
431 m_tree->setGrammar(m_x);
432 m_tree->setGrammar(m_y);
433 m_tree->setGrammar(m_z);
434 m_tree->setGrammar(m_so);
435 m_tree->setGrammar(m_rot);
436 m_tree->setGrammar(m_scalex);
437 m_tree->setGrammar(m_scaley);
438 m_tree->setGrammar(m_scale);
439 m_tree->setGrammar(m_shearx);
440 m_tree->setGrammar(m_sheary);
441 m_tree->setGrammar(m_posPath);
442
443 if (id.isCamera()) m_camera = new TCamera();
444
445 m_pinnedRangeSet = new TPinnedRangeSet();
446 }
447
448 //-----------------------------------------------------------------------------
449
~TStageObject()450 TStageObject::~TStageObject() {
451 if (m_spline) {
452 if (m_posPath) m_spline->removeParam(m_posPath.getPointer());
453 m_spline->release();
454 }
455
456 if (m_x) m_x->removeObserver(this);
457 if (m_y) m_y->removeObserver(this);
458 if (m_z) m_z->removeObserver(this);
459 if (m_so) m_so->removeObserver(this);
460 if (m_rot) m_rot->removeObserver(this);
461 if (m_scalex) m_scalex->removeObserver(this);
462 if (m_scaley) m_scaley->removeObserver(this);
463 if (m_scale) m_scale->removeObserver(this);
464 if (m_shearx) m_shearx->removeObserver(this);
465 if (m_sheary) m_sheary->removeObserver(this);
466 if (m_posPath) m_posPath->removeObserver(this);
467
468 if (m_skeletonDeformation) {
469 PlasticDeformerStorage::instance()->releaseDeformationData(
470 m_skeletonDeformation.getPointer());
471 m_skeletonDeformation->removeObserver(this);
472 }
473
474 delete m_camera;
475 delete m_pinnedRangeSet;
476 }
477
478 //-----------------------------------------------------------------------------
479
lazyData() const480 const TStageObject::LazyData &TStageObject::lazyData() const {
481 return m_lazyData([this](LazyData &ld) { this->update(ld); });
482 }
483
484 //-----------------------------------------------------------------------------
485
lazyData()486 TStageObject::LazyData &TStageObject::lazyData() {
487 return const_cast<LazyData &>(
488 static_cast<const TStageObject &>(*this).lazyData());
489 }
490
491 //-----------------------------------------------------------------------------
492
update(LazyData & ld) const493 void TStageObject::update(LazyData &ld) const {
494 if (ld.m_time >= 0.0) invalidate(ld);
495
496 updateKeyframes(ld);
497 }
498
499 //-----------------------------------------------------------------------------
500
onChange(const class TParamChange & c)501 void TStageObject::onChange(const class TParamChange &c) {
502 // Rationale: Since a stage object holds many parameters (or par references),
503 // it may receive multiple notifications at the same time - but it should
504 // actually refresh its data only ONCE for 'em all.
505
506 // Even worse, the stage object may be notified for EACH touched key of just
507 // one of its parameters. This means this function gets called A LOT.
508
509 // Thus, we're just SCHEDULING for a data refresh. The actual refresh happens
510 // whenever the scheduled data is accessed.
511
512 if (c.m_keyframeChanged)
513 m_lazyData.invalidate(); // Both invalidate placement AND keyframes
514 else
515 invalidate(); // Invalidate placement only
516 }
517
518 //-----------------------------------------------------------------------------
519
getId() const520 TStageObjectId TStageObject::getId() const { return m_id; }
521
522 //-----------------------------------------------------------------------------
523
paramsTime(double t) const524 double TStageObject::paramsTime(double t) const {
525 const KeyframeMap &keyframes = lazyData().m_keyframes;
526
527 if (m_cycleEnabled && keyframes.size() > 1) {
528 int firstT = keyframes.begin()->first;
529 if (t <= firstT) return t;
530 int lastT = keyframes.rbegin()->first;
531 int tRange = lastT - firstT + 1;
532 assert(tRange > 0);
533 int it = tfloor(t);
534 double ft = t - it;
535 return firstT + ((it - firstT) % tRange) + ft;
536 } else
537 return t;
538 }
539
540 //-----------------------------------------------------------------------------
541
setName(const std::string & name)542 void TStageObject::setName(const std::string &name) {
543 m_name = (name == m_id.toString()) ? std::string() : name;
544 }
545
546 //-----------------------------------------------------------------------------
547
getName() const548 string TStageObject::getName() const {
549 if (m_name != "") return m_name;
550 if (!m_id.isColumn()) return m_id.toString();
551 return "Col" + std::to_string(m_id.getIndex() + 1);
552 }
553
554 //-----------------------------------------------------------------------------
555
getFullName() const556 string TStageObject::getFullName() const {
557 string name = getName();
558 if (m_id.isColumn()) {
559 if (name.find("Col") == 0 && name.length() > 3 &&
560 name.find_first_not_of("0123456789", 3) == string::npos)
561 return name;
562 else
563 return name + " (" + std::to_string(m_id.getIndex() + 1) + ")";
564 } else
565 return name;
566 }
567
568 //-----------------------------------------------------------------------------
569
setParent(const TStageObjectId & parentId)570 void TStageObject::setParent(const TStageObjectId &parentId) {
571 assert(m_tree);
572 TStageObject *newParent = 0;
573 if (parentId != TStageObjectId::NoneId) {
574 newParent = m_tree->getStageObject(parentId);
575 assert(newParent);
576
577 // cerco di evitare i cicli
578 TStageObject *p = newParent;
579 while (p->m_parent) {
580 if (p->m_parent->getId() == getId()) return;
581 p = p->m_parent;
582 }
583 } else {
584 if (!m_id.isCamera() && !m_id.isTable()) {
585 newParent = m_tree->getStageObject(TStageObjectId::TableId);
586 assert(newParent);
587 }
588 }
589
590 if (m_parent) m_parent->m_children.remove(this);
591
592 m_parent = newParent;
593 if (m_parent) m_parent->m_children.insert(m_parent->m_children.end(), this);
594 invalidate();
595
596 #ifndef NDEBUG
597 if (m_id.isCamera()) {
598 } else if (m_id.isTable()) {
599 assert(m_parent == 0);
600 } else if (m_id.isColumn()) {
601 assert(m_parent &&
602 (m_parent->m_id.isTable() || m_parent->m_id.isColumn() ||
603 m_parent->m_id.isPegbar() || m_parent->m_id.isCamera()));
604 } else if (m_id.isPegbar()) {
605 assert(m_parent && (m_parent->m_id.isTable() || m_parent->m_id.isCamera() ||
606 m_parent->m_id.isPegbar()));
607 } else {
608 assert(0);
609 }
610 #endif
611 }
612
613 //-----------------------------------------------------------------------------
614
detachFromParent()615 void TStageObject::detachFromParent() {
616 if (m_parent) m_parent->m_children.remove(this);
617 m_parent = 0;
618 invalidate();
619 }
620
621 //-----------------------------------------------------------------------------
622
attachChildrenToParent(const TStageObjectId & parentId)623 void TStageObject::attachChildrenToParent(const TStageObjectId &parentId) {
624 while (!m_children.empty()) {
625 TStageObject *son = *m_children.begin();
626 if (son) son->setParent(parentId);
627 }
628 }
629
630 //-----------------------------------------------------------------------------
631
getParent() const632 TStageObjectId TStageObject::getParent() const {
633 return m_parent ? m_parent->m_id : TStageObjectId();
634 }
635
636 //-----------------------------------------------------------------------------
637
isAncestor(TStageObject * stageObject) const638 bool TStageObject::isAncestor(TStageObject *stageObject) const {
639 if (!stageObject) return false;
640 if (stageObject == (TStageObject *)m_parent)
641 return true;
642 else if (m_parent == 0)
643 return false;
644 else
645 return m_parent->isAncestor(stageObject);
646 }
647
648 //-----------------------------------------------------------------------------
649
getSpline() const650 TStageObjectSpline *TStageObject::getSpline() const { return m_spline; }
651
652 //-----------------------------------------------------------------------------
653
doSetSpline(TStageObjectSpline * spline)654 void TStageObject::doSetSpline(TStageObjectSpline *spline) {
655 TDoubleParam *param = m_posPath.getPointer();
656 bool uppkEnabled = isUppkEnabled();
657 if (!spline) {
658 if (uppkEnabled && m_spline) m_spline->removeParam(param);
659 if (m_spline) m_spline->release();
660 m_spline = 0;
661 enablePath(false);
662 } else {
663 if (m_spline != spline) {
664 if (m_spline && uppkEnabled) m_spline->removeParam(param);
665 if (m_spline) m_spline->release();
666 m_spline = spline;
667 m_spline->addRef();
668 if (m_spline && uppkEnabled) m_spline->addParam(param);
669 }
670 if (!isPathEnabled()) enablePath(true);
671 }
672 }
673
674 //-----------------------------------------------------------------------------
675
setSpline(TStageObjectSpline * spline)676 void TStageObject::setSpline(TStageObjectSpline *spline) {
677 doSetSpline(spline);
678 TNotifier::instance()->notify(TXsheetChange());
679 TNotifier::instance()->notify(TStageChange());
680 invalidate();
681 }
682
683 //-----------------------------------------------------------------------------
684
setStatus(Status status)685 void TStageObject::setStatus(Status status) {
686 if (m_status == status) return;
687 bool oldPathEnabled = isPathEnabled();
688 bool oldUppkEnabled = isUppkEnabled();
689 m_status = status;
690 bool pathEnabled = isPathEnabled();
691 bool uppkEnabled = isUppkEnabled();
692
693 if (pathEnabled) {
694 if (!m_spline)
695 doSetSpline(m_tree->createSpline());
696 else if (oldUppkEnabled != uppkEnabled) {
697 TDoubleParam *param = getParam(T_Path);
698 if (uppkEnabled)
699 m_spline->addParam(param);
700 else
701 m_spline->removeParam(param);
702 }
703 } else {
704 doSetSpline(0);
705 }
706 invalidate();
707 }
708
709 //-----------------------------------------------------------------------------
710
enableAim(bool enabled)711 void TStageObject::enableAim(bool enabled) {
712 setStatus((Status)((m_status & ~STATUS_MASK) | (enabled ? PATH_AIM : PATH)));
713 }
714
715 //-----------------------------------------------------------------------------
716
enablePath(bool enabled)717 void TStageObject::enablePath(bool enabled) {
718 if (isPathEnabled() != enabled) setStatus(enabled ? PATH : XY);
719 }
720
721 //-----------------------------------------------------------------------------
722
enableUppk(bool enabled)723 void TStageObject::enableUppk(bool enabled) {
724 assert(isPathEnabled());
725 setStatus((Status)((m_status & ~UPPK_MASK) | (enabled ? UPPK_MASK : 0)));
726 }
727
728 //-----------------------------------------------------------------------------
729
setCenter(double frame,const TPointD & center)730 void TStageObject::setCenter(double frame, const TPointD ¢er) {
731 TPointD c = center - getHandlePos(m_handle, (int)frame);
732
733 TAffine aff = computeLocalPlacement(frame);
734 TPointD delta = aff * c - aff * m_center;
735 m_center = c;
736 m_offset += delta;
737 invalidate();
738 }
739
740 //-----------------------------------------------------------------------------
741
getCenter(double frame) const742 TPointD TStageObject::getCenter(double frame) const {
743 return m_center + getHandlePos(m_handle, (int)frame);
744 }
745
746 //-----------------------------------------------------------------------------
747
getOffset() const748 TPointD TStageObject::getOffset() const { return m_offset; }
749
750 //-----------------------------------------------------------------------------
751
setOffset(const TPointD & off)752 void TStageObject::setOffset(const TPointD &off) {
753 m_offset = off;
754 invalidate();
755 }
756
757 //-----------------------------------------------------------------------------
758
getCenterAndOffset(TPointD & center,TPointD & offset) const759 void TStageObject::getCenterAndOffset(TPointD ¢er, TPointD &offset) const {
760 center = m_center;
761 offset = m_offset;
762 }
763
764 //-----------------------------------------------------------------------------
765
setCenterAndOffset(const TPointD & center,const TPointD & offset)766 void TStageObject::setCenterAndOffset(const TPointD ¢er,
767 const TPointD &offset) {
768 m_center = center;
769 m_offset = offset;
770 invalidate();
771 }
772
773 //-----------------------------------------------------------------------------
774
setHandle(const std::string & s)775 void TStageObject::setHandle(const std::string &s) {
776 m_handle = s;
777 if (!s.empty() && s[0] == 'H') m_offset = m_center = TPointD();
778
779 invalidate();
780 }
781
782 //-----------------------------------------------------------------------------
783
setParentHandle(const std::string & s)784 void TStageObject::setParentHandle(const std::string &s) {
785 m_parentHandle = s;
786 invalidate();
787 }
788
789 //-----------------------------------------------------------------------------
790
getHandlePos(string handle,int row) const791 TPointD TStageObject::getHandlePos(string handle, int row) const {
792 double unit = 8;
793 if (handle == "")
794 return TPointD();
795 else if (handle.length() > 1 && handle[0] == 'H')
796 return m_tree->getHandlePos(m_id, handle, row);
797 else if (handle.length() == 1 && 'A' <= handle[0] && handle[0] <= 'Z')
798 return TPointD(unit * (handle[0] - 'B'), 0);
799 else if (handle.length() == 1 && 'a' <= handle[0] && handle[0] <= 'z')
800 return TPointD(0.5 * unit * (handle[0] - 'b'), 0);
801 else
802 return TPointD(0, 0);
803 }
804
805 //-----------------------------------------------------------------------------
806
isKeyframe(int frame) const807 bool TStageObject::isKeyframe(int frame) const {
808 const KeyframeMap &keyframes = lazyData().m_keyframes;
809 return keyframes.find(frame) != keyframes.end();
810 }
811
812 //-----------------------------------------------------------------------------
813
is52FullKeyframe(int frame) const814 bool TStageObject::is52FullKeyframe(int frame) const {
815 return m_rot->isKeyframe(frame) && m_x->isKeyframe(frame) &&
816 m_y->isKeyframe(frame) && m_z->isKeyframe(frame) &&
817 m_posPath->isKeyframe(frame) && m_scalex->isKeyframe(frame) &&
818 m_scaley->isKeyframe(frame) && m_shearx->isKeyframe(frame) &&
819 m_sheary->isKeyframe(frame);
820 }
821
822 //-----------------------------------------------------------------------------
823
isFullKeyframe(int frame) const824 bool TStageObject::isFullKeyframe(int frame) const {
825 return m_rot->isKeyframe(frame) && m_x->isKeyframe(frame) &&
826 m_y->isKeyframe(frame) && m_z->isKeyframe(frame) &&
827 m_so->isKeyframe(frame) && m_posPath->isKeyframe(frame) &&
828 m_scalex->isKeyframe(frame) && m_scaley->isKeyframe(frame) &&
829 m_scale->isKeyframe(frame) && m_shearx->isKeyframe(frame) &&
830 m_sheary->isKeyframe(frame);
831 }
832
833 //-----------------------------------------------------------------------------
834
getKeyframe(int frame) const835 TStageObject::Keyframe TStageObject::getKeyframe(int frame) const {
836 const KeyframeMap &keyframes = lazyData().m_keyframes;
837
838 std::map<int, TStageObject::Keyframe>::const_iterator it;
839 it = keyframes.find(frame);
840 if (it == keyframes.end()) {
841 TStageObject::Keyframe k;
842 k.m_channels[TStageObject::T_Angle] = m_rot->getValue(frame);
843 k.m_channels[TStageObject::T_X] = m_x->getValue(frame);
844 k.m_channels[TStageObject::T_Y] = m_y->getValue(frame);
845 k.m_channels[TStageObject::T_Z] = m_z->getValue(frame);
846 k.m_channels[TStageObject::T_SO] = m_so->getValue(frame);
847 k.m_channels[TStageObject::T_ScaleX] = m_scalex->getValue(frame);
848 k.m_channels[TStageObject::T_ScaleY] = m_scaley->getValue(frame);
849 k.m_channels[TStageObject::T_Scale] = m_scale->getValue(frame);
850 k.m_channels[TStageObject::T_Path] = m_posPath->getValue(frame);
851 k.m_channels[TStageObject::T_ShearX] = m_shearx->getValue(frame);
852 k.m_channels[TStageObject::T_ShearY] = m_sheary->getValue(frame);
853
854 if (m_skeletonDeformation)
855 m_skeletonDeformation->getKeyframeAt(frame, k.m_skeletonKeyframe);
856
857 k.m_isKeyframe = false;
858 return k;
859 } else
860 return it->second;
861 }
862
863 //-----------------------------------------------------------------------------
864
setKeyframeWithoutUndo(int frame,const TStageObject::Keyframe & k)865 void TStageObject::setKeyframeWithoutUndo(int frame,
866 const TStageObject::Keyframe &k) {
867 KeyframeMap &keyframes = lazyData().m_keyframes;
868
869 bool keyWasSet = false;
870 keyWasSet = ::setKeyframe(m_rot, k.m_channels[TStageObject::T_Angle], frame,
871 k.m_easeIn, k.m_easeOut) ||
872 keyWasSet;
873 keyWasSet = ::setKeyframe(m_x, k.m_channels[TStageObject::T_X], frame,
874 k.m_easeIn, k.m_easeOut) ||
875 keyWasSet;
876 keyWasSet = ::setKeyframe(m_y, k.m_channels[TStageObject::T_Y], frame,
877 k.m_easeIn, k.m_easeOut) ||
878 keyWasSet;
879 keyWasSet = ::setKeyframe(m_z, k.m_channels[TStageObject::T_Z], frame,
880 k.m_easeIn, k.m_easeOut) ||
881 keyWasSet;
882 keyWasSet = ::setKeyframe(m_so, k.m_channels[TStageObject::T_SO], frame,
883 k.m_easeIn, k.m_easeOut) ||
884 keyWasSet;
885 keyWasSet = ::setKeyframe(m_posPath, k.m_channels[TStageObject::T_Path],
886 frame, k.m_easeIn, k.m_easeOut) ||
887 keyWasSet;
888 keyWasSet = ::setKeyframe(m_scalex, k.m_channels[TStageObject::T_ScaleX],
889 frame, k.m_easeIn, k.m_easeOut) ||
890 keyWasSet;
891 keyWasSet = ::setKeyframe(m_scaley, k.m_channels[TStageObject::T_ScaleY],
892 frame, k.m_easeIn, k.m_easeOut) ||
893 keyWasSet;
894 keyWasSet = ::setKeyframe(m_scale, k.m_channels[TStageObject::T_Scale], frame,
895 k.m_easeIn, k.m_easeOut) ||
896 keyWasSet;
897 keyWasSet = ::setKeyframe(m_shearx, k.m_channels[TStageObject::T_ShearX],
898 frame, k.m_easeIn, k.m_easeOut) ||
899 keyWasSet;
900 keyWasSet = ::setKeyframe(m_sheary, k.m_channels[TStageObject::T_ShearY],
901 frame, k.m_easeIn, k.m_easeOut) ||
902 keyWasSet;
903
904 if (m_skeletonDeformation)
905 keyWasSet = m_skeletonDeformation->setKeyframe(k.m_skeletonKeyframe, frame,
906 k.m_easeIn, k.m_easeOut) ||
907 keyWasSet;
908
909 if (keyWasSet) keyframes[frame] = k;
910
911 invalidate();
912 }
913
914 //-----------------------------------------------------------------------------
915
setKeyframeWithoutUndo(int frame)916 void TStageObject::setKeyframeWithoutUndo(int frame) {
917 if (isFullKeyframe(frame)) return;
918
919 setkey(m_x, frame);
920 setkey(m_y, frame);
921 setkey(m_z, frame);
922 setkey(m_so, frame);
923 setkey(m_posPath, frame);
924 setkey(m_rot, frame);
925 setkey(m_scalex, frame);
926 setkey(m_scaley, frame);
927 setkey(m_scale, frame);
928 setkey(m_shearx, frame);
929 setkey(m_sheary, frame);
930
931 // Plastic keys are currently not *created* by xsheet commands.
932
933 /*if(m_skeletonDeformation)
934 {
935 const PlasticSkeleton* skeleton = m_skeletonDeformation->skeleton();
936 const tcg::list<PlasticSkeleton::vertex_type>& vertices = skeleton->vertices();
937
938 tcg::list<PlasticSkeleton::vertex_type>::const_iterator vt,
939 vEnd(vertices.end());
940 for(vt = vertices.begin(); vt != vertices.end(); ++vt)
941 {
942 SkVD* vd = m_skeletonDeformation->vertexDeformation(vt->name());
943 assert(vd);
944
945 for(int p=0; p<SkVD::PARAMS_COUNT; ++p)
946 setkey(vd->m_params[p], frame);
947 }
948 }*/
949 }
950
951 //-----------------------------------------------------------------------------
952
removeKeyframeWithoutUndo(int frame)953 void TStageObject::removeKeyframeWithoutUndo(int frame) {
954 KeyframeMap &keyframes = lazyData().m_keyframes;
955 double &time = lazyData().m_time;
956
957 if (!isKeyframe(frame)) return;
958
959 keyframes.erase(frame);
960 m_rot->deleteKeyframe(frame);
961 m_x->deleteKeyframe(frame);
962 m_y->deleteKeyframe(frame);
963 m_z->deleteKeyframe(frame);
964 m_so->deleteKeyframe(frame);
965 m_scalex->deleteKeyframe(frame);
966 m_scaley->deleteKeyframe(frame);
967 m_scale->deleteKeyframe(frame);
968 m_posPath->deleteKeyframe(frame);
969 m_shearx->deleteKeyframe(frame);
970 m_sheary->deleteKeyframe(frame);
971
972 if (m_skeletonDeformation) m_skeletonDeformation->deleteKeyframe(frame);
973
974 time = -1;
975 if ((int)keyframes.size() < 2) m_cycleEnabled = false;
976
977 invalidate();
978 }
979
980 //-----------------------------------------------------------------------------
981
moveKeyframe(int dst,int src)982 bool TStageObject::moveKeyframe(int dst, int src) {
983 assert(dst != src);
984 if (isKeyframe(dst) || !isKeyframe(src)) return false;
985 setKeyframeWithoutUndo(dst, getKeyframe(src));
986 removeKeyframeWithoutUndo(src);
987 assert(isKeyframe(dst));
988 assert(!isKeyframe(src));
989 invalidate();
990 return true;
991 }
992
993 //-----------------------------------------------------------------------------
994
canMoveKeyframes(std::set<int> & frames,int delta)995 bool TStageObject::canMoveKeyframes(std::set<int> &frames, int delta) {
996 if (delta == 0) return false;
997 std::set<int>::iterator it;
998 for (it = frames.begin(); it != frames.end(); ++it) {
999 int f = *it;
1000 if (!isKeyframe(f)) return false;
1001 f += delta;
1002 if (f < 0) return false;
1003 if (frames.find(f) == frames.end() && isKeyframe(f)) return false;
1004 }
1005 return true;
1006 }
1007
1008 //-----------------------------------------------------------------------------
1009
moveKeyframes(std::set<int> & frames,int delta)1010 bool TStageObject::moveKeyframes(std::set<int> &frames, int delta) {
1011 if (!canMoveKeyframes(frames, delta)) return false;
1012 if (delta < 0) {
1013 std::set<int>::iterator it;
1014 for (it = frames.begin(); it != frames.end(); ++it) {
1015 bool ret = moveKeyframe(*it + delta, *it);
1016 assert(ret);
1017 }
1018 } else {
1019 std::set<int>::reverse_iterator ti;
1020 for (ti = frames.rbegin(); ti != frames.rend(); ++ti) {
1021 bool ret = moveKeyframe(*ti + delta, *ti);
1022 assert(ret);
1023 }
1024 }
1025 return true;
1026 }
1027
1028 //-----------------------------------------------------------------------------
1029
getKeyframes(KeyframeMap & keyframes) const1030 void TStageObject::getKeyframes(KeyframeMap &keyframes) const {
1031 keyframes = lazyData().m_keyframes;
1032 }
1033
1034 //-----------------------------------------------------------------------------
1035
getKeyframeRange(int & r0,int & r1) const1036 bool TStageObject::getKeyframeRange(int &r0, int &r1) const {
1037 const KeyframeMap &keyframes = lazyData().m_keyframes;
1038
1039 if (keyframes.empty()) {
1040 r0 = 0;
1041 r1 = -1;
1042 return false;
1043 }
1044 r0 = keyframes.begin()->first;
1045 r1 = keyframes.rbegin()->first;
1046
1047 return true;
1048 }
1049
1050 //-----------------------------------------------------------------------------
1051
getKeyframeSpan(int row,int & r0,double & ease0,int & r1,double & ease1) const1052 bool TStageObject::getKeyframeSpan(int row, int &r0, double &ease0, int &r1,
1053 double &ease1) const {
1054 const KeyframeMap &keyframes = lazyData().m_keyframes;
1055
1056 KeyframeMap::const_iterator it = keyframes.lower_bound(row);
1057 if (it == keyframes.end() || it == keyframes.begin() || it->first == row) {
1058 r0 = 0;
1059 r1 = -1;
1060 ease0 = ease1 = 0;
1061 return false;
1062 }
1063 r1 = it->first;
1064 ease1 = it->second.m_easeIn;
1065 --it;
1066 r0 = it->first;
1067 ease0 = it->second.m_easeOut;
1068
1069 return true;
1070 }
1071
1072 //-----------------------------------------------------------------------------
1073
setParam(Channel type,double frame,double val)1074 void TStageObject::setParam(Channel type, double frame, double val) {
1075 assert(0);
1076 }
1077
1078 //-----------------------------------------------------------------------------
1079
getParam(Channel type,double frame) const1080 double TStageObject::getParam(Channel type, double frame) const {
1081 switch (type) {
1082 case T_Angle:
1083 return m_rot->getValue(frame);
1084 case T_X:
1085 return m_x->getValue(frame);
1086 case T_Y:
1087 return m_y->getValue(frame);
1088 case T_Z:
1089 return m_z->getValue(frame);
1090 case T_SO:
1091 return m_so->getValue(frame);
1092 case T_ScaleX:
1093 return m_scalex->getValue(frame);
1094 case T_ScaleY:
1095 return m_scaley->getValue(frame);
1096 case T_Scale:
1097 return m_scale->getValue(frame);
1098 case T_Path:
1099 return m_posPath->getValue(frame);
1100 case T_ShearX:
1101 return m_shearx->getValue(frame);
1102 case T_ShearY:
1103 return m_sheary->getValue(frame);
1104
1105 default:
1106 assert(false);
1107 return 0;
1108 }
1109 }
1110
1111 //-----------------------------------------------------------------------------
1112
getParam(Channel channel) const1113 TDoubleParam *TStageObject::getParam(Channel channel) const {
1114 switch (channel) {
1115 case T_X:
1116 return m_x.getPointer();
1117 case T_Y:
1118 return m_y.getPointer();
1119 case T_Z:
1120 return m_z.getPointer();
1121 case T_SO:
1122 return m_so.getPointer();
1123 case T_Angle:
1124 return m_rot.getPointer();
1125 case T_Path:
1126 return m_posPath.getPointer();
1127 case T_ScaleX:
1128 return m_scalex.getPointer();
1129 case T_ScaleY:
1130 return m_scaley.getPointer();
1131 case T_Scale:
1132 return m_scale.getPointer();
1133 case T_ShearX:
1134 return m_shearx.getPointer();
1135 case T_ShearY:
1136 return m_sheary.getPointer();
1137 default:
1138 return 0;
1139 }
1140 }
1141
1142 //-----------------------------------------------------------------------------
1143
getPlasticSkeletonDeformation() const1144 PlasticSkeletonDeformationP TStageObject::getPlasticSkeletonDeformation()
1145 const {
1146 return m_skeletonDeformation;
1147 }
1148
1149 //-----------------------------------------------------------------------------
1150
setPlasticSkeletonDeformation(const PlasticSkeletonDeformationP & sd)1151 void TStageObject::setPlasticSkeletonDeformation(
1152 const PlasticSkeletonDeformationP &sd) {
1153 if (m_skeletonDeformation == sd) return;
1154
1155 if (m_skeletonDeformation) {
1156 PlasticDeformerStorage::instance()->releaseDeformationData(
1157 m_skeletonDeformation.getPointer());
1158
1159 m_skeletonDeformation->setGrammar(0);
1160 m_skeletonDeformation->removeObserver(this);
1161 }
1162
1163 m_skeletonDeformation = sd;
1164
1165 if (m_skeletonDeformation) {
1166 m_skeletonDeformation->setGrammar(m_tree->getGrammar());
1167 m_skeletonDeformation->addObserver(this);
1168 }
1169 }
1170
1171 //-----------------------------------------------------------------------------
1172
clone()1173 TStageObject *TStageObject::clone() {
1174 assert(m_tree);
1175 TStageObjectId pegId = getId();
1176 TStageObjectId newPegId = TStageObjectId::NoneId;
1177 int newIndex = pegId.getIndex();
1178 if (pegId.isCamera()) {
1179 while ((m_tree->getStageObject(TStageObjectId::CameraId(newIndex), false) !=
1180 0L) ||
1181 (pegId.getIndex() == newIndex))
1182 ++newIndex;
1183 newPegId = TStageObjectId::CameraId(newIndex);
1184 } else if (pegId.isColumn()) {
1185 while ((m_tree->getStageObject(TStageObjectId::ColumnId(newIndex), false) !=
1186 0L) ||
1187 (pegId.getIndex() == newIndex))
1188 ++newIndex;
1189 newPegId = TStageObjectId::ColumnId(newIndex);
1190 } else if (pegId.isPegbar()) {
1191 while ((m_tree->getStageObject(TStageObjectId::PegbarId(newIndex), false) !=
1192 0L) ||
1193 (pegId.getIndex() == newIndex))
1194 ++newIndex;
1195 newPegId = TStageObjectId::PegbarId(newIndex);
1196 } else {
1197 assert(!"Unknown stage object type");
1198 return 0L;
1199 }
1200 assert(newPegId != TStageObjectId::NoneId);
1201 assert(newIndex >= 0);
1202 assert(newPegId.getIndex() != pegId.getIndex());
1203
1204 // aggiunge lo stage object clonato nel stage object tree
1205 TStageObject *clonedPeg = m_tree->getStageObject(newPegId, true);
1206 TStageObject *cloned = clonedPeg;
1207 assert(cloned);
1208 assert(cloned->m_tree == m_tree);
1209
1210 KeyframeMap &keyframes = lazyData().m_keyframes;
1211 KeyframeMap &clonedKeyframes = cloned->lazyData().m_keyframes;
1212
1213 std::map<int, TStageObject::Keyframe>::iterator itKf = keyframes.begin();
1214 for (; itKf != keyframes.end(); ++itKf) {
1215 clonedKeyframes.insert(make_pair(itKf->first, itKf->second));
1216 }
1217 cloned->m_cycleEnabled = m_cycleEnabled;
1218 cloned->lazyData().m_time = lazyData().m_time;
1219 cloned->m_localPlacement = m_localPlacement;
1220 cloned->m_absPlacement = m_absPlacement;
1221 cloned->m_status = m_status;
1222 cloned->doSetSpline(m_spline);
1223
1224 cloned->m_x = static_cast<TDoubleParam *>(m_x->clone());
1225 cloned->m_y = static_cast<TDoubleParam *>(m_y->clone());
1226 cloned->m_z = static_cast<TDoubleParam *>(m_z->clone());
1227 cloned->m_so = static_cast<TDoubleParam *>(m_so->clone());
1228 cloned->m_rot = static_cast<TDoubleParam *>(m_rot->clone());
1229 cloned->m_scalex = static_cast<TDoubleParam *>(m_scalex->clone());
1230 cloned->m_scaley = static_cast<TDoubleParam *>(m_scaley->clone());
1231 cloned->m_scale = static_cast<TDoubleParam *>(m_scale->clone());
1232 cloned->m_posPath = static_cast<TDoubleParam *>(m_posPath->clone());
1233 cloned->m_shearx = static_cast<TDoubleParam *>(m_shearx->clone());
1234 cloned->m_sheary = static_cast<TDoubleParam *>(m_sheary->clone());
1235
1236 if (m_skeletonDeformation)
1237 cloned->m_skeletonDeformation =
1238 new PlasticSkeletonDeformation(*m_skeletonDeformation);
1239
1240 cloned->m_noScaleZ = m_noScaleZ;
1241 cloned->m_center = m_center;
1242 cloned->m_offset = m_offset;
1243 cloned->m_name = m_name;
1244 cloned->m_dagNodePos = m_dagNodePos;
1245
1246 return cloned;
1247 }
1248
1249 //-----------------------------------------------------------------------------
1250
isCycleEnabled() const1251 bool TStageObject::isCycleEnabled() const { return m_cycleEnabled; }
1252
1253 //-----------------------------------------------------------------------------
1254
enableCycle(bool on)1255 void TStageObject::enableCycle(bool on) { m_cycleEnabled = on; }
1256
1257 //-----------------------------------------------------------------------------
1258
findRoot(double frame) const1259 TStageObject *TStageObject::findRoot(double frame) const {
1260 if (!m_parent) return NULL;
1261
1262 TStageObject *parent = m_parent;
1263 while (parent->m_parent && parent->lazyData().m_time != frame)
1264 parent = parent->m_parent;
1265
1266 return parent;
1267 }
1268
1269 //-----------------------------------------------------------------------------
1270
getPinnedDescendant(int frame)1271 TStageObject *TStageObject::getPinnedDescendant(int frame) {
1272 if (getPinnedRangeSet()->isPinned(frame)) return this;
1273 for (list<TStageObject *>::iterator it = m_children.begin();
1274 it != m_children.end(); ++it) {
1275 TStageObject *child = *it;
1276 if (child->getPinnedRangeSet()->isPinned(frame)) return child;
1277 TStageObject *pinned = child->getPinnedDescendant(frame);
1278 if (pinned) return pinned;
1279 }
1280 return 0;
1281 }
1282
1283 //-----------------------------------------------------------------------------
1284
computeIkRootOffset(int t)1285 TAffine TStageObject::computeIkRootOffset(int t) {
1286 if (m_ikflag > 0) return TAffine();
1287
1288 // get normal movement (which will be left-multiplied to the IK-part)
1289 setStatus(XY);
1290 invalidate();
1291 TAffine basePlacement = getPlacement(t);
1292 setStatus(IK);
1293 invalidate();
1294
1295 TStageObject *foot = getPinnedDescendant(t);
1296 if (foot == 0) {
1297 foot = this;
1298 setStatus(XY);
1299 }
1300
1301 m_ikflag++;
1302 invalidate();
1303
1304 TAffine placement = foot->getPlacement(t).inv();
1305 int t0 = 0;
1306 const TPinnedRangeSet::Range *range = foot->getPinnedRangeSet()->getRange(t);
1307 if (range) t0 = range->first;
1308 while (t0 > 0) {
1309 TStageObject *oldFoot = getPinnedDescendant(t0 - 1);
1310 if (oldFoot == 0) break; // oldFoot = this;
1311 assert(oldFoot != foot);
1312 TAffine changeFootAff =
1313 oldFoot->getPlacement(t0).inv() * foot->getPlacement(t0);
1314 placement = changeFootAff * placement;
1315 foot = oldFoot;
1316 range = oldFoot->getPinnedRangeSet()->getRange(t0 - 1);
1317 t0 = 0;
1318 if (range) t0 = range->first;
1319 }
1320 m_ikflag--;
1321 invalidate();
1322
1323 placement = foot->getPinnedRangeSet()->getPlacement() * placement;
1324
1325 return basePlacement * placement;
1326 }
1327
1328 //-----------------------------------------------------------------------------
1329 /*
1330 inline double getPosPathAtCP(const TStroke* path, int cpIndex)
1331 {
1332 int n = path->getControlPointCount();
1333 return path->getLengthAtControlPoint(tcrop(cpIndex*4,0,n-1));
1334 }
1335
1336 //-----------------------------------------------------------------------------
1337 */
1338
computeLocalPlacement(double frame)1339 TAffine TStageObject::computeLocalPlacement(double frame) {
1340 frame = paramsTime(frame);
1341
1342 if (lazyData().m_time != frame) {
1343 double sc = m_scale->getValue(frame);
1344 double sx = sc * m_scalex->getValue(frame);
1345 double sy = sc * m_scaley->getValue(frame);
1346 double ang = m_rot->getValue(frame);
1347 double shx = m_shearx->getValue(frame);
1348 double shy = m_sheary->getValue(frame);
1349
1350 TPointD position;
1351 double posPath = 0;
1352 switch (m_status & STATUS_MASK) {
1353 case XY:
1354 position.x = m_x->getValue(frame) * Stage::inch;
1355 position.y = m_y->getValue(frame) * Stage::inch;
1356 break;
1357 case PATH:
1358 assert(m_spline);
1359 assert(m_spline->getStroke());
1360 posPath = m_spline->getStroke()->getLength() *
1361 m_posPath->getValue(frame) * 0.01;
1362 position = m_spline->getStroke()->getPointAtLength(posPath);
1363 break;
1364 case PATH_AIM:
1365 assert(m_spline);
1366 assert(m_spline->getStroke());
1367 posPath = m_spline->getStroke()->getLength() *
1368 m_posPath->getValue(frame) * 0.01;
1369
1370 position = m_spline->getStroke()->getPointAtLength(posPath);
1371 if (m_spline->getStroke()->getLength() > 1e-5)
1372 ang +=
1373 rad2degree(atan(m_spline->getStroke()->getSpeedAtLength(posPath)));
1374 break;
1375 case IK:
1376 return computeIkRootOffset(frame);
1377 break;
1378 }
1379
1380 TAffine shear(1, shx, 0, shy, 1, 0);
1381
1382 TPointD handlePos = getHandlePos(m_handle, (int)frame);
1383 TPointD center = (m_center + handlePos) * Stage::inch;
1384
1385 TPointD pos = m_offset;
1386 if (m_parent) pos += m_parent->getHandlePos(m_parentHandle, (int)frame);
1387 pos = pos * Stage::inch + position;
1388
1389 m_localPlacement = TTranslation(pos) * makeRotation(ang) * shear *
1390 TScale(sx, sy) * TTranslation(-center);
1391 }
1392
1393 return m_localPlacement;
1394 }
1395
1396 //-----------------------------------------------------------------------------
1397
getPlacement(double t)1398 TAffine TStageObject::getPlacement(double t) {
1399 double &time = lazyData().m_time;
1400
1401 if (time == t) return m_absPlacement;
1402 if (time != -1) {
1403 if (!m_parent)
1404 invalidate();
1405 else
1406 findRoot(t)->invalidate();
1407 }
1408
1409 double tt = paramsTime(t);
1410
1411 TAffine place;
1412 if (m_parent)
1413 place = m_parent->getPlacement(t) * computeLocalPlacement(tt);
1414 else
1415 place = computeLocalPlacement(tt);
1416 m_absPlacement = place;
1417 time = t;
1418 return place;
1419 }
1420
1421 //-----------------------------------------------------------------------------
1422
getZ(double t)1423 double TStageObject::getZ(double t) {
1424 double tt = paramsTime(t);
1425 if (m_parent)
1426 return m_parent->getZ(t) + m_z->getValue(tt);
1427 else
1428 return m_z->getValue(tt);
1429 }
1430
1431 //-----------------------------------------------------------------------------
1432
getSO(double t)1433 double TStageObject::getSO(double t) {
1434 double tt = paramsTime(t);
1435 if (m_parent)
1436 return m_parent->getSO(t) + m_so->getValue(tt);
1437 else
1438 return m_so->getValue(tt);
1439 }
1440
1441 //-----------------------------------------------------------------------------
1442
getGlobalNoScaleZ() const1443 double TStageObject::getGlobalNoScaleZ() const {
1444 return m_parent ? m_parent->getGlobalNoScaleZ() + m_noScaleZ : m_noScaleZ;
1445 }
1446
1447 //-----------------------------------------------------------------------------
1448
getNoScaleZ() const1449 double TStageObject::getNoScaleZ() const { return m_noScaleZ; }
1450
1451 //-----------------------------------------------------------------------------
1452
setNoScaleZ(double noScaleZ)1453 void TStageObject::setNoScaleZ(double noScaleZ) {
1454 if (m_noScaleZ == noScaleZ) return;
1455 m_noScaleZ = noScaleZ;
1456 invalidate();
1457 }
1458
1459 //-----------------------------------------------------------------------------
1460
invalidate(LazyData & ld) const1461 void TStageObject::invalidate(LazyData &ld) const {
1462 // Since this is an invalidation function, access to the invalidable data
1463 // should
1464 // not trigger a data update
1465 ld.m_time = -1;
1466
1467 std::list<TStageObject *>::const_iterator cit = m_children.begin();
1468 for (; cit != m_children.end(); ++cit) (*cit)->invalidate();
1469 }
1470
1471 //-----------------------------------------------------------------------------
1472
invalidate()1473 void TStageObject::invalidate() { invalidate(m_lazyData(tcg::direct_access)); }
1474
1475 //-----------------------------------------------------------------------------
1476
getParentPlacement(double t) const1477 TAffine TStageObject::getParentPlacement(double t) const {
1478 return m_parent ? m_parent->getPlacement(t) : TAffine();
1479 }
1480
1481 //-----------------------------------------------------------------------------
1482
1483 // Rebuild the keyframes map
updateKeyframes(LazyData & ld) const1484 void TStageObject::updateKeyframes(LazyData &ld) const {
1485 KeyframeMap &keyframes = ld.m_keyframes;
1486
1487 // Clear the map
1488 keyframes.clear();
1489
1490 // Gather all sensible parameters in a vector
1491 std::vector<TDoubleParam *> params;
1492
1493 if (m_status == XY) {
1494 params.push_back(m_x.getPointer());
1495 params.push_back(m_y.getPointer());
1496 } else {
1497 params.push_back(m_posPath.getPointer());
1498 }
1499
1500 params.push_back(m_z.getPointer());
1501 params.push_back(m_so.getPointer());
1502 params.push_back(m_rot.getPointer());
1503 params.push_back(m_scalex.getPointer());
1504 params.push_back(m_scaley.getPointer());
1505 params.push_back(m_scale.getPointer());
1506 params.push_back(m_shearx.getPointer());
1507 params.push_back(m_sheary.getPointer());
1508
1509 if (m_skeletonDeformation) {
1510 params.push_back(m_skeletonDeformation->skeletonIdsParam().getPointer());
1511
1512 // Add Plastic Skeleton params too
1513 SkD::vd_iterator vdt, vdEnd;
1514 m_skeletonDeformation->vertexDeformations(vdt, vdEnd);
1515
1516 for (; vdt != vdEnd; ++vdt) {
1517 const std::pair<const QString *, SkVD *> &vd = *vdt;
1518
1519 for (int p = 0; p < SkVD::PARAMS_COUNT; ++p)
1520 params.push_back(vd.second->m_params[p].getPointer());
1521 }
1522 }
1523
1524 // Scan each parameter for a key frame - add each in a set
1525 std::set<int> frames;
1526
1527 int p, pCount = params.size();
1528 for (p = 0; p < pCount; ++p) {
1529 TDoubleParam *param = params[p];
1530
1531 int k, kCount = param->getKeyframeCount();
1532 for (k = 0; k < kCount; ++k) {
1533 const TDoubleKeyframe &kf = param->getKeyframe(k);
1534 frames.insert((int)kf.m_frame);
1535 }
1536 }
1537
1538 // Traverse said set and build a TStageObject keyframe for each found instant
1539
1540 std::set<int>::iterator ft, fEnd(frames.end());
1541 for (ft = frames.begin(); ft != fEnd; ++ft) {
1542 int f = *ft;
1543
1544 // Add values
1545 TStageObject::Keyframe stageKf;
1546 stageKf.m_channels[TStageObject::T_Angle] = m_rot->getKeyframeAt(f);
1547 stageKf.m_channels[TStageObject::T_X] = m_x->getKeyframeAt(f);
1548 stageKf.m_channels[TStageObject::T_Y] = m_y->getKeyframeAt(f);
1549 stageKf.m_channels[TStageObject::T_Z] = m_z->getKeyframeAt(f);
1550 stageKf.m_channels[TStageObject::T_SO] = m_so->getKeyframeAt(f);
1551 stageKf.m_channels[TStageObject::T_ScaleX] = m_scalex->getKeyframeAt(f);
1552 stageKf.m_channels[TStageObject::T_ScaleY] = m_scaley->getKeyframeAt(f);
1553 stageKf.m_channels[TStageObject::T_Scale] = m_scale->getKeyframeAt(f);
1554 stageKf.m_channels[TStageObject::T_Path] = m_posPath->getKeyframeAt(f);
1555 stageKf.m_channels[TStageObject::T_ShearX] = m_shearx->getKeyframeAt(f);
1556 stageKf.m_channels[TStageObject::T_ShearY] = m_sheary->getKeyframeAt(f);
1557
1558 if (m_skeletonDeformation)
1559 m_skeletonDeformation->getKeyframeAt(f, stageKf.m_skeletonKeyframe);
1560
1561 stageKf.m_isKeyframe = true;
1562
1563 // Build the stage keyframe's global ease factors
1564 stageKf.m_easeIn = -1;
1565 stageKf.m_easeOut = -1;
1566
1567 TDoubleKeyframe::Type type = TDoubleKeyframe::None;
1568 bool easeOk = true;
1569
1570 // Start from analyzing standard channels
1571 for (int c = 0; easeOk && c < T_ChannelCount; ++c) {
1572 const TDoubleKeyframe &kf = stageKf.m_channels[c];
1573 if (!kf.m_isKeyframe) continue;
1574
1575 easeOk = touchEaseAndCompare(kf, stageKf, type);
1576 }
1577
1578 // Finally, check the skeleton deformation keyframes
1579 const std::map<QString, SkVD::Keyframe> &vdfs =
1580 stageKf.m_skeletonKeyframe.m_vertexKeyframes;
1581
1582 std::map<QString, SkVD::Keyframe>::const_iterator vdft, vdfEnd(vdfs.end());
1583 for (vdft = vdfs.begin(); easeOk && vdft != vdfEnd; ++vdft) {
1584 for (int p = 0; p < SkVD::PARAMS_COUNT; ++p) {
1585 const TDoubleKeyframe &kf = vdft->second.m_keyframes[p];
1586 if (!kf.m_isKeyframe) continue;
1587
1588 easeOk = touchEaseAndCompare(kf, stageKf, type);
1589 }
1590 }
1591
1592 keyframes[f] = stageKf;
1593 }
1594 }
1595
1596 //-----------------------------------------------------------------------------
1597
updateKeyframes()1598 void TStageObject::updateKeyframes() {
1599 return updateKeyframes(m_lazyData(tcg::direct_access));
1600 }
1601
1602 //-----------------------------------------------------------------------------
1603
saveData(TOStream & os)1604 void TStageObject::saveData(TOStream &os) {
1605 TStageObjectId parentId = getParent();
1606 std::map<std::string, string> attr;
1607 attr["id"] = parentId.toString();
1608 attr["handle"] = m_handle;
1609 attr["parentHandle"] = m_parentHandle;
1610 os.openChild("parent", attr);
1611 os.closeChild();
1612 if (m_name != "") os.child("name") << m_name;
1613 os.child("isOpened") << (int)m_isOpened;
1614 if (isGrouped()) {
1615 os.openChild("groupIds");
1616 int i;
1617 for (i = 0; i < m_groupId.size(); i++) os << m_groupId[i];
1618 os.closeChild();
1619 os.openChild("groupNames");
1620 for (i = 0; i < m_groupName.size(); i++) os << m_groupName[i];
1621 os.closeChild();
1622 }
1623
1624 m_pinnedRangeSet->saveData(os);
1625
1626 os.child("center") << m_center.x << m_center.y << -m_offset.x << -m_offset.y;
1627 os.child("status") << (int)m_status;
1628 if (m_noScaleZ != 0) os.child("noScaleZ") << m_noScaleZ;
1629
1630 if (m_spline) os.child("splinep") << m_spline;
1631
1632 if (!m_x->isDefault()) os.child("x") << *m_x;
1633 if (!m_y->isDefault()) os.child("y") << *m_y;
1634 if (!m_z->isDefault()) os.child("z") << *m_z;
1635 if (!m_so->isDefault()) os.child("so") << *m_so;
1636 if (!m_scalex->isDefault()) os.child("sx") << *m_scalex;
1637 if (!m_scaley->isDefault()) os.child("sy") << *m_scaley;
1638 if (!m_scale->isDefault()) os.child("sc") << *m_scale;
1639 if (!m_rot->isDefault()) os.child("rot") << *m_rot;
1640 if (!m_posPath->isDefault()) os.child("pos") << *m_posPath;
1641 if (!m_shearx->isDefault()) os.child("shx") << *m_shearx;
1642 if (!m_sheary->isDefault()) os.child("shy") << *m_sheary;
1643 if (m_cycleEnabled) os.child("cycle") << 1;
1644
1645 if (m_skeletonDeformation) os.child("plasticSD") << *m_skeletonDeformation;
1646
1647 os.child("nodePos") << m_dagNodePos.x << m_dagNodePos.y;
1648
1649 if (getId().isCamera()) {
1650 os.openChild("camera");
1651 m_camera->saveData(os);
1652 os.closeChild();
1653
1654 /*TDimensionD size = m_camera->getSize();
1655 TDimension res = m_camera->getRes();
1656 bool isXPrevalence = m_camera->isXPrevalence();
1657 os.child("cameraSize") << size.lx << size.ly;
1658 os.child("cameraRes") << res.lx << res.ly;
1659 os.child("xPrevalence") << (int)isXPrevalence;*/
1660 }
1661 }
1662
1663 //-----------------------------------------------------------------------------
1664
loadData(TIStream & is)1665 void TStageObject::loadData(TIStream &is) {
1666 VersionNumber tnzVersion = is.getVersion();
1667 string tagName;
1668 QList<int> groupIds;
1669 QList<wstring> groupNames;
1670
1671 KeyframeMap &keyframes = lazyData().m_keyframes;
1672
1673 while (is.matchTag(tagName)) {
1674 if (tagName == "parent") {
1675 string parentIdStr = is.getTagAttribute("id");
1676 string handle = is.getTagAttribute("handle");
1677 string parentHandle = is.getTagAttribute("parentHandle");
1678 if (tnzVersion < VersionNumber(1, 15)) {
1679 handle = convertTo4InchCenterUnits(handle);
1680 parentHandle = convertTo4InchCenterUnits(parentHandle);
1681 }
1682 if (parentIdStr == "") // vecchio formato
1683 is >> parentIdStr;
1684 else {
1685 }
1686
1687 TStageObjectId parentId = toStageObjectId(parentIdStr);
1688 if (m_id != TStageObjectId::NoneId &&
1689 parentId != TStageObjectId::NoneId) {
1690 assert(parentId != m_id);
1691 setParent(parentId);
1692 }
1693 if (handle != "") setHandle(handle);
1694 if (parentHandle != "") setParentHandle(parentHandle);
1695 } else if (tagName == "center") {
1696 is >> m_center.x >> m_center.y >> m_offset.x >> m_offset.y;
1697 m_offset = -m_offset;
1698 } else if (tagName == "name")
1699 is >> m_name;
1700 else if (tagName == "x")
1701 is >> *m_x;
1702 else if (tagName == "y")
1703 is >> *m_y;
1704 else if (tagName == "z")
1705 is >> *m_z;
1706 else if (tagName == "so")
1707 is >> *m_so;
1708 else if (tagName == "rot")
1709 is >> *m_rot;
1710 else if (tagName == "sx")
1711 is >> *m_scalex;
1712 else if (tagName == "sy")
1713 is >> *m_scaley;
1714 else if (tagName == "sc")
1715 is >> *m_scale;
1716 else if (tagName == "shx")
1717 is >> *m_shearx;
1718 else if (tagName == "shy")
1719 is >> *m_sheary;
1720 else if (tagName == "pos")
1721 is >> *m_posPath;
1722 else if (tagName == "posCP") {
1723 TDoubleParam posCP;
1724 is >> posCP;
1725 } // Ghibli 6.2 release. cfr
1726 else if (tagName == "noScaleZ")
1727 is >> m_noScaleZ;
1728 else if (tagName == "isOpened") {
1729 int v = 0;
1730 is >> v;
1731 m_isOpened = (bool)v;
1732 } else if (tagName == "pinnedStatus") {
1733 m_pinnedRangeSet->loadData(is);
1734 } else if (tagName == "status") {
1735 int v = 0;
1736 is >> v;
1737 m_status = (Status)v;
1738 } else if (tagName == "spline") {
1739 TStageObjectSpline *spline = m_tree->createSpline();
1740 is >> *spline;
1741 m_spline = spline;
1742 m_spline->addRef();
1743 } else if (tagName == "splinep") {
1744 TPersist *p = 0;
1745 is >> p;
1746 m_spline = dynamic_cast<TStageObjectSpline *>(p);
1747 m_tree->insertSpline(m_spline);
1748 m_spline->addRef();
1749 } else if (tagName == "cycle") {
1750 int dummy;
1751 is >> dummy;
1752 m_cycleEnabled = true;
1753 } else if (tagName == "nodePos") {
1754 TPointD pos;
1755 is >> pos.x >> pos.y;
1756 m_dagNodePos = updateDagPosition(pos, tnzVersion);
1757 // is >> m_dagNodePos.x >> m_dagNodePos.y;
1758 }
1759 //***** camera parameters till toonz 6.0 ********
1760 else if (tagName == "cameraSize") {
1761 TDimensionD size(0, 0);
1762 is >> size.lx >> size.ly;
1763 if (m_camera) m_camera->setSize(size);
1764 } else if (tagName == "cameraRes") {
1765 TDimension res(0, 0);
1766 is >> res.lx >> res.ly;
1767 if (m_camera) m_camera->setRes(res);
1768 }
1769 //***** camera parameters toonz 6.1 ******** november 2009
1770 else if (tagName == "camera")
1771 m_camera->loadData(is);
1772 else if (tagName == "groupIds") {
1773 int groupId;
1774 while (!is.eos()) {
1775 is >> groupId;
1776 groupIds.push_back(groupId);
1777 }
1778 } else if (tagName == "groupNames") {
1779 wstring groupName;
1780 while (!is.eos()) {
1781 is >> groupName;
1782 groupNames.push_back(groupName);
1783 }
1784 } else if (tagName == "plasticSD") {
1785 PlasticSkeletonDeformation *sd = new PlasticSkeletonDeformation;
1786 is >> *sd;
1787 setPlasticSkeletonDeformation(sd);
1788 } else
1789 throw TException("TStageObject::loadData. unexpected tag: " + tagName);
1790 is.matchEndTag();
1791 }
1792 if (!groupIds.isEmpty()) {
1793 assert(groupIds.size() == groupNames.size());
1794 int i;
1795 for (i = 0; i < groupIds.size(); i++) {
1796 setGroupId(groupIds[i]);
1797 setGroupName(groupNames[i]);
1798 }
1799 }
1800 if (tnzVersion < VersionNumber(1, 13)) {
1801 updateUnit(m_y.getPointer());
1802 updateUnit(m_x.getPointer());
1803 }
1804 if (tnzVersion < VersionNumber(1, 14)) {
1805 double factor = 1.0 / Stage::inch;
1806 m_center = m_center * factor;
1807 m_offset = m_offset * factor;
1808 }
1809 if (tnzVersion < VersionNumber(1, 16) && !keyframes.empty()) {
1810 std::map<int, TStageObject::Keyframe>::iterator itKf = keyframes.begin();
1811 std::set<int> keyframeIndexSet;
1812 for (; itKf != keyframes.end(); itKf++)
1813 if (is52FullKeyframe(itKf->first)) keyframeIndexSet.insert(itKf->first);
1814 std::set<int>::iterator itKfInd = keyframeIndexSet.begin();
1815 for (; itKfInd != keyframeIndexSet.end(); itKfInd++)
1816 setkey(m_scale, *itKfInd);
1817 }
1818 // Calling updateKeyframes() here may cause failure to load expressions
1819 // especially if it refers to a curve which is to be loaded AFTER this
1820 // function while loading scene process. So I will skip it assuming that
1821 // updateKeyframes() will be called when it is actually needed.
1822 // updateKeyframes();
1823 if (m_spline != 0 && isUppkEnabled())
1824 m_spline->addParam(m_posPath.getPointer());
1825 invalidate();
1826 }
1827
1828 //-----------------------------------------------------------------------------
1829
getParams() const1830 TStageObjectParams *TStageObject::getParams() const {
1831 TStageObjectParams *data = new TStageObjectParams();
1832 data->m_name = m_name;
1833 data->m_center = m_center;
1834 data->m_noScaleZ = m_noScaleZ;
1835
1836 data->m_id = m_id;
1837 data->m_parentId = getParent();
1838 data->m_offset = m_offset;
1839 data->m_status = m_status;
1840
1841 data->m_x = m_x;
1842 data->m_y = m_y;
1843 data->m_z = m_z;
1844 data->m_so = m_so;
1845 data->m_rot = m_rot;
1846 data->m_scalex = m_scalex;
1847 data->m_scaley = m_scaley;
1848 data->m_scale = m_scale;
1849 data->m_posPath = m_posPath;
1850 data->m_shearx = m_shearx;
1851 data->m_sheary = m_sheary;
1852
1853 data->m_skeletonDeformation = m_skeletonDeformation;
1854
1855 data->m_cycleEnabled = m_cycleEnabled;
1856 data->m_spline = m_spline;
1857
1858 data->m_handle = m_handle;
1859 data->m_parentHandle = m_parentHandle;
1860 if (m_pinnedRangeSet) data->m_pinnedRangeSet = m_pinnedRangeSet->clone();
1861
1862 return data;
1863 }
1864
1865 //-----------------------------------------------------------------------------
1866
assignParams(const TStageObjectParams * src,bool doParametersClone)1867 void TStageObject::assignParams(const TStageObjectParams *src,
1868 bool doParametersClone) {
1869 m_name = src->m_name;
1870 m_center = src->m_center;
1871 m_noScaleZ = src->m_noScaleZ;
1872 m_offset = src->m_offset;
1873 m_status = src->m_status;
1874 if (m_spline) m_spline->release();
1875 m_spline = src->m_spline;
1876 if (m_spline) m_spline->addRef();
1877
1878 if (doParametersClone) {
1879 m_x->copy(src->m_x.getPointer());
1880 m_y->copy(src->m_y.getPointer());
1881 m_z->copy(src->m_z.getPointer());
1882 m_so->copy(src->m_so.getPointer());
1883 m_rot->copy(src->m_rot.getPointer());
1884 m_scalex->copy(src->m_scalex.getPointer());
1885 m_scaley->copy(src->m_scaley.getPointer());
1886 m_scale->copy(src->m_scale.getPointer());
1887 m_posPath->copy(src->m_posPath.getPointer());
1888 m_shearx->copy(src->m_shearx.getPointer());
1889 m_sheary->copy(src->m_sheary.getPointer());
1890
1891 if (src->m_skeletonDeformation)
1892 setPlasticSkeletonDeformation(
1893 new PlasticSkeletonDeformation(*src->m_skeletonDeformation));
1894 } else {
1895 m_x = src->m_x.getPointer();
1896 m_x->addObserver(this);
1897 m_y = src->m_y.getPointer();
1898 m_y->addObserver(this);
1899 m_z = src->m_z.getPointer();
1900 m_z->addObserver(this);
1901 m_so = src->m_so.getPointer();
1902 m_so->addObserver(this);
1903 m_rot = src->m_rot.getPointer();
1904 m_rot->addObserver(this);
1905 m_scalex = src->m_scalex.getPointer();
1906 m_scalex->addObserver(this);
1907 m_scaley = src->m_scaley.getPointer();
1908 m_scaley->addObserver(this);
1909 m_scale = src->m_scale.getPointer();
1910 m_scale->addObserver(this);
1911 m_posPath = src->m_posPath.getPointer();
1912 m_posPath->addObserver(this);
1913 m_shearx = src->m_shearx.getPointer();
1914 m_shearx->addObserver(this);
1915 m_sheary = src->m_sheary.getPointer();
1916 m_sheary->addObserver(this);
1917
1918 m_skeletonDeformation = src->m_skeletonDeformation;
1919 if (m_skeletonDeformation) m_skeletonDeformation->addObserver(this);
1920 }
1921
1922 m_handle = src->m_handle;
1923 m_parentHandle = src->m_parentHandle;
1924
1925 m_cycleEnabled = src->m_cycleEnabled;
1926 if (m_pinnedRangeSet) *m_pinnedRangeSet = *src->m_pinnedRangeSet;
1927 updateKeyframes();
1928 if (m_spline && isUppkEnabled()) m_spline->addParam(m_posPath.getPointer());
1929 invalidate();
1930 }
1931
1932 //-----------------------------------------------------------------------------
1933 //
1934 // objectZ e' la posizione dell'oggetto lungo l'asse Z
1935 // il default e' 0. valori grandi rappresentano oggetti piu' vicini alla
1936 // camera
1937 // la distanza iniziale fra tavolo e camera e' 1000
1938 //
1939 // cameraZ e' la posizione della camera lungo l'asse Z
1940 // il default e' 0. valori negativi indicano che la camera si avvicina al
1941 // tavolo
1942 // (che raggiungerebbe per un valore di -1000)
1943 //
1944
perspective(TAffine & aff,const TAffine & cameraAff,double cameraZ,const TAffine & objectAff,double objectZ,double objectNoScaleZ)1945 bool TStageObject::perspective(TAffine &aff, const TAffine &cameraAff,
1946 double cameraZ, const TAffine &objectAff,
1947 double objectZ, double objectNoScaleZ) {
1948 TPointD cameraPos(cameraAff.a13, cameraAff.a23);
1949 TPointD objectPos(objectAff.a13, objectAff.a23);
1950
1951 const double focus = 1000;
1952 const double nearPlane = 1;
1953
1954 /*--
1955 * dzはカメラとオブジェクトの間の距離、focus(=1000)はPegbarをZ軸方向に動かさなかった場合のデフォルト距離
1956 * --*/
1957 double dz = focus + cameraZ - objectZ;
1958 if (dz < nearPlane) {
1959 aff = TAffine();
1960 return false;
1961 }
1962
1963 double noScaleSc = 1 - objectNoScaleZ / focus;
1964 aff = cameraAff * TScale((focus + cameraZ) / dz) * cameraAff.inv() *
1965 objectAff * TScale(noScaleSc);
1966
1967 return true;
1968 }
1969
1970 //-----------------------------------------------------------------------------
1971
setGroupId(int value)1972 int TStageObject::setGroupId(int value) {
1973 m_groupSelector++;
1974 m_groupId.insert(m_groupSelector, value);
1975 return m_groupSelector;
1976 }
1977
1978 //-----------------------------------------------------------------------------
1979
setGroupId(int value,int position)1980 void TStageObject::setGroupId(int value, int position) {
1981 assert(position >= 0 && position <= m_groupId.size());
1982 m_groupId.insert(position, value);
1983 if (m_groupSelector + 1 >= position) m_groupSelector++;
1984 }
1985
1986 //-----------------------------------------------------------------------------
1987
getGroupId()1988 int TStageObject::getGroupId() {
1989 return m_groupId.isEmpty() || m_groupSelector < 0 ||
1990 m_groupSelector >= m_groupId.size()
1991 ? 0
1992 : m_groupId[m_groupSelector];
1993 }
1994
1995 //-----------------------------------------------------------------------------
1996
getGroupIdStack()1997 QStack<int> TStageObject::getGroupIdStack() { return m_groupId; }
1998
1999 //-----------------------------------------------------------------------------
2000
removeGroupId(int position)2001 void TStageObject::removeGroupId(int position) {
2002 if (!isGrouped()) return;
2003 assert(position >= 0 && position <= m_groupId.size());
2004 m_groupId.remove(position);
2005 if (m_groupSelector + 1 >= position && m_groupSelector > -1)
2006 m_groupSelector--;
2007 }
2008
2009 //-----------------------------------------------------------------------------
2010
removeGroupId()2011 int TStageObject::removeGroupId() {
2012 m_groupId.remove(m_groupSelector);
2013 if (m_groupSelector > -1) m_groupSelector--;
2014 return m_groupSelector + 1;
2015 }
2016
2017 //-----------------------------------------------------------------------------
2018
isGrouped()2019 bool TStageObject::isGrouped() { return !m_groupId.isEmpty(); }
2020
2021 //-----------------------------------------------------------------------------
2022
isContainedInGroup(int groupId)2023 bool TStageObject::isContainedInGroup(int groupId) {
2024 return m_groupId.contains(groupId);
2025 }
2026
2027 //-----------------------------------------------------------------------------
2028
setGroupName(const wstring & name,int position)2029 void TStageObject::setGroupName(const wstring &name, int position) {
2030 int groupSelector = position < 0 ? m_groupSelector : position;
2031 assert(groupSelector >= 0 && groupSelector <= m_groupName.size());
2032 m_groupName.insert(groupSelector, name);
2033 }
2034
2035 //-----------------------------------------------------------------------------
2036
getGroupName(bool fromEditor)2037 wstring TStageObject::getGroupName(bool fromEditor) {
2038 int groupSelector = fromEditor ? m_groupSelector + 1 : m_groupSelector;
2039 return m_groupName.isEmpty() || groupSelector < 0 ||
2040 groupSelector >= m_groupName.size()
2041 ? L""
2042 : m_groupName[groupSelector];
2043 }
2044
2045 //-----------------------------------------------------------------------------
2046
getGroupNameStack()2047 QStack<wstring> TStageObject::getGroupNameStack() { return m_groupName; }
2048
2049 //-----------------------------------------------------------------------------
2050
removeGroupName(bool fromEditor)2051 int TStageObject::removeGroupName(bool fromEditor) {
2052 int groupSelector = fromEditor ? m_groupSelector + 1 : m_groupSelector;
2053 if (!isGrouped()) return -1;
2054 assert(groupSelector >= 0 && groupSelector <= m_groupName.size());
2055 m_groupName.remove(groupSelector);
2056 return groupSelector;
2057 }
2058
2059 //-----------------------------------------------------------------------------
2060
removeGroupName(int position)2061 void TStageObject::removeGroupName(int position) {
2062 int groupSelector = position < 0 ? m_groupSelector : position;
2063 assert(groupSelector >= 0 && groupSelector <= m_groupName.size());
2064 m_groupName.remove(groupSelector);
2065 }
2066
2067 //-----------------------------------------------------------------------------
2068
removeFromAllGroup()2069 void TStageObject::removeFromAllGroup() {
2070 m_groupId.clear();
2071 m_groupName.clear();
2072 m_groupSelector = -1;
2073 }
2074
2075 //-----------------------------------------------------------------------------
2076
editGroup()2077 void TStageObject::editGroup() { m_groupSelector--; }
2078
2079 //-----------------------------------------------------------------------------
2080
isGroupEditing()2081 bool TStageObject::isGroupEditing() {
2082 return isGrouped() && m_groupSelector == -1;
2083 }
2084
2085 //-----------------------------------------------------------------------------
2086
closeEditingGroup(int groupId)2087 void TStageObject::closeEditingGroup(int groupId) {
2088 if (!m_groupId.contains(groupId)) return;
2089 m_groupSelector = 0;
2090 while (m_groupId[m_groupSelector] != groupId &&
2091 m_groupSelector < m_groupId.size())
2092 m_groupSelector++;
2093 }
2094
2095 //-----------------------------------------------------------------------------
2096
getEditingGroupId()2097 int TStageObject::getEditingGroupId() {
2098 if (!isGrouped() || m_groupSelector + 1 >= m_groupId.size()) return -1;
2099 return m_groupId[m_groupSelector + 1];
2100 }
2101
2102 //-----------------------------------------------------------------------------
2103
getEditingGroupName()2104 wstring TStageObject::getEditingGroupName() {
2105 if (!isGrouped() || m_groupSelector + 1 >= m_groupName.size()) return L"";
2106 return m_groupName[m_groupSelector + 1];
2107 }
2108