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_RotateOperation.cc')
-rw-r--r--source/blender/compositor/operations/COM_RotateOperation.cc133
1 files changed, 110 insertions, 23 deletions
diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc
index 8578e5c3269..9e26c93feac 100644
--- a/source/blender/compositor/operations/COM_RotateOperation.cc
+++ b/source/blender/compositor/operations/COM_RotateOperation.cc
@@ -25,8 +25,8 @@ namespace blender::compositor {
RotateOperation::RotateOperation()
{
- this->addInputSocket(DataType::Color);
- this->addInputSocket(DataType::Value);
+ this->addInputSocket(DataType::Color, ResizeMode::None);
+ this->addInputSocket(DataType::Value, ResizeMode::None);
this->addOutputSocket(DataType::Color);
this->set_canvas_input_index(0);
this->m_imageSocket = nullptr;
@@ -36,6 +36,21 @@ RotateOperation::RotateOperation()
sampler_ = PixelSampler::Bilinear;
}
+void RotateOperation::get_rotation_center(const rcti &area, float &r_x, float &r_y)
+{
+ r_x = (BLI_rcti_size_x(&area) - 1) / 2.0;
+ r_y = (BLI_rcti_size_y(&area) - 1) / 2.0;
+}
+
+void RotateOperation::get_rotation_offset(const rcti &input_canvas,
+ const rcti &rotate_canvas,
+ float &r_offset_x,
+ float &r_offset_y)
+{
+ r_offset_x = (BLI_rcti_size_x(&input_canvas) - BLI_rcti_size_x(&rotate_canvas)) / 2.0f;
+ r_offset_y = (BLI_rcti_size_y(&input_canvas) - BLI_rcti_size_y(&rotate_canvas)) / 2.0f;
+}
+
void RotateOperation::get_area_rotation_bounds(const rcti &area,
const float center_x,
const float center_y,
@@ -48,14 +63,14 @@ void RotateOperation::get_area_rotation_bounds(const rcti &area,
const float dxmax = area.xmax - center_x;
const float dymax = area.ymax - center_y;
- const float x1 = center_x + (cosine * dxmin + sine * dymin);
- const float x2 = center_x + (cosine * dxmax + sine * dymin);
- const float x3 = center_x + (cosine * dxmin + sine * dymax);
- const float x4 = center_x + (cosine * dxmax + sine * dymax);
- const float y1 = center_y + (-sine * dxmin + cosine * dymin);
- const float y2 = center_y + (-sine * dxmax + cosine * dymin);
- const float y3 = center_y + (-sine * dxmin + cosine * dymax);
- const float y4 = center_y + (-sine * dxmax + cosine * dymax);
+ const float x1 = center_x + (cosine * dxmin + (-sine) * dymin);
+ const float x2 = center_x + (cosine * dxmax + (-sine) * dymin);
+ const float x3 = center_x + (cosine * dxmin + (-sine) * dymax);
+ const float x4 = center_x + (cosine * dxmax + (-sine) * dymax);
+ const float y1 = center_y + (sine * dxmin + cosine * dymin);
+ const float y2 = center_y + (sine * dxmax + cosine * dymin);
+ const float y3 = center_y + (sine * dxmin + cosine * dymax);
+ const float y4 = center_y + (sine * dxmax + cosine * dymax);
const float minx = MIN2(x1, MIN2(x2, MIN2(x3, x4)));
const float maxx = MAX2(x1, MAX2(x2, MAX2(x3, x4)));
const float miny = MIN2(y1, MIN2(y2, MIN2(y3, y4)));
@@ -67,10 +82,56 @@ void RotateOperation::get_area_rotation_bounds(const rcti &area,
r_bounds.ymax = ceil(maxy);
}
+void RotateOperation::get_area_rotation_bounds_inverted(const rcti &area,
+ const float center_x,
+ const float center_y,
+ const float sine,
+ const float cosine,
+ rcti &r_bounds)
+{
+ get_area_rotation_bounds(area, center_x, center_y, -sine, cosine, r_bounds);
+}
+
+void RotateOperation::get_rotation_area_of_interest(const rcti &input_canvas,
+ const rcti &rotate_canvas,
+ const float sine,
+ const float cosine,
+ const rcti &output_area,
+ rcti &r_input_area)
+{
+ float center_x, center_y;
+ get_rotation_center(input_canvas, center_x, center_y);
+
+ float rotate_offset_x, rotate_offset_y;
+ get_rotation_offset(input_canvas, rotate_canvas, rotate_offset_x, rotate_offset_y);
+
+ r_input_area = output_area;
+ BLI_rcti_translate(&r_input_area, rotate_offset_x, rotate_offset_y);
+ get_area_rotation_bounds_inverted(r_input_area, center_x, center_y, sine, cosine, r_input_area);
+}
+
+void RotateOperation::get_rotation_canvas(const rcti &input_canvas,
+ const float sine,
+ const float cosine,
+ rcti &r_canvas)
+{
+ float center_x, center_y;
+ get_rotation_center(input_canvas, center_x, center_y);
+
+ rcti rot_bounds;
+ get_area_rotation_bounds(input_canvas, center_x, center_y, sine, cosine, rot_bounds);
+
+ float offset_x, offset_y;
+ get_rotation_offset(input_canvas, rot_bounds, offset_x, offset_y);
+ r_canvas = rot_bounds;
+ BLI_rcti_translate(&r_canvas, -offset_x, -offset_y);
+}
+
void RotateOperation::init_data()
{
- this->m_centerX = (getWidth() - 1) / 2.0;
- this->m_centerY = (getHeight() - 1) / 2.0;
+ if (execution_model_ == eExecutionModel::Tiled) {
+ get_rotation_center(get_canvas(), m_centerX, m_centerY);
+ }
}
void RotateOperation::initExecution()
@@ -94,11 +155,7 @@ inline void RotateOperation::ensureDegree()
this->m_degreeSocket->readSampled(degree, 0, 0, PixelSampler::Nearest);
break;
case eExecutionModel::FullFrame:
- NodeOperation *degree_op = getInputOperation(DEGREE_INPUT_INDEX);
- const bool is_constant_degree = degree_op->get_flags().is_constant_operation;
- degree[0] = is_constant_degree ?
- static_cast<ConstantOperation *>(degree_op)->get_constant_elem()[0] :
- 0.0f;
+ degree[0] = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f);
break;
}
@@ -159,6 +216,26 @@ bool RotateOperation::determineDependingAreaOfInterest(rcti *input,
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
+void RotateOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
+{
+ if (execution_model_ == eExecutionModel::Tiled) {
+ NodeOperation::determine_canvas(preferred_area, r_area);
+ return;
+ }
+
+ const bool image_determined =
+ getInputSocket(IMAGE_INPUT_INDEX)->determine_canvas(preferred_area, r_area);
+ if (image_determined) {
+ rcti input_canvas = r_area;
+ rcti unused;
+ getInputSocket(DEGREE_INPUT_INDEX)->determine_canvas(input_canvas, unused);
+
+ ensureDegree();
+
+ get_rotation_canvas(input_canvas, m_sine, m_cosine, r_area);
+ }
+}
+
void RotateOperation::get_area_of_interest(const int input_idx,
const rcti &output_area,
rcti &r_input_area)
@@ -169,7 +246,10 @@ void RotateOperation::get_area_of_interest(const int input_idx,
}
ensureDegree();
- get_area_rotation_bounds(output_area, m_centerX, m_centerY, m_sine, m_cosine, r_input_area);
+
+ const rcti &input_image_canvas = get_input_operation(IMAGE_INPUT_INDEX)->get_canvas();
+ get_rotation_area_of_interest(
+ input_image_canvas, this->get_canvas(), m_sine, m_cosine, output_area, r_input_area);
expand_area_for_sampler(r_input_area, sampler_);
}
@@ -177,13 +257,20 @@ void RotateOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
- ensureDegree();
const MemoryBuffer *input_img = inputs[IMAGE_INPUT_INDEX];
+
+ NodeOperation *image_op = get_input_operation(IMAGE_INPUT_INDEX);
+ float center_x, center_y;
+ get_rotation_center(image_op->get_canvas(), center_x, center_y);
+ float rotate_offset_x, rotate_offset_y;
+ get_rotation_offset(
+ image_op->get_canvas(), this->get_canvas(), rotate_offset_x, rotate_offset_y);
+
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
- float x = it.x;
- float y = it.y;
- rotate_coords(x, y, m_centerX, m_centerY, m_sine, m_cosine);
- input_img->read_elem_sampled(x, y, sampler_, it.out);
+ float x = rotate_offset_x + it.x + canvas_.xmin;
+ float y = rotate_offset_y + it.y + canvas_.ymin;
+ rotate_coords(x, y, center_x, center_y, m_sine, m_cosine);
+ input_img->read_elem_sampled(x - canvas_.xmin, y - canvas_.ymin, sampler_, it.out);
}
}