| |
| |
|
|
| #include "tfxattributes.h" |
| #include "tfxutil.h" |
| #include "tmacrofx.h" |
| #include "toutputproperties.h" |
| #include "tparamcontainer.h" |
| |
| |
| #include "toonz/txsheet.h" |
| #include "toonz/tstageobjecttree.h" |
| #include "toonz/tcolumnfx.h" |
| #include "toonz/tcolumnfxset.h" |
| #include "toonz/fxdag.h" |
| #include "toonz/txshchildlevel.h" |
| #include "toonz/txshcell.h" |
| #include "toonz/txshleveltypes.h" |
| #include "toonz/txshlevelcolumn.h" |
| #include "toonz/txshpalettecolumn.h" |
| #include "toonz/txshzeraryfxcolumn.h" |
| #include "toonz/txshsimplelevel.h" |
| #include "toonz/dpiscale.h" |
| #include "toonz/tcamera.h" |
| #include "toonz/toonzscene.h" |
| #include "toonz/sceneproperties.h" |
| #include "toonz/plasticdeformerfx.h" |
| #include "toonz/stage.h" |
| #include "toonz/preferences.h" |
| #include "ttzpimagefx.h" |
| |
| #include "../stdfx/motionawarebasefx.h" |
| |
| #include "toonz/scenefx.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class TimeShuffleFx : public TRasterFx |
| { |
| FX_DECLARATION(TimeShuffleFx) |
| |
| private: |
| int m_frame; |
| TFxTimeRegion m_timeRegion; |
| TRasterFxPort m_port; |
| |
| public: |
| TimeShuffleFx() : TRasterFx(), m_frame(0), m_timeRegion() { addInputPort("source", m_port); } |
| ~TimeShuffleFx() {} |
| |
| TFx *clone(bool recursive = true) const |
| { |
| TimeShuffleFx *fx = dynamic_cast<TimeShuffleFx *>(TFx::clone(recursive)); |
| assert(fx); |
| |
| fx->setFrame(m_frame); |
| fx->setTimeRegion(getTimeRegion()); |
| |
| return fx; |
| } |
| |
| int getFrame() const { return m_frame; } |
| void setFrame(int frame) { m_frame = frame; } |
| |
| void setTimeRegion(const TFxTimeRegion &timeRegion) { m_timeRegion = timeRegion; } |
| TFxTimeRegion getTimeRegion() const { return m_timeRegion; } |
| |
| bool canHandle(const TRenderSettings &info, double frame) { return true; } |
| |
| string getPluginId() const { return string(); } |
| |
| void compute(TFlash &flash, int frame) |
| { |
| if (!m_port.isConnected()) |
| return; |
| |
| TRasterFxP(m_port.getFx())->compute(flash, m_frame); |
| } |
| |
| void doCompute(TTile &tile, double frame, const TRenderSettings &ri) |
| { |
| if (!m_port.isConnected()) { |
| tile.getRaster()->clear(); |
| return; |
| } |
| |
| |
| TRasterFxP(m_port.getFx())->compute(tile, m_frame, ri); |
| } |
| |
| bool doGetBBox(double frame, TRectD &bbox, const TRenderSettings &info) |
| { |
| if (!m_port.isConnected()) |
| return false; |
| |
| return TRasterFxP(m_port.getFx())->doGetBBox(m_frame, bbox, info); |
| } |
| |
| string getAlias(double frame, const TRenderSettings &info) const |
| { |
| return TRasterFx::getAlias(m_frame, info); |
| } |
| |
| void doDryCompute(TRectD &rect, |
| double frame, |
| const TRenderSettings &info) |
| { |
| if (m_port.isConnected()) |
| TRasterFxP(m_port.getFx())->dryCompute(rect, m_frame, info); |
| } |
| |
| private: |
| |
| TimeShuffleFx(const TimeShuffleFx &); |
| TimeShuffleFx &operator=(const TimeShuffleFx &); |
| }; |
| |
| FX_IDENTIFIER_IS_HIDDEN(TimeShuffleFx, "timeShuffleFx") |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class AffineFx : public TGeometryFx |
| { |
| FX_DECLARATION(AffineFx) |
| |
| private: |
| TXsheet *m_xsheet; |
| TStageObject *m_stageObject; |
| TRasterFxPort m_input; |
| |
| public: |
| AffineFx() : m_xsheet(0), m_stageObject(0) |
| { |
| addInputPort("source", m_input); |
| setName(L"AffineFx"); |
| } |
| AffineFx(TXsheet *xsh, TStageObject *pegbar) |
| : m_xsheet(xsh), m_stageObject(pegbar) |
| { |
| addInputPort("source", m_input); |
| setName(L"AffineFx"); |
| } |
| ~AffineFx() {} |
| |
| TFx *clone(bool recursive = true) const |
| { |
| AffineFx *fx = dynamic_cast<AffineFx *>(TFx::clone(recursive)); |
| assert(fx); |
| fx->m_stageObject = m_stageObject; |
| fx->m_xsheet = m_xsheet; |
| return fx; |
| } |
| |
| bool canHandle(const TRenderSettings &info, double frame) { return true; } |
| |
| TAffine getPlacement(double frame) |
| { |
| TAffine objAff = m_stageObject->getPlacement(frame); |
| |
| double objZ = m_stageObject->getZ(frame); |
| double objNoScaleZ = m_stageObject->getGlobalNoScaleZ(); |
| |
| TStageObjectId cameraId = m_xsheet->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = m_xsheet->getStageObject(cameraId); |
| TAffine cameraAff = camera->getPlacement(frame); |
| double cameraZ = camera->getZ(frame); |
| |
| TAffine aff; |
| bool isVisible = TStageObject::perspective(aff, |
| cameraAff, cameraZ, |
| objAff, objZ, objNoScaleZ); |
| |
| if (!isVisible) |
| return TAffine(); |
| else |
| return aff; |
| } |
| |
| TAffine getParentPlacement(double frame) { return m_stageObject->getPlacement(frame); } |
| |
| string getPluginId() const { return string(); } |
| |
| private: |
| |
| AffineFx(const AffineFx &); |
| AffineFx &operator=(const AffineFx &); |
| }; |
| |
| FX_IDENTIFIER_IS_HIDDEN(AffineFx, "affineFx") |
| |
| |
| |
| |
| |
| |
| class PlacedFx |
| { |
| public: |
| double m_z; |
| double m_so; |
| int m_columnIndex; |
| |
| TFxP m_fx; |
| TAffine m_aff; |
| |
| TFxPort *m_leftXsheetPort; |
| |
| public: |
| PlacedFx() : m_z(0), m_so(0), m_columnIndex(-1), m_fx(0), m_aff(), m_leftXsheetPort(0) {} |
| explicit PlacedFx(const TFxP &fx) |
| : m_z(0), m_so(0), m_columnIndex(-1), m_fx(fx), m_aff(), m_leftXsheetPort(0) {} |
| |
| bool operator<(const PlacedFx &pf) const |
| { |
| return (m_z < pf.m_z) ? true : (m_z > pf.m_z) ? false : (m_so < pf.m_so) ? true : (m_so > pf.m_so) ? false : (m_columnIndex < pf.m_columnIndex); |
| } |
| |
| TFxP makeFx() |
| { |
| return (!m_fx) ? TFxP() : (m_aff == TAffine()) ? m_fx : TFxUtil::makeAffine(m_fx, m_aff); |
| } |
| }; |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| TFxP timeShuffle(TFxP fx, int frame, TFxTimeRegion timeRegion) |
| { |
| TimeShuffleFx *timeShuffle = new TimeShuffleFx(); |
| |
| timeShuffle->setFrame(frame); |
| timeShuffle->setTimeRegion(timeRegion); |
| if (!timeShuffle->connect("source", fx.getPointer())) |
| assert(!"Could not connect ports!"); |
| |
| return timeShuffle; |
| }; |
| |
| } |
| |
| |
| |
| |
| |
| bool getColumnPlacement(TAffine &aff, TXsheet *xsh, double row, int col, bool isPreview) |
| { |
| if (col < 0) |
| return false; |
| TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(col)); |
| TAffine objAff = pegbar->getPlacement(row); |
| double objZ = pegbar->getZ(row); |
| double noScaleZ = pegbar->getGlobalNoScaleZ(); |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraAff = camera->getPlacement(row); |
| double cameraZ = camera->getZ(row); |
| |
| bool isVisible = TStageObject::perspective( |
| aff, |
| cameraAff, cameraZ, |
| objAff, objZ, |
| noScaleZ); |
| |
| return isVisible; |
| } |
| |
| |
| |
| bool getColumnPlacement(PlacedFx &pf, TXsheet *xsh, double row, int col, bool isPreview) |
| { |
| if (col < 0) |
| return false; |
| TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(col)); |
| TAffine objAff = pegbar->getPlacement(row); |
| pf.m_z = pegbar->getZ(row); |
| pf.m_so = pegbar->getSO(row); |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraAff = camera->getPlacement(row); |
| double cameraZ = camera->getZ(row); |
| |
| bool isVisible = TStageObject::perspective( |
| pf.m_aff, |
| cameraAff, cameraZ, |
| objAff, pf.m_z, |
| pegbar->getGlobalNoScaleZ()); |
| |
| return isVisible; |
| } |
| |
| |
| |
| bool getStageObjectPlacement(TAffine &aff, TXsheet *xsh, double row, TStageObjectId &id, bool isPreview) |
| { |
| TStageObject *pegbar = xsh->getStageObjectTree()->getStageObject(id, false); |
| if (!pegbar) |
| return false; |
| |
| TAffine objAff = pegbar->getPlacement(row); |
| double objZ = pegbar->getZ(row); |
| double noScaleZ = pegbar->getGlobalNoScaleZ(); |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraAff = camera->getPlacement(row); |
| double cameraZ = camera->getZ(row); |
| |
| bool isVisible = TStageObject::perspective( |
| aff, |
| cameraAff, cameraZ, |
| objAff, objZ, |
| noScaleZ); |
| |
| return isVisible; |
| } |
| |
| |
| namespace |
| { |
| TStageObjectId getMotionObjectId(MotionObjectType type, int index) |
| { |
| switch (type) { |
| case OBJTYPE_OWN: |
| return TStageObjectId::NoneId; |
| break; |
| case OBJTYPE_COLUMN: |
| if (index == 0) |
| return TStageObjectId::NoneId; |
| return TStageObjectId::ColumnId(index - 1); |
| break; |
| case OBJTYPE_PEGBAR: |
| if (index == 0) |
| return TStageObjectId::NoneId; |
| return TStageObjectId::PegbarId(index - 1); |
| break; |
| case OBJTYPE_TABLE: |
| return TStageObjectId::TableId; |
| break; |
| case OBJTYPE_CAMERA: |
| if (index == 0) |
| return TStageObjectId::NoneId; |
| return TStageObjectId::CameraId(index - 1); |
| break; |
| } |
| |
| return TStageObjectId::NoneId; |
| } |
| }; |
| |
| |
| |
| TPointD getColumnSpeed(TXsheet *xsh, double row, int col, bool isPreview) |
| { |
| TAffine aff; |
| TPointD a, b; |
| const double h = 0.001; |
| getColumnPlacement(aff, xsh, row + h, col, isPreview); |
| |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraAff = camera->getPlacement(row + h); |
| a = aff * TPointD(-cameraAff.a13, -cameraAff.a23); |
| |
| aff = TAffine(); |
| getColumnPlacement(aff, xsh, row - h, col, isPreview); |
| |
| cameraAff = camera->getPlacement(row - h); |
| b = aff * TPointD(-cameraAff.a13, -cameraAff.a23); |
| |
| return (b - a) * (0.5 / h); |
| } |
| |
| |
| |
| |
| |
| QList<TPointD> getColumnMotionPoints(TXsheet *xsh, double row, int col, TStageObjectId &objectId, bool isPreview, |
| double shutterStart, double shutterEnd, int traceResolution) |
| { |
| |
| if (shutterStart == 0.0 && shutterEnd == 0.0) |
| return QList<TPointD>(); |
| |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine dpiAff = getDpiAffine(camera->getCamera()); |
| |
| |
| TAffine aff; |
| |
| |
| bool useOwnMotion = false; |
| if (objectId == TStageObjectId::NoneId || |
| !xsh->getStageObjectTree()->getStageObject(objectId, false)) { |
| getColumnPlacement(aff, xsh, row, col, isPreview); |
| useOwnMotion = true; |
| } else { |
| getStageObjectPlacement(aff, xsh, row, objectId, isPreview); |
| } |
| |
| TAffine cameraAff = camera->getPlacement(row); |
| TPointD basePos = dpiAff.inv() * aff * TPointD(-cameraAff.a13, -cameraAff.a23); |
| |
| |
| QList<TPointD> points; |
| |
| double dFrame = (shutterStart + shutterEnd) / (double)traceResolution; |
| |
| for (int i = 0; i <= traceResolution; i++) { |
| |
| double frameOffset = -shutterStart + dFrame * (double)i; |
| |
| if (frameOffset == 0.0) { |
| points.append(TPointD(0.0, 0.0)); |
| continue; |
| } |
| |
| |
| if (useOwnMotion) |
| getColumnPlacement(aff, xsh, row + frameOffset, col, isPreview); |
| else |
| getStageObjectPlacement(aff, xsh, row + frameOffset, objectId, isPreview); |
| |
| TAffine cameraAff = camera->getPlacement(row + frameOffset); |
| TPointD tmpPos = dpiAff.inv() * aff * TPointD(-cameraAff.a13, -cameraAff.a23); |
| |
| |
| points.append(tmpPos - basePos); |
| } |
| return points; |
| } |
| |
| |
| |
| |
| |
| class FxBuilder |
| { |
| public: |
| ToonzScene *m_scene; |
| TXsheet *m_xsh; |
| TAffine m_cameraAff; |
| double m_cameraZ; |
| double m_frame; |
| int m_whichLevels; |
| bool m_isPreview; |
| bool m_expandXSheet; |
| |
| |
| |
| int m_particleDescendentCount; |
| |
| public: |
| FxBuilder(ToonzScene *scene, TXsheet *xsh, double frame, int whichLevels, |
| bool isPreview = false, bool expandXSheet = true); |
| |
| TFxP buildFx(); |
| TFxP buildFx(const TFxP &root, BSFX_Transforms_Enum transforms); |
| |
| PlacedFx makePF(TLevelColumnFx *fx); |
| PlacedFx makePF(TPaletteColumnFx *fx); |
| PlacedFx makePF(TZeraryColumnFx *fx); |
| PlacedFx makePF(TXsheetFx *fx); |
| PlacedFx makePFfromUnaryFx(TFx *fx); |
| PlacedFx makePFfromGenericFx(TFx *fx); |
| PlacedFx makePF(TFx *fx); |
| |
| TFxP getFxWithColumnMovements(const PlacedFx &pf); |
| |
| bool addPlasticDeformerFx(PlacedFx &pf); |
| }; |
| |
| |
| |
| FxBuilder::FxBuilder(ToonzScene *scene, TXsheet *xsh, double frame, int whichLevels, |
| bool isPreview, bool expandXSheet) |
| : m_scene(scene), m_xsh(xsh), m_frame(frame), m_whichLevels(whichLevels), m_isPreview(isPreview), m_expandXSheet(expandXSheet), m_particleDescendentCount(0) |
| { |
| TStageObjectId cameraId; |
| if (m_isPreview) |
| cameraId = m_xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = m_xsh->getStageObjectTree()->getCurrentCameraId(); |
| |
| TStageObject *camera = m_xsh->getStageObject(cameraId); |
| m_cameraAff = camera->getPlacement(m_frame); |
| m_cameraZ = camera->getZ(m_frame); |
| } |
| |
| |
| |
| TFxP FxBuilder::buildFx() |
| { |
| TFx *outputFx = m_xsh->getFxDag()->getOutputFx(0); |
| if (!outputFx || |
| outputFx->getInputPortCount() != 1 || |
| outputFx->getInputPort(0)->getFx() == 0) |
| return TFxP(); |
| |
| outputFx->setName(L"OutputFx"); |
| |
| assert(m_particleDescendentCount == 0); |
| PlacedFx pf = makePF(outputFx->getInputPort(0)->getFx()); |
| assert(m_particleDescendentCount == 0); |
| |
| TAffine cameraFullAff = m_cameraAff * TScale((1000 + m_cameraZ) / 1000); |
| return TFxUtil::makeAffine(pf.makeFx(), cameraFullAff.inv()); |
| } |
| |
| |
| |
| TFxP FxBuilder::buildFx(const TFxP &root, BSFX_Transforms_Enum transforms) |
| { |
| assert(m_particleDescendentCount == 0); |
| PlacedFx pf = makePF(root.getPointer()); |
| assert(m_particleDescendentCount == 0); |
| |
| TFxP fx = (transforms & BSFX_COLUMN_TR) ? pf.makeFx() : pf.m_fx; |
| if (transforms & BSFX_CAMERA_TR) { |
| TAffine cameraFullAff = m_cameraAff * TScale((1000 + m_cameraZ) / 1000); |
| fx = TFxUtil::makeAffine(fx, cameraFullAff.inv()); |
| } |
| |
| return fx; |
| } |
| |
| |
| |
| TFxP FxBuilder::getFxWithColumnMovements(const PlacedFx &pf) |
| { |
| TFxP fx = pf.m_fx; |
| if (!fx) |
| return fx; |
| |
| if (pf.m_columnIndex == -1) |
| return pf.m_fx; |
| |
| TStageObjectId id = TStageObjectId::ColumnId(pf.m_columnIndex); |
| TStageObject *pegbar = m_xsh->getStageObject(id); |
| |
| AffineFx *affFx = new AffineFx(m_xsh, pegbar); |
| affFx->getInputPort(0)->setFx(fx.getPointer()); |
| |
| return affFx; |
| } |
| |
| |
| |
| bool FxBuilder::addPlasticDeformerFx(PlacedFx &pf) |
| { |
| TStageObject *obj = m_xsh->getStageObject(TStageObjectId::ColumnId(pf.m_columnIndex)); |
| TStageObjectId parentId(obj->getParent()); |
| |
| if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') { |
| const SkDP &sd = m_xsh->getStageObject(parentId)->getPlasticSkeletonDeformation(); |
| |
| const TXshCell &parentCell = m_xsh->getCell(m_frame, parentId.getIndex()); |
| TXshSimpleLevel *parentSl = parentCell.getSimpleLevel(); |
| |
| if (sd && parentSl && (parentSl->getType() == MESH_XSHLEVEL)) { |
| |
| |
| |
| PlasticDeformerFx *plasticFx = new PlasticDeformerFx; |
| plasticFx->m_xsh = m_xsh; |
| plasticFx->m_col = parentId.getIndex(); |
| plasticFx->m_texPlacement = obj->getLocalPlacement(m_frame); |
| |
| if (!plasticFx->connect("source", pf.m_fx.getPointer())) |
| assert(!"Could not connect ports!"); |
| |
| pf.m_fx = plasticFx; |
| pf.m_aff = pf.m_aff * plasticFx->m_texPlacement.inv(); |
| |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| |
| |
| PlacedFx FxBuilder::makePF(TFx *fx) |
| { |
| if (!fx) |
| return PlacedFx(); |
| |
| if (TLevelColumnFx *lcfx = dynamic_cast<TLevelColumnFx *>(fx)) |
| return makePF(lcfx); |
| else if (TPaletteColumnFx *pcfx = dynamic_cast<TPaletteColumnFx *>(fx)) |
| return makePF(pcfx); |
| else if (TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx)) |
| return makePF(zcfx); |
| else if (TXsheetFx *xsfx = dynamic_cast<TXsheetFx *>(fx)) |
| return makePF(xsfx); |
| else if (fx->getInputPortCount() == 1) |
| return makePFfromUnaryFx(fx); |
| else |
| return makePFfromGenericFx(fx); |
| } |
| |
| |
| |
| PlacedFx FxBuilder::makePF(TXsheetFx *fx) |
| { |
| if (!m_expandXSheet) |
| return PlacedFx(fx); |
| |
| |
| TFxSet *fxs = m_xsh->getFxDag()->getTerminalFxs(); |
| int m = fxs->getFxCount(); |
| if (m == 0) |
| return PlacedFx(); |
| |
| std::vector<PlacedFx> pfs(m); |
| int i; |
| for (i = 0; i < m; i++) { |
| |
| TFx *fx = fxs->getFx(i); |
| assert(fx); |
| pfs[i] = makePF(fx); |
| } |
| |
| |
| std::sort(pfs.begin(), pfs.end()); |
| |
| |
| TFxP currentFx = pfs[0].makeFx(); |
| for (i = 1; i < m; i++) { |
| TFxP fx = pfs[i].makeFx(); |
| if (pfs[i].m_leftXsheetPort) { |
| |
| |
| |
| TFxP inputFx = currentFx; |
| inputFx = TFxUtil::makeAffine(inputFx, pfs[i].m_aff.inv()); |
| pfs[i].m_leftXsheetPort->setFx(inputFx.getPointer()); |
| currentFx = fx; |
| } else { |
| if (Preferences::instance()->isShowRasterImagesDarkenBlendedInViewerEnabled()) |
| currentFx = TFxUtil::makeDarken(currentFx, fx); |
| else |
| currentFx = TFxUtil::makeOver(currentFx, fx); |
| } |
| } |
| |
| return PlacedFx(currentFx); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| PlacedFx FxBuilder::makePF(TLevelColumnFx *lcfx) |
| { |
| assert(m_scene); |
| assert(lcfx); |
| assert(lcfx->getColumn()); |
| if (!lcfx || !lcfx->getColumn()) |
| return PlacedFx(); |
| |
| if (!lcfx->getColumn()->isPreviewVisible()) |
| return PlacedFx(); |
| |
| |
| |
| TXshCell cell = lcfx->getColumn()->getCell(tfloor(m_frame)); |
| int levelFrame = cell.m_frameId.getNumber() - 1; |
| |
| |
| if (m_particleDescendentCount == 0 && cell.isEmpty()) |
| return PlacedFx(); |
| |
| if (m_whichLevels == TOutputProperties::AnimatedOnly) { |
| |
| |
| |
| |
| |
| TXshLevel *xl = cell.m_level.getPointer(); |
| |
| |
| if (m_particleDescendentCount == 0) { |
| if (!xl || xl->getType() != PLI_XSHLEVEL && xl->getType() != TZP_XSHLEVEL && xl->getType() != CHILD_XSHLEVEL) |
| return PlacedFx(); |
| } |
| |
| else { |
| if (xl && xl->getType() != PLI_XSHLEVEL && |
| xl->getType() != TZP_XSHLEVEL && |
| xl->getType() != CHILD_XSHLEVEL) |
| return PlacedFx(); |
| } |
| } |
| |
| |
| PlacedFx pf; |
| pf.m_columnIndex = lcfx->getColumn()->getIndex(); |
| pf.m_fx = lcfx; |
| |
| |
| bool columnVisible = getColumnPlacement(pf, m_xsh, m_frame, pf.m_columnIndex, m_isPreview); |
| |
| |
| if (!cell.isEmpty() && cell.m_level->getChildLevel()) { |
| |
| TXsheet *xsh = cell.m_level->getChildLevel()->getXsheet(); |
| |
| |
| FxBuilder builder(m_scene, xsh, levelFrame, m_whichLevels, m_isPreview); |
| |
| |
| pf.m_fx = timeShuffle(builder.buildFx(), levelFrame, lcfx->getTimeRegion()); |
| pf.m_fx->setIdentifier(lcfx->getIdentifier()); |
| pf.m_fx->getAttributes()->passiveCacheDataIdx() = lcfx->getAttributes()->passiveCacheDataIdx(); |
| |
| |
| addPlasticDeformerFx(pf); |
| } |
| |
| if (columnVisible) { |
| |
| TXshSimpleLevel *sl = cell.isEmpty() ? 0 : cell.m_level->getSimpleLevel(); |
| if (sl) { |
| |
| if (!addPlasticDeformerFx(pf)) { |
| |
| TAffine dpiAff = ::getDpiAffine(sl, cell.m_frameId, true); |
| pf.m_fx = TFxUtil::makeAffine(pf.m_fx, dpiAff); |
| if (pf.m_fx) |
| pf.m_fx->setName(L"LevelColumn AffineFx"); |
| } |
| } else { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TXshLevelColumn *column = lcfx->getColumn(); |
| int i; |
| for (i = 0; i < column->getRowCount(); i++) { |
| TXshCell dpiCell = lcfx->getColumn()->getCell(i); |
| if (dpiCell.isEmpty()) |
| continue; |
| |
| sl = dpiCell.m_level->getSimpleLevel(); |
| if (!sl) |
| break; |
| |
| TAffine dpiAff = ::getDpiAffine(sl, dpiCell.m_frameId, true); |
| pf.m_fx = TFxUtil::makeAffine(pf.m_fx, dpiAff); |
| break; |
| } |
| } |
| |
| return pf; |
| } else |
| return PlacedFx(); |
| } |
| |
| |
| |
| PlacedFx FxBuilder::makePF(TPaletteColumnFx *pcfx) |
| { |
| assert(pcfx); |
| assert(pcfx->getColumn()); |
| if (!pcfx->getColumn()->isPreviewVisible()) |
| return PlacedFx(); |
| |
| TXshCell cell = pcfx->getColumn()->getCell(tfloor(m_frame)); |
| if (cell.isEmpty()) |
| return PlacedFx(); |
| |
| PlacedFx pf; |
| pf.m_columnIndex = pcfx->getColumn()->getIndex(); |
| pf.m_fx = pcfx; |
| |
| return pf; |
| } |
| |
| |
| |
| PlacedFx FxBuilder::makePF(TZeraryColumnFx *zcfx) |
| { |
| assert(zcfx); |
| assert(zcfx->getColumn()); |
| |
| if (!zcfx->getColumn()->isPreviewVisible()) |
| return PlacedFx(); |
| |
| if (!zcfx->getAttributes()->isEnabled()) |
| return PlacedFx(); |
| |
| TFx *fx = zcfx->getZeraryFx(); |
| if (!fx || !fx->getAttributes()->isEnabled()) |
| return PlacedFx(); |
| |
| TXshCell cell = zcfx->getColumn()->getCell(tfloor(m_frame)); |
| if (cell.isEmpty()) |
| return PlacedFx(); |
| |
| |
| PlacedFx pf; |
| pf.m_columnIndex = zcfx->getColumn()->getIndex(); |
| pf.m_fx = fx->clone(false); |
| |
| |
| |
| for (int i = 0; i < fx->getInputPortCount(); ++i) { |
| |
| if (TFxP inputFx = fx->getInputPort(i)->getFx()) { |
| PlacedFx inputPF; |
| |
| |
| |
| if (fx->getFxType() == "STD_particlesFx" || |
| fx->getFxType() == "STD_iwa_TiledParticlesFx" || |
| fx->getFxType() == "STD_tiledParticlesFx") { |
| m_particleDescendentCount++; |
| inputPF = makePF(inputFx.getPointer()); |
| m_particleDescendentCount--; |
| } else |
| inputPF = makePF(inputFx.getPointer()); |
| |
| inputFx = getFxWithColumnMovements(inputPF); |
| if (!inputFx) |
| continue; |
| |
| inputFx = TFxUtil::makeAffine(inputFx, pf.m_aff.inv()); |
| if (!pf.m_fx->connect(pf.m_fx->getInputPortName(i), inputFx.getPointer())) |
| assert(!"Could not connect ports!"); |
| } |
| } |
| |
| |
| if (getColumnPlacement(pf, m_xsh, m_frame, pf.m_columnIndex, m_isPreview)) |
| return pf; |
| else |
| return PlacedFx(); |
| } |
| |
| |
| |
| PlacedFx FxBuilder::makePFfromUnaryFx(TFx *fx) |
| { |
| assert(!dynamic_cast<TLevelColumnFx *>(fx)); |
| assert(!dynamic_cast<TZeraryColumnFx *>(fx)); |
| assert(fx->getInputPortCount() == 1); |
| |
| TFx *inputFx = fx->getInputPort(0)->getFx(); |
| if (!inputFx) |
| return PlacedFx(); |
| |
| PlacedFx pf = makePF(inputFx); |
| if (!pf.m_fx) |
| return PlacedFx(); |
| |
| if (fx->getAttributes()->isEnabled()) { |
| |
| |
| |
| if (pf.m_fx.getPointer() != inputFx || |
| fx->getAttributes()->isSpeedAware() || |
| dynamic_cast<TMacroFx *>(fx)) |
| |
| { |
| fx = fx->clone(false); |
| if (!fx->connect(fx->getInputPortName(0), pf.m_fx.getPointer())) |
| assert(!"Could not connect ports!"); |
| } |
| |
| pf.m_fx = fx; |
| |
| if (fx->getAttributes()->isSpeedAware()) { |
| |
| MotionAwareBaseFx *mabfx = dynamic_cast<MotionAwareBaseFx *>(fx); |
| if (mabfx) { |
| double shutterStart = mabfx->getShutterStart()->getValue(m_frame); |
| double shutterEnd = mabfx->getShutterEnd()->getValue(m_frame); |
| int traceResolution = mabfx->getTraceResolution()->getValue(); |
| |
| MotionObjectType type = mabfx->getMotionObjectType(); |
| int index = mabfx->getMotionObjectIndex()->getValue(); |
| TStageObjectId objectId = getMotionObjectId(type, index); |
| fx->getAttributes()->setMotionPoints(getColumnMotionPoints(m_xsh, m_frame, pf.m_columnIndex, objectId, m_isPreview, |
| shutterStart, shutterEnd, traceResolution)); |
| } else { |
| TPointD speed = getColumnSpeed(m_xsh, m_frame, pf.m_columnIndex, m_isPreview); |
| fx->getAttributes()->setSpeed(speed); |
| } |
| } |
| } |
| |
| return pf; |
| } |
| |
| |
| |
| PlacedFx FxBuilder::makePFfromGenericFx(TFx *fx) |
| { |
| assert(!dynamic_cast<TLevelColumnFx *>(fx)); |
| assert(!dynamic_cast<TZeraryColumnFx *>(fx)); |
| |
| PlacedFx pf; |
| |
| if (!fx->getAttributes()->isEnabled()) { |
| if (fx->getInputPortCount() == 0) |
| return PlacedFx(); |
| |
| TFxP inputFx = fx->getInputPort(fx->getPreferredInputPort())->getFx(); |
| if (inputFx) |
| return makePF(inputFx.getPointer()); |
| |
| return pf; |
| } |
| |
| |
| |
| pf.m_fx = fx->clone(false); |
| |
| bool firstInput = true; |
| |
| int m = fx->getInputPortCount(); |
| for (int i = 0; i < m; ++i) { |
| if (TFxP inputFx = fx->getInputPort(i)->getFx()) { |
| PlacedFx inputPF = makePF(inputFx.getPointer()); |
| inputFx = inputPF.m_fx; |
| if (!inputFx) |
| continue; |
| |
| if (firstInput) { |
| firstInput = false; |
| |
| |
| pf.m_aff = inputPF.m_aff; |
| pf.m_columnIndex = inputPF.m_columnIndex; |
| pf.m_z = inputPF.m_z; |
| pf.m_so = inputPF.m_so; |
| |
| |
| if (pf.m_fx->getAttributes()->isSpeedAware()) { |
| MotionAwareBaseFx *mabfx = dynamic_cast<MotionAwareBaseFx *>(fx); |
| if (mabfx) { |
| double shutterStart = mabfx->getShutterStart()->getValue(m_frame); |
| double shutterEnd = mabfx->getShutterEnd()->getValue(m_frame); |
| int traceResolution = mabfx->getTraceResolution()->getValue(); |
| |
| MotionObjectType type = mabfx->getMotionObjectType(); |
| int index = mabfx->getMotionObjectIndex()->getValue(); |
| TStageObjectId objectId = getMotionObjectId(type, index); |
| fx->getAttributes()->setMotionPoints(getColumnMotionPoints(m_xsh, m_frame, pf.m_columnIndex, objectId, m_isPreview, |
| shutterStart, shutterEnd, traceResolution)); |
| } |
| } |
| |
| } else { |
| |
| inputFx = getFxWithColumnMovements(inputPF); |
| inputFx = TFxUtil::makeAffine(inputFx, pf.m_aff.inv()); |
| } |
| |
| if (!pf.m_fx->connect(pf.m_fx->getInputPortName(i), inputFx.getPointer())) |
| assert(!"Could not connect ports!"); |
| } |
| } |
| |
| |
| |
| if (pf.m_fx->getXsheetPort() && pf.m_fx->getXsheetPort()->getFx() == 0) |
| pf.m_leftXsheetPort = pf.m_fx->getXsheetPort(); |
| |
| return pf; |
| } |
| |
| |
| |
| |
| |
| TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, int whichLevels, int shrink, bool isPreview) |
| { |
| FxBuilder builder(scene, xsh, row, whichLevels, isPreview); |
| TFxP fx = builder.buildFx(); |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *cameraPegbar = xsh->getStageObject(cameraId); |
| assert(cameraPegbar); |
| TCamera *camera = cameraPegbar->getCamera(); |
| assert(camera); |
| |
| TAffine aff = getDpiAffine(camera).inv(); |
| if (shrink > 1) { |
| double fac = 0.5 * (1.0 / shrink - 1.0); |
| aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) * TScale(1.0 / shrink) * aff; |
| } |
| |
| fx = TFxUtil::makeAffine(fx, aff); |
| if (fx) |
| fx->setName(L"CameraDPI and Shrink NAffineFx"); |
| |
| fx = TFxUtil::makeOver( |
| TFxUtil::makeColorCard(scene->getProperties()->getBgColor()), |
| fx); |
| return fx; |
| } |
| |
| |
| |
| TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, int shrink, bool isPreview) |
| { |
| int whichLevels = |
| scene->getProperties()->getOutputProperties()->getWhichLevels(); |
| return buildSceneFx(scene, xsh, row, whichLevels, shrink, isPreview); |
| } |
| |
| |
| |
| TFxP buildSceneFx(ToonzScene *scene, double row, int shrink, bool isPreview) |
| { |
| return buildSceneFx(scene, scene->getXsheet(), row, shrink, isPreview); |
| } |
| |
| |
| |
| TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, const TFxP &root, bool isPreview) |
| { |
| int whichLevels = |
| scene->getProperties()->getOutputProperties()->getWhichLevels(); |
| FxBuilder builder(scene, xsh, row, whichLevels, isPreview); |
| return builder.buildFx(root, BSFX_NO_TR); |
| } |
| |
| |
| |
| TFxP buildSceneFx(ToonzScene *scene, double row, const TFxP &root, bool isPreview) |
| { |
| return buildSceneFx(scene, scene->getXsheet(), row, root, isPreview); |
| } |
| |
| |
| |
| |
| |
| DVAPI TFxP buildPartialSceneFx(ToonzScene *scene, double row, const TFxP &root, int shrink, bool isPreview) |
| { |
| int whichLevels = |
| scene->getProperties()->getOutputProperties()->getWhichLevels(); |
| FxBuilder builder(scene, scene->getXsheet(), row, whichLevels, isPreview); |
| TFxP fx = builder.buildFx(root, BSFX_Transforms_Enum(BSFX_CAMERA_TR | BSFX_COLUMN_TR)); |
| |
| TXsheet *xsh = scene->getXsheet(); |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *cameraPegbar = xsh->getStageObject(cameraId); |
| assert(cameraPegbar); |
| TCamera *camera = cameraPegbar->getCamera(); |
| assert(camera); |
| |
| TAffine aff = getDpiAffine(camera).inv(); |
| if (shrink > 1) { |
| double fac = 0.5 * (1.0 / shrink - 1.0); |
| |
| aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) * TScale(1.0 / shrink) * aff; |
| } |
| |
| fx = TFxUtil::makeAffine(fx, aff); |
| return fx; |
| } |
| |
| |
| |
| DVAPI TFxP buildPartialSceneFx(ToonzScene *scene, TXsheet *xsheet, double row, const TFxP &root, int shrink, bool isPreview) |
| { |
| int whichLevels = |
| scene->getProperties()->getOutputProperties()->getWhichLevels(); |
| FxBuilder builder(scene, xsheet, row, whichLevels, isPreview); |
| TFxP fx = builder.buildFx(root, BSFX_Transforms_Enum(BSFX_CAMERA_TR | BSFX_COLUMN_TR)); |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsheet->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsheet->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *cameraPegbar = xsheet->getStageObject(cameraId); |
| assert(cameraPegbar); |
| TCamera *camera = cameraPegbar->getCamera(); |
| assert(camera); |
| |
| TAffine aff = getDpiAffine(camera).inv(); |
| if (shrink > 1) { |
| double fac = 0.5 * (1.0 / shrink - 1.0); |
| |
| aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) * TScale(1.0 / shrink) * aff; |
| } |
| |
| fx = TFxUtil::makeAffine(fx, aff); |
| return fx; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| DVAPI TFxP buildPostSceneFx(ToonzScene *scene, double frame, int shrink, bool isPreview) |
| { |
| |
| int whichLevels = scene->getProperties()->getOutputProperties()->getWhichLevels(); |
| |
| TXsheet *xsh = scene->getXsheet(); |
| if (!xsh) |
| xsh = scene->getXsheet(); |
| |
| |
| FxBuilder builder(scene, xsh, frame, whichLevels, isPreview, false); |
| |
| TFxP fx = builder.buildFx(); |
| |
| TStageObjectId cameraId; |
| if (isPreview) |
| cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId(); |
| else |
| cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *cameraPegbar = xsh->getStageObject(cameraId); |
| assert(cameraPegbar); |
| TCamera *camera = cameraPegbar->getCamera(); |
| assert(camera); |
| |
| TAffine aff = getDpiAffine(camera).inv(); |
| |
| if (shrink > 1) { |
| double fac = 0.5 * (1.0 / shrink - 1.0); |
| aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) * TScale(1.0 / shrink) * aff; |
| } |
| |
| if (!aff.isIdentity()) |
| fx = TFxUtil::makeAffine(fx, aff); |
| |
| return fx; |
| } |
| |
| |
| |
| DVAPI TFxP buildSceneFx(ToonzScene *scene, double frame, TXsheet *xsh, const TFxP &root, |
| BSFX_Transforms_Enum transforms, |
| bool isPreview, int whichLevels, int shrink) |
| { |
| |
| if (whichLevels == -1) |
| whichLevels = scene->getProperties()->getOutputProperties()->getWhichLevels(); |
| |
| if (!xsh) |
| xsh = scene->getXsheet(); |
| |
| FxBuilder builder(scene, xsh, frame, whichLevels, isPreview); |
| |
| TFxP fx = root ? builder.buildFx(root, transforms) |
| : builder.buildFx(); |
| |
| TStageObjectId cameraId = |
| isPreview ? xsh->getStageObjectTree()->getCurrentPreviewCameraId() |
| : xsh->getStageObjectTree()->getCurrentCameraId(); |
| |
| TStageObject *cameraPegbar = xsh->getStageObject(cameraId); |
| assert(cameraPegbar); |
| |
| TCamera *camera = cameraPegbar->getCamera(); |
| assert(camera); |
| |
| TAffine aff; |
| if (transforms & BSFX_CAMERA_DPI_TR) |
| aff = getDpiAffine(camera).inv(); |
| |
| if (shrink > 1) { |
| double fac = 0.5 * (1.0 / shrink - 1.0); |
| aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) * TScale(1.0 / shrink) * aff; |
| } |
| |
| if (!aff.isIdentity()) |
| fx = TFxUtil::makeAffine(fx, aff); |
| |
| return fx; |
| } |
| |