|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxattributes.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmacrofx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toutputproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamcontainer.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheet.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjecttree.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnfxset.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/fxdag.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshchildlevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshleveltypes.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshlevelcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshpalettecolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshzeraryfxcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/dpiscale.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcamera.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/sceneproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/plasticdeformerfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/preferences.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttzpimagefx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "../stdfx/motionawarebasefx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/scenefx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
TODO: Some parts of the following render-tree building procedure should be
|
|
Shinya Kitaoka |
120a6e |
revised. In particular,
|
|
Shinya Kitaoka |
120a6e |
there is scarce support for frame-shifting fxs, whenever the frame-shift
|
|
Shinya Kitaoka |
120a6e |
can be resolved
|
|
Toshihiro Shimizu |
890ddd |
only during rendering (as is the case for ParticlesFx).
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// TimeShuffleFx definition
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! TimeShuffleFx is the rendering-tree equivalent of a sub-xsheet column.
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
TimeShuffleFx is a special-purpose fx which is used in render-tree building
|
|
Shinya Kitaoka |
120a6e |
procedures
|
|
Toshihiro Shimizu |
890ddd |
to simulate the effect of a sub-xsheet.
|
|
Toshihiro Shimizu |
890ddd |
\n\n
|
|
Shinya Kitaoka |
120a6e |
A rendering tree is a fully expanded tree that mixes implicit xsheet nesting
|
|
Shinya Kitaoka |
120a6e |
with
|
|
Shinya Kitaoka |
120a6e |
the explicit fxs dag for a specific frame <\I>. Since the frame the tree
|
|
Shinya Kitaoka |
120a6e |
is developed from
|
|
Toshihiro Shimizu |
890ddd |
is fixed, a sub-xsheet can be seen as a frame setter <\I> fx.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TimeShuffleFx final : public TRasterFx {
|
|
Shinya Kitaoka |
120a6e |
FX_DECLARATION(TimeShuffleFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
int m_frame; //!< Frame this fx redirects to
|
|
Shinya Kitaoka |
120a6e |
TFxTimeRegion m_timeRegion; //!< Input (outer) valid column frame range
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_port; //!< Input port
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TimeShuffleFx() : TRasterFx(), m_frame(0), m_timeRegion() {
|
|
Shinya Kitaoka |
120a6e |
addInputPort("source", m_port);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
~TimeShuffleFx() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
TFx *clone(bool recursive = true) const override {
|
|
Shinya Kitaoka |
120a6e |
TimeShuffleFx *fx = dynamic_cast<timeshufflefx *="">(TFx::clone(recursive));</timeshufflefx>
|
|
Shinya Kitaoka |
120a6e |
assert(fx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
fx->setFrame(m_frame);
|
|
Shinya Kitaoka |
120a6e |
fx->setTimeRegion(getTimeRegion());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int getFrame() const { return m_frame; }
|
|
Shinya Kitaoka |
120a6e |
void setFrame(int frame) { m_frame = frame; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void setTimeRegion(const TFxTimeRegion &timeRegion) {
|
|
Shinya Kitaoka |
120a6e |
m_timeRegion = timeRegion;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TFxTimeRegion getTimeRegion() const override { return m_timeRegion; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
bool canHandle(const TRenderSettings &info, double frame) override {
|
|
Shinya Kitaoka |
38fd86 |
return true;
|
|
Shinya Kitaoka |
38fd86 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
std::string getPluginId() const override { return std::string(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void compute(TFlash &flash, int frame) override {
|
|
Shinya Kitaoka |
120a6e |
if (!m_port.isConnected()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterFxP(m_port.getFx())->compute(flash, m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
void doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &ri) override {
|
|
Shinya Kitaoka |
120a6e |
if (!m_port.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->clear();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Exchange frame with the stored one
|
|
Shinya Kitaoka |
120a6e |
TRasterFxP(m_port.getFx())->compute(tile, m_frame, ri);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
bool doGetBBox(double frame, TRectD &bbox,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
if (!m_port.isConnected()) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TRasterFxP(m_port.getFx())->doGetBBox(m_frame, bbox, info);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
std::string getAlias(double frame,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &info) const override {
|
|
Shinya Kitaoka |
120a6e |
return TRasterFx::getAlias(m_frame, info);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
void doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
if (m_port.isConnected())
|
|
Shinya Kitaoka |
120a6e |
TRasterFxP(m_port.getFx())->dryCompute(rect, m_frame, info);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
// not implemented
|
|
Shinya Kitaoka |
120a6e |
TimeShuffleFx(const TimeShuffleFx &);
|
|
Shinya Kitaoka |
120a6e |
TimeShuffleFx &operator=(const TimeShuffleFx &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_IDENTIFIER_IS_HIDDEN(TimeShuffleFx, "timeShuffleFx")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// AffineFx definition
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! AffineFx is a specialization of TGeometryFx which implements animated or
|
|
Shinya Kitaoka |
120a6e |
//! stage-controlled affines
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
This specific implementation of TGeometryFx is needed to deal with those
|
|
Shinya Kitaoka |
120a6e |
affines which are best
|
|
Toshihiro Shimizu |
890ddd |
\b not resolved during the rendering-tree expansion procedure.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class AffineFx final : public TGeometryFx {
|
|
Shinya Kitaoka |
120a6e |
FX_DECLARATION(AffineFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TXsheet *m_xsheet; //!< Xsheet owning m_stageObject
|
|
Shinya Kitaoka |
120a6e |
TStageObject *m_stageObject; //!< The stage object this AffineFx refers to
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_input; //!< The input port
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
AffineFx() : m_xsheet(0), m_stageObject(0) {
|
|
Shinya Kitaoka |
120a6e |
addInputPort("source", m_input);
|
|
Shinya Kitaoka |
120a6e |
setName(L"AffineFx");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
AffineFx(TXsheet *xsh, TStageObject *pegbar)
|
|
Shinya Kitaoka |
120a6e |
: m_xsheet(xsh), m_stageObject(pegbar) {
|
|
Shinya Kitaoka |
120a6e |
addInputPort("source", m_input);
|
|
Shinya Kitaoka |
120a6e |
setName(L"AffineFx");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
~AffineFx() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TFx *clone(bool recursive = true) const override {
|
|
Shinya Kitaoka |
120a6e |
AffineFx *fx = dynamic_cast<affinefx *="">(TFx::clone(recursive));</affinefx>
|
|
Shinya Kitaoka |
120a6e |
assert(fx);
|
|
Shinya Kitaoka |
120a6e |
fx->m_stageObject = m_stageObject;
|
|
Shinya Kitaoka |
120a6e |
fx->m_xsheet = m_xsheet;
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
38fd86 |
bool canHandle(const TRenderSettings &info, double frame) override {
|
|
Shinya Kitaoka |
38fd86 |
return true;
|
|
Shinya Kitaoka |
38fd86 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TAffine getPlacement(double frame) override {
|
|
Shinya Kitaoka |
120a6e |
TAffine objAff = m_stageObject->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double objZ = m_stageObject->getZ(frame);
|
|
Shinya Kitaoka |
120a6e |
double objNoScaleZ = m_stageObject->getGlobalNoScaleZ();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId =
|
|
Shinya Kitaoka |
120a6e |
m_xsheet->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = m_xsheet->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraAff = camera->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
double cameraZ = camera->getZ(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff;
|
|
Shinya Kitaoka |
120a6e |
bool isVisible = TStageObject::perspective(aff, cameraAff, cameraZ, objAff,
|
|
Shinya Kitaoka |
120a6e |
objZ, objNoScaleZ);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!isVisible)
|
|
Shinya Kitaoka |
120a6e |
return TAffine(); // uh oh
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return aff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TAffine getParentPlacement(double frame) override {
|
|
Shinya Kitaoka |
120a6e |
return m_stageObject->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
std::string getPluginId() const override { return std::string(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
// not implemented
|
|
Shinya Kitaoka |
120a6e |
AffineFx(const AffineFx &);
|
|
Shinya Kitaoka |
120a6e |
AffineFx &operator=(const AffineFx &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_IDENTIFIER_IS_HIDDEN(AffineFx, "affineFx")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlacedFx definition
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! PlacedFx is the enriched form of a TRasterFx during render-tree building.
|
|
Shinya Kitaoka |
120a6e |
class PlacedFx {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
double m_z; //!< Z value for this fx's column
|
|
Shinya Kitaoka |
120a6e |
double m_so; //!< Same as above, for stacking order
|
|
Shinya Kitaoka |
120a6e |
int m_columnIndex; //!< This fx's column index
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP m_fx; //!< The referenced fx
|
|
Shinya Kitaoka |
120a6e |
TAffine m_aff; //!<
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxPort *m_leftXsheetPort;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
PlacedFx()
|
|
Shinya Kitaoka |
120a6e |
: m_z(0)
|
|
Shinya Kitaoka |
120a6e |
, m_so(0)
|
|
Shinya Kitaoka |
120a6e |
, m_columnIndex(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_fx(0)
|
|
Shinya Kitaoka |
120a6e |
, m_aff()
|
|
Shinya Kitaoka |
120a6e |
, m_leftXsheetPort(0) {}
|
|
Shinya Kitaoka |
120a6e |
explicit PlacedFx(const TFxP &fx)
|
|
Shinya Kitaoka |
120a6e |
: m_z(0)
|
|
Shinya Kitaoka |
120a6e |
, m_so(0)
|
|
Shinya Kitaoka |
120a6e |
, m_columnIndex(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_fx(fx)
|
|
Shinya Kitaoka |
120a6e |
, m_aff()
|
|
Shinya Kitaoka |
120a6e |
, m_leftXsheetPort(0) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator<(const PlacedFx &pf) const {
|
|
Shinya Kitaoka |
120a6e |
return (m_z < pf.m_z)
|
|
Shinya Kitaoka |
120a6e |
? true
|
|
Shinya Kitaoka |
120a6e |
: (m_z > pf.m_z)
|
|
Shinya Kitaoka |
120a6e |
? false
|
|
Shinya Kitaoka |
120a6e |
: (m_so < pf.m_so)
|
|
Shinya Kitaoka |
120a6e |
? true
|
|
Shinya Kitaoka |
120a6e |
: (m_so > pf.m_so)
|
|
Shinya Kitaoka |
120a6e |
? false
|
|
Shinya Kitaoka |
120a6e |
: (m_columnIndex < pf.m_columnIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFxP makeFx() {
|
|
Shinya Kitaoka |
120a6e |
return (!m_fx)
|
|
Shinya Kitaoka |
120a6e |
? TFxP()
|
|
Shinya Kitaoka |
120a6e |
: (m_aff == TAffine()) ? m_fx : TFxUtil::makeAffine(m_fx, m_aff);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP timeShuffle(TFxP fx, int frame, TFxTimeRegion timeRegion) {
|
|
Shinya Kitaoka |
120a6e |
TimeShuffleFx *timeShuffle = new TimeShuffleFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
timeShuffle->setFrame(frame);
|
|
Shinya Kitaoka |
120a6e |
timeShuffle->setTimeRegion(timeRegion);
|
|
Shinya Kitaoka |
120a6e |
if (!timeShuffle->connect("source", fx.getPointer()))
|
|
Shinya Kitaoka |
120a6e |
assert(!"Could not connect ports!");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return timeShuffle;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Column-related functions
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool getColumnPlacement(TAffine &aff, TXsheet *xsh, double row, int col,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
if (col < 0) return false;
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(col));
|
|
Shinya Kitaoka |
120a6e |
TAffine objAff = pegbar->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
double objZ = pegbar->getZ(row);
|
|
Shinya Kitaoka |
120a6e |
double noScaleZ = pegbar->getGlobalNoScaleZ();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraAff = camera->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
double cameraZ = camera->getZ(row);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isVisible = TStageObject::perspective(aff, cameraAff, cameraZ, objAff,
|
|
Shinya Kitaoka |
120a6e |
objZ, noScaleZ);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return isVisible;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
b3bd84 |
static bool getColumnPlacement(PlacedFx &pf, TXsheet *xsh, double row, int col,
|
|
Campbell Barton |
b3bd84 |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
if (col < 0) return false;
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(col));
|
|
Shinya Kitaoka |
120a6e |
TAffine objAff = pegbar->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
pf.m_z = pegbar->getZ(row);
|
|
Shinya Kitaoka |
120a6e |
pf.m_so = pegbar->getSO(row);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraAff = camera->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
double cameraZ = camera->getZ(row);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isVisible =
|
|
Shinya Kitaoka |
120a6e |
TStageObject::perspective(pf.m_aff, cameraAff, cameraZ, objAff, pf.m_z,
|
|
Shinya Kitaoka |
120a6e |
pegbar->getGlobalNoScaleZ());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return isVisible;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*-- Objectの位置を得る --*/
|
|
Campbell Barton |
b3bd84 |
static bool getStageObjectPlacement(TAffine &aff, TXsheet *xsh, double row,
|
|
Campbell Barton |
b3bd84 |
TStageObjectId &id, bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = xsh->getStageObjectTree()->getStageObject(id, false);
|
|
Shinya Kitaoka |
120a6e |
if (!pegbar) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine objAff = pegbar->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
double objZ = pegbar->getZ(row);
|
|
Shinya Kitaoka |
120a6e |
double noScaleZ = pegbar->getGlobalNoScaleZ();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraAff = camera->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
double cameraZ = camera->getZ(row);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isVisible = TStageObject::perspective(aff, cameraAff, cameraZ, objAff,
|
|
Shinya Kitaoka |
120a6e |
objZ, noScaleZ);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return isVisible;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*-- typeとindexからStageObjectIdを得る --*/
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId getMotionObjectId(MotionObjectType type, int index) {
|
|
Shinya Kitaoka |
120a6e |
switch (type) {
|
|
Shinya Kitaoka |
120a6e |
case OBJTYPE_OWN:
|
|
Shinya Kitaoka |
120a6e |
return TStageObjectId::NoneId;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case OBJTYPE_COLUMN:
|
|
Shinya Kitaoka |
120a6e |
if (index == 0) return TStageObjectId::NoneId;
|
|
Shinya Kitaoka |
120a6e |
return TStageObjectId::ColumnId(index - 1);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case OBJTYPE_PEGBAR:
|
|
Shinya Kitaoka |
120a6e |
if (index == 0) return TStageObjectId::NoneId;
|
|
Shinya Kitaoka |
120a6e |
return TStageObjectId::PegbarId(index - 1);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case OBJTYPE_TABLE:
|
|
Shinya Kitaoka |
120a6e |
return TStageObjectId::TableId;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case OBJTYPE_CAMERA:
|
|
Shinya Kitaoka |
120a6e |
if (index == 0) return TStageObjectId::NoneId;
|
|
Shinya Kitaoka |
120a6e |
return TStageObjectId::CameraId(index - 1);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TStageObjectId::NoneId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
}; // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static TPointD getColumnSpeed(TXsheet *xsh, double row, int col,
|
|
shun-iwasawa |
27b0cf |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
TAffine aff;
|
|
Shinya Kitaoka |
120a6e |
TPointD a, b;
|
|
Shinya Kitaoka |
120a6e |
const double h = 0.001;
|
|
Shinya Kitaoka |
120a6e |
getColumnPlacement(aff, xsh, row + h, col, isPreview);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- カラムと、カメラの動きに反応 --*/
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraAff = camera->getPlacement(row + h);
|
|
Shinya Kitaoka |
120a6e |
a = aff * TPointD(-cameraAff.a13, -cameraAff.a23);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
aff = TAffine();
|
|
Shinya Kitaoka |
120a6e |
getColumnPlacement(aff, xsh, row - h, col, isPreview);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cameraAff = camera->getPlacement(row - h);
|
|
Shinya Kitaoka |
120a6e |
b = aff * TPointD(-cameraAff.a13, -cameraAff.a23);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (b - a) * (0.5 / h);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*-- オブジェクトの軌跡を、基準点との差分で得る
|
|
Shinya Kitaoka |
120a6e |
objectId: 移動の参考にするオブジェクト。自分自身の場合はNoneId
|
|
Toshihiro Shimizu |
890ddd |
--*/
|
|
Campbell Barton |
b3bd84 |
static QList<tpointd> getColumnMotionPoints(TXsheet *xsh, double row, int col,</tpointd>
|
|
shun-iwasawa |
27b0cf |
TStageObjectId &objectId,
|
|
shun-iwasawa |
27b0cf |
bool isPreview, double shutterStart,
|
|
shun-iwasawa |
27b0cf |
double shutterEnd,
|
|
Campbell Barton |
b3bd84 |
int traceResolution) {
|
|
Shinya Kitaoka |
120a6e |
/*-- 前後フレームが共に0なら空のリストを返す --*/
|
|
Shinya Kitaoka |
120a6e |
if (shutterStart == 0.0 && shutterEnd == 0.0) return QList<tpointd>();</tpointd>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- 現在のカメラを得る --*/
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
TAffine dpiAff = getDpiAffine(camera->getCamera());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- 基準点の位置を得る --*/
|
|
Shinya Kitaoka |
120a6e |
TAffine aff;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- objectIdが有効なものかどうかチェック --*/
|
|
Shinya Kitaoka |
120a6e |
bool useOwnMotion = false;
|
|
Shinya Kitaoka |
120a6e |
if (objectId == TStageObjectId::NoneId ||
|
|
Shinya Kitaoka |
120a6e |
!xsh->getStageObjectTree()->getStageObject(objectId, false)) {
|
|
Shinya Kitaoka |
120a6e |
getColumnPlacement(aff, xsh, row, col, isPreview);
|
|
Shinya Kitaoka |
120a6e |
useOwnMotion = true;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
getStageObjectPlacement(aff, xsh, row, objectId, isPreview);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraAff = camera->getPlacement(row);
|
|
Shinya Kitaoka |
120a6e |
TPointD basePos =
|
|
Shinya Kitaoka |
120a6e |
dpiAff.inv() * aff * TPointD(-cameraAff.a13, -cameraAff.a23);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- 結果を収めるリスト --*/
|
|
Shinya Kitaoka |
120a6e |
QList<tpointd> points;</tpointd>
|
|
Shinya Kitaoka |
120a6e |
/*-- 軌跡点間のフレーム間隔 --*/
|
|
Shinya Kitaoka |
120a6e |
double dFrame = (shutterStart + shutterEnd) / (double)traceResolution;
|
|
Shinya Kitaoka |
120a6e |
/*-- 各点の位置を、基準点との差分で格納していく --*/
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i <= traceResolution; i++) {
|
|
Shinya Kitaoka |
120a6e |
/*-- 基準位置とのフレーム差 --*/
|
|
Shinya Kitaoka |
120a6e |
double frameOffset = -shutterStart + dFrame * (double)i;
|
|
Shinya Kitaoka |
120a6e |
/*-- 基準位置とのフレーム差が無ければ、基準点に一致するので差分は0を入れる
|
|
Shinya Kitaoka |
120a6e |
* --*/
|
|
Shinya Kitaoka |
120a6e |
if (frameOffset == 0.0) {
|
|
Shinya Kitaoka |
120a6e |
points.append(TPointD(0.0, 0.0));
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
a048bc |
double targetFrame = row + frameOffset;
|
|
shun-iwasawa |
a048bc |
// Proper position cannot be obtained for frame = -1.0
|
|
shun-iwasawa |
a048bc |
if (targetFrame == -1.0) targetFrame = -0.9999;
|
|
shun-iwasawa |
a048bc |
|
|
Shinya Kitaoka |
120a6e |
/*-- 自分自身の動きを使うか、別オブジェクトの動きを使うか --*/
|
|
Shinya Kitaoka |
120a6e |
if (useOwnMotion)
|
|
shun-iwasawa |
a048bc |
getColumnPlacement(aff, xsh, targetFrame, col, isPreview);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
shun-iwasawa |
a048bc |
getStageObjectPlacement(aff, xsh, targetFrame, objectId, isPreview);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
a048bc |
TAffine cameraAff = camera->getPlacement(targetFrame);
|
|
Shinya Kitaoka |
120a6e |
TPointD tmpPos =
|
|
Shinya Kitaoka |
120a6e |
dpiAff.inv() * aff * TPointD(-cameraAff.a13, -cameraAff.a23);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- 基準位置との差を記録 --*/
|
|
Shinya Kitaoka |
120a6e |
points.append(tmpPos - basePos);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return points;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// FxBuilder definition
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class FxBuilder {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ToonzScene *m_scene;
|
|
Shinya Kitaoka |
120a6e |
TXsheet *m_xsh;
|
|
Shinya Kitaoka |
120a6e |
TAffine m_cameraAff;
|
|
Shinya Kitaoka |
120a6e |
double m_cameraZ;
|
|
Shinya Kitaoka |
120a6e |
double m_frame;
|
|
Shinya Kitaoka |
120a6e |
int m_whichLevels;
|
|
Shinya Kitaoka |
120a6e |
bool m_isPreview;
|
|
Shinya Kitaoka |
120a6e |
bool m_expandXSheet;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// in the makePF() methods m_particleDescendentCount>0 iff the TFx* is an
|
|
Shinya Kitaoka |
120a6e |
// ancestor
|
|
Shinya Kitaoka |
120a6e |
// (at least) of a particle Fx
|
|
Shinya Kitaoka |
120a6e |
int m_particleDescendentCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
FxBuilder(ToonzScene *scene, TXsheet *xsh, double frame, int whichLevels,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview = false, bool expandXSheet = true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP buildFx();
|
|
Shinya Kitaoka |
120a6e |
TFxP buildFx(const TFxP &root, BSFX_Transforms_Enum transforms);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePF(TLevelColumnFx *fx);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePF(TPaletteColumnFx *fx);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePF(TZeraryColumnFx *fx);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePF(TXsheetFx *fx);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePFfromUnaryFx(TFx *fx);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePFfromGenericFx(TFx *fx);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx makePF(TFx *fx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP getFxWithColumnMovements(const PlacedFx &pf);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool addPlasticDeformerFx(PlacedFx &pf);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FxBuilder::FxBuilder(ToonzScene *scene, TXsheet *xsh, double frame,
|
|
Shinya Kitaoka |
120a6e |
int whichLevels, bool isPreview, bool expandXSheet)
|
|
Shinya Kitaoka |
120a6e |
: m_scene(scene)
|
|
Shinya Kitaoka |
120a6e |
, m_xsh(xsh)
|
|
Shinya Kitaoka |
120a6e |
, m_frame(frame)
|
|
Shinya Kitaoka |
120a6e |
, m_whichLevels(whichLevels)
|
|
Shinya Kitaoka |
120a6e |
, m_isPreview(isPreview)
|
|
Shinya Kitaoka |
120a6e |
, m_expandXSheet(expandXSheet)
|
|
Shinya Kitaoka |
120a6e |
, m_particleDescendentCount(0) {
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (m_isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = m_xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = m_xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *camera = m_xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
m_cameraAff = camera->getPlacement(m_frame);
|
|
Shinya Kitaoka |
120a6e |
m_cameraZ = camera->getZ(m_frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP FxBuilder::buildFx() {
|
|
Shinya Kitaoka |
120a6e |
TFx *outputFx = m_xsh->getFxDag()->getOutputFx(0);
|
|
Shinya Kitaoka |
120a6e |
if (!outputFx || outputFx->getInputPortCount() != 1 ||
|
|
Shinya Kitaoka |
120a6e |
outputFx->getInputPort(0)->getFx() == 0)
|
|
Shinya Kitaoka |
120a6e |
return TFxP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
outputFx->setName(L"OutputFx");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_particleDescendentCount == 0);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf = makePF(outputFx->getInputPort(0)->getFx());
|
|
Shinya Kitaoka |
120a6e |
assert(m_particleDescendentCount == 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraFullAff = m_cameraAff * TScale((1000 + m_cameraZ) / 1000);
|
|
Shinya Kitaoka |
120a6e |
return TFxUtil::makeAffine(pf.makeFx(), cameraFullAff.inv());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP FxBuilder::buildFx(const TFxP &root, BSFX_Transforms_Enum transforms) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_particleDescendentCount == 0);
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf = makePF(root.getPointer());
|
|
Shinya Kitaoka |
120a6e |
assert(m_particleDescendentCount == 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = (transforms & BSFX_COLUMN_TR) ? pf.makeFx() : pf.m_fx;
|
|
Shinya Kitaoka |
120a6e |
if (transforms & BSFX_CAMERA_TR) {
|
|
Shinya Kitaoka |
120a6e |
TAffine cameraFullAff = m_cameraAff * TScale((1000 + m_cameraZ) / 1000);
|
|
Shinya Kitaoka |
120a6e |
fx = TFxUtil::makeAffine(fx, cameraFullAff.inv());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP FxBuilder::getFxWithColumnMovements(const PlacedFx &pf) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = pf.m_fx;
|
|
Shinya Kitaoka |
120a6e |
if (!fx) return fx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (pf.m_columnIndex == -1) return pf.m_fx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId id = TStageObjectId::ColumnId(pf.m_columnIndex);
|
|
Shinya Kitaoka |
120a6e |
TStageObject *pegbar = m_xsh->getStageObject(id);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
AffineFx *affFx = new AffineFx(m_xsh, pegbar);
|
|
Shinya Kitaoka |
120a6e |
affFx->getInputPort(0)->setFx(fx.getPointer());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return affFx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool FxBuilder::addPlasticDeformerFx(PlacedFx &pf) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *obj =
|
|
Shinya Kitaoka |
120a6e |
m_xsh->getStageObject(TStageObjectId::ColumnId(pf.m_columnIndex));
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId parentId(obj->getParent());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') {
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd =
|
|
Shinya Kitaoka |
120a6e |
m_xsh->getStageObject(parentId)->getPlasticSkeletonDeformation();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &parentCell = m_xsh->getCell(m_frame, parentId.getIndex());
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *parentSl = parentCell.getSimpleLevel();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (sd && parentSl && (parentSl->getType() == MESH_XSHLEVEL)) {
|
|
Shinya Kitaoka |
120a6e |
// Plastic Deformer case - add the corresponding fx,
|
|
Shinya Kitaoka |
120a6e |
// absorb the dpi and local column placement affines
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerFx *plasticFx = new PlasticDeformerFx;
|
|
Shinya Kitaoka |
120a6e |
plasticFx->m_xsh = m_xsh;
|
|
Shinya Kitaoka |
120a6e |
plasticFx->m_col = parentId.getIndex();
|
|
Shinya Kitaoka |
120a6e |
plasticFx->m_texPlacement = obj->getLocalPlacement(m_frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!plasticFx->connect("source", pf.m_fx.getPointer()))
|
|
Shinya Kitaoka |
120a6e |
assert(!"Could not connect ports!");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = plasticFx;
|
|
Shinya Kitaoka |
120a6e |
pf.m_aff = pf.m_aff * plasticFx->m_texPlacement.inv();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePF(TFx *fx) {
|
|
Shinya Kitaoka |
120a6e |
if (!fx) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TLevelColumnFx *lcfx = dynamic_cast<tlevelcolumnfx *="">(fx))</tlevelcolumnfx>
|
|
Shinya Kitaoka |
120a6e |
return makePF(lcfx);
|
|
Shinya Kitaoka |
120a6e |
else if (TPaletteColumnFx *pcfx = dynamic_cast<tpalettecolumnfx *="">(fx))</tpalettecolumnfx>
|
|
Shinya Kitaoka |
120a6e |
return makePF(pcfx);
|
|
Shinya Kitaoka |
120a6e |
else if (TZeraryColumnFx *zcfx = dynamic_cast<tzerarycolumnfx *="">(fx))</tzerarycolumnfx>
|
|
Shinya Kitaoka |
120a6e |
return makePF(zcfx);
|
|
Shinya Kitaoka |
120a6e |
else if (TXsheetFx *xsfx = dynamic_cast<txsheetfx *="">(fx))</txsheetfx>
|
|
Shinya Kitaoka |
120a6e |
return makePF(xsfx);
|
|
Shinya Kitaoka |
120a6e |
else if (fx->getInputPortCount() == 1)
|
|
Shinya Kitaoka |
120a6e |
return makePFfromUnaryFx(fx);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return makePFfromGenericFx(fx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePF(TXsheetFx *fx) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_expandXSheet) // Xsheet expansion is typically blocked for render-tree
|
|
Shinya Kitaoka |
120a6e |
// building of
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx(fx); // post-xsheet fxs only.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Expand the render-tree from terminal fxs
|
|
Shinya Kitaoka |
120a6e |
TFxSet *fxs = m_xsh->getFxDag()->getTerminalFxs();
|
|
Shinya Kitaoka |
120a6e |
int m = fxs->getFxCount();
|
|
Shinya Kitaoka |
120a6e |
if (m == 0) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<placedfx> pfs(m);</placedfx>
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m; i++) {
|
|
Shinya Kitaoka |
120a6e |
// Expand each terminal fx
|
|
Shinya Kitaoka |
120a6e |
TFx *fx = fxs->getFx(i);
|
|
Shinya Kitaoka |
120a6e |
assert(fx);
|
|
Shinya Kitaoka |
120a6e |
pfs[i] = makePF(fx); // Builds the sub-render-trees here
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*--
|
|
Shinya Kitaoka |
120a6e |
* Xsheetに複数ノードが繋がっていた場合、PlacedFxの条件に従ってOverノードの付く順番を決める
|
|
Shinya Kitaoka |
120a6e |
* --*/
|
|
Shinya Kitaoka |
120a6e |
std::sort(pfs.begin(),
|
|
Shinya Kitaoka |
120a6e |
pfs.end()); // Sort each terminal depending on Z/SO/Column index
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Compose them in a cascade of overs (or affines 'leftXsheetPort' cases)
|
|
Shinya Kitaoka |
120a6e |
TFxP currentFx =
|
|
Shinya Kitaoka |
120a6e |
pfs[0].makeFx(); // Adds an NaAffineFx if pf.m_aff is not the identity
|
|
Shinya Kitaoka |
120a6e |
for (i = 1; i < m; i++) {
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = pfs[i].makeFx(); // See above
|
|
Shinya Kitaoka |
120a6e |
if (pfs[i].m_leftXsheetPort) {
|
|
Shinya Kitaoka |
120a6e |
// LeftXsheetPort cases happen for those fxs like Add, Multiply, etc that
|
|
Shinya Kitaoka |
120a6e |
// declare an xsheet-like input port.
|
|
Shinya Kitaoka |
120a6e |
// That is, all terminal fxs below ours are attached COMPOSED to enter the
|
|
Shinya Kitaoka |
120a6e |
// fx's leftXsheet input port.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFxP inputFx = currentFx;
|
|
Shinya Kitaoka |
120a6e |
inputFx = TFxUtil::makeAffine(inputFx, pfs[i].m_aff.inv());
|
|
Shinya Kitaoka |
120a6e |
pfs[i].m_leftXsheetPort->setFx(inputFx.getPointer());
|
|
Shinya Kitaoka |
120a6e |
currentFx = fx;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (Preferences::instance()
|
|
Shinya Kitaoka |
120a6e |
->isShowRasterImagesDarkenBlendedInViewerEnabled())
|
|
Shinya Kitaoka |
120a6e |
currentFx = TFxUtil::makeDarken(currentFx, fx);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
currentFx = TFxUtil::makeOver(currentFx, fx); // Common over case
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx(currentFx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Creates and returns a PlacedFx for a TLevelColumnFx.
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Fxs under a ParticlesFx node seem to have special treatment - that is,
|
|
Toshihiro Shimizu |
890ddd |
empty column cells are still attached to a not-empty PlacedFx.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
This must be a remnant of old Toonz code, that should no longer remain here -
|
|
Toshihiro Shimizu |
890ddd |
in fact, well, you can only extract an empty render from an empty column!
|
|
Toshihiro Shimizu |
890ddd |
So why bother?
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePF(TLevelColumnFx *lcfx) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_scene);
|
|
Shinya Kitaoka |
120a6e |
assert(lcfx);
|
|
Shinya Kitaoka |
120a6e |
assert(lcfx->getColumn());
|
|
Shinya Kitaoka |
120a6e |
if (!lcfx || !lcfx->getColumn()) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!lcfx->getColumn()->isPreviewVisible()) // This is the 'eye' icon
|
|
Shinya Kitaoka |
120a6e |
// property in the column header
|
|
Shinya Kitaoka |
120a6e |
// interface
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx(); // that disables rendering of this particular column
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve the corresponding xsheet cell to build up
|
|
Shinya Kitaoka |
120a6e |
/*-- 現在のフレームのセルを取得 --*/
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = lcfx->getColumn()->getCell(tfloor(m_frame));
|
|
Shinya Kitaoka |
120a6e |
int levelFrame = cell.m_frameId.getNumber() - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- ParticlesFxに繋がっておらず、空セルの場合は 中身無しを返す --*/
|
|
Shinya Kitaoka |
120a6e |
if (m_particleDescendentCount == 0 && cell.isEmpty()) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_whichLevels == TOutputProperties::AnimatedOnly) {
|
|
Shinya Kitaoka |
120a6e |
// In case only 'animated levels' are selected to be rendered, exclude all
|
|
Shinya Kitaoka |
120a6e |
// 'backgrounds' - that is,
|
|
Shinya Kitaoka |
120a6e |
// fullcolor levels...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Still, I wonder if this is still used in Toonz. I don't remember seeing
|
|
Shinya Kitaoka |
120a6e |
// it anywhere :\ ?
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshLevel *xl = cell.m_level.getPointer();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- ParticleFxのTextureポートに繋がっていない場合 --*/
|
|
Shinya Kitaoka |
120a6e |
if (m_particleDescendentCount == 0) {
|
|
Shinya Kitaoka |
120a6e |
if (!xl ||
|
|
Shinya Kitaoka |
120a6e |
xl->getType() != PLI_XSHLEVEL && xl->getType() != TZP_XSHLEVEL &&
|
|
Shinya Kitaoka |
120a6e |
xl->getType() != CHILD_XSHLEVEL)
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*-- ParticleFxのTextureポートに繋がっている場合 --*/
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
if (xl && xl->getType() != PLI_XSHLEVEL &&
|
|
Shinya Kitaoka |
120a6e |
xl->getType() != TZP_XSHLEVEL && xl->getType() != CHILD_XSHLEVEL)
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build a PlacedFx for the column - start with the standard version for
|
|
Shinya Kitaoka |
120a6e |
// common (image) levels
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf;
|
|
Shinya Kitaoka |
120a6e |
pf.m_columnIndex = lcfx->getColumn()->getIndex();
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = lcfx;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build column placement
|
|
Shinya Kitaoka |
120a6e |
bool columnVisible =
|
|
Shinya Kitaoka |
120a6e |
getColumnPlacement(pf, m_xsh, m_frame, pf.m_columnIndex, m_isPreview);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- subXsheetのとき、その中身もBuildFxを実行 --*/
|
|
Shinya Kitaoka |
120a6e |
if (!cell.isEmpty() && cell.m_level->getChildLevel()) {
|
|
Shinya Kitaoka |
120a6e |
// Treat the sub-xsheet case - build the sub-render-tree and reassign stuff
|
|
Shinya Kitaoka |
120a6e |
// to pf
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = cell.m_level->getChildLevel()->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build the sub-render-tree
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(m_scene, xsh, levelFrame, m_whichLevels, m_isPreview);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Then, add the TimeShuffleFx
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = timeShuffle(builder.buildFx(), levelFrame, lcfx->getTimeRegion());
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx->setIdentifier(lcfx->getIdentifier());
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx->getAttributes()->passiveCacheDataIdx() =
|
|
Shinya Kitaoka |
120a6e |
lcfx->getAttributes()->passiveCacheDataIdx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If the level should sustain a Plastic deformation, add the corresponding
|
|
Shinya Kitaoka |
120a6e |
// fx
|
|
Shinya Kitaoka |
120a6e |
addPlasticDeformerFx(pf);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (columnVisible) {
|
|
Shinya Kitaoka |
120a6e |
// Column is visible, alright
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *sl = cell.isEmpty() ? 0 : cell.m_level->getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
if (sl) {
|
|
Shinya Kitaoka |
120a6e |
// If the level should sustain a Plastic deformation, add the
|
|
Shinya Kitaoka |
120a6e |
// corresponding fx
|
|
Shinya Kitaoka |
120a6e |
if (!addPlasticDeformerFx(pf)) {
|
|
Shinya Kitaoka |
120a6e |
// Common (image) level case - add an NaAffineFx to compensate for the
|
|
Shinya Kitaoka |
120a6e |
// image's dpi
|
|
Shinya Kitaoka |
120a6e |
TAffine dpiAff = ::getDpiAffine(
|
|
Shinya Kitaoka |
120a6e |
sl, cell.m_frameId, true); // true stands for 'force full-sampling'
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = TFxUtil::makeAffine(pf.m_fx, dpiAff);
|
|
Shinya Kitaoka |
120a6e |
if (pf.m_fx) pf.m_fx->setName(L"LevelColumn AffineFx");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Okay, weird code ensues. This is what happens on non-common image
|
|
Shinya Kitaoka |
120a6e |
// cases, which should be:
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// 1. Sub-Xsheet cases - and it really shouldn't
|
|
Shinya Kitaoka |
120a6e |
// 2. Empty cell cases - with m_particles_blabla > 0; and again I don't
|
|
Shinya Kitaoka |
120a6e |
// get why on earth this should happen...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Please, note that (1) is a bug, although it happens when inserting a
|
|
Shinya Kitaoka |
120a6e |
// common level and a sub-xsh
|
|
Shinya Kitaoka |
120a6e |
// level in the same column...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// when a cell not exists, there is no way to keep the dpi of the image!
|
|
Shinya Kitaoka |
120a6e |
// in this case it is kept the dpi of the first cell not empty in the
|
|
Shinya Kitaoka |
120a6e |
// column!
|
|
Shinya Kitaoka |
120a6e |
/*--
|
|
Shinya Kitaoka |
120a6e |
* 空セルのとき、Dpiアフィン変換には、その素材が入っている一番上のセルのものを使う
|
|
Shinya Kitaoka |
120a6e |
* --*/
|
|
Shinya Kitaoka |
120a6e |
TXshLevelColumn *column = lcfx->getColumn();
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < column->getRowCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TXshCell dpiCell = lcfx->getColumn()->getCell(i);
|
|
Shinya Kitaoka |
120a6e |
if (dpiCell.isEmpty()) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sl = dpiCell.m_level->getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
if (!sl) break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine dpiAff = ::getDpiAffine(sl, dpiCell.m_frameId, true);
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = TFxUtil::makeAffine(pf.m_fx, dpiAff);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun_iwasawa |
2c0f50 |
// Apply column's color filter and semi-transparency for rendering
|
|
shun_iwasawa |
2c0f50 |
TXshLevelColumn *column = lcfx->getColumn();
|
|
shun_iwasawa |
2c0f50 |
if (m_scene->getProperties()->isColumnColorFilterOnRenderEnabled() &&
|
|
shun_iwasawa |
2c0f50 |
(column->getFilterColorId() != TXshColumn::FilterNone ||
|
|
shun_iwasawa |
2c0f50 |
(column->isCamstandVisible() && column->getOpacity() != 255))) {
|
|
shun_iwasawa |
2c0f50 |
TPixel32 colorScale = column->getFilterColor();
|
|
shun_iwasawa |
2c0f50 |
colorScale.m = column->getOpacity();
|
|
shun_iwasawa |
2c0f50 |
pf.m_fx = TFxUtil::makeColumnColorFilter(pf.m_fx, colorScale);
|
|
shun_iwasawa |
2c0f50 |
}
|
|
shun_iwasawa |
2c0f50 |
|
|
Shinya Kitaoka |
120a6e |
return pf;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePF(TPaletteColumnFx *pcfx) {
|
|
Shinya Kitaoka |
120a6e |
assert(pcfx);
|
|
Shinya Kitaoka |
120a6e |
assert(pcfx->getColumn());
|
|
Shinya Kitaoka |
120a6e |
if (!pcfx->getColumn()->isPreviewVisible()) return PlacedFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = pcfx->getColumn()->getCell(tfloor(m_frame));
|
|
Shinya Kitaoka |
120a6e |
if (cell.isEmpty()) return PlacedFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf;
|
|
Shinya Kitaoka |
120a6e |
pf.m_columnIndex = pcfx->getColumn()->getIndex();
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = pcfx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return pf;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePF(TZeraryColumnFx *zcfx) {
|
|
Shinya Kitaoka |
120a6e |
assert(zcfx);
|
|
Shinya Kitaoka |
120a6e |
assert(zcfx->getColumn());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!zcfx->getColumn()->isPreviewVisible()) // ...
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!zcfx->getAttributes()->isEnabled()) // ...
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFx *fx = zcfx->getZeraryFx();
|
|
Shinya Kitaoka |
120a6e |
if (!fx || !fx->getAttributes()->isEnabled()) // ... Perhaps these shouldn't
|
|
Shinya Kitaoka |
120a6e |
// be tested altogether? Only 1
|
|
Shinya Kitaoka |
120a6e |
// truly works !
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshCell cell = zcfx->getColumn()->getCell(tfloor(m_frame));
|
|
Shinya Kitaoka |
120a6e |
if (cell.isEmpty()) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf;
|
|
Shinya Kitaoka |
120a6e |
pf.m_columnIndex = zcfx->getColumn()->getIndex();
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = fx->clone(
|
|
Shinya Kitaoka |
120a6e |
false); // Detach the fx with a clone. Why? It's typically done to
|
|
Shinya Kitaoka |
120a6e |
// build fx connections in the render-tree freely. Here, it's
|
|
Shinya Kitaoka |
120a6e |
// used just for particles, I guess...
|
|
Shinya Kitaoka |
120a6e |
// Deal with input sub-trees
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < fx->getInputPortCount(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
// Note that only particles should end up here, currently
|
|
Shinya Kitaoka |
120a6e |
if (TFxP inputFx = fx->getInputPort(i)->getFx()) {
|
|
Shinya Kitaoka |
120a6e |
PlacedFx inputPF;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if the effect is a particle fx, it is necessary to consider also empty
|
|
Shinya Kitaoka |
120a6e |
// cells
|
|
Shinya Kitaoka |
120a6e |
// this causes a connection with the effect and a level also with empty
|
|
Shinya Kitaoka |
120a6e |
// cells.
|
|
Shinya Kitaoka |
120a6e |
if (fx->getFxType() == "STD_particlesFx" ||
|
|
Shinya Kitaoka |
120a6e |
fx->getFxType() == "STD_iwa_TiledParticlesFx" ||
|
|
Shinya Kitaoka |
120a6e |
fx->getFxType() == "STD_tiledParticlesFx") {
|
|
Shinya Kitaoka |
120a6e |
m_particleDescendentCount++;
|
|
Shinya Kitaoka |
120a6e |
inputPF = makePF(inputFx.getPointer());
|
|
Shinya Kitaoka |
120a6e |
m_particleDescendentCount--;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
inputPF = makePF(inputFx.getPointer());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputFx = getFxWithColumnMovements(inputPF);
|
|
Shinya Kitaoka |
120a6e |
if (!inputFx) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputFx = TFxUtil::makeAffine(inputFx, pf.m_aff.inv());
|
|
Shinya Kitaoka |
120a6e |
if (!pf.m_fx->connect(pf.m_fx->getInputPortName(i), inputFx.getPointer()))
|
|
Shinya Kitaoka |
120a6e |
assert(!"Could not connect ports!");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add the column placement NaAffineFx
|
|
Shinya Kitaoka |
120a6e |
if (getColumnPlacement(pf, m_xsh, m_frame, pf.m_columnIndex, m_isPreview))
|
|
Shinya Kitaoka |
120a6e |
return pf;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return PlacedFx();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePFfromUnaryFx(TFx *fx) {
|
|
Shinya Kitaoka |
120a6e |
assert(!dynamic_cast<tlevelcolumnfx *="">(fx));</tlevelcolumnfx>
|
|
Shinya Kitaoka |
120a6e |
assert(!dynamic_cast<tzerarycolumnfx *="">(fx));</tzerarycolumnfx>
|
|
Shinya Kitaoka |
120a6e |
assert(fx->getInputPortCount() == 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFx *inputFx = fx->getInputPort(0)->getFx();
|
|
Shinya Kitaoka |
120a6e |
if (!inputFx) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf = makePF(inputFx); // Build sub-render-tree
|
|
Shinya Kitaoka |
120a6e |
if (!pf.m_fx) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (fx->getAttributes()->isEnabled()) {
|
|
Shinya Kitaoka |
120a6e |
// Fx is enabled, so insert it in the render-tree
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Clone this fx necessary
|
|
Shinya Kitaoka |
120a6e |
if (pf.m_fx.getPointer() != inputFx || // As in an earlier makePF, clone
|
|
Shinya Kitaoka |
120a6e |
// whenever input connections have
|
|
Shinya Kitaoka |
120a6e |
// changed
|
|
Shinya Kitaoka |
120a6e |
fx->getAttributes()->isSpeedAware() || // In the 'speedAware' case,
|
|
Shinya Kitaoka |
120a6e |
// we'll alter the fx's
|
|
Shinya Kitaoka |
120a6e |
// attributes (see below)
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tmacrofx *="">(fx)) // As for macros... I'm not sure. Not</tmacrofx>
|
|
Shinya Kitaoka |
120a6e |
// even who wrote this *understood*
|
|
Shinya Kitaoka |
120a6e |
// why - it just solved a bug X( . Investigate!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
fx = fx->clone(false);
|
|
Shinya Kitaoka |
120a6e |
if (!fx->connect(fx->getInputPortName(0), pf.m_fx.getPointer()))
|
|
Shinya Kitaoka |
120a6e |
assert(!"Could not connect ports!");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = fx;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (fx->getAttributes()->isSpeedAware()) {
|
|
Shinya Kitaoka |
120a6e |
/*-- スピードでなく、軌跡を取得する場合 --*/
|
|
Shinya Kitaoka |
120a6e |
MotionAwareBaseFx *mabfx = dynamic_cast<motionawarebasefx *="">(fx);</motionawarebasefx>
|
|
Shinya Kitaoka |
120a6e |
if (mabfx) {
|
|
Shinya Kitaoka |
120a6e |
double shutterStart = mabfx->getShutterStart()->getValue(m_frame);
|
|
Shinya Kitaoka |
120a6e |
double shutterEnd = mabfx->getShutterEnd()->getValue(m_frame);
|
|
Shinya Kitaoka |
120a6e |
int traceResolution = mabfx->getTraceResolution()->getValue();
|
|
Shinya Kitaoka |
120a6e |
/*-- 移動の参考にするオブジェクトの取得。自分自身の場合はNoneId --*/
|
|
Shinya Kitaoka |
120a6e |
MotionObjectType type = mabfx->getMotionObjectType();
|
|
Shinya Kitaoka |
120a6e |
int index = mabfx->getMotionObjectIndex()->getValue();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objectId = getMotionObjectId(type, index);
|
|
Shinya Kitaoka |
120a6e |
fx->getAttributes()->setMotionPoints(getColumnMotionPoints(
|
|
Shinya Kitaoka |
120a6e |
m_xsh, m_frame, pf.m_columnIndex, objectId, m_isPreview,
|
|
Shinya Kitaoka |
120a6e |
shutterStart, shutterEnd, traceResolution));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TPointD speed =
|
|
Shinya Kitaoka |
120a6e |
getColumnSpeed(m_xsh, m_frame, pf.m_columnIndex, m_isPreview);
|
|
Shinya Kitaoka |
120a6e |
fx->getAttributes()->setSpeed(speed);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return pf;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx FxBuilder::makePFfromGenericFx(TFx *fx) {
|
|
Shinya Kitaoka |
120a6e |
assert(!dynamic_cast<tlevelcolumnfx *="">(fx));</tlevelcolumnfx>
|
|
Shinya Kitaoka |
120a6e |
assert(!dynamic_cast<tzerarycolumnfx *="">(fx));</tzerarycolumnfx>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PlacedFx pf;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!fx->getAttributes()->isEnabled()) {
|
|
Shinya Kitaoka |
120a6e |
if (fx->getInputPortCount() == 0) return PlacedFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFxP inputFx = fx->getInputPort(fx->getPreferredInputPort())->getFx();
|
|
Shinya Kitaoka |
120a6e |
if (inputFx) return makePF(inputFx.getPointer());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return pf;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Multi-input fxs are always cloned - since at least one of its input ports
|
|
Shinya Kitaoka |
120a6e |
// will have an NaAffineFx
|
|
Shinya Kitaoka |
120a6e |
// injected just before its actual input fx.
|
|
Shinya Kitaoka |
120a6e |
pf.m_fx = fx->clone(false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool firstInput = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int m = fx->getInputPortCount();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m; ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (TFxP inputFx = fx->getInputPort(i)->getFx()) {
|
|
Shinya Kitaoka |
120a6e |
PlacedFx inputPF = makePF(inputFx.getPointer());
|
|
Shinya Kitaoka |
120a6e |
inputFx = inputPF.m_fx;
|
|
Shinya Kitaoka |
120a6e |
if (!inputFx) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (firstInput) {
|
|
Shinya Kitaoka |
120a6e |
firstInput = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// The first found input PlacedFx carries its placement infos up
|
|
Shinya Kitaoka |
120a6e |
pf.m_aff = inputPF.m_aff;
|
|
Shinya Kitaoka |
120a6e |
pf.m_columnIndex = inputPF.m_columnIndex;
|
|
Shinya Kitaoka |
120a6e |
pf.m_z = inputPF.m_z;
|
|
Shinya Kitaoka |
120a6e |
pf.m_so = inputPF.m_so;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- 軌跡を取得するBinaryFxの場合 --*/
|
|
Shinya Kitaoka |
120a6e |
if (pf.m_fx->getAttributes()->isSpeedAware()) {
|
|
shun-iwasawa |
a048bc |
MotionAwareBaseFx *mabfx =
|
|
shun-iwasawa |
a048bc |
dynamic_cast<motionawarebasefx *="">(pf.m_fx.getPointer());</motionawarebasefx>
|
|
Shinya Kitaoka |
120a6e |
if (mabfx) {
|
|
Shinya Kitaoka |
120a6e |
double shutterStart = mabfx->getShutterStart()->getValue(m_frame);
|
|
Shinya Kitaoka |
120a6e |
double shutterEnd = mabfx->getShutterEnd()->getValue(m_frame);
|
|
Shinya Kitaoka |
120a6e |
int traceResolution = mabfx->getTraceResolution()->getValue();
|
|
Shinya Kitaoka |
120a6e |
/*-- 移動の参考にするオブジェクトの取得。自分自身の場合はNoneId --*/
|
|
Shinya Kitaoka |
120a6e |
MotionObjectType type = mabfx->getMotionObjectType();
|
|
Shinya Kitaoka |
120a6e |
int index = mabfx->getMotionObjectIndex()->getValue();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId objectId = getMotionObjectId(type, index);
|
|
shun-iwasawa |
a048bc |
pf.m_fx->getAttributes()->setMotionPoints(getColumnMotionPoints(
|
|
Shinya Kitaoka |
120a6e |
m_xsh, m_frame, pf.m_columnIndex, objectId, m_isPreview,
|
|
Shinya Kitaoka |
120a6e |
shutterStart, shutterEnd, traceResolution));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// The follow-ups traduce their PlacedFx::m_aff into an NaAffineFx,
|
|
Shinya Kitaoka |
120a6e |
// instead
|
|
Shinya Kitaoka |
120a6e |
inputFx = getFxWithColumnMovements(inputPF);
|
|
Shinya Kitaoka |
120a6e |
inputFx = TFxUtil::makeAffine(inputFx, pf.m_aff.inv());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!pf.m_fx->connect(pf.m_fx->getInputPortName(i), inputFx.getPointer()))
|
|
Shinya Kitaoka |
120a6e |
assert(!"Could not connect ports!");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// The xsheet-like input port is activated and brought upwards whenever it is
|
|
Shinya Kitaoka |
120a6e |
// both
|
|
Shinya Kitaoka |
120a6e |
// specified by the fx, and there is no input fx attached to it.
|
|
Shinya Kitaoka |
120a6e |
if (pf.m_fx->getXsheetPort() && pf.m_fx->getXsheetPort()->getFx() == 0)
|
|
Shinya Kitaoka |
120a6e |
pf.m_leftXsheetPort = pf.m_fx->getXsheetPort();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return pf;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Exported Render-Tree building functions
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, int whichLevels,
|
|
Shinya Kitaoka |
120a6e |
int shrink, bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(scene, xsh, row, whichLevels, isPreview);
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = builder.buildFx();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
assert(cameraPegbar);
|
|
Shinya Kitaoka |
120a6e |
TCamera *camera = cameraPegbar->getCamera();
|
|
Shinya Kitaoka |
120a6e |
assert(camera);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = getDpiAffine(camera).inv();
|
|
Shinya Kitaoka |
120a6e |
if (shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
double fac = 0.5 * (1.0 / shrink - 1.0);
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) *
|
|
Shinya Kitaoka |
120a6e |
TScale(1.0 / shrink) * aff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fx = TFxUtil::makeAffine(fx, aff);
|
|
Shinya Kitaoka |
120a6e |
if (fx) fx->setName(L"CameraDPI and Shrink NAffineFx");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fx = TFxUtil::makeOver(
|
|
Shinya Kitaoka |
120a6e |
TFxUtil::makeColorCard(scene->getProperties()->getBgColor()), fx);
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, int shrink,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
int whichLevels =
|
|
Shinya Kitaoka |
120a6e |
scene->getProperties()->getOutputProperties()->getWhichLevels();
|
|
Shinya Kitaoka |
120a6e |
return buildSceneFx(scene, xsh, row, whichLevels, shrink, isPreview);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP buildSceneFx(ToonzScene *scene, double row, int shrink, bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
return buildSceneFx(scene, scene->getXsheet(), row, shrink, isPreview);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP buildSceneFx(ToonzScene *scene, TXsheet *xsh, double row, const TFxP &root,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
int whichLevels =
|
|
Shinya Kitaoka |
120a6e |
scene->getProperties()->getOutputProperties()->getWhichLevels();
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(scene, xsh, row, whichLevels, isPreview);
|
|
Shinya Kitaoka |
120a6e |
return builder.buildFx(root, BSFX_NO_TR);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP buildSceneFx(ToonzScene *scene, double row, const TFxP &root,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
return buildSceneFx(scene, scene->getXsheet(), row, root, isPreview);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Similar to buildSceneFx(ToonzScene *scene, double row, const TFxP &root,
|
|
Shinya Kitaoka |
120a6e |
//! bool isPreview) method, build the sceneFx
|
|
Toshihiro Shimizu |
890ddd |
//! adding also camera transformations. Used for Preview Fx function.
|
|
Shinya Kitaoka |
120a6e |
DVAPI TFxP buildPartialSceneFx(ToonzScene *scene, double row, const TFxP &root,
|
|
Shinya Kitaoka |
120a6e |
int shrink, bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
int whichLevels =
|
|
Shinya Kitaoka |
120a6e |
scene->getProperties()->getOutputProperties()->getWhichLevels();
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(scene, scene->getXsheet(), row, whichLevels, isPreview);
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = builder.buildFx(
|
|
Shinya Kitaoka |
120a6e |
root, BSFX_Transforms_Enum(BSFX_CAMERA_TR | BSFX_COLUMN_TR));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = scene->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
assert(cameraPegbar);
|
|
Shinya Kitaoka |
120a6e |
TCamera *camera = cameraPegbar->getCamera();
|
|
Shinya Kitaoka |
120a6e |
assert(camera);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = getDpiAffine(camera).inv();
|
|
Shinya Kitaoka |
120a6e |
if (shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
double fac = 0.5 * (1.0 / shrink - 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) *
|
|
Shinya Kitaoka |
120a6e |
TScale(1.0 / shrink) * aff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fx = TFxUtil::makeAffine(fx, aff);
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DVAPI TFxP buildPartialSceneFx(ToonzScene *scene, TXsheet *xsheet, double row,
|
|
Shinya Kitaoka |
120a6e |
const TFxP &root, int shrink, bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
int whichLevels =
|
|
Shinya Kitaoka |
120a6e |
scene->getProperties()->getOutputProperties()->getWhichLevels();
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(scene, xsheet, row, whichLevels, isPreview);
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = builder.buildFx(
|
|
Shinya Kitaoka |
120a6e |
root, BSFX_Transforms_Enum(BSFX_CAMERA_TR | BSFX_COLUMN_TR));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsheet->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsheet->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *cameraPegbar = xsheet->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
assert(cameraPegbar);
|
|
Shinya Kitaoka |
120a6e |
TCamera *camera = cameraPegbar->getCamera();
|
|
Shinya Kitaoka |
120a6e |
assert(camera);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = getDpiAffine(camera).inv();
|
|
Shinya Kitaoka |
120a6e |
if (shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
double fac = 0.5 * (1.0 / shrink - 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) *
|
|
Shinya Kitaoka |
120a6e |
TScale(1.0 / shrink) * aff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fx = TFxUtil::makeAffine(fx, aff);
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
Builds the post-rendering fxs tree - that is, all fxs between the xsheet node
|
|
Shinya Kitaoka |
120a6e |
and
|
|
Toshihiro Shimizu |
890ddd |
current output node.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
This function can be used to isolate global post-processing fxs that typically
|
|
Shinya Kitaoka |
120a6e |
do not
|
|
Toshihiro Shimizu |
890ddd |
contribute to scene compositing. When encountered, the xsheet node is \a not
|
|
Toshihiro Shimizu |
890ddd |
xpanded - it must be replaced manually.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
DVAPI TFxP buildPostSceneFx(ToonzScene *scene, double frame, int shrink,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview) {
|
|
Shinya Kitaoka |
120a6e |
// NOTE: Should whichLevels access output AND PREVIEW settings?
|
|
Shinya Kitaoka |
120a6e |
int whichLevels =
|
|
Shinya Kitaoka |
120a6e |
scene->getProperties()->getOutputProperties()->getWhichLevels();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXsheet *xsh = scene->getXsheet();
|
|
Shinya Kitaoka |
120a6e |
if (!xsh) xsh = scene->getXsheet();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Do not expand the xsheet node
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(scene, xsh, frame, whichLevels, isPreview, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = builder.buildFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId;
|
|
Shinya Kitaoka |
120a6e |
if (isPreview)
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentPreviewCameraId();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cameraId = xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Shinya Kitaoka |
120a6e |
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
assert(cameraPegbar);
|
|
Shinya Kitaoka |
120a6e |
TCamera *camera = cameraPegbar->getCamera();
|
|
Shinya Kitaoka |
120a6e |
assert(camera);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = getDpiAffine(camera).inv();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
double fac = 0.5 * (1.0 / shrink - 1.0);
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) *
|
|
Shinya Kitaoka |
120a6e |
TScale(1.0 / shrink) * aff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!aff.isIdentity()) fx = TFxUtil::makeAffine(fx, aff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DVAPI TFxP buildSceneFx(ToonzScene *scene, double frame, TXsheet *xsh,
|
|
Shinya Kitaoka |
120a6e |
const TFxP &root, BSFX_Transforms_Enum transforms,
|
|
Shinya Kitaoka |
120a6e |
bool isPreview, int whichLevels, int shrink) {
|
|
Shinya Kitaoka |
120a6e |
// NOTE: Should whichLevels access output AND PREVIEW settings?
|
|
Shinya Kitaoka |
120a6e |
if (whichLevels == -1)
|
|
Shinya Kitaoka |
120a6e |
whichLevels =
|
|
Shinya Kitaoka |
120a6e |
scene->getProperties()->getOutputProperties()->getWhichLevels();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!xsh) xsh = scene->getXsheet();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FxBuilder builder(scene, xsh, frame, whichLevels, isPreview);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFxP fx = root ? builder.buildFx(root, transforms) : builder.buildFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId cameraId =
|
|
Shinya Kitaoka |
120a6e |
isPreview ? xsh->getStageObjectTree()->getCurrentPreviewCameraId()
|
|
Shinya Kitaoka |
120a6e |
: xsh->getStageObjectTree()->getCurrentCameraId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *cameraPegbar = xsh->getStageObject(cameraId);
|
|
Shinya Kitaoka |
120a6e |
assert(cameraPegbar);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TCamera *camera = cameraPegbar->getCamera();
|
|
Shinya Kitaoka |
120a6e |
assert(camera);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff;
|
|
Shinya Kitaoka |
120a6e |
if (transforms & BSFX_CAMERA_DPI_TR) aff = getDpiAffine(camera).inv();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (shrink > 1) {
|
|
Shinya Kitaoka |
120a6e |
double fac = 0.5 * (1.0 / shrink - 1.0);
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(fac * camera->getRes().lx, fac * camera->getRes().ly) *
|
|
Shinya Kitaoka |
120a6e |
TScale(1.0 / shrink) * aff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!aff.isIdentity()) fx = TFxUtil::makeAffine(fx, aff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|