Camera tracking integration
[blender.git] / source / blender / nodes / composite / nodes / node_composite_movieclip.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Blender Foundation,
24  *                 Sergey Sharybin
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/nodes/composite/nodes/node_composite_movieclip.c
30  *  \ingroup cmpnodes
31  */
32
33
34 #include "node_composite_util.h"
35
36 static bNodeSocketTemplate cmp_node_movieclip_out[]= {
37         {       SOCK_RGBA,              0,      "Image"},
38         {       SOCK_FLOAT,             1,      "Offset X"},
39         {       SOCK_FLOAT,             1,      "Offset Y"},
40         {       SOCK_FLOAT,             1,      "Scale"},
41         {       SOCK_FLOAT,             1,      "Angle"},
42         {       -1, 0, ""       }
43 };
44
45 static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user)
46 {
47         ImBuf *ibuf;
48         CompBuf *stackbuf;
49         int type;
50
51         float *rect;
52         int alloc= FALSE;
53
54         ibuf= BKE_movieclip_get_ibuf(clip, user);
55
56         if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
57                 IMB_freeImBuf(ibuf);
58                 return NULL;
59         }
60
61         if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) {
62                 IMB_float_from_rect(ibuf);
63                 ibuf->userflags&= ~IB_RECT_INVALID;
64         }
65
66         /* now we need a float buffer from the image with matching color management */
67         if(ibuf->channels == 4) {
68                 rect= node_composit_get_float_buffer(rd, ibuf, &alloc);
69         }
70         else {
71                 /* non-rgba passes can't use color profiles */
72                 rect= ibuf->rect_float;
73         }
74         /* done coercing into the correct color management */
75
76         if(!alloc) {
77                 rect= MEM_dupallocN(rect);
78                 alloc= 1;
79         }
80
81         type= ibuf->channels;
82
83         if(rd->scemode & R_COMP_CROP) {
84                 stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
85                 if(alloc)
86                         MEM_freeN(rect);
87         }
88         else {
89                 /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
90                 stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
91                 stackbuf->rect= rect;
92                 stackbuf->malloc= alloc;
93         }
94
95         IMB_freeImBuf(ibuf);
96
97         return stackbuf;
98 }
99
100 static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
101 {
102         if(node->id) {
103                 RenderData *rd= data;
104                 MovieClip *clip= (MovieClip *)node->id;
105                 MovieClipUser *user= (MovieClipUser *)node->storage;
106                 CompBuf *stackbuf= NULL;
107
108                 BKE_movieclip_user_set_frame(user, rd->cfra);
109
110                 stackbuf= node_composit_get_movieclip(rd, clip, user);
111
112                 if (stackbuf) {
113                         MovieTrackingStabilization *stab= &clip->tracking.stabilization;
114
115                         /* put image on stack */
116                         out[0]->data= stackbuf;
117
118                         if(stab->flag&TRACKING_2D_STABILIZATION) {
119                                 float loc[2], scale, angle;
120
121                                 BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y,
122                                                         loc, &scale, &angle);
123
124                                 out[1]->vec[0]= loc[0];
125                                 out[2]->vec[0]= loc[1];
126
127                                 out[3]->vec[0]= scale;
128                                 out[4]->vec[0]= angle;
129                         }
130
131                         /* generate preview */
132                         generate_preview(data, node, stackbuf);
133                 }
134         }
135 }
136
137 static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
138 {
139         MovieClipUser *user= MEM_callocN(sizeof(MovieClipUser), "node movie clip user");
140
141         node->storage= user;
142         user->framenr= 1;
143 }
144
145 void register_node_type_cmp_movieclip(ListBase *lb)
146 {
147         static bNodeType ntype;
148
149         node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
150         node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out);
151         node_type_size(&ntype, 120, 80, 300);
152         node_type_init(&ntype, init);
153         node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage);
154         node_type_exec(&ntype, node_composit_exec_movieclip);
155
156         nodeRegisterType(lb, &ntype);
157 }