Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor/operations/COM_MapUVOperation.cpp')
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp
new file mode 100644
index 00000000000..ef0c9004a7d
--- /dev/null
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Dalai Felinto
+ */
+
+#include "COM_MapUVOperation.h"
+#include "BLI_math.h"
+
+MapUVOperation::MapUVOperation(): NodeOperation() {
+ this->addInputSocket(COM_DT_COLOR);
+ this->addInputSocket(COM_DT_VECTOR);
+ this->addOutputSocket(COM_DT_COLOR);
+ this->alpha = 0.f;
+ this->setComplex(true);
+
+ this->inputUVProgram = NULL;
+ this->inputColorProgram = NULL;
+}
+
+void MapUVOperation::initExecution() {
+ this->inputColorProgram = this->getInputSocketReader(0);
+ this->inputUVProgram = this->getInputSocketReader(1);
+}
+
+void MapUVOperation::executePixel(float* color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) {
+ float inputUV[4];
+ float uv_a[4], uv_b[4];
+ float u,v;
+
+ float dx, dy;
+ float uv_l, uv_r;
+ float uv_u, uv_d;
+
+ this->inputUVProgram->read(inputUV, x, y, sampler, inputBuffers);
+ if (inputUV[2] == 0.f) {
+ color[0] = 0.f;
+ color[1] = 0.f;
+ color[2] = 0.f;
+ color[3] = 0.f;
+ return;
+ }
+ /* adaptive sampling, red (U) channel */
+ this->inputUVProgram->read(uv_a, x-1, y, COM_PS_NEAREST, inputBuffers);
+ this->inputUVProgram->read(uv_b, x+1, y, COM_PS_NEAREST, inputBuffers);
+ uv_l= uv_a[2]!=0.f? fabs(inputUV[0] - uv_a[0]) : 0.f;
+ uv_r= uv_b[2]!=0.f? fabs(inputUV[0] - uv_b[0]) : 0.f;
+
+ dx= 0.5f * (uv_l + uv_r);
+
+ /* adaptive sampling, green (V) channel */
+ this->inputUVProgram->read(uv_a, x, y-1, COM_PS_NEAREST, inputBuffers);
+ this->inputUVProgram->read(uv_b, x, y+1, COM_PS_NEAREST, inputBuffers);
+ uv_u= uv_a[2]!=0.f? fabs(inputUV[1] - uv_a[1]) : 0.f;
+ uv_d= uv_b[2]!=0.f? fabs(inputUV[1] - uv_b[1]) : 0.f;
+
+ dy= 0.5f * (uv_u + uv_d);
+
+ /* more adaptive sampling, red and green (UV) channels */
+ this->inputUVProgram->read(uv_a, x-1, y-1, COM_PS_NEAREST, inputBuffers);
+ this->inputUVProgram->read(uv_b, x-1, y+1, COM_PS_NEAREST, inputBuffers);
+ uv_l= uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f;
+ uv_r= uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f;
+ uv_u= uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f;
+ uv_d= uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f;
+
+ dx+= 0.25f * (uv_l + uv_r);
+ dy+= 0.25f * (uv_u + uv_d);
+
+ this->inputUVProgram->read(uv_a, x+1, y-1, COM_PS_NEAREST, inputBuffers);
+ this->inputUVProgram->read(uv_b, x+1, y+1, COM_PS_NEAREST, inputBuffers);
+ uv_l= uv_a[2]!=0.f? fabsf(inputUV[0] - uv_a[0]) : 0.f;
+ uv_r= uv_b[2]!=0.f? fabsf(inputUV[0] - uv_b[0]) : 0.f;
+ uv_u= uv_a[2]!=0.f? fabsf(inputUV[1] - uv_a[1]) : 0.f;
+ uv_d= uv_b[2]!=0.f? fabsf(inputUV[1] - uv_b[1]) : 0.f;
+
+ dx+= 0.25f * (uv_l + uv_r);
+ dy+= 0.25f * (uv_u + uv_d);
+
+ /* UV to alpha threshold */
+ const float threshold = this->alpha * 0.05f;
+ float alpha = 1.0f - threshold * (dx + dy);
+ if (alpha < 0.f) alpha= 0.f;
+ else alpha *= inputUV[2];
+
+ /* should use mipmap */
+ dx= min(dx, 0.2f);
+ dy= min(dy, 0.2f);
+
+
+ /* EWA filtering */
+ u = inputUV[0] * inputColorProgram->getWidth();
+ v = inputUV[1] * inputColorProgram->getHeight();
+
+ this->inputColorProgram->read(color, u, v, dx, dy, inputBuffers);
+
+ /* "premul" */
+ if(alpha < 1.0f) {
+ color[0]*= alpha;
+ color[1]*= alpha;
+ color[2]*= alpha;
+ color[3]*= alpha;
+ }
+}
+
+void MapUVOperation::deinitExecution() {
+ this->inputUVProgram = NULL;
+ this->inputColorProgram = NULL;
+}
+
+bool MapUVOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) {
+ rcti colorInput;
+ rcti uvInput;
+ NodeOperation *operation=NULL;
+
+ /* the uv buffer only needs a 3x3 buffer. The image needs whole buffer */
+
+ operation = getInputOperation(0);
+ colorInput.xmax = operation->getWidth();
+ colorInput.xmin = 0;
+ colorInput.ymax = operation->getHeight();
+ colorInput.ymin = 0;
+ if (operation->determineDependingAreaOfInterest(&colorInput, readOperation, output)) {
+ return true;
+ }
+
+ operation = getInputOperation(1);
+ uvInput.xmax = input->xmax + 1;
+ uvInput.xmin = input->xmin - 1;
+ uvInput.ymax = input->ymax + 1;
+ uvInput.ymin = input->ymin - 1;
+ if (operation->determineDependingAreaOfInterest(&uvInput, readOperation, output)) {
+ return true;
+ }
+
+ return false;
+}
+