|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Rendering components
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/multimediarenderer.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/movierenderer.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trenderer.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Scene structures
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheet.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/fxdag.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnfxset.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Fxs tree decomposition
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/scenefx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Idle processing
|
|
Toshihiro Shimizu |
890ddd |
#include <qeventloop></qeventloop>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Local stuff
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
wstring removeSpaces(const wstring &str)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
wstring result;
|
|
Toshihiro Shimizu |
890ddd |
wstring::size_type a = 0, b;
|
|
Toshihiro Shimizu |
890ddd |
while ((b = str.find_first_of(L" ", a)) != wstring::npos) {
|
|
Toshihiro Shimizu |
890ddd |
result += str.substr(a, b - a);
|
|
Toshihiro Shimizu |
890ddd |
a = b + 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
result += str.substr(a, wstring::npos);
|
|
Toshihiro Shimizu |
890ddd |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=========================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// MultimediaRenderer::Imp class
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class MultimediaRenderer::Imp
|
|
Toshihiro Shimizu |
890ddd |
: public MovieRenderer::Listener,
|
|
Toshihiro Shimizu |
890ddd |
public TSmartObject
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
ToonzScene *m_scene;
|
|
Toshihiro Shimizu |
890ddd |
TFilePath m_fp;
|
|
Toshihiro Shimizu |
890ddd |
int m_threadCount;
|
|
Toshihiro Shimizu |
890ddd |
bool m_cacheResults;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Output movie frames. May be remapped from rendered ones.
|
|
Toshihiro Shimizu |
890ddd |
double m_xDpi, m_yDpi;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRenderSettings m_renderSettings;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<multimediarenderer::listener *=""> m_listeners;</multimediarenderer::listener>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool m_precomputingEnabled;
|
|
Toshihiro Shimizu |
890ddd |
bool m_canceled;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int m_currentFx;
|
|
Toshihiro Shimizu |
890ddd |
set<double>::iterator m_currentFrame;</double>
|
|
Toshihiro Shimizu |
890ddd |
TRenderer *m_currentTRenderer;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFxSet m_fxsToRender;
|
|
Toshihiro Shimizu |
890ddd |
set<double> m_framesToRender;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QEventLoop m_eventLoop;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int m_multimediaMode;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Imp(ToonzScene *scene,
|
|
Toshihiro Shimizu |
890ddd |
const TFilePath &moviePath,
|
|
Toshihiro Shimizu |
890ddd |
int multimediaMode,
|
|
Toshihiro Shimizu |
890ddd |
int threadCount,
|
|
Toshihiro Shimizu |
890ddd |
bool cacheResults);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~Imp();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void scanSceneForRenderNodes();
|
|
Toshihiro Shimizu |
890ddd |
void scanSceneForColumns();
|
|
Toshihiro Shimizu |
890ddd |
void scanSceneForLayers();
|
|
Toshihiro Shimizu |
890ddd |
bool scanColsRecursive(TFx *fx);
|
|
Toshihiro Shimizu |
890ddd |
TColumnFx *searchColumn(TFxP fx);
|
|
Toshihiro Shimizu |
890ddd |
TFxP addPostProcessing(TFxP fx, TFxP postProc);
|
|
Toshihiro Shimizu |
890ddd |
void addPostProcessingRecursive(TFxP fx, TFxP postProc);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void start();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool onFrameCompleted(int frame);
|
|
Toshihiro Shimizu |
890ddd |
bool onFrameFailed(int frame, TException &e);
|
|
Toshihiro Shimizu |
890ddd |
void onSequenceCompleted(const TFilePath &fp);
|
|
Toshihiro Shimizu |
890ddd |
void onRenderCompleted();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
MultimediaRenderer::Imp::Imp(
|
|
Toshihiro Shimizu |
890ddd |
ToonzScene *scene,
|
|
Toshihiro Shimizu |
890ddd |
const TFilePath &moviePath,
|
|
Toshihiro Shimizu |
890ddd |
int multimediaMode,
|
|
Toshihiro Shimizu |
890ddd |
int threadCount,
|
|
Toshihiro Shimizu |
890ddd |
bool cacheResults)
|
|
Toshihiro Shimizu |
890ddd |
: m_scene(scene), m_fp(moviePath), m_threadCount(threadCount), m_cacheResults(cacheResults), m_xDpi(72), m_yDpi(72), m_renderSettings(), m_listeners(), m_precomputingEnabled(true), m_canceled(false), m_currentFx(0), m_currentFrame(), m_multimediaMode(multimediaMode)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Retrieve all fx nodes to be rendered in this process.
|
|
Toshihiro Shimizu |
890ddd |
scanSceneForRenderNodes();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
MultimediaRenderer::Imp::~Imp()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::scanSceneForRenderNodes()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
switch (m_multimediaMode) {
|
|
Toshihiro Shimizu |
890ddd |
case COLUMNS:
|
|
Toshihiro Shimizu |
890ddd |
scanSceneForColumns();
|
|
Toshihiro Shimizu |
890ddd |
CASE LAYERS : scanSceneForLayers();
|
|
Toshihiro Shimizu |
890ddd |
DEFAULT:
|
|
Toshihiro Shimizu |
890ddd |
assert(0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!Retrieve the first level of scene columns, climb their paths
|
|
Toshihiro Shimizu |
890ddd |
//!along unary fxs, and then build the scene fxs.
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::scanSceneForColumns()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Retrieve the terminal fxs (ie, fxs which are implicitly
|
|
Toshihiro Shimizu |
890ddd |
//connected to the xsheet one)
|
|
Toshihiro Shimizu |
890ddd |
TXsheet *xsh = m_scene->getXsheet();
|
|
Toshihiro Shimizu |
890ddd |
TFxSet *fxs = xsh->getFxDag()->getTerminalFxs();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Launch the recursive column climber procedure for each
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < fxs->getFxCount(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
TFx *fx = fxs->getFx(i);
|
|
Toshihiro Shimizu |
890ddd |
if (!fx)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
bool isItARenderFx = scanColsRecursive(fx);
|
|
Toshihiro Shimizu |
890ddd |
if (isItARenderFx)
|
|
Toshihiro Shimizu |
890ddd |
m_fxsToRender.addFx(fx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!Returns true if the passed fx is a valid column representant
|
|
Toshihiro Shimizu |
890ddd |
bool MultimediaRenderer::Imp::scanColsRecursive(TFx *fx)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Columns should return true - they are column representant
|
|
Toshihiro Shimizu |
890ddd |
if (dynamic_cast<tcolumnfx *="">(fx))</tcolumnfx>
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Search columns in every port
|
|
Toshihiro Shimizu |
890ddd |
bool isChildAnFxRepres;
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < fx->getInputPortCount(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
TFx *childFx = fx->getInputPort(i)->getFx();
|
|
Toshihiro Shimizu |
890ddd |
if (!childFx)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
isChildAnFxRepres = scanColsRecursive(childFx);
|
|
Toshihiro Shimizu |
890ddd |
if (isChildAnFxRepres && fx->getInputPortCount() > 1)
|
|
Toshihiro Shimizu |
890ddd |
m_fxsToRender.addFx(childFx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isChildAnFxRepres && fx->getInputPortCount() == 1)
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!Build the scene fx for each node below the xsheet one.
|
|
Toshihiro Shimizu |
890ddd |
//!Remember that left xsheet ports must not be expanded.
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::scanSceneForLayers()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Retrieve the terminal fxs (ie, fxs which are implicitly
|
|
Toshihiro Shimizu |
890ddd |
//connected to the xsheet one)
|
|
Toshihiro Shimizu |
890ddd |
TXsheet *xsh = m_scene->getXsheet();
|
|
Toshihiro Shimizu |
890ddd |
TFxSet *fxs = xsh->getFxDag()->getTerminalFxs();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Examine all of them and - eventually - expand left xsheet
|
|
Toshihiro Shimizu |
890ddd |
//ports (ie fx nodes who allow implicit overlaying)
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < fxs->getFxCount(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
TFx *fx = fxs->getFx(i);
|
|
Toshihiro Shimizu |
890ddd |
TFxPort *leftXSheetPort;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
retry:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!fx)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
leftXSheetPort = fx->getXsheetPort();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!leftXSheetPort) {
|
|
Toshihiro Shimizu |
890ddd |
m_fxsToRender.addFx(fx);
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//If the leftXSheetPort is not connected, retry on port 0
|
|
Toshihiro Shimizu |
890ddd |
if (leftXSheetPort->isConnected())
|
|
Toshihiro Shimizu |
890ddd |
m_fxsToRender.addFx(fx);
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
fx = fx->getInputPort(0)->getFx();
|
|
Toshihiro Shimizu |
890ddd |
goto retry;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TColumnFx *MultimediaRenderer::Imp::searchColumn(TFxP fx)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Descend ports 0 until a TColumnFx is found. Then, output its number.
|
|
Toshihiro Shimizu |
890ddd |
TFx *currFx = fx.getPointer();
|
|
Toshihiro Shimizu |
890ddd |
TColumnFx *colFx = dynamic_cast<tcolumnfx *="">(currFx);</tcolumnfx>
|
|
Toshihiro Shimizu |
890ddd |
while (!colFx) {
|
|
Toshihiro Shimizu |
890ddd |
if (fx->getInputPortCount() <= 0)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
currFx = currFx->getInputPort(0)->getFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!currFx)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
colFx = dynamic_cast<tcolumnfx *="">(currFx);</tcolumnfx>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return colFx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFxP MultimediaRenderer::Imp::addPostProcessing(TFxP fx, TFxP postProc)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (dynamic_cast<txsheetfx *="">(postProc.getPointer()))</txsheetfx>
|
|
Toshihiro Shimizu |
890ddd |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Clone the postProcessing tree and substitute recursively
|
|
Toshihiro Shimizu |
890ddd |
postProc = postProc->clone(true);
|
|
Toshihiro Shimizu |
890ddd |
addPostProcessingRecursive(fx, postProc);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return postProc;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::addPostProcessingRecursive(TFxP fx, TFxP postProc)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!postProc)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int i, count = postProc->getInputPortCount();
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < count; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
TFxPort *port = postProc->getInputPort(i);
|
|
Toshihiro Shimizu |
890ddd |
TFx *childFx = port->getFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dynamic_cast<txsheetfx *="">(childFx))</txsheetfx>
|
|
Toshihiro Shimizu |
890ddd |
port->setFx(fx.getPointer());
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
addPostProcessingRecursive(fx, childFx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::start()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Retrieve some useful infos
|
|
Toshihiro Shimizu |
890ddd |
double stretchTo = m_renderSettings.m_timeStretchTo;
|
|
Toshihiro Shimizu |
890ddd |
double stretchFrom = m_renderSettings.m_timeStretchFrom;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double timeStretchFactor = stretchFrom / stretchTo;
|
|
Toshihiro Shimizu |
890ddd |
bool fieldRendering = m_renderSettings.m_fieldPrevalence != TRenderSettings::NoField;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
wstring modeStr;
|
|
Toshihiro Shimizu |
890ddd |
switch (m_multimediaMode) {
|
|
Toshihiro Shimizu |
890ddd |
case COLUMNS:
|
|
Toshihiro Shimizu |
890ddd |
modeStr = L"_col";
|
|
Toshihiro Shimizu |
890ddd |
CASE LAYERS : modeStr = L"_lay";
|
|
Toshihiro Shimizu |
890ddd |
DEFAULT:
|
|
Toshihiro Shimizu |
890ddd |
assert(0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Build the post processing fxs tree
|
|
Toshihiro Shimizu |
890ddd |
std::vector<tfxp> postFxs(m_framesToRender.size());</tfxp>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::set<double>::iterator jt;</double>
|
|
Toshihiro Shimizu |
890ddd |
int j;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0, jt = m_framesToRender.begin(); jt != m_framesToRender.end(); ++j, ++jt)
|
|
Toshihiro Shimizu |
890ddd |
postFxs[j] = buildPostSceneFx(m_scene, *jt, m_renderSettings.m_shrinkX, false); // Adds camera and camera dpi transforms
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//For each node to be rendered
|
|
Toshihiro Shimizu |
890ddd |
int i, count = m_fxsToRender.getFxCount();
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < count; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
//In case the process has been canceled, return
|
|
Toshihiro Shimizu |
890ddd |
if (m_canceled)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Then, build the scene fx for each frame to be rendered
|
|
Toshihiro Shimizu |
890ddd |
std::vector<std::pair<double, tfxpair="">> pairsToBeRendered;</std::pair<double,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//NOTE: The above pairs should not be directly added to a previously declared movierenderer,
|
|
Toshihiro Shimizu |
890ddd |
//since an output level would be created even before knowing if any cell to be rendered is
|
|
Toshihiro Shimizu |
890ddd |
//actually available.
|
|
Toshihiro Shimizu |
890ddd |
const BSFX_Transforms_Enum transforms = // Do NOT add camera and
|
|
Toshihiro Shimizu |
890ddd |
BSFX_Transforms_Enum(BSFX_COLUMN_TR); // camera dpi transforms
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int j;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0, jt = m_framesToRender.begin(); jt != m_framesToRender.end(); ++j, ++jt) {
|
|
Toshihiro Shimizu |
890ddd |
TFxPair fx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_renderSettings.m_stereoscopic)
|
|
Toshihiro Shimizu |
890ddd |
m_scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fx.m_frameA = buildSceneFx(m_scene, *jt, 0, m_fxsToRender.getFx(i),
|
|
Toshihiro Shimizu |
890ddd |
transforms);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_renderSettings.m_stereoscopic) {
|
|
Toshihiro Shimizu |
890ddd |
m_scene->shiftCameraX(m_renderSettings.m_stereoscopicShift);
|
|
Toshihiro Shimizu |
890ddd |
fx.m_frameB = buildSceneFx(m_scene, *jt, 0, m_fxsToRender.getFx(i),
|
|
Toshihiro Shimizu |
890ddd |
transforms);
|
|
Toshihiro Shimizu |
890ddd |
m_scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2);
|
|
Toshihiro Shimizu |
890ddd |
} else if (fieldRendering)
|
|
Toshihiro Shimizu |
890ddd |
fx.m_frameB = buildSceneFx(m_scene, *jt + 0.5 * timeStretchFactor, 0,
|
|
Toshihiro Shimizu |
890ddd |
m_fxsToRender.getFx(i), transforms);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
fx.m_frameB = TRasterFxP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Substitute with the post-process...
|
|
Toshihiro Shimizu |
890ddd |
if (fx.m_frameA)
|
|
Toshihiro Shimizu |
890ddd |
fx.m_frameA = addPostProcessing(fx.m_frameA, postFxs[j]);
|
|
Toshihiro Shimizu |
890ddd |
if (fx.m_frameB)
|
|
Toshihiro Shimizu |
890ddd |
fx.m_frameB = addPostProcessing(fx.m_frameB, postFxs[j]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (fx.m_frameA) //Could be 0, if the corresponding cell is void / not rendered
|
|
Toshihiro Shimizu |
890ddd |
pairsToBeRendered.push_back(std::pair<double, tfxpair="">(*jt, fx));</double,>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (pairsToBeRendered.size() == 0)
|
|
Toshihiro Shimizu |
890ddd |
continue; //Could be, if no cell for this column was in the frame range.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Build the output name
|
|
Toshihiro Shimizu |
890ddd |
TColumnFx *colFx = searchColumn(m_fxsToRender.getFx(i));
|
|
Toshihiro Shimizu |
890ddd |
TFx *currFx = m_fxsToRender.getFx(i);
|
|
Toshihiro Shimizu |
890ddd |
assert(colFx);
|
|
Toshihiro Shimizu |
890ddd |
if (!colFx)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int columnIndex = colFx->getColumnIndex();
|
|
Toshihiro Shimizu |
890ddd |
wstring columnName(colFx->getColumnName());
|
|
Toshihiro Shimizu |
890ddd |
wstring columnId(colFx->getColumnId());
|
|
Toshihiro Shimizu |
890ddd |
wstring fxName(currFx->getName());
|
|
Toshihiro Shimizu |
890ddd |
wstring fxNameNoSpaces(::removeSpaces(fxName));
|
|
Toshihiro Shimizu |
890ddd |
wstring fxId(currFx->getFxId());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
wstring fpName = m_fp.getWideName() +
|
|
Toshihiro Shimizu |
890ddd |
L"_" + columnName + (columnId == columnName ? L"" : L"(" + columnId + L")") +
|
|
Toshihiro Shimizu |
890ddd |
(fxId.empty() ? L"" : L"_" + fxName + (fxId == fxNameNoSpaces ? L"" : L"(" + fxId + L")"));
|
|
Toshihiro Shimizu |
890ddd |
//+ modeStr + toWideString(columnIndex+1);
|
|
Toshihiro Shimizu |
890ddd |
TFilePath movieFp(m_fp.withName(fpName));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Initialize a MovieRenderer with our infos
|
|
Toshihiro Shimizu |
890ddd |
MovieRenderer movieRenderer(m_scene, movieFp, m_threadCount, false);
|
|
Toshihiro Shimizu |
890ddd |
movieRenderer.setRenderSettings(m_renderSettings);
|
|
Toshihiro Shimizu |
890ddd |
movieRenderer.setDpi(m_xDpi, m_yDpi);
|
|
Toshihiro Shimizu |
890ddd |
movieRenderer.enablePrecomputing(m_precomputingEnabled);
|
|
Toshihiro Shimizu |
890ddd |
movieRenderer.addListener(this);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int j = 0; j < pairsToBeRendered.size(); ++j) {
|
|
Toshihiro Shimizu |
890ddd |
std::pair<double, tfxpair=""> ¤tPair = pairsToBeRendered[j];</double,>
|
|
Toshihiro Shimizu |
890ddd |
movieRenderer.addFrame(currentPair.first, currentPair.second);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Finally, start rendering currently initialized MovieRenderer.
|
|
Toshihiro Shimizu |
890ddd |
m_currentFx = i;
|
|
Toshihiro Shimizu |
890ddd |
m_currentFrame = m_framesToRender.begin();
|
|
Toshihiro Shimizu |
890ddd |
m_currentTRenderer = movieRenderer.getTRenderer();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
movieRenderer.start();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//I don't recall Toonz currently supports different, simultaneous rendering processes.
|
|
Toshihiro Shimizu |
890ddd |
//However, one rendering process is supposed to be exhausting the machine's resources
|
|
Toshihiro Shimizu |
890ddd |
//on its own - so, we'll just set up an idle (but GUI-reactive) loop here.
|
|
Toshihiro Shimizu |
890ddd |
//It will quit looping whenever the "onSequenceCompleted" notification gets called.
|
|
Toshihiro Shimizu |
890ddd |
m_eventLoop.exec();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------- Loops here --------------------------
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Lastly, inform everyone that rendering stopped
|
|
Toshihiro Shimizu |
890ddd |
onRenderCompleted();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool MultimediaRenderer::Imp::onFrameCompleted(int frame)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Inform all listeners
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int i = 0; i < m_listeners.size(); ++i)
|
|
Toshihiro Shimizu |
890ddd |
m_listeners[i]->onFrameCompleted(*m_currentFrame, m_currentFx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_currentFrame++;
|
|
Toshihiro Shimizu |
890ddd |
return !m_canceled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool MultimediaRenderer::Imp::onFrameFailed(int frame, TException &e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Inform all listeners
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int i = 0; i < m_listeners.size(); ++i)
|
|
Toshihiro Shimizu |
890ddd |
m_listeners[i]->onFrameFailed(*m_currentFrame, m_currentFx, e);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_currentFrame++;
|
|
Toshihiro Shimizu |
890ddd |
return !m_canceled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::onSequenceCompleted(const TFilePath &fp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Inform all listeners
|
|
Toshihiro Shimizu |
890ddd |
m_currentTRenderer = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int i = 0; i < m_listeners.size(); ++i)
|
|
Toshihiro Shimizu |
890ddd |
m_listeners[i]->onSequenceCompleted(m_currentFx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_eventLoop.quit();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::Imp::onRenderCompleted()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (unsigned int i = 0; i < m_listeners.size(); ++i)
|
|
Toshihiro Shimizu |
890ddd |
m_listeners[i]->onRenderCompleted();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// MultimediaRenderer class
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
MultimediaRenderer::MultimediaRenderer(
|
|
Toshihiro Shimizu |
890ddd |
ToonzScene *scene, const TFilePath &moviePath, int multimediaMode,
|
|
Toshihiro Shimizu |
890ddd |
int threadCount, bool cacheResults)
|
|
Toshihiro Shimizu |
890ddd |
: m_imp(new Imp(scene, moviePath, multimediaMode, threadCount, cacheResults))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->addRef();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
MultimediaRenderer::~MultimediaRenderer()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->release();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TFilePath &MultimediaRenderer::getFilePath()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_fp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int MultimediaRenderer::getFrameCount()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_framesToRender.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int MultimediaRenderer::getColumnsCount()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_fxsToRender.getFxCount();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int MultimediaRenderer::getMultimediaMode() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_multimediaMode;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::setRenderSettings(const TRenderSettings &renderSettings)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//assert(m_imp->m_framesOnRendering.empty());
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_renderSettings = renderSettings;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::setDpi(double xDpi, double yDpi)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_xDpi = xDpi;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_yDpi = yDpi;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::addListener(Listener *listener)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_listeners.push_back(listener);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::addFrame(double frame)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_framesToRender.insert(frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::enablePrecomputing(bool on)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_precomputingEnabled = on;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!\b NOTE: Such render may vary from time to time, and even be 0 if no renderer is currently
|
|
Toshihiro Shimizu |
890ddd |
//!active, for example due to preprocessing states.
|
|
Toshihiro Shimizu |
890ddd |
TRenderer *MultimediaRenderer::getTRenderer()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_currentTRenderer;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool MultimediaRenderer::isPrecomputingEnabled() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_precomputingEnabled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::start()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->start();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void MultimediaRenderer::onCanceled()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_canceled = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool MultimediaRenderer::done() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|