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:
-rw-r--r--source/blender/blenloader/intern/versioning_270.c17
-rw-r--r--source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp8
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp152
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h39
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cpp50
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.h2
-rw-r--r--source/blender/editors/space_node/drawnode.c7
-rw-r--r--source/blender/makesdna/DNA_node_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c15
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c3
11 files changed, 230 insertions, 79 deletions
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index a6320ed597b..096fc315f39 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -542,4 +542,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
part->child_flag |= PART_CHILD_USE_ROUGH_CURVE;
}
}
+
+ if (!DNA_struct_elem_find(fd->filesdna, "NodePlaneTrackDeformData", "char", "flag")) {
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_COMPOSIT) {
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (ELEM(node->type, CMP_NODE_PLANETRACKDEFORM)) {
+ NodePlaneTrackDeformData *data = node->storage;
+ data->flag = 0;
+ data->motion_blur_samples = 16;
+ data->motion_blur_shutter = 0.5f;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END
+ }
}
diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
index 9b69bc5a46e..379b9f193e8 100644
--- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
+++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
@@ -54,6 +54,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C
warp_image_operation->setTrackingObject(data->tracking_object);
warp_image_operation->setPlaneTrackName(data->plane_track_name);
warp_image_operation->setFramenumber(frame_number);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ warp_image_operation->setMotionBlurSamples(data->motion_blur_samples);
+ warp_image_operation->setMotionBlurShutter(data->motion_blur_shutter);
+ }
converter.addOperation(warp_image_operation);
converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0));
@@ -64,6 +68,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C
plane_mask_operation->setTrackingObject(data->tracking_object);
plane_mask_operation->setPlaneTrackName(data->plane_track_name);
plane_mask_operation->setFramenumber(frame_number);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ plane_mask_operation->setMotionBlurSamples(data->motion_blur_samples);
+ plane_mask_operation->setMotionBlurShutter(data->motion_blur_shutter);
+ }
converter.addOperation(plane_mask_operation);
converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket());
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
index fe272000b6e..fb8730c9fa0 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
@@ -135,7 +135,7 @@ void *PlaneCornerPinMaskOperation::initializeTileData(rcti *rect)
getInputSocketReader(3) };
float corners[4][2];
readCornersFromSockets(rect, readers, corners);
- calculateCorners(corners, true);
+ calculateCorners(corners, true, 0);
m_corners_ready = true;
}
@@ -194,8 +194,7 @@ void *PlaneCornerPinWarpImageOperation::initializeTileData(rcti *rect)
getInputSocketReader(4) };
float corners[4][2];
readCornersFromSockets(rect, readers, corners);
- calculateCorners(corners, true);
- calculatePerspectiveMatrix();
+ calculateCorners(corners, true, 0);
m_corners_ready = true;
}
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
index c507b4cfa98..e3095f74b99 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
@@ -56,36 +56,38 @@ PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() :
this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
this->addOutputSocket(COM_DT_COLOR);
this->m_pixelReader = NULL;
+ this->m_motion_blur_samples = 1;
+ this->m_motion_blur_shutter = 0.5f;
this->setComplex(true);
}
-void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], bool normalized)
+void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ const int width = this->m_pixelReader->getWidth();
+ const int height = this->m_pixelReader->getHeight();
+ float frame_corners[4][2] = {{0.0f, 0.0f},
+ {(float) width, 0.0f},
+ {(float) width, (float) height},
+ {0.0f, (float) height}};
+ MotionSample *sample_data = &this->m_samples[sample];
if (normalized) {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
}
}
else {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0];
- this->m_frameSpaceCorners[i][1] = corners[i][1];
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
}
}
-}
-
-void PlaneDistortWarpImageOperation::calculatePerspectiveMatrix()
-{
- const int width = this->m_pixelReader->getWidth();
- const int height = this->m_pixelReader->getHeight();
- float frame_corners[4][2] = {{0.0f, 0.0f},
- {(float) width, 0.0f},
- {(float) width, (float) height},
- {0.0f, (float) height}};
- BKE_tracking_homography_between_two_quads(this->m_frameSpaceCorners,
+ BKE_tracking_homography_between_two_quads(sample_data->frameSpaceCorners,
frame_corners,
- this->m_perspectiveMatrix);
+ sample_data->perspectiveMatrix);
}
void PlaneDistortWarpImageOperation::initExecution()
@@ -100,35 +102,47 @@ void PlaneDistortWarpImageOperation::deinitExecution()
void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float xy[2] = {x, y};
float uv[2];
float deriv[2][2];
-
- pixelTransform(xy, uv, deriv);
-
- m_pixelReader->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR);
-}
-
-void PlaneDistortWarpImageOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2])
-{
- warpCoord(xy[0], xy[1], m_perspectiveMatrix, r_uv, r_deriv);
+ if (this->m_motion_blur_samples == 1) {
+ warpCoord(x, y, this->m_samples[0].perspectiveMatrix, uv, deriv);
+ m_pixelReader->readFiltered(output,
+ uv[0], uv[1],
+ deriv[0], deriv[1],
+ COM_PS_BILINEAR);
+ }
+ else {
+ zero_v4(output);
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ float color[4];
+ warpCoord(x, y, this->m_samples[sample].perspectiveMatrix, uv, deriv);
+ m_pixelReader->readFiltered(color,
+ uv[0], uv[1],
+ deriv[0], deriv[1],
+ COM_PS_BILINEAR);
+ add_v4_v4(output, color);
+ }
+ mul_v4_fl(output, 1.0f / (float)this->m_motion_blur_samples);
+ }
}
bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- float UVs[4][2];
- float deriv[2][2];
-
- /* TODO(sergey): figure out proper way to do this. */
- warpCoord(input->xmin - 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[0], deriv);
- warpCoord(input->xmax + 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[1], deriv);
- warpCoord(input->xmax + 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[2], deriv);
- warpCoord(input->xmin - 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[3], deriv);
-
float min[2], max[2];
INIT_MINMAX2(min, max);
- for (int i = 0; i < 4; i++) {
- minmax_v2v2_v2(min, max, UVs[i]);
+
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ float UVs[4][2];
+ float deriv[2][2];
+ MotionSample *sample_data = &this->m_samples[sample];
+ /* TODO(sergey): figure out proper way to do this. */
+ warpCoord(input->xmin - 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[0], deriv);
+ warpCoord(input->xmax + 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[1], deriv);
+ warpCoord(input->xmax + 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[2], deriv);
+ warpCoord(input->xmin - 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[3], deriv);
+ for (int i = 0; i < 4; i++) {
+ minmax_v2v2_v2(min, max, UVs[i]);
+ }
}
rcti newInput;
@@ -151,20 +165,26 @@ PlaneDistortMaskOperation::PlaneDistortMaskOperation() :
/* Currently hardcoded to 8 samples. */
m_osa = 8;
+ this->m_motion_blur_samples = 1;
+ this->m_motion_blur_shutter = 0.5f;
}
-void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2], bool normalized)
+void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ MotionSample *sample_data = &this->m_samples[sample];
if (normalized) {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
}
}
else {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0];
- this->m_frameSpaceCorners[i][1] = corners[i][1];
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
}
}
}
@@ -177,18 +197,44 @@ void PlaneDistortMaskOperation::initExecution()
void PlaneDistortMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float point[2];
-
int inside_counter = 0;
- for (int sample = 0; sample < this->m_osa; sample++) {
- point[0] = x + this->m_jitter[sample][0];
- point[1] = y + this->m_jitter[sample][1];
-
- if (isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[1], this->m_frameSpaceCorners[2]) ||
- isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[2], this->m_frameSpaceCorners[3]))
+ if (this->m_motion_blur_samples == 1) {
+ MotionSample *sample_data = &this->m_samples[0];
+ for (int sample = 0; sample < this->m_osa; sample++) {
+ point[0] = x + this->m_jitter[sample][0];
+ point[1] = y + this->m_jitter[sample][1];
+ if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[1],
+ sample_data->frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[2],
+ sample_data->frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
+ output[0] = (float)inside_counter / this->m_osa;
+ }
+ else {
+ for (int motion_sample = 0;
+ motion_sample < this->m_motion_blur_samples;
+ ++motion_sample)
{
- inside_counter++;
+ MotionSample *sample_data = &this->m_samples[motion_sample];
+ for (int osa_sample = 0; osa_sample < this->m_osa; ++osa_sample) {
+ point[0] = x + this->m_jitter[osa_sample][0];
+ point[1] = y + this->m_jitter[osa_sample][1];
+ if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[1],
+ sample_data->frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[2],
+ sample_data->frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
}
+ output[0] = (float)inside_counter / (this->m_osa * this->m_motion_blur_samples);
}
-
- output[0] = (float) inside_counter / this->m_osa;
}
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
index ee2874c6b46..6ceb476f5f9 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
@@ -33,43 +33,68 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
+#define PLANE_DISTORT_MAX_SAMPLES 64
class PlaneDistortWarpImageOperation : public NodeOperation {
protected:
+ struct MotionSample {
+ float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ float perspectiveMatrix[3][3];
+ };
SocketReader *m_pixelReader;
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
- float m_perspectiveMatrix[3][3];
+ MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
+ int m_motion_blur_samples;
+ float m_motion_blur_shutter;
public:
PlaneDistortWarpImageOperation();
- void calculateCorners(const float corners[4][2], bool normalized);
- void calculatePerspectiveMatrix();
+ void calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample);
void initExecution();
void deinitExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
- void pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ void setMotionBlurSamples(int samples) {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter) { this->m_motion_blur_shutter = shutter; }
};
class PlaneDistortMaskOperation : public NodeOperation {
protected:
+ struct MotionSample {
+ float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ };
int m_osa;
+ MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
float m_jitter[32][2];
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ int m_motion_blur_samples;
+ float m_motion_blur_shutter;
public:
PlaneDistortMaskOperation();
- void calculateCorners(const float corners[4][2], bool normalized);
+ void calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample);
void initExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+
+ void setMotionBlurSamples(int samples) {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter) { this->m_motion_blur_shutter = shutter; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
index fec39cbfde0..f6152981ee7 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
@@ -46,7 +46,7 @@ PlaneTrackCommon::PlaneTrackCommon()
this->m_planeTrackName[0] = '\0';
}
-void PlaneTrackCommon::readCornersFromTrack(float corners[4][2])
+void PlaneTrackCommon::readCornersFromTrack(float corners[4][2], float frame)
{
MovieTracking *tracking;
MovieTrackingObject *object;
@@ -64,13 +64,13 @@ void PlaneTrackCommon::readCornersFromTrack(float corners[4][2])
if (plane_track) {
MovieTrackingPlaneMarker *plane_marker;
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);
-
+ float clip_framenr =
+ BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip,
+ frame);
plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
- copy_v2_v2(corners[0], plane_marker->corners[0]);
- copy_v2_v2(corners[1], plane_marker->corners[1]);
- copy_v2_v2(corners[2], plane_marker->corners[2]);
- copy_v2_v2(corners[3], plane_marker->corners[3]);
+ BKE_tracking_plane_marker_get_subframe_corners(plane_track,
+ clip_framenr,
+ corners);
}
}
}
@@ -98,10 +98,21 @@ void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned
void PlaneTrackMaskOperation::initExecution()
{
PlaneDistortMaskOperation::initExecution();
-
float corners[4][2];
- readCornersFromTrack(corners);
- calculateCorners(corners, true);
+ if (this->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
+ const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ readCornersFromTrack(corners, frame_iter);
+ calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
}
/* ******** PlaneTrackWarpImageOperation ******** */
@@ -109,9 +120,20 @@ void PlaneTrackMaskOperation::initExecution()
void PlaneTrackWarpImageOperation::initExecution()
{
PlaneDistortWarpImageOperation::initExecution();
-
+ /* TODO(sergey): De-duplicate with mask operation. */
float corners[4][2];
- readCornersFromTrack(corners);
- calculateCorners(corners, true);
- calculatePerspectiveMatrix();
+ if (this->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
+ const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ readCornersFromTrack(corners, frame_iter);
+ calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
index 3c5dd783542..b355c64a1ca 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
@@ -43,7 +43,7 @@ protected:
/* note: this class is not an operation itself (to prevent virtual inheritance issues)
* implementation classes must make wrappers to use these methods, see below.
*/
- void readCornersFromTrack(float corners[4][2]);
+ void readCornersFromTrack(float corners[4][2], float frame);
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
public:
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 394d148de54..c986a249663 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2314,6 +2314,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
+ NodePlaneTrackDeformData *data = node->storage;
uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
@@ -2342,6 +2343,12 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
uiItemR(layout, ptr, "plane_track_name", 0, "", ICON_ANIM_DATA);
}
}
+
+ uiItemR(layout, ptr, "use_motion_blur", 0, NULL, ICON_NONE);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ uiItemR(layout, ptr, "motion_blur_samples", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_shutter", 0, NULL, ICON_NONE);
+ }
}
static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout), bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 5d1793e479a..f08b3ea9590 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -825,6 +825,10 @@ typedef struct NodeTranslateData {
typedef struct NodePlaneTrackDeformData {
char tracking_object[64];
char plane_track_name[64];
+ char flag;
+ char motion_blur_samples;
+ char pad[2];
+ float motion_blur_shutter;
} NodePlaneTrackDeformData;
typedef struct NodeShaderScript {
@@ -1080,4 +1084,11 @@ enum {
/* viewer and cmposite output */
#define CMP_NODE_OUTPUT_IGNORE_ALPHA 1
+/* Plane track deform node */
+enum {
+ CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR = 1,
+};
+
+#define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64
+
#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 7f574c41b1f..8d2a44136e8 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -6231,6 +6231,21 @@ static void def_cmp_planetrackdeform(StructRNA *srna)
RNA_def_property_string_sdna(prop, NULL, "plane_track_name");
RNA_def_property_ui_text(prop, "Plane Track", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR);
+ RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled motion blur of the mask");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX);
+ RNA_def_property_ui_text(prop, "Samples", "Number of motion blur samples");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 1.0f);
+ RNA_def_property_ui_text(prop, "Shutter", "Exposure for motion blur as a factor of FPS");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_sunbeams(StructRNA *srna)
diff --git a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
index 7a15d6364dc..415427c360f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
+++ b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
@@ -47,7 +47,8 @@ static bNodeSocketTemplate cmp_node_planetrackdeform_out[] = {
static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodePlaneTrackDeformData *data = MEM_callocN(sizeof(NodePlaneTrackDeformData), "node plane track deform data");
-
+ data->motion_blur_samples = 16;
+ data->motion_blur_shutter = 0.5f;
node->storage = data;
}