|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tofflinegl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstencilcontrol.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorrenderdata.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcolorfunctions.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpalette.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tropcm.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmeshimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcolorstyles.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tregion.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzscene.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tenv.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/meshutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticskeleton.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticskeletondeformation.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticdeformerstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stageplayer.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage2.h"
|
|
Campbell Barton |
b3bd84 |
#include "toonz/tcolumnfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheet.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshchildlevel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/onionskinmask.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/dpiscale.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/imagemanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobjecttree.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/glrasterpainter.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/preferences.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/fill.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/levelproperties.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/autoclose.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshleveltypes.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "imagebuilders.h"
|
|
Jeremy Bullock |
1e17ed |
#include "toonz/tframehandle.h"
|
|
shun-iwasawa |
1d5937 |
#include "toonz/preferences.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qimage></qimage>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainter></qpainter>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpolygon></qpolygon>
|
|
Toshihiro Shimizu |
890ddd |
#include <qthreadstorage></qthreadstorage>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmatrix></qmatrix>
|
|
shun_iwasawa |
ed1861 |
#include <qthread></qthread>
|
|
shun_iwasawa |
ed1861 |
#include <qguiapplication></qguiapplication>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stagevisitor.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Stage namespace
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! \namespace Stage
|
|
Shinya Kitaoka |
120a6e |
\brief The Stage namespace provides objects, classes and methods useful to
|
|
Shinya Kitaoka |
120a6e |
view or display images.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace Stage;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! \var Stage::inch
|
|
Shinya Kitaoka |
120a6e |
For historical reasons camera stand is defined in a coordinate
|
|
Shinya Kitaoka |
120a6e |
system in which
|
|
Shinya Kitaoka |
120a6e |
an inch is equal to 'Stage::inch' unit.
|
|
Shinya Kitaoka |
120a6e |
Pay attention: modify this value condition apparent line
|
|
Shinya Kitaoka |
120a6e |
thickness of
|
|
Shinya Kitaoka |
120a6e |
images .pli.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
// const double Stage::inch = 53.33333;
|
|
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 |
QImage rasterToQImage(const TRaster32P &ras) {
|
|
Shinya Kitaoka |
120a6e |
QImage image(ras->getRawData(), ras->getLx(), ras->getLy(),
|
|
Shinya Kitaoka |
120a6e |
QImage::Format_ARGB32_Premultiplied);
|
|
Shinya Kitaoka |
120a6e |
return image;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QImage rasterToQImage(const TRasterGR8P &ras) {
|
|
Shinya Kitaoka |
120a6e |
QImage image(ras->getLx(), ras->getLy(), QImage::Format_ARGB32_Premultiplied);
|
|
Shinya Kitaoka |
120a6e |
int lx = ras->getLx(), ly = ras->getLy();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < ly; y++) {
|
|
Shinya Kitaoka |
120a6e |
TPixelGR8 *pix = ras->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
TPixelGR8 *endPix = pix + lx;
|
|
Shinya Kitaoka |
120a6e |
QRgb *outPix = (QRgb *)image.scanLine(y);
|
|
Shinya Kitaoka |
120a6e |
for (; pix < endPix; ++pix) {
|
|
Shinya Kitaoka |
120a6e |
int value = pix->value;
|
|
Shinya Kitaoka |
120a6e |
*outPix++ = qRgba(value, value, value, 255);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return image;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QImage rasterToQImage(const TRasterP &ras) {
|
|
Shinya Kitaoka |
120a6e |
if (TRaster32P src32 = ras)
|
|
Shinya Kitaoka |
120a6e |
return rasterToQImage(src32);
|
|
Shinya Kitaoka |
120a6e |
else if (TRasterGR8P srcGr8 = ras)
|
|
Shinya Kitaoka |
120a6e |
return rasterToQImage(srcGr8);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// assert(!"Cannot use drawImage with this image!");
|
|
Shinya Kitaoka |
120a6e |
return QImage();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Draw orthogonal projection of \b bbox onto x-axis and y-axis.
|
|
Shinya Kitaoka |
120a6e |
void draw3DShadow(const TRectD &bbox, double z, double phi) {
|
|
Shinya Kitaoka |
120a6e |
// bruttino assai, ammetto
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double a = bigBoxSize[0];
|
|
Shinya Kitaoka |
120a6e |
double b = bigBoxSize[1];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.9, 0.9, 0.86);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x0, bbox.y0, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x0, bbox.y1, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x1, bbox.y1, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x1, bbox.y0, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x0, bbox.y0, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double y = -b;
|
|
Shinya Kitaoka |
120a6e |
double x = phi >= 0 ? a : -a;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double xm = 0.5 * (bbox.x0 + bbox.x1);
|
|
Shinya Kitaoka |
120a6e |
double ym = 0.5 * (bbox.y0 + bbox.y1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (bbox.y0 > y) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(xm, y, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(xm, bbox.y0, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
} else if (bbox.y1 < y) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(xm, y, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(xm, bbox.y1, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (bbox.x0 > x) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(x, ym, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x0, ym, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
} else if (bbox.x1 < x) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(x, ym, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x1, ym, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor3d(0.0, 0.0, 0.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x0, -b, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(bbox.x1, -b, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_STRIP);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(x, bbox.y0, z);
|
|
Shinya Kitaoka |
120a6e |
glVertex3d(x, bbox.y1, z);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=====================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Plastic function declarations
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Returns from the specified player the stage object to be plastic
|
|
Toshihiro Shimizu |
890ddd |
deformed - or 0 if current Toonz rules prevent it from being deformed.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
TStageObject *plasticDeformedObj(const Stage::Player &player,
|
|
Shinya Kitaoka |
120a6e |
const PlasticVisualSettings &pvs);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Draws the specified mesh image
|
|
Shinya Kitaoka |
120a6e |
void onMeshImage(TMeshImage *mi, const Stage::Player &player,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &viewAff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Applies Plastic deformation of the specified player's stage object.
|
|
Shinya Kitaoka |
120a6e |
void onPlasticDeformedImage(TStageObject *playerObj,
|
|
Shinya Kitaoka |
120a6e |
const Stage::Player &player,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &viewAff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Picker implementation
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Picker::Picker(const TAffine &viewAff, const TPointD &point,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs)
|
|
Shinya Kitaoka |
120a6e |
: Visitor(vs)
|
|
Shinya Kitaoka |
120a6e |
, m_viewAff(viewAff)
|
|
Shinya Kitaoka |
120a6e |
, m_point(point)
|
|
Shinya Kitaoka |
120a6e |
, m_columnIndexes()
|
|
Shinya Kitaoka |
120a6e |
, m_minDist2(1.0e10) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::setDistance(double d) { m_minDist2 = d * d; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::onImage(const Stage::Player &player) {
|
|
shun-iwasawa |
1d5937 |
// if m_currentColumnIndex is other than the default value (-1),
|
|
shun-iwasawa |
1d5937 |
// then pick only the current column.
|
|
shun-iwasawa |
1d5937 |
if (m_currentColumnIndex != -1 &&
|
|
shun-iwasawa |
1d5937 |
m_currentColumnIndex != player.m_ancestorColumnIndex)
|
|
shun-iwasawa |
1d5937 |
return;
|
|
shun-iwasawa |
1d5937 |
|
|
Shinya Kitaoka |
120a6e |
bool picked = false;
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = m_viewAff * player.m_placement;
|
|
Shinya Kitaoka |
120a6e |
TPointD point = aff.inv() * m_point;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TImageP &img = player.image();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TVectorImageP vi = img) {
|
|
Shinya Kitaoka |
120a6e |
double w = 0;
|
|
Shinya Kitaoka |
120a6e |
UINT strokeIndex = 0;
|
|
Shinya Kitaoka |
120a6e |
double dist2 = 0;
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = vi->getRegion(point);
|
|
Shinya Kitaoka |
120a6e |
int styleId = 0;
|
|
Shinya Kitaoka |
120a6e |
if (r) styleId = r->getStyle();
|
|
Shinya Kitaoka |
120a6e |
if (styleId != 0)
|
|
Shinya Kitaoka |
120a6e |
picked = true;
|
|
Shinya Kitaoka |
120a6e |
else if (vi->getNearestStroke(point, w, strokeIndex, dist2) &&
|
|
Shinya Kitaoka |
120a6e |
dist2 < m_minDist2)
|
|
Shinya Kitaoka |
120a6e |
picked = true;
|
|
Shinya Kitaoka |
120a6e |
} else if (TRasterImageP ri = img) {
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras = ri->getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (!ras) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
TPointD pp = player.m_dpiAff.inv() * point + ras->getCenterD();
|
|
Shinya Kitaoka |
120a6e |
TPoint p(tround(pp.x), tround(pp.y));
|
|
Shinya Kitaoka |
120a6e |
if (!ras->getBounds().contains(p)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = ras->pixels(p.y);
|
|
Shinya Kitaoka |
120a6e |
if (pix[p.x].m != 0) picked = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff2 = (aff * player.m_dpiAff).inv();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD pa(p.x, p.y);
|
|
Shinya Kitaoka |
120a6e |
TPointD dx = aff2 * (m_point + TPointD(3, 0)) - aff2 * m_point;
|
|
Shinya Kitaoka |
120a6e |
TPointD dy = aff2 * (m_point + TPointD(0, 3)) - aff2 * m_point;
|
|
Shinya Kitaoka |
120a6e |
double rx = dx.x * dx.x + dx.y * dx.y;
|
|
Shinya Kitaoka |
120a6e |
double ry = dy.x * dy.x + dy.y * dy.y;
|
|
Shinya Kitaoka |
120a6e |
int radius = tround(sqrt(rx > ry ? rx : ry));
|
|
Shinya Kitaoka |
120a6e |
TRect rect = TRect(p.x - radius, p.y - radius, p.x + radius, p.y + radius) *
|
|
Shinya Kitaoka |
120a6e |
ras->getBounds();
|
|
Shinya Kitaoka |
120a6e |
for (int y = rect.y0; !picked && y <= rect.y1; y++) {
|
|
Shinya Kitaoka |
120a6e |
pix = ras->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
for (int x = rect.x0; !picked && x <= rect.x1; x++)
|
|
Shinya Kitaoka |
120a6e |
if (pix[x].m != 0) picked = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
} else if (TToonzImageP ti = img) {
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P ras = ti->getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (!ras) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
TPointD pp = player.m_dpiAff.inv() * point + ras->getCenterD();
|
|
Shinya Kitaoka |
120a6e |
TPoint p(tround(pp.x), tround(pp.y));
|
|
Shinya Kitaoka |
120a6e |
if (!ras->getBounds().contains(p)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = ras->pixels(p.y) + p.x;
|
|
Shinya Kitaoka |
120a6e |
if (!pix->isPurePaint() || pix->getPaint() != 0) picked = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (picked) {
|
|
Shinya Kitaoka |
120a6e |
int columnIndex = player.m_ancestorColumnIndex;
|
|
Shinya Kitaoka |
120a6e |
if (m_columnIndexes.empty() || m_columnIndexes.back() != columnIndex)
|
|
Shinya Kitaoka |
120a6e |
m_columnIndexes.push_back(columnIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int row = player.m_frame;
|
|
Shinya Kitaoka |
120a6e |
if (m_rows.empty() || m_rows.back() != row) m_rows.push_back(row);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::beginMask() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::endMask() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::enableMask() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::disableMask() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int Picker::getColumnIndex() const {
|
|
Shinya Kitaoka |
120a6e |
if (m_columnIndexes.empty())
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return m_columnIndexes.back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Picker::getColumnIndexes(std::vector<int> &indexes) const {</int>
|
|
Shinya Kitaoka |
120a6e |
indexes = m_columnIndexes;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int Picker::getRow() const {
|
|
Shinya Kitaoka |
120a6e |
if (m_rows.empty())
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return m_rows.back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// RasterPainter implementation
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
RasterPainter::RasterPainter(const TDimension &dim, const TAffine &viewAff,
|
|
Shinya Kitaoka |
120a6e |
const TRect &rect,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs,
|
|
Shinya Kitaoka |
120a6e |
bool checkFlags)
|
|
Shinya Kitaoka |
120a6e |
: Visitor(vs)
|
|
Shinya Kitaoka |
120a6e |
, m_dim(dim)
|
|
Shinya Kitaoka |
120a6e |
, m_viewAff(viewAff)
|
|
Shinya Kitaoka |
120a6e |
, m_clipRect(rect)
|
|
Shinya Kitaoka |
120a6e |
, m_maskLevel(0)
|
|
Shinya Kitaoka |
120a6e |
, m_singleColumnEnabled(false)
|
|
Shinya Kitaoka |
120a6e |
, m_checkFlags(checkFlags)
|
|
Shinya Kitaoka |
120a6e |
, m_doRasterDarkenBlendedView(false) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//! Utilizzato solo per TAB Pro
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::beginMask() {
|
|
Shinya Kitaoka |
120a6e |
flushRasterImages(); // per evitare che venga fatto dopo il beginMask
|
|
Shinya Kitaoka |
120a6e |
++m_maskLevel;
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->beginMask();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
//! Utilizzato solo per TAB Pro
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::endMask() {
|
|
Shinya Kitaoka |
120a6e |
flushRasterImages(); // se ci sono delle immagini raster nella maschera
|
|
Shinya Kitaoka |
120a6e |
// devono uscire ora
|
|
Shinya Kitaoka |
120a6e |
--m_maskLevel;
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->endMask();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
//! Utilizzato solo per TAB Pro
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::enableMask() {
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->enableMask(TStencilControl::SHOW_INSIDE);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
//! Utilizzato solo per TAB Pro
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::disableMask() {
|
|
Shinya Kitaoka |
120a6e |
flushRasterImages(); // se ci sono delle immagini raster mascherate devono
|
|
Shinya Kitaoka |
120a6e |
// uscire ora
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->disableMask();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEnv::DoubleVar AutocloseDistance("InknpaintAutocloseDistance", 10.0);
|
|
Toshihiro Shimizu |
890ddd |
TEnv::DoubleVar AutocloseAngle("InknpaintAutocloseAngle", 60.0);
|
|
Toshihiro Shimizu |
890ddd |
TEnv::IntVar AutocloseInk("InknpaintAutocloseInk", 1);
|
|
Toshihiro Shimizu |
890ddd |
TEnv::IntVar AutocloseOpacity("InknpaintAutocloseOpacity", 255);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int RasterPainter::getNodesCount() { return m_nodes.size(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::clearNodes() { m_nodes.clear(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterP RasterPainter::getRaster(int index, QMatrix &matrix) {
|
|
Shinya Kitaoka |
120a6e |
if ((int)m_nodes.size() <= index) return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes[index].m_onionMode != Node::eOnionSkinNone) return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes.empty()) return TRasterP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double delta = sqrt(fabs(m_nodes[0].m_aff.det()));
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = m_nodes[0].m_bbox.enlarge(delta);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 1; i < (int)m_nodes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
delta = sqrt(fabs(m_nodes[i].m_aff.det()));
|
|
Shinya Kitaoka |
120a6e |
bbox += m_nodes[i].m_bbox.enlarge(delta);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TRect rect(tfloor(bbox.x0), tfloor(bbox.y0), tceil(bbox.x1), tceil(bbox.y1));
|
|
Shinya Kitaoka |
120a6e |
rect = rect * TRect(0, 0, m_dim.lx - 1, m_dim.ly - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = TTranslation(-rect.x0, -rect.y0) * m_nodes[index].m_aff;
|
|
Shinya Kitaoka |
120a6e |
matrix = QMatrix(aff.a11, aff.a21, aff.a12, aff.a22, aff.a13, aff.a23);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return m_nodes[index].m_raster;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! Make frame visualization.
|
|
Shinya Kitaoka |
120a6e |
\n If onon-skin is active, create a new raster with dimension containing
|
|
Shinya Kitaoka |
120a6e |
all
|
|
Shinya Kitaoka |
120a6e |
frame with onion-skin; recall \b TRop::quickPut with argument
|
|
Shinya Kitaoka |
120a6e |
each frame
|
|
Shinya Kitaoka |
120a6e |
with onion-skin and new raster. If onion-skin is not active
|
|
Shinya Kitaoka |
120a6e |
recall
|
|
Shinya Kitaoka |
120a6e |
\b TRop::quickPut with argument current frame and new raster.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
QThreadStorage<std::vector<char> *> threadBuffers;</std::vector<char>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::flushRasterImages() {
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build nodes bbox union
|
|
Shinya Kitaoka |
120a6e |
double delta = sqrt(fabs(m_nodes[0].m_aff.det()));
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = m_nodes[0].m_bbox.enlarge(delta);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i, nodesCount = m_nodes.size();
|
|
Shinya Kitaoka |
120a6e |
for (i = 1; i < nodesCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
delta = sqrt(fabs(m_nodes[i].m_aff.det()));
|
|
Shinya Kitaoka |
120a6e |
bbox += m_nodes[i].m_bbox.enlarge(delta);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRect rect(tfloor(bbox.x0), tfloor(bbox.y0), tceil(bbox.x1), tceil(bbox.y1));
|
|
Shinya Kitaoka |
120a6e |
rect = rect * TRect(0, 0, m_dim.lx - 1, m_dim.ly - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int lx = rect.getLx(), ly = rect.getLy();
|
|
Shinya Kitaoka |
120a6e |
TDimension dim(lx, ly);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build a raster buffer of sufficient size to hold said union.
|
|
Shinya Kitaoka |
120a6e |
// The buffer is per-thread cached in order to improve the rendering speed.
|
|
Shinya Kitaoka |
120a6e |
if (!threadBuffers.hasLocalData())
|
|
Shinya Kitaoka |
120a6e |
threadBuffers.setLocalData(new std::vector<char>());</char>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int size = dim.lx * dim.ly * sizeof(TPixel32);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<char> *vbuff = (std::vector<char> *)threadBuffers.localData();</char></char>
|
|
Shinya Kitaoka |
120a6e |
if (size > (int)vbuff->size()) vbuff->resize(size);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras(dim.lx, dim.ly, dim.lx, (TPixel32 *)&(*vbuff)[0]);
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_vs.m_colorMask != 0) {
|
|
Shinya Kitaoka |
120a6e |
ras2 = TRaster32P(ras->getSize());
|
|
Shinya Kitaoka |
120a6e |
ras->clear();
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
ras2 = ras;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Clear the buffer - it will hold all the stacked nodes content to be overed
|
|
Shinya Kitaoka |
120a6e |
// on top of the OpenGL buffer through a glDrawPixel()
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ras->clear(); // ras is typically reused - and we need it transparent first
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRect r = rect - rect.getP00();
|
|
Shinya Kitaoka |
120a6e |
TRaster32P viewedRaster = ras->extract(r);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int current = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve preferences-related data
|
|
Shinya Kitaoka |
120a6e |
int tc = m_checkFlags ? ToonzCheck::instance()->getChecks() : 0;
|
|
Shinya Kitaoka |
120a6e |
int index = ToonzCheck::instance()->getColorIndex();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 frontOnionColor, backOnionColor;
|
|
Shinya Kitaoka |
120a6e |
bool onionInksOnly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Preferences::instance()->getOnionData(frontOnionColor, backOnionColor,
|
|
Shinya Kitaoka |
120a6e |
onionInksOnly);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Stack every node on top of the raster buffer
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < nodesCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes[i].m_isCurrentColumn) current = i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = TTranslation(-rect.x0, -rect.y0) * m_nodes[i].m_aff;
|
|
Shinya Kitaoka |
120a6e |
TDimension imageDim = m_nodes[i].m_raster->getSize();
|
|
Shinya Kitaoka |
120a6e |
TPointD offset(0.5, 0.5);
|
|
Shinya Kitaoka |
120a6e |
aff *= TTranslation(offset); // very quick and very dirty fix: in
|
|
Shinya Kitaoka |
120a6e |
// camerastand the images seems shifted of an
|
|
Shinya Kitaoka |
120a6e |
// half pixel...it's a quickput approximation?
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 colorscale = TPixel32(0, 0, 0, m_nodes[i].m_alpha);
|
|
Shinya Kitaoka |
120a6e |
int inksOnly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes[i].m_onionMode != Node::eOnionSkinNone) {
|
|
Shinya Kitaoka |
120a6e |
inksOnly = onionInksOnly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes[i].m_onionMode == Node::eOnionSkinFront)
|
|
Shinya Kitaoka |
120a6e |
colorscale = TPixel32(frontOnionColor.r, frontOnionColor.g,
|
|
Shinya Kitaoka |
120a6e |
frontOnionColor.b, m_nodes[i].m_alpha);
|
|
Shinya Kitaoka |
120a6e |
else if (m_nodes[i].m_onionMode == Node::eOnionSkinBack)
|
|
Shinya Kitaoka |
120a6e |
colorscale = TPixel32(backOnionColor.r, backOnionColor.g,
|
|
Shinya Kitaoka |
120a6e |
backOnionColor.b, m_nodes[i].m_alpha);
|
|
shun_iwasawa |
a3cdd8 |
} else {
|
|
shun_iwasawa |
a3cdd8 |
if (m_nodes[i].m_filterColor != TPixel32::Black) {
|
|
shun_iwasawa |
a3cdd8 |
colorscale = m_nodes[i].m_filterColor;
|
|
shun_iwasawa |
a3cdd8 |
colorscale.m = m_nodes[i].m_alpha;
|
|
shun_iwasawa |
a3cdd8 |
}
|
|
Shinya Kitaoka |
120a6e |
inksOnly = tc & ToonzCheck::eInksOnly;
|
|
shun_iwasawa |
a3cdd8 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TRaster32P src32 = m_nodes[i].m_raster)
|
|
Shinya Kitaoka |
120a6e |
TRop::quickPut(viewedRaster, src32, aff, colorscale,
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_doPremultiply, m_nodes[i].m_whiteTransp,
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_isFirstColumn, m_doRasterDarkenBlendedView);
|
|
Shinya Kitaoka |
120a6e |
else if (TRasterGR8P srcGr8 = m_nodes[i].m_raster)
|
|
Shinya Kitaoka |
120a6e |
TRop::quickPut(viewedRaster, srcGr8, aff, colorscale);
|
|
Shinya Kitaoka |
120a6e |
else if (TRasterCM32P srcCm = m_nodes[i].m_raster) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_nodes[i].m_palette);
|
|
Shinya Kitaoka |
120a6e |
int oldframe = m_nodes[i].m_palette->getFrame();
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_palette->setFrame(m_nodes[i].m_frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPaletteP plt;
|
|
Shinya Kitaoka |
120a6e |
if ((tc & ToonzCheck::eGap || tc & ToonzCheck::eAutoclose) &&
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_isCurrentColumn) {
|
|
Shinya Kitaoka |
120a6e |
srcCm = srcCm->clone();
|
|
Shinya Kitaoka |
120a6e |
plt = m_nodes[i].m_palette->clone();
|
|
Shinya Kitaoka |
120a6e |
int styleIndex = plt->addStyle(TPixel::Magenta);
|
|
Shinya Kitaoka |
120a6e |
if (tc & ToonzCheck::eAutoclose)
|
|
Shinya Kitaoka |
120a6e |
TAutocloser(srcCm, AutocloseDistance, AutocloseAngle, styleIndex,
|
|
Shinya Kitaoka |
120a6e |
AutocloseOpacity)
|
|
Shinya Kitaoka |
120a6e |
.exec();
|
|
Shinya Kitaoka |
120a6e |
if (tc & ToonzCheck::eGap)
|
|
Shinya Kitaoka |
120a6e |
AreaFiller(srcCm).rectFill(m_nodes[i].m_savebox, 1, true, true,
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
plt = m_nodes[i].m_palette;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tc == 0 || tc == ToonzCheck::eBlackBg ||
|
|
Shinya Kitaoka |
120a6e |
!m_nodes[i].m_isCurrentColumn)
|
|
Shinya Kitaoka |
120a6e |
TRop::quickPut(viewedRaster, srcCm, plt, aff, colorscale, inksOnly);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TRop::CmappedQuickputSettings settings;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
settings.m_globalColorScale = colorscale;
|
|
Shinya Kitaoka |
120a6e |
settings.m_inksOnly = inksOnly;
|
|
Shinya Kitaoka |
120a6e |
settings.m_transparencyCheck =
|
|
Shinya Kitaoka |
120a6e |
tc & (ToonzCheck::eTransparency | ToonzCheck::eGap);
|
|
Shinya Kitaoka |
120a6e |
settings.m_blackBgCheck = tc & ToonzCheck::eBlackBg;
|
|
Shinya Kitaoka |
120a6e |
/*-- InkCheck, Ink#1Check, PaintCheckはカレントカラムにのみ有効 --*/
|
|
Shinya Kitaoka |
120a6e |
settings.m_inkIndex =
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_isCurrentColumn
|
|
Shinya Kitaoka |
120a6e |
? (tc & ToonzCheck::eInk ? index
|
|
Shinya Kitaoka |
120a6e |
: (tc & ToonzCheck::eInk1 ? 1 : -1))
|
|
Shinya Kitaoka |
120a6e |
: -1;
|
|
Shinya Kitaoka |
120a6e |
settings.m_paintIndex = m_nodes[i].m_isCurrentColumn
|
|
Shinya Kitaoka |
120a6e |
? (tc & ToonzCheck::ePaint ? index : -1)
|
|
Shinya Kitaoka |
120a6e |
: -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Preferences::instance()->getTranspCheckData(
|
|
Shinya Kitaoka |
120a6e |
settings.m_transpCheckBg, settings.m_transpCheckInk,
|
|
Shinya Kitaoka |
120a6e |
settings.m_transpCheckPaint);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRop::quickPut(viewedRaster, srcCm, plt, aff, settings);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
srcCm = TRasterCM32P();
|
|
Shinya Kitaoka |
120a6e |
plt = TPaletteP();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_nodes[i].m_palette->setFrame(oldframe);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(!"Cannot use quickput with this raster combination!");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_vs.m_colorMask != 0) {
|
|
Shinya Kitaoka |
120a6e |
TRop::setChannel(ras, ras, m_vs.m_colorMask, false);
|
|
Shinya Kitaoka |
120a6e |
TRop::quickPut(ras2, ras, TAffine());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Now, output the raster buffer on top of the OpenGL buffer
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_COLOR_BUFFER_BIT); // Preserve blending and stuff
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_ONE,
|
|
Shinya Kitaoka |
120a6e |
GL_ONE_MINUS_SRC_ALPHA); // The raster buffer is intended in
|
|
Shinya Kitaoka |
120a6e |
// premultiplied form - thus the GL_ONE on src
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_DEPTH_TEST);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_DITHER);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_LOGIC_OP);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
4cdcb0 |
/* disable, since these features are never enabled, and cause OpenGL to assert
|
|
Campbell Barton |
4cdcb0 |
* on systems that don't support them: see #591 */
|
|
Campbell Barton |
4cdcb0 |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
#ifdef GL_EXT_convolution
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_CONVOLUTION_1D_EXT);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_CONVOLUTION_2D_EXT);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_SEPARABLE_2D_EXT);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef GL_EXT_histogram
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_HISTOGRAM_EXT);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_MINMAX_EXT);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Campbell Barton |
4cdcb0 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef GL_EXT_texture3D
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_TEXTURE_3D_EXT);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
glLoadIdentity();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glRasterPos2d(rect.x0, rect.y0);
|
|
Shinya Kitaoka |
120a6e |
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
Shinya Kitaoka |
120a6e |
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glDrawPixels(ras2->getLx(), ras2->getLy(), // Perform the over
|
|
Shinya Kitaoka |
120a6e |
TGL_FMT, TGL_TYPE, ras2->getRawData()); //
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib(); // Restore blending status
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_vs.m_showBBox && current > -1) {
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
glLoadIdentity();
|
|
Shinya Kitaoka |
120a6e |
tglColor(TPixel(200, 200, 200));
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(m_nodes[current].m_aff);
|
|
Shinya Kitaoka |
120a6e |
tglDrawRect(m_nodes[current].m_raster->getBounds());
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_nodes.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*! Make frame visualization in QPainter.
|
|
Toshihiro Shimizu |
890ddd |
\n Draw in painter mode just raster image in m_nodes.
|
|
Toshihiro Shimizu |
890ddd |
\n Onon-skin or channel mode are not considered.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::drawRasterImages(QPainter &p, QPolygon cameraPol) {
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double delta = sqrt(fabs(m_nodes[0].m_aff.det()));
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = m_nodes[0].m_bbox.enlarge(delta);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 1; i < (int)m_nodes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
delta = sqrt(fabs(m_nodes[i].m_aff.det()));
|
|
Shinya Kitaoka |
120a6e |
bbox += m_nodes[i].m_bbox.enlarge(delta);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TRect rect(tfloor(bbox.x0), tfloor(bbox.y0), tceil(bbox.x1), tceil(bbox.y1));
|
|
Shinya Kitaoka |
120a6e |
rect = rect * TRect(0, 0, m_dim.lx - 1, m_dim.ly - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRect r = rect - rect.getP00();
|
|
Shinya Kitaoka |
120a6e |
TAffine flipY(1, 0, 0, 0, -1, m_dim.ly);
|
|
Shinya Kitaoka |
120a6e |
p.setClipRegion(QRegion(cameraPol));
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_nodes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_nodes[i].m_onionMode != Node::eOnionSkinNone) continue;
|
|
Shinya Kitaoka |
120a6e |
p.resetMatrix();
|
|
Shinya Kitaoka |
120a6e |
TRasterP ras = m_nodes[i].m_raster;
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = TTranslation(-rect.x0, -rect.y0) * flipY * m_nodes[i].m_aff;
|
|
Shinya Kitaoka |
120a6e |
QMatrix matrix(aff.a11, aff.a21, aff.a12, aff.a22, aff.a13, aff.a23);
|
|
Shinya Kitaoka |
120a6e |
QImage image = rasterToQImage(ras);
|
|
Shinya Kitaoka |
120a6e |
if (image.isNull()) continue;
|
|
Shinya Kitaoka |
120a6e |
p.setMatrix(matrix);
|
|
Shinya Kitaoka |
120a6e |
p.drawImage(rect.getP00().x, rect.getP00().y, image);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p.resetMatrix();
|
|
Shinya Kitaoka |
120a6e |
m_nodes.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static void buildAutocloseImage(
|
|
shun-iwasawa |
27b0cf |
TVectorImage *vaux, TVectorImage *vi,
|
|
shun-iwasawa |
27b0cf |
const std::vector<std::pair<int, double="">> &startPoints,</std::pair<int,>
|
|
shun-iwasawa |
27b0cf |
const std::vector<std::pair<int, double="">> &endPoints) {</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < startPoints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p1 = vi->getStroke(startPoints[i].first)
|
|
Shinya Kitaoka |
120a6e |
->getThickPoint(startPoints[i].second);
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p2 =
|
|
Shinya Kitaoka |
120a6e |
vi->getStroke(endPoints[i].first)->getThickPoint(endPoints[i].second);
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points(3);</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
points[0] = p1;
|
|
Shinya Kitaoka |
120a6e |
points[1] = 0.5 * (p1 + p2);
|
|
Shinya Kitaoka |
120a6e |
points[2] = p2;
|
|
Shinya Kitaoka |
120a6e |
points[0].thick = points[1].thick = points[2].thick = 0.0;
|
|
Shinya Kitaoka |
120a6e |
TStroke *auxStroke = new TStroke(points);
|
|
Shinya Kitaoka |
120a6e |
auxStroke->setStyle(2);
|
|
Shinya Kitaoka |
120a6e |
vaux->addStroke(auxStroke);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEnv::DoubleVar AutocloseFactor("InknpaintAutocloseFactor", 4.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
b3bd84 |
static void drawAutocloses(TVectorImage *vi, TVectorRenderData &rd) {
|
|
Shinya Kitaoka |
120a6e |
static TPalette *plt = 0;
|
|
Shinya Kitaoka |
120a6e |
if (!plt) {
|
|
Shinya Kitaoka |
120a6e |
plt = new TPalette();
|
|
Shinya Kitaoka |
120a6e |
plt->addStyle(TPixel::Magenta);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<int, double="">> startPoints, endPoints;</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
getClosingPoints(vi->getBBox(), AutocloseFactor, vi, startPoints, endPoints);
|
|
Shinya Kitaoka |
120a6e |
TVectorImage *vaux = new TVectorImage();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rd.m_palette = plt;
|
|
Shinya Kitaoka |
120a6e |
buildAutocloseImage(vaux, vi, startPoints, endPoints);
|
|
Shinya Kitaoka |
120a6e |
tglDraw(rd, vaux);
|
|
Shinya Kitaoka |
120a6e |
delete vaux;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! Take image from \b Stage::Player \b data and recall the right method for
|
|
Shinya Kitaoka |
120a6e |
this kind of image, for vector image recall \b onVectorImage(),
|
|
Shinya Kitaoka |
120a6e |
for raster
|
|
Shinya Kitaoka |
120a6e |
image recall \b onRasterImage() for toonz image recall \b
|
|
Shinya Kitaoka |
120a6e |
onToonzImage().
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::onImage(const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
if (m_singleColumnEnabled && !player.m_isCurrentColumn) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Attempt Plastic-deformed drawing
|
|
shun_iwasawa |
ed1861 |
// For now generating icons of plastic-deformed image causes crash as
|
|
shun_iwasawa |
ed1861 |
// QOffscreenSurface is created outside the gui thread.
|
|
shun_iwasawa |
ed1861 |
// As a quick workaround, ignore the deformation if this is called from
|
|
shun_iwasawa |
ed1861 |
// non-gui thread (i.e. icon generator thread)
|
|
shun_iwasawa |
7e52a2 |
// 12/1/2018 Now the scene icon is rendered without deformation either
|
|
shun_iwasawa |
7e52a2 |
// since it causes unknown error with opengl contexts..
|
|
shun_iwasawa |
ed1861 |
TStageObject *obj =
|
|
shun_iwasawa |
ed1861 |
::plasticDeformedObj(player, m_vs.m_plasticVisualSettings);
|
|
shun_iwasawa |
7e52a2 |
if (obj && QThread::currentThread() == qGuiApp->thread() &&
|
|
shun_iwasawa |
7e52a2 |
!m_vs.m_forSceneIcon) {
|
|
Shinya Kitaoka |
120a6e |
flushRasterImages();
|
|
Shinya Kitaoka |
120a6e |
::onPlasticDeformedImage(obj, player, m_vs, m_viewAff);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Common image draw
|
|
Shinya Kitaoka |
120a6e |
const TImageP &img = player.image();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (TVectorImageP vi = img)
|
|
Shinya Kitaoka |
120a6e |
onVectorImage(vi.getPointer(), player);
|
|
Shinya Kitaoka |
120a6e |
else if (TRasterImageP ri = img)
|
|
Shinya Kitaoka |
120a6e |
onRasterImage(ri.getPointer(), player);
|
|
Shinya Kitaoka |
120a6e |
else if (TToonzImageP ti = img)
|
|
Shinya Kitaoka |
120a6e |
onToonzImage(ti.getPointer(), player);
|
|
Shinya Kitaoka |
120a6e |
else if (TMeshImageP mi = img) {
|
|
Shinya Kitaoka |
120a6e |
flushRasterImages();
|
|
Shinya Kitaoka |
120a6e |
::onMeshImage(mi.getPointer(), player, m_vs, m_viewAff);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*! View a vector cell images.
|
|
Toshihiro Shimizu |
890ddd |
\n If onion-skin is active compute \b TOnionFader value.
|
|
Shinya Kitaoka |
120a6e |
Create and boot a \b TVectorRenderData and recall \b tglDraw().
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::onVectorImage(TVectorImage *vi,
|
|
Shinya Kitaoka |
120a6e |
const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
flushRasterImages();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// When loaded, vectorimages needs to have regions recomputed, but doing that
|
|
Shinya Kitaoka |
120a6e |
// while loading them
|
|
Shinya Kitaoka |
120a6e |
// is quite slow (think about loading whole scenes!..). They are recomputed
|
|
Shinya Kitaoka |
120a6e |
// the first time they
|
|
Shinya Kitaoka |
120a6e |
// are selected and shown on screen...except when playing back, to avoid
|
|
Shinya Kitaoka |
120a6e |
// slowness!
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// (Daniele) This function should *NOT* be responsible of that.
|
|
Shinya Kitaoka |
120a6e |
// It's the *image itself* that should recalculate or initialize
|
|
Shinya Kitaoka |
120a6e |
// said data
|
|
Shinya Kitaoka |
120a6e |
// if queried about it and turns out it's not available...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!player.m_isPlaying && player.m_isCurrentColumn)
|
|
Shinya Kitaoka |
120a6e |
vi->recomputeRegionsIfNeeded();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const Preferences &prefs = *Preferences::instance();
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
1e17ed |
TColorFunction *cf = 0, *guidedCf = 0;
|
|
Shinya Kitaoka |
120a6e |
TPalette *vPalette = vi->getPalette();
|
|
Shinya Kitaoka |
120a6e |
TPixel32 bgColor = TPixel32::White;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int tc = (m_checkFlags && player.m_isCurrentColumn)
|
|
Shinya Kitaoka |
120a6e |
? ToonzCheck::instance()->getChecks()
|
|
Shinya Kitaoka |
120a6e |
: 0;
|
|
Shinya Kitaoka |
120a6e |
bool inksOnly = tc & ToonzCheck::eInksOnly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int oldFrame = vPalette->getFrame();
|
|
Shinya Kitaoka |
120a6e |
vPalette->setFrame(player.m_frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 frontOnionColor, backOnionColor;
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
1d5937 |
if (player.m_onionSkinDistance != 0 &&
|
|
shun-iwasawa |
1d5937 |
(!player.m_isShiftAndTraceEnabled ||
|
|
shun-iwasawa |
1d5937 |
Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())) {
|
|
Shinya Kitaoka |
120a6e |
prefs.getOnionData(frontOnionColor, backOnionColor, inksOnly);
|
|
Shinya Kitaoka |
120a6e |
bgColor =
|
|
Shinya Kitaoka |
120a6e |
(player.m_onionSkinDistance < 0) ? backOnionColor : frontOnionColor;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double m[4] = {1.0, 1.0, 1.0, 1.0}, c[4];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Weighted addition to RGB and matte multiplication
|
|
Shinya Kitaoka |
120a6e |
m[3] = 1.0 -
|
|
Shinya Kitaoka |
120a6e |
((player.m_onionSkinDistance == 0)
|
|
Shinya Kitaoka |
120a6e |
? 0.1
|
|
Shinya Kitaoka |
120a6e |
: OnionSkinMask::getOnionSkinFade(player.m_onionSkinDistance));
|
|
Shinya Kitaoka |
120a6e |
c[0] = (1.0 - m[3]) * bgColor.r, c[1] = (1.0 - m[3]) * bgColor.g,
|
|
Shinya Kitaoka |
120a6e |
c[2] = (1.0 - m[3]) * bgColor.b;
|
|
Shinya Kitaoka |
120a6e |
c[3] = 0.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cf = new TGenericColorFunction(m, c);
|
|
shun_iwasawa |
2c0f50 |
} else if (player.m_filterColor != TPixel::Black) {
|
|
shun_iwasawa |
2c0f50 |
TPixel32 colorScale = player.m_filterColor;
|
|
shun_iwasawa |
2c0f50 |
colorScale.m = player.m_opacity;
|
|
shun_iwasawa |
2c0f50 |
cf = new TColumnColorFilterFunction(colorScale);
|
|
Shinya Kitaoka |
120a6e |
} else if (player.m_opacity < 255)
|
|
Shinya Kitaoka |
120a6e |
cf = new TTranspFader(player.m_opacity / 255.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TVectorRenderData rd(m_viewAff * player.m_placement, TRect(), vPalette, cf,
|
|
Shinya Kitaoka |
120a6e |
true // alpha enabled
|
|
Shinya Kitaoka |
120a6e |
);
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
1e17ed |
rd.m_drawRegions = !inksOnly;
|
|
Jeremy Bullock |
1e17ed |
rd.m_inkCheckEnabled = tc & ToonzCheck::eInk;
|
|
Jeremy Bullock |
1e17ed |
rd.m_paintCheckEnabled = tc & ToonzCheck::ePaint;
|
|
Jeremy Bullock |
1e17ed |
rd.m_blackBgEnabled = tc & ToonzCheck::eBlackBg;
|
|
Jeremy Bullock |
1e17ed |
rd.m_colorCheckIndex = ToonzCheck::instance()->getColorIndex();
|
|
Jeremy Bullock |
1e17ed |
rd.m_show0ThickStrokes = prefs.getShow0ThickLines();
|
|
Jeremy Bullock |
1e17ed |
rd.m_regionAntialias = prefs.getRegionAntialias();
|
|
Jeremy Bullock |
1e17ed |
rd.m_animatedGuidedDrawing = prefs.getAnimatedGuidedDrawing();
|
|
Jeremy Bullock |
1e17ed |
if (player.m_onionSkinDistance < 0 &&
|
|
Jeremy Bullock |
1e17ed |
(player.m_isCurrentColumn || player.m_isCurrentXsheetLevel)) {
|
|
Jeremy Bullock |
1e17ed |
if (player.m_isGuidedDrawingEnabled == 3 // show guides on all
|
|
Jeremy Bullock |
1e17ed |
|| (player.m_isGuidedDrawingEnabled == 1 && // show guides on closest
|
|
Jeremy Bullock |
1e17ed |
player.m_onionSkinDistance == player.m_firstBackOnionSkin) ||
|
|
Jeremy Bullock |
1e17ed |
(player.m_isGuidedDrawingEnabled == 2 && // show guides on farthest
|
|
Jeremy Bullock |
1e17ed |
player.m_onionSkinDistance == player.m_onionSkinBackSize) ||
|
|
Jeremy Bullock |
1e17ed |
(player.m_isEditingLevel && // fix for level editing mode sending extra
|
|
Jeremy Bullock |
1e17ed |
// players
|
|
Jeremy Bullock |
1e17ed |
player.m_isGuidedDrawingEnabled == 2 &&
|
|
Jeremy Bullock |
1e17ed |
player.m_onionSkinDistance == player.m_lastBackVisibleSkin)) {
|
|
Jeremy Bullock |
1e17ed |
rd.m_showGuidedDrawing = player.m_isGuidedDrawingEnabled > 0;
|
|
Jeremy Bullock |
1e17ed |
int currentStrokeCount = 0;
|
|
Jeremy Bullock |
1e17ed |
int totalStrokes = vi->getStrokeCount();
|
|
Jeremy Bullock |
1e17ed |
TXshSimpleLevel *sl = player.m_sl;
|
|
Jeremy Bullock |
1e17ed |
|
|
Jeremy Bullock |
1e17ed |
if (sl) {
|
|
Jeremy Bullock |
1e17ed |
TImageP image = sl->getFrame(player.m_currentFrameId, false);
|
|
Jeremy Bullock |
1e17ed |
TVectorImageP vecImage = image;
|
|
Jeremy Bullock |
1e17ed |
if (vecImage) currentStrokeCount = vecImage->getStrokeCount();
|
|
Jeremy Bullock |
1e17ed |
if (currentStrokeCount < totalStrokes)
|
|
Jeremy Bullock |
1e17ed |
rd.m_indexToHighlight = currentStrokeCount;
|
|
Jeremy Bullock |
1e17ed |
|
|
Jeremy Bullock |
1e17ed |
double guidedM[4] = {1.0, 1.0, 1.0, 1.0}, guidedC[4];
|
|
Jeremy Bullock |
1e17ed |
TPixel32 bgColor = TPixel32::Blue;
|
|
Jeremy Bullock |
1e17ed |
guidedM[3] =
|
|
Jeremy Bullock |
1e17ed |
1.0 -
|
|
Jeremy Bullock |
1e17ed |
((player.m_onionSkinDistance == 0)
|
|
Jeremy Bullock |
1e17ed |
? 0.1
|
|
Jeremy Bullock |
1e17ed |
: OnionSkinMask::getOnionSkinFade(player.m_onionSkinDistance));
|
|
Jeremy Bullock |
1e17ed |
|
|
Jeremy Bullock |
1e17ed |
guidedC[0] = (1.0 - guidedM[3]) * bgColor.r,
|
|
Jeremy Bullock |
1e17ed |
guidedC[1] = (1.0 - guidedM[3]) * bgColor.g,
|
|
Jeremy Bullock |
1e17ed |
guidedC[2] = (1.0 - guidedM[3]) * bgColor.b;
|
|
Jeremy Bullock |
1e17ed |
guidedC[3] = 0.0;
|
|
Jeremy Bullock |
1e17ed |
|
|
Jeremy Bullock |
1e17ed |
guidedCf = new TGenericColorFunction(guidedM, guidedC);
|
|
Jeremy Bullock |
1e17ed |
rd.m_guidedCf = guidedCf;
|
|
Jeremy Bullock |
1e17ed |
}
|
|
Jeremy Bullock |
1e17ed |
}
|
|
Jeremy Bullock |
1e17ed |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tc & (ToonzCheck::eTransparency | ToonzCheck::eGap)) {
|
|
Shinya Kitaoka |
120a6e |
TPixel dummy;
|
|
Shinya Kitaoka |
120a6e |
rd.m_tcheckEnabled = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (rd.m_blackBgEnabled)
|
|
Shinya Kitaoka |
120a6e |
prefs.getTranspCheckData(rd.m_tCheckInk, dummy, rd.m_tCheckPaint);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
prefs.getTranspCheckData(dummy, rd.m_tCheckInk, rd.m_tCheckPaint);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_vs.m_colorMask != 0) {
|
|
Shinya Kitaoka |
120a6e |
glColorMask((m_vs.m_colorMask & TRop::RChan) ? GL_TRUE : GL_FALSE,
|
|
Shinya Kitaoka |
120a6e |
(m_vs.m_colorMask & TRop::GChan) ? GL_TRUE : GL_FALSE,
|
|
Shinya Kitaoka |
120a6e |
(m_vs.m_colorMask & TRop::BChan) ? GL_TRUE : GL_FALSE, GL_TRUE);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP viDelete;
|
|
Shinya Kitaoka |
120a6e |
if (tc & ToonzCheck::eGap) {
|
|
Shinya Kitaoka |
120a6e |
viDelete = vi->clone();
|
|
Shinya Kitaoka |
120a6e |
vi = viDelete.getPointer();
|
|
Shinya Kitaoka |
120a6e |
vi->selectFill(vi->getBBox(), 0, 1, true, true, false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
18a7c6 |
TStroke *guidedStroke = 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_maskLevel > 0)
|
|
Shinya Kitaoka |
120a6e |
tglDrawMask(rd, vi);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
shun-iwasawa |
18a7c6 |
tglDraw(rd, vi, &guidedStroke);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tc & ToonzCheck::eAutoclose) drawAutocloses(vi, rd);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
Shinya Kitaoka |
120a6e |
vPalette->setFrame(oldFrame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
delete cf;
|
|
Jeremy Bullock |
1e17ed |
delete guidedCf;
|
|
shun-iwasawa |
18a7c6 |
|
|
shun-iwasawa |
18a7c6 |
if (guidedStroke) m_guidedStrokes.push_back(guidedStroke);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! Create a \b Node and put it in \b m_nodes.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::onRasterImage(TRasterImage *ri,
|
|
Shinya Kitaoka |
120a6e |
const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
TRasterP r = ri->getRaster();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff;
|
|
Shinya Kitaoka |
120a6e |
aff = m_viewAff * player.m_placement * player.m_dpiAff;
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(m_dim.lx * 0.5, m_dim.ly * 0.5) * aff *
|
|
Shinya Kitaoka |
120a6e |
TTranslation(-r->getCenterD() +
|
|
Shinya Kitaoka |
120a6e |
convert(ri->getOffset())); // this offset is !=0 only if
|
|
Shinya Kitaoka |
120a6e |
// in cleanup camera test mode
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = TRectD(0, 0, m_dim.lx, m_dim.ly);
|
|
Shinya Kitaoka |
120a6e |
bbox *= convert(m_clipRect);
|
|
Shinya Kitaoka |
120a6e |
if (bbox.isEmpty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int alpha = 255;
|
|
Shinya Kitaoka |
120a6e |
Node::OnionMode onionMode = Node::eOnionSkinNone;
|
|
Shinya Kitaoka |
120a6e |
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
|
Shinya Kitaoka |
120a6e |
// GetOnionSkinFade va bene per il vettoriale mentre il raster funziona al
|
|
Shinya Kitaoka |
120a6e |
// contrario
|
|
Shinya Kitaoka |
120a6e |
// 1 opaco -> 0 completamente trasparente
|
|
Shinya Kitaoka |
120a6e |
// inverto quindi il risultato della funzione stando attento al caso 0
|
|
Shinya Kitaoka |
120a6e |
// (in cui era scolpito il valore 0.9)
|
|
Shinya Kitaoka |
120a6e |
double onionSkiFade = player.m_onionSkinDistance == 0
|
|
Shinya Kitaoka |
120a6e |
? 0.9
|
|
Shinya Kitaoka |
120a6e |
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
|
Shinya Kitaoka |
120a6e |
player.m_onionSkinDistance));
|
|
shun-iwasawa |
1d5937 |
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
|
shun-iwasawa |
1d5937 |
if (player.m_isShiftAndTraceEnabled &&
|
|
shun-iwasawa |
1d5937 |
!Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())
|
|
shun-iwasawa |
1d5937 |
onionMode = Node::eOnionSkinNone;
|
|
shun-iwasawa |
1d5937 |
else {
|
|
shun-iwasawa |
1d5937 |
onionMode =
|
|
shun-iwasawa |
1d5937 |
(player.m_onionSkinDistance > 0)
|
|
shun-iwasawa |
1d5937 |
? Node::eOnionSkinFront
|
|
shun-iwasawa |
1d5937 |
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
|
shun-iwasawa |
1d5937 |
: Node::eOnionSkinNone);
|
|
shun-iwasawa |
1d5937 |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (player.m_opacity < 255)
|
|
Shinya Kitaoka |
120a6e |
alpha = player.m_opacity;
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *sl = player.m_sl;
|
|
Shinya Kitaoka |
120a6e |
bool doPremultiply = false;
|
|
Shinya Kitaoka |
120a6e |
bool whiteTransp = false;
|
|
Shinya Kitaoka |
120a6e |
if (sl) {
|
|
Shinya Kitaoka |
120a6e |
LevelProperties *levelProp = sl->getProperties();
|
|
Shinya Kitaoka |
120a6e |
if (levelProp->doPremultiply())
|
|
Shinya Kitaoka |
120a6e |
doPremultiply = true;
|
|
Shinya Kitaoka |
120a6e |
else if (levelProp->whiteTransp())
|
|
Shinya Kitaoka |
120a6e |
whiteTransp = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool ignoreAlpha =
|
|
Shinya Kitaoka |
120a6e |
(Preferences::instance()->isIgnoreAlphaonColumn1Enabled() &&
|
|
Shinya Kitaoka |
120a6e |
player.m_column == 0 &&
|
|
Shinya Kitaoka |
120a6e |
isSubsheetChainOnColumn0(sl->getScene()->getTopXsheet(), player.m_xsh,
|
|
Shinya Kitaoka |
120a6e |
player.m_frame));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_nodes.push_back(Node(r, 0, alpha, aff, ri->getSavebox(), bbox,
|
|
Shinya Kitaoka |
120a6e |
player.m_frame, player.m_isCurrentColumn, onionMode,
|
|
shun_iwasawa |
a3cdd8 |
doPremultiply, whiteTransp, ignoreAlpha,
|
|
shun_iwasawa |
a3cdd8 |
player.m_filterColor));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*! Create a \b Node and put it in \b m_nodes.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
void RasterPainter::onToonzImage(TToonzImage *ti, const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P r = ti->getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (!ti->getPalette()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = m_viewAff * player.m_placement * player.m_dpiAff;
|
|
Shinya Kitaoka |
120a6e |
aff = TTranslation(m_dim.lx / 2.0, m_dim.ly / 2.0) * aff *
|
|
Shinya Kitaoka |
120a6e |
TTranslation(-r->getCenterD());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = TRectD(0, 0, m_dim.lx, m_dim.ly);
|
|
Shinya Kitaoka |
120a6e |
bbox *= convert(m_clipRect);
|
|
Shinya Kitaoka |
120a6e |
if (bbox.isEmpty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int alpha = 255;
|
|
Shinya Kitaoka |
120a6e |
Node::OnionMode onionMode = Node::eOnionSkinNone;
|
|
Shinya Kitaoka |
120a6e |
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
|
Shinya Kitaoka |
120a6e |
// GetOnionSkinFade va bene per il vettoriale mentre il raster funziona al
|
|
Shinya Kitaoka |
120a6e |
// contrario
|
|
Shinya Kitaoka |
120a6e |
// 1 opaco -> 0 completamente trasparente
|
|
Shinya Kitaoka |
120a6e |
// inverto quindi il risultato della funzione stando attento al caso 0
|
|
Shinya Kitaoka |
120a6e |
// (in cui era scolpito il valore 0.9)
|
|
Shinya Kitaoka |
120a6e |
double onionSkiFade = player.m_onionSkinDistance == 0
|
|
Shinya Kitaoka |
120a6e |
? 0.9
|
|
Shinya Kitaoka |
120a6e |
: (1.0 - OnionSkinMask::getOnionSkinFade(
|
|
Shinya Kitaoka |
120a6e |
player.m_onionSkinDistance));
|
|
shun-iwasawa |
1d5937 |
alpha = tcrop(tround(onionSkiFade * 255.0), 0, 255);
|
|
shun-iwasawa |
1d5937 |
|
|
shun-iwasawa |
1d5937 |
if (player.m_isShiftAndTraceEnabled &&
|
|
shun-iwasawa |
1d5937 |
!Preferences::instance()->areOnionColorsUsedForShiftAndTraceGhosts())
|
|
shun-iwasawa |
1d5937 |
onionMode = Node::eOnionSkinNone;
|
|
shun-iwasawa |
1d5937 |
else {
|
|
shun-iwasawa |
1d5937 |
onionMode =
|
|
shun-iwasawa |
1d5937 |
(player.m_onionSkinDistance > 0)
|
|
shun-iwasawa |
1d5937 |
? Node::eOnionSkinFront
|
|
shun-iwasawa |
1d5937 |
: ((player.m_onionSkinDistance < 0) ? Node::eOnionSkinBack
|
|
shun-iwasawa |
1d5937 |
: Node::eOnionSkinNone);
|
|
shun-iwasawa |
1d5937 |
}
|
|
shun-iwasawa |
1d5937 |
|
|
Shinya Kitaoka |
120a6e |
} else if (player.m_opacity < 255)
|
|
Shinya Kitaoka |
120a6e |
alpha = player.m_opacity;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_nodes.push_back(Node(r, ti->getPalette(), alpha, aff, ti->getSavebox(),
|
|
Shinya Kitaoka |
120a6e |
bbox, player.m_frame, player.m_isCurrentColumn,
|
|
shun_iwasawa |
a3cdd8 |
onionMode, false, false, false, player.m_filterColor));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// OpenGLPainter implementation
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
OpenGlPainter::OpenGlPainter(const TAffine &viewAff, const TRect &rect,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs,
|
|
Shinya Kitaoka |
120a6e |
bool isViewer, bool alphaEnabled)
|
|
Shinya Kitaoka |
120a6e |
: Visitor(vs)
|
|
Shinya Kitaoka |
120a6e |
, m_viewAff(viewAff)
|
|
Shinya Kitaoka |
120a6e |
, m_clipRect(rect)
|
|
Shinya Kitaoka |
120a6e |
, m_camera3d(false)
|
|
Shinya Kitaoka |
120a6e |
, m_phi(0)
|
|
Shinya Kitaoka |
120a6e |
, m_maskLevel(0)
|
|
Shinya Kitaoka |
120a6e |
, m_isViewer(isViewer)
|
|
Shinya Kitaoka |
120a6e |
, m_alphaEnabled(alphaEnabled)
|
|
Shinya Kitaoka |
120a6e |
, m_paletteHasChanged(false)
|
|
Shinya Kitaoka |
120a6e |
, m_minZ(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::onImage(const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
if (player.m_z < m_minZ) m_minZ = player.m_z;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_camera3d)
|
|
Shinya Kitaoka |
120a6e |
glTranslated(
|
|
Shinya Kitaoka |
120a6e |
0, 0,
|
|
Shinya Kitaoka |
120a6e |
player.m_z); // Ok, move object along z as specified in the player
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Attempt Plastic-deformed drawing
|
|
Shinya Kitaoka |
120a6e |
if (TStageObject *obj =
|
|
Shinya Kitaoka |
120a6e |
::plasticDeformedObj(player, m_vs.m_plasticVisualSettings))
|
|
Shinya Kitaoka |
120a6e |
::onPlasticDeformedImage(obj, player, m_vs, m_viewAff);
|
|
Shinya Kitaoka |
120a6e |
else if (const TImageP &image = player.image()) {
|
|
Shinya Kitaoka |
120a6e |
if (TVectorImageP vi = image)
|
|
Shinya Kitaoka |
120a6e |
onVectorImage(vi.getPointer(), player);
|
|
Shinya Kitaoka |
120a6e |
else if (TRasterImageP ri = image)
|
|
Shinya Kitaoka |
120a6e |
onRasterImage(ri.getPointer(), player);
|
|
Shinya Kitaoka |
120a6e |
else if (TToonzImageP ti = image)
|
|
Shinya Kitaoka |
120a6e |
onToonzImage(ti.getPointer(), player);
|
|
Shinya Kitaoka |
120a6e |
else if (TMeshImageP mi = image)
|
|
Shinya Kitaoka |
120a6e |
onMeshImage(mi.getPointer(), player, m_vs, m_viewAff);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::onVectorImage(TVectorImage *vi,
|
|
Shinya Kitaoka |
120a6e |
const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
if (m_camera3d && (player.m_onionSkinDistance == c_noOnionSkin ||
|
|
Shinya Kitaoka |
120a6e |
player.m_onionSkinDistance == 0)) {
|
|
Shinya Kitaoka |
120a6e |
const TRectD &bbox = player.m_placement * player.m_dpiAff * vi->getBBox();
|
|
Shinya Kitaoka |
120a6e |
draw3DShadow(bbox, player.m_z, m_phi);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TColorFunction *cf = 0;
|
|
Shinya Kitaoka |
120a6e |
TOnionFader fader;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPalette *vPalette = vi->getPalette();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int oldFrame = vPalette->getFrame();
|
|
Shinya Kitaoka |
120a6e |
vPalette->setFrame(player.m_frame); // Hehe. Should be locking
|
|
Shinya Kitaoka |
120a6e |
// vPalette's mutex here...
|
|
Shinya Kitaoka |
120a6e |
if (player.m_onionSkinDistance != c_noOnionSkin) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 bgColor = TPixel32::White;
|
|
Shinya Kitaoka |
120a6e |
fader = TOnionFader(
|
|
Shinya Kitaoka |
120a6e |
bgColor, OnionSkinMask::getOnionSkinFade(player.m_onionSkinDistance));
|
|
Shinya Kitaoka |
120a6e |
cf = &fader;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TVectorRenderData rd =
|
|
Shinya Kitaoka |
120a6e |
isViewer() ? TVectorRenderData(TVectorRenderData::ViewerSettings(),
|
|
Shinya Kitaoka |
120a6e |
m_viewAff * player.m_placement, m_clipRect,
|
|
Shinya Kitaoka |
120a6e |
vPalette)
|
|
Shinya Kitaoka |
120a6e |
: TVectorRenderData(TVectorRenderData::ProductionSettings(),
|
|
Shinya Kitaoka |
120a6e |
m_viewAff * player.m_placement, m_clipRect,
|
|
Shinya Kitaoka |
120a6e |
vPalette);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rd.m_alphaChannel = m_alphaEnabled;
|
|
Shinya Kitaoka |
120a6e |
rd.m_is3dView = m_camera3d;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_maskLevel > 0)
|
|
Shinya Kitaoka |
120a6e |
tglDrawMask(rd, vi);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
tglDraw(rd, vi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vPalette->setFrame(oldFrame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::onRasterImage(TRasterImage *ri,
|
|
Shinya Kitaoka |
120a6e |
const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
if (m_camera3d && (player.m_onionSkinDistance == c_noOnionSkin ||
|
|
Shinya Kitaoka |
120a6e |
player.m_onionSkinDistance == 0)) {
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox(ri->getBBox());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Since bbox is in image coordinates, adjust to level coordinates first
|
|
Shinya Kitaoka |
120a6e |
bbox -= ri->getRaster()->getCenterD() - convert(ri->getOffset());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Then, to world coordinates
|
|
Shinya Kitaoka |
120a6e |
bbox = player.m_placement * player.m_dpiAff * bbox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
draw3DShadow(bbox, player.m_z, m_phi);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool tlvFlag = player.m_sl && player.m_sl->getType() == TZP_XSHLEVEL;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (tlvFlag &&
|
|
Shinya Kitaoka |
120a6e |
m_paletteHasChanged) // o.o! Raster images here - should never be
|
|
Shinya Kitaoka |
120a6e |
assert(false); // dealing with tlv stuff!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool premultiplied = tlvFlag; // xD
|
|
Shinya Kitaoka |
120a6e |
static std::vector<char></char>
|
|
Shinya Kitaoka |
120a6e |
matteChan; // Wtf this is criminal. Altough probably this
|
|
Shinya Kitaoka |
120a6e |
// stuff is used only in the main thread... hmmm....
|
|
Shinya Kitaoka |
120a6e |
TRaster32P r = (TRaster32P)ri->getRaster();
|
|
Shinya Kitaoka |
120a6e |
r->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (c_noOnionSkin != player.m_onionSkinDistance) {
|
|
Shinya Kitaoka |
120a6e |
double fade =
|
|
Shinya Kitaoka |
120a6e |
0.5 - 0.45 * (1 - 1 / (1 + 0.15 * abs(player.m_onionSkinDistance)));
|
|
Shinya Kitaoka |
120a6e |
if ((int)matteChan.size() < r->getLx() * r->getLy())
|
|
Shinya Kitaoka |
120a6e |
matteChan.resize(r->getLx() * r->getLy());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int k = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < r->getLy(); ++y) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = r->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + r->getLx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
matteChan[k++] = pix->m;
|
|
Shinya Kitaoka |
120a6e |
pix->m = (int)(pix->m * fade);
|
|
Shinya Kitaoka |
120a6e |
pix++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
premultiplied = false; // pfff
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = player.m_dpiAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
Shinya Kitaoka |
120a6e |
tglEnableBlending(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GLRasterPainter::drawRaster(m_viewAff * player.m_placement * aff *
|
|
Shinya Kitaoka |
120a6e |
TTranslation(convert(ri->getOffset())),
|
|
Shinya Kitaoka |
120a6e |
ri, premultiplied);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (c_noOnionSkin != player.m_onionSkinDistance) {
|
|
Shinya Kitaoka |
120a6e |
int k = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < r->getLy(); ++y) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = r->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *endPix = pix + r->getLx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) pix++->m = matteChan[k++];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
r->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::onToonzImage(TToonzImage *ti, const Stage::Player &player) {
|
|
Shinya Kitaoka |
120a6e |
if (m_camera3d && (player.m_onionSkinDistance == c_noOnionSkin ||
|
|
Shinya Kitaoka |
120a6e |
player.m_onionSkinDistance == 0)) {
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox(ti->getBBox());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bbox -= ti->getRaster()->getCenterD();
|
|
Shinya Kitaoka |
120a6e |
bbox = player.m_placement * player.m_dpiAff * bbox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
draw3DShadow(bbox, player.m_z, m_phi);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P ras = ti->getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras32(ras->getSize());
|
|
Shinya Kitaoka |
120a6e |
ras32->fill(TPixel32(0, 0, 0, 0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// onionSkin
|
|
Shinya Kitaoka |
120a6e |
TRop::quickPut(ras32, ras, ti->getPalette(), TAffine());
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = player.m_dpiAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterImageP ri(ras32);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GLRasterPainter::drawRaster(m_viewAff * player.m_placement * aff, ri, true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::beginMask() {
|
|
Shinya Kitaoka |
120a6e |
++m_maskLevel;
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->beginMask();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::endMask() {
|
|
Shinya Kitaoka |
120a6e |
--m_maskLevel;
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->endMask();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::enableMask() {
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->enableMask(TStencilControl::SHOW_INSIDE);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
void OpenGlPainter::disableMask() {
|
|
Shinya Kitaoka |
120a6e |
TStencilControl::instance()->disableMask();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Plastic functions implementation
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *plasticDeformedObj(const Stage::Player &player,
|
|
Shinya Kitaoka |
120a6e |
const PlasticVisualSettings &pvs) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static inline bool isDeformableMeshColumn(
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *column, const PlasticVisualSettings &pvs) {
|
|
Shinya Kitaoka |
120a6e |
return (column->getColumnType() == TXshColumn::eMeshType) &&
|
|
Shinya Kitaoka |
120a6e |
(pvs.m_showOriginalColumn != column);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static inline bool isDeformableMeshLevel(TXshSimpleLevel *sl) {
|
|
Shinya Kitaoka |
120a6e |
return sl && (sl->getType() == MESH_XSHLEVEL);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}; // locals
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (pvs.m_applyPlasticDeformation && player.m_column >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Check whether the player's column is a direct stage-schematic child of a
|
|
Shinya Kitaoka |
120a6e |
// mesh object
|
|
Shinya Kitaoka |
120a6e |
TStageObject *playerObj =
|
|
Shinya Kitaoka |
120a6e |
player.m_xsh->getStageObject(TStageObjectId::ColumnId(player.m_column));
|
|
Shinya Kitaoka |
120a6e |
assert(playerObj);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TStageObjectId &parentId = playerObj->getParent();
|
|
Shinya Kitaoka |
120a6e |
if (parentId.isColumn() && playerObj->getParentHandle()[0] != 'H') {
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *parentCol = player.m_xsh->getColumn(parentId.getIndex());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (locals::isDeformableMeshColumn(parentCol, pvs) &&
|
|
Shinya Kitaoka |
120a6e |
!locals::isDeformableMeshLevel(player.m_sl)) {
|
|
Shinya Kitaoka |
120a6e |
const SkDP &sd = player.m_xsh->getStageObject(parentId)
|
|
Shinya Kitaoka |
120a6e |
->getPlasticSkeletonDeformation();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &parentCell =
|
|
Shinya Kitaoka |
120a6e |
player.m_xsh->getCell(player.m_frame, parentId.getIndex());
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *parentSl = parentCell.getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (sd && locals::isDeformableMeshLevel(parentSl)) return playerObj;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void onMeshImage(TMeshImage *mi, const Stage::Player &player,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &viewAff) {
|
|
Shinya Kitaoka |
120a6e |
assert(mi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
static const double soMinColor[4] = {0.0, 0.0, 0.0,
|
|
Shinya Kitaoka |
120a6e |
0.6}; // Translucent black
|
|
Shinya Kitaoka |
120a6e |
static const double soMaxColor[4] = {1.0, 1.0, 1.0,
|
|
Shinya Kitaoka |
120a6e |
0.6}; // Translucent white
|
|
Shinya Kitaoka |
120a6e |
static const double rigMinColor[4] = {0.0, 1.0, 0.0,
|
|
Shinya Kitaoka |
120a6e |
0.6}; // Translucent green
|
|
Shinya Kitaoka |
120a6e |
static const double rigMaxColor[4] = {1.0, 0.0, 0.0, 0.6}; // Translucent red
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool doOnionSkin = (player.m_onionSkinDistance != c_noOnionSkin);
|
|
Shinya Kitaoka |
120a6e |
bool onionSkinImage = doOnionSkin && (player.m_onionSkinDistance != 0);
|
|
Shinya Kitaoka |
120a6e |
bool drawMeshes =
|
|
Shinya Kitaoka |
120a6e |
vs.m_plasticVisualSettings.m_drawMeshesWireframe && !onionSkinImage;
|
|
Shinya Kitaoka |
120a6e |
bool drawSO = vs.m_plasticVisualSettings.m_drawSO && !onionSkinImage;
|
|
Shinya Kitaoka |
120a6e |
bool drawRigidity =
|
|
Shinya Kitaoka |
120a6e |
vs.m_plasticVisualSettings.m_drawRigidity && !onionSkinImage;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Currently skipping onion skinned meshes
|
|
Shinya Kitaoka |
120a6e |
if (onionSkinImage) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build dpi
|
|
Shinya Kitaoka |
120a6e |
TPointD meshSlDpi(player.m_sl->getDpi(player.m_fid, 0));
|
|
Shinya Kitaoka |
120a6e |
assert(meshSlDpi.x != 0.0 && meshSlDpi.y != 0.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build reference change affines
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldMeshToMeshAff =
|
|
Shinya Kitaoka |
120a6e |
TScale(meshSlDpi.x / Stage::inch, meshSlDpi.y / Stage::inch);
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToWorldMeshAff =
|
|
Shinya Kitaoka |
120a6e |
TScale(Stage::inch / meshSlDpi.x, Stage::inch / meshSlDpi.y);
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldMeshToWorldAff = player.m_placement;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToWorldAff = worldMeshToWorldAff * meshToWorldMeshAff;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Prepare OpenGL
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_LINE_SMOOTH);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Push mesh coordinates
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(viewAff * meshToWorldAff);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Fetch deformation
|
|
Shinya Kitaoka |
120a6e |
PlasticSkeletonDeformation *deformation = 0;
|
|
Shinya Kitaoka |
120a6e |
double sdFrame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (vs.m_plasticVisualSettings.m_applyPlasticDeformation &&
|
|
Shinya Kitaoka |
120a6e |
player.m_column >= 0) {
|
|
Shinya Kitaoka |
120a6e |
TXshColumn *column = player.m_xsh->getColumn(player.m_column);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (column != vs.m_plasticVisualSettings.m_showOriginalColumn) {
|
|
Shinya Kitaoka |
120a6e |
TStageObject *playerObj = player.m_xsh->getStageObject(
|
|
Shinya Kitaoka |
120a6e |
TStageObjectId::ColumnId(player.m_column));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
deformation = playerObj->getPlasticSkeletonDeformation().getPointer();
|
|
Shinya Kitaoka |
120a6e |
sdFrame = playerObj->paramsTime(player.m_frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (deformation) {
|
|
Shinya Kitaoka |
120a6e |
// Retrieve the associated plastic deformers data (this may eventually
|
|
Shinya Kitaoka |
120a6e |
// update the deforms)
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *dataGroup =
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->process(
|
|
Shinya Kitaoka |
120a6e |
sdFrame, mi, deformation, deformation->skeletonId(sdFrame),
|
|
Shinya Kitaoka |
120a6e |
worldMeshToMeshAff);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw faces first
|
|
Shinya Kitaoka |
120a6e |
if (drawSO)
|
|
Shinya Kitaoka |
120a6e |
tglDrawSO(*mi, (double *)soMinColor, (double *)soMaxColor, dataGroup,
|
|
Shinya Kitaoka |
120a6e |
true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawRigidity)
|
|
Shinya Kitaoka |
120a6e |
tglDrawRigidity(*mi, (double *)rigMinColor, (double *)rigMaxColor,
|
|
Shinya Kitaoka |
120a6e |
dataGroup, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw edges next
|
|
Shinya Kitaoka |
120a6e |
if (drawMeshes) {
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.0, 1.0, 0.0, 0.7 * player.m_opacity / 255.0); // Green
|
|
Shinya Kitaoka |
120a6e |
tglDrawEdges(*mi, dataGroup); // The mesh must be deformed
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Draw un-deformed data
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw faces first
|
|
Shinya Kitaoka |
120a6e |
if (drawSO) tglDrawSO(*mi, (double *)soMinColor, (double *)soMaxColor);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawRigidity)
|
|
Shinya Kitaoka |
120a6e |
tglDrawRigidity(*mi, (double *)rigMinColor, (double *)rigMaxColor);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Just draw the mesh image next
|
|
Shinya Kitaoka |
120a6e |
if (drawMeshes) {
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.0, 1.0, 0.0, 0.7 * player.m_opacity / 255.0); // Green
|
|
Shinya Kitaoka |
120a6e |
tglDrawEdges(*mi);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Cleanup OpenGL
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_LINE_SMOOTH);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_BLEND);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Applies Plastic deformation of the specified player's stage object.
|
|
Shinya Kitaoka |
120a6e |
void onPlasticDeformedImage(TStageObject *playerObj,
|
|
Shinya Kitaoka |
120a6e |
const Stage::Player &player,
|
|
Shinya Kitaoka |
120a6e |
const ImagePainter::VisualSettings &vs,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &viewAff) {
|
|
Shinya Kitaoka |
120a6e |
bool doOnionSkin = (player.m_onionSkinDistance != c_noOnionSkin);
|
|
Shinya Kitaoka |
120a6e |
bool onionSkinImage = doOnionSkin && (player.m_onionSkinDistance != 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Deal with color scaling due to transparency / onion skin
|
|
Shinya Kitaoka |
120a6e |
double pixScale[4] = {1.0, 1.0, 1.0, 1.0};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (doOnionSkin) {
|
|
Shinya Kitaoka |
120a6e |
if (onionSkinImage) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 frontOnionColor, backOnionColor;
|
|
Shinya Kitaoka |
120a6e |
bool inksOnly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Preferences::instance()->getOnionData(frontOnionColor, backOnionColor,
|
|
Shinya Kitaoka |
120a6e |
inksOnly);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TPixel32 &refColor =
|
|
Shinya Kitaoka |
120a6e |
(player.m_onionSkinDistance < 0) ? backOnionColor : frontOnionColor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
pixScale[3] =
|
|
Shinya Kitaoka |
120a6e |
1.0 - OnionSkinMask::getOnionSkinFade(player.m_onionSkinDistance);
|
|
Shinya Kitaoka |
120a6e |
pixScale[0] =
|
|
Shinya Kitaoka |
120a6e |
(refColor.r / 255.0) * pixScale[3]; // refColor is not premultiplied
|
|
Shinya Kitaoka |
120a6e |
pixScale[1] = (refColor.g / 255.0) * pixScale[3];
|
|
Shinya Kitaoka |
120a6e |
pixScale[2] = (refColor.b / 255.0) * pixScale[3];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (player.m_opacity < 255) {
|
|
Shinya Kitaoka |
120a6e |
pixScale[3] = player.m_opacity / 255.0;
|
|
Shinya Kitaoka |
120a6e |
pixScale[0] = pixScale[1] = pixScale[2] = 0.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build the Mesh-related data
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &cell =
|
|
Shinya Kitaoka |
120a6e |
player.m_xsh->getCell(player.m_frame, playerObj->getParent().getIndex());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *meshLevel = cell.getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
const TFrameId &meshFid = cell.getFrameId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TMeshImageP &mi = meshLevel->getFrame(meshFid, false);
|
|
Shinya Kitaoka |
120a6e |
if (!mi) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build deformation-related data
|
|
Shinya Kitaoka |
120a6e |
TStageObject *parentObj =
|
|
Shinya Kitaoka |
120a6e |
player.m_xsh->getStageObject(playerObj->getParent());
|
|
Shinya Kitaoka |
120a6e |
assert(playerObj);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonDeformationP &deformation =
|
|
Shinya Kitaoka |
120a6e |
parentObj->getPlasticSkeletonDeformation().getPointer();
|
|
Shinya Kitaoka |
120a6e |
assert(deformation);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double sdFrame = parentObj->paramsTime(player.m_frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build dpis
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD meshSlDpi(meshLevel->getDpi(meshFid, 0));
|
|
Shinya Kitaoka |
120a6e |
assert(meshSlDpi.x != 0.0 && meshSlDpi.y != 0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD slDpi(player.m_sl ? player.m_sl->getDpi(player.m_fid, 0) : TPointD());
|
|
Shinya Kitaoka |
120a6e |
if (slDpi.x == 0.0 || slDpi.y == 0.0 ||
|
|
Shinya Kitaoka |
120a6e |
player.m_sl->getType() == PLI_XSHLEVEL)
|
|
Shinya Kitaoka |
120a6e |
slDpi.x = slDpi.y = Stage::inch;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build reference transforms
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldTextureToWorldMeshAff =
|
|
Shinya Kitaoka |
120a6e |
playerObj->getLocalPlacement(player.m_frame);
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldTextureToWorldAff = player.m_placement;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (fabs(worldTextureToWorldMeshAff.det()) < 1e-6)
|
|
Shinya Kitaoka |
120a6e |
return; // Skip near-singular mesh/texture placements
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldMeshToWorldTextureAff = worldTextureToWorldMeshAff.inv();
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldMeshToWorldAff =
|
|
Shinya Kitaoka |
120a6e |
worldTextureToWorldAff * worldMeshToWorldTextureAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToWorldMeshAff =
|
|
Shinya Kitaoka |
120a6e |
TScale(Stage::inch / meshSlDpi.x, Stage::inch / meshSlDpi.y);
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldMeshToMeshAff =
|
|
Shinya Kitaoka |
120a6e |
TScale(meshSlDpi.x / Stage::inch, meshSlDpi.y / Stage::inch);
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldTextureToTextureAff = TScale(
|
|
Shinya Kitaoka |
120a6e |
slDpi.x / Stage::inch,
|
|
Shinya Kitaoka |
120a6e |
slDpi.y /
|
|
Shinya Kitaoka |
120a6e |
Stage::inch); // ::getDpiScale().inv() should be used instead...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToWorldAff = worldMeshToWorldAff * meshToWorldMeshAff;
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToTextureAff = worldTextureToTextureAff *
|
|
Shinya Kitaoka |
120a6e |
worldMeshToWorldTextureAff *
|
|
Shinya Kitaoka |
120a6e |
meshToWorldMeshAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve a drawable texture from the player's simple level
|
|
Shinya Kitaoka |
120a6e |
const DrawableTextureDataP &texData = player.texture();
|
|
Shinya Kitaoka |
120a6e |
if (!texData) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve the associated plastic deformers data (this may eventually update
|
|
Shinya Kitaoka |
120a6e |
// the deforms)
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *dataGroup =
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->process(
|
|
Shinya Kitaoka |
120a6e |
sdFrame, mi.getPointer(), deformation.getPointer(),
|
|
Shinya Kitaoka |
120a6e |
deformation->skeletonId(sdFrame), worldMeshToMeshAff);
|
|
Shinya Kitaoka |
120a6e |
assert(dataGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Set up OpenGL stuff
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_LINE_SMOOTH);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Push mesh coordinates
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(viewAff * meshToWorldAff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_TEXTURE_2D);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Applying modulation by the specified transparency parameter
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glColor4d(pixScale[3], pixScale[3], pixScale[3], pixScale[3]);
|
|
Shinya Kitaoka |
120a6e |
tglDraw(*mi, *texData, meshToTextureAff, *dataGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_TEXTURE_2D);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (onionSkinImage) {
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_ONE, GL_ONE);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Add Onion skin color. Observe that this way we don't consider blending
|
|
Shinya Kitaoka |
120a6e |
// with the texture's
|
|
Shinya Kitaoka |
120a6e |
// alpha - to obtain that, there is no simple way...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double k = (1.0 - pixScale[3]);
|
|
Shinya Kitaoka |
120a6e |
glColor4d(k * pixScale[0], k * pixScale[1], k * pixScale[2], 0.0);
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(*mi, dataGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_LINE_SMOOTH);
|
|
Shinya Kitaoka |
120a6e |
glDisable(GL_BLEND);
|
|
shun_iwasawa |
7e52a2 |
assert(glGetError() == GL_NO_ERROR);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|