diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-07-27 13:32:47 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-07-27 13:32:47 +0400 |
commit | b10a35a9a9128531347e60be530631b39386dcb2 (patch) | |
tree | bea13c8ae1f9557b4dc359eb173d0326440884dc /source/blender/compositor | |
parent | 93c29aaeb1b0021bac6cb09da1f0cfc7ca90809e (diff) |
motion blur for mask node:
TODO
- add shutter speed option
- add blur option
Diffstat (limited to 'source/blender/compositor')
-rw-r--r-- | source/blender/compositor/nodes/COM_MaskNode.cpp | 4 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_MaskOperation.cpp | 88 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_MaskOperation.h | 4 |
3 files changed, 82 insertions, 14 deletions
diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp index 2620f84cfae..71a7191a35e 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cpp +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -69,5 +69,9 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co operation->setSmooth((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_AA) != 0); operation->setFeather((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0); + if (editorNode->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) { + operation->setMotionBlurSamples(editorNode->custom2); + } + graph->addOperation(operation); } diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 5e68142bda3..a4e548d47ac 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -137,28 +137,74 @@ MaskOperation::MaskOperation() : NodeOperation() this->m_mask = NULL; this->m_maskWidth = 0; this->m_maskHeight = 0; + this->m_maskWidthInv = 0.0f; + this->m_maskHeightInv = 0.0f; this->m_framenumber = 0; - this->m_rasterMaskHandle = NULL; + this->m_rasterMaskHandleTot = 1; + memset(this->m_rasterMaskHandles, 0, sizeof(this->m_rasterMaskHandles)); } void MaskOperation::initExecution() { - if (this->m_mask) { - if (this->m_rasterMaskHandle == NULL) { - this->m_rasterMaskHandle = BKE_maskrasterize_handle_new(); + if (this->m_mask && this->m_rasterMaskHandles[0] == NULL) { + if (this->m_rasterMaskHandleTot == 1) { + this->m_rasterMaskHandles[0] = BKE_maskrasterize_handle_new(); - BKE_maskrasterize_handle_init(this->m_rasterMaskHandle, this->m_mask, - this->m_maskWidth, this->m_maskHeight, - TRUE, this->m_do_smooth, this->m_do_feather); + BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[0], this->m_mask, + this->m_maskWidth, this->m_maskHeight, + TRUE, this->m_do_smooth, this->m_do_feather); + } + else { + /* make a throw away copy of the mask */ + const float frame_range = 1.0f; /* should be 1 max, could be configurable */ + const float frame = (float)this->m_framenumber - frame_range; + const float frame_step = (frame_range * 2.0f) / this->m_rasterMaskHandleTot; + float frame_iter = frame; + + Mask *mask_temp; + + mask_temp = BKE_mask_copy_nolib(this->m_mask); + + /* trick so we can get unkeyed edits to display */ + { + MaskLayer *masklay; + MaskLayerShape *masklay_shape; + + for (masklay = (MaskLayer *)mask_temp->masklayers.first; + masklay; + masklay = (MaskLayer *)masklay->next) + { + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_framenumber); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); + } + } + + for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) { + this->m_rasterMaskHandles[i] = BKE_maskrasterize_handle_new(); + + /* re-eval frame info */ + BKE_mask_evaluate(mask_temp, frame_iter, TRUE); + + BKE_maskrasterize_handle_init(this->m_rasterMaskHandles[i], mask_temp, + this->m_maskWidth, this->m_maskHeight, + TRUE, this->m_do_smooth, this->m_do_feather); + + frame_iter += frame_step; + } + + BKE_mask_free(mask_temp); + MEM_freeN(mask_temp); } } } void MaskOperation::deinitExecution() { - if (this->m_rasterMaskHandle) { - BKE_maskrasterize_handle_free(this->m_rasterMaskHandle); - this->m_rasterMaskHandle = NULL; + for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) { + if (this->m_rasterMaskHandles[i]) { + BKE_maskrasterize_handle_free(this->m_rasterMaskHandles[i]); + this->m_rasterMaskHandles[i] = NULL; + } } } @@ -182,12 +228,28 @@ void MaskOperation::determineResolution(unsigned int resolution[], unsigned int void MaskOperation::executePixel(float *color, float x, float y, PixelSampler sampler) { - if (this->m_rasterMaskHandle) { - const float xy[2] = {x * this->m_maskWidthInv, y * this->m_maskHeightInv}; - color[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandle, xy); + const float xy[2] = {x * this->m_maskWidthInv, y * this->m_maskHeightInv}; + + if (this->m_rasterMaskHandleTot == 1) { + if (this->m_rasterMaskHandles[0]) { + color[0] = BKE_maskrasterize_handle_sample(this->m_rasterMaskHandles[0], xy); + } + else { + color[0] = 0.0f; + } } else { + /* incase loop below fails */ color[0] = 0.0f; + + for (unsigned int i = 0; i < this->m_rasterMaskHandleTot; i++) { + if (this->m_rasterMaskHandles[i]) { + color[0] += BKE_maskrasterize_handle_sample(this->m_rasterMaskHandles[i], xy); + } + } + + /* until we get better falloff */ + color[0] /= this->m_rasterMaskHandleTot; } } diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 59c84bdbb7b..a8c23b3bca1 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -64,7 +64,8 @@ protected: ListBase m_maskLayers; #else /* USE_RASKTER */ - struct MaskRasterHandle *m_rasterMaskHandle; + struct MaskRasterHandle *m_rasterMaskHandles[32]; + unsigned int m_rasterMaskHandleTot; #endif /* USE_RASKTER */ /** @@ -93,6 +94,7 @@ public: void setFramenumber(int framenumber) { this->m_framenumber = framenumber; } void setSmooth(bool smooth) { this->m_do_smooth = smooth; } void setFeather(bool feather) { this->m_do_feather = feather; } + void setMotionBlurSamples(int samples) { this->m_rasterMaskHandleTot = max(1, samples); } #ifdef USE_RASKTER void *initializeTileData(rcti *rect); |