36
36
/* **************** Displace ******************** */
38
static bNodeSocketTemplate cmp_node_displace_in[]= {
39
{ SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f},
40
{ SOCK_VECTOR, 1, "Vector", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_TRANSLATION},
41
{ SOCK_FLOAT, 1, "X Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR},
42
{ SOCK_FLOAT, 1, "Y Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR},
45
static bNodeSocketTemplate cmp_node_displace_out[]= {
46
{ SOCK_RGBA, 0, "Image"},
50
/* minimum distance (in pixels) a pixel has to be displaced
51
* in order to take effect */
52
#define DISPLACE_EPSILON 0.01f
54
static void do_displace(bNode *node, CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *UNUSED(veccol), CompBuf *xbuf, CompBuf *ybuf, float *xscale, float *yscale)
58
float p_dx, p_dy; /* main displacement in pixel space */
63
float vec[3], vecdx[3], vecdy[3];
66
ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
67
ibuf->rect_float= cbuf->rect;
69
for (y=0; y < stackbuf->y; y++) {
70
for (x=0; x < stackbuf->x; x++) {
71
/* calc pixel coordinates */
72
qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof, vec);
75
qd_getPixel(xbuf, x-xbuf->xof, y-xbuf->yof, &xs);
80
qd_getPixel(ybuf, x-ybuf->xof, y-ybuf->yof, &ys);
84
/* clamp x and y displacement to triple image resolution -
85
* to prevent hangs from huge values mistakenly plugged in eg. z buffers */
86
CLAMP(xs, -stackbuf->x*4, stackbuf->x*4);
87
CLAMP(ys, -stackbuf->y*4, stackbuf->y*4);
92
/* if no displacement, then just copy this pixel */
93
if (fabsf(p_dx) < DISPLACE_EPSILON && fabsf(p_dy) < DISPLACE_EPSILON) {
94
qd_getPixel(cbuf, x-cbuf->xof, y-cbuf->yof, col);
95
qd_setPixel(stackbuf, x, y, col);
99
/* displaced pixel in uv coords, for image sampling */
100
u = (x - cbuf->xof - p_dx + 0.5f) / (float)stackbuf->x;
101
v = (y - cbuf->yof - p_dy + 0.5f) / (float)stackbuf->y;
104
/* calc derivatives */
105
qd_getPixel(vecbuf, x-vecbuf->xof+1, y-vecbuf->yof, vecdx);
106
qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof+1, vecdy);
107
d_dx = vecdx[0] * xs;
108
d_dy = vecdy[0] * ys;
110
/* clamp derivatives to minimum displacement distance in UV space */
114
dxt = signf(dxt)*maxf(fabsf(dxt), DISPLACE_EPSILON)/(float)stackbuf->x;
115
dyt = signf(dyt)*maxf(fabsf(dyt), DISPLACE_EPSILON)/(float)stackbuf->y;
117
ibuf_sample(ibuf, u, v, dxt, dyt, col);
118
qd_setPixel(stackbuf, x, y, col);
120
if (node->exec & NODE_BREAK) break;
123
if (node->exec & NODE_BREAK) break;
128
/* simple method for reference, linear interpolation */
136
for (y=0; y < stackbuf->y; y++) {
137
for (x=0; x < stackbuf->x; x++) {
138
qd_getPixel(vecbuf, x, y, vec);
140
dx = vec[0] * (xscale[0]);
141
dy = vec[1] * (yscale[0]);
143
u = (x - dx + 0.5f) / (float)stackbuf->x;
144
v = (y - dy + 0.5f) / (float)stackbuf->y;
146
qd_getPixelLerp(cbuf, u*cbuf->x - 0.5f, v*cbuf->y - 0.5f, col);
147
qd_setPixel(stackbuf, x, y, col);
154
static void node_composit_exec_displace(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
156
if (out[0]->hasoutput==0)
159
if (in[0]->data && in[1]->data) {
160
CompBuf *cbuf= in[0]->data;
161
CompBuf *vecbuf= in[1]->data;
162
CompBuf *xbuf= in[2]->data;
163
CompBuf *ybuf= in[3]->data;
166
cbuf= typecheck_compbuf(cbuf, CB_RGBA);
167
vecbuf= typecheck_compbuf(vecbuf, CB_VEC3);
168
xbuf= typecheck_compbuf(xbuf, CB_VAL);
169
ybuf= typecheck_compbuf(ybuf, CB_VAL);
171
stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
173
do_displace(node, stackbuf, cbuf, vecbuf, in[1]->vec, xbuf, ybuf, in[2]->vec, in[3]->vec);
175
out[0]->data= stackbuf;
178
if (cbuf!=in[0]->data)
180
if (vecbuf!=in[1]->data)
181
free_compbuf(vecbuf);
38
static bNodeSocketTemplate cmp_node_displace_in[] = {
39
{ SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f},
40
{ SOCK_VECTOR, 1, N_("Vector"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_TRANSLATION},
41
{ SOCK_FLOAT, 1, N_("X Scale"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR},
42
{ SOCK_FLOAT, 1, N_("Y Scale"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR},
45
static bNodeSocketTemplate cmp_node_displace_out[] = {
46
{ SOCK_RGBA, 0, N_("Image")},
185
50
void register_node_type_cmp_displace(bNodeTreeType *ttype)