diff options
Diffstat (limited to 'source/blender/compositor/operations/COM_BoxMaskOperation.cc')
-rw-r--r-- | source/blender/compositor/operations/COM_BoxMaskOperation.cc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc index 9938d4a85ed..15bb19660dc 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc @@ -105,6 +105,64 @@ void BoxMaskOperation::executePixelSampled(float output[4], float x, float y, Pi } } +void BoxMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) +{ + MaskFunc mask_func; + switch (m_maskType) { + case CMP_NODE_MASKTYPE_ADD: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? MAX2(mask[0], value[0]) : mask[0]; + }; + break; + case CMP_NODE_MASKTYPE_SUBTRACT: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? CLAMPIS(mask[0] - value[0], 0, 1) : mask[0]; + }; + break; + case CMP_NODE_MASKTYPE_MULTIPLY: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? mask[0] * value[0] : 0; + }; + break; + case CMP_NODE_MASKTYPE_NOT: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + if (is_inside) { + return mask[0] > 0.0f ? 0.0f : value[0]; + } + return mask[0]; + }; + break; + } + apply_mask(output, area, inputs, mask_func); +} + +void BoxMaskOperation::apply_mask(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs, + MaskFunc mask_func) +{ + const float op_w = this->getWidth(); + const float op_h = this->getHeight(); + const float half_w = this->m_data->width / 2.0f; + const float half_h = this->m_data->height / 2.0f; + for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) { + const float op_ry = it.y / op_h; + const float dy = (op_ry - this->m_data->y) / m_aspectRatio; + const float op_rx = it.x / op_w; + const float dx = op_rx - this->m_data->x; + const float rx = this->m_data->x + (m_cosine * dx + m_sine * dy); + const float ry = this->m_data->y + (-m_sine * dx + m_cosine * dy); + + const bool inside = (rx > this->m_data->x - half_w && rx < this->m_data->x + half_w && + ry > this->m_data->y - half_h && ry < this->m_data->y + half_h); + const float *mask = it.in(0); + const float *value = it.in(1); + *it.out = mask_func(inside, mask, value); + } +} + void BoxMaskOperation::deinitExecution() { this->m_inputMask = nullptr; |