TAffine TTool::getCurrentColumnParentMatrix() const { if (!m_application) return TAffine(); TFrameHandle *fh = m_application->getCurrentFrame(); if (fh->isEditingLevel()) return TAffine(); int frame = fh->getFrame(); int columnIndex = m_application->getCurrentColumn()->getColumnIndex(); TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); TStageObjectId parentId = xsh->getStageObjectParent(TStageObjectId::ColumnId(columnIndex)); return xsh->getPlacement(parentId, frame); }
TAffine TTool::getCurrentObjectParentMatrix() const { if (!m_application) return TAffine(); TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); int frame = m_application->getCurrentFrame()->getFrame(); TStageObjectId currentObjectId = m_application->getCurrentObject()->getObjectId(); if (currentObjectId == TStageObjectId::NoneId) return TAffine(); TStageObjectId parentId = xsh->getStageObjectParent(currentObjectId); if (parentId == TStageObjectId::NoneId) return TAffine(); else return xsh->getPlacement(parentId, frame); }
TAffine TTool::getCurrentObjectParentMatrix2() const { TTool::Application *app = m_application; TFrameHandle *fh = app->getCurrentFrame(); if (fh->isEditingLevel()) return TAffine(); int frame = fh->getFrame(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TStageObjectId id = app->getCurrentObject()->getObjectId(); double objZ = xsh->getZ(id, frame); TStageObjectId parentId = xsh->getStageObjectParent(id); if (parentId == TStageObjectId::NoneId) return TAffine(); id = parentId; TAffine objPlacement = xsh->getPlacement(id, frame); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); TStageObject *camera = xsh->getStageObject(cameraId); TAffine cameraPlacement = camera->getPlacement(frame); double cameraZ = camera->getZ(frame); TAffine placement; TStageObject::perspective(placement, cameraPlacement, cameraZ, objPlacement, objZ, 0); return placement; }
TAffine TTool::getColumnMatrix(int columnIndex) const { if (!m_application) return TAffine(); TFrameHandle *fh = m_application->getCurrentFrame(); if (fh->isEditingLevel()) return TAffine(); int frame = fh->getFrame(); TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); TStageObjectId columnId = TStageObjectId::ColumnId(columnIndex); TAffine columnPlacement = xsh->getPlacement(columnId, frame); double columnZ = xsh->getZ(columnId, frame); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); TStageObject *camera = xsh->getStageObject(cameraId); TAffine cameraPlacement = camera->getPlacement(frame); double cameraZ = camera->getZ(frame); TStageObject *object = xsh->getStageObject(columnId); TAffine placement; TStageObject::perspective(placement, cameraPlacement, cameraZ, columnPlacement, columnZ, object->getGlobalNoScaleZ()); return placement; }
void SkeletonTool::togglePinnedStatus(int columnIndex, int frame, bool shiftPressed) { Skeleton skeleton; buildSkeleton(skeleton, columnIndex); if (!skeleton.getRootBone() || !skeleton.getRootBone()->getStageObject()) return; Skeleton::Bone *bone = skeleton.getBoneByColumnIndex(columnIndex); assert(bone); if (!bone) return; TogglePinnedStatusUndo *undo = new TogglePinnedStatusUndo(this, frame); for (int i = 0; i < skeleton.getBoneCount(); i++) { TStageObject *obj = skeleton.getBone(i)->getStageObject(); if (obj) { undo->addBoneId(obj->getId()); obj->setKeyframeWithoutUndo(frame); } } getApplication()->getCurrentXsheet()->notifyXsheetChanged(); getApplication()->getCurrentObject()->notifyObjectIdChanged(false); undo->setOldTemp(m_temporaryPinnedColumns); bool isTemporaryPinned = m_temporaryPinnedColumns.count(columnIndex) > 0; if (shiftPressed || isTemporaryPinned) { if (isTemporaryPinned) m_temporaryPinnedColumns.erase(columnIndex); else m_temporaryPinnedColumns.insert(columnIndex); } else { TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet(); TAffine placement = xsh->getPlacement(bone->getStageObject()->getId(), frame); TStageObjectId rootId = skeleton.getRootBone()->getStageObject()->getId(); TAffine rootPlacement = xsh->getPlacement(rootId, frame); int pinnedStatus = bone->getPinnedStatus(); if (pinnedStatus != Skeleton::Bone::PINNED) { int oldPinned = -1; for (int i = 0; i < skeleton.getBoneCount(); i++) { TStageObject *obj = skeleton.getBone(i)->getStageObject(); if (obj->getPinnedRangeSet()->isPinned(frame)) { oldPinned = i; break; } } int lastFrame = 1000000; if (oldPinned >= 0) { assert(skeleton.getBone(oldPinned) != bone); TStageObject *obj = skeleton.getBone(oldPinned)->getStageObject(); const TPinnedRangeSet::Range *range = obj->getPinnedRangeSet()->getRange(frame); assert(range && range->first <= frame && frame <= range->second); lastFrame = range->second; TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet(); rangeSet->removeRange(frame, range->second); obj->invalidate(); undo->setOldRange(oldPinned, frame, range->second, rangeSet->getPlacement()); } else { for (int i = 0; i < skeleton.getBoneCount(); i++) { TStageObject *obj = skeleton.getBone(i)->getStageObject(); const TPinnedRangeSet::Range *range = obj->getPinnedRangeSet()->getNextRange(frame); if (range) { assert(range->first > frame); if (range->first - 1 < lastFrame) lastFrame = range->first - 1; } } } TStageObject *obj = bone->getStageObject(); TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet(); rangeSet->setRange(frame, lastFrame); if (frame == 0) { // this code should be moved elsewhere, possibly in the stageobject implementation // the idea is to remove the normal TStageObject *rootObj = skeleton.getRootBone()->getStageObject(); rootObj->setStatus(TStageObject::XY); placement = rootObj->getPlacement(0).inv() * placement; rootObj->setStatus(TStageObject::IK); rangeSet->setPlacement(placement); rootObj->invalidate(); } undo->setNewRange(bone->getColumnIndex(), frame, lastFrame, rangeSet->getPlacement()); } } undo->setNewTemp(m_temporaryPinnedColumns); TUndoManager::manager()->add(undo); }