particlesfx : use 16bpc control image for gradient
This commit is contained in:
parent
5d866328ea
commit
3b3c1b2fa1
4 changed files with 136 additions and 94 deletions
|
@ -150,12 +150,14 @@ Particle::Particle(int g_lifetime, int seed, std::map<int, TTile *> porttiles,
|
||||||
|
|
||||||
/*- Speed Angleの制御。RangeモードとGradientモードがある -*/
|
/*- Speed Angleの制御。RangeモードとGradientモードがある -*/
|
||||||
if (values.speeda_ctrl_val &&
|
if (values.speeda_ctrl_val &&
|
||||||
(porttiles.find(values.speeda_ctrl_val) != porttiles.end())) {
|
(porttiles.find(values.speeda_ctrl_val) != porttiles.end() ||
|
||||||
|
porttiles.find(values.speeda_ctrl_val + Ctrl_64_Offset) !=
|
||||||
|
porttiles.end())) {
|
||||||
if (values.speeda_use_gradient_val) {
|
if (values.speeda_use_gradient_val) {
|
||||||
/*- 参照画像のGradientを得る関数を利用して角度を得る -*/
|
/*- 参照画像のGradientを得る関数を利用して角度を得る -*/
|
||||||
float dir_x, dir_y;
|
float dir_x, dir_y;
|
||||||
get_image_gravity(porttiles[values.speeda_ctrl_val], values, dir_x,
|
get_image_gravity(porttiles[values.speeda_ctrl_val + Ctrl_64_Offset],
|
||||||
dir_y);
|
values, dir_x, dir_y);
|
||||||
if (dir_x == 0.0f && dir_y == 0.0f)
|
if (dir_x == 0.0f && dir_y == 0.0f)
|
||||||
random_s_a_range = values.speed_val.first;
|
random_s_a_range = values.speed_val.first;
|
||||||
else
|
else
|
||||||
|
@ -558,67 +560,41 @@ void Particle::get_image_reference(TTile *ctrl, const particles_values &values,
|
||||||
/*-----------------------------------------------------------------*/
|
/*-----------------------------------------------------------------*/
|
||||||
void Particle::get_image_gravity(TTile *ctrl1, const particles_values &values,
|
void Particle::get_image_gravity(TTile *ctrl1, const particles_values &values,
|
||||||
float &gx, float &gy) {
|
float &gx, float &gy) {
|
||||||
TRaster32P raster32 = ctrl1->getRaster();
|
TRaster64P raster64 = ctrl1->getRaster();
|
||||||
TPointD tmp(x, y);
|
TPointD tmp(x, y);
|
||||||
tmp -= ctrl1->m_pos;
|
tmp -= ctrl1->m_pos;
|
||||||
int radius = 4;
|
int radius = 2;
|
||||||
gx = 0;
|
gx = 0;
|
||||||
gy = 0;
|
gy = 0;
|
||||||
//#define OLDSTUFF
|
raster64->lock();
|
||||||
#ifdef OLDSTUFF
|
if (raster64 && tmp.x >= radius && tmp.x < raster64->getLx() - radius &&
|
||||||
int i;
|
tmp.y >= radius && tmp.y < raster64->getLy() - radius) {
|
||||||
#endif
|
TPixel64 *pix = &(raster64->pixels(troundp(tmp.y))[(int)tmp.x]);
|
||||||
raster32->lock();
|
|
||||||
#ifdef OLDSTUFF
|
|
||||||
if (!values.gravity_radius_val) {
|
|
||||||
radius = 4;
|
|
||||||
if (raster32 && tmp.x >= radius && tmp.x < raster32->getLx() - radius &&
|
|
||||||
tmp.y >= radius && tmp.y < raster32->getLy() - radius) {
|
|
||||||
TPixel32 *pix = &(raster32->pixels(troundp(tmp.y))[(int)tmp.x]);
|
|
||||||
double norm = 1 / ((double)TPixelGR8::maxChannelValue);
|
|
||||||
for (i = 1; i < radius; i++) {
|
|
||||||
gx += TPixelGR8::from(*(pix + i)).value;
|
|
||||||
gx -= TPixelGR8::from(*(pix - i)).value;
|
|
||||||
gy += TPixelGR8::from(*(pix + raster32->getWrap() * i)).value;
|
|
||||||
gy -= TPixelGR8::from(*(pix - raster32->getWrap() * i)).value;
|
|
||||||
}
|
|
||||||
gx = gx * norm;
|
|
||||||
gy = gy * norm;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
radius = 2;
|
|
||||||
if (raster32 && tmp.x >= radius && tmp.x < raster32->getLx() - radius &&
|
|
||||||
tmp.y >= radius && tmp.y < raster32->getLy() - radius) {
|
|
||||||
TPixel32 *pix = &(raster32->pixels(troundp(tmp.y))[(int)tmp.x]);
|
|
||||||
|
|
||||||
gx += 2 * TPixelGR8::from(*(pix + 1)).value;
|
gx += 2 * TPixelGR16::from(*(pix + 1)).value;
|
||||||
gx += TPixelGR8::from(*(pix + 1 + raster32->getWrap() * 1)).value;
|
gx += TPixelGR16::from(*(pix + 1 + raster64->getWrap() * 1)).value;
|
||||||
gx += TPixelGR8::from(*(pix + 1 - raster32->getWrap() * 1)).value;
|
gx += TPixelGR16::from(*(pix + 1 - raster64->getWrap() * 1)).value;
|
||||||
|
|
||||||
gx -= 2 * TPixelGR8::from(*(pix - 1)).value;
|
gx -= 2 * TPixelGR16::from(*(pix - 1)).value;
|
||||||
gx -= TPixelGR8::from(*(pix - 1 + raster32->getWrap() * 1)).value;
|
gx -= TPixelGR16::from(*(pix - 1 + raster64->getWrap() * 1)).value;
|
||||||
gx -= TPixelGR8::from(*(pix - 1 - raster32->getWrap() * 1)).value;
|
gx -= TPixelGR16::from(*(pix - 1 - raster64->getWrap() * 1)).value;
|
||||||
|
|
||||||
gy += 2 * TPixelGR8::from(*(pix + raster32->getWrap() * 1)).value;
|
gy += 2 * TPixelGR16::from(*(pix + raster64->getWrap() * 1)).value;
|
||||||
gy += TPixelGR8::from(*(pix + raster32->getWrap() * 1 + 1)).value;
|
gy += TPixelGR16::from(*(pix + raster64->getWrap() * 1 + 1)).value;
|
||||||
gy += TPixelGR8::from(*(pix + raster32->getWrap() * 1 - 1)).value;
|
gy += TPixelGR16::from(*(pix + raster64->getWrap() * 1 - 1)).value;
|
||||||
|
|
||||||
gy -= 2 * TPixelGR8::from(*(pix - raster32->getWrap() * 1)).value;
|
gy -= 2 * TPixelGR16::from(*(pix - raster64->getWrap() * 1)).value;
|
||||||
gy -= TPixelGR8::from(*(pix - raster32->getWrap() * 1 + 1)).value;
|
gy -= TPixelGR16::from(*(pix - raster64->getWrap() * 1 + 1)).value;
|
||||||
gy -= TPixelGR8::from(*(pix - raster32->getWrap() * 1 - 1)).value;
|
gy -= TPixelGR16::from(*(pix - raster64->getWrap() * 1 - 1)).value;
|
||||||
|
|
||||||
double norm = sqrt(gx * gx + gy * gy);
|
double norm = std::sqrt(gx * gx + gy * gy);
|
||||||
if (norm) {
|
if (norm) {
|
||||||
double inorm = 0.1 / norm;
|
double inorm = 0.1 / norm;
|
||||||
gx = gx * inorm;
|
gx = gx * inorm;
|
||||||
gy = gy * inorm;
|
gy = gy * inorm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef OLDSTUFF
|
raster64->unlock();
|
||||||
}
|
|
||||||
#endif
|
|
||||||
raster32->unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------*/
|
/*-----------------------------------------------------------------*/
|
||||||
|
@ -701,9 +677,10 @@ void Particle::move(std::map<int, TTile *> porttiles,
|
||||||
// time=genlifetime-lifetime-1;
|
// time=genlifetime-lifetime-1;
|
||||||
// if(time<0) time=0;
|
// if(time<0) time=0;
|
||||||
if (values.gravity_ctrl_val &&
|
if (values.gravity_ctrl_val &&
|
||||||
(porttiles.find(values.gravity_ctrl_val) != porttiles.end())) {
|
(porttiles.find(values.gravity_ctrl_val + Ctrl_64_Offset) !=
|
||||||
get_image_gravity(porttiles[values.gravity_ctrl_val], values, xgravity,
|
porttiles.end())) {
|
||||||
ygravity);
|
get_image_gravity(porttiles[values.gravity_ctrl_val + Ctrl_64_Offset],
|
||||||
|
values, xgravity, ygravity);
|
||||||
xgravity *= values.gravity_val;
|
xgravity *= values.gravity_val;
|
||||||
ygravity *= values.gravity_val;
|
ygravity *= values.gravity_val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "tspectrum.h"
|
#include "tspectrum.h"
|
||||||
#include "trandom.h"
|
#include "trandom.h"
|
||||||
|
|
||||||
|
const int Ctrl_64_Offset = 1000;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct particles_values {
|
struct particles_values {
|
||||||
|
|
|
@ -160,15 +160,31 @@ void Particles_Engine::fill_range_struct(struct particles_values &values,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Particles_Engine::port_is_used(int i, struct particles_values &values) {
|
bool Particles_Engine::port_is_used(int i, struct particles_values &values) {
|
||||||
|
return port_is_used_for_value(i, values) ||
|
||||||
|
port_is_used_for_gradient(i, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the pixel value of control image is used.
|
||||||
|
// Such image will be computed in 8bpc.
|
||||||
|
bool Particles_Engine::port_is_used_for_value(int i,
|
||||||
|
struct particles_values &values) {
|
||||||
return values.fincol_ctrl_val == i || values.foutcol_ctrl_val == i ||
|
return values.fincol_ctrl_val == i || values.foutcol_ctrl_val == i ||
|
||||||
values.friction_ctrl_val == i || values.gencol_ctrl_val == i ||
|
values.friction_ctrl_val == i || values.gencol_ctrl_val == i ||
|
||||||
values.gravity_ctrl_val == i || values.opacity_ctrl_val == i ||
|
values.opacity_ctrl_val == i || values.rot_ctrl_val == i ||
|
||||||
values.rot_ctrl_val == i || values.scale_ctrl_val == i ||
|
values.scale_ctrl_val == i || values.scalestep_ctrl_val == i ||
|
||||||
values.scalestep_ctrl_val == i || values.source_ctrl_val == i ||
|
values.source_ctrl_val == i || values.speed_ctrl_val == i ||
|
||||||
values.speed_ctrl_val == i || values.speeda_ctrl_val == i ||
|
(values.speeda_ctrl_val == i && !values.speeda_use_gradient_val) ||
|
||||||
values.lifetime_ctrl_val == i || values.randomx_ctrl_val == i ||
|
values.lifetime_ctrl_val == i || values.randomx_ctrl_val == i ||
|
||||||
values.randomy_ctrl_val == i;
|
values.randomy_ctrl_val == i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if the gradient of control image is used.
|
||||||
|
// Such image will be computed in 16bpc to get smooth result.
|
||||||
|
bool Particles_Engine::port_is_used_for_gradient(
|
||||||
|
int i, struct particles_values &values) {
|
||||||
|
return values.gravity_ctrl_val == i ||
|
||||||
|
(values.speeda_ctrl_val == i && values.speeda_use_gradient_val);
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------*/
|
/*-----------------------------------------------------------------*/
|
||||||
/*-- Startフレームからカレントフレームまで順番に回す関数 --*/
|
/*-- Startフレームからカレントフレームまで順番に回す関数 --*/
|
||||||
void Particles_Engine::roll_particles(
|
void Particles_Engine::roll_particles(
|
||||||
|
@ -492,6 +508,9 @@ void Particles_Engine::render_particles(
|
||||||
TRenderSettings riAux(ri);
|
TRenderSettings riAux(ri);
|
||||||
riAux.m_affine = TAffine();
|
riAux.m_affine = TAffine();
|
||||||
riAux.m_bpp = 32;
|
riAux.m_bpp = 32;
|
||||||
|
// control image using its gradient is computed in 64bpp
|
||||||
|
TRenderSettings riAux64(riAux);
|
||||||
|
riAux64.m_bpp = 64;
|
||||||
|
|
||||||
int r_frame; // Useful in case of negative roll frames
|
int r_frame; // Useful in case of negative roll frames
|
||||||
if (frame < 0)
|
if (frame < 0)
|
||||||
|
@ -538,6 +557,47 @@ void Particles_Engine::render_particles(
|
||||||
// dryComputed - so, declare the same here.
|
// dryComputed - so, declare the same here.
|
||||||
(*it->second)->dryCompute(bbox, r_frame, riAux);
|
(*it->second)->dryCompute(bbox, r_frame, riAux);
|
||||||
} else {
|
} else {
|
||||||
|
// control image is used its gradient
|
||||||
|
if (port_is_used_for_gradient(it->first, values)) {
|
||||||
|
tmp = new TTile;
|
||||||
|
|
||||||
|
if (isPrecomputingEnabled)
|
||||||
|
(*it->second)
|
||||||
|
->allocateAndCompute(*tmp, bbox.getP00(),
|
||||||
|
convert(bbox).getSize(), 0, r_frame,
|
||||||
|
riAux64);
|
||||||
|
else {
|
||||||
|
std::string alias =
|
||||||
|
"CTRL64: " + (*(it->second))->getAlias(r_frame, riAux64);
|
||||||
|
TRasterImageP rimg = TImageCache::instance()->get(alias, false);
|
||||||
|
|
||||||
|
if (rimg) {
|
||||||
|
tmp->m_pos = bbox.getP00();
|
||||||
|
tmp->setRaster(rimg->getRaster());
|
||||||
|
} else {
|
||||||
|
(*it->second)
|
||||||
|
->allocateAndCompute(*tmp, bbox.getP00(),
|
||||||
|
convert(bbox).getSize(), 0, r_frame,
|
||||||
|
riAux64);
|
||||||
|
|
||||||
|
addRenderCache(alias, TRasterImageP(tmp->getRaster()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
porttiles[it->first + Ctrl_64_Offset] = tmp;
|
||||||
|
|
||||||
|
// in case the control image is also used for non-gradient
|
||||||
|
if (port_is_used_for_value(it->first, values)) {
|
||||||
|
TRaster32P tileRas(tmp->getRaster()->getSize());
|
||||||
|
TRop::convert(tileRas, tmp->getRaster());
|
||||||
|
tmp = new TTile;
|
||||||
|
tmp->m_pos = bbox.getP00();
|
||||||
|
tmp->setRaster(tileRas);
|
||||||
|
porttiles[it->first] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// control images used only for non-gradient
|
||||||
|
else {
|
||||||
tmp = new TTile;
|
tmp = new TTile;
|
||||||
|
|
||||||
if (isPrecomputingEnabled)
|
if (isPrecomputingEnabled)
|
||||||
|
@ -568,6 +628,7 @@ void Particles_Engine::render_particles(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (frame > pcFrame) {
|
if (frame > pcFrame) {
|
||||||
// Invoke the actual rolling procedure
|
// Invoke the actual rolling procedure
|
||||||
|
|
|
@ -52,6 +52,8 @@ public:
|
||||||
std::map<std::pair<int, int>, double> &partScales);
|
std::map<std::pair<int, int>, double> &partScales);
|
||||||
|
|
||||||
bool port_is_used(int i, struct particles_values &values);
|
bool port_is_used(int i, struct particles_values &values);
|
||||||
|
bool port_is_used_for_value(int i, struct particles_values &values);
|
||||||
|
bool port_is_used_for_gradient(int i, struct particles_values &values);
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
do_source_gradationがONのとき、入力画像のアルファ値に比例して発生濃度を変える。
|
do_source_gradationがONのとき、入力画像のアルファ値に比例して発生濃度を変える。
|
||||||
|
|
Loading…
Reference in a new issue