diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-06-04 01:11:10 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-06-04 01:11:10 +0400 |
commit | 329b05dcd789bd8421661898697ed060c83b3286 (patch) | |
tree | 3d664826fefbe62078c878baab174e066eb48afa /source/blender/compositor/operations | |
parent | eabf741a8d76aa9400a071c37227504378fc6315 (diff) | |
parent | f9856c1c2da8139651eb59ff3bf174065d0f628c (diff) |
Merged changes in the trunk up to revision 47381.
Conflicts resolved:
source/blender/blenloader/intern/readfile.c
Diffstat (limited to 'source/blender/compositor/operations')
29 files changed, 513 insertions, 1200 deletions
diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp index aedf6ec5e9e..7d489ce856e 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp @@ -27,7 +27,7 @@ AlphaOverMixedOperation::AlphaOverMixedOperation(): MixBaseOperation() this->x = 0.0f; } -void AlphaOverMixedOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) +void AlphaOverMixedOperation::executePixel(float outputValue[4], float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float inputColor1[4]; float inputOverColor[4]; diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index 6e1a7e2a908..babea459d6a 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -37,6 +37,7 @@ BlurBaseOperation::BlurBaseOperation(): NodeOperation() this->data = NULL; this->size = 1.0f; this->deleteData = false; + this->sizeavailable=false; } void BlurBaseOperation::initExecution() { diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h index 13e7eb52b77..24002588413 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -39,6 +39,7 @@ protected: float *make_gausstab(int rad); float size; bool deleteData; + bool sizeavailable; void updateSize(MemoryBuffer **memoryBuffers); public: /** @@ -54,5 +55,7 @@ public: void setData(NodeBlurData *data) {this->data = data;} void deleteDataWhenFinished() {this->deleteData = true;} + + void setSize(float size) {this->size = size; sizeavailable = true;} }; #endif diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp index 56141efe681..9b57d64eb40 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp @@ -40,40 +40,40 @@ void ColorSpillOperation::initExecution() this->inputImageReader = this->getInputSocketReader(0); this->inputFacReader = this->getInputSocketReader(1); if (spillChannel == 0) { - rmut = -1.0f; - gmut = 1.0f; - bmut = 1.0f; + this->rmut = -1.0f; + this->gmut = 1.0f; + this->bmut = 1.0f; this->channel2 = 1; this->channel3 = 2; - if (settings->unspill == 0) { - settings->uspillr = 1.0f; - settings->uspillg = 0.0f; - settings->uspillb = 0.0f; + if (this->settings->unspill == 0) { + this->settings->uspillr = 1.0f; + this->settings->uspillg = 0.0f; + this->settings->uspillb = 0.0f; } } else if (spillChannel == 1) { - rmut = 1.0f; - gmut = -1.0f; - bmut = 1.0f; + this->rmut = 1.0f; + this->gmut = -1.0f; + this->bmut = 1.0f; this->channel2 = 0; this->channel3 = 2; - if (settings->unspill == 0) { - settings->uspillr = 0.0f; - settings->uspillg = 1.0f; - settings->uspillb = 0.0f; + if (this->settings->unspill == 0) { + this->settings->uspillr = 0.0f; + this->settings->uspillg = 1.0f; + this->settings->uspillb = 0.0f; } } else { - rmut = 1.0f; - gmut = 1.0f; - bmut = -1.0f; + this->rmut = 1.0f; + this->gmut = 1.0f; + this->bmut = -1.0f; this->channel2 = 0; this->channel3 = 1; - if (settings->unspill == 0) { - settings->uspillr = 0.0f; - settings->uspillg = 0.0f; - settings->uspillb = 1.0f; + if (this->settings->unspill == 0) { + this->settings->uspillr = 0.0f; + this->settings->uspillg = 0.0f; + this->settings->uspillb = 1.0f; } } } @@ -88,27 +88,23 @@ void ColorSpillOperation::executePixel(float *outputValue, float x, float y, Pix { float fac[4]; float input[4]; - float map; this->inputFacReader->read(fac, x, y, sampler, inputBuffers); this->inputImageReader->read(input, x, y, sampler, inputBuffers); float rfac = min(1.0f, fac[0]); - map = calculateMapValue(rfac, input); - if (map>0) { - outputValue[0]=input[0]+rmut*(settings->uspillr*map); - outputValue[1]=input[1]+gmut*(settings->uspillg*map); - outputValue[2]=input[2]+bmut*(settings->uspillb*map); - outputValue[3]=input[3]; + float map = calculateMapValue(rfac, input); + if (map > 0.0f) { + outputValue[0] = input[0] + this->rmut * (this->settings->uspillr * map); + outputValue[1] = input[1] + this->gmut * (this->settings->uspillg * map); + outputValue[2] = input[2] + this->bmut * (this->settings->uspillb * map); + outputValue[3] = input[3]; } else { - outputValue[0]=input[0]; - outputValue[1]=input[1]; - outputValue[2]=input[2]; - outputValue[3]=input[3]; + copy_v4_v4(outputValue, input); } } float ColorSpillOperation::calculateMapValue(float fac, float *input) { - return fac * (input[this->spillChannel]-(this->settings->limscale*input[settings->limchan])); + return fac * (input[this->spillChannel]-(this->settings->limscale*input[this->settings->limchan])); } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 5a919965ede..d75cb39325f 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -69,6 +69,11 @@ void CompositorOperation::deinitExecution() } rr->rectf = outputBuffer; } + else { + if (this->outputBuffer) { + MEM_freeN(this->outputBuffer); + } + } if (re) { RE_ReleaseResult(re); re = NULL; diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp index 0daa2b9c08a..db67412f3e7 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -36,9 +36,22 @@ inline void addFilter(float *result, float*input, float value) void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, MemoryBuffer *inputBuffers[], void *data) { float in1[4],in2[4], res1[4], res2[4]; + + int x1 = x - 1; + int x2 = x; + int x3 = x + 1; + int y1 = y - 1; + int y2 = y; + int y3 = y + 1; + CLAMP(x1, 0, getWidth()-1); + CLAMP(x2, 0, getWidth()-1); + CLAMP(x3, 0, getWidth()-1); + CLAMP(y1, 0, getHeight()-1); + CLAMP(y2, 0, getHeight()-1); + CLAMP(y3, 0, getHeight()-1); float value[4]; - this->inputValueOperation->read(value, x, y, inputBuffers, NULL); + this->inputValueOperation->read(value, x2, y2, inputBuffers, NULL); float mval = 1.0f - value[0]; res1[0] = 0.0f; @@ -50,39 +63,39 @@ void ConvolutionEdgeFilterOperation::executePixel(float *color,int x, int y, Mem res2[2] = 0.0f; res2[3] = 0.0f; - this->inputOperation->read(in1, x-1, y-1, inputBuffers, NULL); + this->inputOperation->read(in1, x1, y1, inputBuffers, NULL); addFilter(res1, in1, this->filter[0]); addFilter(res2, in1, this->filter[0]); - this->inputOperation->read(in1, x, y-1, inputBuffers, NULL); + this->inputOperation->read(in1, x2, y1, inputBuffers, NULL); addFilter(res1, in1, this->filter[1]); addFilter(res2, in1, this->filter[3]); - this->inputOperation->read(in1, x+1, y-1, inputBuffers, NULL); + this->inputOperation->read(in1, x3, y1, inputBuffers, NULL); addFilter(res1, in1, this->filter[2]); addFilter(res2, in1, this->filter[6]); - this->inputOperation->read(in1, x-1, y, inputBuffers, NULL); + this->inputOperation->read(in1, x1, y2, inputBuffers, NULL); addFilter(res1, in1, this->filter[3]); addFilter(res2, in1, this->filter[1]); - this->inputOperation->read(in2, x, y, inputBuffers, NULL); + this->inputOperation->read(in2, x2, y2, inputBuffers, NULL); addFilter(res1, in2, this->filter[4]); addFilter(res2, in2, this->filter[4]); - this->inputOperation->read(in1, x+1, y, inputBuffers, NULL); + this->inputOperation->read(in1, x3, y2, inputBuffers, NULL); addFilter(res1, in1, this->filter[5]); addFilter(res2, in1, this->filter[7]); - this->inputOperation->read(in1, x-1, y+1, inputBuffers, NULL); + this->inputOperation->read(in1, x1, y3, inputBuffers, NULL); addFilter(res1, in1, this->filter[6]); addFilter(res2, in1, this->filter[2]); - this->inputOperation->read(in1, x, y+1, inputBuffers, NULL); + this->inputOperation->read(in1, x2, y3, inputBuffers, NULL); addFilter(res1, in1, this->filter[7]); addFilter(res2, in1, this->filter[5]); - this->inputOperation->read(in1, x+1, y+1, inputBuffers, NULL); + this->inputOperation->read(in1, x3, y3, inputBuffers, NULL); addFilter(res1, in1, this->filter[8]); addFilter(res2, in1, this->filter[8]); diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp index 05cd570feaa..9fec75abafe 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -22,6 +22,8 @@ #include "COM_ConvolutionFilterOperation.h" +#include "BLI_utildefines.h" + ConvolutionFilterOperation::ConvolutionFilterOperation() : NodeOperation() { this->addInputSocket(COM_DT_COLOR); @@ -73,51 +75,62 @@ void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryB color[3] = 0.0; float in1[4]; float in2[4]; + int x1 = x - 1; + int x2 = x; + int x3 = x + 1; + int y1 = y - 1; + int y2 = y; + int y3 = y + 1; + CLAMP(x1, 0, getWidth()-1); + CLAMP(x2, 0, getWidth()-1); + CLAMP(x3, 0, getWidth()-1); + CLAMP(y1, 0, getHeight()-1); + CLAMP(y2, 0, getHeight()-1); + CLAMP(y3, 0, getHeight()-1); float value[4]; - this->inputValueOperation->read(value, x, y, inputBuffers, NULL); + this->inputValueOperation->read(value, x2, y2, inputBuffers, NULL); float mval = 1.0f - value[0]; - - this->inputOperation->read(in1, x-1, y-1, inputBuffers, NULL); + this->inputOperation->read(in1, x1, y1, inputBuffers, NULL); color[0] += in1[0] * this->filter[0]; color[1] += in1[1] * this->filter[0]; color[2] += in1[2] * this->filter[0]; color[3] += in1[3] * this->filter[0]; - this->inputOperation->read(in1, x, y-1, inputBuffers, NULL); + this->inputOperation->read(in1, x2, y1, inputBuffers, NULL); color[0] += in1[0] * this->filter[1]; color[1] += in1[1] * this->filter[1]; color[2] += in1[2] * this->filter[1]; color[3] += in1[3] * this->filter[1]; - this->inputOperation->read(in1, x+1, y-1, inputBuffers, NULL); + this->inputOperation->read(in1, x3, y1, inputBuffers, NULL); color[0] += in1[0] * this->filter[2]; color[1] += in1[1] * this->filter[2]; color[2] += in1[2] * this->filter[2]; color[3] += in1[3] * this->filter[2]; - this->inputOperation->read(in1, x-1, y, inputBuffers, NULL); + this->inputOperation->read(in1, x1, y2, inputBuffers, NULL); color[0] += in1[0] * this->filter[3]; color[1] += in1[1] * this->filter[3]; color[2] += in1[2] * this->filter[3]; color[3] += in1[3] * this->filter[3]; - this->inputOperation->read(in2, x, y, inputBuffers, NULL); + this->inputOperation->read(in2, x2, y2, inputBuffers, NULL); color[0] += in2[0] * this->filter[4]; color[1] += in2[1] * this->filter[4]; color[2] += in2[2] * this->filter[4]; color[3] += in2[3] * this->filter[4]; - this->inputOperation->read(in1, x+1, y, inputBuffers, NULL); + this->inputOperation->read(in1, x3, y2, inputBuffers, NULL); color[0] += in1[0] * this->filter[5]; color[1] += in1[1] * this->filter[5]; color[2] += in1[2] * this->filter[5]; color[3] += in1[3] * this->filter[5]; - this->inputOperation->read(in1, x-1, y+1, inputBuffers, NULL); + this->inputOperation->read(in1, x1, y3, inputBuffers, NULL); color[0] += in1[0] * this->filter[6]; color[1] += in1[1] * this->filter[6]; color[2] += in1[2] * this->filter[6]; color[3] += in1[3] * this->filter[6]; - this->inputOperation->read(in1, x, y+1, inputBuffers, NULL); + this->inputOperation->read(in1, x2, y3, inputBuffers, NULL); color[0] += in1[0] * this->filter[7]; color[1] += in1[1] * this->filter[7]; color[2] += in1[2] * this->filter[7]; color[3] += in1[3] * this->filter[7]; - this->inputOperation->read(in1, x+1, y+1, inputBuffers, NULL); + this->inputOperation->read(in1, x3, y3, inputBuffers, NULL); color[0] += in1[0] * this->filter[8]; color[1] += in1[1] * this->filter[8]; color[2] += in1[2] * this->filter[8]; @@ -126,6 +139,7 @@ void ConvolutionFilterOperation::executePixel(float *color,int x, int y, MemoryB color[0] = color[0]*value[0] + in2[0] * mval; color[1] = color[1]*value[0] + in2[1] * mval; color[2] = color[2]*value[0] + in2[2] * mval; + color[3] = color[3]*value[0] + in2[3] * mval; } bool ConvolutionFilterOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index a73f76030ab..7bc49fa695c 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -23,6 +23,7 @@ #include "COM_DilateErodeOperation.h" #include "BLI_math.h" +// DilateErode Distance Threshold DilateErodeDistanceOperation::DilateErodeDistanceOperation(): NodeOperation() { this->addInputSocket(COM_DT_VALUE); @@ -158,6 +159,115 @@ bool DilateErodeDistanceOperation::determineDependingAreaOfInterest(rcti *input, return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } +// Dilate Distance +DilateDistanceOperation::DilateDistanceOperation(): NodeOperation() +{ + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_VALUE); + this->setComplex(true); + this->inputProgram = NULL; + this->distance = 0.0f; +} +void DilateDistanceOperation::initExecution() +{ + this->inputProgram = this->getInputSocketReader(0); + this->scope = distance; + if (scope < 3) { + scope = 3; + } +} + +void *DilateDistanceOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + void *buffer = inputProgram->initializeTileData(NULL, memoryBuffers); + return buffer; +} + +void DilateDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + const float distance = this->distance; + float mindist = distance * distance; + + MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + float *buffer = inputBuffer->getBuffer(); + rcti *rect = inputBuffer->getRect(); + const int minx = max(x - scope, rect->xmin); + const int miny = max(y - scope, rect->ymin); + const int maxx = min(x + scope, rect->xmax); + const int maxy = min(y + scope, rect->ymax); + const int bufferWidth = rect->xmax-rect->xmin; + int offset; + + float value = 0.0f; + + for (int yi = miny ; yi<maxy;yi++) { + offset = ((yi-rect->ymin)*bufferWidth+(minx-rect->xmin))*4; + for (int xi = minx ; xi<maxx;xi++) { + const float dx = xi-x; + const float dy = yi-y; + const float dis = dx*dx+dy*dy; + if (dis <= mindist) { + value = max(buffer[offset], value); + } + offset +=4; + } + } + color[0] = value; +} + +void DilateDistanceOperation::deinitExecution() +{ + this->inputProgram = NULL; +} + +bool DilateDistanceOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +{ + rcti newInput; + + newInput.xmax = input->xmax + scope; + newInput.xmin = input->xmin - scope; + newInput.ymax = input->ymax + scope; + newInput.ymin = input->ymin - scope; + + return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); +} +// Erode Distance +ErodeDistanceOperation::ErodeDistanceOperation() : DilateDistanceOperation() +{ +} + +void ErodeDistanceOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + const float distance = this->distance; + float mindist = distance * distance; + + MemoryBuffer *inputBuffer = (MemoryBuffer*)data; + float *buffer = inputBuffer->getBuffer(); + rcti *rect = inputBuffer->getRect(); + const int minx = max(x - scope, rect->xmin); + const int miny = max(y - scope, rect->ymin); + const int maxx = min(x + scope, rect->xmax); + const int maxy = min(y + scope, rect->ymax); + const int bufferWidth = rect->xmax-rect->xmin; + int offset; + + float value = 1.0f; + + for (int yi = miny ; yi<maxy;yi++) { + offset = ((yi-rect->ymin)*bufferWidth+(minx-rect->xmin))*4; + for (int xi = minx ; xi<maxx;xi++) { + const float dx = xi-x; + const float dy = yi-y; + const float dis = dx*dx+dy*dy; + if (dis <= mindist) { + value = min(buffer[offset], value); + } + offset +=4; + } + } + color[0] = value; +} + // Dilate step DilateStepOperation::DilateStepOperation(): NodeOperation() { diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 7f01ea94494..71bbab74a4b 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -68,6 +68,47 @@ public: }; +class DilateDistanceOperation : public NodeOperation { +private: + /** + * Cached reference to the inputProgram + */ + SocketReader * inputProgram; +protected: + float distance; + int scope; +public: + DilateDistanceOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); + + /** + * Initialize the execution + */ + void initExecution(); + + void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + /** + * Deinitialize the execution + */ + void deinitExecution(); + + void setDistance(float distance) {this->distance = distance;} + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); +}; +class ErodeDistanceOperation : public DilateDistanceOperation { +public: + ErodeDistanceOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); +}; + class DilateStepOperation : public NodeOperation { protected: /** diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index cf36e7f6ebe..6c3e373472b 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -36,7 +36,7 @@ public: bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); - void IIR_gauss(MemoryBuffer *src, float sigma, int channel, int xy); + static void IIR_gauss(MemoryBuffer *src, float sigma, int channel, int xy); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index af10791590b..b5d175729f3 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -34,11 +34,20 @@ GaussianBokehBlurOperation::GaussianBokehBlurOperation(): BlurBaseOperation() void *GaussianBokehBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - updateGauss(memoryBuffers); + if (!sizeavailable) { + updateGauss(memoryBuffers); + } void *buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); return buffer; } +void GaussianBokehBlurOperation::initExecution() +{ + if (this->sizeavailable) { + updateGauss(NULL); + } +} + void GaussianBokehBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { if (this->gausstab == NULL) { @@ -51,8 +60,9 @@ void GaussianBokehBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) int j, i; const float width = this->getWidth(); const float height = this->getHeight(); - updateSize(memoryBuffers); - + if (!sizeavailable) { + updateSize(memoryBuffers); + } radxf = size*(float)this->data->sizex; if (radxf>width/2.0f) radxf = width/2.0f; @@ -163,19 +173,20 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, R return true; } else { - if (this->gausstab) { + if (this->sizeavailable && this->gausstab != NULL) { + newInput.xmin = 0; + newInput.ymin = 0; + newInput.xmax = this->getWidth(); + newInput.ymax = this->getHeight(); + } + else { int addx = radx; int addy = rady; newInput.xmax = input->xmax + addx; newInput.xmin = input->xmin - addx; newInput.ymax = input->ymax + addy; newInput.ymin = input->ymin - addy; - } - else { - newInput.xmin = 0; - newInput.ymin = 0; - newInput.xmax = this->getWidth(); - newInput.ymax = this->getHeight(); + } return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h index a7a0ee74364..78c6437eac6 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h @@ -34,7 +34,7 @@ private: public: GaussianBokehBlurOperation(); - + void initExecution(); void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); /** * the inner loop of this program diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 276efd90740..121bbbd45a0 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -36,11 +36,25 @@ GaussianXBlurOperation::GaussianXBlurOperation(): BlurBaseOperation() void *GaussianXBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - updateGauss(memoryBuffers); + if (!this->sizeavailable) { + updateGauss(memoryBuffers); + } void *buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); return buffer; } +void GaussianXBlurOperation::initExecution() +{ + if (this->sizeavailable) { + float rad = size*this->data->sizex; + if (rad<1) + rad = 1; + + this->rad = rad; + this->gausstab = BlurBaseOperation::make_gausstab(rad); + } +} + void GaussianXBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { if (this->gausstab == NULL) { @@ -118,18 +132,18 @@ bool GaussianXBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB return true; } else { - if (this->gausstab == NULL) { - newInput.xmax = this->getWidth(); - newInput.xmin = 0; - newInput.ymax = this->getHeight(); - newInput.ymin = 0; - } - else { + if (this->sizeavailable && this->gausstab != NULL) { newInput.xmax = input->xmax + rad; newInput.xmin = input->xmin - rad; newInput.ymax = input->ymax; newInput.ymin = input->ymin; } + else { + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + } return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } } diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index 704d063d28f..a957b8c12af 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -34,12 +34,17 @@ public: GaussianXBlurOperation(); /** - * the inner loop of this program + *@brief the inner loop of this program */ void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); /** - * Deinitialize the execution + *@brief initialize the execution + */ + void initExecution(); + + /** + *@brief Deinitialize the execution */ void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index faef152dc31..cab3e3d6094 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -35,11 +35,25 @@ GaussianYBlurOperation::GaussianYBlurOperation(): BlurBaseOperation() void *GaussianYBlurOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) { - updateGauss(memoryBuffers); + if (!this->sizeavailable) { + updateGauss(memoryBuffers); + } void *buffer = getInputOperation(0)->initializeTileData(NULL, memoryBuffers); return buffer; } +void GaussianYBlurOperation::initExecution() +{ + if (this->sizeavailable) { + float rad = size*this->data->sizey; + if (rad<1) + rad = 1; + + this->rad = rad; + this->gausstab = BlurBaseOperation::make_gausstab(rad); + } +} + void GaussianYBlurOperation::updateGauss(MemoryBuffer **memoryBuffers) { if (this->gausstab == NULL) { @@ -115,18 +129,18 @@ bool GaussianYBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadB return true; } else { - if (this->gausstab == NULL) { - newInput.xmax = this->getWidth(); - newInput.xmin = 0; - newInput.ymax = this->getHeight(); - newInput.ymin = 0; - } - else { + if (this->sizeavailable && this->gausstab != NULL) { newInput.xmax = input->xmax; newInput.xmin = input->xmin; newInput.ymax = input->ymax + rad; newInput.ymin = input->ymin - rad; } + else { + newInput.xmax = this->getWidth(); + newInput.xmin = 0; + newInput.ymax = this->getHeight(); + newInput.ymin = 0; + } return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } } diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h index c9baf27b1d6..f33d38de14e 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -39,6 +39,11 @@ public: void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data); /** + *@brief initialize the execution + */ + void initExecution(); + + /** * Deinitialize the execution */ void deinitExecution(); diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index e06244d3cdd..2fa8afc9c4c 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -25,6 +25,36 @@ #include "COM_NodeOperation.h" #include "DNA_node_types.h" + +/* utility functions used by glare, tonemap and lens distortion */ +/* soms macros for color handling */ +typedef float fRGB[4]; +/* clear color */ +#define fRGB_clear(c) { c[0]=c[1]=c[2]=0.f; } (void)0 +/* copy c2 to c1 */ +#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; c1[3]=c2[3]; } (void)0 +/* add c2 to c1 */ +#define fRGB_add(c1, c2) { c1[0]+=c2[0]; c1[1]+=c2[1]; c1[2]+=c2[2]; } (void)0 +/* subtract c2 from c1 */ +#define fRGB_sub(c1, c2) { c1[0]-=c2[0]; c1[1]-=c2[1]; c1[2]-=c2[2]; } (void)0 +/* multiply c by float value s */ +#define fRGB_mult(c, s) { c[0]*=s; c[1]*=s; c[2]*=s; } (void)0 +/* multiply c2 by s and add to c1 */ +#define fRGB_madd(c1, c2, s) { c1[0]+=c2[0]*s; c1[1]+=c2[1]*s; c1[2]+=c2[2]*s; } (void)0 +/* multiply c2 by color c1 */ +#define fRGB_colormult(c, cs) { c[0]*=cs[0]; c[1]*=cs[1]; c[2]*=cs[2]; } (void)0 +/* multiply c2 by color c3 and add to c1 */ +#define fRGB_colormadd(c1, c2, c3) { c1[0]+=c2[0]*c3[0]; c1[1]+=c2[1]*c3[1]; c1[2]+=c2[2]*c3[2]; } (void)0 +/* multiply c2 by color rgb, rgb as separate arguments */ +#define fRGB_rgbmult(c, r, g, b) { c[0]*=(r); c[1]*=(g); c[2]*=(b); } (void)0 +/* swap colors c1 & c2 */ +#define fRGB_swap(c1, c2) { float _t=c1[0]; c1[0]=c2[0]; c2[0]=_t;\ + _t=c1[1]; c1[1]=c2[1]; c2[1]=_t;\ + _t=c1[2]; c1[2]=c2[2]; c2[2]=_t;\ + _t=c1[3]; c1[3]=c2[3]; c3[3]=_t;\ + } (void)0 + + class GlareBaseOperation : public NodeOperation { private: /** diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp new file mode 100644 index 00000000000..c5b1d6caa89 --- /dev/null +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -0,0 +1,114 @@ +/* + * 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: + * Jeroen Bakker + * Monique Dewanchand + */ + +#include "COM_GlareGhostOperation.h" +#include "BLI_math.h" +#include "COM_FastGaussianBlurOperation.h" + +static float smoothMask(float x, float y) +{ + float t; + x = 2.f*x - 1.f, y = 2.f*y - 1.f; + if ((t = 1.f - sqrtf(x*x + y*y)) <= 0.f) return 0.f; + return t; +} + + +void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings) +{ + const int qt = 1 << settings->quality; + const float s1 = 4.f/(float)qt, s2 = 2.f*s1; + int x, y, n, p, np; + fRGB c, tc, cm[64]; + float sc, isc, u, v, sm, s, t, ofs, scalef[64]; + const float cmo = 1.f - settings->colmod; + + MemoryBuffer *gbuf = inputTile->duplicate(); + MemoryBuffer *tbuf1 = inputTile->duplicate(); + + FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 0, 3); + FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 1, 3); + FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 2, 3); + + MemoryBuffer *tbuf2 = tbuf1->duplicate(); + + FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 0, 3); + FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 1, 3); + FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 2, 3); + + if (settings->iter & 1) ofs = 0.5f; else ofs = 0.f; + for (x=0; x<(settings->iter*4); x++) { + y = x & 3; + cm[x][0] = cm[x][1] = cm[x][2] = 1; + if (y==1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo); + if (y==2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f); + if (y==3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo); + scalef[x] = 2.1f*(1.f-(x+ofs)/(float)(settings->iter*4)); + if (x & 1) scalef[x] = -0.99f/scalef[x]; + } + + sc = 2.13; + isc = -0.97; + for (y=0; y<gbuf->getHeight(); y++) { + v = (float)(y+0.5f) / (float)gbuf->getHeight(); + for (x=0; x<gbuf->getWidth(); x++) { + u = (float)(x+0.5f) / (float)gbuf->getWidth(); + s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f; + tbuf1->read(c, s*gbuf->getWidth(), t*gbuf->getHeight()); + sm = smoothMask(s, t); + fRGB_mult(c, sm); + s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f; + tbuf2->read(tc, s*gbuf->getWidth()-0.5f, t*gbuf->getHeight()-0.5f); + sm = smoothMask(s, t); + fRGB_madd(c, tc, sm); + + gbuf->writePixel(x, y, c); + } + } + + memset(tbuf1->getBuffer(), 0, tbuf1->getWidth()*tbuf1->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + for (n=1; n<settings->iter; n++) { + for (y=0; y<gbuf->getHeight(); y++) { + v = (float)(y+0.5f) / (float)gbuf->getHeight(); + for (x=0; x<gbuf->getWidth(); x++) { + u = (float)(x+0.5f) / (float)gbuf->getWidth(); + tc[0] = tc[1] = tc[2] = 0.f; + for (p=0;p<4;p++) { + np = (n<<2) + p; + s = (u-0.5f)*scalef[np] + 0.5f; + t = (v-0.5f)*scalef[np] + 0.5f; + gbuf->read(c, s*gbuf->getWidth() - 0.5f, t*gbuf->getHeight() - 0.5f); + fRGB_colormult(c, cm[np]); + sm = smoothMask(s, t)*0.25f; + fRGB_madd(tc, c, sm); + } + tbuf1->writePixel(x, y, tc); + } + } + memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth()*tbuf1->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + } + memcpy(data, gbuf->getBuffer(), gbuf->getWidth()*gbuf->getHeight()*COM_NUMBER_OF_CHANNELS*sizeof(float)); + + delete gbuf; + delete tbuf1; + delete tbuf2; +} diff --git a/source/blender/compositor/operations/COM_LensGlowImageOperation.h b/source/blender/compositor/operations/COM_GlareGhostOperation.h index 424b4d4fc3d..48b5e8986a9 100644 --- a/source/blender/compositor/operations/COM_LensGlowImageOperation.h +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.h @@ -20,33 +20,16 @@ * Monique Dewanchand */ -#ifndef _COM_LensGlowImageOperation_h -#define _COM_LensGlowImageOperation_h +#ifndef _COM_GlareGhostOperation_h +#define _COM_GlareGhostOperation_h #include "COM_NodeOperation.h" +#include "DNA_node_types.h" +#include "COM_GlareBaseOperation.h" - -class LensGlowImageOperation : public NodeOperation { -private: - float scale; - +class GlareGhostOperation : public GlareBaseOperation { public: - LensGlowImageOperation(); - - /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - - /** - * Initialize the execution - */ - void initExecution(); - - /** - * Deinitialize the execution - */ - void deinitExecution(); - - void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + GlareGhostOperation() : GlareBaseOperation() {} +protected: + void generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings); }; #endif diff --git a/source/blender/compositor/operations/COM_LensGhostOperation.cpp b/source/blender/compositor/operations/COM_LensGhostOperation.cpp deleted file mode 100644 index bbf6df6c1e5..00000000000 --- a/source/blender/compositor/operations/COM_LensGhostOperation.cpp +++ /dev/null @@ -1,815 +0,0 @@ -/* - * 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: - * Jeroen Bakker - * Monique Dewanchand - */ - -#include "COM_LensGhostOperation.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" - -#define MAX_STEP 256 -class Ray { -public: - float position[3]; - float direction[3]; - float uv[2]; - double wavelength; - float intensity; - bool valid; - void copyFrom(Ray *other) { - copy_v3_v3(position, other->position); - copy_v3_v3(direction, other->direction); - copy_v2_v2(uv, other->uv); - wavelength = other->wavelength; - intensity = other->intensity; - this->valid = other->valid; - } -}; - -class Intersection { -public: - float position[3]; - float normal[3]; - double theta; - bool hit; - bool inverted; -}; - -class LensInterface { -public: - float position[3]; - float radius; - float nominalRadius; - double refraction1; - double refraction2; - double refraction3; - float thicknessCoathing; - virtual bool isFlat() = 0; - virtual void intersect(Intersection *result, Ray *ray) = 0; -}; - -class FlatInterface: public LensInterface { -public: - bool isFlat() {return true;} - FlatInterface(float positionX, float positionY, float positionZ, float radius) { - this->position[0] = positionX; - this->position[1] = positionY; - this->position[2] = positionZ; - this->radius = radius; - this->nominalRadius = radius; - this->refraction1 = 1.0f; - this->refraction2 = 1.0f; - this->refraction3 = 1.0f; - this->thicknessCoathing = 0.0f; - - } - void intersect(Intersection *result, Ray *ray) { - const float dz = this->position[2]-ray->position[2]; - result->position[0] = ray->position[0] + ray->direction[0]*(dz)/ray->direction[2]; - result->position[1] = ray->position[1] + ray->direction[1]*(dz)/ray->direction[2]; - result->position[2] = ray->position[2] + ray->direction[2]*(dz)/ray->direction[2]; - result->normal[0] = 0.0f; - result->normal[1] = 0.0f; - result->normal[2] = ray->direction[2]>0?-1.0f:1.0f; - result->theta = 0.0f; -// result->hit = this->nominalRadius>maxf(fabs(result->position[0]), fabs(result->position[1])); - result->hit = true; - result->inverted = false; - } -}; - -class SphereInterface: public LensInterface { -public: - SphereInterface(float positionX, float positionY, float positionZ, float radius, float nominalRadius, float n0, float n2, float coatingPhase) { - this->position[0] = positionX; - this->position[1] = positionY; - this->position[2] = positionZ; - this->radius = radius; - this->nominalRadius = nominalRadius; - this->refraction1 = n0; - this->refraction3 = n2; - this->refraction2 = maxf(sqrtf(n0*n2), 1.38); - - this->thicknessCoathing = coatingPhase/4/this->refraction2; - } - bool isFlat() {return false;} - void intersect(Intersection *result, Ray *ray) { - float delta[3] ={ray->position[0] - this->position[0], - ray->position[1] - this->position[1], - ray->position[2] - this->position[2]}; - float b = dot_v3v3(delta, ray->direction); - float c = dot_v3v3(delta, delta) - this->radius*this->radius; - float b2c = b*b-c; - if (b2c < 0) { - result->hit = false; - } - else { - float sgn = (this->radius*ray->direction[2])>0?1.0f:-1.0f; - float t = sqrtf(b2c)*sgn-b; - result->position[0] = ray->direction[0]*t+ray->position[0]; - result->position[1] = ray->direction[1]*t+ray->position[1]; - result->position[2] = ray->direction[2]*t+ray->position[2]; - - float p[3] = { - result->position[0] - this->position[0], - result->position[1] - this->position[1], - result->position[2] - this->position[2] - }; - normalize_v3(p); - - if (dot_v3v3(p, ray->direction)> 0) { - result->normal[0] = -p[0]; - result->normal[1] = -p[1]; - result->normal[2] = -p[2]; - } - else { - result->normal[0] = p[0]; - result->normal[1] = p[1]; - result->normal[2] = p[2]; - } - - float inverse[3] ={ - -ray->direction[0], - -ray->direction[1], - -ray->direction[2]}; - - result->theta = acosf(dot_v3v3(inverse, result->normal)); - result->hit = this->nominalRadius>sqrt(result->position[0]*result->position[0]+result->position[1]*result->position[1]); -// result->hit = this->nominalRadius>maxf(fabs(result->position[0]), fabs(result->position[1])); -// result->hit = true; - result->inverted = t < 0; - } - } -}; -class RayResult { -public: - float x; - float y; - float intensity[3]; - float u; - float v; - float screenX; - float screenY; - bool valid; - bool hasIntensity; -}; -class Bounce { -public: - LensInterface *interface1; - LensInterface *interface2; - RayResult *raster; - int length; // number of interfaces to travel - int rasterLength; - Bounce(LensInterface *interface1, LensInterface *interface2, int length, int rasterStep) { - this->interface1 = interface1; - this->interface2 = interface2; - this->length = length; - this->rasterLength = rasterStep; - this->raster = new RayResult[rasterLength*rasterLength]; - for (int i = 0 ; i < rasterLength*rasterLength ; i++) { - RayResult * res = &this->raster[i]; - res->intensity[0] = 0.0f; - res->intensity[1] = 0.0f; - res->intensity[2] = 0.0f; - res->x = 0.0f; - res->y = 0.0f; - res->u = 0.0f; - res->v = 0.0f; - res->valid = false; - } - } - ~Bounce() { - delete raster; - - } - - RayResult *getRayResult(int x, int y) { - return &(raster[x+y*rasterLength]); - } -}; -class LensSystem { -public: - vector<LensInterface*> interfaces; - vector<Bounce*> bounces; - int bokehIndex; - int lensIndex; - - ~LensSystem() { - for (int index = 0 ; index <bounces.size();index++) {delete bounces[index];} - for (int index = 0 ; index <interfaces.size();index++) {delete interfaces[index];} - } - - void updateBounces(int step) { - for (int i = 0; i < interfaces.size()-1 ; i ++) { - if (!interfaces[i]->isFlat()) { - for (int j = i+1; j < interfaces.size()-1 ; j ++) { - if (!interfaces[j]->isFlat()) { - int length = interfaces.size()+2*(j-i); - Bounce *bounce = new Bounce(interfaces[j], interfaces[i], length, step); - bounces.push_back(bounce); - } - } - } - } - - } - - void addInterface(LensInterface *pinterface) { - this->interfaces.push_back(pinterface); - this->lensIndex = this->interfaces.size()-1; - } - - static int refraction(float *refract, float *n, float *view, double index) - { - - return 1; - -// float dot, fac; - -// VECCOPY(refract, view); - -// dot = view[0]*n[0] + view[1]*n[1] + view[2]*n[2]; - -// if (dot>0.0f) { -// index = 1.0f/index; -// fac = 1.0f - (1.0f - dot*dot)*index*index; -// if (fac<= 0.0f) return 0; -// fac= -dot*index + sqrt(fac); -// } -// else { -// fac = 1.0f - (1.0f - dot*dot)*index*index; -// if (fac<= 0.0f) return 0; -// fac= -dot*index - sqrt(fac); -// } - -// refract[0] = index*view[0] + fac*n[0]; -// refract[1] = index*view[1] + fac*n[1]; -// refract[2] = index*view[2] + fac*n[2]; - -// normalize_v3(refract); -// return 1; - //--- -// const double cosI = dot_v3v3(n, view); -// const double sinT2 = index * index * (1.0 - cosI * cosI); -// if (sinT2 >= 1.0f) -// { -// return 0; -// } -// refract[0] = index*view[0] - (index + sqrt(1.0-sinT2))*n[0]; -// refract[1] = index*view[1] - (index + sqrt(1.0-sinT2))*n[1]; -// refract[2] = index*view[2] - (index + sqrt(1.0-sinT2))*n[2]; -// normalize_v3(refract); -// return 1; - //--- - -// double ni = -dot_v3v3(view, n); -// double test = 1.0f - index*index*(1.0f-ni*ni); -// if (test < 0) { -// return 0; -// } -// else { -// double mul = index*ni + sqrt(test); -// refract[0] = index * view[0] - mul*n[0]; -// refract[1] = index * view[1] - mul*n[1]; -// refract[2] = index * view[2] - mul*n[2]; -// normalize_v3(refract); -// return 1; -// } - } - - /* orn = original face normal */ - static void reflection(float *ref, float *n, float *view) - { - float f1; - - f1= -2.0f*dot_v3v3(n, view); - - ref[0] = (view[0]+f1*n[0]); - ref[1] = (view[1]+f1*n[1]); - ref[2] = (view[2]+f1*n[2]); - normalize_v3(ref); - } - - static float fresnelAR(float theta0, float lambda, float d1, float n0, float n1, float n2) { - // refractionangles in coating and the 2nd medium - float theta1 = asin(sin(theta0)*n0/n1); - float theta2 = asin(sin(theta0)*n0/n2); - - float rs01 = -sin(theta0-theta1)/sin(theta0+theta1); - float rp01 = tan( theta0-theta1)/tan(theta0+theta1); - float ts01 = 2 * sin( theta1 ) * cos( theta0 ) / sin( theta0+theta1 ) ; - float tp01 = ts01*cos(theta0-theta1); - // amplitude for inner reflection - float rs12 = -sin( theta1-theta2 ) / sin( theta1+theta2 ) ; - float rp12 = +tan( theta1-theta2 ) / tan( theta1+theta2 ) ; - // after passing through first surface twice : - // 2 transmissions and 1 reflection - float ris = ts01 * ts01 * rs12 ; - float rip = tp01 * tp01 * rp12 ; - // phase difference between outer and inner reflections - float dy = d1 * n1 ; - float dx = tan( theta1 ) * dy ; - float delay = sqrt( dx * dx+dy * dy ) ; - float relPhase = 4 * M_PI / lambda * ( delay-dx * sin( theta0 ) ) ; - // Add up sines of different phase and amplitude - float out_s2 = rs01 * rs01 + ris * ris + 2 * rs01 * ris * cos( relPhase ) ; - float out_p2 = rp01 * rp01 + rip * rip + 2 * rp01 * rip * cos( relPhase ) ; - return (out_s2 + out_p2) / 2 ; - } - - void detectHit(Ray *result, Ray *inputRay, Bounce *bounce) { - int phase = 0; - int delta = 1; - int t = 1; - int k; - result->copyFrom(inputRay); - result->valid = false; - LensInterface *next = bounce->interface1; - LensInterface *f = NULL; - Intersection intersection; - for (k = 0 ; k < bounce->length-1;k++, t+=delta) { - f = this->interfaces[t]; - bool breflect = next == f; - if (breflect) { - delta = -delta; - if (phase == 0) { - next = bounce->interface2; - } - else { - next = NULL; - } - phase ++; - } - - f->intersect(&intersection, result); - if (!intersection.hit) { - break; - } - if (f->isFlat()) { - if (t == this->bokehIndex) { - result->uv[0] = intersection.position[0]/f->nominalRadius; - result->uv[1] = intersection.position[1]/f->nominalRadius; - } - } - - float p[3] = { - intersection.position[0]-result->position[0], - intersection.position[1]-result->position[1], - intersection.position[2]-result->position[2] - }; - - float nfac = sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]); - - if (intersection.inverted) { - nfac *= -1; - } - - result->direction[0] = p[0]/nfac; - result->direction[1] = p[1]/nfac; - result->direction[2] = p[2]/nfac; - result->position[0] = intersection.position[0]; - result->position[1] = intersection.position[1]; - result->position[2] = intersection.position[2]; - - if (!f->isFlat()) { - // do refraction and reflection - double n0 = result->direction[2]<0?f->refraction1:f->refraction3; - double n1 = f->refraction2; - double n2 = result->direction[2]<0?f->refraction3:f->refraction1; - if (!breflect) { - float view[3] ={ - result->direction[0], - result->direction[1], - result->direction[2] - }; - int ref = this->refraction(result->direction, intersection.normal, view, n0/n1); - if (ref == 0) { - break; - } - } - else { - this->reflection(result->direction, intersection.normal, result->direction); - float fresnelMultiplyer = fresnelAR(intersection.theta, result->wavelength, f->thicknessCoathing, n0, n1, n2); - if (isnan(fresnelMultiplyer)) { - fresnelMultiplyer = 0.0f; - } - result->intensity *= fresnelMultiplyer; - } - } - - } - if (k < bounce->length-1) { - result->intensity = 0; - } - else { - result->valid = true; - } - } -}; - -typedef struct LensFace { - RayResult *v1; - RayResult *v2; - RayResult *v3; -} LensFace; - -LensGhostProjectionOperation::LensGhostProjectionOperation(): NodeOperation() -{ - this->addInputSocket(COM_DT_COLOR); - this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); - this->addOutputSocket(COM_DT_COLOR); - this->lampObject = NULL; - this->cameraObject = NULL; - this->system = NULL; - this->quality = COM_QUALITY_HIGH; - this->setComplex(false); -} - -LensGhostOperation::LensGhostOperation(): LensGhostProjectionOperation() -{ - this->setComplex(true); - -} - -void LensGhostProjectionOperation::initExecution() -{ - if (this->cameraObject != NULL && this->lampObject != NULL) { - if (lampObject == NULL || cameraObject == NULL) { - visualLampPosition[0] = 0; - visualLampPosition[1] = 0; - visualLampPosition[2] = 0; - } - else { - /* too simple, better to return the distance on the view axis only - * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ - float matt[4][4], imat[4][4], obmat[4][4]; - - copy_m4_m4(obmat, cameraObject->obmat); - normalize_m4(obmat); - invert_m4_m4(imat, obmat); - mult_m4_m4m4(matt, imat, lampObject->obmat); - - visualLampPosition[0] = (float)(matt[3][0]); - visualLampPosition[1] = (float)(matt[3][1]); - visualLampPosition[2] = (float)fabs(matt[3][2]); - } - } - this->lamp = (Lamp*)lampObject->data; - - this->step = this->quality==COM_QUALITY_LOW?64:this->quality==COM_QUALITY_MEDIUM?128:256; - this->bokehReader = this->getInputSocketReader(1); - -#define MM *0.001f -#define CM *0.01f -#define NM *0.000000001 -#define RED 650 NM -#define GREEN 510 NM -#define BLUE 475 NM -#define AIR 1.000293f -#define GLASS 1.5200f -#define TEST 0.000002f - // determine interfaces - LensSystem *system = new LensSystem(); - system->addInterface(new FlatInterface(0.0f,0.0f, 6.5 CM, 30 MM)); //ENTRANCE - system->addInterface(new SphereInterface(0.0f,0.0f, -3 CM, 8 CM, 3 CM, AIR, GLASS , 0.f)); - system->addInterface(new SphereInterface(0.0f,0.0f, -4 CM, 8 CM, 3 CM, GLASS, AIR, GREEN)); - system->addInterface(new FlatInterface(0.0f,0.0f, 3.0 CM, 15 MM)); // BOKEH - system->addInterface(new SphereInterface(0.0f,0.0f, 6 CM, 3 CM, 2 CM, AIR, GLASS, 0.0f)); - system->addInterface(new SphereInterface(0.0f,0.0f, 5.5 CM, 3 CM, 2 CM, GLASS, AIR, 0.f)); - system->addInterface(new FlatInterface(0.0f,0.0f,0 CM, 30 MM)); // SENSOR - system->bokehIndex = 3; - - // determine interfaces -// LensSystem *system = new LensSystem(); -// system->addInterface(new FlatInterface(0.0f,0.0f, 6.5 CM, 30 MM)); //ENTRANCE -// system->addInterface(new SphereInterface(0.0f,0.0f, 14 CM, 8 CM, 6 CM, AIR, GLASS , 0.0f)); -// system->addInterface(new SphereInterface(0.0f,0.0f, 12 CM, 8 CM, 6 CM, GLASS, AIR, GREEN)); -// system->addInterface(new FlatInterface(0.0f,0.0f, 3.0 CM, 30 MM)); // BOKEH -// system->addInterface(new SphereInterface(0.0f,0.0f, 1 CM, 3 CM, 2 CM, AIR, GLASS, GREEN)); -// system->addInterface(new SphereInterface(0.0f,0.0f, -2 CM, 3 CM, 2 CM, GLASS, AIR, RED)); -// system->addInterface(new FlatInterface(0.0f,0.0f,0 CM, 20 MM)); // SENSOR -// system->bokehIndex = 3; -#undef CM -#undef MM - // determine bounces - system->updateBounces(step); - this->system = system; -} - -void LensGhostOperation::initExecution() -{ - LensGhostProjectionOperation::initExecution(); - LensSystem *system = (LensSystem*)this->system; - LensInterface *interface1 = system->interfaces[0]; - - // for every herz - float HERZ[3]={650 NM,510 NM,475 NM}; /// @todo use 7 for high quality? - for (int iw = 0 ; iw < 3 ; iw ++) { - float wavelength = HERZ[iw]; - // for every bounce - for (int ib = 0 ; ib < system->bounces.size() ; ib++) { - Bounce *bounce = system->bounces[ib]; - // based on quality setting the number of iteration will be different (128^2, 64^2, 32^2) - for (int xi = 0 ; xi < step ; xi ++) { - float x = -interface1->radius+xi*(interface1->radius*2/step); - for (int yi = 0 ; yi < step ; yi ++) { - float y = -interface1->radius+yi*(interface1->radius*2/step); - Ray r; - Ray result; - r.wavelength = wavelength; - r.intensity = this->lamp->energy; - r.uv[0] = 0.0f; - r.uv[1] = 0.0f; - r.position[0] = visualLampPosition[0]; - r.position[1] = visualLampPosition[1]; - r.position[2] = visualLampPosition[2]; - r.direction[0] = interface1->position[0]+x - r.position[0]; - r.direction[1] = interface1->position[1]+y - r.position[1]; - r.direction[2] = interface1->position[2] - r.position[2]; - normalize_v3(r.direction); - system->detectHit(&result, &r, bounce); - RayResult *res = bounce->getRayResult(xi, yi); - if (iw == 0) { - res->x = result.position[0]; - res->y = result.position[1]; - res->u = result.uv[0]; - res->v = result.uv[1]; - } - res->intensity[iw] = result.intensity; - if (result.valid) { - res->valid = true; - } - } - } - } - } -#undef NM - const int width = this->getWidth(); - const int height = this->getHeight(); - const float width2 = width/2.0f; - const float height2 = height/2.0f; - float *data = new float[width*height*4]; - for (int i = 0 ; i < width*height ; i ++) { - data[i*4+0] = 0.0f; - data[i*4+1] = 0.0f; - data[i*4+2] = 0.0f; - data[i*4+3] = 1.0f; - } - /// @todo every bounce creates own image. these images are added together at the end -// LensSystem *system = (LensSystem*)this->system; - LensInterface * lens = system->interfaces[system->lensIndex]; - for (int i = 0 ; i < system->bounces.size() ; i ++) { - Bounce *bounce = system->bounces[i]; - for (int r = 0 ; r < bounce->rasterLength*bounce->rasterLength ; r ++) { - RayResult *result = &bounce->raster[r]; -// if (result->valid) { - float ru = result->x/lens->nominalRadius*width2+width2; - float rv = result->y/lens->nominalRadius*height2+height2; - result->screenX = ru; - result->screenY = rv; - result->hasIntensity = result->intensity[0]>0.0f &&result->intensity[1]>0.0f&& result->intensity[2]>0.0f; -// } - } - } -} - -void *LensGhostOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) -{ - vector<LensFace*>* result = new vector<LensFace*>(); - LensSystem *system = (LensSystem*)this->system; - const float minx = rect->xmin; - const float miny = rect->ymin; - const float maxx = rect->xmax; - const float maxy = rect->ymax; - for (int i = 0 ; i < system->bounces.size() ; i ++) { - Bounce *bounce = system->bounces[i]; - int faceX, faceY; - for (faceX = 0 ; faceX < bounce->rasterLength-1 ; faceX++) { - for (faceY = 0 ; faceY < bounce->rasterLength-1 ; faceY++) { - RayResult *vertex1 = bounce->getRayResult(faceX, faceY); - RayResult *vertex2 = bounce->getRayResult(faceX+1, faceY); - RayResult *vertex3 = bounce->getRayResult(faceX+1, faceY+1); - RayResult *vertex4 = bounce->getRayResult(faceX, faceY+1); - // early hit test - if (!((vertex1->screenX < minx && vertex2->screenX < minx && vertex3->screenX < minx && vertex4->screenX < minx) || - (vertex1->screenX > maxx && vertex2->screenX > maxx && vertex3->screenX > maxx && vertex4->screenX > maxx) || - (vertex1->screenY < miny && vertex2->screenY < miny && vertex3->screenY < miny && vertex4->screenY < miny) || - (vertex1->screenY > maxy && vertex2->screenY > maxy && vertex3->screenY > maxy && vertex4->screenY > maxy))) { - int number = vertex1->hasIntensity + vertex2->hasIntensity + vertex3->hasIntensity + vertex4->hasIntensity; - if (number == 4) { - LensFace *face = new LensFace(); - face->v1 = vertex1; - face->v2 = vertex2; - face->v3 = vertex3; - result->push_back(face); - face = new LensFace(); - face->v1 = vertex3; - face->v2 = vertex4; - face->v3 = vertex1; - result->push_back(face); - } - else if (number == 3) { - LensFace *face = new LensFace(); - if (!vertex1->hasIntensity) { - face->v1 = vertex2; - face->v2 = vertex3; - face->v3 = vertex4; - } - else if (!vertex2->hasIntensity) { - face->v1 = vertex1; - face->v2 = vertex3; - face->v3 = vertex4; - } - else if (!vertex3->hasIntensity) { - face->v1 = vertex1; - face->v2 = vertex2; - face->v3 = vertex4; - } - else { - face->v1 = vertex1; - face->v2 = vertex2; - face->v3 = vertex3; - } - result->push_back(face); - } - } - } - } - } - - return result; -} - -void LensGhostOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) -{ - if (data) { - vector<LensFace*>* faces = (vector<LensFace*>*)data; - while (faces->size() != 0) { - LensFace *face = faces->back(); - faces->pop_back(); - delete face; - } - delete faces; - } -} - - -void LensGhostProjectionOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) -{ - float bokeh[4]; - LensSystem *system = (LensSystem*)this->system; - LensInterface *interface1 = system->interfaces[0]; - color[0] = 0.0f; - color[1] = 0.0f; - color[2] = 0.0f; - color[3] = 0.0f; - const float width = this->getWidth(); - const float height = this->getHeight(); - const float size = min(height, width); - const float width2 = width/2; - const float height2 = height/2; - const float size2 = size/2; - -#define NM *0.000000001 - float HERZ[3]={650 NM,510 NM,475 NM}; /// @todo use 7 for high quality? - float rx = ((x-width2)/size2) * interface1->radius; - float ry = ((y-height2)/size2) * interface1->radius; - - for (int iw = 0 ; iw < 3 ; iw ++) { - float intensity = 0.0f; - float wavelength = HERZ[iw]; - float colorcomponent = 0.0f; - if (iw ==0 ) colorcomponent = lamp->r; - if (iw ==1 ) colorcomponent = lamp->g; - if (iw ==2 ) colorcomponent = lamp->b; - - - // for every bounce - for (int ib = 0 ; ib < system->bounces.size() ; ib++) { - Bounce *bounce = system->bounces[ib]; - // based on quality setting the number of iteration will be different (128^2, 64^2, 32^2) - - Ray r; - Ray result; - r.wavelength = wavelength; - r.intensity = this->lamp->energy; - r.uv[0] = 0.0f; - r.uv[1] = 0.0f; - r.position[0] = visualLampPosition[0]; - r.position[1] = visualLampPosition[1]; - r.position[2] = visualLampPosition[2]; - r.direction[0] = interface1->position[0]+rx - r.position[0]; - r.direction[1] = interface1->position[1]+ry - r.position[1]; - r.direction[2] = interface1->position[2] - r.position[2]; - normalize_v3(r.direction); - system->detectHit(&result, &r, bounce); - if (result.valid) { - float u = ((result.uv[0]+1.0f)/2)*bokehReader->getWidth(); - float v = ((result.uv[1]+1.0f)/2)*bokehReader->getHeight(); - - bokehReader->read(bokeh, u, v, sampler, inputBuffers); - - intensity += result.intensity *bokeh[iw]; - } - } - intensity = maxf(0.0f, intensity); - color[iw] = intensity*colorcomponent; - } - color[3] = 1.0f; -#undef NM - -} - - - -void LensGhostOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) -{ - vector<LensFace*>* faces = (vector<LensFace*>*)data; -#if 0 /* UNUSED */ - const float bokehWidth = bokehReader->getWidth(); - const float bokehHeight = bokehReader->getHeight(); - float bokeh[4]; -#endif - color[0] = 0.0f; - color[1] = 0.0f; - color[2] = 0.0f; - color[3] = 1.0f; - - unsigned int index; - for (index = 0 ; index < faces->size() ; index ++) { - LensFace * face = faces->operator [](index); - RayResult *vertex1 = face->v1; - RayResult *vertex2 = face->v2; - RayResult *vertex3 = face->v3; - if (!((vertex1->screenX < x && vertex2->screenX < x && vertex3->screenX < x) || - (vertex1->screenX > x && vertex2->screenX > x && vertex3->screenX > x) || - (vertex1->screenY < y && vertex2->screenY < y && vertex3->screenY < y) || - (vertex1->screenY > y && vertex2->screenY > y && vertex3->screenY > y))) { - - const float v1[2] = {vertex1->screenX, vertex1->screenY}; - const float v2[2] = {vertex2->screenX, vertex2->screenY}; - const float v3[2] = {vertex3->screenX, vertex3->screenY}; - const float co[2] = {x, y}; - float weights[3]; - - barycentric_weights_v2(v1, v2, v3, co, weights); - if (weights[0]>=0.0f && weights[0]<=1.0f && - weights[1]>=0.0f && weights[1]<=1.0f && - weights[2]>=0.0f && weights[2]<=1.0f) { -// const float u = (vertex1->u*weights[0]+vertex2->u*weights[1]+vertex3->u*weights[2]); -// const float v = (vertex1->v*weights[0]+vertex2->v*weights[1]+vertex3->v*weights[2]); -// const float tu = ((u+1.0f)/2.0f)*bokehWidth; -// const float tv = ((v+1.0f)/2.0f)*bokehHeight; -// bokehReader->read(bokeh, tu, tv, inputBuffers); - -// color[0] = max(color[0], bokeh[0]*(vertex1->intensity[0]*weights[0]+vertex2->intensity[0]*weights[1]+vertex3->intensity[0]*weights[2])); -// color[1] = max(color[1], bokeh[1]*(vertex1->intensity[1]*weights[0]+vertex2->intensity[1]*weights[1]+vertex3->intensity[1]*weights[2])); -// color[2] = max(color[2], bokeh[2]*(vertex1->intensity[2]*weights[0]+vertex2->intensity[2]*weights[1]+vertex3->intensity[2]*weights[2])); - color[0] = max(color[0], (vertex1->intensity[0]*weights[0]+vertex2->intensity[0]*weights[1]+vertex3->intensity[0]*weights[2])); - color[1] = max(color[1], (vertex1->intensity[1]*weights[0]+vertex2->intensity[1]*weights[1]+vertex3->intensity[1]*weights[2])); - color[2] = max(color[2], (vertex1->intensity[2]*weights[0]+vertex2->intensity[2]*weights[1]+vertex3->intensity[2]*weights[2])); - } - } - } -} - - -void LensGhostProjectionOperation::deinitExecution() -{ - if (this->system) delete (LensSystem*)this->system; - this->system = NULL; - this->bokehReader = NULL; -} - -bool LensGhostProjectionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) -{ - rcti bokehInput; - - NodeOperation *operation = this->getInputOperation(1); - bokehInput.xmax = operation->getWidth(); - bokehInput.xmin = 0; - bokehInput.ymax = operation->getHeight(); - bokehInput.ymin = 0; - if (operation->determineDependingAreaOfInterest(&bokehInput, readOperation, output) ) { - return true; - } - - return NodeOperation::determineDependingAreaOfInterest(input, readOperation, output); -} diff --git a/source/blender/compositor/operations/COM_LensGhostOperation.h b/source/blender/compositor/operations/COM_LensGhostOperation.h deleted file mode 100644 index 5546ce96fd1..00000000000 --- a/source/blender/compositor/operations/COM_LensGhostOperation.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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: - * Jeroen Bakker - * Monique Dewanchand - */ - -#ifndef _COM_LensGhostOperation_h -#define _COM_LensGhostOperation_h -#include "COM_NodeOperation.h" -#include "DNA_lamp_types.h" -#include "DNA_object_types.h" -#include "DNA_camera_types.h" - -class LensGhostProjectionOperation : public NodeOperation { -protected: - Object *lampObject; - Lamp *lamp; - Object *cameraObject; - - void *system; - float visualLampPosition[3]; - CompositorQuality quality; - int step; - SocketReader * bokehReader; - -public: - LensGhostProjectionOperation(); - - /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - - /** - * Initialize the execution - */ - void initExecution(); - - /** - * Deinitialize the execution - */ - void deinitExecution(); - bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); - - void setLampObject(Object *lampObject) {this->lampObject = lampObject;} - void setCameraObject(Object *cameraObject) {this->cameraObject = cameraObject;} - - void setQuality(CompositorQuality quality) {this->quality = quality;} -}; - -class LensGhostOperation : public LensGhostProjectionOperation { -public: - LensGhostOperation(); - - void *initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); - void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); - /** - * the inner loop of this program - */ - void executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void * data); - /** - * Initialize the execution - */ - void initExecution(); -}; -#endif diff --git a/source/blender/compositor/operations/COM_LensGlowImageOperation.cpp b/source/blender/compositor/operations/COM_LensGlowImageOperation.cpp deleted file mode 100644 index ee0a02e5fae..00000000000 --- a/source/blender/compositor/operations/COM_LensGlowImageOperation.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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: - * Jeroen Bakker - * Monique Dewanchand - */ - -#include "COM_LensGlowImageOperation.h" -#include "BLI_math.h" - -LensGlowImageOperation::LensGlowImageOperation(): NodeOperation() -{ - this->addOutputSocket(COM_DT_COLOR); -} -void LensGlowImageOperation::initExecution() -{ - this->scale = 1/20000.0f; -} -void LensGlowImageOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) -{ - const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f; - const float v = 2.f*(y / (float)512.0f) - 1.f; - const float u = 2.f*(x / (float)512.0f) - 1.f; - const float r = (u*u + v*v)*scale; - const float d = -sqrtf(sqrtf(sqrtf(r)))*9.f; - const float w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI)); - color[0] = expf(d*cs_r) * w; - color[1] = expf(d*cs_g) * w; - color[2] = expf(d*cs_b) * w; - color[3] = 1.0f; -} - -void LensGlowImageOperation::deinitExecution() -{ -} - -void LensGlowImageOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) -{ - resolution[0] = 512; - resolution[1] = 512; -} diff --git a/source/blender/compositor/operations/COM_LensGlowOperation.cpp b/source/blender/compositor/operations/COM_LensGlowOperation.cpp deleted file mode 100644 index 492dc715f10..00000000000 --- a/source/blender/compositor/operations/COM_LensGlowOperation.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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: - * Jeroen Bakker - * Monique Dewanchand - */ - -#include "COM_LensGlowOperation.h" -#include "BLI_math.h" - -LensGlowOperation::LensGlowOperation(): NodeOperation() -{ - this->addInputSocket(COM_DT_COLOR); - this->addOutputSocket(COM_DT_COLOR); - this->inputProgram = NULL; - this->lamp = NULL; -} -void LensGlowOperation::initExecution() -{ - this->inputProgram = this->getInputSocketReader(0); -} - -void LensGlowOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) -{ -// const float emit100 = this->lamp->energy*100; -// const float emit200 = emit100*2; -// const float deltaX = 160-x; -// const float deltaY = 100-y; -// const float distance = deltaX * deltaX + deltaY*deltaY; - -// float glow = (emit100-(distance))/(emit200); -// if (glow<0) glow=0; - -// color[0] = glow*lamp->r; -// color[1] = glow*lamp->g; -// color[2] = glow*lamp->b; -// color[3] = 1.0f; -} - -void LensGlowOperation::deinitExecution() -{ - this->inputProgram = NULL; -} diff --git a/source/blender/compositor/operations/COM_LensGlowOperation.h b/source/blender/compositor/operations/COM_LensGlowOperation.h deleted file mode 100644 index 77e13e88418..00000000000 --- a/source/blender/compositor/operations/COM_LensGlowOperation.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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: - * Jeroen Bakker - * Monique Dewanchand - */ - -#ifndef _COM_LensGlowOperation_h -#define _COM_LensGlowOperation_h -#include "COM_NodeOperation.h" -#include "DNA_lamp_types.h" - -class LensGlowOperation : public NodeOperation { -private: - /** - * Cached reference to the inputProgram - */ - SocketReader * inputProgram; - Lamp *lamp; - -public: - LensGlowOperation(); - - /** - * the inner loop of this program - */ - void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]); - - /** - * Initialize the execution - */ - void initExecution(); - - /** - * Deinitialize the execution - */ - void deinitExecution(); - - void setLamp(Lamp *lamp) {this->lamp = lamp;} -}; -#endif diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index 3a287cb7239..2ea5f85253b 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -47,6 +47,22 @@ void MathBaseOperation::deinitExecution() this->inputValue2Operation = NULL; } +void MathBaseOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + InputSocket *socket; + unsigned int tempPreferredResolution[] = {0,0}; + unsigned int tempResolution[2]; + + socket = this->getInputSocket(0); + socket->determineResolution(tempResolution, tempPreferredResolution); + if ((tempResolution[0] != 0) && (tempResolution[1] != 0)) { + this->setResolutionInputSocketIndex(0); + } else { + this->setResolutionInputSocketIndex(1); + } + NodeOperation::determineResolution(resolution, preferredResolution); +} + void MathAddOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) { float inputValue1[4]; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index 87f8a304158..64e8c4af88f 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -58,6 +58,10 @@ public: */ void deinitExecution(); + /** + * Determine resolution + */ + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); }; class MathAddOperation: public MathBaseOperation { diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index b565e48345c..6019ab879be 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -70,19 +70,16 @@ void MovieClipOperation::deinitExecution() void MovieClipOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) { - ImBuf *ibuf; - resolution[0] = 0; resolution[1] = 0; if (this->movieClip) { - ibuf = BKE_movieclip_get_ibuf(this->movieClip, this->movieClipUser); - if (ibuf) { - resolution[0] = ibuf->x; - resolution[1] = ibuf->y; + int width, height; - IMB_freeImBuf(ibuf); - } + BKE_movieclip_get_size(this->movieClip, this->movieClipUser, &width, &height); + + resolution[0] = width; + resolution[1] = height; } } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index f583493340b..5792248464a 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -81,10 +81,11 @@ public: if (x<0 || x >= this->width || y <0 || y >= this->height) { *u = x; *v = y; - } else { - + } + else { int offset = y * this->width + x; - int offset2 = offset*2; + int offset2 = offset * 2; + if (!bufferCalculated[offset]) { //float overscan = 0.0f; float w = (float)this->width/* / (1 + overscan) */; @@ -99,7 +100,8 @@ public: if (inverted) { BKE_tracking_invert_intrinsics(trackingData, in, out); - } else { + } + else { BKE_tracking_apply_intrinsics(trackingData, in, out); } diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 3af914f8d0e..498add2fc87 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -22,10 +22,8 @@ #include "COM_WriteBufferOperation.h" #include "COM_defines.h" -#include "COM_MemoryManager.h" #include <stdio.h> -/// @TODO: writebuffers don't have an actual data type set. WriteBufferOperation::WriteBufferOperation() :NodeOperation() { this->addInputSocket(COM_DT_COLOR); @@ -46,20 +44,23 @@ void WriteBufferOperation::executePixel(float *color, float x, float y, PixelSam { input->read(color, x, y, sampler, inputBuffers); } + void WriteBufferOperation::initExecution() { - this->input = this->getInputOperation(0); - MemoryManager::addMemoryProxy(this->memoryProxy); + this->input = this->getInputOperation(0); + this->memoryProxy->allocate(this->width, this->height); } + void WriteBufferOperation::deinitExecution() { this->input = NULL; + this->memoryProxy->free(); } - void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers) { - MemoryBuffer *memoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), tileNumber); + //MemoryBuffer *memoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), tileNumber); + MemoryBuffer *memoryBuffer = this->memoryProxy->getBuffer(); float *buffer = memoryBuffer->getBuffer(); if (this->input->isComplex()) { void *data = this->input->initializeTileData(rect, memoryBuffers); @@ -67,14 +68,14 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset4 = 0; int x; int y; bool breaked = false; for (y = y1 ; y < y2 && (!breaked) ; y++) { + int offset4 = (y*memoryBuffer->getWidth()+x1)*COM_NUMBER_OF_CHANNELS; for (x = x1 ; x < x2; x++) { input->read(&(buffer[offset4]), x, y, memoryBuffers, data); - offset4 +=4; + offset4 +=COM_NUMBER_OF_CHANNELS; } if (tree->test_break && tree->test_break(tree->tbh)) { @@ -92,14 +93,15 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me int y1 = rect->ymin; int x2 = rect->xmax; int y2 = rect->ymax; - int offset4 = 0; + int x; int y; bool breaked = false; for (y = y1 ; y < y2 && (!breaked) ; y++) { + int offset4 = (y*memoryBuffer->getWidth()+x1)*COM_NUMBER_OF_CHANNELS; for (x = x1 ; x < x2 ; x++) { input->read(&(buffer[offset4]), x, y, COM_PS_NEAREST, memoryBuffers); - offset4 +=4; + offset4 +=COM_NUMBER_OF_CHANNELS; } if (tree->test_break && tree->test_break(tree->tbh)) { breaked = true; @@ -111,7 +113,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** inputMemoryBuffers) { - MemoryBuffer *outputMemoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), chunkNumber); + MemoryBuffer *outputMemoryBuffer = this->getMemoryProxy()->getBuffer();// @todo wrong implementation needs revision float *outputFloatBuffer = outputMemoryBuffer->getBuffer(); cl_int error; /* |