Merge branch 'blender-v2.82-release'
[blender.git] / source / blender / compositor / operations / COM_DifferenceMatteOperation.cpp
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2011, Blender Foundation.
17  */
18
19 #include "COM_DifferenceMatteOperation.h"
20 #include "BLI_math.h"
21
22 DifferenceMatteOperation::DifferenceMatteOperation() : NodeOperation()
23 {
24   addInputSocket(COM_DT_COLOR);
25   addInputSocket(COM_DT_COLOR);
26   addOutputSocket(COM_DT_VALUE);
27
28   this->m_inputImage1Program = NULL;
29   this->m_inputImage2Program = NULL;
30 }
31
32 void DifferenceMatteOperation::initExecution()
33 {
34   this->m_inputImage1Program = this->getInputSocketReader(0);
35   this->m_inputImage2Program = this->getInputSocketReader(1);
36 }
37 void DifferenceMatteOperation::deinitExecution()
38 {
39   this->m_inputImage1Program = NULL;
40   this->m_inputImage2Program = NULL;
41 }
42
43 void DifferenceMatteOperation::executePixelSampled(float output[4],
44                                                    float x,
45                                                    float y,
46                                                    PixelSampler sampler)
47 {
48   float inColor1[4];
49   float inColor2[4];
50
51   const float tolerance = this->m_settings->t1;
52   const float falloff = this->m_settings->t2;
53   float difference;
54   float alpha;
55
56   this->m_inputImage1Program->readSampled(inColor1, x, y, sampler);
57   this->m_inputImage2Program->readSampled(inColor2, x, y, sampler);
58
59   difference = (fabsf(inColor2[0] - inColor1[0]) + fabsf(inColor2[1] - inColor1[1]) +
60                 fabsf(inColor2[2] - inColor1[2]));
61
62   /* average together the distances */
63   difference = difference / 3.0f;
64
65   /* make 100% transparent */
66   if (difference <= tolerance) {
67     output[0] = 0.0f;
68   }
69   /*in the falloff region, make partially transparent */
70   else if (difference <= falloff + tolerance) {
71     difference = difference - tolerance;
72     alpha = difference / falloff;
73     /*only change if more transparent than before */
74     if (alpha < inColor1[3]) {
75       output[0] = alpha;
76     }
77     else { /* leave as before */
78       output[0] = inColor1[3];
79     }
80   }
81   else {
82     /* foreground object */
83     output[0] = inColor1[3];
84   }
85 }