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): Bob Holcomb 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include "node_composite_util.h" 00034 00035 /* ******************* channel Distance Matte ********************************* */ 00036 static bNodeSocketTemplate cmp_node_distance_matte_in[]={ 00037 {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, 00038 {SOCK_RGBA,1,"Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, 00039 {-1,0,""} 00040 }; 00041 00042 static bNodeSocketTemplate cmp_node_distance_matte_out[]={ 00043 {SOCK_RGBA,0,"Image"}, 00044 {SOCK_FLOAT,0,"Matte"}, 00045 {-1,0,""} 00046 }; 00047 00048 /* note, keyvals is passed on from caller as stack array */ 00049 /* might have been nicer as temp struct though... */ 00050 static void do_distance_matte(bNode *node, float *out, float *in) 00051 { 00052 NodeChroma *c= (NodeChroma *)node->storage; 00053 float tolerence=c->t1; 00054 float falloff=c->t2; 00055 float distance; 00056 float alpha; 00057 00058 distance=sqrt((c->key[0]-in[0])*(c->key[0]-in[0]) + 00059 (c->key[1]-in[1])*(c->key[1]-in[1]) + 00060 (c->key[2]-in[2])*(c->key[2]-in[2])); 00061 00062 copy_v3_v3(out, in); 00063 00064 /*make 100% transparent */ 00065 if(distance < tolerence) { 00066 out[3]=0.0; 00067 } 00068 /*in the falloff region, make partially transparent */ 00069 else if(distance < falloff+tolerence){ 00070 distance=distance-tolerence; 00071 alpha=distance/falloff; 00072 /*only change if more transparent than before */ 00073 if(alpha < in[3]) { 00074 out[3]=alpha; 00075 } 00076 else { /* leave as before */ 00077 out[3]=in[3]; 00078 } 00079 } 00080 else { 00081 out[3]=in[3]; 00082 } 00083 } 00084 00085 static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00086 { 00087 /* 00088 Loosely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and 00089 uses a different difference function (suggested in forums of vfxtalk.com). 00090 */ 00091 CompBuf *workbuf; 00092 CompBuf *inbuf; 00093 NodeChroma *c; 00094 00095 /*is anything connected?*/ 00096 if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; 00097 /*must have an image imput*/ 00098 if(in[0]->data==NULL) return; 00099 00100 inbuf=typecheck_compbuf(in[0]->data, CB_RGBA); 00101 00102 c=node->storage; 00103 workbuf=dupalloc_compbuf(inbuf); 00104 00105 /*use the input color*/ 00106 c->key[0]= in[1]->vec[0]; 00107 c->key[1]= in[1]->vec[1]; 00108 c->key[2]= in[1]->vec[2]; 00109 00110 /* note, processor gets a keyvals array passed on as buffer constant */ 00111 composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA); 00112 00113 00114 out[0]->data=workbuf; 00115 if(out[1]->hasoutput) 00116 out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A); 00117 generate_preview(data, node, workbuf); 00118 00119 if(inbuf!=in[0]->data) 00120 free_compbuf(inbuf); 00121 } 00122 00123 static void node_composit_init_distance_matte(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) 00124 { 00125 NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); 00126 node->storage= c; 00127 c->t1= 0.1f; 00128 c->t2= 0.1f; 00129 } 00130 00131 void register_node_type_cmp_distance_matte(bNodeTreeType *ttype) 00132 { 00133 static bNodeType ntype; 00134 00135 node_type_base(ttype, &ntype, CMP_NODE_DIST_MATTE, "Distance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS); 00136 node_type_socket_templates(&ntype, cmp_node_distance_matte_in, cmp_node_distance_matte_out); 00137 node_type_size(&ntype, 200, 80, 250); 00138 node_type_init(&ntype, node_composit_init_distance_matte); 00139 node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); 00140 node_type_exec(&ntype, node_composit_exec_distance_matte); 00141 00142 nodeRegisterType(ttype, &ntype); 00143 }