Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2006 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include "node_composite_util.h" 00034 00035 00036 /* **************** Z COMBINE ******************** */ 00037 /* lazy coder note: node->custom2 is abused to send signal */ 00038 static bNodeSocketTemplate cmp_node_zcombine_in[]= { 00039 { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00040 { SOCK_FLOAT, 1, "Z", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, 00041 { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00042 { SOCK_FLOAT, 1, "Z", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, 00043 { -1, 0, "" } 00044 }; 00045 static bNodeSocketTemplate cmp_node_zcombine_out[]= { 00046 { SOCK_RGBA, 0, "Image"}, 00047 { SOCK_FLOAT, 0, "Z"}, 00048 { -1, 0, "" } 00049 }; 00050 00051 static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2) 00052 { 00053 float alpha; 00054 float malpha; 00055 00056 if(*z1 <= *z2) { 00057 if (node->custom1) { 00058 // use alpha in combine operation 00059 alpha= src1[3]; 00060 malpha= 1.0f - alpha; 00061 out[0]= malpha*src2[0] + alpha*src1[0]; 00062 out[1]= malpha*src2[1] + alpha*src1[1]; 00063 out[2]= malpha*src2[2] + alpha*src1[2]; 00064 out[3]= malpha*src2[3] + alpha*src1[3]; 00065 } 00066 else { 00067 // do combination based solely on z value 00068 copy_v4_v4(out, src1); 00069 } 00070 } 00071 else { 00072 if (node->custom1) { 00073 // use alpha in combine operation 00074 alpha= src2[3]; 00075 malpha= 1.0f - alpha; 00076 out[0]= malpha*src1[0] + alpha*src2[0]; 00077 out[1]= malpha*src1[1] + alpha*src2[1]; 00078 out[2]= malpha*src1[2] + alpha*src2[2]; 00079 out[3]= malpha*src1[3] + alpha*src2[3]; 00080 } 00081 else { 00082 // do combination based solely on z value 00083 copy_v4_v4(out, src1); 00084 } 00085 00086 if(node->custom2) 00087 *z1= *z2; 00088 } 00089 } 00090 00091 static void do_zcombine_mask(bNode *node, float *out, float *z1, float *z2) 00092 { 00093 if(*z1 > *z2) { 00094 *out= 1.0f; 00095 if(node->custom2) 00096 *z1= *z2; 00097 } 00098 } 00099 00100 static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, float *acol) 00101 { 00102 float alpha; 00103 float malpha; 00104 00105 if (node->custom1) { 00106 // use alpha in combine operation, antialiased mask in used here just as hint for the z value 00107 if (*acol>0.0f) { 00108 alpha= col2[3]; 00109 malpha= 1.0f - alpha; 00110 00111 00112 out[0]= malpha*col1[0] + alpha*col2[0]; 00113 out[1]= malpha*col1[1] + alpha*col2[1]; 00114 out[2]= malpha*col1[2] + alpha*col2[2]; 00115 out[3]= malpha*col1[3] + alpha*col2[3]; 00116 } 00117 else { 00118 alpha= col1[3]; 00119 malpha= 1.0f - alpha; 00120 00121 00122 out[0]= malpha*col2[0] + alpha*col1[0]; 00123 out[1]= malpha*col2[1] + alpha*col1[1]; 00124 out[2]= malpha*col2[2] + alpha*col1[2]; 00125 out[3]= malpha*col2[3] + alpha*col1[3]; 00126 } 00127 } 00128 else { 00129 // do combination based solely on z value but with antialiased mask 00130 alpha = *acol; 00131 malpha= 1.0f - alpha; 00132 00133 out[0]= malpha*col1[0] + alpha*col2[0]; 00134 out[1]= malpha*col1[1] + alpha*col2[1]; 00135 out[2]= malpha*col1[2] + alpha*col2[2]; 00136 out[3]= malpha*col1[3] + alpha*col2[3]; 00137 } 00138 } 00139 00140 static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00141 { 00142 RenderData *rd= data; 00143 CompBuf *cbuf= in[0]->data; 00144 CompBuf *zbuf; 00145 00146 /* stack order in: col z col z */ 00147 /* stack order out: col z */ 00148 if(out[0]->hasoutput==0 && out[1]->hasoutput==0) 00149 return; 00150 00151 /* no input image; do nothing now */ 00152 if(in[0]->data==NULL) { 00153 return; 00154 } 00155 00156 if(out[1]->hasoutput) { 00157 /* copy or make a buffer for for the first z value, here we write result in */ 00158 if(in[1]->data) 00159 zbuf= dupalloc_compbuf(in[1]->data); 00160 else { 00161 float *zval; 00162 int tot= cbuf->x*cbuf->y; 00163 00164 zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00165 for(zval= zbuf->rect; tot; tot--, zval++) 00166 *zval= in[1]->vec[0]; 00167 } 00168 /* lazy coder hack */ 00169 node->custom2= 1; 00170 out[1]->data= zbuf; 00171 } 00172 else { 00173 node->custom2= 0; 00174 zbuf= in[1]->data; 00175 } 00176 00177 if(rd->scemode & R_FULL_SAMPLE) { 00178 /* make output size of first input image */ 00179 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs 00180 00181 composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, zbuf, in[1]->vec, in[2]->data, in[2]->vec, 00182 in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL); 00183 00184 out[0]->data= stackbuf; 00185 } 00186 else { 00187 /* make output size of first input image */ 00188 CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */ 00189 CompBuf *mbuf; 00190 float *fp; 00191 int x; 00192 char *aabuf; 00193 00194 00195 /* make a mask based on comparison, optionally write zvalue */ 00196 mbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00197 composit2_pixel_processor(node, mbuf, zbuf, in[1]->vec, in[3]->data, in[3]->vec, do_zcombine_mask, CB_VAL, CB_VAL); 00198 00199 /* convert to char */ 00200 aabuf= MEM_mallocN(cbuf->x*cbuf->y, "aa buf"); 00201 fp= mbuf->rect; 00202 for(x= cbuf->x*cbuf->y-1; x>=0; x--) 00203 if(fp[x]==0.0f) aabuf[x]= 0; 00204 else aabuf[x]= 255; 00205 00206 antialias_tagbuf(cbuf->x, cbuf->y, aabuf); 00207 00208 /* convert to float */ 00209 fp= mbuf->rect; 00210 for(x= cbuf->x*cbuf->y-1; x>=0; x--) 00211 if(aabuf[x]>1) 00212 fp[x]= (1.0f/255.0f)*(float)aabuf[x]; 00213 00214 composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[2]->data, in[2]->vec, mbuf, NULL, 00215 do_zcombine_add, CB_RGBA, CB_RGBA, CB_VAL); 00216 /* free */ 00217 free_compbuf(mbuf); 00218 MEM_freeN(aabuf); 00219 00220 out[0]->data= stackbuf; 00221 } 00222 00223 } 00224 00225 void register_node_type_cmp_zcombine(bNodeTreeType *ttype) 00226 { 00227 static bNodeType ntype; 00228 00229 node_type_base(ttype, &ntype, CMP_NODE_ZCOMBINE, "Z Combine", NODE_CLASS_OP_COLOR, NODE_OPTIONS); 00230 node_type_socket_templates(&ntype, cmp_node_zcombine_in, cmp_node_zcombine_out); 00231 node_type_size(&ntype, 80, 40, 120); 00232 node_type_exec(&ntype, node_composit_exec_zcombine); 00233 00234 nodeRegisterType(ttype, &ntype); 00235 }