tahoma2d/toonz/sources/stdfx/backlit.cpp

187 lines
4.6 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#include "texception.h"
#include "stdfx.h"
#include "tpixelutils.h"
//-------------------------------------------------------------------
class BacklitFx : public TStandardRasterFx
{
FX_PLUGIN_DECLARATION(BacklitFx)
TRasterFxPort m_input;
//TDoubleParamP m_value;
public:
BacklitFx()
// , m_value (args, "Blur")
{
//m_value->setDefaultValue(100);
addInputPort("Source", m_input);
}
~BacklitFx(){};
bool doGetBBox(double frame, TRectD &bBox);
void doCompute(TTile &tile, double frame, const TRenderSettings &ri);
int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info);
TRect getInvalidRect(const TRect &max);
};
//-------------------------------------------------------------------
bool BacklitFx::doGetBBox(double frame, TRectD &bBox)
{
if (m_input.isConnected()) {
bool ret = m_input->doGetBBox(frame, bBox);
// devo scurire bgColor
return ret;
} else {
bBox = TRectD();
return false;
}
}
//===================================================================
namespace
{
template <class T>
void computeBacklit(TRasterPT<T> dst,
TRasterPT<T> src,
const TPoint &srcPos,
// cordinate di src[0,0] rispetto a dst;
// in genere srcPos.x,.y <= 0
const TPoint &center
// coordinate della sorgente di luce rispetto a dst;
)
{
//TRect srcRect = src->getBounds() + srcPos;
//assert(srcRect.contains(dst->getBounds()));
//assert(srcRect.contains(center));
UINT max = T::maxChannelValue;
dst->lock();
for (int x = 0; x < dst->getLx(); x++)
for (int y = 0; y < dst->getLy(); y++) {
int dx = x - center.x;
int dy = y - center.y;
int dist = (int)sqrt((float)(dx * dx + dy * dy));
int d = tmin(100, dist) + 1;
double value = 0.0;
for (int i = 0; i <= d; i++) {
int xx = center.x + (x - center.x) * i / d - srcPos.x;
int yy = center.y + (y - center.y) * i / d - srcPos.y;
assert(src->getBounds().contains(TPoint(xx, yy)));
value += (max - src->pixels(yy)[xx].m) * 2;
}
value = value / dist;
// double value = sin(dist)<0?0:255;
int v = tcrop((int)value, 0, (int)max);
int srcX = -srcPos.x + x;
int srcY = -srcPos.y + y;
T srcPix(0, 0, 0, 0);
if (src->getBounds().contains(TPoint(srcX, srcY)))
srcPix = src->pixels(srcY)[srcX];
srcPix.r = srcPix.r * (max - v) / max;
srcPix.g = srcPix.g * (max - v) / max;
srcPix.b = srcPix.b * (max - v) / max;
dst->pixels(y)[x] = overPix(srcPix, T(v, v, v, v / 2));
}
dst->unlock();
}
} // namespace
//---------------------------------------------------------------------
void BacklitFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri)
{
if (!m_input.isConnected()) {
tile.getRaster()->clear();
return;
}
TTile srcTile;
srcTile.m_pos = tile.m_pos;
TPoint srcPos(0, 0);
TDimension srcSize = tile.getRaster()->getSize();
TPoint center(-(int)tile.m_pos.x, -(int)tile.m_pos.y);
center += TPoint(10, 10);
if (center.x < 0) {
srcSize.lx += -center.x;
srcPos.x += center.x;
srcTile.m_pos.x += center.x;
} else if (center.x >= srcSize.lx) {
srcSize.lx += center.x - srcSize.lx + 1;
}
if (center.y < 0) {
srcSize.ly += -center.y;
srcPos.y += center.y;
srcTile.m_pos.y += center.y;
} else if (center.y >= srcSize.ly) {
srcSize.ly += center.y - srcSize.ly + 1;
}
if ((TRaster32P)tile.getRaster()) {
TRaster32P src = TRaster32P(srcSize);
src->clear();
srcTile.getRaster() = src;
m_input->compute(srcTile, frame, ri);
TRaster32P dst = tile.getRaster();
assert(dst);
computeBacklit<TPixel32>(dst, src, srcPos, center);
} else if ((TRaster64P)tile.getRaster()) {
TRaster64P src = TRaster64P(srcSize);
src->clear();
srcTile.getRaster() = src;
m_input->compute(srcTile, frame, ri);
TRaster64P dst = tile.getRaster();
assert(dst);
computeBacklit<TPixel64>(dst, src, srcPos, center);
}
//dst->copy(src,srcPos);
}
//---------------------------------------------------------------------
int BacklitFx::getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
{
return TRasterFx::memorySize(rect, frame, info);
}
//---------------------------------------------------------------------
TRect BacklitFx::getInvalidRect(const TRect &max)
{
if (!m_input.isConnected())
return TRect();
TRect rect = m_input->getInvalidRect(max);
TRect ris = max;
if (rect.x0 >= 0)
ris.x0 = tmin(rect.x0, max.x1);
else if (rect.x1 <= 0)
ris.x1 = tmax(rect.x1, max.x0);
if (rect.y0 >= 0)
ris.y0 = tmin(rect.y0, max.y1);
else if (rect.y1 <= 0)
ris.y1 = tmax(rect.y1, max.y0);
return ris;
}
//FX_PLUGIN_IDENTIFIER(BacklitFx , "backlitFx")