diff options
3 files changed, 50 insertions, 1 deletions
diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cpp b/source/blender/compositor/nodes/COM_ScaleNode.cpp index 5b2d6851f9f..85d5644484b 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.cpp +++ b/source/blender/compositor/nodes/COM_ScaleNode.cpp @@ -65,6 +65,8 @@ void ScaleNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c case CMP_SCALE_RENDERPERCENT: { const RenderData *data = &context->getScene()->r; ScaleFixedSizeOperation *operation = new ScaleFixedSizeOperation(); + operation->setIsAspect((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_ASPECT) != 0); + operation->setIsCrop((bnode->custom2 & CMP_SCALE_RENDERSIZE_FRAME_CROP) != 0); operation->setNewWidth(data->xsch * data->size / 100.0f); operation->setNewHeight(data->ysch * data->size / 100.0f); inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cpp b/source/blender/compositor/operations/COM_ScaleOperation.cpp index f0c3b41b61a..aea4da920a0 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cpp +++ b/source/blender/compositor/operations/COM_ScaleOperation.cpp @@ -190,6 +190,38 @@ void ScaleFixedSizeOperation::initExecution() this->inputOperation = this->getInputSocketReader(0); this->relX = inputOperation->getWidth() / (float)this->newWidth; this->relY = inputOperation->getHeight() / (float)this->newHeight; + + if (this->is_aspect) { + /* apply aspect from clip */ + const float w_src = inputOperation->getWidth(); + const float h_src = inputOperation->getHeight(); + + /* destination aspect is already applied from the camera frame */ + const float w_dst = this->newWidth; + const float h_dst = this->newHeight; + + const float asp_src = w_src / h_src; + const float asp_dst = w_dst / h_dst; + + this->offsetX = 0.0f; + this->offsetY = 0.0f; + + if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { + if ((asp_src > asp_dst) == (this->is_crop == true)) { + /* fit X */ + const float div = asp_src / asp_dst; + this->relX /= div; + this->offsetX = ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f; + } + else { + /* fit Y */ + const float div = asp_dst / asp_src; + this->relY /= div; + this->offsetY = ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f; + } + } + + } } void ScaleFixedSizeOperation::deinitExecution() @@ -204,7 +236,14 @@ void ScaleFixedSizeOperation::executePixel(float *color, float x, float y, Pixel sampler = COM_PS_BICUBIC; #endif - this->inputOperation->read(color, x * relX, y * relY, sampler, inputBuffers); + if (this->is_aspect) { + float nx = ((x - this->offsetX) * relX); + float ny = ((y - this->offsetY) * relY); + this->inputOperation->read(color, nx, ny, sampler, inputBuffers); + } + else { + this->inputOperation->read(color, x * relX, y * relY, sampler, inputBuffers); + } } bool ScaleFixedSizeOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index cf2f878e8bc..3964a5e2f71 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -63,6 +63,12 @@ class ScaleFixedSizeOperation : public NodeOperation { int newHeight; float relX; float relY; + + /* center is only used for aspect correction */ + float offsetX; + float offsetY; + bool is_aspect; + bool is_crop; public: ScaleFixedSizeOperation(); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); @@ -73,6 +79,8 @@ public: void deinitExecution(); void setNewWidth(int width) { this->newWidth = width; } void setNewHeight(int height) { this->newHeight = height; } + void setIsAspect(int is_aspect) { this->is_aspect = is_aspect; } + void setIsCrop(int is_crop) { this->is_crop = is_crop; } }; #endif |