|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/plasticdeformerfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheet.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshleveltypes.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshcell.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshlevelcolumn.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/dpiscale.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticskeleton.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticdeformerstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/ttexturesstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticvisualsettings.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/meshutils.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "trenderer.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tofflinegl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgldisplaylistsmanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
d5d1ac |
#include <qopenglframebufferobject></qopenglframebufferobject>
|
|
shun_iwasawa |
7e52a2 |
#include <qoffscreensurface></qoffscreensurface>
|
|
shun_iwasawa |
7e52a2 |
#include <qsurfaceformat></qsurfaceformat>
|
|
shun_iwasawa |
7e52a2 |
#include <qopenglcontext></qopenglcontext>
|
|
shun_iwasawa |
7e52a2 |
#include <qimage></qimage>
|
|
shun_iwasawa |
7e52a2 |
|
|
Toshihiro Shimizu |
890ddd |
FX_IDENTIFIER_IS_HIDDEN(PlasticDeformerFx, "plasticDeformerFx")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::string toString(const TAffine &aff) {
|
|
Shinya Kitaoka |
120a6e |
return
|
|
Shinya Kitaoka |
120a6e |
// Observe that toString distinguishes + and - 0. That is a problem
|
|
Shinya Kitaoka |
120a6e |
// when comparing aliases - so near 0 values are explicitly rounded to 0.
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(aff.a11, 0.0) ? "0" : ::to_string(aff.a11, 5)) + "," +
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(aff.a12, 0.0) ? "0" : ::to_string(aff.a12, 5)) + "," +
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(aff.a13, 0.0) ? "0" : ::to_string(aff.a13, 5)) + "," +
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(aff.a21, 0.0) ? "0" : ::to_string(aff.a21, 5)) + "," +
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(aff.a22, 0.0) ? "0" : ::to_string(aff.a22, 5)) + "," +
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(aff.a23, 0.0) ? "0" : ::to_string(aff.a23, 5));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string toString(SkVD *vd, double sdFrame) {
|
|
Shinya Kitaoka |
120a6e |
std::string result;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p < SkVD::PARAMS_COUNT; ++p)
|
|
Shinya Kitaoka |
120a6e |
result += ::to_string(vd->m_params[p]->getValue(sdFrame), 5) + " ";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string toString(const PlasticSkeleton::vertex_type &vx) {
|
|
Shinya Kitaoka |
120a6e |
// TODO: Add z and rigidity
|
|
Shinya Kitaoka |
120a6e |
return ::to_string(vx.P().x, 5) + " " + ::to_string(vx.P().y, 5);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string toString(const PlasticSkeletonDeformationP &sd, double sdFrame) {
|
|
Shinya Kitaoka |
120a6e |
std::string result;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonP &skeleton = sd->skeleton(sdFrame);
|
|
Shinya Kitaoka |
120a6e |
if (!skeleton || skeleton->empty()) return result;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const tcg::list<plasticskeleton::vertex_type> &vertices =</plasticskeleton::vertex_type>
|
|
Shinya Kitaoka |
120a6e |
skeleton->vertices();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tcg::list<plasticskeleton::vertex_type>::const_iterator vt,</plasticskeleton::vertex_type>
|
|
Shinya Kitaoka |
120a6e |
vEnd(vertices.end());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
result = toString(*vertices.begin());
|
|
Shinya Kitaoka |
120a6e |
for (vt = vertices.begin(); vt != vEnd; ++vt) {
|
|
Shinya Kitaoka |
120a6e |
result += "; " + toString(*vt);
|
|
Shinya Kitaoka |
120a6e |
result += " " + toString(sd->vertexDeformation(vt->name()), sdFrame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// PlasticDeformerFx implementation
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerFx::PlasticDeformerFx() : TRasterFx() {
|
|
Shinya Kitaoka |
120a6e |
addInputPort("source", m_port);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFx *PlasticDeformerFx::clone(bool recursive) const {
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerFx *fx =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<plasticdeformerfx *="">(TFx::clone(recursive));</plasticdeformerfx>
|
|
Shinya Kitaoka |
120a6e |
assert(fx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
fx->m_xsh = m_xsh;
|
|
Shinya Kitaoka |
120a6e |
fx->m_col = m_col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return fx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool PlasticDeformerFx::canHandle(const TRenderSettings &info, double frame) {
|
|
Shinya Kitaoka |
120a6e |
// Yep. Affines are handled. Well - it's easy, since OpenGL lets you do that
|
|
Shinya Kitaoka |
120a6e |
// directly
|
|
Shinya Kitaoka |
120a6e |
// with a glPushMatrix...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::string PlasticDeformerFx::getAlias(double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) const {
|
|
Shinya Kitaoka |
120a6e |
std::string alias(getFxType());
|
|
Shinya Kitaoka |
120a6e |
alias += "[";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_port.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
TRasterFxP ifx = m_port.getFx();
|
|
Shinya Kitaoka |
120a6e |
assert(ifx);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
alias += ifx->getAlias(frame, info);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *meshColumnObj =
|
|
Shinya Kitaoka |
120a6e |
m_xsh->getStageObject(TStageObjectId::ColumnId(m_col));
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonDeformationP &sd =
|
|
Shinya Kitaoka |
120a6e |
meshColumnObj->getPlasticSkeletonDeformation();
|
|
Shinya Kitaoka |
120a6e |
if (sd) alias += ", " + toString(sd, meshColumnObj->paramsTime(frame));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
alias + "]";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return alias;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool PlasticDeformerFx::doGetBBox(double frame, TRectD &bbox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_port.isConnected()) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// It's hard work to calculate the bounding box of a plastic deformation.
|
|
Shinya Kitaoka |
120a6e |
// Decline.
|
|
Shinya Kitaoka |
120a6e |
bbox = TConsts::infiniteRectD;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticDeformerFx::buildRenderSettings(double frame,
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
// As previously pointed out, this fx is able to handle affines. We can,
|
|
Shinya Kitaoka |
120a6e |
// actually, *decide*
|
|
Shinya Kitaoka |
120a6e |
// the input reference to work with.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// So, the best choice is to let the *input fx* decide the appropriate
|
|
Shinya Kitaoka |
120a6e |
// reference, by invoking
|
|
Shinya Kitaoka |
120a6e |
// its handledAffine() method.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
info.m_bpp = 32; // We need to fix the input to 32-bpp
|
|
Shinya Kitaoka |
120a6e |
info.m_affine = m_port->handledAffine(info, frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool PlasticDeformerFx::buildTextureDataSl(double frame, TRenderSettings &info,
|
|
Shinya Kitaoka |
120a6e |
TAffine &worldLevelToLevelAff) {
|
|
Shinya Kitaoka |
120a6e |
int row = (int)frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Initialize level vars
|
|
Shinya Kitaoka |
120a6e |
TLevelColumnFx *lcfx = (TLevelColumnFx *)m_port.getFx();
|
|
Shinya Kitaoka |
120a6e |
TXshLevelColumn *texColumn = lcfx->getColumn();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &texCell = texColumn->getCell(row);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *texSl = texCell.getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
const TFrameId &texFid = texCell.getFrameId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!texSl || texSl->getType() == MESH_XSHLEVEL) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build dpi data
|
|
Shinya Kitaoka |
120a6e |
TPointD texDpi(texSl->getDpi(texFid, 0));
|
|
Shinya Kitaoka |
120a6e |
if (texDpi.x == 0.0 || texDpi.y == 0.0 || texSl->getType() == PLI_XSHLEVEL)
|
|
Shinya Kitaoka |
120a6e |
texDpi.x = texDpi.y = Stage::inch;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build reference transforms data
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: TAffine() corresponds to IMAGE coordinates here, not WORLD
|
|
Shinya Kitaoka |
120a6e |
// coordinates. This is achieved
|
|
Shinya Kitaoka |
120a6e |
// by removing the level's dpi affine during render-tree build-up (see
|
|
Shinya Kitaoka |
120a6e |
// scenefx.cpp).
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
worldLevelToLevelAff = TScale(texDpi.x / Stage::inch, texDpi.y / Stage::inch);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Initialize input render settings
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// In the case of vector images, in order to retain the image quality required
|
|
Shinya Kitaoka |
120a6e |
// by info.m_affine,
|
|
Shinya Kitaoka |
120a6e |
// the scale component is allowed too.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// In the raster image case, we'll use the original image reference IF the
|
|
Shinya Kitaoka |
120a6e |
// affine is a magnification
|
|
Shinya Kitaoka |
120a6e |
// (ie the scale is > 1.0) - OTHERWISE, the OpenGL minification filter is too
|
|
Shinya Kitaoka |
120a6e |
// crude since it renders
|
|
Shinya Kitaoka |
120a6e |
// a fragment using its 4 adjacent pixels ONLY; in this case, we'll pass the
|
|
Shinya Kitaoka |
120a6e |
// affine below.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &handledAff = TRasterFx::handledAffine(info, frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (texSl->getType() == PLI_XSHLEVEL) {
|
|
Shinya Kitaoka |
120a6e |
info.m_affine = handledAff;
|
|
Shinya Kitaoka |
120a6e |
buildRenderSettings(frame, info);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
info.m_affine = TAffine();
|
|
Shinya Kitaoka |
120a6e |
buildRenderSettings(frame, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: scale = handledAff.a11 / worldLevelToLevelAff.a11
|
|
Shinya Kitaoka |
120a6e |
if (handledAff.a11 < worldLevelToLevelAff.a11)
|
|
Shinya Kitaoka |
120a6e |
info.m_affine =
|
|
Shinya Kitaoka |
120a6e |
TScale(handledAff.a11 / worldLevelToLevelAff.a11) * info.m_affine;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool PlasticDeformerFx::buildTextureData(double frame, TRenderSettings &info,
|
|
Shinya Kitaoka |
120a6e |
TAffine &worldLevelToLevelAff) {
|
|
Shinya Kitaoka |
120a6e |
// Common case (typically happen with sub-xsheets)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
buildRenderSettings(frame, info); // Adjust the info
|
|
Shinya Kitaoka |
120a6e |
worldLevelToLevelAff = TAffine(); // Reference match
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticDeformerFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_port.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->clear();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int row = (int)frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build texture data
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings texInfo(info);
|
|
Shinya Kitaoka |
120a6e |
TAffine worldTexLevelToTexLevelAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dynamic_cast<tlevelcolumnfx *="">(m_port.getFx())) {</tlevelcolumnfx>
|
|
Shinya Kitaoka |
120a6e |
if (!buildTextureDataSl(frame, texInfo, worldTexLevelToTexLevelAff)) return;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
buildTextureData(frame, texInfo, worldTexLevelToTexLevelAff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Initialize mesh level vars
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &meshCell = m_xsh->getCell(row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *meshSl = meshCell.getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
const TFrameId &meshFid = meshCell.getFrameId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!meshSl || meshSl->getType() != MESH_XSHLEVEL) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve mesh image and deformation
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *meshColumnObj =
|
|
Shinya Kitaoka |
120a6e |
m_xsh->getStageObject(TStageObjectId::ColumnId(m_col));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TMeshImageP mi(meshSl->getFrame(meshFid, false));
|
|
Shinya Kitaoka |
120a6e |
if (!mi) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve deformation data
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonDeformationP &sd =
|
|
Shinya Kitaoka |
120a6e |
meshColumnObj->getPlasticSkeletonDeformation();
|
|
Shinya Kitaoka |
120a6e |
assert(sd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double sdFrame = meshColumnObj->paramsTime(frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build dpi data
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD meshDpi(meshSl->getDpi(meshFid, 0));
|
|
Shinya Kitaoka |
120a6e |
assert(meshDpi.x != 0.0 && meshDpi.y != 0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build reference transforms data
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build affines
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &imageToTextureAff = texInfo.m_affine;
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldTexLevelToWorldMeshAff = m_texPlacement;
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToWorldMeshAff =
|
|
Shinya Kitaoka |
120a6e |
TScale(Stage::inch / meshDpi.x, Stage::inch / meshDpi.y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToTexLevelAff = worldTexLevelToTexLevelAff *
|
|
Shinya Kitaoka |
120a6e |
worldTexLevelToWorldMeshAff.inv() *
|
|
Shinya Kitaoka |
120a6e |
meshToWorldMeshAff;
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToTextureAff = imageToTextureAff * meshToTexLevelAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve deformer data
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TScale worldMeshToMeshAff(meshDpi.x / Stage::inch, meshDpi.y / Stage::inch);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
2a7129 |
std::unique_ptr<const plasticdeformerdatagroup=""> dataGroup(</const>
|
|
Shinya Kitaoka |
120a6e |
PlasticDeformerStorage::instance()->processOnce(
|
|
Shinya Kitaoka |
120a6e |
sdFrame, mi.getPointer(), sd.getPointer(), sd->skeletonId(sdFrame),
|
|
Shinya Kitaoka |
120a6e |
worldMeshToMeshAff));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build texture
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build the mesh's bounding box and map it to input reference
|
|
Shinya Kitaoka |
120a6e |
TRectD meshBBox(meshToTextureAff * mi->getBBox());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Now, build the tile's geometry
|
|
Shinya Kitaoka |
120a6e |
TRectD texBBox;
|
|
Shinya Kitaoka |
120a6e |
m_port->getBBox(frame, texBBox, texInfo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = texBBox * meshBBox;
|
|
Shinya Kitaoka |
120a6e |
if (bbox.getLx() <= 0.0 || bbox.getLy() <= 0.0) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bbox.x0 = tfloor(bbox.x0);
|
|
Shinya Kitaoka |
120a6e |
bbox.y0 = tfloor(bbox.y0);
|
|
Shinya Kitaoka |
120a6e |
bbox.x1 = tceil(bbox.x1);
|
|
Shinya Kitaoka |
120a6e |
bbox.y1 = tceil(bbox.y1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDimension tileSize(tround(bbox.getLx()), tround(bbox.getLy()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Then, compute the input image
|
|
Shinya Kitaoka |
120a6e |
TTile inTile;
|
|
Shinya Kitaoka |
120a6e |
m_port->allocateAndCompute(inTile, bbox.getP00(), tileSize, TRasterP(), frame,
|
|
Shinya Kitaoka |
120a6e |
texInfo);
|
|
shun_iwasawa |
7e52a2 |
QOpenGLContext *context;
|
|
Shinya Kitaoka |
120a6e |
// Draw the textured mesh
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// Prepare texture
|
|
Shinya Kitaoka |
120a6e |
TRaster32P tex(inTile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
TRop::depremultiply(tex); // Textures must be stored depremultiplied.
|
|
Shinya Kitaoka |
120a6e |
// See docs about the tglDraw() below.
|
|
Shinya Kitaoka |
120a6e |
static TAtomicVar var;
|
|
Shinya Kitaoka |
120a6e |
const std::string &texId = "render_tex " + std::to_string(++var);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Prepare an OpenGL context
|
|
shun_iwasawa |
7e52a2 |
context = new QOpenGLContext();
|
|
shun-iwasawa |
b08db1 |
if (QOpenGLContext::currentContext())
|
|
shun-iwasawa |
b08db1 |
context->setShareContext(QOpenGLContext::currentContext());
|
|
shun_iwasawa |
7e52a2 |
context->setFormat(QSurfaceFormat::defaultFormat());
|
|
shun_iwasawa |
7e52a2 |
context->create();
|
|
shun_iwasawa |
7e52a2 |
context->makeCurrent(info.m_offScreenSurface.get());
|
|
shun_iwasawa |
7e52a2 |
|
|
shun_iwasawa |
7e52a2 |
TDimension d = tile.getRaster()->getSize();
|
|
shun_iwasawa |
7e52a2 |
QOpenGLFramebufferObject fb(d.lx, d.ly);
|
|
shun_iwasawa |
7e52a2 |
|
|
shun_iwasawa |
7e52a2 |
fb.bind();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Load texture into the context
|
|
Shinya Kitaoka |
120a6e |
TTexturesStorage *ts = TTexturesStorage::instance();
|
|
Shinya Kitaoka |
120a6e |
const DrawableTextureDataP &texData = ts->loadTexture(texId, tex, bbox);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw
|
|
shun_iwasawa |
7e52a2 |
glViewport(0, 0, d.lx, d.ly);
|
|
shun_iwasawa |
7e52a2 |
glClearColor(0, 0, 0, 0);
|
|
shun_iwasawa |
7e52a2 |
glClear(GL_COLOR_BUFFER_BIT);
|
|
shun_iwasawa |
7e52a2 |
|
|
shun_iwasawa |
7e52a2 |
glMatrixMode(GL_PROJECTION);
|
|
shun_iwasawa |
7e52a2 |
glLoadIdentity();
|
|
shun_iwasawa |
7e52a2 |
gluOrtho2D(0, d.lx, 0, d.ly);
|
|
shun_iwasawa |
7e52a2 |
|
|
shun_iwasawa |
7e52a2 |
glMatrixMode(GL_MODELVIEW);
|
|
shun_iwasawa |
7e52a2 |
glLoadIdentity();
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(TTranslation(-tile.m_pos) * info.m_affine *
|
|
Shinya Kitaoka |
120a6e |
meshToWorldMeshAff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_TEXTURE_2D);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tglDraw(*mi, *texData, meshToTextureAff, *dataGroup);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve drawing and copy to output tile
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun_iwasawa |
7e52a2 |
QImage img = fb.toImage().scaled(QSize(d.lx, d.ly), Qt::IgnoreAspectRatio,
|
|
shun_iwasawa |
7e52a2 |
Qt::SmoothTransformation);
|
|
shun_iwasawa |
7e52a2 |
int wrap = tile.getRaster()->getLx() * sizeof(TPixel32);
|
|
shun_iwasawa |
7e52a2 |
uchar *srcPix = img.bits();
|
|
shun_iwasawa |
7e52a2 |
uchar *dstPix = tile.getRaster()->getRawData() + wrap * (d.ly - 1);
|
|
shun_iwasawa |
7e52a2 |
for (int y = 0; y < d.ly; y++) {
|
|
shun_iwasawa |
7e52a2 |
memcpy(dstPix, srcPix, wrap);
|
|
shun_iwasawa |
7e52a2 |
dstPix -= wrap;
|
|
shun_iwasawa |
7e52a2 |
srcPix += wrap;
|
|
shun_iwasawa |
7e52a2 |
}
|
|
shun_iwasawa |
7e52a2 |
fb.release();
|
|
shun_iwasawa |
7e52a2 |
|
|
shun_iwasawa |
7e52a2 |
// context->getRaster(tile.getRaster());
|
|
shun_iwasawa |
7e52a2 |
glFlush();
|
|
shun_iwasawa |
7e52a2 |
glFinish();
|
|
Shinya Kitaoka |
120a6e |
// Cleanup
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// No need to disable stuff - the context dies here
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ts->unloadTexture(texId); // Auto-released
|
|
Shinya Kitaoka |
120a6e |
// due to display list destruction
|
|
shun_iwasawa |
7e52a2 |
context->deleteLater();
|
|
shun_iwasawa |
7e52a2 |
// context->doneCurrent();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun_iwasawa |
7e52a2 |
assert(glGetError() == GL_NO_ERROR);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void PlasticDeformerFx::doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_port.isConnected()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int row = (int)frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings texInfo(info);
|
|
Shinya Kitaoka |
120a6e |
TAffine worldTexLevelToTexLevelAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dynamic_cast<tlevelcolumnfx *="">(m_port.getFx())) {</tlevelcolumnfx>
|
|
Shinya Kitaoka |
120a6e |
if (!buildTextureDataSl(frame, texInfo, worldTexLevelToTexLevelAff)) return;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
buildTextureData(frame, texInfo, worldTexLevelToTexLevelAff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TXshCell &meshCell = m_xsh->getCell(row, m_col);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *meshSl = meshCell.getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
const TFrameId &meshFid = meshCell.getFrameId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!meshSl || meshSl->getType() == MESH_XSHLEVEL) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStageObject *meshColumnObj =
|
|
Shinya Kitaoka |
120a6e |
m_xsh->getStageObject(TStageObjectId::ColumnId(m_col));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TMeshImageP mi(meshSl->getFrame(meshFid, false));
|
|
Shinya Kitaoka |
120a6e |
if (!mi) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PlasticSkeletonDeformationP &sd =
|
|
Shinya Kitaoka |
120a6e |
meshColumnObj->getPlasticSkeletonDeformation();
|
|
Shinya Kitaoka |
120a6e |
assert(sd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD meshDpi(meshSl->getDpi(meshFid, 0));
|
|
Shinya Kitaoka |
120a6e |
assert(meshDpi.x != 0.0 && meshDpi.y != 0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &textureToImageAff = texInfo.m_affine;
|
|
Shinya Kitaoka |
120a6e |
const TAffine &worldImageToWorldMeshAff = m_texPlacement;
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToWorldMeshAff =
|
|
Shinya Kitaoka |
120a6e |
TScale(Stage::inch / meshDpi.x, Stage::inch / meshDpi.y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToTextureAff =
|
|
Shinya Kitaoka |
120a6e |
textureToImageAff.inv() * worldTexLevelToTexLevelAff *
|
|
Shinya Kitaoka |
120a6e |
worldImageToWorldMeshAff.inv() * meshToWorldMeshAff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Build the mesh's bounding box and map it to input reference
|
|
Shinya Kitaoka |
120a6e |
TRectD meshBBox(meshToTextureAff * mi->getBBox());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Now, build the tile's geometry
|
|
Shinya Kitaoka |
120a6e |
TRectD texBBox;
|
|
Shinya Kitaoka |
120a6e |
m_port->getBBox(frame, texBBox, texInfo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = texBBox * meshBBox;
|
|
Shinya Kitaoka |
120a6e |
if (bbox.getLx() <= 0.0 || bbox.getLy() <= 0.0) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bbox.x0 = tfloor(bbox.x0);
|
|
Shinya Kitaoka |
120a6e |
bbox.y0 = tfloor(bbox.y0);
|
|
Shinya Kitaoka |
120a6e |
bbox.x1 = tceil(bbox.x1);
|
|
Shinya Kitaoka |
120a6e |
bbox.y1 = tceil(bbox.y1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_port->dryCompute(bbox, frame, texInfo);
|
|
Toshihiro Shimizu |
890ddd |
}
|