|
Blender
V2.59
|
00001 /* 00002 * $Id: CMP_distanceMatte.c 36276 2011-04-21 15:53:30Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2006 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): Bob Holcomb 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "../CMP_util.h" 00036 00037 /* ******************* channel Distance Matte ********************************* */ 00038 static bNodeSocketType cmp_node_distance_matte_in[]={ 00039 {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00040 {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00041 {-1,0,""} 00042 }; 00043 00044 static bNodeSocketType cmp_node_distance_matte_out[]={ 00045 {SOCK_RGBA,0,"Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, 00046 {SOCK_VALUE,0,"Matte",0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, 00047 {-1,0,""} 00048 }; 00049 00050 /* note, keyvals is passed on from caller as stack array */ 00051 /* might have been nicer as temp struct though... */ 00052 static void do_distance_matte(bNode *node, float *out, float *in) 00053 { 00054 NodeChroma *c= (NodeChroma *)node->storage; 00055 float tolerence=c->t1; 00056 float falloff=c->t2; 00057 float distance; 00058 float alpha; 00059 00060 distance=sqrt((c->key[0]-in[0])*(c->key[0]-in[0]) + 00061 (c->key[1]-in[1])*(c->key[1]-in[1]) + 00062 (c->key[2]-in[2])*(c->key[2]-in[2])); 00063 00064 VECCOPY(out, in); 00065 00066 /*make 100% transparent */ 00067 if(distance < tolerence) { 00068 out[3]=0.0; 00069 } 00070 /*in the falloff region, make partially transparent */ 00071 else if(distance < falloff+tolerence){ 00072 distance=distance-tolerence; 00073 alpha=distance/falloff; 00074 /*only change if more transparent than before */ 00075 if(alpha < in[3]) { 00076 out[3]=alpha; 00077 } 00078 else { /* leave as before */ 00079 out[3]=in[3]; 00080 } 00081 } 00082 else { 00083 out[3]=in[3]; 00084 } 00085 } 00086 00087 static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out) 00088 { 00089 /* 00090 Loosely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and 00091 uses a different difference function (suggested in forums of vfxtalk.com). 00092 */ 00093 CompBuf *workbuf; 00094 CompBuf *inbuf; 00095 NodeChroma *c; 00096 00097 /*is anything connected?*/ 00098 if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; 00099 /*must have an image imput*/ 00100 if(in[0]->data==NULL) return; 00101 00102 inbuf=typecheck_compbuf(in[0]->data, CB_RGBA); 00103 00104 c=node->storage; 00105 workbuf=dupalloc_compbuf(inbuf); 00106 00107 /*use the input color*/ 00108 c->key[0]= in[1]->vec[0]; 00109 c->key[1]= in[1]->vec[1]; 00110 c->key[2]= in[1]->vec[2]; 00111 00112 /* note, processor gets a keyvals array passed on as buffer constant */ 00113 composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA); 00114 00115 00116 out[0]->data=workbuf; 00117 if(out[1]->hasoutput) 00118 out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A); 00119 generate_preview(data, node, workbuf); 00120 00121 if(inbuf!=in[0]->data) 00122 free_compbuf(inbuf); 00123 } 00124 00125 static void node_composit_init_distance_matte(bNode *node) 00126 { 00127 NodeChroma *c= MEM_callocN(sizeof(NodeChroma), "node chroma"); 00128 node->storage= c; 00129 c->t1= 0.1f; 00130 c->t2= 0.1f; 00131 } 00132 00133 void register_node_type_cmp_distance_matte(ListBase *lb) 00134 { 00135 static bNodeType ntype; 00136 00137 node_type_base(&ntype, CMP_NODE_DIST_MATTE, "Distance Key", NODE_CLASS_MATTE, NODE_PREVIEW|NODE_OPTIONS, 00138 cmp_node_distance_matte_in, cmp_node_distance_matte_out); 00139 node_type_size(&ntype, 200, 80, 250); 00140 node_type_init(&ntype, node_composit_init_distance_matte); 00141 node_type_storage(&ntype, "NodeChroma", node_free_standard_storage, node_copy_standard_storage); 00142 node_type_exec(&ntype, node_composit_exec_distance_matte); 00143 00144 nodeRegisterType(lb, &ntype); 00145 } 00146 00147 00148